综合办公系统
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

addproject.vue 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2024-03-18 11:00:04
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2024-06-03 17:15:38
  6. -->
  7. <template>
  8. <div class="project-wrapper">
  9. <!-- 项目登记 -->
  10. <h2 style="text-align: center">项目登记</h2>
  11. <el-form :model="addForm" :rules="rules" label-width="100px" :disabled="disabled">
  12. <el-row :gutter="20">
  13. <el-col :span="12">
  14. <el-form-item label="项目编号:" prop="projectNumber">
  15. <el-input v-model="addForm.projectNumber"></el-input>
  16. </el-form-item>
  17. </el-col>
  18. <el-col :span="12" v-if="addForm.projectSource == 0">
  19. <el-form-item label="合同编码:">
  20. <el-input v-model="contractCode" disabled></el-input>
  21. </el-form-item>
  22. </el-col>
  23. </el-row>
  24. <el-row :gutter="20">
  25. <el-col :span="12"><el-form-item label="项目名称:" prop="projectName">
  26. <el-input v-model="addForm.projectName"></el-input>
  27. </el-form-item>
  28. </el-col>
  29. <el-col :span="12" v-if="addForm.projectSource == 0">
  30. <el-form-item label="合同编号:">
  31. <el-input v-model="contractNumber" disabled></el-input>
  32. </el-form-item>
  33. </el-col>
  34. </el-row>
  35. <el-form-item label="项目类型:" prop="projectType">
  36. <el-input v-model="addForm.projectType"></el-input>
  37. </el-form-item>
  38. <el-form-item label="项目级别:" prop="projectLevel">
  39. <el-radio v-model="addForm.projectLevel" label="0">一般项目</el-radio>
  40. <el-radio v-model="addForm.projectLevel" label="1">重大项目</el-radio>
  41. </el-form-item>
  42. <el-form-item label="项目来源:" prop="projectSource">
  43. <el-radio v-model="addForm.projectSource" label="0">院内</el-radio>
  44. <el-radio v-model="addForm.projectSource" label="1">院外</el-radio>
  45. </el-form-item>
  46. <el-form-item label="合同编码:" v-if="addForm.projectSource == '1'">
  47. <el-input v-model="chooseContractInfo.contractCode">
  48. <el-button slot="append" @click="openContract = true">选择</el-button>
  49. </el-input>
  50. </el-form-item>
  51. <el-form-item label="合同编号:" v-if="addForm.projectSource == '1'">
  52. <el-input v-model="chooseContractInfo.contractNumber" disabled></el-input>
  53. </el-form-item>
  54. <el-form-item label="甲方单位:" prop="partyA">
  55. <el-autocomplete class="inline-input" v-model="addForm.partyA" :fetch-suggestions="querySearch"
  56. placeholder="请输入内容" style="width: 100%"></el-autocomplete>
  57. <!-- <el-input v-model="addForm.partyA"></el-input> -->
  58. </el-form-item>
  59. <el-form-item label="联系人:" prop="contactPerson">
  60. <el-input v-model="addForm.contactPerson"></el-input>
  61. </el-form-item>
  62. <el-form-item label="联系电话:" prop="telephone">
  63. <el-input v-model="addForm.telephone"></el-input>
  64. </el-form-item>
  65. <el-form-item label="项目概况:">
  66. <table border="1">
  67. <tr>
  68. <td style="width: 180px">工作内容</td>
  69. <td>等级或比例尺</td>
  70. <td>单位</td>
  71. <td>工作量</td>
  72. <td style="width: 100px">要求完成时间</td>
  73. <td>备注</td>
  74. </tr>
  75. <tr v-for="(work, index) in workList" :key="index">
  76. <td>
  77. <el-input v-model="work.content" type="textarea" clearable
  78. :autosize="{ minRows: 4, maxRows: 10 }"></el-input>
  79. </td>
  80. <td>
  81. <el-select v-model="work.scale" placeholder="请选择" clearable>
  82. <el-option v-for="dict in dict.type.cmc_scale_grade" :key="dict.value" :label="dict.label"
  83. :value="dict.label" />
  84. </el-select>
  85. </td>
  86. <td>
  87. <el-select v-model="work.unit" placeholder="请选择" clearable>
  88. <el-option v-for="dict in dict.type.cmc_unit" :key="dict.value" :label="dict.label"
  89. :value="dict.label" />
  90. </el-select>
  91. </td>
  92. <td>
  93. <el-input v-model="work.workload" clearable></el-input>
  94. </td>
  95. <td>
  96. <el-date-picker style="width: 140px" v-model="work.deadline" value-format="yyyy-MM-dd" type="date"
  97. placeholder="选择日期">
  98. </el-date-picker>
  99. </td>
  100. <td>
  101. <el-input v-model="work.remark" type="textarea" clearable
  102. :autosize="{ minRows: 4, maxRows: 10 }"></el-input>
  103. </td>
  104. <td>
  105. <el-button type="danger" icon="el-icon-minus" size="mini" circle
  106. @click="deletWorkItem(index)"></el-button>
  107. </td>
  108. </tr>
  109. </table>
  110. <el-button icon="el-icon-plus" size="mini" @click="addWorkList"></el-button>
  111. </el-form-item>
  112. <el-form-item label="附件上传:" prop="taskDocument">
  113. <FileUpload v-if="$route.query.taskName == '项目登记'" ref="orz" :limit="1" :filePathName="'项目任务书'"
  114. :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf']" @input="setProjectDocument">
  115. </FileUpload>
  116. <div v-if="$route.query.taskName != '项目登记'" class="upload-list">
  117. <el-link type="primary" :href="`${baseUrl}${'/profile/upload' + addForm.taskDocument}`" :underline="false" target="_blank">
  118. <span class="el-icon-document"> {{ getFileName(addForm.taskDocument) }} </span>
  119. </el-link>
  120. </div>
  121. </el-form-item>
  122. <el-form-item label="备注:" prop="remark">
  123. <el-input v-model="addForm.remark" type="textarea" rows="3"></el-input>
  124. </el-form-item>
  125. <el-row>
  126. <el-col :span="6" :xs="24" :offset="12">
  127. <el-form-item label="项目登记人:" prop="registrantUser">
  128. <span class="auditor"> {{ addForm.projectRegistrantUser ? addForm.projectRegistrantUser.nickName :
  129. registrantUser }} </span>
  130. </el-form-item>
  131. </el-col>
  132. <el-col :span="6">
  133. <el-form-item label="登记日期:" label-width="120px">
  134. <span> {{ addForm.registerTime ? addForm.registerTime : registerTime }} </span>
  135. </el-form-item>
  136. </el-col>
  137. </el-row>
  138. </el-form>
  139. <div slot="footer" class="dialog-footer" style="text-align: center">
  140. <el-button type="primary" @click="confirmAddForm" :disabled="disabled">提 交</el-button>
  141. <!-- <el-button @click="cancel" :disabled="disabled">取 消</el-button> -->
  142. </div>
  143. <el-dialog title="选择合同" :visible.sync="openContract" width="1000px" append-to-body>
  144. <choose-contract @choose="setContract" @close="openContract = false"></choose-contract>
  145. </el-dialog>
  146. </div>
  147. </template>
  148. <script>
  149. import { parseTime } from "@/utils/ruoyi";
  150. import { mapGetters } from "vuex";
  151. import { listProject, getProject, addProject, delProject } from "@/api/oa/project/project";
  152. import { getUser } from "@/api/system/user";
  153. import { getUsersDeptLeaderByDept } from "@/api/system/post";
  154. import { complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate, flowTaskForm } from "@/api/flowable/todo";
  155. import { listProjectWork, addProjectWork } from "@/api/oa/project/projectWork";
  156. import { listProjectContract, addProjectContract } from "@/api/oa/contract/projectContract";
  157. import { listContract, getContract, delContract, addContract, updateContract } from "@/api/oa/contract/contract";
  158. import chooseContract from '../components/chooseContract.vue';
  159. export default {
  160. components: { chooseContract },
  161. dicts: ['cmc_scale_grade', 'cmc_unit'],
  162. props: {
  163. disabled: {
  164. type: Boolean,
  165. require: true,
  166. },
  167. taskForm: {
  168. type: Object,
  169. required: true,
  170. },
  171. },
  172. computed: {
  173. ...mapGetters(["userId", "name"]),
  174. },
  175. data() {
  176. return {
  177. baseUrl:process.env.VUE_APP_BASE_API,
  178. openContract: false,
  179. registerTime: undefined,
  180. // 查询参数
  181. queryParams: {
  182. pageNum: 1,
  183. pageSize: 10,
  184. projectNumber: "",
  185. projectLeader: "",
  186. projectLeaderName: undefined,
  187. projectName: "",
  188. },
  189. projectList: [],
  190. total: 0,
  191. loading: true,
  192. modifyOpen: false,
  193. addForm: {
  194. registerTime: undefined,
  195. projectRegistrant: "",
  196. projectSource: "0"
  197. },
  198. chooseContractInfo: {},
  199. contractCode: "",
  200. contractNumber: "",
  201. rules: {
  202. projectNumber: [{ required: true, message: "请输入项目编号", trigger: "blur" }],
  203. projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
  204. },
  205. workList: [
  206. {
  207. content: "",
  208. scale: "",
  209. unit: "",
  210. workload: "",
  211. deadline: undefined,
  212. remark: "",
  213. },
  214. ],
  215. restaurants: [{ value: "中国电建集团成都勘测设计研究院有限公司勘测设计分公司" }],
  216. registrantUser: ''
  217. };
  218. },
  219. created() {
  220. this.registerTime = parseTime(new Date(), '{y}-{m}-{d}')
  221. if (this.$route.query.taskName != '项目登记') {
  222. this.getProjectInfo();
  223. this.getProjectWorkList();
  224. } else {
  225. this.addForm.projectRegistrant = this.userId;
  226. this.registrantUser = this.name;
  227. }
  228. this.getContractDataList();
  229. // this.getList();
  230. },
  231. mounted() {
  232. },
  233. methods: {
  234. // 查询项目列表
  235. getList() {
  236. this.loading = true;
  237. listProject(this.queryParams).then(response => {
  238. this.projectList = [];
  239. for (let p of response.rows) {
  240. if (p.projectLeader != null) {
  241. getUser(Number(p.projectLeader)).then(res => {
  242. p.projectLeaderName = res.data.nickName;
  243. });
  244. }
  245. this.projectList.push(p);
  246. }
  247. this.total = response.total;
  248. this.loading = false;
  249. });
  250. },
  251. getProjectInfo() {
  252. getProject(this.taskForm.formId).then(res => {
  253. this.addForm = res.data;
  254. })
  255. },
  256. getProjectWorkList() {
  257. listProjectWork({ projectId: this.taskForm.formId }).then(res => {
  258. this.workList = res.rows;
  259. })
  260. },
  261. getContractDataList() {
  262. listProjectContract({ projectId: this.taskForm.formId }).then(res => {
  263. if (res.rows) {
  264. for (let row of res.rows) {
  265. getContract(row.contractId).then(res => {
  266. if (res.data) {
  267. if (this.contractCode != '') {
  268. this.contractCode = this.contractCode + '、' + res.data.contractCode;
  269. } else {
  270. this.contractCode = res.data.contractCode;
  271. }
  272. if (this.contractNumber != '') {
  273. this.contractNumber = this.contractNumber + '、' + res.data.contractNumber;
  274. } else {
  275. this.contractNumber = res.data.contractNumber;
  276. }
  277. }
  278. })
  279. }
  280. }
  281. })
  282. },
  283. setContract(val) {
  284. this.chooseContractInfo = val;
  285. this.openContract = false;
  286. },
  287. confirmAddForm() {
  288. this.addForm.projectId = this.taskForm.formId;
  289. for (let work of this.workList) {
  290. work.projectId = this.taskForm.formId;
  291. addProjectWork(work);
  292. }
  293. addProject(this.addForm).then(response => {
  294. this.$modal.msgSuccess("新增成功");
  295. this.getList();
  296. });
  297. let contractId = this.chooseContractInfo.contractId ? this.chooseContractInfo.contractId : ''
  298. let pcobj = { projectId: this.taskForm.formId, contractId }
  299. if (contractId != '') {
  300. addProjectContract(pcobj).then(response => {
  301. this.$modal.msgSuccess("合同关联成功");
  302. })
  303. }
  304. const params = { taskId: this.taskForm.taskId };
  305. // 获取下一个流程节点
  306. getNextFlowNode(params).then(res => {
  307. getUsersDeptLeaderByDept({ deptId: 107 }).then(res => {
  308. let userId = res.data.userId;
  309. this.$set(this.taskForm.variables, "approval", userId);
  310. complete(this.taskForm).then(response => {
  311. this.$modal.msgSuccess(response.msg);
  312. this.$emit("goBack");
  313. });
  314. });
  315. });
  316. },
  317. cancel() {
  318. this.addForm = {};
  319. },
  320. addWorkList() {
  321. this.workList.push({
  322. content: "",
  323. scale: "",
  324. unit: "",
  325. workload: "",
  326. deadline: undefined,
  327. remark: "",
  328. });
  329. },
  330. deletWorkItem(index) {
  331. let arr = this.workList;
  332. if (arr.length == 1) {
  333. return;
  334. }
  335. if (index >= 0 && index < arr.length) {
  336. arr.splice(index, 1);
  337. }
  338. },
  339. querySearch(queryString, cb) {
  340. var restaurants = this.restaurants;
  341. var results = queryString
  342. ? restaurants.filter(this.createFilter(queryString))
  343. : restaurants;
  344. // 调用 callback 返回建议列表的数据
  345. cb(results);
  346. },
  347. createFilter(queryString) {
  348. return restaurant => {
  349. return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
  350. };
  351. },
  352. setProjectDocument(val) {
  353. let arr = val.split('/upload')
  354. this.addForm.taskDocument = arr[1]
  355. if (val == "") {
  356. this.addForm.taskDocument = ""
  357. }
  358. },
  359. getFileName(name) {
  360. if (name != null) {
  361. let arr = name.split('/')
  362. return arr[arr.length - 1];
  363. }
  364. },
  365. },
  366. };
  367. </script>
  368. <style lang="scss" scoped>
  369. @import "@/assets/styles/element-reset.scss";
  370. .project-wrapper {
  371. padding: 25px;
  372. }
  373. .table-header {
  374. background-color: #f5f5f5;
  375. }
  376. .card-header {
  377. display: flex;
  378. justify-content: space-between;
  379. padding: 0 10px;
  380. }
  381. table {
  382. /*居中*/
  383. margin: 0 auto;
  384. /*边框*/
  385. /* border: 1px solid black; */
  386. text-align: center;
  387. border-collapse: collapse;
  388. /*设置背景颜色*/
  389. /* background-color: #bfa; */
  390. }
  391. ::v-deep .el-input.is-disabled .el-input__inner {
  392. color: #686a6e;
  393. }
  394. ::v-deep .el-textarea.is-disabled .el-textarea__inner,
  395. .el-radio__input.is-disabled+span.el-radio__label {
  396. color: #686a6e;
  397. }
  398. ::v-deep .el-radio__input.is-disabled+span.el-radio__label {
  399. color: #686a6e;
  400. }
  401. ::v-deep .el-radio__input.is-disabled.is-checked .el-radio__inner::after {
  402. background-color: var(--current-color);
  403. width: 6px;
  404. height: 6px;
  405. }
  406. ::v-deep .el-radio__input.is-disabled .el-radio__inner,
  407. .el-radio__input.is-disabled.is-checked .el-radio__inner {
  408. border-color: var(--current-color);
  409. }
  410. </style>