f6e2f544 by lihua

合同进度页面前端开发

1 parent a0e8bb0e
...@@ -444,6 +444,26 @@ export const getRegisterExchangeList = () => request({ ...@@ -444,6 +444,26 @@ export const getRegisterExchangeList = () => request({
444 method: 'get' 444 method: 'get'
445 }) 445 })
446 446
447 /** 获取合同列表 */
448 export const getContractList = (params) => request({
449 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-contract/page-list`,
450 method: 'post',
451 data: params
452 })
453
454 /** 获取会员列表 */
455 export const getTenantList = (params) => request({
456 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/singlePage`,
457 method: 'post',
458 data: params
459 })
460
461 /** 获取当前用户所在的企业 */
462 export const getOwnerTenantList = (userGuid) => request({
463 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/get-tenant-by-user?userGuid=${userGuid}`,
464 method: 'get'
465 })
466
447 // API详情 467 // API详情
448 /** 查询域名和文根 */ 468 /** 查询域名和文根 */
449 /** api类型,有表单类型,自定义sql. */ 469 /** api类型,有表单类型,自定义sql. */
......
...@@ -217,6 +217,27 @@ const routes: RouteRecordRaw[] = [ ...@@ -217,6 +217,27 @@ const routes: RouteRecordRaw[] = [
217 }, 217 },
218 }, 218 },
219 ] 219 ]
220 },
221 {
222 path: '/data-asset-register/contract-progress',
223 component: Layout,
224 meta: {
225 title: '合同进度一览',
226 icon: 'ep:grid',
227 },
228 children: [
229 {
230 path: '',
231 name: 'contractProgress',
232 component: () => import('@/views/data_asset/contractProgress.vue'),
233 meta: {
234 title: '合同进度一览',
235 sidebar: false,
236 cache: true,
237 breadcrumb: false,
238 },
239 },
240 ]
220 } 241 }
221 ] 242 ]
222 export default routes 243 export default routes
......
1 <route lang="yaml">
2 name: contractProgress
3 </route>
4
5 <script lang="ts" setup name="contractProgress">
6 import { ref } from 'vue';
7 import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
8 import {
9 getContractList,
10 getParamsList,
11 getTenantList,
12 getOwnerTenantList
13 } from "@/api/modules/dataAsset";
14 import { Plus } from "@element-plus/icons-vue";
15 import TableTools from "@/components/Tools/table_tools.vue";
16 import { useValidator } from '@/hooks/useValidator';
17 import useUserStore from "@/store/modules/user";
18
19 const { proxy } = getCurrentInstance() as any;
20 const userStore = useUserStore();
21 const userData = JSON.parse(userStore.userData)
22 const { required } = useValidator();
23 const contractTypes: any = ref([]);
24
25 /** 交易合同节点 */
26 const tradeContractNodesList: any = ref([]);
27
28 /** 资产合同节点 */
29 const registerContractNodesList: any = ref([]);
30
31 const partyAList: any = ref([]);
32
33 const partyBList: any = ref([]);
34
35 const searchItemList = ref([
36 {
37 type: "input",
38 label: "",
39 field: "contractName",
40 default: "",
41 maxlength: 50,
42 placeholder: "合同名称",
43 clearable: true,
44 },
45 {
46 label: "",
47 type: "select",
48 placeholder: "合同类型",
49 field: "contractTypeCode",
50 options: contractTypes.value,
51 default: '',
52 filterable: true,
53 clearable: true,
54 },
55 {
56 type: 'select',
57 label: '',
58 field: 'contractNodeCode',
59 default: '',
60 placeholder: '进展阶段',
61 options: [],
62 clearable: true
63 },
64 {
65 type: "date-time",
66 field: "dateRange",
67 default: null,
68 placeholder: "开始日期~结束日期",
69 clearable: true,
70 required: true
71 }
72 ]);
73
74 const page = ref({
75 ...commonPageConfig,
76 contractName: '',
77 contractTypeCode: '',
78 contractNodeCode: '',
79 dateRange: []
80 });
81
82 const toSearch = (val: any, clear: boolean = false) => {
83 page.value.curr = 1;
84 if (clear) {
85 searchItemList.value.map((item) => (item.default = ""));
86 page.value.contractName = '';
87 page.value.contractTypeCode = "";
88 page.value.contractNodeCode = "";
89 page.value.dateRange = [];
90 } else {
91 page.value.contractName = val.contractName;
92 page.value.contractTypeCode = val.contractTypeCode;
93 page.value.contractNodeCode = val.contractNodeCode;
94 page.value.dateRange = val.dateRange;
95 }
96 getTableData();
97 };
98
99 const getTableData = () => {
100 //tableInfo.value.loading = true;
101 // getContractList({
102 // pageSize: page.value.limit,
103 // pageIndex: page.value.curr,
104 // contractName: page.value.contractName,
105 // contractTypeCode: page.value.contractTypeCode,
106 // contractNodeCode: page.value.contractNodeCode,
107 // startDate: page.value.dateRange?.[0] || '',
108 // endDate: page.value.dateRange?.[1] || '',
109 // }).then((res: any) => {
110 // tableInfo.value.loading = false
111 // if (res.code == proxy.$passCode) {
112 // const data = res.data || {}
113 // tableInfo.value.data = data.records || [];
114 // tableInfo.value.page.curr = data.pageIndex;
115 // tableInfo.value.page.rows = data.totalRows || 0;
116 // } else {
117 // proxy.$ElMessage.error(res.msg);
118 // }
119 // })
120 }
121
122 const tableInfo = ref({
123 id: 'contract-data-table',
124 rowKey: 'guid',
125 loading: false,
126 fields: [
127 { label: "合同名称", field: "contractName", width: 180, align: "left" },
128 { label: "合同类型", field: "contractTypeName", width: 140 },
129 { label: "甲方名称", field: "partyAName", width: 180 },
130 { label: "乙方名称", field: "partyBName", width: 180 },
131 { label: "签约日期", field: "signContractDate", width: TableColumnWidth.DATE },
132 ],
133 childFields: [
134 { label: "进展节点", field: "contractNodeName", width: 140, align: "left" },
135 { label: "开始日期", field: "startDate", width: TableColumnWidth.DATE },
136 { label: "结束日期", field: "endDate", width: TableColumnWidth.DATE },
137 { label: "工作内容描述", field: "endDate", width: 280 },
138 ],
139 data: [],
140 page: {
141 type: "normal",
142 rows: 0,
143 ...page.value,
144 }
145 });
146
147 const getNodeSteps = (scope) => {
148 return [];
149 }
150
151 const contractEditFormItems = ref([
152 {
153 label: "合同类型",
154 type: "select",
155 placeholder: "请选择",
156 field: "contractTypeCode",
157 options: contractTypes.value,
158 default: '',
159 filterable: true,
160 clearable: true,
161 required: true,
162 },
163 {
164 type: "input",
165 label: "合同名称",
166 field: "contractName",
167 default: "",
168 maxlength: 50,
169 placeholder: "请输入",
170 clearable: true,
171 required: true,
172 },
173 {
174 label: "甲方名称",
175 type: "select",
176 placeholder: "请选择",
177 field: "partyAGuid",
178 options: partyAList.value,
179 props: {
180 value: 'guid',
181 label: 'tenantName'
182 },
183 default: '',
184 filterable: true,
185 clearable: true,
186 required: true,
187 },
188 {
189 label: "乙方名称",
190 type: "select",
191 placeholder: "请选择",
192 field: "partyBGuid",
193 options: partyBList.value,
194 props: {
195 value: 'guid',
196 label: 'tenantName'
197 },
198 default: '',
199 filterable: true,
200 clearable: true,
201 required: true,
202 },
203 {
204 label: "跟进节点",
205 type: "select",
206 placeholder: "请选择",
207 field: "contractNodeCodes",
208 options: [],
209 props: {
210 value: 'paramValue',
211 label: 'paramName'
212 },
213 multiple: true,
214 default: [],
215 filterable: true,
216 clearable: true,
217 required: true,
218 },
219 {
220 label: '签约日期',
221 type: 'date',
222 placeholder: '请输入',
223 field: 'signContractDate',
224 default: "",
225 unlink: true,
226 disabled: false,
227 clearable: true,
228 required: true
229 },
230 ]);
231
232 const contractEditFormRules = ref({
233 contractTypeCode: [required('请选择合同类型')],
234 contractName: [required('请填写合同名称')],
235 partyAGuid: [required('请选择甲方名称')],
236 partyBGuid: [required('请选择乙方名称')],
237 contractNodeCodes: [required('请选择跟进节点')],
238 signContractDate: [required('请选择签约日期')],
239 });
240
241
242 /** 新增分类的form */
243 const contractEditFormInfo = ref({
244 type: "form",
245 title: "",
246 col: "span",
247 formInfo: {
248 id: "add-class-form",
249 readonly: false,
250 items: contractEditFormItems.value,
251 rules: contractEditFormRules.value,
252 },
253 });
254
255 const drawerRef = ref();
256
257 /** 新增编辑分类。 */
258 const drawerInfo = ref({
259 visible: false,
260 direction: 'rtl',
261 size: 550,
262 header: {
263 title: '新增合同',
264 },
265 type: '',
266 container: {
267 contents: [contractEditFormInfo.value],
268 },
269 footer: {
270 visible: true,
271 btns: [
272 { type: 'default', label: '取消', value: 'cancel' },
273 { type: 'primary', label: '确定', value: 'save', loading: false },
274 ]
275 }
276 })
277
278 const drawerBtnClick = async (btn, info) => {
279 if (btn.value == 'cancel') {
280 drawerInfo.value.visible = false;
281 } else {
282
283 }
284 }
285
286 const drawerSelectChange = (val, row, info) => {
287
288 }
289
290 const handleNodeFileView = (scope) => {
291
292 }
293
294 const handleTableEdit = (scope) => {
295
296 }
297
298 const handleTableDel = (scope) => {
299
300 }
301
302 const handleCreate = () => {
303 drawerInfo.value.visible = true;
304 drawerInfo.value.header.title = '新增合同';
305
306 }
307
308 const nodesInfo: any = ref([]);
309
310 const nodeFormItems = ref([{
311 label: '开始日期',
312 type: 'date',
313 placeholder: '请输入',
314 field: 'startDate',
315 default: "",
316 unlink: true,
317 disabled: false,
318 clearable: true,
319 required: true
320 }, {
321 label: '结束日期',
322 type: 'date',
323 placeholder: '请输入',
324 field: 'endDate',
325 default: "",
326 unlink: true,
327 disabled: false,
328 clearable: true,
329 required: true
330 }, {
331 label: '节点成果上传',
332 tip: '支持格式:xls .xlsx .doc .docx .rar .zip',
333 type: 'upload-file',
334 accept: '.xls, .xlsx, .doc, .docx, .rar, .zip',
335 required: true,
336 block: true,
337 visible: true,
338 default: [],
339 field: 'nodeAchievement',
340 limit: 1,
341 }, {
342 label: '工作内容描述',
343 type: 'textarea',
344 placeholder: '请输入',
345 field: 'description',
346 default: '',
347 clearable: true,
348 },]);
349
350 const nodeFormRules = ref({
351 startDate: [required('请填写开始日期')],
352 endDate: [required('请填写结束日期')],
353 nodeAchievement: [{
354 validator: (rule: any, value: any, callback: any) => {
355 if (!value?.length) {
356 callback(new Error('请上传节点成果附件'))
357 } else {
358 callback();
359 }
360 }, trigger: 'change'
361 }],
362 });
363
364 const addNode = () => {
365
366 }
367
368 onBeforeMount(() => {
369 getParamsList({
370 dictType: "资产合同类型"
371 }).then((res: any) => {
372 contractTypes.value = [];
373 if (res.code == proxy.$passCode) {
374 contractTypes.value = res.data || [];
375 searchItemList.value[1].options = contractTypes.value;
376 contractEditFormItems.value[0].options = contractTypes.value;
377 } else {
378 proxy.$ElMessage.error(res.msg);
379 }
380 })
381 getParamsList({
382 dictType: "登记合同节点"
383 }).then((res: any) => {
384 tradeContractNodesList.value = [];
385 if (res.code == proxy.$passCode) {
386 tradeContractNodesList.value = res.data || [];
387 } else {
388 proxy.$ElMessage.error(res.msg);
389 }
390 })
391 getParamsList({
392 dictType: "交易合同节点"
393 }).then((res: any) => {
394 registerContractNodesList.value = [];
395 if (res.code == proxy.$passCode) {
396 registerContractNodesList.value = res.data || [];
397 } else {
398 proxy.$ElMessage.error(res.msg);
399 }
400 })
401 getTenantList({
402 bizState: 'Y',
403 pageSize: -1
404 }).then((res: any) => {
405 partyAList.value = [];
406 if (res.code == proxy.$passCode) {
407 partyAList.value = res.data?.records || [];
408 contractEditFormItems.value[2].options = partyAList.value;
409 } else {
410 proxy.$ElMessage.error(res.msg);
411 }
412 })
413 getOwnerTenantList(userData.userGuid).then((res: any) => {
414 partyAList.value = [];
415 if (res.code == proxy.$passCode) {
416 partyBList.value = res.data || [];
417 contractEditFormItems.value[3].options = partyBList.value;
418 } else {
419 proxy.$ElMessage.error(res.msg);
420 }
421 })
422 })
423
424 </script>
425
426 <template>
427 <div class="container_wrap">
428 <div class="table_tool_wrap">
429 <TableTools :searchItems="searchItemList" :searchId="'contract-data-search'" @search="toSearch" :init="true" />
430 </div>
431 <div class="tools_btns">
432 <el-button type="primary" @click="handleCreate">新增</el-button>
433 </div>
434 <div class="table_panel_wrap">
435 <el-table v-loading="tableInfo.loading" ref="tableRef" :data="tableInfo.data" :highlight-current-row="true" stripe
436 border height="100%" tooltip-effect="light" row-key="guid"
437 :style="{ width: '100%', height: 'calc(100% - 8px)', marginTop: '8px', display: 'inline-block', }">
438 <el-table-column type="expand">
439 <template #default="scope">
440 <el-table ref="fieldsTableRef" :data="scope.row.contractNodes" :highlight-current-row="true" stripe border
441 height="100%" tooltip-effect="light" :style="{
442 width: '100%',
443 'max-height': '100%',
444 display: 'inline-block',
445 }">
446 <el-table-column label="序号" type="index" width="56px" align="center" show-overflow-tooltip>
447 </el-table-column>
448 <el-table-column v-for="field in tableInfo.childFields" :prop="field.field" :label="field.label"
449 :width="field.width" :align="field.align" show-overflow-tooltip>
450 <template #default="scope">
451 <span>{{ scope.row[field.field || ''] || '--' }}</span>
452 </template>
453 </el-table-column>
454 <el-table-column label="附件信息" minWidth="120px" align="left" fixed="right" show-overflow-tooltip>
455 <template #default="scope">
456 <span class="text_btn" @click="handleNodeFileView(scope)">查看</span>
457 </template>
458 </el-table-column>
459 </el-table>
460 </template>
461 </el-table-column>
462 <el-table-column label="序号" type="index" width="56px" align="center" show-overflow-tooltip>
463 </el-table-column>
464 <el-table-column v-for="field in tableInfo.fields" :prop="field.field" :label="field.label" :width="field.width"
465 :align="field.align" show-overflow-tooltip>
466 <template #default="scope">
467 <span>{{ scope.row[field.field || ''] || '--' }}</span>
468 </template>
469 </el-table-column>
470 <el-table-column label="进展阶段" width="320px" align="center">
471 <template #default="scope">
472 <div class="custom-steps" v-if="scope.row.contractNodes?.length">
473 <StepBar :steps-info="getNodeSteps(scope)" />
474 </div>
475 <span v-else>--</span>
476 </template>
477 </el-table-column>
478 <el-table-column label="操作" minWidth="120px" align="left" fixed="right" show-overflow-tooltip>
479 <template #default="scope">
480 <span class="text_btn" @click="handleTableEdit(scope)">编辑</span>
481 <span class="text_btn ml4" @click="handleTableDel(scope)">删除</span>
482 </template>
483 </el-table-column>
484 </el-table>
485 </div>
486 <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" ref="drawerRef"
487 @drawerSelectChange='drawerSelectChange'>
488 <!-- 传递到 Form 组件中的默认插槽 -->
489 <template v-slot:default>
490 <template v-if="drawerRef.getDrawerConRef()?.formInline?.contractNodeCodes?.length > 0">
491 <div class="title-label">进展阶段录入</div>
492 <!-- 渲染行 -->
493 <div v-for="(row, index) in nodesInfo" :key="index" class="match-content-wrapper">
494 <div class="title-row"><span>{{ row.contractNodeName }}</span><span>删除</span></div>
495 <Form ref="nodeFormRef" :itemList="nodeFormItems" formId="node-form" :rules="nodeFormRules" col="col2" />
496 </div>
497
498 <!-- 新增按钮 -->
499 <div class="bottm_tools"
500 v-show="nodesInfo.length < drawerRef.getDrawerConRef()?.formInline?.contractNodeCodes?.length"
501 @click="addNode">
502 <el-icon>
503 <Plus />
504 </el-icon>
505 <span>新增规则</span>
506 </div>
507 </template>
508 </template>
509 </Drawer>
510 </div>
511 </template>
512
513 <style lang="scss">
514 .container_wrap {
515 padding: 0 16px;
516 }
517
518 .table_panel_wrap {
519 height: calc(100% - 48px);
520 }
521
522 .ml4 {
523 margin-left: 4px;
524 }
525
526 :deep(.custom-steps) {
527 width: 100%;
528 height: 60px;
529 display: flex;
530
531 .el-steps {
532 width: 100%;
533 }
534 }
535
536 .title-label {
537 margin-bottom: 4px;
538 }
539
540 .bottm_tools {
541 width: 100%;
542 height: 40px;
543 display: flex;
544 justify-content: center;
545 align-items: center;
546 background: #fafafa;
547 color: #999;
548 font-size: 14px;
549 border: 1px dashed var(--el-border-color-regular);
550 margin-bottom: 12px;
551
552 >span {
553 margin-left: 8px;
554 }
555
556 &:hover {
557 background: #EBF6F7;
558 border: 1px dashed var(--el-color-primary);
559 }
560 }
561 </style>
...\ No newline at end of file ...\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!