45435f5f by lihua

企业认证,连接器代码迁移

1 parent c28a06e0
...@@ -98,7 +98,7 @@ VITE_APP_DATA_DELIVERY = http://192.168.6.20:38052/ ...@@ -98,7 +98,7 @@ VITE_APP_DATA_DELIVERY = http://192.168.6.20:38052/
98 #数据服务接口地址 98 #数据服务接口地址
99 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service 99 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service
100 100
101 #数字合约接口 101 #数字合约接口,身份认证有关的服务
102 VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service 102 VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service
103 103
104 # 本地访问地址 104 # 本地访问地址
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
37 "html2canvas": "^1.4.1", 37 "html2canvas": "^1.4.1",
38 "html2pdf.js": "^0.12.1", 38 "html2pdf.js": "^0.12.1",
39 "insert-css": "^2.0.0", 39 "insert-css": "^2.0.0",
40 "ip-regex": "^5.0.0",
40 "jquery": "^3.7.1", 41 "jquery": "^3.7.1",
41 "jsencrypt": "^3.3.2", 42 "jsencrypt": "^3.3.2",
42 "lodash-es": "^4.17.21", 43 "lodash-es": "^4.17.21",
......
...@@ -71,6 +71,9 @@ dependencies: ...@@ -71,6 +71,9 @@ dependencies:
71 insert-css: 71 insert-css:
72 specifier: ^2.0.0 72 specifier: ^2.0.0
73 version: 2.0.0 73 version: 2.0.0
74 ip-regex:
75 specifier: ^5.0.0
76 version: 5.0.0
74 jquery: 77 jquery:
75 specifier: ^3.7.1 78 specifier: ^3.7.1
76 version: 3.7.1 79 version: 3.7.1
...@@ -6056,6 +6059,11 @@ packages: ...@@ -6056,6 +6059,11 @@ packages:
6056 resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} 6059 resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
6057 dev: true 6060 dev: true
6058 6061
6062 /ip-regex@5.0.0:
6063 resolution: {integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==}
6064 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
6065 dev: false
6066
6059 /is-absolute@1.0.0: 6067 /is-absolute@1.0.0:
6060 resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} 6068 resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==}
6061 engines: {node: '>=0.10.0'} 6069 engines: {node: '>=0.10.0'}
......
...@@ -588,3 +588,29 @@ export const getDictionaryTree = (params) => request({ ...@@ -588,3 +588,29 @@ export const getDictionaryTree = (params) => request({
588 method: 'post', 588 method: 'post',
589 params 589 params
590 }) 590 })
591
592 /** -------------------- 数据产品目录分类----------- */
593
594 export const addDictClass = (params) => request({
595 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dict/save-class`,
596 method: 'post',
597 data: params
598 })
599
600 export const getDictClass = (params) => request({
601 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dict/get-type-page-list`,
602 method: 'post',
603 data: params
604 })
605
606 export const removeDict = (guids) => request({
607 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dict/del`,
608 method: 'delete',
609 data: guids
610 });
611
612 export const getDictData = (params) => request({
613 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dict/get-tree`,
614 method: 'post',
615 data: params
616 })
...\ No newline at end of file ...\ No newline at end of file
......
1 import request from "@/utils/request";
2
3 // 最后一级节点审批通过
4 export const contractApprove = (params, serviceTenantGuid:any = null) => request({
5 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/data-contract/submit-flow${serviceTenantGuid?`?serviceTenantGuid=${serviceTenantGuid}`:''}`,
6 method: 'post',
7 data: params
8 })
9
10 /** 企业认证 **/
11 // 企业认证分页
12 export const getEnterpriseList = (params) => request({
13 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/page-list`,
14 method: 'post',
15 data: params
16 })
17
18 // 企业认证详情
19 export const getEnterpriseDetail = (params) => request({
20 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail`,
21 method: 'get',
22 params
23 })
24
25 // 企业认证新增
26 export const enterpriseSave = (params) => request({
27 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/save`,
28 method: 'post',
29 data: params
30 })
31
32 // 企业认证修改
33 export const enterpriseUpdate = (params) => request({
34 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/update`,
35 method: 'put',
36 data: params
37 })
38
39 // 企业认证删除
40 export const enterpriseDelete = (params) => request({
41 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/delete`,
42 method: 'delete',
43 data: params
44 })
45
46 // 企业认证变更删除
47 export const enterpriseChangeDelete = (params) => request({
48 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/change/delete`,
49 method: 'delete',
50 data: params
51 })
52
53 // 企业认证最后一级审批
54 export const enterpriseApprove = (params) => request({
55 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/last-approve`,
56 method: 'post',
57 data: params
58 })
59
60 // 企业认证进度列表
61 export const getTaskGressList = (params) => request({
62 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/page-list`,
63 method: 'post',
64 data: params
65 })
66
67 // 企业认证重新发起
68 export const getTaskRestart = (params) => request({
69 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/restart`,
70 method: 'get',
71 params
72 })
73
74 // 企业认证执行日志
75 export const getTaskExecutionLog = (params) => request({
76 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/task-info`,
77 method: 'get',
78 params
79 })
80
81 // 获取企业认证流程列表
82 export const getFlowEnterpriseList = (params) => request({
83 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/flow/page-list`,
84 method: 'post',
85 data: params
86 })
87
88 // 获取企业信息
89 export const getUserTenant = () => request({
90 // url: `http://localhost:9000/master/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
91 url: `http://192.168.6.20:18052/master/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
92 method: 'get'
93 })
94
95 // 获取企业信息
96 export const getEnterpriseData = (params) => request({
97 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail-by-logonUser`,
98 method: 'get',
99 params
100 })
101
102 /** -------------------- 连接器管理 -------------------------- */
103
104 // 连接器分页
105 export const getConnectorList = (params) => request({
106 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/page-list`,
107 method: 'post',
108 data: params
109 })
110
111 /** 保存 */
112 export const saveConnector = (params) => request({
113 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/save`,
114 method: 'post',
115 data: params
116 })
117
118 /** 更新 */
119 export const updateConnector = (params) => request({
120 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/update`,
121 method: 'put',
122 data: params
123 })
124
125 /** 变更的重新提交 */
126 export const changeSaveConnector = (params) => request({
127 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/change-save`,
128 method: 'post',
129 data: params
130 })
131
132 /** 删除 */
133 export const deleteConnector = (params) => request({
134 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/delete`,
135 method: 'delete',
136 data: params
137 })
138
139 export const getConnectorDetail = (guid) => request({
140 url: `${import.meta.env.VITE_APP_CIRCULATION_PORTAL_URL}/tds-connector-identity/detail?guid=${guid}`,
141 method: 'get'
142 })
143
144 /** 判断当前用户企业是否已申请连接器 */
145 export const checkConnector = () => request({
146 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/tds-connector-identity/check-connector `,
147 method: 'get'
148 })
149
150 /** 接入方式下拉列表 */
151 export const assessMethodList = [
152 {
153 label: "专线",
154 value: 1,
155 },
156 {
157 label: "互联网(固定公网IP)",
158 value: 2,
159 },
160 {
161 label: "互联网(无固定公网IP)",
162 value: 3,
163 },
164 {
165 label: "高速数据网",
166 value: 4,
167 },
168 {
169 label: "其他",
170 value: 5,
171 },
172 ]
...\ No newline at end of file ...\ No newline at end of file
...@@ -345,3 +345,9 @@ export const checkSql = (params) => request({ ...@@ -345,3 +345,9 @@ export const checkSql = (params) => request({
345 method: 'post', 345 method: 'post',
346 data:params 346 data:params
347 }) 347 })
348
349 export const getUserSomeInfo = (params) => request({
350 url: `/ms-daop-user-service/user/data/get-some-info`,
351 method: 'post',
352 data: params
353 })
......
...@@ -83,3 +83,21 @@ export const isNeedApprove = (params) => request({ ...@@ -83,3 +83,21 @@ export const isNeedApprove = (params) => request({
83 url: `${import.meta.env.VITE_APP_WORK_FLOW_URL}/func-flow-config/is-need-approve?funcCode=${params.funcCode}`, 83 url: `${import.meta.env.VITE_APP_WORK_FLOW_URL}/func-flow-config/is-need-approve?funcCode=${params.funcCode}`,
84 method: 'get', 84 method: 'get',
85 }) 85 })
86
87 export const changeApproveSave = (params)=>request({
88 url: `${import.meta.env.VITE_APP_WORK_FLOW_URL}/changeApprove/save`,
89 method: 'post',
90 data: params
91 })
92
93 export const myLastNode = (params) => request({
94 url: `${import.meta.env.VITE_APP_WORK_FLOW_URL}/work-flow/data/is-my-last-node`,
95 method: 'post',
96 data: params
97 })
98
99 // 获取最新变更信息
100 export const getLastChange = (params) => request({
101 url: `${import.meta.env.VITE_APP_WORK_FLOW_URL}/changeApprove/get-by-guid/${params}`,
102 method: 'get'
103 })
...\ No newline at end of file ...\ No newline at end of file
......
1 /** form表单检验规则钩子函数 */ 1 /** form表单检验规则钩子函数 */
2 import { FormItemRule } from 'element-plus' 2 import { FormItemRule } from 'element-plus'
3 import { cnIdCode, StringUtils } from '@/utils/validation'
4 import ipRegex from 'ip-regex';
3 5
4 export const useValidator = () => { 6 export const useValidator = () => {
5 const required = (message?: string): FormItemRule => { 7 const required = (message?: string): FormItemRule => {
...@@ -187,6 +189,33 @@ export const useValidator = () => { ...@@ -187,6 +189,33 @@ export const useValidator = () => {
187 trigger: "blur", 189 trigger: "blur",
188 }; 190 };
189 } 191 }
192
193 const isUSCCCode = (message?: string): FormItemRule => {
194 return {
195 validator: (_, val, callback) => {
196 if (val && !StringUtils.checkUnifiedCreditCode(val).success) {
197 callback(new Error(message || StringUtils.checkUnifiedCreditCode(val).errorMessage || '统一社会信用代码格式不正确!'))
198 } else {
199 callback()
200 }
201 },
202 trigger: 'blur'
203 }
204 }
205
206 const idCode = (message?: string): FormItemRule => {
207 return {
208 validator: (_, val, callback) => {
209 if (val && !cnIdCode(val)) {
210 callback(new Error(message || '身份证格式不正确!'))
211 } else {
212 callback()
213 }
214 },
215 trigger: 'blur',
216 }
217 }
218
190 /** 验证输入的多个IP地址 */ 219 /** 验证输入的多个IP地址 */
191 const validateIPList = (): FormItemRule => { 220 const validateIPList = (): FormItemRule => {
192 return { 221 return {
...@@ -303,6 +332,8 @@ export const useValidator = () => { ...@@ -303,6 +332,8 @@ export const useValidator = () => {
303 scrollToError, 332 scrollToError,
304 checkExistName, 333 checkExistName,
305 requiredFiles, 334 requiredFiles,
335 isUSCCCode,
336 idCode,
306 validateIPList, 337 validateIPList,
307 validateDomainList 338 validateDomainList
308 } 339 }
......
1 import type { RouteRecordRaw } from 'vue-router'
2 function Layout() {
3 return import('@/layouts/index.vue')
4 }
5 const routes: RouteRecordRaw[] = [
6 {
7 path: '/data-facilitator/authentication-management',
8 component: Layout,
9 meta: {
10 title: '认证管理',
11 icon: 'sidebar-videos',
12 },
13 children: [{
14 path: '',
15 name: 'authenticationManagement',
16 component: () => import('@/views/data_facilitator/authenticationManagement.vue'),
17 meta: {
18 title: '认证管理',
19 sidebar: false,
20 breadcrumb: false,
21 cache: true,
22 editPage: true
23 },
24 }]
25 },
26 {
27 path: '/data-facilitator/certification-audit',
28 component: Layout,
29 meta: {
30 title: '认证审核管理',
31 icon: 'sidebar-videos',
32 },
33 children: [
34 {
35 path: '',
36 name: 'certificationAudit',
37 component: () => import('@/views/data_facilitator/certificationAudit.vue'),
38 meta: {
39 title: '认证审核管理',
40 sidebar: false,
41 breadcrumb: false,
42 cache: true
43 },
44 },
45 {
46 path: 'certification-audit-detail',
47 name: 'certificationAuditDetail',
48 component: () => import('@/views/data_facilitator/certificationAuditDetail.vue'),
49 meta: {
50 title: '详情-',
51 sidebar: false,
52 breadcrumb: false,
53 cache: true,
54 },
55 beforeEnter: (to, from) => {
56 to.meta.title = `详情-${to.query.name}`;
57 }
58 }
59 ]
60 },
61 {
62 path: '/data-connector/settle-management',
63 component: Layout,
64 meta: {
65 title: '连接器管理',
66 icon: 'sidebar-videos',
67 },
68 children: [{
69 path: '',
70 name: 'settleManagement',
71 component: () => import('@/views/data_facilitator/settleManagement.vue'),
72 meta: {
73 title: '',
74 sidebar: false,
75 breadcrumb: false,
76 cache: true,
77 editPage: true
78 },
79 }, {
80 path: 'settle-start',
81 name: 'settleStart',
82 component: () => import('@/views/data_facilitator/settleStart.vue'),
83 meta: {
84 title: '连接器入驻',
85 sidebar: false,
86 breadcrumb: false,
87 cache: true,
88 editPage: true,
89 reuse: true
90 },
91 beforeEnter: (to, from) => {
92 to.meta.title = !to.query.guid ? '连接器入驻' : (to.query.isChange == 'Y' ? `变更-${to.query.name}` : `编辑-${to.query.name}`);
93 to.meta.editPage = true;
94 }
95 }, {
96 path: 'settle-detail',
97 name: 'settleDetail',
98 component: () => import('@/views/data_facilitator/settleDetail.vue'),
99 meta: {
100 title: '详情-',
101 sidebar: false,
102 breadcrumb: false,
103 cache: true,
104 reuse: true
105 },
106 beforeEnter: (to, from) => {
107 to.meta.title = `详情-${to.query.name}`;
108 }
109 },]
110 },
111 ]
112 export default routes
...@@ -4,6 +4,7 @@ import type { RouteRecordRaw } from 'vue-router' ...@@ -4,6 +4,7 @@ import type { RouteRecordRaw } from 'vue-router'
4 import DataAssess from './modules/dataAsset'; 4 import DataAssess from './modules/dataAsset';
5 import DataService from './modules/dataService'; 5 import DataService from './modules/dataService';
6 import DataSmartContract from './modules/dataSmartContract'; 6 import DataSmartContract from './modules/dataSmartContract';
7 import DataFacilitator from './modules/dataFacilitator';
7 8
8 import useSettingsStore from '@/store/modules/settings' 9 import useSettingsStore from '@/store/modules/settings'
9 10
...@@ -93,6 +94,7 @@ const asyncRoutes: RouteRecordRaw[] = [ ...@@ -93,6 +94,7 @@ const asyncRoutes: RouteRecordRaw[] = [
93 ...DataAssess, 94 ...DataAssess,
94 ...DataService, 95 ...DataService,
95 ...DataSmartContract, 96 ...DataSmartContract,
97 ...DataFacilitator,
96 // ...DataAssetRegistry, 98 // ...DataAssetRegistry,
97 ] 99 ]
98 100
......
1 const useDataConnectorStore = defineStore(
2 'isRefresh',
3 () => {
4 const isRefresh = ref<boolean>(false)
5
6 function set(v: boolean) {
7 isRefresh.value = v;
8 }
9
10 return {
11 isRefresh,
12 set,
13 }
14 },
15 )
16
17 export default useDataConnectorStore
...\ No newline at end of file ...\ No newline at end of file
...@@ -33,7 +33,7 @@ const useUserStore = defineStore( ...@@ -33,7 +33,7 @@ const useUserStore = defineStore(
33 function getToken(data, state) { 33 function getToken(data, state) {
34 data.platformGuid = "7f16f697aec111ef8656fa163e60becd"; 34 data.platformGuid = "7f16f697aec111ef8656fa163e60becd";
35 data.userType = 2; 35 data.userType = 2;
36 data.appKey = '691689d8e4b0f359c04d204a'; 36 // data.appKey = '691689d8e4b0f359c04d204a';
37 data.validateUri = location.origin == 'http://localhost:9000' ? 'http://localhost:9000/' : location.origin + '/'; 37 data.validateUri = location.origin == 'http://localhost:9000' ? 'http://localhost:9000/' : location.origin + '/';
38 return getTokenPromise.value = getTokenByCode(data).then((res: any) => { 38 return getTokenPromise.value = getTokenByCode(data).then((res: any) => {
39 getTokenPromise.value = null; 39 getTokenPromise.value = null;
......
1 import moment from "moment";
2
3 const normalize = (id) => {
4 let re;
5
6 re = /\[-\/\s]/g;
7
8 id = id.toUpperCase().replace(re, "");
9
10 re = /\([A-Z0-9]\)$/;
11
12 if (re.test(id)) {
13 id = id.replace(/\[\(\)]/g, "");
14 }
15
16 return id;
17 };
18
19 const isDateValid = (idDate, minDate, maxDate) => {
20 let isFormatValid, parseDate;
21
22 if (minDate == null) {
23 minDate = "default";
24 }
25
26 if (maxDate == null) {
27 maxDate = "today";
28 }
29
30 if (minDate === "default" || minDate === "") {
31 minDate = "18991129";
32 }
33
34 isFormatValid = function (date) {
35 return typeof date === "string" && /^[0-9]{8}$/.test(date);
36 };
37
38 if (!isFormatValid(idDate)) {
39 return false;
40 }
41
42 if (!isFormatValid(minDate)) {
43 return false;
44 }
45
46 parseDate = function (input) {
47 let date,
48 day,
49 isDayValid,
50 isFutureDate,
51 isLeapYear,
52 isMonthValid,
53 maxDay,
54 month,
55 startIndex,
56 year;
57
58 startIndex = 0;
59
60 year = +input.substring(startIndex, (startIndex += 4));
61
62 month = input.substring(startIndex, (startIndex += 2));
63
64 day = +input.substring(startIndex, (startIndex += 2));
65
66 date = new Date(year, +month - 1, day);
67
68 maxDay =
69 "01,03,05,07,08,10,12".indexOf(month) >= 0
70 ? 31
71 : "04,06,09,11".indexOf(month) >= 0
72 ? 30
73 : ((isLeapYear =
74 (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0),
75 isLeapYear ? 29 : 28);
76
77 isDayValid = day > 0 && day <= maxDay;
78
79 if (!isDayValid) {
80 return false;
81 }
82
83 isMonthValid = +month > 0 && +month <= 12;
84
85 if (!isMonthValid) {
86 return false;
87 }
88
89 isFutureDate = new Date() < date;
90
91 if (isFutureDate) {
92 return false;
93 }
94
95 return date;
96 };
97
98 idDate = parseDate(idDate);
99
100 if (idDate === false) {
101 return false;
102 }
103
104 minDate = parseDate(minDate);
105
106 if (minDate === false) {
107 return false;
108 }
109
110 maxDate =
111 maxDate === "today"
112 ? new Date()
113 : typeof maxDate === "string"
114 ? parseDate(maxDate)
115 : maxDate;
116
117 if (maxDate === false) {
118 return false;
119 }
120
121 return idDate >= minDate && idDate <= maxDate;
122 };
123
124 const getMaxDate = (yearsOld) => {
125 let now, year;
126
127 now = new Date();
128
129 year = now.getFullYear() - yearsOld;
130
131 return new Date(year, now.getMonth(), now.getDate());
132 };
133
134 /**
135 * 身份证校验函数
136 * @param id
137 * @returns
138 */
139 export const cnIdCode = (id) => {
140 let isChecksumValid, isDateValidFn, isFormatValid, isLengthValid
141
142 isLengthValid = function (id) {
143
144 return id.length === 18
145
146 }
147
148 isFormatValid = function (id) {
149
150 return /^[0-9]{17}[0-9X]$/.test(id)
151
152 }
153
154 isDateValidFn = function () {
155 return isDateValid(id.substring(6, 14), '18860625',null)
156 }
157
158 isChecksumValid = function (id) {
159
160 let char, checkDigit, getWeight, i, identifier, index, len, remainder, weightedSum
161
162 identifier = id.slice(0, -1)
163
164 checkDigit = id.slice(-1) === 'X' ? 10 : +id.slice(-1)
165
166 getWeight = function (n) {
167
168 return Math.pow(2, n - 1) % 11
169
170 }
171
172 weightedSum = 0
173
174 index = id.length
175
176 for (i = 0, len = identifier.length; i < len; i++) {
177
178 char = identifier[i]
179
180 weightedSum += +char * getWeight(index)
181
182 index--
183
184 }
185
186 remainder = (12 - weightedSum % 11) % 11 - checkDigit
187
188 return remainder === 0
189
190 }
191
192 id = normalize(id)
193
194 return isLengthValid(id) && isFormatValid(id) && isDateValidFn() && isChecksumValid(id)
195 };
196
197 /**
198 * 校验工具类
199 */
200 export class StringUtils {
201
202 constructor() {
203 }
204
205 /**
206 * 判断是空字符串?
207 * @param str
208 */
209 static isBlank(str: string) {
210 return str === undefined || str === null || '' === str.trim();
211 }
212
213 /**
214 * 去空格
215 * @param str 处理字符串
216 * @return 结果字符串
217 */
218 static trim(str: string) {
219 return str.replace('\n', '').replace(' ', '').trim();
220 }
221
222 /**
223 * 判断不是空字符串?
224 * @param str
225 */
226 static isNotBlank(str: string) {
227 return !this.isBlank(str);
228 }
229
230 /**
231 * 判断是空?
232 * @param o
233 */
234 static isEmpty(o) {
235 return o === null || o === 'null' || o === undefined || o === 'undefined' || o === '';
236 }
237
238 /**
239 * 判断不是空?
240 * @param o
241 */
242 static isNotEmpty(o) {
243 return !this.isEmpty(o);
244 }
245
246 /**
247 * 校验身份证的
248 * @param code
249 */
250 public static identityCodeValid(code): ProcessResult {
251 // 判断是否为空 长度是否合法
252 if (this.isBlank(code) || code.length !== 18) {
253 return new ProcessResult(false, '身份证长度不够');
254 }
255 code = this.trim(code);
256 // 身份证号格式错误
257 if (!code || !/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(code)) {
258 return new ProcessResult(false, '身份证不合法');
259 }
260 // 省份对应的省编码
261 const city = {
262 11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江', 31: '上海',
263 32: '江苏', 33: '浙江', 34: '安徽', 35: '福建', 36: '江西', 37: '山东', 41: '河南', 42: '湖北', 43: '湖南',
264 44: '广东', 45: '广西', 46: '海南', 50: '重庆', 51: '四川', 52: '贵州', 53: '云南', 54: '西藏', 61: '陕西',
265 62: '甘肃', 63: '青海', 64: '宁夏', 65: '新疆', 71: '台湾', 81: '香港', 82: '澳门', 91: '国外'
266 };
267 if (!city[code.substr(0, 2)]) {
268 // 地址编码错误
269 return new ProcessResult(false, '身份证前2为输入有误');
270 } else {
271 // 18位身份证需要验证最后一位校验位
272 code = code.split('');
273 // 身份证最后一位
274 const lastOneCode = code[17];
275 // 加权因子 ∑(ai×Wi)(mod 11)
276 const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
277 // 校验位
278 const parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
279 let sum = 0;
280 let ai = 0;
281 let wi = 0;
282 // 取前17位,(每一位数字 * 每一位数字在加权因子数组的对应的数字) 之和
283 for (let i = 0; i < 17; i++) {
284 ai = code[i];
285 wi = factor[i];
286 sum += ai * wi;
287 }
288 // 算出来的和 mod 11 得到 最后一位,再把传进来的身份证的最后一位和算出来的最后一位对比
289 return new ProcessResult(parity[sum % 11] === lastOneCode, '身份证不合法');
290 }
291 }
292
293 /**
294 * 身份证自定义校验器
295 */
296 public static idCardNoValidator() {
297 return (control): { [key: string]: any } | null => {
298 const processResult = this.identityCodeValid(control.value);
299 return processResult.isSuccess() ? null : {idCardError: {value: control.value, message: processResult.errorMessage}};
300 };
301 }
302
303 /**
304 * 统一社会信用代码自定义校验器
305 */
306 public static isValidUSCC() {
307 return (control): { [key: string]: any } | null => {
308 const processResult = this.checkUnifiedCreditCode(control.value);
309 return processResult.isSuccess() ? null : {unifiedCreditCodeError: {value: control.value, message: processResult.errorMessage}};
310 };
311 }
312
313 /**
314 * 统一社会信用代码校验
315 * @param uniCode
316 */
317 public static checkUnifiedCreditCode(uniCode: string): ProcessResult {
318 // 假如不是18位,错误
319 if (!uniCode || uniCode.length !== 18) {
320 return new ProcessResult(false, '统一社会信用代码长度不合法');
321 }
322 uniCode = this.trim(uniCode);
323 // 统一社会信用代码由18位阿拉伯数字或英文大写字母表示(不包括I,O,Z,S,V以防止和阿拉伯字母混淆)-->V:???关我毛事?
324 const upUniCode = uniCode.toUpperCase();
325 if (upUniCode.indexOf('I') !== -1 || upUniCode.indexOf('O') !== -1 || upUniCode.indexOf('Z') !== -1 || upUniCode.indexOf('S') !== -1 || upUniCode.indexOf('V') !== -1) {
326 return new ProcessResult(false, '统一社会信用代码不能含有(I,O,Z,S,V)');
327 }
328 // (组织机构代码)校验
329 const orgCheckCode = [
330 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
331 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
332 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
333 'U', 'V', 'W', 'X', 'Y', 'Z'
334 ];
335 // 组织机构代码加权因子
336 const orgWeight = [3, 7, 9, 10, 5, 8, 4, 2];
337 const orgCode = uniCode.substring(8, 17);
338 let sumOrg = 0;
339 // 去前8位数 每一位数对应在orgWeight数组的下标 * 对应的加权因子 之和
340 for (let i = 0; i < 8; i++) {
341 const tmpAttr = orgCode[i] as any;
342 const tmpCode = orgCheckCode.indexOf(tmpAttr);
343 const tmpWeight = orgWeight[i];
344 sumOrg += (tmpCode * tmpWeight);
345 }
346 // 再用11 - 算出的合数 mod 11
347 const modOrg = 11 - sumOrg % 11;
348 // 再用算出来的数字转换成最后一位的数字 拿到最后一个字符
349 const modOrgLast = (modOrg === 10) ? 'X' : ((modOrg === 11) ? '0' : ('' + modOrg));
350 // 对比算出来的最后一位是否等于给我的组织机构代码的最后一位
351 if (modOrgLast !== orgCode[8]) {
352 return new ProcessResult(false, '统一社会信用代码中的组织机构代码不合法');
353 }
354 // 最后一位的校验 (A=10, B=11,以此类推)
355 const uniCheckCode = [
356 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
357 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q',
358 'R', 'T', 'U', 'W', 'X', 'Y'
359 ];
360 // 统一社会信用代码加权因子
361 const uniCodeWeight = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
362 let sumUniCode = 0;
363 // 去前17位数 每一位数对应在uniCheckCode数组的下标 * 对应的加权因子 之和
364 for (let i = 0; i < 17; i++) {
365 const tmpAttr = uniCode[i] as any;
366 const tmpCode = uniCheckCode.indexOf(tmpAttr);
367 const tmpWeight = uniCodeWeight[i];
368 sumUniCode += (tmpCode * tmpWeight);
369 }
370 // 再用31 - 算出的合数 mod 31
371 const modOrgUni = 31 - sumUniCode % 31;
372 // 在uniCheckCode数组找出对应的字符就是最后一位
373 const modOrgUniLast = uniCheckCode[modOrgUni % 31];
374 // 对比算出来的最后一位是否等于给我的信用代码的最后一位
375 return new ProcessResult(modOrgUniLast + '' === uniCode[17] + '', '统一社会信用代码不合法');
376 }
377
378 /**
379 * 根据身份证号码获取生日年龄性别
380 */
381 public static getIdCardInformation(idCardNo): IdCardInformation {
382 const processResult = this.identityCodeValid(idCardNo);
383 if (processResult.isFailure()) {
384 return new IdCardInformation(undefined, undefined, undefined);
385 }
386 // 区分二代身份证
387 const mark = idCardNo.length > 15;
388 // 获取身份证上的出生日期
389 const birthday = moment(idCardNo.substring(6, mark ? 14 : 11), 'YYYYMMDD').toDate();
390 // 算出年龄
391 const age = new Date().getFullYear() - birthday.getFullYear();
392 // 得出年龄
393 const gender = !(Number(idCardNo.charAt(mark ? 16 : 14)) % 2 === 0);
394 // 返回身份证信息
395 return new IdCardInformation(birthday, age, gender);
396 }
397
398 public static isValidBankCard(cardNumber):ProcessResult {
399 // 银行卡号长度检查,一般16-19位
400 if (!/^\d{16,19}$/.test(cardNumber)) {
401 return new ProcessResult(false, '银行卡号格式/长度不正确');
402 }
403
404 // Luhn算法校验
405 let sum = 0;
406 let shouldDouble = false;
407 for (let i = cardNumber.length - 1; i >= 0; i--) {
408 let digit = parseInt(cardNumber.charAt(i), 10);
409 if (shouldDouble) {
410 digit *= 2;
411 if (digit > 9) {
412 digit -= 9;
413 }
414 }
415 sum += digit;
416 shouldDouble = !shouldDouble;
417 }
418 return new ProcessResult(sum % 10 === 0, '银行卡号格式不正确');
419 }
420 }
421
422 /**
423 * 身份证信息
424 */
425 class IdCardInformation {
426
427 /**
428 * 出生日期
429 */
430 birthday: Date;
431
432 /**
433 * 年龄
434 */
435 age: number;
436
437 /**
438 * 性别
439 */
440 gender: boolean;
441
442 constructor(birthday: Date, age: number, gender: boolean) {
443 this.birthday = birthday;
444 this.age = age;
445 this.gender = gender;
446 }
447 }
448
449 /**
450 * 处理结果
451 */
452 class ProcessResult {
453
454 /**
455 * 成功?
456 */
457 success: boolean;
458
459 /**
460 * 错误信息
461 */
462 errorMessage: string;
463
464 constructor(success: boolean, errorMessage: string) {
465 this.success = success;
466 this.errorMessage = errorMessage;
467 }
468
469 /**
470 * 是成功的?
471 */
472 isSuccess() {
473 return this.success;
474 }
475
476 /**
477 * 是失败的?
478 */
479 isFailure() {
480 return !this.success;
481 }
482 }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
6 <el-input class="tree_search_input" v-model="asidePage.searchKey" @change="asideSearch()" 6 <el-input class="tree_search_input" v-model="asidePage.searchKey" @change="asideSearch()"
7 :placeholder="asidePage.queryPlaceholder" :prefix-icon="SearchIcon" clearable /> 7 :placeholder="asidePage.queryPlaceholder" :prefix-icon="SearchIcon" clearable />
8 <el-button class="tree_add" :icon="Plus" @click="loadAsideDialog">{{ asidePage.addButtonText }}</el-button> 8 <el-button class="tree_add" :icon="Plus" @click="loadAsideDialog">{{ asidePage.addButtonText }}</el-button>
9 <el-table ref="asideTable" style="height: calc(100% - 90px);" :data="asideTableData" highlight-current-row 9 <el-table v-loading="leftTableLoading" ref="asideTable" style="height: calc(100% - 90px);" :data="asideTableData"
10 :show-header="false" @row-click="searchDict"> 10 highlight-current-row :show-header="false" @row-click="searchDict">
11 11
12 <el-table-column prop="dictTypeName"> 12 <el-table-column prop="dictTypeName">
13 <template #default="scope"> 13 <template #default="scope">
...@@ -42,9 +42,9 @@ ...@@ -42,9 +42,9 @@
42 <!-- 列表区域 start --> 42 <!-- 列表区域 start -->
43 <div class="main_wrap"> 43 <div class="main_wrap">
44 <div class="table_tool_wrap"> 44 <div class="table_tool_wrap">
45 <TableTools :searchItems="searchItemList" :searchId="'user-manage-search'" @search="toSearch" /> 45 <TableTools :searchItems="searchItemList" :searchId="'user-manage-search'" :init="false" @search="toSearch" />
46 <div class="tools_btns"> 46 <div class="tools_btns">
47 <el-button type="primary" @click="loadDialog" v-preReClick>添加规则</el-button> 47 <el-button type="primary" @click="loadDialog" v-preReClick>添加目录</el-button>
48 <el-button @click="batchDelete">批量删除</el-button> 48 <el-button @click="batchDelete">批量删除</el-button>
49 </div> 49 </div>
50 </div> 50 </div>
...@@ -73,47 +73,39 @@ import { Plus, Edit, Delete, Search as SearchIcon } from "@element-plus/icons-vu ...@@ -73,47 +73,39 @@ import { Plus, Edit, Delete, Search as SearchIcon } from "@element-plus/icons-vu
73 import TableTools from '@/components/Tools/table_tools.vue'; 73 import TableTools from '@/components/Tools/table_tools.vue';
74 import { commonPageConfig } from "@/components/PageNav"; 74 import { commonPageConfig } from "@/components/PageNav";
75 import { useValidator } from '@/hooks/useValidator'; 75 import { useValidator } from '@/hooks/useValidator';
76 import {
77 addDictClass,
78 getDictClass,
79 removeDict,
80 getDictData,
81 } from "@/api/modules/dataAsset";
76 82
77 const { required } = useValidator(); 83 const { required } = useValidator();
78 const { proxy } = getCurrentInstance() as any; 84 const { proxy } = getCurrentInstance() as any;
79 85
80 const leftTableLoading = ref(false) 86 const leftTableLoading = ref(false)
81 87
82 const submitForm = async () => {
83 let res1 = await formItem1.value.submitForm()
84 console.log("submitForm111", res1);
85
86 if (res1) {
87 let resultForm1 = await formItem1.value.getData()
88 resultForm1.remarks = resultForm1.remarks || '';
89 let message = resultForm1.guid ? '修改成功' : '新增成功'
90 // dictApi.addDictionary(resultForm1).then(res => {
91 // if (res.data.code === proxy.$passCode) {
92 // proxy.$ElMessage({
93 // type: 'success',
94 // message: message
95 // })
96 // drawerInfo.value.visible = false;
97 // toSearch(params.value)
98 // }
99 // });
100 }
101 }
102 const asideSubmitForm = async () => { 88 const asideSubmitForm = async () => {
103 let resultForm1 = asideDrawerRef.value?.getDrawerConRef('drawerFormRef')?.formInline 89 let resultForm1 = asideDrawerRef.value?.getDrawerConRef('drawerFormRef')?.formInline
104 let message = resultForm1.guid ? '修改成功' : '新增成功' 90 let message = asideDrawerInfo.value.type != 'add' ? '编辑成功' : '新增成功';
105 // dictApi.addDictClass(resultForm1).then(res => { 91 resultForm1.guid = asideDrawerInfo.value.type != 'add' ? currAsideRow.value.guid : '';
106 // if (res.data.code === proxy.$passCode) { 92 asideDrawerInfo.value.footer.btns[1].loading = true;
107 // proxy.$ElMessage({ 93 addDictClass(resultForm1).then((res: any) => {
108 // type: 'success', 94 asideDrawerInfo.value.footer.btns[1].loading = false;
109 // message: message 95 if (res?.code === proxy.$passCode) {
110 // }) 96 proxy.$ElMessage({
111 // asideDrawerInfo.value.visible = false; 97 type: 'success',
112 // asidePage.value.curr = 1; 98 message: message
113 //asidePage.value.searchKey = ''; 99 })
114 // asideSearch() 100 asideDrawerInfo.value.visible = false;
115 // } 101 asidePage.value.curr = 1;
116 // }) 102 asidePage.value.searchKey = '';
103 asideSearch();
104 getAllAsideData();
105 } else {
106 proxy.$ElMessage.error(res?.msg);
107 }
108 })
117 } 109 }
118 110
119 const params = ref({}) 111 const params = ref({})
...@@ -201,6 +193,7 @@ const loadAsideDialog = () => { ...@@ -201,6 +193,7 @@ const loadAsideDialog = () => {
201 // 抽屉逻辑 193 // 抽屉逻辑
202 asideDrawerInfo.value.header.title = '新增分类' 194 asideDrawerInfo.value.header.title = '新增分类'
203 asideDrawerInfo.value.visible = true; 195 asideDrawerInfo.value.visible = true;
196 asideDrawerInfo.value.type = 'add';
204 classEditFormItems.value.forEach(item => { 197 classEditFormItems.value.forEach(item => {
205 item.default = ''; 198 item.default = '';
206 if (item.field == 'bizState') { 199 if (item.field == 'bizState') {
...@@ -223,35 +216,37 @@ const asideSearch = () => { ...@@ -223,35 +216,37 @@ const asideSearch = () => {
223 getAsideTableData(params) 216 getAsideTableData(params)
224 }; 217 };
225 218
219 const asideTable = ref();
220
226 // 获取左边表格 221 // 获取左边表格
227 const getAsideTableData = (params: any) => { 222 const getAsideTableData = (params: any) => {
228 // leftTableLoading.value = true; 223 leftTableLoading.value = true;
229 // dictApi.getDictClass(params).then((res: any) => { 224 getDictClass(params).then((res: any) => {
230 // leftTableLoading.value = false; 225 leftTableLoading.value = false;
231 // if (res.code == proxy.$passCode) { 226 if (res.code == proxy.$passCode) {
232 // let data = res.data || {}; 227 let data = res.data || {};
233 // asideTableData.value = res.data.records ?? []; 228 asideTableData.value = res.data.records ?? [];
234 // asidePage.value.limit = data.pageSize; 229 asidePage.value.limit = data.pageSize;
235 // asidePage.value.curr = data.pageIndex; 230 asidePage.value.curr = data.pageIndex;
236 // // asidePage.value.totalPage = data.totalPages; 231 // asidePage.value.totalPage = data.totalPages;
237 // asidePage.value.total = data.totalRows; 232 asidePage.value.total = data.totalRows;
238 233
239 // if (asideTableData.value.length > 0) { 234 if (asideTableData.value.length > 0) {
240 // let row = asideTableData.value[0] 235 let row = asideTableData.value[0]
241 // proxy.$refs['asideTable'].setCurrentRow(row); 236 asideTable.value?.setCurrentRow(row);
242 // // 点击分类 237 // 点击分类
243 // dictType.value = row.dicName 238 dictType.value = row.dicName
244 // classGuid.value = row.guid 239 classGuid.value = row.guid
245 // page.value.curr = 1; 240 page.value.curr = 1;
246 // toSearch({}) 241 toSearch({})
247 // } 242 }
248 // } else { 243 } else {
249 // ElMessage({ 244 ElMessage({
250 // type: "info", 245 type: "error",
251 // message: res.data.msg, 246 message: res.msg,
252 // }); 247 });
253 // } 248 }
254 // }) 249 })
255 } 250 }
256 251
257 //左边列表点击 252 //左边列表点击
...@@ -263,28 +258,37 @@ const searchDict = (row?) => { ...@@ -263,28 +258,37 @@ const searchDict = (row?) => {
263 258
264 } 259 }
265 260
261 /** 当前正在编辑的分类 */
262 const currAsideRow: any = ref({});
263
266 const toAsideEdit = (data) => { 264 const toAsideEdit = (data) => {
267 let row = data 265 let row = data
266 currAsideRow.value = row;
268 asideDrawerInfo.value.header.title = '编辑分类' 267 asideDrawerInfo.value.header.title = '编辑分类'
269 asideDrawerInfo.value.visible = true; 268 asideDrawerInfo.value.visible = true;
269 asideDrawerInfo.value.type = 'edit';
270 row.dictTypeName = row.dicName;
270 classEditFormItems.value.forEach(item => { 271 classEditFormItems.value.forEach(item => {
271 item.default = row[item.field]; 272 item.default = row[item.field];
272 }) 273 })
274 asideDrawerInfo.value.container.contents[0] = classEditFormInfo.value;
273 } 275 }
274 const toAsideDelete = (data) => { // 删除 276 const toAsideDelete = (data) => { // 删除
275 let row = data 277 let row = data
276 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => { 278 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => {
277 // dictApi.removeDict([row.guid]).then(async (res) => { 279 removeDict([row.guid]).then(async (res: any) => {
278 // if (res.data.code === proxy.$passCode) { 280 if (res?.code === proxy.$passCode) {
279 // proxy.$ElMessage({ 281 proxy.$ElMessage({
280 // type: 'success', 282 type: 'success',
281 // message: '删除成功' 283 message: '删除成功'
282 // }) 284 })
283 // asidePage.value.curr = 1; 285 asidePage.value.curr = 1;
284 // asideSearch() 286 asideSearch();
285 // } 287 getAllAsideData();
286 288 } else {
287 // }) 289 proxy.$ElMessage.error(res?.msg);
290 }
291 })
288 }, () => { 292 }, () => {
289 proxy.$ElMessage.info("已取消删除"); 293 proxy.$ElMessage.info("已取消删除");
290 }) 294 })
...@@ -314,7 +318,7 @@ const asideDrawerInfo: any = ref({ ...@@ -314,7 +318,7 @@ const asideDrawerInfo: any = ref({
314 header: { 318 header: {
315 title: '添加分类', 319 title: '添加分类',
316 }, 320 },
317 type: '', 321 type: 'add',
318 container: { 322 container: {
319 contents: [classEditFormInfo.value], 323 contents: [classEditFormInfo.value],
320 }, 324 },
...@@ -346,7 +350,7 @@ const searchItemList = ref([ ...@@ -346,7 +350,7 @@ const searchItemList = ref([
346 field: 'dicName', 350 field: 'dicName',
347 default: '', 351 default: '',
348 maxlength: 50, 352 maxlength: 50,
349 placeholder: '名称', 353 placeholder: '目录名称',
350 clearable: true, 354 clearable: true,
351 visible: true 355 visible: true
352 }, { 356 }, {
...@@ -355,7 +359,7 @@ const searchItemList = ref([ ...@@ -355,7 +359,7 @@ const searchItemList = ref([
355 field: 'dicValue', 359 field: 'dicValue',
356 default: '', 360 default: '',
357 maxlength: 50, 361 maxlength: 50,
358 placeholder: '值', 362 placeholder: '目录值',
359 clearable: true, 363 clearable: true,
360 visible: true 364 visible: true
361 }, 365 },
...@@ -438,7 +442,7 @@ const dictFormItems: any = ref([ ...@@ -438,7 +442,7 @@ const dictFormItems: any = ref([
438 442
439 { 443 {
440 field: "dicName", 444 field: "dicName",
441 label: "名称", 445 label: "目录名称",
442 type: 'input', 446 type: 'input',
443 maxlength: 50, 447 maxlength: 50,
444 placeholder: '请输入', 448 placeholder: '请输入',
...@@ -449,7 +453,7 @@ const dictFormItems: any = ref([ ...@@ -449,7 +453,7 @@ const dictFormItems: any = ref([
449 }, 453 },
450 { 454 {
451 field: "dicValue", 455 field: "dicValue",
452 label: "值", 456 label: "目录值",
453 type: 'input', 457 type: 'input',
454 maxlength: 50, 458 maxlength: 50,
455 placeholder: '请输入', 459 placeholder: '请输入',
...@@ -495,8 +499,8 @@ const dictFormItems: any = ref([ ...@@ -495,8 +499,8 @@ const dictFormItems: any = ref([
495 499
496 const dictFormRules = ref({ 500 const dictFormRules = ref({
497 classGuid: [required('请选择分类')], 501 classGuid: [required('请选择分类')],
498 dicName: [required('请输入名称')], 502 dicName: [required('请输入目录名称')],
499 dicValue: [required('请输入值')], 503 dicValue: [required('请输入目录值')],
500 }); 504 });
501 505
502 /** 新增分类的form */ 506 /** 新增分类的form */
...@@ -517,7 +521,7 @@ const drawerInfo: any = ref({ ...@@ -517,7 +521,7 @@ const drawerInfo: any = ref({
517 visible: false, 521 visible: false,
518 size: 600, 522 size: 600,
519 header: { 523 header: {
520 title: "新增/编辑规则", 524 title: "新增/编辑目录",
521 }, 525 },
522 type: "", 526 type: "",
523 container: { 527 container: {
...@@ -534,17 +538,18 @@ const drawerInfo: any = ref({ ...@@ -534,17 +538,18 @@ const drawerInfo: any = ref({
534 538
535 // 添加字典打开抽屉 539 // 添加字典打开抽屉
536 const loadDialog = () => { 540 const loadDialog = () => {
537 drawerInfo.value.header.title = '新增规则' 541 drawerInfo.value.header.title = '新增目录'
538 // dictApi.getDictTable({ 542 drawerInfo.value.type = 'add'
539 // classGuid: row.classGuid 543 getDictData({
540 // }).then((res: any) => { 544 classGuid: classGuid.value
541 // if (res.code == proxy.$passCode) { 545 }).then((res: any) => {
542 // classList.value = res?.data || []; 546 if (res.code == proxy.$passCode) {
543 // dictFormItems.value[1].options = classList.value 547 classList.value = res?.data || [];
544 // } else { 548 dictFormItems.value[1].options = classList.value
545 // proxy.$ElMessage.error(res.msg); 549 } else {
546 // } 550 proxy.$ElMessage.error(res.msg);
547 // }) 551 }
552 })
548 drawerInfo.value.visible = true; 553 drawerInfo.value.visible = true;
549 let value = { 554 let value = {
550 guid: '', 555 guid: '',
...@@ -559,7 +564,6 @@ const loadDialog = () => { ...@@ -559,7 +564,6 @@ const loadDialog = () => {
559 }; 564 };
560 dictFormItems.value.forEach(item => { 565 dictFormItems.value.forEach(item => {
561 item.default = value[item.field]; 566 item.default = value[item.field];
562
563 }) 567 })
564 dictFormItemInfo.value.formInfo.items = dictFormItems.value; 568 dictFormItemInfo.value.formInfo.items = dictFormItems.value;
565 drawerInfo.value.container.contents[0] = dictFormItemInfo.value; 569 drawerInfo.value.container.contents[0] = dictFormItemInfo.value;
...@@ -580,16 +584,18 @@ function batchDelete(param) { ...@@ -580,16 +584,18 @@ function batchDelete(param) {
580 return; 584 return;
581 } 585 }
582 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => { 586 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => {
583 // dictApi.removeDict(selectRowData.value).then(async (res) => { 587 removeDict(selectRowData.value).then(async (res: any) => {
584 // if (res.data.code === proxy.$passCode) { 588 if (res?.code === proxy.$passCode) {
585 // proxy.$ElMessage({ 589 proxy.$ElMessage({
586 // type: 'success', 590 type: 'success',
587 // message: '删除成功' 591 message: '删除成功'
588 // }) 592 })
589 // page.value.curr = 1; 593 page.value.curr = 1;
590 // toSearch(params.value) 594 toSearch(params.value)
591 // } 595 } else {
592 // }) 596 proxy.$ElMessage.error(res.msg);
597 }
598 })
593 }); 599 });
594 } 600 }
595 }; 601 };
...@@ -623,41 +629,41 @@ const toSearch = (val: any, clear: boolean = false) => { ...@@ -623,41 +629,41 @@ const toSearch = (val: any, clear: boolean = false) => {
623 }; 629 };
624 630
625 const getTableData = () => { 631 const getTableData = () => {
626 // tableInfo.value.loading = true; 632 tableInfo.value.loading = true;
627 // getPlanList({ 633 getDictData({
628 // pageIndex: page.value.curr, pageSize: page.value.limit, 634 // pageIndex: page.value.curr, pageSize: page.value.limit,
629 // dicName: page.value.dicName, 635 dicName: page.value.dicName,
630 // dicValue: page.value.dicValue, 636 dicValue: page.value.dicValue,
631 // classGuid: classGuid.value 637 classGuid: classGuid.value
632 // }).then((res: any) => { 638 }).then((res: any) => {
633 // tableInfo.value.loading = false; 639 tableInfo.value.loading = false;
634 // if (res === undefined) { 640 if (res === undefined) {
635 // return; 641 return;
636 // } 642 }
637 // if (res.code == proxy.$passCode) { 643 if (res.code == proxy.$passCode) {
638 // const data = res.data || {} 644 const data = res.data || [];
639 // tableInfo.value.data = data.records || [] 645 tableInfo.value.data = data;
640 // tableInfo.value.page.limit = data.pageSize 646 } else {
641 // tableInfo.value.page.curr = data.pageIndex 647 ElMessage.error(res.msg);
642 // tableInfo.value.page.rows = data.totalRows 648 }
643 // } else { 649 })
644 // ElMessage.error(res.msg);
645 // }
646 // })
647 }; 650 };
648 651
649 const tableInfo = ref({ 652 const tableInfo = ref({
650 id: 'rule-table', 653 id: 'rule-table',
651 loading: false, 654 loading: false,
655 rowKey: 'guid',
656 multiple: true,
657 treeProps: { children: 'childList', hasChildren: 'hasChildren' },
652 fields: [ 658 fields: [
653 { 659 {
654 label: "名称", 660 label: "目录名称",
655 field: "dicName", 661 field: "dicName",
656 fixed: 'left', 662 fixed: 'left',
657 width: 140, 663 width: 180,
658 }, 664 },
659 { 665 {
660 label: "值", 666 label: "目录值",
661 field: "dicValue", 667 field: "dicValue",
662 width: 140, 668 width: 140,
663 }, 669 },
...@@ -694,7 +700,7 @@ const tableInfo = ref({ ...@@ -694,7 +700,7 @@ const tableInfo = ref({
694 }, 700 },
695 ], 701 ],
696 data: [], 702 data: [],
697 showPage: true, 703 showPage: false,
698 page: { 704 page: {
699 type: "normal", 705 type: "normal",
700 rows: 0, 706 rows: 0,
...@@ -708,12 +714,12 @@ const tableInfo = ref({ ...@@ -708,12 +714,12 @@ const tableInfo = ref({
708 return [ 714 return [
709 { 715 {
710 label: "编辑", value: "edit", click: (scope) => { 716 label: "编辑", value: "edit", click: (scope) => {
711 toEdit(scope.row) 717 toEdit(scope)
712 } 718 }
713 }, 719 },
714 { 720 {
715 label: "删除", value: "delete", click: (scope) => { 721 label: "删除", value: "delete", click: (scope) => {
716 toDelete(scope.row) 722 toDelete(scope)
717 } 723 }
718 }, 724 },
719 ] 725 ]
...@@ -721,9 +727,14 @@ const tableInfo = ref({ ...@@ -721,9 +727,14 @@ const tableInfo = ref({
721 } 727 }
722 }); 728 });
723 729
730 const currEditTableRow: any = ref({});
731
724 const toEdit = async (data) => { 732 const toEdit = async (data) => {
725 let { row } = data 733 let { row } = data
726 if (!row.classGuid) return 734 if (!row.classGuid) return
735 currEditTableRow.value = row;
736 classList.value = tableInfo.value.data || [];
737 dictFormItems.value[1].options = classList.value
727 // dictApi.getDictTable({ 738 // dictApi.getDictTable({
728 // classGuid: row.classGuid 739 // classGuid: row.classGuid
729 // }).then((res: any) => { 740 // }).then((res: any) => {
...@@ -734,9 +745,12 @@ const toEdit = async (data) => { ...@@ -734,9 +745,12 @@ const toEdit = async (data) => {
734 // proxy.$ElMessage.error(res.msg); 745 // proxy.$ElMessage.error(res.msg);
735 // } 746 // }
736 // }) 747 // })
737 748 if (row.classGuid == row.parentGuid) {
738 drawerInfo.value.header.title = '编辑' 749 row.parentGuid = '';
750 }
751 drawerInfo.value.header.title = '编辑目录'
739 drawerInfo.value.visible = true; 752 drawerInfo.value.visible = true;
753 drawerInfo.value.type = 'edit';
740 dictFormItems.value.forEach(item => { 754 dictFormItems.value.forEach(item => {
741 item.default = row[item.field]; 755 item.default = row[item.field];
742 }) 756 })
...@@ -744,16 +758,18 @@ const toEdit = async (data) => { ...@@ -744,16 +758,18 @@ const toEdit = async (data) => {
744 const toDelete = (data) => { // 删除 758 const toDelete = (data) => { // 删除
745 let { row } = data 759 let { row } = data
746 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => { 760 proxy.$openMessageBox("数据删除后不可恢复,确定是否删除?", () => {
747 // dictApi.removeDict([row.guid]).then(async (res) => { 761 removeDict([row.guid]).then(async (res: any) => {
748 // if (res.data.code === proxy.$passCode) { 762 if (res?.code === proxy.$passCode) {
749 // proxy.$ElMessage({ 763 proxy.$ElMessage({
750 // type: 'success', 764 type: 'success',
751 // message: '删除成功' 765 message: '删除成功'
752 // }) 766 })
753 // } 767 page.value.curr = 1;
754 // page.value.curr = 1; 768 toSearch(params.value)
755 // toSearch(params.value) 769 } else {
756 // }) 770 proxy.$ElMessage.error(res.msg);
771 }
772 })
757 }, () => { 773 }, () => {
758 proxy.$ElMessage.info("已取消删除"); 774 proxy.$ElMessage.info("已取消删除");
759 }) 775 })
...@@ -769,18 +785,22 @@ const handleDrawSelectChange = (val, row, info) => { ...@@ -769,18 +785,22 @@ const handleDrawSelectChange = (val, row, info) => {
769 classGuid: val, 785 classGuid: val,
770 }; 786 };
771 // 获取上级字典下拉选项 787 // 获取上级字典下拉选项
772 // dictApi.getDictTable(params).then((res: any) => { 788 getDictData(params).then((res: any) => {
773 // if (res.data.code == proxy.$passCode) { 789 if (res.code == proxy.$passCode) {
774 // const data = res.data.data; 790 const data = res.data || [];
775 // classList.value = data ?? []; 791 classList.value = data;
776 // dictFormItems.value[1].options = classList.value; 792 dictFormItems.value[1].options = classList.value;
777 // } else { 793 info.parentGuid = '';
778 // ElMessage({ 794 dictFormItems.value.forEach(d => {
779 // type: "info", 795 d.default = info[d.field] || '';
780 // message: res.msg, 796 })
781 // }); 797 } else {
782 // } 798 ElMessage({
783 // }) 799 type: "error",
800 message: res.msg,
801 });
802 }
803 })
784 804
785 } 805 }
786 806
...@@ -790,7 +810,23 @@ const drawerBtnClick = (btn, info) => { ...@@ -790,7 +810,23 @@ const drawerBtnClick = (btn, info) => {
790 drawerInfo.value.visible = false; 810 drawerInfo.value.visible = false;
791 } else { 811 } else {
792 if (btn.value == "save") { 812 if (btn.value == "save") {
793 submitForm() 813 let message = drawerInfo.value.type != 'add' ? '编辑成功' : '新增成功'
814 if (drawerInfo.value.type != 'add') {
815 info.guid = currEditTableRow.value.guid;
816 }
817
818 //TODO
819
820 // dictApi.addDictionary(resultForm1).then(res => {
821 // if (res.data.code === proxy.$passCode) {
822 // proxy.$ElMessage({
823 // type: 'success',
824 // message: message
825 // })
826 // drawerInfo.value.visible = false;
827 // toSearch(params.value)
828 // }
829 // });
794 } else { 830 } else {
795 drawerInfo.value.container.id = "add-dictionary-form"; 831 drawerInfo.value.container.id = "add-dictionary-form";
796 drawerInfo.value.visible = false; 832 drawerInfo.value.visible = false;
...@@ -798,6 +834,20 @@ const drawerBtnClick = (btn, info) => { ...@@ -798,6 +834,20 @@ const drawerBtnClick = (btn, info) => {
798 } 834 }
799 }; 835 };
800 836
837 const getAllAsideData = () => {
838 getDictClass({ pageSize: -1 }).then((res: any) => {
839 if (res.code == proxy.$passCode) {
840 allClassData.value = res.data.records || [];
841 dictFormItems.value[0].options = allClassData.value;
842 } else {
843 ElMessage({
844 type: "error",
845 message: res.msg,
846 });
847 }
848 })
849 }
850
801 onMounted(() => { 851 onMounted(() => {
802 852
803 }); 853 });
...@@ -805,7 +855,7 @@ onMounted(() => { ...@@ -805,7 +855,7 @@ onMounted(() => {
805 855
806 onBeforeMount(() => { 856 onBeforeMount(() => {
807 asideSearch() 857 asideSearch()
808 //TODO.需要查一个没有分页的作为下拉选择框。 858 getAllAsideData();
809 }); 859 });
810 </script> 860 </script>
811 861
...@@ -894,6 +944,7 @@ onBeforeMount(() => { ...@@ -894,6 +944,7 @@ onBeforeMount(() => {
894 944
895 .table_panel_wrap { 945 .table_panel_wrap {
896 width: 100%; 946 width: 100%;
947 height: calc(100% - 108px);
897 } 948 }
898 } 949 }
899 950
......
...@@ -430,8 +430,7 @@ const handleUploadClose = (itemGuid) => { ...@@ -430,8 +430,7 @@ const handleUploadClose = (itemGuid) => {
430 <div class="mid-content"> 430 <div class="mid-content">
431 <div class="left">产品来源</div> 431 <div class="left">产品来源</div>
432 <!-- TODO,要改成连接器名称 --> 432 <!-- TODO,要改成连接器名称 -->
433 <div class="right">{{ item.foundMode ? (item.foundMode === 1 ? '自建' : (item.foundMode == 2 ? '加工交付' : (item.foundMode == 4 ? '江苏专区' : (item.foundMode == 5 ? '数据港' : '专区')))) : '--' 433 <div class="right">{{ item.foundModeName ? item.foundModeName : '自建' }}</div>
434 }}</div>
435 </div> 434 </div>
436 <div class="mid-content"> 435 <div class="mid-content">
437 <div class="left">登记机构</div> 436 <div class="left">登记机构</div>
......
1 <route lang="yaml">
2 name: authenticationManagement //企业认证
3 </route>
4
5 <script lang="ts" setup name="authenticationManagement">
6 import { ref, onMounted } from "vue";
7 import { ElMessage, ElMessageBox } from "element-plus";
8 import { enterpriseSave, enterpriseUpdate, getEnterpriseData } from "@/api/modules/dataRequire";
9 import { getAreaData, getParamsList, getTenantDetailInfo, getUserSomeInfo } from "@/api/modules/queryService";
10 import { changeApproveSave, getCamundaDeploymentId } from "@/api/modules/workFlowService";
11 import { useValidator } from '@/hooks/useValidator';
12 import Moment from "moment";
13 import { CirclePlus } from "@element-plus/icons-vue";
14 import { scrollLastRowToView } from '@/utils/common';
15 import { onUploadFilePreview } from "@/api/modules/common";
16
17 const { proxy } = getCurrentInstance() as any;
18 const userData = JSON.parse(localStorage.userData);
19 const tenantData = JSON.parse(localStorage.tenantInfo);
20 const { staffName, staffNo } = userData;
21 const { required, isUSCCCode, idCode } = useValidator()
22 const loading = ref(false);
23 const flowDetail: any = ref({});
24 const getAreaDataPromise: any = ref({});
25 const getAreaDatas: any = ref({});
26 const setTenant = ref(false);
27 const typeMap: any = ref({});
28
29 const industryList: any = ref([]);
30
31 /**
32 * bizApproveState
33 * bizApproveStateNotList,排除状态数组,传值格式如:["N","C","D"]。
34 * N 草稿中,A 审批中,Y 已通过,R 驳回,C 已撤销,D 已废弃;B 变更中;
35 **/
36
37 const getArea = (node, resolve) => {
38 const { level } = node
39 let params = {
40 parentGuid: node.value
41 }
42 if (getAreaDatas.value[node.value]?.length) {
43 resolve(getAreaDatas.value[node.value]);
44 return;
45 }
46 if (!getAreaDataPromise.value[node.value]) {
47 getAreaDataPromise.value[node.value] = getAreaData(params).then((res: any) => {
48 getAreaDataPromise.value[node.value] = null;
49 node.loaded = true;
50 if (res?.code == proxy.$passCode) {
51 const data = res.data ?? []
52 data.map(item => {
53 item.leaf = level >= 2
54 })
55 resolve(data)
56 getAreaDatas.value[node.value] = data;
57 return res.data ?? [];
58 }
59 })
60 } else {
61 getAreaDataPromise.value[node.value].then((data) => {
62 getAreaDataPromise.value[node.value] = null;
63 node.loaded = true;
64 data.map(item => {
65 item.leaf = level >= 1
66 })
67 resolve(data)
68 })
69 }
70 }
71
72 const isEdit = ref(true);
73 const detailGuid = ref('');
74 const bizApproveState = ref('');
75 const crossPlatformApproveState = ref('');
76 const expand1 = ref(true)
77 const expand2 = ref(true)
78 const expand3 = ref(true)
79 const expand4 = ref(true)
80 const expand5 = ref(true)
81 const expand6 = ref(true)
82 const uploadInfoExpand = ref(true);
83 const expandResult = ref(true);
84
85 // 企业信息
86 const contentFormItems: any = ref([
87 {
88 label: '企业名称',
89 type: 'input',
90 placeholder: '请输入',
91 field: 'tenantName',
92 default: staffName,
93 maxlength: 50,
94 clearable: true,
95 required: true
96 },
97 {
98 label: '统一社会信用代码',
99 type: 'input',
100 placeholder: '请输入',
101 field: 'socialCreditCode',
102 default: '',
103 maxlength: 50,
104 clearable: true,
105 required: true
106 },
107 {
108 label: '机构类型',
109 type: 'select',
110 placeholder: '请选择',
111 field: 'tenantTypeVal',
112 default: '',
113 options: [],
114 clearable: true,
115 required: true,
116 },
117 {
118 label: '组织机构性质',
119 type: 'select',
120 placeholder: '请选择',
121 field: 'institutionType',
122 default: '',
123 options: [],
124 clearable: true,
125 filterable: true,
126 required: true,
127 },
128 {
129 label: '公司注册日期',
130 type: 'date',
131 placeholder: '请选择日期',
132 field: 'registrationDate',
133 default: "",
134 unlink: true,
135 clearable: true,
136 required: true,
137 },
138 {
139 label: '注册资本(万元)',
140 type: 'input',
141 inputType: 'moneyNumber',
142 field: 'registeredCapital',
143 placeholder: '请输入',
144 default: '',
145 maxlength: 18,
146 clearable: true,
147 required: true
148 },
149 {
150 label: '税号',
151 type: 'input',
152 placeholder: '请输入',
153 field: 'bankTaxNo',
154 default: '',
155 maxlength: 20,
156 clearable: true,
157 required: true,
158 },
159 {
160 label: '注册地',
161 type: 'cascader',
162 placeholder: '请选择',
163 field: 'area',
164 default: [],
165 props: {
166 label: 'name',
167 value: 'guid',
168 lazy: true,
169 lazyLoad: getArea,
170 },
171 clearable: true,
172 required: true,
173 },
174 {
175 label: '详细地址',
176 type: 'input',
177 placeholder: '请输入',
178 field: 'detailedAddress',
179 default: "",
180 maxlength: 250, // 后端是250
181 clearable: true,
182 required: true
183 },
184 {
185 label: '行业分类',
186 type: 'select',
187 placeholder: '请选择',
188 field: 'industry',
189 default: '',
190 options: industryList.value,
191 clearable: true,
192 filterable: true,
193 required: true,
194 },
195 {
196 label: '行业小类',
197 type: 'tree-select',
198 placeholder: '请选择',
199 field: 'industrySmallcode',
200 nodeKey: 'value',
201 options: industryList.value,
202 checkStrictly: false,//只能选择叶子节点。
203 lazy: false,
204 multiple: false,
205 props: {
206 label: "label",
207 value: "value",
208 children: 'childDictList'
209 },
210 filterable: true,
211 clearable: true,
212 default: '',
213 required: true,
214 },
215 {
216 label: '营业开始日期',
217 type: 'date',
218 placeholder: '请选择',
219 field: 'businessLicenseStartDate',
220 default: "",
221 unlink: true,
222 clearable: true,
223 required: true,
224 },
225 {
226 label: "营业结束日期",
227 type: "select",
228 placeholder: "请选择",
229 field: "businessLicenseTerm",
230 default: "2",
231 options: [
232 {
233 label: "长期有效",
234 value: "1",
235 },
236 {
237 label: "自定义",
238 value: "2",
239 },
240 ],
241 required: true,
242 clearable: true,
243 style: {
244 width: '110px'
245 }
246 },
247 {
248 label: "营业结束日期",
249 type: 'date',
250 placeholder: '请选择',
251 field: "businessLicenseEndDate",
252 default: '',
253 labelClass: 'hide',
254 clearable: true,
255 required: true,
256 visible: false,
257 style: {
258 width: 'calc(33.33% - 124px)'
259 }
260 },
261 {
262 label: '营业执照',
263 type: 'upload-file',
264 field: 'businessLicenseFile',
265 default: [],
266 tip: '请上传最新营业执照原件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
267 accept: '.jpg, .png',
268 required: true,
269 block: true,
270 },
271 {
272 label: '公司简介及经营范围',
273 type: 'textarea',
274 focusValue: false,
275 placeholder: '请输入公司简介及经营描述',
276 field: 'businessLicenseScope',
277 default: '',
278 clearable: true,
279 required: true,
280 block: true,
281 maxlength: 1000
282 },
283 ])
284 const contentFormRules = ref({
285 tenantName: [
286 { required: true, trigger: 'blur', message: "请填写企业名称" }
287 ],
288 socialCreditCode: [
289 required(),
290 isUSCCCode()
291 ],
292 tenantTypeVal: [
293 { required: true, trigger: 'change', message: "请选择机构类型" }
294 ],
295 institutionType: [
296 { required: true, trigger: 'change', message: "请选择组织机构性质" }
297 ],
298 registrationDate: [
299 { required: true, trigger: 'change', message: "请选择公司注册日期" }
300 ],
301 registeredCapital: [
302 { required: true, trigger: 'blur', message: "请填写注册资本(万元)" }
303 ],
304 detailedAddress: [
305 { required: true, trigger: 'blur', message: "请填写详细地址" }
306 ],
307 bankTaxNo: [
308 { required: true, trigger: 'blur', message: "请填写税号" }
309 ],
310 area: [
311 { required: true, trigger: 'change', message: "请选择注册地" }
312 ],
313 industry: [
314 { required: true, trigger: 'change', message: "请选择行业分类" }
315 ],
316 industrySmallcode: [
317 { required: true, trigger: 'change', message: "请选择行业小类" }
318 ],
319 businessLicenseStartDate: [
320 { required: true, trigger: 'change', message: "请选择营业开始日期" },
321 {
322 validator: (rule: any, value: any, callback: any) => {
323 if (!value) {
324 callback(new Error('请选择营业开始日期'))
325 return;
326 }
327 let businessLicenseEndDate = companyFormRef.value.formInline?.businessLicenseEndDate || '';
328 if (!businessLicenseEndDate) {
329 callback();
330 return;
331 }
332 let value1 = new Date(value);
333 // 将 today 设置为 00:00:00,只比较日期部分(本地时间)
334 const todayStart = new Date(
335 value1.getFullYear(),
336 value1.getMonth(),
337 value1.getDate()
338 );
339
340 // 将 date 也转换为本地日期的开始时间(避免 UTC 问题)
341 businessLicenseEndDate = new Date(businessLicenseEndDate);
342 const dateEnd = new Date(
343 businessLicenseEndDate.getFullYear(),
344 businessLicenseEndDate.getMonth(),
345 businessLicenseEndDate.getDate()
346 );
347
348 // 禁用 dateStart < todayStart 的日期(即今天之前)
349 if (dateEnd.getTime() < todayStart.getTime()) {
350 callback(new Error('营业开始日期不能晚于结束日期'))
351 } else {
352 callback();
353 }
354 }, trigger: 'change'
355 }
356 ],
357 businessLicenseTerm: [
358 { required: true, trigger: 'change', message: "请选择营业结束日期" }
359 ],
360 businessLicenseEndDate: [
361 { required: true, trigger: 'change', message: "请选择营业结束日期" },
362 {
363 validator: (rule: any, value: any, callback: any) => {
364 if (!value) {
365 callback(new Error('请选择营业结束日期'))
366 return;
367 }
368 let businessLicenseStartDate = companyFormRef.value.formInline?.businessLicenseStartDate || '';
369 if (!businessLicenseStartDate) {
370 callback();
371 return;
372 }
373 let value1 = new Date(value);
374 // 将 today 设置为 00:00:00,只比较日期部分(本地时间)
375 const todayStart = new Date(
376 value1.getFullYear(),
377 value1.getMonth(),
378 value1.getDate()
379 );
380
381 // 将 date 也转换为本地日期的开始时间(避免 UTC 问题)
382 businessLicenseStartDate = new Date(businessLicenseStartDate);
383 const dateStart = new Date(
384 businessLicenseStartDate.getFullYear(),
385 businessLicenseStartDate.getMonth(),
386 businessLicenseStartDate.getDate()
387 );
388
389 // 禁用 dateStart < todayStart 的日期(即今天之前)
390 if (dateStart.getTime() > todayStart.getTime()) {
391 callback(new Error('营业结束日期不能早于开始日期'))
392 } else {
393 callback();
394 }
395 }, trigger: 'change'
396 }
397 ],
398 businessLicenseFile: [{
399 validator: (rule: any, value: any, callback: any) => {
400 if (!value?.length) {
401 callback(new Error('请上传营业执照'))
402 } else {
403 callback();
404 }
405 }, trigger: 'change'
406 }],
407 businessLicenseScope: [
408 { required: true, trigger: 'blur', message: "请填写公司简介及经营范围" }
409 ],
410 });
411 const companyFormRef = ref();
412 const companyForm = ref({
413 items: contentFormItems.value,
414 rules: contentFormRules.value,
415 })
416
417 // 法人信息
418 const corporateFormItems: any = ref([
419 {
420 label: '法定代表人姓名',
421 type: 'input',
422 placeholder: '请输入',
423 field: 'juridicalPerson',
424 default: '',
425 maxlength: 50,
426 clearable: true,
427 required: true,
428 },
429 {
430 label: '法定代表人证件类型',
431 type: 'select',
432 placeholder: '请选择',
433 field: 'juridicalPersonIdType',
434 default: '1',
435 options: [],
436 clearable: true,
437 required: true,
438 },
439 {
440 label: '法定代表人证件号',
441 type: 'input',
442 placeholder: '请输入',
443 field: 'juridicalPersonId',
444 default: '',
445 maxlength: 50,
446 clearable: true,
447 required: true,
448 },
449 {
450 label: '法定代表人证件正反面',
451 type: 'upload-file',
452 field: 'juridicalPersonIdPhoto',
453 default: [],
454 tip: '请上传最新法定代表人证件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
455 accept: '.jpg, .png',
456 required: true,
457 block: true,
458 },
459 ])
460 const corporateFormRules = ref({
461 juridicalPerson: [
462 { required: true, trigger: 'blur', message: "请填写法定代表人姓名" }
463 ],
464 juridicalPersonIdType: [
465 { required: true, trigger: 'change', message: "请选择法人证件类型" }
466 ],
467 juridicalPersonId: [
468 { required: true, trigger: 'blur', message: "请填写法定代表人证件号" }
469 ],
470 juridicalPersonIdPhoto: [{
471 validator: (rule: any, value: any, callback: any) => {
472 if (!value?.length) {
473 callback(new Error('请上传法定代表人证件正反面'))
474 } else {
475 callback();
476 }
477 }, trigger: 'change'
478 }],
479 });
480 const corporateFormRef = ref();
481 const corporateForm = ref({
482 items: corporateFormItems.value,
483 rules: corporateFormRules.value,
484 })
485
486 // 账号信息
487 const accountFormItem = ref([
488 {
489 label: '账号',
490 type: 'input',
491 placeholder: '请输入',
492 field: 'logonUser',
493 default: userData.logonUser,
494 clearable: true,
495 required: true,
496 maxlength: 50,
497 disabled: true
498 },
499 {
500 label: '账号管理人姓名',
501 type: 'input',
502 placeholder: '请输入',
503 field: 'contacts',
504 default: '',
505 maxlength: 50,
506 clearable: true,
507 required: true,
508 },
509 {
510 label: '账号管理人手机号',
511 type: 'input',
512 placeholder: '请输入',
513 field: 'contactTel',
514 default: userData.mobileNo || '',
515 clearable: true,
516 maxlength: 50,
517 required: true,
518 },
519 {
520 label: '账号管理人证件类型',
521 type: 'select',
522 placeholder: '请选择',
523 field: 'handlePersonIdType',
524 default: '1',
525 options: [],
526 clearable: true,
527 required: true,
528 },
529 {
530 label: '账号管理人证件号',
531 type: 'input',
532 placeholder: '请输入',
533 field: 'managerPersonId',
534 default: '',
535 clearable: true,
536 maxlength: 50,
537 required: true,
538 },
539 {
540 label: '账号管理员证件正反面',
541 type: 'upload-file',
542 field: 'managerPersonIdPhoto',
543 default: [],
544 tip: '请上传最新管理员证件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
545 accept: '.jpg, .png',
546 required: true,
547 block: true,
548 },
549 ]);
550 const accountFormRules = ref({
551 logonUser: [
552 { required: true, trigger: 'blur', message: "请填写用户名" }
553 ],
554 contacts: [
555 { required: true, trigger: 'blur', message: "请填写账号管理人姓名" }
556 ],
557 handlePersonIdType: [
558 { required: true, trigger: 'blur', message: "请选择账号管理人证件类型" }
559 ],
560 contactTel: [
561 {
562 validator: (rule: any, value: any, callback: any) => {
563 if (value === '') {
564 callback(new Error('请填写手机号'))
565 } else {
566 const regs = /^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(17[0-9]{1})|(19[0-9]{1})|(18[0-9]{1}))+\d{8})$/
567 if (regs.test(value)) {
568 callback();
569 } else {
570 callback(new Error('请填写正确的手机号'))
571 }
572 }
573 },
574 trigger: 'blur'
575 },
576 {
577 min: 1,
578 max: 11,
579 message: '请填写账号管理人手机号',
580 trigger: 'change',
581 },
582 ],
583 managerPersonId: [
584 { required: true, trigger: 'blur', message: "账号管理人证件号" },
585 // required(),
586 // idCode()
587 // {
588 // validator: (rule: any, value: any, callback: any) => {
589 // if (value === '') {
590 // callback(new Error('请填写账号管理人证件号'))
591 // } else {
592 // const regs = /^(\d{15}$|^\d{18}(\d|X|x))$/
593 // if (regs.test(value)) {
594 // callback();
595 // } else {
596 // callback(new Error('请输入正确的15位或18位身份证号码'))
597 // }
598 // }
599 // },
600 // trigger: 'blur'
601 // },
602 {
603 min: 1,
604 max: 18,
605 message: '请填写账号管理人证件号',
606 trigger: 'change',
607 },
608 ],
609 managerPersonIdPhoto: [{
610 validator: (rule: any, value: any, callback: any) => {
611 if (!value?.length) {
612 callback(new Error('请上传账号管理员证件正反面'))
613 } else {
614 if (value.length < 1) {
615 callback(new Error('请上传账号管理员证件正反面'))
616 } else {
617 callback();
618 }
619 }
620 }, trigger: 'change'
621 }],
622 });
623 const accountFormRef = ref();
624 const accountForm: any = ref({
625 items: accountFormItem.value,
626 rules: accountFormRules.value,
627 })
628
629 // 协议签署
630 const contractFormItem: any = ref([
631 {
632 label: '授权委托书',
633 type: 'upload-file',
634 field: 'authorizationLetterFile',
635 default: [],
636 tip: '支持扩展名:.pdf, 最大50M',
637 accept: '.pdf',
638 required: true,
639 block: true,
640 },
641 ]);
642 const contractFormRules = ref({
643 authorizationLetterFile: [{
644 validator: (rule: any, value: any, callback: any) => {
645 if (!value?.length) {
646 callback(new Error('请上传授权委托书'))
647 } else {
648 callback();
649 }
650 }, trigger: 'change'
651 }],
652 });
653 const contractFormRef = ref();
654 const contractForm = ref({
655 items: contractFormItem.value,
656 rules: contractFormRules.value,
657 })
658
659 // 历史变更
660 const mergeRowCount: any = ref({});
661
662 // 历史信息
663 const rowCount = {
664 name: { index: 0, rowspan: [] }
665 };
666 const tableField: any = ref([
667 { label: "变更字段", field: "name", width: 200 },
668 {
669 label: "变更时间", field: "date", width: 120, getName: (scope) => {
670 return scope.row.date ? Moment(scope.row.date).format('YYYY-MM-DD') : '--';
671 }
672 },
673 ]);
674
675 const tableData = ref([])
676
677 const selectChange = (val, item, scope = null) => {
678 // console.log(val, item, scope);
679 if (item.field == 'businessLicenseTerm' || item.field == 'industry') {
680 setFormItems(scope, false)
681 // contentFormItems.value.at(7).default = val || '';
682 // contentFormItems.value.at(8).default = [];
683 // contentFormItems.value.at(8).visible = val == '2';
684 }
685 }
686
687 /**
688 * 传入多个promise对象,当全部结束时取消Loading
689 * @param promises 传入多个promise对象,当全部结束时取消Loading
690 */
691 const promiseList = async (...promises: Promise<void>[]) => {
692 try {
693 await Promise.all(promises).then((res) => {
694 loading.value = false;
695 setTableField();
696 if (detailGuid.value) {
697 setFormItems();
698 // const approveVO = flowDetail.value.approveVO || {};
699 // deploymentId.value = approveVO.camundaDeploymentId || ''
700 // processInstanceId.value = approveVO.camundaInstanceId || '';
701 }
702 });
703 } catch (e) {
704 loading.value = false;
705 }
706 };
707
708 // 获取需求类型
709 const getDataType = (dictType, fieldName) => {
710 return getParamsList({ dictType }).then((res: any) => {
711 if (res?.code == proxy.$passCode) {
712 const data = res.data || [];
713 if (fieldName == 'tenantTypeVal') {
714 typeMap.value.tenantType = JSON.parse(JSON.stringify(data));
715 let item = contentFormItems.value.find(item => item.field == fieldName);
716 item && (item.options = data);
717 } else if (fieldName == 'institutionType') {
718 typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
719 let item = contentFormItems.value.find(item => item.field == fieldName);
720 item && (item.options = data);
721 } else {
722 typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
723 let item = corporateFormItems.value.find(item => item.field == fieldName);
724 item && (item.options = data);
725 if (fieldName == 'juridicalPersonIdType') {
726 typeMap.value[fieldName] = data;
727 let item = accountFormItem.value.find(item => item.field == 'handlePersonIdType');
728 item && (item.options = data);
729 }
730 }
731 } else {
732 proxy.$ElMessage.error(res.msg);
733 }
734 })
735 }
736
737 const setFormItems = (info = null, setOther = true) => {
738 const datas = info ? JSON.parse(JSON.stringify(info)) : JSON.parse(JSON.stringify(flowDetail.value));
739 contentFormItems.value.map((a, index) => {
740 a.disabled = !isEdit.value;
741 if (a.field == 'tenantName') {
742 a.default = datas[a.field] || staffName;
743 } else if (a.field == 'registeredCapital') {
744 a.default = Number.isNaN(datas[a.field]) ? '' : datas[a.field];
745 } else if (a.field == 'tenantTypeVal') {
746 a.default = setTenant.value ? (datas[a.field] || '') : (datas.tenantType || datas[a.field] || '');
747 } else if (a.field == 'socialCreditCode') {
748 a.default = setTenant.value ? (datas[a.field] || '') : (datas[a.field] || staffNo);
749 } else if (a.field == 'area') {
750 a.default = setTenant.value ? (datas.companyAddress ? datas.companyAddress.split('/') : datas[a.field] || []) : datas.province ? [datas.province, datas.city, datas.district] : (datas[a.field] || []);
751 } else if (a.field == 'businessLicenseEndDate') {
752 a.default = datas[a.field] || '';
753 a.visible = datas.businessLicenseTerm == '2';
754 } else if (a.field == 'businessLicenseFile') {
755 if (setTenant.value) {
756 const tenantLicList = (datas.tenantLicList || []);
757 const pictList = tenantLicList.filter(t => t.licenseType == '1') || [];
758 let picts: any = [];
759 pictList.map(m => {
760 const fl = JSON.parse(m.pictContentJson || '[]')
761 fl.map(f => {
762 picts.push({ name: f.name, url: f.path, file: { uid: f.uid, url: f.path } })
763 })
764 });
765 a.default = tenantLicList.length == 0 ? datas[a.field] || [] : picts;
766 } else {
767 a.default = datas.businessLicenseJson ? JSON.parse(datas.businessLicenseJson) : (datas[a.field] || []);
768 }
769 } else if (a.field == 'industry') {
770 a.default = datas[a.field] || '';
771 contentFormItems.value[index + 1].options = !a.default ? [] : industryList.value.find(i => i.value == a.default)?.childDictList || [];
772 } else {
773 a.default = datas[a.field] || '';
774 }
775 })
776 if (!setOther) return;
777 corporateFormItems.value.map(b => {
778 b.disabled = !isEdit.value;
779 if (b.field == 'juridicalPersonIdPhoto') {
780 b.default = datas.juridicalPersonIdPhotoJson ? JSON.parse(datas.juridicalPersonIdPhotoJson) : (datas[b.field] || []);
781 } else if (b.field == 'juridicalPerson') {
782 b.default = setTenant.value ? (datas.personIncharge || datas[b.field] || '') : (datas[b.field] || '');
783 } else if (b.field == 'juridicalPersonIdType') {
784 b.default = datas[b.field] || '1';
785 } else {
786 b.default = datas[b.field] || '';
787 }
788 })
789 accountFormItem.value.map(c => {
790 c.disabled = !isEdit.value;
791 if (c.field == 'logonUser') {
792 c.default = datas[c.field] || userData.logonUser;
793 c.disabled = true;
794 } else if (c.field == 'managerPersonIdPhoto') {
795 c.default = datas.managerPersonIdPhotoJson ? JSON.parse(datas.managerPersonIdPhotoJson) : (datas[c.field] || []);
796 } else if (c.field == 'handlePersonIdType') {
797 c.default = datas[c.field] || '1';
798 } else {
799 c.default = datas[c.field] || '';
800 }
801 })
802 contractFormItem.value.map(d => {
803 d.disabled = !isEdit.value;
804 d.default = datas.authorizationLetter ? JSON.parse(datas.authorizationLetter) : (datas.authorizationLetterFile || []);
805 })
806 setTimeout(() => {
807 if (setTenant.value && setOther) {
808 const companyFormObj = companyFormRef.value;
809 const companyFormEl = companyFormObj.ruleFormRef;
810 const corporateFormObj = corporateFormRef.value
811 const corporateFormEl = corporateFormObj.ruleFormRef;
812 const accountFormObj = accountFormRef.value
813 const accountFormEl = accountFormObj.ruleFormRef;
814 const contractFormObj = contractFormRef.value
815 const contractFormEl = contractFormObj.ruleFormRef;
816 companyFormEl.clearValidate();
817 corporateFormEl.clearValidate();
818 accountFormEl.clearValidate();
819 contractFormEl.clearValidate();
820 }
821 }, 100)
822 }
823
824 // 获取用户信息
825 const getUserTenantInfo = () => {
826 let ps1 = getParamsList({ dictType: '开发主体附件类型' })
827 let ps2 = getUserSomeInfo({ guid: userData.userGuid })
828 Promise.all([ps1, ps2]).then((resInfos: any) => {
829 // 处理附件信息
830 let res1 = resInfos?.[0];
831 if (res1?.code == proxy.$passCode) {
832 let data = uploadFileList.value = res1.data || [];
833 uploadFormRules.value = {};
834 uploadFormItems.value = data.map(d => {
835 // uploadFormRules.value[`files-${d.value}`] = [{
836 // validator: (rule: any, value: any, callback: any) => {
837 // if (!value?.length) {
838 // callback(new Error('请上传文件'))
839 // } else {
840 // callback();
841 // }
842 // }, trigger: 'change'
843 // }];
844 return {
845 label: d.label,
846 tip: '支持扩展名:pdf、png、jpg、rar、zip,单个文件不得大于10M',
847 type: 'upload-file',
848 accept: '.pdf, .png, .jpg, .rar, .zip',
849 required: false,
850 limitSize: 10,
851 default: [],
852 field: `files-${d.value}`,
853 }
854 })
855 } else {
856 ElMessage.error(res1.msg);
857 }
858 // 处理公司信息
859 let res = resInfos?.[1];
860 if (res?.code == proxy.$passCode) {
861 const data = res.data.records || [];
862 userData.logonUser = data[0].logonUser;
863 userData.mobileNo = data[0].mobileNo;
864 accountFormItem.value[0].default = userData.logonUser;
865 accountFormItem.value[2].default = userData.mobileNo;
866 getTenant()
867 } else {
868 ElMessage.error(res.msg);
869 }
870 })
871 }
872 // 获取公司信息
873 const getTenant = () => {
874 loading.value = true;
875 getEnterpriseData({
876 logonUser: userData.tenantName == '非认证会员' ? userData.logonUser : tenantData.logonUser,
877 }).then((res: any) => {
878 // debugger
879 if (res?.code == proxy.$passCode) {
880 const data = res.data || {};
881 const totalRows = Object.keys(data).length;
882 flowDetail.value = data;
883 detailGuid.value = data.guid || '';
884 bizApproveState.value = data.bizApproveState || '';
885 crossPlatformApproveState.value = data.crossPlatformApproveState || '';
886 isEdit.value = (bizApproveState.value == 'Y' || crossPlatformApproveState.value == 'Y' || bizApproveState.value == 'A' || crossPlatformApproveState.value == 'A' || bizApproveState.value == 'B') ? false : true;
887 contentFormItems.value[1].disabled = bizApproveState.value == 'Y' || crossPlatformApproveState.value == 'Y' ? true : false;
888 tableData.value = data.changeList || [];
889 orgData.value = data.domainRSVOS?.map(d => {
890 return Object.assign(d, {
891 domainRange: [d.domainStartTime, d.domainEndTime]
892 });
893 }) || [];
894 orgTableInfo.value.data = orgData.value;
895 // orgTableInfo.value.STATUS = isEdit.value ? 'edit' : '';
896 let keys = Object.keys(orgTableInfo.value.editInfo);
897 keys.forEach(k => {
898 orgTableInfo.value.editInfo[k].disabled = !isEdit.value;
899 })
900 orgTableInfo.value.actionInfo.show = isEdit.value
901 let attachmentRQVOS = data.attachmentRSVOS || [];
902 uploadFormItems.value.forEach(item => {
903 let field = item.field;
904 let key = field.slice(6);
905 item.default = attachmentRQVOS.filter(a => a.fileType == key).map(f => {
906 return {
907 name: f.fileName,
908 url: f.fileUrl
909 }
910 })
911 // if (!isEdit.value && !item.default?.length) {
912 // item.visible = false;
913 // } else {
914 // item.visible = true;
915 // }
916 item.disabled = !isEdit.value;
917 })
918 if (totalRows == 0) {
919 promiseList(
920 getDataType('机构类型', 'tenantTypeVal'),
921 getDataType('证件类型', 'juridicalPersonIdType'),
922 getDataType('组织机构性质', 'institutionType'),
923 getDeploymentId('10013')
924 )
925 if (userData.tenantName != '非认证会员') {
926 getTenantData()
927 } else {
928 contentFormItems.value[0].disabled = false;
929 }
930 } else {
931 getMergeRow();
932 promiseList(
933 getDataType('机构类型', 'tenantTypeVal'),
934 getDataType('证件类型', 'juridicalPersonIdType'),
935 getDataType('组织机构性质', 'institutionType'),
936 )
937 }
938 } else {
939 ElMessage.error(res.msg);
940 }
941 }).catch(() => {
942 loading.value = false;
943 })
944 }
945
946 // 获取会员详情
947 const getTenantData = () => {
948 getTenantDetailInfo(userData.tenantGuid).then((res: any) => {
949 if (res.code == proxy.$passCode) {
950 const data = res.data ?? {};
951 flowDetail.value = { ...flowDetail.value, ...data };
952 setTenant.value = true;
953 setFormItems()
954 contentFormItems.value[0].disabled = true;
955 } else {
956 ElMessage.error(res.msg);
957 }
958 })
959 }
960
961 // 获取流程信息
962 const getDeploymentId = (flowType: any) => {
963 return getCamundaDeploymentId(flowType, userData.tenantGuid, userData.staffGuid).then((res: any) => {
964 if (res.code == proxy.$passCode) {
965 } else {
966 ElMessage.error(res.msg);
967 }
968 })
969 }
970
971 const setTableField = () => {
972 tableField.value.splice(2);
973 tableField.value.splice(2, 0, {
974 label: "变更前", field: "before", width: 400, getName: (scope) => {
975 const nameEn = scope.row.nameEn;
976 if (nameEn == 'tenantType' || nameEn == 'juridicalPersonIdType' || nameEn == 'institutionType') {
977 return typeMap.value[nameEn].find((c: any) => c.value == scope.row.before)?.label || '--';
978 } else if (nameEn == 'industry') {
979 return industryList.value.find((c: any) => c.value == scope.row.before)?.label || '--';
980 } else if (nameEn == 'industrySmallcode') {
981 let getChildLabel = (children) => {
982 for (const child of children) {
983 if (child.value == scope.row.before) {
984 return child.label;
985 }
986 let label = getChildLabel(child.childDictList || []);
987 if (label) {
988 return label;
989 }
990 }
991 }
992 return scope.row.before && getChildLabel(industryList.value) || [];
993 } else {
994 return scope.row.before || '--';
995 }
996 }
997 }, {
998 label: "变更后", field: "after", width: 400, getName: (scope) => {
999 const nameEn = scope.row.nameEn;
1000 if (nameEn == 'tenantType' || nameEn == 'juridicalPersonIdType' || nameEn == 'institutionType') {
1001 return typeMap.value[nameEn].find((c: any) => c.value == scope.row.after)?.label || '--';
1002 } else if (nameEn == 'industry') {
1003 return industryList.value.find((c: any) => c.value == scope.row.after)?.label || '--';
1004 } else if (nameEn == 'industrySmallcode') {
1005 let getChildLabel = (children) => {
1006 for (const child of children) {
1007 if (child.value == scope.row.after) {
1008 return child.label;
1009 }
1010 let label = getChildLabel(child.childDictList || []);
1011 if (label) {
1012 return label;
1013 }
1014 }
1015 }
1016 return scope.row.after && getChildLabel(industryList.value) || [];
1017 } else {
1018 return scope.row.after || '--';
1019 }
1020 }
1021 });
1022 }
1023
1024 // 设置表格合并下标
1025 const getMergeRow = () => {
1026 mergeRowCount.value = JSON.parse(JSON.stringify(rowCount));
1027 let list = tableData.value;
1028 for (var i = 0; i < list.length; i++) {
1029 if (i === 0) {
1030 //第一个数据 默认合并1行,开始位置下标默认为0
1031 for (var m in mergeRowCount.value) {
1032 mergeRowCount.value[m].rowspan.push(1);
1033 mergeRowCount.value[m].index = 0;
1034 }
1035 } else {
1036 // 根据拥有子级数量进行合并
1037 for (var m in mergeRowCount.value) {
1038 let mergeRow = mergeRowCount.value[m];
1039 if (list[i][m] && list[i][m] === list[i - 1][m]) {
1040 mergeRow.rowspan[mergeRow.index] += 1;
1041 mergeRow.rowspan.push(0);
1042 } else {
1043 mergeRow.rowspan.push(1);
1044 mergeRow.index = i;
1045 }
1046 }
1047 }
1048 }
1049 }
1050 // 表格行合并
1051 const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
1052 if (columnIndex === 0) {
1053 const mergeInfo = mergeRowCount.value.name;
1054 const rowspan = mergeInfo?.rowspan?.[rowIndex];
1055 if (rowspan == null) {
1056 return {
1057 rowspan: 1,
1058 colspan: 1
1059 }
1060 }
1061 if (rowspan > 0) {
1062 return {
1063 rowspan,
1064 colspan: 1,
1065 };
1066 } else {
1067 return {
1068 rowspan: 0,
1069 colspan: 0,
1070 };
1071 }
1072 }
1073 }
1074
1075 const setFormDisable = () => {
1076 isEdit.value = false;
1077 contentFormItems.value.map(a => a.disabled = true);
1078 corporateFormItems.value.map(b => b.disabled = true);
1079 accountFormItem.value.map(c => c.disabled = true);
1080 contractFormItem.value.map(d => d.disabled = true);
1081 // orgTableInfo.value.STATUS = isEdit.value ? 'edit' : '';
1082 orgTableInfo.value.actionInfo.show = isEdit.value;
1083 let keys = Object.keys(orgTableInfo.value.editInfo);
1084 keys.forEach(k => {
1085 orgTableInfo.value.editInfo[k].disabled = !isEdit.value;
1086 })
1087 uploadFormItems.value.forEach(item => {
1088 // if (!isEdit.value && !item.default?.length) {
1089 // item.visible = false;
1090 // } else {
1091 // item.visible = true;
1092 // }
1093 item.disabled = !isEdit.value;
1094 })
1095 }
1096
1097 /** 保存草稿,不用校验。 */
1098 const saveDraft = (params) => {
1099 loading.value = true;
1100 if (detailGuid.value) {
1101 enterpriseUpdate(params).then((res: any) => {
1102 loading.value = false;
1103 if (res.code == proxy.$passCode) {
1104 ElMessage.success('编辑认证信息成功');
1105 bizApproveState.value = 'N';
1106 // setFormDisable();
1107 // setTimeout(() => {
1108 // getTenant();
1109 // }, 2000);
1110 } else {
1111 ElMessage.error(res.msg);
1112 }
1113 }).catch((xhr) => {
1114 loading.value = false;
1115 ElMessage.error(xhr.response.data.msg);
1116 });
1117 } else {
1118 enterpriseSave(params).then((res: any) => {
1119 loading.value = false;
1120 if (res.code == proxy.$passCode) {
1121 ElMessage.success('新建认证信息成功');
1122 bizApproveState.value = 'N';
1123 // setFormDisable();
1124 // setTimeout(() => {
1125 // getTenant();
1126 // }, 2000);
1127 } else {
1128 ElMessage.error(res.msg);
1129 }
1130 }).catch((xhr) => {
1131 loading.value = false;
1132 ElMessage.error(xhr.response.data.msg);
1133 });
1134 }
1135 }
1136
1137 const subSave = (params) => {
1138 loading.value = true;
1139 if (detailGuid.value) {
1140 enterpriseUpdate(params).then((res: any) => {
1141 loading.value = false;
1142 if (res.code == proxy.$passCode) {
1143 ElMessage.success('编辑认证信息提交申请成功');
1144 bizApproveState.value = 'A';
1145 setFormDisable();
1146 } else {
1147 ElMessage.error(res.msg);
1148 }
1149 }).catch((xhr) => {
1150 loading.value = false;
1151 ElMessage.error(xhr.response.data.msg);
1152 });
1153 } else {
1154 enterpriseSave(params).then((res: any) => {
1155 loading.value = false;
1156 if (res.code == proxy.$passCode) {
1157 ElMessage.success('新建认证信息提交申请成功');
1158 bizApproveState.value = 'A';
1159 setFormDisable();
1160 } else {
1161 ElMessage.error(res.msg);
1162 }
1163 }).catch((xhr) => {
1164 loading.value = false;
1165 ElMessage.error(xhr.response.data.msg);
1166 });
1167 }
1168 }
1169
1170 const changeApprove = (params) => {
1171 loading.value = true;
1172 changeApproveSave(params).then((res: any) => {
1173 loading.value = false;
1174 if (res.code == proxy.$passCode) {
1175 ElMessage.success('认证信息变更申请成功');
1176 bizApproveState.value = 'B';
1177 setFormDisable();
1178 } else {
1179 ElMessage.error(res.msg);
1180 }
1181 }).catch((xhr) => {
1182 loading.value = false;
1183 ElMessage.error(xhr.response.data.msg);
1184 });
1185 }
1186
1187 const btnClick = async (btn, bType = null) => {
1188 const type = btn.value;
1189 if (type == 'save' || type == 'submit') {
1190 const companyFormObj = companyFormRef.value;
1191 const companyFormEl = companyFormObj.ruleFormRef;
1192 const companyFormInfo = companyFormObj.formInline;
1193 const corporateFormObj = corporateFormRef.value
1194 const corporateFormEl = corporateFormObj.ruleFormRef;
1195 const corporateFormInfo: any = corporateFormObj.formInline;
1196 const accountFormObj = accountFormRef.value
1197 const accountFormEl = accountFormObj.ruleFormRef;
1198 const accountFormInfo: any = accountFormObj.formInline;
1199 const contractFormObj = contractFormRef.value
1200 const contractFormEl = contractFormObj.ruleFormRef;
1201 const contractFormInfo: any = contractFormObj.formInline;
1202 const saveParam = () => {
1203 let params = {
1204 ...companyFormInfo,
1205 ...corporateFormInfo,
1206 ...accountFormInfo,
1207 ...contractFormInfo,
1208 };
1209 params.province = params.area[0];
1210 params.city = params.area[1];
1211 params.district = params.area[2];
1212 params.tenantType = params.tenantTypeVal;
1213 params.businessLicenseJson = JSON.stringify(params.businessLicenseFile);
1214 params.juridicalPersonIdPhotoJson = JSON.stringify(params.juridicalPersonIdPhoto);
1215 params.managerPersonIdPhotoJson = JSON.stringify(params.managerPersonIdPhoto);
1216 params.authorizationLetter = JSON.stringify(params.authorizationLetterFile);
1217 // params.businessLicenseStartDate = params.businessLicenseTerm == '2' ? params.businessLicenseDate[0] : null;
1218 params.businessLicenseEndDate = params.businessLicenseTerm == '2' ? params.businessLicenseEndDate : null;
1219 delete params.area;
1220 delete params.businessLicenseFile;
1221 delete params.juridicalPersonIdPhoto;
1222 delete params.managerPersonIdPhoto;
1223 delete params.authorizationLetterFile;
1224 delete params.businessLicenseDate;
1225 delete params.tenantTypeVal;
1226 params.tenantGuid = userData.tenantGuid;
1227 detailGuid.value && (params.guid = detailGuid.value);
1228 //TODO,只有江苏专区时才需要必填
1229 // if (!orgData.value.length) {
1230 // proxy.$ElMessage.error('开发主体领域信息不能为空');
1231 // return;
1232 // }
1233 for (const d of orgData.value) {
1234 if (!d.domainId) {
1235 proxy.$ElMessage.error('领域名称不能为空');
1236 return;
1237 }
1238 if (!d.authId) {
1239 proxy.$ElMessage.error('授权协议号不能为空');
1240 return;
1241 }
1242 if (!d.domainRange) {
1243 proxy.$ElMessage.error('协议日期不能为空');
1244 return;
1245 }
1246 // if (!d.domainEndTime) {
1247 // proxy.$ElMessage.error('协议结束日期不能为空');
1248 // return;
1249 // }
1250 if (!d.domainSignTime) {
1251 proxy.$ElMessage.error('协议签订时间不能为空');
1252 return;
1253 }
1254 if (!d.signee) {
1255 proxy.$ElMessage.error('协议签订人不能为空');
1256 return;
1257 }
1258 }
1259 params.domainRQVOS = orgData.value?.map(d => {
1260 return Object.assign(d, {
1261 domainEndTime: d.domainRange?.[1],
1262 domainStartTime: d.domainRange?.[0],
1263 })
1264 });
1265 let uploadValue = uploadFormRef.value.formInline;
1266 let attachmentRQVOS: any[] = [];
1267 for (const key in uploadValue) {
1268 if (!uploadValue[key]?.length) {
1269 continue;
1270 }
1271 let n = key.slice(6);
1272 uploadValue[key].forEach(uf => {
1273 attachmentRQVOS.push({
1274 fileName: uf.name,
1275 fileType: n,
1276 fileUrl: uf.url,
1277 });
1278 })
1279 }
1280 params.attachmentRQVOS = attachmentRQVOS;
1281
1282 if (bizApproveState.value == 'Y' && crossPlatformApproveState.value == 'Y') {
1283 let flowParams: any = {};
1284 flowParams.flowType = '10014';
1285 flowParams.bizGuid = detailGuid.value;
1286 flowParams.sourceApproveGuid = flowDetail.value.approveVO.approveGuid;
1287 flowParams.bizDataJson = JSON.stringify(params);
1288 flowParams.oldBizDataJson = JSON.stringify(flowDetail.value);
1289 flowParams.isDraft = type == 'submit' ? 'N' : 'Y';
1290 changeApprove(flowParams);
1291 } else {
1292 if (type == 'submit') {
1293 params.immediateApprove = true;
1294 params.bizApproveState = 'A';
1295 params.isRestart = (bizApproveState.value == 'C' || bizApproveState.value == 'R') ? true : false;
1296 subSave(params)
1297 } else {
1298 params.immediateApprove = false;
1299 params.bizApproveState = 'N';
1300 saveDraft(params)
1301 }
1302 }
1303 }
1304
1305 companyFormEl.validate((valid, errorItem) => {
1306 if (valid) {
1307 corporateFormEl.validate((valid, errorItem) => {
1308 if (valid) {
1309 accountFormEl.validate((valid, errorItem) => {
1310 if (valid) {
1311 contractFormEl.validate((valid, errorItem) => {
1312 if (valid) {
1313 saveParam();
1314 } else {
1315 expand4.value = true;
1316 var obj = Object.keys(errorItem);
1317 contractFormEl.scrollToField(obj[0]);
1318 }
1319 });
1320 } else {
1321 expand3.value = true;
1322 var obj = Object.keys(errorItem);
1323 accountFormEl.scrollToField(obj[0]);
1324 }
1325 });
1326 } else {
1327 expand2.value = true;
1328 var obj = Object.keys(errorItem);
1329 corporateFormEl.scrollToField(obj[0]);
1330 }
1331 });
1332 } else {
1333 expand1.value = true;
1334 var obj = Object.keys(errorItem);
1335 companyFormEl.scrollToField(obj[0]);
1336 }
1337 });
1338 } else if (type == 'cancel') {
1339 setFormItems();
1340 if (bizApproveState.value == 'Y' && crossPlatformApproveState.value == 'Y') {
1341 setFormDisable();
1342 }
1343 } else if (type == 'change') {
1344 isEdit.value = true;
1345 contentFormItems.value.map(a => {
1346 if (a.field == 'socialCreditCode') {
1347 a.disabled = bizApproveState.value == 'Y' || crossPlatformApproveState.value == 'Y' ? true : false;
1348 } else {
1349 a.disabled = false
1350 }
1351 });
1352 corporateFormItems.value.map(b => b.disabled = false);
1353 accountFormItem.value.map(c => c.disabled = c.field == 'logonUser' ? true : false);
1354 contractFormItem.value.map(d => d.disabled = false);
1355 // orgTableInfo.value.STATUS = isEdit.value ? 'edit' : '';
1356 let keys = Object.keys(orgTableInfo.value.editInfo);
1357 keys.forEach(k => {
1358 orgTableInfo.value.editInfo[k].disabled = !isEdit.value;
1359 })
1360 orgTableInfo.value.actionInfo.show = isEdit.value
1361 uploadFormItems.value.forEach(item => {
1362 // if (!isEdit.value && !item.default?.length) {
1363 // item.visible = false;
1364 // } else {
1365 // item.visible = true;
1366 // }
1367 item.disabled = !isEdit.value;
1368 })
1369 }
1370 }
1371
1372 onBeforeMount(() => {
1373 // userData的值为空,则获取用户信息
1374 getUserTenantInfo();
1375 getParamsList({ dictType: '领域' }).then((res: any) => {
1376 if (res?.code == proxy.$passCode) {
1377 const data = res.data || [];
1378 orgTableInfo.value.editInfo.domainId.options = data;
1379 } else {
1380 res?.msg && proxy.$ElMessage.error(res?.msg);
1381 }
1382 })
1383 getParamsList({ dictType: '行业分类' }).then((res: any) => {
1384 if (res?.code == proxy.$passCode) {
1385 industryList.value = res.data || [];
1386 let index = contentFormItems.value.findIndex(item => item.field == 'industry');
1387 let item = contentFormItems.value[index];
1388 item.options = industryList.value;
1389 contentFormItems.value[index + 1].options = !item.default ? [] : industryList.value.find(i => i.value == item.default)?.childDictList || [];
1390 } else {
1391 res?.msg && proxy.$ElMessage.error(res?.msg);
1392 }
1393 })
1394 })
1395
1396 const orgTableRef = ref();
1397 const orgData: any = ref([]);
1398 /** 领域的字典列表 */
1399 const domainList: any = ref([]);
1400 /** 被授权资源信息的表格配置 */
1401 const orgTableInfo = ref({
1402 id: "org-table",
1403 height: '214px',
1404 fields: [
1405 { label: "序号", type: "index", width: 56, align: "center" },
1406 { label: "领域名称", field: "domainId", width: 160, required: true, columClass: 'edit-colum', type: 'edit' },
1407 { label: "授权协议号", field: "authId", width: 180, required: true, columClass: 'edit-colum', type: 'edit' },
1408 { label: "协议日期", field: "domainRange", width: 260, required: true, columClass: 'edit-colum', type: 'edit' },
1409 // { label: "协议结束日期", field: "domainEndTime", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1410 { label: "协议签订时间", field: "domainSignTime", width: 200, required: true, columClass: 'edit-colum', type: 'edit' },
1411 { label: "协议签订人", field: "signee", width: 150, required: true, columClass: 'edit-colum', type: 'edit' },
1412 { label: "协议状态", field: "domainStatus", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1413 ],
1414 editInfo: {
1415 authId: {
1416 label: '',
1417 type: 'input',
1418 field: 'authId',
1419 default: '',
1420 maxlength: 50,
1421 placeholder: '请输入',
1422 clearable: true,
1423 },
1424 signee: {
1425 label: '',
1426 type: 'input',
1427 field: 'signee',
1428 default: '',
1429 maxlength: 20,
1430 placeholder: '请输入',
1431 clearable: true,
1432 },
1433 domainId: {
1434 label: '',
1435 type: 'select',
1436 field: 'domainId',
1437 default: '',
1438 options: domainList.value,
1439 props: {
1440 label: 'label',
1441 value: 'value'
1442 },
1443 placeholder: '请选择',
1444 clearable: true,
1445 filterable: true
1446 },
1447 domainRange: {
1448 label: '',
1449 type: 'date-picker',
1450 field: 'domainRange',
1451 default: [],
1452 placeholder: '请选择',
1453 clearable: true,
1454 },
1455 // domainStartTime: {
1456 // label: '',
1457 // type: 'date',
1458 // field: 'domainStartTime',
1459 // default: '',
1460 // placeholder: '请选择',
1461 // clearable: true,
1462 // },
1463 // domainEndTime: {
1464 // label: '',
1465 // type: 'date',
1466 // field: 'domainEndTime',
1467 // default: '',
1468 // placeholder: '请选择',
1469 // clearable: true,
1470 // },
1471 domainSignTime: {
1472 label: '',
1473 type: 'datetime',
1474 field: 'domainSignTime',
1475 default: '',
1476 placeholder: '请选择',
1477 clearable: true,
1478 },
1479 domainStatus: {
1480 label: '',
1481 type: 'select',
1482 field: 'domainStatus',
1483 default: '',
1484 options: [{
1485 value: '10',
1486 label: '生效中'
1487 }, {
1488 value: '20',
1489 label: '已终止'
1490 }],
1491 props: {
1492 label: 'label',
1493 value: 'value'
1494 },
1495 placeholder: '请选择',
1496 clearable: true,
1497 filterable: true
1498 },
1499 },
1500 STATUS: 'edit',
1501 data: orgData.value,
1502 showPage: false,
1503 actionInfo: {
1504 show: true,
1505 label: "操作",
1506 type: "btn",
1507 width: 60,
1508 fixed: 'right',
1509 btns: [
1510 {
1511 label: "删除", value: "remove", click: (scope) => {
1512 let index = scope.$index;
1513 proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => {
1514 orgData.value.splice(index, 1);
1515 orgTableInfo.value.data = orgData.value;
1516 proxy.$ElMessage.success('开发主体领域信息删除成功');
1517 }, () => {
1518 proxy.$ElMessage.info("已取消");
1519 });
1520 }
1521 },
1522 ]
1523 },
1524 loading: false
1525 });
1526
1527 /** 给表格添加一行入参定义。 */
1528 const addOrgs = () => {
1529 orgData.value.push({ domainId: '', authId: '', domainRange: [], domainSignTime: '', signee: '', domainStatus: '10', guid: '' });
1530 orgTableInfo.value.data = orgData.value;
1531 nextTick(() => {
1532 scrollLastRowToView(orgTableRef.value?.tableRef, orgData.value.length);
1533 })
1534 }
1535
1536 const uploadFormRef = ref();
1537
1538 /** 开发主体附件信息 */
1539 const uploadFormItems: any = ref([]);
1540
1541 const uploadFormRules = ref({});
1542
1543 /** 开发主体附件类型的字典 */
1544 const uploadFileList: any = ref([]);
1545
1546 // 查看凭证证书
1547 const viewVoucherFile = () => {
1548 const url = flowDetail.value.trustedIdentityCredential;
1549 if (!url) {
1550 return;
1551 }
1552 onUploadFilePreview(url);
1553 }
1554
1555 </script>
1556
1557 <template>
1558 <div class="container_wrap full" v-loading="loading">
1559 <div class="content_main panel"
1560 :class="{ full: bizApproveState == 'A' || bizApproveState == 'B' || crossPlatformApproveState == 'A' }">
1561 <ContentWrap title="企业信息" expandSwicth style="margin-top: 15px" :isExpand="expand1" @expand="(v) => expand1 = v"
1562 description="备注:与平台运营签订相关的合同后才能进行认证,避免认证不成功,请知晓!">
1563 <div class="form_panel">
1564 <Form ref="companyFormRef" formId="company-form" :itemList="companyForm.items" :rules="companyForm.rules"
1565 col="col3" @selectChange="selectChange" />
1566 </div>
1567 </ContentWrap>
1568 <ContentWrap title="法人信息" expandSwicth style="margin-top: 15px" :isExpand="expand2" @expand="(v) => expand2 = v">
1569 <Form ref="corporateFormRef" formId="corporate-form" :itemList="corporateForm.items"
1570 :rules="corporateForm.rules" col="col3" @selectChange="selectChange" />
1571 </ContentWrap>
1572 <ContentWrap title="管理员(经办人)信息" expandSwicth style="margin-top: 15px" :isExpand="expand3"
1573 @expand="(v) => expand3 = v">
1574 <div class="form_panel">
1575 <Form ref="accountFormRef" formId="account-form" :itemList="accountForm.items" :rules="accountForm.rules"
1576 col="col3" />
1577 </div>
1578 </ContentWrap>
1579 <ContentWrap title="协议签署" expandSwicth style="margin-top: 15px" :isExpand="expand4" @expand="(v) => expand4 = v">
1580 <div class="form_panel">
1581 <Form ref="contractFormRef" formId="contract-form" :itemList="contractForm.items" :rules="contractForm.rules"
1582 col="col3" />
1583 </div>
1584 </ContentWrap>
1585 <ContentWrap title="开发主体领域信息" expandSwicth style="margin-top: 15px" :isExpand="expand6"
1586 @expand="(v) => expand6 = v">
1587 <Table ref="orgsTableRef" :tableInfo="orgTableInfo" class="fiveRow-table" />
1588 <div v-show="isEdit" class="row-add-btn">
1589 <el-button link @click="addOrgs" :icon="CirclePlus" v-preReClick>添加</el-button>
1590 </div>
1591 </ContentWrap>
1592 <ContentWrap id="id-files" title="开发主体附件信息" description="" expandSwicth style="margin-top: 15px"
1593 :isExpand="uploadInfoExpand" @expand="(v) => uploadInfoExpand = v" v-show="uploadFormItems.length">
1594 <Form class='uploadForm' ref="uploadFormRef" :itemList="uploadFormItems" formId="upload-form"
1595 :rules="uploadFormRules" col="col2" />
1596 </ContentWrap>
1597 <ContentWrap title="历史变更信息" expandSwicth style="margin-top: 15px" :isExpand="expand5"
1598 @expand="(v) => expand4 = v">
1599 <div class="table_panel" :class="{ full: tableData.length > 0 }">
1600 <el-table border :data="tableData" :span-method="tableSpanMethod" tooltip-effect="light" style="height: 100%;"
1601 v-if="tableData.length > 0">
1602 <el-table-column v-for="(item, i) in tableField" :key="'r_' + i" :label="item.label" :width="item.width"
1603 :min-width="item.minWidth" :fixed="item.fixed" :align="item.align" :sortable="item.sortable ?? false"
1604 :prop="item.field" :class-name="item.columClass" show-overflow-tooltip>
1605 <template #default="scope">
1606 <span>
1607 {{ item.getName ? item.getName(scope) : scope.row[item.field] !== 0 && !scope.row[item.field] ?
1608 "--" : scope.row[item.field] }}
1609 </span>
1610 </template>
1611 </el-table-column>
1612 </el-table>
1613 <div class="empty_tips" v-else>暂无变更信息</div>
1614 </div>
1615 </ContentWrap>
1616 <ContentWrap title="认证结果信息" v-if="bizApproveState == 'Y' && crossPlatformApproveState == 'Y' && !isEdit" expandSwicth style="margin-top: 15px" :isExpand="expandResult"
1617 @expand="(v) => expandResult = v">
1618 <div class="list_panel">
1619 <div class="list_item">
1620 <span class="item_label">认证时间:</span>
1621 <span class="item_value">{{ flowDetail.credentialTime || '--' }}</span>
1622 </div>
1623 <div class="list_item">
1624 <span class="item_label">身份认证凭证:</span>
1625 <span v-if="flowDetail.trustedIdentityCredential" class="item_value link" @click="viewVoucherFile">查看</span>
1626 <span v-else class="item_value">--</span>
1627 </div>
1628 </div>
1629 </ContentWrap>
1630 <!-- <ContentWrap id="id-approveInfo" title="审核信息" expandSwicth style="margin-top: 15px" :isExpand="expand6"
1631 @expand="(v) => expand6 = v" v-show="deploymentId">
1632 <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :processInstanceId="processInstanceId"
1633 :definitionId="''">
1634 </ApprovalProcess>
1635 </ContentWrap> -->
1636 </div>
1637 <div class="tool_btns">
1638 <div class="btns" v-if="isEdit">
1639 <el-button @click="btnClick({ value: 'cancel' })">取消</el-button>
1640 <!-- <el-button type="primary" v-if="bizApproveState != 'R' && bizApproveState != 'C'"
1641 @click="btnClick({ value: 'save' })">保存</el-button> -->
1642 <el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button>
1643 </div>
1644 <div class="btns" v-else-if="bizApproveState == 'Y' && crossPlatformApproveState == 'Y' && !isEdit">
1645 <el-button type="primary" @click="btnClick({ value: 'change' })">变更认证</el-button>
1646 </div>
1647 </div>
1648 </div>
1649 </template>
1650
1651 <style scoped lang="scss">
1652 .container_wrap {
1653 overflow: hidden;
1654
1655 .content_main {
1656 height: calc(100% - 45px);
1657 overflow: hidden auto;
1658
1659 &.panel {
1660 padding: 0 16px 16px;
1661 }
1662
1663 &.full {
1664 height: 100%;
1665 }
1666
1667 .template_panel {
1668 display: flex;
1669 flex-wrap: wrap;
1670 padding: 16px 16px 8px;
1671
1672 .title_item {
1673 display: flex;
1674 margin-bottom: 8px;
1675
1676 +.title_item {
1677 margin-left: 40px;
1678 }
1679
1680 .title_label {
1681 display: block;
1682 width: 80px;
1683 line-height: 1.5;
1684 }
1685
1686 .title_text {
1687 line-height: 1.5;
1688 }
1689
1690 &.is_block {
1691 width: 100%;
1692 margin-left: 0;
1693
1694 .title_text {
1695 display: block;
1696 width: calc(100% - 80px);
1697 text-align: justify;
1698 }
1699 }
1700 }
1701 }
1702
1703 .panel_content {
1704 height: 100%;
1705 display: flex;
1706 flex: 1;
1707 border-top: 1px solid #d9d9d9;
1708
1709 .box_left {
1710 width: 200px;
1711 height: 100%;
1712 border-right: 1px solid #d9d9d9;
1713
1714 .aside_title {
1715 padding: 0 8px;
1716 height: 40px;
1717 line-height: 40px;
1718 font-size: 14px;
1719 color: #212121;
1720 font-weight: 600;
1721 }
1722
1723 .tree_panel {
1724 height: 100%;
1725 }
1726 }
1727
1728 .box_right {
1729 width: calc(100% - 200px);
1730 padding-top: 8px;
1731
1732 .el-breadcrumb {
1733 padding: 0 12px;
1734 line-height: 40px;
1735 }
1736 }
1737 }
1738
1739 .table_panel_wrap {
1740 width: 100%;
1741 height: 100%;
1742 padding: 0 12px;
1743
1744 &.full {
1745 padding: 0;
1746 }
1747 }
1748
1749 :deep(.el-card) {
1750 .table_panel {
1751 height: auto;
1752
1753 &.full {
1754 height: 212px;
1755 }
1756 }
1757 }
1758 }
1759
1760 .tool_btns {
1761 height: 44px;
1762 margin: 0 -8px;
1763 display: flex;
1764 justify-content: center;
1765 align-items: center;
1766 border-top: 1px solid #d9d9d9;
1767 }
1768 }
1769
1770 .row-add-btn {
1771 .el-button--default {
1772 padding: 4px 0px;
1773 margin-top: 4px;
1774 }
1775
1776 :deep(.el-icon) {
1777 width: 16px;
1778 height: 16px;
1779
1780 svg {
1781 width: 16px;
1782 height: 16px;
1783 }
1784 }
1785 }
1786
1787 .title {
1788 color: #212121;
1789 font-size: 14px;
1790 line-height: 32px;
1791 font-weight: 600;
1792 }
1793
1794 .list_panel {
1795 display: flex;
1796 flex-wrap: wrap;
1797 display: flex;
1798 align-items: center;
1799
1800 .list_item {
1801 width: 33.33%;
1802 line-height: 32px;
1803 font-size: 14px;
1804 color: var(--el-text-color-regular);
1805 display: flex;
1806 justify-content: space-between;
1807 min-width: 120px;
1808
1809 .item_label {
1810 text-align: left;
1811 }
1812
1813 .item_value {
1814 color: var(--el-color-regular);
1815 padding: 0 4px;
1816 flex: 1;
1817 text-align: justify;
1818 min-width: 0;
1819 }
1820
1821 &.is_block {
1822 width: 100%;
1823
1824 .item_value {
1825 white-space: pre-wrap;
1826 }
1827 }
1828 }
1829 }
1830 </style>
1 <route lang="yaml">
2 name: certificationAudit
3 </route>
4
5 <script lang="ts" setup name="certificationAudit">
6 import { ref } from 'vue';
7 import TableTools from "@/components/Tools/table_tools.vue";
8 import { ElMessage, ElMessageBox } from 'element-plus';
9 import { getParamsList } from "@/api/modules/queryService";
10 import { getTaskGressList, getTaskRestart, getTaskExecutionLog, getFlowEnterpriseList, enterpriseDelete, enterpriseChangeDelete } from "@/api/modules/dataRequire";
11 import { passFlowData, rejectFlowData, myLastNode } from "@/api/modules/workFlowService";
12 import useDataAssetStore from "@/store/modules/dataAsset";
13 import Moment from "moment";
14 import { TableColumnWidth } from '@/utils/enum';
15 import DialogApproval from '@/components/ApprovalProcess/dialog_approval.vue';
16
17 const assetStore = useDataAssetStore();
18
19 const router = useRouter();
20 const { proxy } = getCurrentInstance() as any;
21
22 const userData = JSON.parse(localStorage.userData);
23
24 const loading = ref(false);
25 const typeMap: any = ref({});
26 const isLastNode = ref(false);
27 const searchItemList = ref([
28 {
29 type: "input",
30 label: "",
31 field: "tenantName",
32 default: "",
33 placeholder: "企业名称",
34 clearable: true,
35 },
36 {
37 type: 'select',
38 label: '',
39 field: 'tenantType',
40 default: '',
41 placeholder: '机构类型',
42 options: [],
43 filterable: true,
44 clearable: true
45 },
46 // {
47 // type: 'select',
48 // label: '',
49 // field: 'canContinueCollaborate',
50 // default: '',
51 // placeholder: '能否合作',
52 // options: [
53 // { label: '能', value: 'Y' },
54 // { label: '不能', value: 'N' }
55 // ],
56 // clearable: true
57 // },
58 ]);
59
60 const systemApproveCurrentRowInfo: any = ref({})
61
62 const approvalDialogVisible = ref(false);
63
64 const handleApprovalDialogCancel = () => {
65 approvalDialogVisible.value = false;
66 }
67
68 const tableFields: any = ref([
69 { label: "序号", type: "index", width: 56, align: "center" },
70 { label: "企业名称", field: "param1", width: 200, },
71 { label: "统一社会信用代码", field: "param3", width: 160 },
72 {
73 label: "法人姓名", field: "juridicalPerson", width: TableColumnWidth.USERNAME, getName: (scope) => {
74 const param4 = scope.row.param4 || '';
75 return param4 ? param4.split('_')[0] : '--'
76 }
77 },
78 {
79 label: "管理员姓名", field: "contacts", width: TableColumnWidth.USERNAME, getName: (scope) => {
80 const param4 = scope.row.param4 || '';
81 return param4 ? param4.split('_')[1] : '--'
82 }
83 },
84 {
85 label: "管理员手机号", field: "contactTel", width: 120, getName: (scope) => {
86 const param4 = scope.row.param4 || '';
87 return param4 ? param4.split('_')[2] : '--'
88 }
89 },
90 {
91 label: "审批状态", field: "bizApproveState", type: "tag", width: TableColumnWidth.STATE, align: 'center', getName: (scope) => {
92 const approveState = scope.row.bizApproveState
93 switch (approveState) {
94 case 'N':
95 return '草稿中';
96 case 'A':
97 return '审批中';
98 case 'Y':
99 return '已通过';
100 case 'R':
101 return '已驳回';
102 case 'C':
103 return '已撤销';
104 case 'D':
105 return '已废弃';
106 default:
107 return '--';
108 }
109 }, tagType: (scope) => {
110 const approveState = scope.row.bizApproveState
111 switch (approveState) {
112 case 'A':
113 return 'warning';
114 case 'Y':
115 return 'success';
116 case 'R':
117 return 'danger';
118 default:
119 return 'info';
120 }
121 }
122 },
123 {
124 label: "主平台审批状态", field: "crossPlatformApproveState", type: "approveTagBtn", width: 150, align: 'center', btn: {
125 label: '查看', visible: (scope) => {
126 return scope.row.crossPlatformApproveState != null;
127 }, click: (scope) => {
128 systemApproveCurrentRowInfo.value = scope.row;
129 approvalDialogVisible.value = true;
130 }
131 }
132 },
133 {
134 label: "提交时间", field: "createTime", width: TableColumnWidth.DATETIME, getName: (scope) => {
135 return scope.row.createTime ? Moment(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') : '--';
136 }
137 },
138 ]);
139
140 const page = ref({
141 limit: 50,
142 curr: 1,
143 sizes: [
144 { label: "10", value: 10 },
145 { label: "50", value: 50 },
146 { label: "100", value: 100 },
147 { label: "150", value: 150 },
148 { label: "200", value: 200 },
149 ],
150 tenantName: '',
151 tenantType: '',
152 canContinueCollaborate: ''
153 });
154 const currTableData: any = ref({});
155 const tableInfo = ref({
156 id: 'value-asset-table',
157 rowKey: 'guid',
158 loading: false,
159 fields: tableFields.value,
160 data: [],
161 page: {
162 type: "normal",
163 rows: 0,
164 ...page.value,
165 },
166 actionInfo: {
167 label: "操作",
168 type: "btn",
169 width: 180,
170 btns: (scope) => {
171 let row = scope.row;
172 return getTableBtns(row);
173 }
174 }
175 });
176
177 const getTableBtns = (row, includeDetail = true) => {
178 let btnsArr: any[] = [];
179 const currentStaffGuid = userData.staffGuid;
180 const approveState = row.bizApproveState || 'N';
181 const approveStaffGuids = row.approveStaffGuids || [];
182 const staffGuid = row.staffGuid || '';
183 let flowState;
184 if (approveState == 'N' && staffGuid == currentStaffGuid) {
185 flowState = 1;
186 }
187 if (approveState == 'A' && approveStaffGuids.indexOf(currentStaffGuid) > -1) {
188 flowState = 2;
189 }
190 if ((approveState == 'C' || approveState == 'R') && staffGuid == currentStaffGuid) {
191 flowState = 3;
192 }
193 if (row.flowType == '10013' && approveState == 'Y') {
194 flowState = 4;
195 }
196
197 btnsArr.push({ label: "详情", value: "detail" })
198 if (flowState === 1) {
199 btnsArr.push({ label: "删除", value: "delete" })
200 } else if (flowState === 2) {
201 btnsArr.push(...[{ label: "通过", value: "pass" }, { label: "驳回", value: "reject" }])
202 } else if (flowState === 3) {
203 btnsArr.push({ label: "删除", value: "delete" })
204 } else if (flowState === 4) {
205 btnsArr.push({ label: "查看进度", value: "progress" })
206 }
207 return btnsArr
208 }
209
210 /**
211 * 传入多个promise对象,当全部结束时取消Loading
212 * @param promises 传入多个promise对象,当全部结束时取消Loading
213 */
214 const promiseList = async (...promises: Promise<void>[]) => {
215 try {
216 await Promise.all(promises).then((res) => {
217 setTableField();
218 });
219 } catch (e) {
220 loading.value = false;
221 }
222 };
223
224 // 获取需求类型
225 const getDataType = (dictType, fieldName) => {
226 return getParamsList({ dictType }).then((res: any) => {
227 if (res.code == proxy.$passCode) {
228 const data = res.data || [];
229 typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
230 let item = searchItemList.value.find(item => item.field == fieldName);
231 item && (item.options = data);
232 } else {
233 proxy.$ElMessage.error(res.msg);
234 }
235 })
236 }
237
238 const setTableField = () => {
239 tableFields.value.splice(2, 0, {
240 label: "机构类型", field: "tenantType", width: 120, getName: (scope) => {
241 const datas = typeMap.value.tenantType;
242 return datas.find((item) => item.value == scope.row.param2)?.label || '--';
243 }
244 });
245 }
246
247 const toSearch = (val: any, clear: boolean = false) => {
248 page.value.curr = 1;
249 if (clear) {
250 searchItemList.value.map((item) => (item.default = ""));
251 page.value.tenantName = '';
252 page.value.tenantType = "";
253 page.value.canContinueCollaborate = "";
254 } else {
255 page.value.tenantName = val.tenantName || '';
256 page.value.tenantType = val.tenantType || '';
257 page.value.canContinueCollaborate = val.canContinueCollaborate || '';
258 }
259 getTableData();
260 };
261
262 const getTableData = () => {
263 tableInfo.value.loading = true;
264 getFlowEnterpriseList({
265 pageSize: page.value.limit,
266 pageIndex: page.value.curr,
267 param1Like: page.value.tenantName,
268 param2: page.value.tenantType,
269 flowTypeList: ["10013", "10014"],
270 tenantGuid: userData.tenantGuid,
271 staffGuid: userData.staffGuid,
272 }).then((res: any) => {
273 tableInfo.value.loading = false;
274 if (res.code == proxy.$passCode) {
275 const data = res.data || {};
276 tableInfo.value.data = data.records || [];
277 tableInfo.value.page.curr = res.data.pageIndex;
278 tableInfo.value.page.limit = res.data.pageSize;
279 tableInfo.value.page.rows = res.data.totalRows || 0;
280 } else {
281 ElMessage.error(res.msg);
282 }
283 }).catch(() => {
284 tableInfo.value.loading = false;
285 })
286 }
287
288 const tableBtnClick = (scope, btn) => {
289 const type = btn.value;
290 const row = scope.row;
291 currTableData.value = row;
292 if (type === 'detail') { // 详情
293 router.push({
294 name: 'certificationAuditDetail',
295 query: { guid: row.flowType == '10014' ? row.objectGuid : row.bizGuid, name: row.param1, tName: row.tenantName, fType: row.flowType, bizGuid: row.bizGuid, type }
296 });
297 } else if (type == "delete") {
298 delTableOpen("此操作将永久删除该认证信息,是否继续?", "warning");
299 } else if (type === 'pass') {
300 if (row.tenantName == '非认证会员') {
301 myLastNode({ deploymentId: row.camundaDeploymentId, processInstanceId: row.camundaInstanceId, staffGuid: userData.staffGuid }).then((res: any) => {
302 if (res?.code == proxy.$passCode) {
303 isLastNode.value = res.data;
304 passDialogInfo.value.visible = true;
305 } else {
306 ElMessage.error(res.msg);
307 }
308 }).catch(() => {
309 ElMessage.error('流程信息获取失败!');
310 });
311 } else {
312 passDialogInfo.value.visible = true;
313 }
314 } else if (type == 'reject') {
315 rejectDialogInfo.value.visible = true;
316 } else if (type == 'progress') {
317 loading.value = true;
318 getTaskGressList({ bizGuid: row.bizGuid }).then((res: any) => {
319 loading.value = false;
320 if (res?.code == proxy.$passCode) {
321 const data = res.data.records || [];
322 gressTableData.value = data;
323 gressDialogInfo.value.tableInfo.data = gressTableData.value;
324 gressDialogInfo.value.visible = true;
325 } else {
326 ElMessage.error(res.msg);
327 }
328 }).catch(() => {
329 loading.value = false;
330 ElMessage.error('进度信息获取失败!');
331 });
332 } else if (type == 'log') {
333 getTaskExecutionLog({ guid: row.guid }).then((res: any) => {
334 if (res?.code == proxy.$passCode) {
335 drawerInfo.value.container.contents[0].listInfo.data = res.data || '';
336 gressDialogInfo.value.visible = false;
337 drawerInfo.value.visible = true
338 } else {
339 ElMessage.error(res.msg);
340 }
341 }).catch(() => {
342 ElMessage.error('日志信息获取失败!');
343 });
344 } else if (type == 'restart') {
345 ElMessageBox.confirm('确定要重建该流程吗?', "提示", {
346 confirmButtonText: "确定",
347 cancelButtonText: "取消",
348 type: "warning",
349 }).then(() => {
350 getTaskRestart({ guid: row.guid }).then((res: any) => {
351 if (res?.code == proxy.$passCode) {
352 ElMessage.success('流程已重建!');
353 gressDialogInfo.value.visible = false;
354 getTableData();
355 } else {
356 ElMessage.error(res.msg);
357 }
358 });
359 }).catch(() => {
360 ElMessage({
361 type: 'info',
362 message: '已取消重建'
363 });
364 });
365 }
366 };
367
368 const delTableOpen = (msg, type, isBatch: boolean = false) => {
369 ElMessageBox.confirm(msg, "提示", {
370 confirmButtonText: "确定",
371 cancelButtonText: "取消",
372 type: type,
373 }).then(() => {
374 let guids: any = [], method: any = null;
375 guids = [currTableData.value.bizGuid]
376 if(currTableData.value.flowType == '10013'){
377 method = enterpriseDelete(guids)
378 } else {
379 method = enterpriseChangeDelete(guids)
380 }
381 method.then((res: any) => {
382 if (res.code == proxy.$passCode) {
383 page.value.curr = 1;
384 getTableData();
385 ElMessage({
386 type: "success",
387 message: "删除该认证信息成功",
388 });
389 } else {
390 ElMessage({
391 type: "error",
392 message: res.msg,
393 });
394 }
395 })
396 }).catch(() => {
397 ElMessage({
398 type: 'info',
399 message: '已取消删除'
400 });
401 });
402 };
403
404 const tablePageChange = (info) => {
405 page.value.curr = Number(info.curr);
406 page.value.limit = Number(info.limit);
407 getTableData();
408 };
409
410 const passDialogInfo = ref({
411 visible: false,
412 size: 460,
413 direction: "column",
414 header: {
415 title: "通过",
416 },
417 type: '',
418 contents: [
419 {
420 type: 'form',
421 title: '',
422 formInfo: {
423 id: 'batch-pass-form',
424 items: [
425 {
426 label: '',
427 type: "textarea",
428 placeholder: "请确认该企业是否签署合同,如果是才能进行通过,请知晓!(非必填)",
429 field: "approveSuggest",
430 clearable: true,
431 block: true,
432 col: 'margin_b_0',
433 }
434 ]
435 }
436 }
437 ],
438 footer: {
439 btns: [
440 { type: "default", label: "取消", value: "cancel" },
441 { type: "primary", label: "确定", value: "submit", loading: false },
442 ],
443 },
444 });
445
446 const passDialogBtnClick = (btn, info) => {
447 if (btn.value == 'submit') {
448 passDialogInfo.value.footer.btns[1].loading = true;
449 let params = {
450 guid: currTableData.value.guid,
451 flowType: currTableData.value.flowType,
452 approveSuggest: info.approveSuggest,
453 approveStaffGuid: userData.staffGuid,
454 }
455 passFlowData(params).then((res: any) => {
456 passDialogInfo.value.footer.btns[1].loading = false;
457 if (res?.code == proxy.$passCode) {
458 if (res.data) {
459 ElMessage.success(isLastNode.value ? '正在生成数据,需要15分钟左右,请耐心等待!' : '审批成功');
460 passDialogInfo.value.visible = false;
461 getTableData();
462 } else {
463 ElMessage.error('审批失败');
464 }
465 } else {
466 ElMessage.error(res.msg);
467 }
468 }).catch(() => {
469 passDialogInfo.value.footer.btns[1].loading = false;
470 });
471 // if (isLastNode.value) {
472 // enterpriseApprove(params).then((res: any) => {
473 // passDialogInfo.value.footer.btns[1].loading = false;
474 // if (res?.code == proxy.$passCode) {
475 // if (res.data) {
476 // ElMessage.success('正在生成数据,需要3分钟左右,请耐心等待!');
477 // passDialogInfo.value.visible = false;
478 // getTableData();
479 // } else {
480 // ElMessage.error('审批失败');
481 // }
482 // } else {
483 // ElMessage.error(res.msg);
484 // }
485 // }).catch(() => {
486 // passDialogInfo.value.footer.btns[1].loading = false;
487 // });
488 // } else {
489 // passFlowData(params).then((res: any) => {
490 // passDialogInfo.value.footer.btns[1].loading = false;
491 // if (res?.code == proxy.$passCode) {
492 // if (res.data) {
493 // ElMessage.success('审批成功');
494 // passDialogInfo.value.visible = false;
495 // getTableData();
496 // } else {
497 // ElMessage.error('审批失败');
498 // }
499 // } else {
500 // ElMessage.error(res.msg);
501 // }
502 // }).catch(() => {
503 // passDialogInfo.value.footer.btns[1].loading = false;
504 // });
505 // }
506 } else if (btn.value == 'cancel') {
507 passDialogInfo.value.visible = false;
508 }
509 };
510
511 const rejectDialogInfo = ref({
512 visible: false,
513 size: 460,
514 direction: "column",
515 header: {
516 title: "驳回",
517 },
518 type: '',
519 contents: [
520 {
521 type: 'form',
522 title: '',
523 formInfo: {
524 id: 'batch-reject-form',
525 items: [
526 {
527 label: '',
528 type: "textarea",
529 placeholder: "请填写驳回理由(必填)",
530 field: "approveSuggest",
531 clearable: true,
532 block: true,
533 col: 'margin_b_0',
534 }
535 ]
536 }
537 }
538 ],
539 footer: {
540 btns: [
541 { type: "default", label: "取消", value: "cancel" },
542 { type: "primary", label: "确定", value: "submit", loading: false },
543 ],
544 },
545 });
546
547 const rejectDialogBtnClick = (btn, info) => {
548 if (btn.value == 'submit') {
549 if (info.approveSuggest == '') {
550 ElMessage.error('请填写驳回理由');
551 return
552 }
553 rejectDialogInfo.value.footer.btns[1].loading = true;
554 let params = {
555 guid: currTableData.value.guid,
556 flowType: currTableData.value.flowType,
557 approveSuggest: info.approveSuggest,
558 approveStaffGuid: userData.staffGuid,
559 }
560 rejectFlowData(params).then((res: any) => {
561 rejectDialogInfo.value.footer.btns[1].loading = false;
562 if (res?.code == proxy.$passCode) {
563 if (res.data) {
564 ElMessage.success('驳回成功');
565 rejectDialogInfo.value.visible = false;
566 getTableData();
567 } else {
568 ElMessage.error('驳回失败');
569 }
570 } else {
571 ElMessage.error(res.msg);
572 }
573 }).catch(() => {
574 rejectDialogInfo.value.footer.btns[1].loading = false;
575 });
576 } else if (btn.value == 'cancel') {
577 rejectDialogInfo.value.visible = false;
578 }
579 };
580
581 const gressTableData: any = ref([]);
582 const gressDialogInfo: any = ref({
583 visible: false,
584 size: 780,
585 direction: "column",
586 tableInfo: {
587 id: 'gress-dialog-table',
588 fileds: [
589 {
590 label: '执行状态', field: 'executeState', width: 100, align: 'center', type: 'tag', getName: (scope) => {
591 const executeState = scope.row.executeState || '--';
592 switch (executeState) {
593 case '0':
594 return '未执行';
595 case '1':
596 return '执行中';
597 case '2':
598 return '执行成功';
599 case '3':
600 return '执行失败';
601 }
602 }, tagType: (scope) => {
603 const executeState = scope.row.executeState || 'info';
604 switch (executeState) {
605 case '0':
606 return 'info';
607 case '1':
608 return 'warning';
609 case '2':
610 return 'success';
611 case '3':
612 return 'danger';
613 }
614 }
615 },
616 { label: '失败原因', field: 'failReason', width: 200 },
617 {
618 label: '执行时间', field: 'taskTime', minWidth: 340, getName: (scope) => {
619 // return proxy.$moment(scope.row.startTime).format('YYYY-MM-DD HH:mm:ss') : '';
620 return `${scope.row.startTime || '--'}${scope.row.endTime || '--'}`;
621 }
622 }
623 ],
624 data: [],
625 btns: (scope) => {
626 let btnArr = [{ label: '日志', value: 'log' }];
627 const exIndex = gressTableData.value.findIndex(item => item.executeState == '3');
628 exIndex != -1 && exIndex == scope.$index && btnArr.push({ label: '重建', value: 'restart' });
629 return btnArr;
630 }
631 },
632 footer: {
633 visible: false,
634 btns: [
635 { type: "default", label: "取消", value: "cancel" },
636 { type: "primary", label: "确定", value: "submit" },
637 ],
638 },
639 })
640
641 const gressDialogBtnClick = (btn) => {
642 if (btn.value == 'submit') {
643
644 } else if (btn.value == 'cancel') {
645 gressDialogInfo.value.visible = false;
646 }
647 }
648
649
650 const drawerInfo = ref({
651 visible: false,
652 direction: "rtl",
653 size: '100%',
654 modal: true,
655 modalClose: true,
656 header: {
657 title: "日志详情",
658 },
659 container: {
660 contents: [
661 {
662 type: 'content',
663 listInfo: {
664 data: '',
665 type: 'html'
666 }
667 }
668 ],
669 },
670 footer: {
671 visible: false,
672 },
673 });
674
675 const drawerBtnClick = (btn) => {
676 drawerInfo.value.visible = false;
677 gressDialogInfo.value.visible = true;
678 };
679
680 onBeforeMount(() => {
681 promiseList(
682 getDataType('机构类型', 'tenantType'),
683 )
684 });
685
686 onActivated(() => {
687 if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
688 page.value.curr = 1;
689 getTableData();
690 assetStore.set(false);
691 }
692 })
693
694 </script>
695
696 <template>
697 <div class="container_wrap">
698 <div class="table_tool_wrap">
699 <TableTools :searchItems="searchItemList" :searchId="'value-asset-search'" @search="toSearch" :init="true" />
700 </div>
701 <div class="table_panel_wrap full">
702 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
703 </div>
704 <Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
705 <Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
706 <el-dialog v-model="gressDialogInfo.visible" title="查看进度" :width="gressDialogInfo.size">
707 <div class="table_panel">
708 <el-table border :data="gressDialogInfo.tableInfo.data" style="height: 100%;" tooltip-effect="light">
709 <el-table-column type="index" width="56" label="序号" align="center" />
710 <el-table-column label="任务内容" width="200">
711 <template #default="scope">
712 <span>创建会员、库及绑定流程</span>
713 </template>
714 </el-table-column>
715 <el-table-column v-for="item in gressDialogInfo.tableInfo.fileds" :key="item.field" :label="item.label"
716 :width="item.width" :min-width="item.minWidth" :fixed="item.fixed" :align="item.align"
717 :sortable="item.sortable ?? false" :prop="item.field" :class-name="item.columClass" show-overflow-tooltip>
718 <template #default="scope" v-if="item.type == 'tag'">
719 <el-tag :type="item.tagType ? item.tagType(scope) : ''">{{ item.getName ? item.getName(scope) :
720 scope.row[item.field] !== 0 && !scope.row[item.field] ?
721 "--" : scope.row[item.field] }}</el-tag>
722 </template>
723 <template #default="scope" v-else>
724 <span>
725 {{ item.getName ? item.getName(scope) : scope.row[item.field] !== 0 && !scope.row[item.field] ?
726 "--" : scope.row[item.field] }}
727 </span>
728 </template>
729 </el-table-column>
730 <el-table-column label="操作" width="100" fixed="right">
731 <template #default="scope">
732 <span v-for="(btn, b) in gressDialogInfo.tableInfo.btns(scope)" :key="'btn_' + b" class="text_btn"
733 @click="tableBtnClick(scope, btn)">{{ btn.label }}</span>
734 </template>
735 </el-table-column>
736 </el-table>
737 </div>
738 <template #footer v-if="gressDialogInfo.footer.visible ?? true">
739 <div class="dialog-footer">
740 <template v-for="btn in gressDialogInfo.footer.btns" :key="btn.value">
741 <el-button v-if="btn.visible ?? true" :type="btn.type" :disabled="btn.disabled ?? false"
742 :loading="btn.loading ?? false" @click="gressDialogBtnClick(btn)" v-preReClick>{{ btn.label }}</el-button>
743 </template>
744 </div>
745 </template>
746 </el-dialog>
747 <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" />
748 <DialogApproval :visible="approvalDialogVisible" :currentRowInfo="systemApproveCurrentRowInfo"
749 @dialog-cancel="handleApprovalDialogCancel"></DialogApproval>
750 </div>
751 </template>
752
753 <style scoped lang="scss">
754 .container_wrap {
755 padding: 0 16px;
756 }
757
758 :deep(.el-dialog) {
759 .table_panel {
760 padding: 8px 0;
761 height: 228px;
762
763 .text_btn+.text_btn {
764 margin-left: 8px;
765 }
766
767 .el-popper {
768
769 >span {
770 &:first-child {
771 display: inline-block;
772 max-height: 200px;
773 margin: 0 -11px;
774 padding: 0 11px;
775 overflow: hidden auto;
776 }
777 }
778 }
779 }
780 }
781 </style>
1 <route lang="yaml">
2 name: certificationAuditDetail //企业认证详情
3 </route>
4
5 <script lang="ts" setup name="certificationAuditDetail">
6 import { ref, onMounted } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import { ElMessage, ElMessageBox } from "element-plus";
9 import { CircleCloseFilled } from '@element-plus/icons-vue'
10 import useUserStore from "@/store/modules/user";
11 import useDataAssetStore from "@/store/modules/dataAsset";
12 import { getEnterpriseDetail, enterpriseApprove } from "@/api/modules/dataRequire";
13 import { getAreaData, getParamsList } from "@/api/modules/queryService";
14 import { getLastChange, passFlowData, rejectFlowData, myLastNode, crossPlatformApprove } from "@/api/modules/workFlowService";
15 import Moment from "moment";
16 import { onUploadFilePreview } from "@/api/modules/common";
17
18 const { proxy } = getCurrentInstance() as any;
19 const router = useRouter();
20 const route = useRoute();
21 const userStore = useUserStore();
22 const userData = JSON.parse(localStorage.userData)
23 const fullPath = route.fullPath;
24 const assetStore = useDataAssetStore();
25 const guid = route.query.guid;
26 const detailType = route.query.type;
27 const tName = route.query.tName;
28 const fType = route.query.fType;
29
30 const bizGuid = route.query.bizGuid;
31 const loading = ref(false);
32 const flowDetail: any = ref({});
33 const approveState = ref('');
34 const typeMap: any = ref({});
35 const getAreaDataPromise: any = ref({});
36 const getAreaDatas: any = ref({});
37 const flowState = ref(0);
38 const isLastNode = ref(false);
39 const latestDate = ref('');
40 const approvalProcessRef = ref();
41 const beforeChangeList = ref([]);
42
43 const industryList: any = ref([]);
44
45 const getArea = (node, resolve) => {
46 const { level } = node
47 let params = {
48 parentGuid: node.value
49 }
50 if (getAreaDatas.value[node.value]?.length) {
51 resolve(getAreaDatas.value[node.value]);
52 return;
53 }
54 if (!getAreaDataPromise.value[node.value]) {
55 getAreaDataPromise.value[node.value] = getAreaData(params).then((res: any) => {
56 getAreaDataPromise.value[node.value] = null;
57 node.loaded = true;
58 if (res?.code == proxy.$passCode) {
59 const data = res.data ?? []
60 data.map(item => {
61 item.leaf = level >= 2
62 })
63 resolve(data)
64 getAreaDatas.value[node.value] = data;
65 return res.data ?? [];
66 }
67 })
68 } else {
69 getAreaDataPromise.value[node.value].then((data) => {
70 getAreaDataPromise.value[node.value] = null;
71 node.loaded = true;
72 data.map(item => {
73 item.leaf = level >= 1
74 })
75 resolve(data)
76 })
77 }
78 }
79
80 const detailGuid = ref('');
81 const expand1 = ref(true)
82 const expand2 = ref(true)
83 const expand3 = ref(true)
84 const expand4 = ref(true)
85 const expand5 = ref(true)
86 const expand6 = ref(true)
87 const deploymentId = ref('');
88 const processInstanceId = ref('')
89 const expand7 = ref(true);
90 const uploadInfoExpand = ref(true);
91 const expandResult = ref(true);
92
93 // 企业信息
94 const contentFormItems: any = ref([
95 {
96 label: '企业名称',
97 type: 'input',
98 placeholder: '请输入',
99 field: 'tenantName',
100 default: '',
101 maxlength: 50,
102 clearable: true,
103 required: true,
104 disabled: true
105 },
106 {
107 label: '统一社会信用代码',
108 type: 'input',
109 placeholder: '请输入',
110 field: 'socialCreditCode',
111 default: '',
112 maxlength: 50,
113 clearable: true,
114 required: true,
115 disabled: true
116 },
117 {
118 label: '机构类型',
119 type: 'select',
120 placeholder: '请选择',
121 field: 'tenantType',
122 default: '',
123 options: [],
124 clearable: true,
125 required: true,
126 disabled: true
127 },
128 {
129 label: '组织机构性质',
130 type: 'select',
131 placeholder: '请选择',
132 field: 'institutionType',
133 default: '',
134 options: [],
135 clearable: true,
136 filterable: true,
137 disabled: true,
138 required: true,
139 },
140 {
141 label: '公司注册日期',
142 type: 'date',
143 placeholder: '请选择日期',
144 field: 'registrationDate',
145 default: "",
146 unlink: true,
147 clearable: true,
148 required: true,
149 disabled: true
150 },
151 {
152 label: '注册资本(万元)',
153 type: 'input',
154 inputType: 'moneyNumber',
155 field: 'registeredCapital',
156 placeholder: '请输入',
157 default: '',
158 clearable: true,
159 required: true,
160 disabled: true
161 },
162 {
163 label: '税号',
164 type: 'input',
165 placeholder: '请输入',
166 field: 'bankTaxNo',
167 default: '',
168 clearable: true,
169 required: true,
170 disabled: true
171 },
172 {
173 label: '注册地',
174 type: 'cascader',
175 placeholder: '请选择',
176 field: 'area',
177 default: [],
178 props: {
179 label: 'name',
180 value: 'guid',
181 lazy: true,
182 lazyLoad: getArea,
183 },
184 clearable: true,
185 required: true,
186 disabled: true
187 },
188 {
189 label: '详细地址',
190 type: 'input',
191 placeholder: '请输入',
192 field: 'detailedAddress',
193 default: "",
194 maxlength: 250, // 后端是250
195 clearable: true,
196 disabled: true,
197 required: true
198 },
199 {
200 label: '行业分类',
201 type: 'select',
202 placeholder: '请选择',
203 field: 'industry',
204 default: '',
205 options: industryList.value,
206 clearable: true,
207 filterable: true,
208 required: true,
209 disabled: true
210 },
211 {
212 label: '行业小类',
213 type: 'tree-select',
214 placeholder: '请选择',
215 field: 'industrySmallcode',
216 nodeKey: 'value',
217 options: industryList.value,
218 checkStrictly: false,//只能选择叶子节点。
219 lazy: false,
220 multiple: false,
221 props: {
222 label: "label",
223 value: "value",
224 children: 'childDictList'
225 },
226 filterable: true,
227 clearable: true,
228 default: '',
229 disabled: true,
230 required: true,
231 },
232 {
233 label: '营业开始日期',
234 type: 'date',
235 placeholder: '请选择',
236 field: 'businessLicenseStartDate',
237 default: "",
238 unlink: true,
239 clearable: true,
240 disabled: true,
241 required: true,
242 },
243 {
244 label: "营业结束日期",
245 type: "select",
246 placeholder: "请选择",
247 field: "businessLicenseTerm",
248 default: "",
249 options: [
250 {
251 label: "长期有效",
252 value: "1",
253 },
254 {
255 label: "自定义",
256 value: "2",
257 },
258 ],
259 required: true,
260 clearable: true,
261 disabled: true,
262 col: 'error_auto',
263 style: {
264 width: '110px'
265 }
266 },
267 {
268 label: "营业结束日期",
269 type: 'date',
270 placeholder: '请选择',
271 field: "businessLicenseEndDate",
272 default: '',
273 labelClass: 'hide',
274 clearable: true,
275 required: true,
276 visible: false,
277 disabled: true,
278 style: {
279 width: 'calc(33.33% - 124px)'
280 }
281 },
282 {
283 label: '营业执照',
284 type: 'upload-file',
285 field: 'businessLicenseFile',
286 default: [],
287 tip: '请上传最新营业执照原件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
288 accept: '.jpg, .png',
289 required: true,
290 block: true,
291 disabled: true
292 },
293 {
294 label: '公司简介及经营范围',
295 type: 'textarea',
296 focusValue: false,
297 placeholder: '请输入公司简介及经营描述',
298 field: 'businessLicenseScope',
299 default: '',
300 clearable: true,
301 required: true,
302 block: true,
303 maxlength: 1000,
304 disabled: true,
305 col: 'error_textarea',
306 },
307 ])
308 const contentFormRules = ref({
309 tenantName: [
310 { required: true, trigger: 'blur', message: "请填写企业名称" }
311 ],
312 socialCreditCode: [
313 { required: true, trigger: 'blur', message: "请填写统一社会信用代码" }
314 ],
315 tenantType: [
316 { required: true, trigger: 'change', message: "请选择机构类型" }
317 ],
318 institutionType: [
319 { required: true, trigger: 'change', message: "请选择组织机构性质" }
320 ],
321 registrationDate: [
322 { required: true, trigger: 'change', message: "请选择公司注册日期" }
323 ],
324 registeredCapital: [
325 { required: true, trigger: 'blur', message: "请填写注册资本(万元)" }
326 ],
327 bankTaxNo: [
328 { required: true, trigger: 'blur', message: "请填写税号" }
329 ],
330 area: [
331 { required: true, trigger: 'change', message: "请选择注册地" }
332 ],
333 detailedAddress: [
334 { required: true, trigger: 'blur', message: "请填写详细地址" }
335 ],
336 businessLicenseTerm: [
337 { required: true, trigger: 'change', message: "请选择营业结束日期" }
338 ],
339 businessLicenseStartDate: [
340 { required: true, trigger: 'change', message: "请选择营业开始日期" }
341 ],
342 businessLicenseDate: [
343 { required: true, trigger: 'change', message: "请选择营业日期" }
344 ],
345 businessLicenseFile: [{
346 validator: (rule: any, value: any, callback: any) => {
347 if (!value?.length) {
348 callback(new Error('请上传营业执照'))
349 } else {
350 callback();
351 }
352 }, trigger: 'change'
353 }],
354 businessLicenseScope: [
355 { required: true, trigger: 'blur', message: "请填写公司简介及经营范围" }
356 ],
357 });
358 const companyFormRef = ref();
359 const companyForm = ref({
360 items: contentFormItems.value,
361 rules: contentFormRules.value,
362 })
363
364 // 法人信息
365 const corporateFormItems: any = ref([
366 {
367 label: '法定代表人姓名',
368 type: 'input',
369 placeholder: '请输入',
370 field: 'juridicalPerson',
371 default: '',
372 clearable: true,
373 required: true,
374 disabled: true
375 },
376 {
377 label: '法定代表人证件类型',
378 type: 'select',
379 placeholder: '请选择',
380 field: 'juridicalPersonIdType',
381 default: '',
382 options: [],
383 clearable: true,
384 required: true,
385 disabled: true
386 },
387 {
388 label: '法定代表人证件号',
389 type: 'input',
390 placeholder: '请输入',
391 field: 'juridicalPersonId',
392 default: '',
393 clearable: true,
394 required: true,
395 disabled: true
396 },
397 {
398 label: '法定代表人证件正反面',
399 type: 'upload-file',
400 field: 'juridicalPersonIdPhoto',
401 default: [],
402 tip: '请上传最新法定代表人证件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
403 accept: '.jpg, .png',
404 required: true,
405 block: true,
406 disabled: true
407 },
408 ])
409 const corporateFormRules = ref({
410 juridicalPerson: [
411 { required: true, trigger: 'blur', message: "请填写法定代表人姓名" }
412 ],
413 juridicalPersonIdType: [
414 { required: true, trigger: 'change', message: "请选择法人证件类型" }
415 ],
416 juridicalPersonId: [
417 { required: true, trigger: 'blur', message: "请填写法定代表人证件号" }
418 ],
419 juridicalPersonIdPhoto: [{
420 validator: (rule: any, value: any, callback: any) => {
421 if (!value?.length) {
422 callback(new Error('请上传法定代表人证件正反面'))
423 } else {
424 callback();
425 }
426 }, trigger: 'change'
427 }],
428 });
429 const corporateFormRef = ref();
430 const corporateForm = ref({
431 items: corporateFormItems.value,
432 rules: corporateFormRules.value,
433 })
434
435 // 账号信息
436 const accountFormItem = ref([
437 {
438 label: '用户名',
439 type: 'input',
440 placeholder: '请输入',
441 field: 'logonUser',
442 default: userData.mobileNo,
443 clearable: true,
444 required: true,
445 disabled: true
446 },
447 {
448 label: '账号管理人姓名',
449 type: 'input',
450 placeholder: '请输入',
451 field: 'contacts',
452 default: '',
453 clearable: true,
454 required: true,
455 disabled: true
456 },
457 {
458 label: '账号管理人手机号',
459 type: 'input',
460 placeholder: '请输入',
461 field: 'contactTel',
462 default: '',
463 clearable: true,
464 required: true,
465 disabled: true
466 },
467 {
468 label: '账号管理人证件类型',
469 type: 'select',
470 placeholder: '请选择',
471 field: 'handlePersonIdType',
472 default: '1',
473 options: [],
474 disabled: true,
475 clearable: true,
476 required: true,
477 },
478 {
479 label: '账号管理人证件号',
480 type: 'input',
481 placeholder: '请输入',
482 field: 'managerPersonId',
483 default: '',
484 clearable: true,
485 required: true,
486 disabled: true
487 },
488 {
489 label: '账号管理员证件正反面',
490 type: 'upload-file',
491 field: 'managerPersonIdPhoto',
492 default: [],
493 tip: '请上传最新管理员证件的彩色照片或扫描件,如使用复印件请加盖公章,支持扩展名:.jpg .png, 最大5M',
494 accept: '.jpg, .png',
495 required: true,
496 block: true,
497 disabled: true
498 },
499 ]);
500 const accountFormRules = ref({
501 logonUser: [
502 { required: true, trigger: 'blur', message: "请填写用户名" }
503 ],
504 contacts: [
505 { required: true, trigger: 'blur', message: "请填写账号管理人姓名" }
506 ],
507 contactTel: [
508 {
509 validator: (rule: any, value: any, callback: any) => {
510 if (value === '') {
511 callback(new Error('请填写手机号'))
512 } else {
513 const regs = /^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(17[0-9]{1})|(19[0-9]{1})|(18[0-9]{1}))+\d{8})$/
514 if (regs.test(value)) {
515 callback();
516 } else {
517 callback(new Error('请填写正确的手机号'))
518 }
519 }
520 },
521 trigger: 'blur'
522 },
523 {
524 min: 1,
525 max: 11,
526 message: '请填写账号管理人手机号',
527 trigger: 'change',
528 },
529 ],
530 managerPersonId: [
531 { required: true, trigger: 'blur', message: "账号管理人证件号" }
532 ],
533 managerPersonIdPhoto: [{
534 validator: (rule: any, value: any, callback: any) => {
535 if (!value?.length) {
536 callback(new Error('请上传账号管理员证件正反面'))
537 } else {
538 callback();
539 }
540 }, trigger: 'change'
541 }],
542 });
543 const accountFormRef = ref();
544 const accountForm: any = ref({
545 items: accountFormItem.value,
546 rules: accountFormRules.value,
547 })
548
549 // 协议签署
550 const contractFormItem = ref([
551 {
552 label: '授权委托书',
553 type: 'upload-file',
554 field: 'authorizationLetterFile',
555 default: [],
556 tip: '支持扩展名:.pdf, 最大50M',
557 accept: '.pdf',
558 required: true,
559 block: true,
560 disabled: true
561 },
562 ]);
563 const contractFormRules = ref({
564 authorizationLetterFile: [{
565 validator: (rule: any, value: any, callback: any) => {
566 if (!value?.length) {
567 callback(new Error('请上传授权委托书'))
568 } else {
569 callback();
570 }
571 }, trigger: 'change'
572 }],
573 });
574 const contractFormRef = ref();
575 const contractForm = ref({
576 items: contractFormItem.value,
577 rules: contractFormRules.value,
578 })
579
580 // 历史变更
581 const mergeRowCount: any = ref({});
582 const rowCount = {
583 name: { index: 0, rowspan: [] }
584 };
585 const tableField: any = ref([
586 { label: "变更字段", field: "name", width: 200 },
587 {
588 label: "变更时间", field: "date", width: 120, getName: (scope) => {
589 return scope.row.date ? Moment(scope.row.date).format('YYYY-MM-DD') : '--';
590 }
591 }
592 ]);
593 const tableData = ref([]);
594
595 /**
596 * 传入多个promise对象,当全部结束时取消Loading
597 * @param promises 传入多个promise对象,当全部结束时取消Loading
598 */
599 const promiseList = async (...promises: (() => Promise<void>)[]) => {
600 loading.value = true;
601 try {
602 for (const promise of promises) {
603 await promise(); // 按顺序执行每个 Promise
604 }
605 loading.value = false;
606 // 所有步骤完成后执行的逻辑
607 // if (tableData.value.length) {
608 // const dateRow = tableData.value.reduce((prev: any, current: any) => {
609 // const date1 = new Date(prev.date);
610 // const date2 = new Date(current.date);
611 // return date1 < date2 ? current : prev; // 使用小于号来找到最新的日期
612 // }, tableData.value[0]);
613 // latestDate.value = dateRow.date;
614 // }
615
616 setTableField();
617 setFormItems();
618
619 const approveVO = flowDetail.value.approveVO || {};
620 deploymentId.value = approveVO.camundaDeploymentId || '';
621 processInstanceId.value = approveVO.camundaInstanceId || '';
622 approveState.value = approveVO.approveState || '';
623
624 const approveStaffGuids = approveVO.approveStaffGuids || [];
625 if (approveStaffGuids.indexOf(userData.staffGuid) > -1) {
626 flowState.value = 2;
627 }
628
629 } catch (e) {
630 loading.value = false;
631 }
632 };
633
634 // 获取需求类型
635 const getDataType = async (dictType, fieldName) => {
636 try {
637 const res: any = await getParamsList({ dictType });
638 if (res.code === proxy.$passCode) {
639 const data = res.data || [];
640 typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
641 if (fieldName == 'tenantType' || fieldName == 'institutionType') {
642 let item = contentFormItems.value.find(item => item.field == fieldName);
643 item && (item.options = data);
644 } else {
645 let item = corporateFormItems.value.find(item => item.field == fieldName);
646 item && (item.options = data);
647 if (fieldName == 'juridicalPersonIdType') {
648 typeMap.value[fieldName] = data;
649 let item = accountFormItem.value.find(item => item.field == 'handlePersonIdType');
650 item && (item.options = data);
651 }
652 }
653 } else {
654 proxy.$ElMessage.error(res.msg);
655 }
656 } catch (error) {
657 throw error; // 将错误向上抛出
658 }
659 }
660
661 const setErrorMsg = (item: any) => {
662 setTimeout(() => {
663 const field = item.field;
664 if (field == 'area') {
665 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == 'venue');
666 row && (item.validateStatus = 'error', item.error = `变更前为:${row.before}`)
667 } else if (item.field == 'businessLicenseTerm') {
668 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == 'businessLicenseStartEnd');
669 row && (item.validateStatus = 'error', item.error = `变更前为:${row.before}`)
670 } else if (field == 'tenantType' || field == 'juridicalPersonIdType' || field == 'institutionType') {
671 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == field);
672 if (row) {
673 const cont = typeMap.value[field].find((c: any) => c.value == row.before)?.label || '--';
674 item.validateStatus = 'error';
675 item.error = `变更前为:${cont}`;
676 }
677 } else if (item.field == 'industry') {
678 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == field);
679 if (row) {
680 const cont = industryList.value.find((c: any) => c.value == row.before)?.label || '--';
681 item.validateStatus = 'error';
682 item.error = `变更前为:${cont}`;
683 }
684 } else if (item.field == 'industrySmallcode') {
685 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == field);
686 if (row) {
687 let getChildLabel = (children) => {
688 for (const child of children) {
689 if (child.value == row.before) {
690 return child.label;
691 }
692 let label = getChildLabel(child.childDictList || []);
693 if (label) {
694 return label;
695 }
696 }
697 }
698 let cont = row.before && getChildLabel(industryList.value) || [];
699 item.validateStatus = 'error';
700 item.error = `变更前为:${cont}`;
701 }
702 } else {
703 const row: any = beforeChangeList.value.find((t: any) => t.nameEn == field);
704 row && (item.validateStatus = 'error', item.error = `变更前为:${row.before}`)
705 if (field == 'businessLicenseScope' && row) {
706 setTimeout(() => {
707 const errorDom: any = document.querySelector('.error_textarea .el-form-item__error');
708 errorDom && (errorDom.title = row.before);
709 }, 3000)
710 }
711 }
712 }, 1000)
713 }
714
715 const setFormItems = () => {
716 const datas = JSON.parse(JSON.stringify(flowDetail.value));
717 contentFormItems.value.map((a, index) => {
718 if (a.field == 'tenantName') {
719 a.default = datas[a.field] || userData.staffName;
720 } else if (a.field == 'registeredCapital') {
721 a.default = Number.isNaN(datas[a.field]) ? '' : datas[a.field];
722 } else if (a.field == 'socialCreditCode') {
723 a.default = datas[a.field] || userData.staffNo;
724 } else if (a.field == 'area') {
725 a.default = datas.province ? [datas.province, datas.city, datas.district] : [];
726 } else if (a.field == 'businessLicenseEndDate') {
727 a.visible = datas.businessLicenseTerm == '2';
728 a.default = datas[a.field] || '';
729 } else if (a.field == 'businessLicenseFile') {
730 a.default = JSON.parse(datas.businessLicenseJson || '[]');
731 } else if (a.field == 'industry') {
732 a.default = datas[a.field] || '';
733 contentFormItems.value[index + 1].options = !a.default ? [] : industryList.value.find(i => i.value == a.default)?.childDictList || [];
734 } else {
735 a.default = datas[a.field] || '';
736 }
737 let f = a;
738 (() => {
739 setErrorMsg(f);
740 })()
741 })
742 corporateFormItems.value.map(b => {
743 if (b.field == 'juridicalPersonIdPhoto') {
744 b.default = JSON.parse(datas.juridicalPersonIdPhotoJson || '[]');
745 } else {
746 b.default = datas[b.field] || '';
747 }
748 let f = b;
749 (() => {
750 setErrorMsg(f);
751 })()
752 })
753 accountFormItem.value.map(c => {
754 if (c.field == 'logonUser') {
755 c.default = datas[c.field] || userData.mobileNo;
756 } else if (c.field == 'managerPersonIdPhoto') {
757 c.default = JSON.parse(datas.managerPersonIdPhotoJson || '[]');
758 } else {
759 c.default = datas[c.field] || '';
760 }
761 let f = c;
762 (() => {
763 setErrorMsg(f);
764 })()
765 })
766 contractFormItem.value.map(d => {
767 d.default = JSON.parse(datas.authorizationLetter || '[]');
768 let f = d;
769 (() => {
770 setErrorMsg(f);
771 })()
772 })
773 }
774
775 // 获取详情
776 const getDetail = async () => {
777 try {
778 const res1: any = await getParamsList({ dictType: '开发主体附件类型' });
779 if (res1?.code === proxy.$passCode) {
780 uploadFileList.value = res1.data || [];
781 uploadFormItems.value = uploadFileList.value.map(d => {
782 return {
783 label: d.label,
784 tip: '支持扩展名:pdf、png、jpg、rar、zip,单个文件不得大于10M',
785 type: 'upload-file',
786 accept: '.pdf, .png, .jpg, .rar, .zip',
787 required: false,
788 disabled: true,
789 limitSize: 10,
790 default: [],
791 field: `files-${d.value}`,
792 }
793 })
794 } else {
795 proxy.$ElMessage.error(res1.msg);
796 }
797 const res: any = await getEnterpriseDetail({ guid: bizGuid });
798 if (res.code === proxy.$passCode) {
799 const data = res.data || {};
800 deploymentId.value = '';
801 processInstanceId.value = '';
802 flowState.value = 0;
803 flowDetail.value = data;
804 tableData.value = data.changeList || [];
805 beforeChangeList.value = data.beforeChangeList || [];
806 getMergeRow();
807 orgData.value = data.domainRSVOS || [];;
808 orgTableInfo.value.data = orgData.value;
809 let attachmentRQVOS = data.attachmentRSVOS || [];
810 uploadFormItems.value.forEach(item => {
811 let field = item.field;
812 let key = field.slice(6);
813 item.default = attachmentRQVOS.filter(a => a.fileType == key).map(f => {
814 return {
815 name: f.fileName,
816 url: f.fileUrl
817 }
818 })
819 // if (!item.default?.length) {
820 // item.visible = false;
821 // } else {
822 // item.visible = true;
823 // }
824 item.disabled = true;
825 })
826 } else {
827 proxy.$ElMessage.error(res.msg);
828 }
829 } catch (error) {
830 throw error; // 将错误向上抛出
831 }
832 }
833
834 // 获取变更详情
835 const getChangeDetail = async () => {
836 try {
837 const res: any = await getLastChange(bizGuid);
838 if (res.code === proxy.$passCode) {
839 const data = res.data || {};
840 const bizData = JSON.parse(data.bizDataJson || '{}');
841 const approveVO = data.approveVO || {};
842 flowDetail.value = { ...flowDetail.value, approveVO: { ...flowDetail.value.approveVO, ...approveVO }, ...bizData };
843
844 } else {
845 proxy.$ElMessage.error(res.msg);
846 }
847 } catch (error) {
848 throw error; // 将错误向上抛出
849 }
850 }
851
852 const setTableField = () => {
853 tableField.value.splice(2);
854 tableField.value.splice(2, 0, {
855 label: "变更前", field: "before", width: 400, getName: (scope) => {
856 const nameEn = scope.row.nameEn;
857 if (nameEn == 'tenantType' || nameEn == 'juridicalPersonIdType' || nameEn == 'institutionType') {
858 return typeMap.value[nameEn].find((c: any) => c.value == scope.row.before)?.label || '--';
859 } else if (nameEn == 'industry') {
860 return industryList.value.find((c: any) => c.value == scope.row.before)?.label || '--';
861 } else if (nameEn == 'industrySmallcode') {
862 let getChildLabel = (children) => {
863 for (const child of children) {
864 if (child.value == scope.row.before) {
865 return child.label;
866 }
867 let label = getChildLabel(child.childDictList || []);
868 if (label) {
869 return label;
870 }
871 }
872 }
873 return scope.row.before && getChildLabel(industryList.value) || [];
874 } else {
875 return scope.row.before || '--';
876 }
877 }
878 }, {
879 label: "变更后", field: "after", width: 400, getName: (scope) => {
880 const nameEn = scope.row.nameEn;
881 if (nameEn == 'tenantType' || nameEn == 'juridicalPersonIdType' || nameEn == 'institutionType') {
882 return typeMap.value[nameEn].find((c: any) => c.value == scope.row.after)?.label || '--';
883 } else if (nameEn == 'industry') {
884 return industryList.value.find((c: any) => c.value == scope.row.after)?.label || '--';
885 } else if (nameEn == 'industrySmallcode') {
886 let getChildLabel = (children) => {
887 for (const child of children) {
888 if (child.value == scope.row.after) {
889 return child.label;
890 }
891 let label = getChildLabel(child.childDictList || []);
892 if (label) {
893 return label;
894 }
895 }
896 }
897 return scope.row.after && getChildLabel(industryList.value) || [];
898 } else {
899 return scope.row.after || '--';
900 }
901 }
902 });
903 }
904
905 // 设置表格合并下标
906 const getMergeRow = () => {
907 mergeRowCount.value = JSON.parse(JSON.stringify(rowCount));
908 let list = tableData.value;
909 for (var i = 0; i < list.length; i++) {
910 if (i === 0) {
911 //第一个数据 默认合并1行,开始位置下标默认为0
912 for (var m in mergeRowCount.value) {
913 mergeRowCount.value[m].rowspan.push(1);
914 mergeRowCount.value[m].index = 0;
915 }
916 } else {
917 // 根据拥有子级数量进行合并
918 for (var m in mergeRowCount.value) {
919 let mergeRow = mergeRowCount.value[m];
920 if (list[i][m] && list[i][m] === list[i - 1][m]) {
921 mergeRow.rowspan[mergeRow.index] += 1;
922 mergeRow.rowspan.push(0);
923 } else {
924 mergeRow.rowspan.push(1);
925 mergeRow.index = i;
926 }
927 }
928 }
929 }
930 }
931 // 表格行合并
932 const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
933 if (columnIndex === 0) {
934 const mergeInfo = mergeRowCount.value.name;
935 const rowspan = mergeInfo.rowspan[rowIndex];
936 if (rowspan > 0) {
937 return {
938 rowspan,
939 colspan: 1,
940 };
941 } else {
942 return {
943 rowspan: 0,
944 colspan: 0,
945 };
946 }
947 }
948 }
949
950 const toPath = () => {
951 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
952 assetStore.set(true);
953 router.push({ name: 'certificationAudit' })
954 }
955
956 const btnClick = async (btn, bType = null) => {
957 const type = btn.value;
958 if (type === 'pass') {
959 if (tName == '非认证会员') {
960 myLastNode({ deploymentId: deploymentId.value, processInstanceId: processInstanceId.value, staffGuid: userData.staffGuid }).then((res: any) => {
961 if (res?.code == proxy.$passCode) {
962 isLastNode.value = res.data;
963 passDialogInfo.value.visible = true;
964 } else {
965 ElMessage.error(res.msg);
966 }
967 }).catch(() => {
968 ElMessage.error('流程信息获取失败!');
969 });
970 } else {
971 passDialogInfo.value.visible = true;
972 }
973 } else if (type == 'reject') {
974 rejectDialogInfo.value.visible = true;
975 } else if (type == 'cancel') {
976 toPath();
977 }
978 }
979
980 const passDialogInfo = ref({
981 visible: false,
982 size: 460,
983 direction: "column",
984 header: {
985 title: "通过",
986 },
987 type: '',
988 contents: [
989 {
990 type: 'form',
991 title: '',
992 formInfo: {
993 id: 'batch-pass-form',
994 items: [
995 {
996 label: '',
997 type: "textarea",
998 placeholder: "请确认该企业是否签署合同,如果是才能进行通过,请知晓!(非必填)",
999 field: "approveSuggest",
1000 clearable: true,
1001 block: true,
1002 col: 'margin_b_0',
1003 }
1004 ]
1005 }
1006 }
1007 ],
1008 footer: {
1009 btns: [
1010 { type: "default", label: "取消", value: "cancel" },
1011 { type: "primary", label: "确定", value: "submit", loading: false },
1012 ],
1013 },
1014 });
1015
1016 const passDialogBtnClick = (btn, info) => {
1017 if (btn.value == 'submit') {
1018 passDialogInfo.value.footer.btns[1].loading = true;
1019 let params = {
1020 guid: flowDetail.value.approveVO.approveGuid,
1021 flowType: fType,
1022 approveSuggest: info.approveSuggest,
1023 approveStaffGuid: userData.staffGuid,
1024 }
1025 passFlowData(params).then((res: any) => {
1026 passDialogInfo.value.footer.btns[1].loading = false;
1027 if (res?.code == proxy.$passCode) {
1028 if (res.data) {
1029 ElMessage.success(isLastNode.value ? '正在生成数据,需要3分钟左右,请耐心等待!' : '审批成功');
1030 passDialogInfo.value.visible = false;
1031 if (fType == '10014') {
1032 promiseList(() => getDetail(), () => getChangeDetail());
1033 } else {
1034 promiseList(() => getDetail());
1035 }
1036 approvalProcessRef.value?.renderProcessNodes();
1037 } else {
1038 ElMessage.error('审批失败');
1039 }
1040 } else {
1041 ElMessage.error(res.msg);
1042 }
1043 }).catch(() => {
1044 passDialogInfo.value.footer.btns[1].loading = false;
1045 });
1046 } else if (btn.value == 'cancel') {
1047 passDialogInfo.value.visible = false;
1048 }
1049 };
1050
1051 const rejectDialogInfo = ref({
1052 visible: false,
1053 size: 460,
1054 direction: "column",
1055 header: {
1056 title: "驳回",
1057 },
1058 type: '',
1059 contents: [
1060 {
1061 type: 'form',
1062 title: '',
1063 formInfo: {
1064 id: 'batch-reject-form',
1065 items: [
1066 {
1067 label: '',
1068 type: "textarea",
1069 placeholder: "请填写驳回理由(必填)",
1070 field: "approveSuggest",
1071 clearable: true,
1072 block: true,
1073 col: 'margin_b_0',
1074 }
1075 ],
1076 }
1077 }
1078 ],
1079 footer: {
1080 btns: [
1081 { type: "default", label: "取消", value: "cancel" },
1082 { type: "primary", label: "确定", value: "submit", loading: false },
1083 ],
1084 },
1085 });
1086
1087 const rejectDialogBtnClick = (btn, info) => {
1088 if (btn.value == 'submit') {
1089 if (info.approveSuggest == '') {
1090 ElMessage.error('请填写驳回理由');
1091 return
1092 }
1093 rejectDialogInfo.value.footer.btns[1].loading = true;
1094 let params = {
1095 guid: flowDetail.value.approveVO.approveGuid,
1096 flowType: fType,
1097 approveSuggest: info.approveSuggest,
1098 approveStaffGuid: userData.staffGuid,
1099 }
1100 rejectFlowData(params).then((res: any) => {
1101 rejectDialogInfo.value.footer.btns[1].loading = false;
1102 if (res?.code == proxy.$passCode) {
1103 if (res.data) {
1104 ElMessage.success('驳回成功');
1105 rejectDialogInfo.value.visible = false;
1106 if (fType == '10014') {
1107 promiseList(() => getDetail(), () => getChangeDetail());
1108 } else {
1109 promiseList(() => getDetail());
1110 }
1111 approvalProcessRef.value?.renderProcessNodes();
1112 } else {
1113 ElMessage.error('驳回失败');
1114 }
1115 } else {
1116 ElMessage.error(res.msg);
1117 }
1118 }).catch(() => {
1119 rejectDialogInfo.value.footer.btns[1].loading = false;
1120 });
1121 } else if (btn.value == 'cancel') {
1122 rejectDialogInfo.value.visible = false;
1123 }
1124 };
1125
1126 onActivated(() => {
1127 let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath);
1128 if (tab) {
1129 tab.meta.title = `详情-${route.query.name || ''}`;
1130 }
1131 })
1132
1133 onBeforeMount(() => {
1134 if (fType == '10014') {
1135 promiseList(
1136 () => getDataType('机构类型', 'tenantType'),
1137 () => getDataType('证件类型', 'juridicalPersonIdType'),
1138 () => getDataType('组织机构性质', 'institutionType'),
1139 () => getDetail(),
1140 () => getChangeDetail()
1141 )
1142 } else {
1143 promiseList(
1144 () => getDataType('机构类型', 'tenantType'),
1145 () => getDataType('证件类型', 'juridicalPersonIdType'),
1146 () => getDataType('组织机构性质', 'institutionType'),
1147 () => getDetail(),
1148 )
1149 }
1150 getParamsList({ dictType: '行业分类' }).then((res: any) => {
1151 if (res?.code == proxy.$passCode) {
1152 industryList.value = res.data || [];
1153 let index = contentFormItems.value.findIndex(item => item.field == 'industry');
1154 let item = contentFormItems.value[index];
1155 item.options = industryList.value;
1156 contentFormItems.value[index + 1].options = !item.default ? [] : industryList.value.find(i => i.value == item.default)?.childDictList || [];
1157 } else {
1158 res?.msg && proxy.$ElMessage.error(res?.msg);
1159 }
1160 })
1161 })
1162
1163 const orgTableRef = ref();
1164 const orgData: any = ref([]);
1165 /** 领域的字典列表 */
1166 const domainList: any = ref([]);
1167 /** 被授权资源信息的表格配置 */
1168 const orgTableInfo = ref({
1169 id: "org-table",
1170 height: '214px',
1171 fields: [
1172 { label: "序号", type: "index", width: 56, align: "center" },
1173 { label: "领域名称", field: "domainIdName", width: 160, required: true, columClass: 'edit-colum', type: 'edit' },
1174 { label: "授权协议号", field: "authId", width: 180, required: true, columClass: 'edit-colum', type: 'edit' },
1175 {
1176 label: "协议日期", field: "domainTimeRange", width: 200, getName: (scope) => {
1177 return (scope.row.domainStartTime ? Moment(scope.row.domainStartTime).format('YYYY-MM-DD') : '--') + '至' + (scope.row.domainStartTime ? Moment(scope.row.domainEndTime).format('YYYY-MM-DD') : '--');
1178 }
1179 },
1180 { label: "协议签订时间", field: "domainSignTime", width: 180, required: true, columClass: 'edit-colum', type: 'edit' },
1181 { label: "协议签订人", field: "signee", width: 150, required: true, columClass: 'edit-colum', type: 'edit' },
1182 { label: "协议状态", field: "domainStatusName", width: 140, required: true, columClass: 'edit-colum', type: 'edit' },
1183 ],
1184 STATUS: '',
1185 data: orgData.value,
1186 showPage: false,
1187 actionInfo: {
1188 show: false,
1189 },
1190 loading: false
1191 });
1192
1193 const uploadFormRef = ref();
1194
1195 /** 开发主体附件信息 */
1196 const uploadFormItems: any = ref([]);
1197
1198 const uploadFormRules = ref({});
1199
1200 /** 开发主体附件类型的字典 */
1201 const uploadFileList: any = ref([]);
1202
1203 // 查看凭证证书
1204 const viewVoucherFile = () => {
1205 const url = flowDetail.value.trustedIdentityCredential;
1206 if (!url) {
1207 return;
1208 }
1209 onUploadFilePreview(url);
1210 }
1211
1212 </script>
1213
1214 <template>
1215 <div class="container_wrap full" v-loading="loading">
1216 <div class="content_main panel">
1217 <div
1218 v-if="detailType == 'detail' && (flowDetail.crossPlatformApproveState == 'R' || flowDetail.crossPlatformApproveState == 'E')"
1219 :class="['panel_wrap', 'results_panel', 'reject']">
1220 <div class="panel_header">
1221 <div class="header_title" v-if="flowDetail.crossPlatformApproveState == 'R'">
1222 <el-icon class="title-icon">
1223 <CircleCloseFilled />
1224 </el-icon>
1225 <span class="title_text">主平台审批已驳回,请在列表页面查看具体驳回原因</span>
1226 </div>
1227 <div class="header_title" v-else-if="flowDetail.crossPlatformApproveState == 'E'">
1228 <el-icon class="title-icon">
1229 <CircleCloseFilled />
1230 </el-icon>
1231 <span class="title_text">主平台审批发起失败,请在列表页面查看具体发起失败原因</span>
1232 </div>
1233 </div>
1234 </div>
1235 <ContentWrap title="企业信息" expandSwicth style="margin-top: 15px" :isExpand="expand1" @expand="(v) => expand1 = v"
1236 description="备注:与平台运营签订相关的合同后才能进行认证,避免认证不成功,请知晓!">
1237 <div class="form_panel">
1238 <Form ref="companyFormRef" formId="company-form" :itemList="companyForm.items" :rules="companyForm.rules"
1239 col="col3" />
1240 </div>
1241 </ContentWrap>
1242 <ContentWrap title="法人信息" expandSwicth style="margin-top: 15px" :isExpand="expand2" @expand="(v) => expand2 = v">
1243 <Form ref="corporateFormRef" formId="corporate-form" :itemList="corporateForm.items"
1244 :rules="corporateForm.rules" col="col3" />
1245 </ContentWrap>
1246 <ContentWrap title="管理员(经办人)信息" expandSwicth style="margin-top: 15px" :isExpand="expand3"
1247 @expand="(v) => expand3 = v">
1248 <div class="form_panel">
1249 <Form ref="accountFormRef" formId="account-form" :itemList="accountForm.items" :rules="accountForm.rules"
1250 col="col3" />
1251 </div>
1252 </ContentWrap>
1253 <ContentWrap title="协议签署" expandSwicth style="margin-top: 15px" :isExpand="expand4" @expand="(v) => expand4 = v">
1254 <div class="form_panel">
1255 <Form ref="contractFormRef" formId="contract-form" :itemList="contractForm.items" :rules="contractForm.rules"
1256 col="col3" />
1257 </div>
1258 </ContentWrap>
1259 <ContentWrap title="开发主体领域信息" expandSwicth style="margin-top: 15px" :isExpand="expand7"
1260 @expand="(v) => expand7 = v">
1261 <Table ref="orgsTableRef" :tableInfo="orgTableInfo" class="fiveRow-table" />
1262 </ContentWrap>
1263 <ContentWrap id="id-files" title="开发主体附件信息" description="" expandSwicth style="margin-top: 15px"
1264 :isExpand="uploadInfoExpand" @expand="(v) => uploadInfoExpand = v">
1265 <Form class='uploadForm' ref="uploadFormRef" :itemList="uploadFormItems" formId="upload-form"
1266 :rules="uploadFormRules" col="col2" />
1267 </ContentWrap>
1268 <ContentWrap title="历史变更信息" expandSwicth style="margin-top: 15px" :isExpand="expand5"
1269 @expand="(v) => expand4 = v">
1270 <div class="table_panel" :class="{ full: tableData.length > 0 }">
1271 <el-table border :data="tableData" :span-method="tableSpanMethod" tooltip-effect="light" style="height: 100%;"
1272 v-if="tableData.length > 0">
1273 <el-table-column v-for="(item, i) in tableField" :key="'r_' + i" :label="item.label" :width="item.width"
1274 :min-width="item.minWidth" :fixed="item.fixed" :align="item.align" :sortable="item.sortable ?? false"
1275 :prop="item.field" :class-name="item.columClass" show-overflow-tooltip>
1276 <template #default="scope">
1277 <span>
1278 {{ item.getName ? item.getName(scope) : scope.row[item.field] !== 0 && !scope.row[item.field] ?
1279 "--" : scope.row[item.field] }}
1280 </span>
1281 </template>
1282 </el-table-column>
1283 </el-table>
1284 <div class="empty_tips" v-else>暂无变更信息</div>
1285 </div>
1286 </ContentWrap>
1287 <ContentWrap title="认证结果信息" v-if="approveState == 'Y'" expandSwicth style="margin-top: 15px" :isExpand="expandResult"
1288 @expand="(v) => expandResult = v">
1289 <div class="list_panel">
1290 <div class="list_item">
1291 <span class="item_label">认证时间:</span>
1292 <span class="item_value">{{ flowDetail.credentialTime || '--' }}</span>
1293 </div>
1294 <div class="list_item">
1295 <span class="item_label">身份认证凭证:</span>
1296 <span v-if="flowDetail.trustedIdentityCredential" class="item_value link" @click="viewVoucherFile">查看</span>
1297 <span v-else class="item_value">--</span>
1298 </div>
1299 </div>
1300 </ContentWrap>
1301 <ContentWrap id="id-approveInfo" title="审核信息" expandSwicth style="margin-top: 15px" :isExpand="expand6"
1302 @expand="(v) => expand6 = v">
1303 <ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
1304 :processInstanceId="processInstanceId">
1305 </ApprovalProcess>
1306 </ContentWrap>
1307 </div>
1308 <div class="tool_btns">
1309 <div class="btns">
1310 <el-button @click="btnClick({ value: 'cancel' })" v-if="detailType == 'detail'">关闭</el-button>
1311 <el-button @click="btnClick({ value: 'cancel' })" v-else>取消</el-button>
1312 <el-button type="primary" @click="btnClick({ value: 'pass' })"
1313 v-if="approveState == 'A' && flowState == 2">通过</el-button>
1314 <el-button type="danger" plain @click="btnClick({ value: 'reject' })"
1315 v-if="approveState == 'A' && flowState == 2">驳回</el-button>
1316 </div>
1317 </div>
1318 <Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
1319 <Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
1320 </div>
1321 </template>
1322
1323 <style scoped lang="scss">
1324 .container_wrap {
1325 overflow: hidden;
1326
1327 .content_main {
1328 height: calc(100% - 45px);
1329 overflow: hidden auto;
1330
1331 &.panel {
1332 padding: 0 16px 16px;
1333 }
1334
1335 &.full {
1336 height: 100%;
1337 }
1338
1339 .template_panel {
1340 display: flex;
1341 flex-wrap: wrap;
1342 padding: 16px 16px 8px;
1343
1344 .title_item {
1345 display: flex;
1346 margin-bottom: 8px;
1347
1348 +.title_item {
1349 margin-left: 40px;
1350 }
1351
1352 .title_label {
1353 display: block;
1354 width: 80px;
1355 line-height: 1.5;
1356 }
1357
1358 .title_text {
1359 line-height: 1.5;
1360 }
1361
1362 &.is_block {
1363 width: 100%;
1364 margin-left: 0;
1365
1366 .title_text {
1367 display: block;
1368 width: calc(100% - 80px);
1369 text-align: justify;
1370 }
1371 }
1372 }
1373 }
1374
1375 .panel_content {
1376 height: 100%;
1377 display: flex;
1378 flex: 1;
1379 border-top: 1px solid #d9d9d9;
1380
1381 .box_left {
1382 width: 200px;
1383 height: 100%;
1384 border-right: 1px solid #d9d9d9;
1385
1386 .aside_title {
1387 padding: 0 8px;
1388 height: 40px;
1389 line-height: 40px;
1390 font-size: 14px;
1391 color: #212121;
1392 font-weight: 600;
1393 }
1394
1395 .tree_panel {
1396 height: 100%;
1397 }
1398 }
1399
1400 .box_right {
1401 width: calc(100% - 200px);
1402 padding-top: 8px;
1403
1404 .el-breadcrumb {
1405 padding: 0 12px;
1406 line-height: 40px;
1407 }
1408 }
1409 }
1410
1411 .table_panel_wrap {
1412 width: 100%;
1413 height: 100%;
1414 padding: 0 12px;
1415
1416 &.full {
1417 padding: 0;
1418 }
1419 }
1420
1421 :deep(.el-card) {
1422 .el-form {
1423 .el-form-item {
1424 .el-form-item__error {
1425 height: 14px;
1426 white-space: nowrap;
1427 overflow: hidden;
1428 text-overflow: ellipsis;
1429 }
1430
1431 &.error_auto {
1432 .el-form-item__error {
1433 width: 220px;
1434 }
1435 }
1436 }
1437 }
1438
1439 .table_panel {
1440 height: auto;
1441
1442 &.full {
1443 height: 212px;
1444 }
1445 }
1446 }
1447
1448 .panel_wrap.results_panel {
1449 box-shadow: 0 0 0 1px #d9d9d9;
1450 margin-bottom: 16px;
1451 margin-top: 16px;
1452
1453 .panel_header {
1454 .header_title {
1455 height: 40px;
1456 padding: 0 16px;
1457 display: flex;
1458 align-items: center;
1459 background-color: transparent;
1460 box-shadow: none;
1461
1462
1463 .el-icon {
1464 margin-right: 8px;
1465 width: 20px;
1466 height: 20px;
1467
1468 svg {
1469 width: 100%;
1470 height: 100%;
1471 }
1472 }
1473 }
1474
1475 .title_text {
1476 line-height: 22px;
1477 font-size: 14px;
1478 color: var(--el-color-regular);
1479 font-weight: 600;
1480 display: flex;
1481 align-items: center;
1482
1483 .title_icon {
1484 width: 26px;
1485 height: 21px;
1486 margin-right: 4px;
1487 cursor: pointer;
1488
1489 &.active {
1490 transform: rotate(90deg);
1491 }
1492 }
1493 }
1494 }
1495
1496 &.reject {
1497 background-color: #FDF2F4;
1498 box-shadow: 0 0 0 1px #E63E33;
1499
1500 .panel_header {
1501 .header_title {
1502 .el-icon {
1503 color: #E63E33;
1504 }
1505 }
1506 }
1507 }
1508 }
1509 }
1510
1511 .tool_btns {
1512 height: 44px;
1513 margin: 0 -8px;
1514 display: flex;
1515 justify-content: center;
1516 align-items: center;
1517 border-top: 1px solid #d9d9d9;
1518 }
1519 }
1520
1521 .title {
1522 color: #212121;
1523 font-size: 14px;
1524 line-height: 32px;
1525 font-weight: 600;
1526 }
1527
1528 .list_panel {
1529 display: flex;
1530 flex-wrap: wrap;
1531 display: flex;
1532 align-items: center;
1533
1534 .list_item {
1535 width: 33.33%;
1536 line-height: 32px;
1537 font-size: 14px;
1538 color: var(--el-text-color-regular);
1539 display: flex;
1540 justify-content: space-between;
1541 min-width: 120px;
1542
1543 .item_label {
1544 text-align: left;
1545 }
1546
1547 .item_value {
1548 color: var(--el-color-regular);
1549 padding: 0 4px;
1550 flex: 1;
1551 text-align: justify;
1552 min-width: 0;
1553 }
1554
1555 &.is_block {
1556 width: 100%;
1557
1558 .item_value {
1559 white-space: pre-wrap;
1560 }
1561 }
1562 }
1563 }
1564 </style>
1 <route lang="yaml">
2 name: settleDetail
3 </route>
4
5 <script lang="ts" setup name="settleDetail">
6 import useUserStore from "@/store/modules/user";
7 import { passFlowData, rejectFlowData, revokeFlowData } from "@/api/modules/workFlowService";
8 import {
9 getConnectorDetail,
10 assessMethodList
11 } from "@/api/modules/dataRequire";
12 import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common';
13 import { ElMessage, ElMessageBox } from "element-plus";
14 import useDataConnectorStore from '@/store/modules/dataConnector';
15 import { CircleCloseFilled } from '@element-plus/icons-vue'
16
17 const { proxy } = getCurrentInstance() as any;
18 const router = useRouter();
19 const route = useRoute();
20 const userStore = useUserStore();
21 const userData = JSON.parse(localStorage.userData);
22 const fullscreenloading = ref(false);
23 const flowDetail: any = ref({});
24 const expand1 = ref(true);
25 const expand2 = ref(true);
26 const expand3 = ref(true);
27 const expandApprove = ref(true);
28 const expandCert = ref(true);
29 const approvalProcessRef = ref();
30 const deploymentId = ref('');
31 const processInstanceId = ref('');
32 const fullPath = route.fullPath;
33 const guid = route.query.guid;
34 const dataConnectorStore = useDataConnectorStore();
35
36 const toolBtns: any = computed(() => {
37 let btnsArr: any = [{
38 label: "关闭", value: "cancel", plain: true
39 }];
40 let approveVO = flowDetail.value.approveVO;
41 let staffGuid = userData.staffGuid;
42 if (approveVO && approveVO.approveState == 'A' && approveVO.approveStaffGuids && approveVO.approveStaffGuids.indexOf(staffGuid) > -1) {
43 btnsArr.push(...[{ label: "通过", value: "pass", type: 'primary' }, { label: "驳回", value: "reject", type: 'danger', plain: true }]);
44 }
45 if (approveVO && approveVO.approveState == 'A' && approveVO.staffGuid == staffGuid) {
46 btnsArr.push({ label: "撤销", value: "revoke" });
47 }
48 return btnsArr;
49 });
50
51 const btnClick = async (btn, bType = null) => {
52 const type = btn.value;
53 if (type === 'pass') {
54 passDialogInfo.value.visible = true;
55 } else if (type == 'reject') {
56 rejectDialogInfo.value.visible = true;
57 } else if (type == 'cancel') {
58 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
59 router.push({ name: 'settleManagement' });
60 updateDetailStatus.value && dataConnectorStore.set(true);
61 } else if (type == 'revoke') {
62 ElMessageBox.confirm('确定撤销该连接器审批流程吗?', "提示", {
63 confirmButtonText: "确定",
64 cancelButtonText: "取消",
65 type: 'warning',
66 }).then(() => {
67 let params = {
68 guid: flowDetail.value.approveVO.approveGuid,
69 flowType: flowDetail.value.approveVO.flowType,
70 approveStaffGuid: userData.staffGuid,
71 }
72 revokeFlowData(params, flowDetail.value.tenantGuid).then((res: any) => {
73 if (res?.code == proxy.$passCode) {
74 if (res.data) {
75 ElMessage.success('该审批流程撤销成功!');
76 getDetail();
77 updateDetailStatus.value = true;
78 approvalProcessRef.value?.renderProcessNodes();
79 } else {
80 ElMessage.error('该审批流程撤销失败!');
81 }
82 } else {
83 ElMessage.error(res.msg);
84 }
85 }).catch(() => {
86 });
87 }).catch(() => {
88 ElMessage.info('已取消撤销');
89 });
90 }
91 }
92
93 const passDialogInfo = ref({
94 visible: false,
95 size: 460,
96 direction: "column",
97 header: {
98 title: "通过",
99 },
100 type: '',
101 contents: [
102 {
103 type: 'form',
104 title: '',
105 formInfo: {
106 id: 'batch-pass-form',
107 items: [
108 {
109 label: '',
110 type: "textarea",
111 placeholder: "请填写通过理由(非必填)",
112 field: "approveSuggest",
113 clearable: true,
114 block: true,
115 col: 'margin_b_0',
116 }
117 ]
118 }
119 }
120 ],
121 footer: {
122 btns: [
123 { type: "default", label: "取消", value: "cancel" },
124 { type: "primary", label: "确定", value: "submit", loading: false },
125 ],
126 },
127 });
128
129 const passDialogBtnClick = (btn, info) => {
130 if (btn.value == 'submit') {
131 passDialogInfo.value.footer.btns[1].loading = true;
132 let params = {
133 guid: flowDetail.value.approveVO.approveGuid,
134 flowType: flowDetail.value.approveVO.flowType,
135 approveSuggest: info.approveSuggest,
136 approveStaffGuid: userData.staffGuid,
137 }
138 passFlowData(params).then((res: any) => {
139 passDialogInfo.value.footer.btns[1].loading = false;
140 if (res?.code == proxy.$passCode) {
141 if (res.data) {
142 passDialogInfo.value.visible = false;
143 getDetail();
144 updateDetailStatus.value = true;
145 approvalProcessRef.value?.renderProcessNodes();
146 } else {
147 proxy.$ElMessage.error('审批失败');
148 }
149 } else {
150 proxy.$ElMessage.error(res.msg);
151 }
152 }).catch(() => {
153 passDialogInfo.value.footer.btns[1].loading = false;
154 });
155 } else if (btn.value == 'cancel') {
156 passDialogInfo.value.visible = false;
157 }
158 };
159
160 const rejectDialogInfo = ref({
161 visible: false,
162 size: 460,
163 direction: "column",
164 header: {
165 title: "驳回",
166 },
167 type: '',
168 contents: [
169 {
170 type: 'form',
171 title: '',
172 formInfo: {
173 id: 'batch-reject-form',
174 items: [
175 {
176 label: '',
177 type: "textarea",
178 placeholder: "请填写驳回理由(必填)",
179 field: "approveSuggest",
180 clearable: true,
181 block: true,
182 col: 'margin_b_0',
183 }
184 ],
185 }
186 }
187 ],
188 footer: {
189 btns: [
190 { type: "default", label: "取消", value: "cancel" },
191 { type: "primary", label: "确定", value: "submit", loading: false },
192 ],
193 },
194 });
195
196 const rejectDialogBtnClick = (btn, info) => {
197 if (btn.value == 'submit') {
198 if (info.approveSuggest == '') {
199 proxy.$ElMessage.error('请填写驳回理由');
200 return
201 }
202 rejectDialogInfo.value.footer.btns[1].loading = true;
203 let params = {
204 guid: flowDetail.value.approveVO.approveGuid,
205 flowType: flowDetail.value.approveVO.flowType,
206 approveSuggest: info.approveSuggest,
207 approveStaffGuid: userData.staffGuid,
208 }
209 rejectFlowData(params).then((res: any) => {
210 rejectDialogInfo.value.footer.btns[1].loading = false;
211 if (res?.code == proxy.$passCode) {
212 if (res.data) {
213 proxy.$ElMessage.success('驳回成功');
214 rejectDialogInfo.value.visible = false;
215 getDetail();
216 updateDetailStatus.value = true;
217 approvalProcessRef.value?.renderProcessNodes();
218 } else {
219 proxy.$ElMessage.error('驳回失败');
220 }
221 } else {
222 proxy.$ElMessage.error(res.msg);
223 }
224 }).catch(() => {
225 rejectDialogInfo.value.footer.btns[1].loading = false;
226 });
227 } else if (btn.value == 'cancel') {
228 rejectDialogInfo.value.visible = false;
229 }
230 };
231
232 const viewVoucherFile = () => {
233 const url = flowDetail.value.trustedIdentityCredential;
234 if (!url) {
235 return;
236 }
237 onUploadFilePreview(url);
238 }
239
240 /** 查看连接器身份凭证证书 */
241 const viewResultVoucherFile = () => {
242 const url = flowDetail.value.trustedIdentityCredential;
243 if (!url) {
244 proxy.$ElMessage.error('暂无可查看的身份凭证证书');
245 return;
246 }
247 onUploadFilePreview(url);
248 }
249
250 /** 调用更新详情状态,关闭之后,需要重新刷新列表 */
251 const updateDetailStatus = ref(false);
252
253 const getDetail = () => {
254 fullscreenloading.value = true;
255 getConnectorDetail(guid).then((res: any) => {
256 fullscreenloading.value = false;
257 if (res?.code == proxy.$passCode) {
258 flowDetail.value = res.data || {};
259 flowDetail.value.accessMethodName = assessMethodList.find(a => a.value == flowDetail.value.accessMethod)?.label;
260 deploymentId.value = res.data.approveVO.camundaDeploymentId
261 processInstanceId.value = res.data.approveVO.camundaInstanceId
262 flowDetail.value.tdsConnectorVerifiable.thirdPartyCertification = [];
263 } else {
264 proxy.$ElMessage.error(res.msg);
265 }
266 }).catch(() => {
267 fullscreenloading.value = false;
268 })
269 }
270
271 onBeforeMount(() => {
272 getDetail();
273 })
274
275 const fileKeyNames = ref({
276 networkAccessQualification: '网络接入资质认证',
277 levelProtectionEvaluationResults: '等级保护(等保 2.0)测评结果',
278 levelProtectionEvaluationExpirationTime: '等级保护(等保 2.0)测评有效期至',
279 networkSecurityFilingCertificate: '网络安全产品备案证明',
280 encryptionModuleAuthentication: '加密模块认证',
281 softwareScmStatemen: '软件供应链合规声明',
282 securityLoopholeRepairStatement: '安全漏洞修复声明',
283 communicationProtocolCompatibilityCertification: '通信协议兼容性认证',
284 teeCertification: '硬件可信执行环境(TEE)认证',
285 accessAuditReport: '接入行为审计合规报告',
286 thirdPartyCertification: '第三方认证声明'
287 });
288
289 </script>
290
291 <template>
292 <div class="container_wrap full" v-loading="fullscreenloading">
293 <div class="content_main panel">
294 <div v-if="flowDetail.crossPlatformApproveState == 'R' || flowDetail.crossPlatformApproveState == 'E'"
295 :class="['panel_wrap', 'results_panel', 'reject']">
296 <div class="panel_header">
297 <div class="header_title" v-if="flowDetail.crossPlatformApproveState == 'R'">
298 <el-icon class="title-icon">
299 <CircleCloseFilled />
300 </el-icon>
301 <span class="title_text">主平台审批已驳回,请在列表页面查看具体驳回原因</span>
302 </div>
303 <div class="header_title" v-else-if="flowDetail.crossPlatformApproveState == 'E'">
304 <el-icon class="title-icon">
305 <CircleCloseFilled />
306 </el-icon>
307 <span class="title_text">主平台审批发起失败,请在列表页面查看具体发起失败原因</span>
308 </div>
309 </div>
310 </div>
311 <ContentWrap title="连接器身份信息" expandSwicth style="margin-top: 15px" :isExpand="expand1"
312 @expand="(v) => expand1 = v">
313 <div class="list_panel">
314 <div class="list_item">
315 <span class="item_label">接入连接器名称:</span>
316 <span class="item_value"><ellipsis-tooltip :content="flowDetail.connectorName || '--'"
317 class-name="w100f mr8-i" :refName="'tooltipOver' + 'connectorName'"></ellipsis-tooltip></span>
318 </div>
319 <div class="list_item">
320 <span class="item_label">接入方式:</span>
321 <span class="item_value"><ellipsis-tooltip :content="flowDetail.accessMethodName || '--'"
322 class-name="w100f mr8-i" :refName="'tooltipOver' + 'accessMethod'"></ellipsis-tooltip></span>
323 </div>
324 <div class="list_item">
325 <span class="item_label">法人或其他组织名称:</span>
326 <span class="item_value"><ellipsis-tooltip :content="flowDetail.legalEntity || '--'"
327 class-name="w100f mr8-i" :refName="'tooltipOver' + 'legalEntity'"></ellipsis-tooltip></span>
328 </div>
329 <div class="list_item">
330 <span class="item_label">法人或其他组织统一社会信用代码:</span>
331 <span class="item_value"><ellipsis-tooltip :content="flowDetail.legalSocialCreditCode || '--'"
332 class-name="w100f mr8-i" :refName="'tooltipOver' + 'legalSocialCreditCode'"></ellipsis-tooltip></span>
333 </div>
334 <div class="list_item">
335 <span class="item_label">可信凭证颁发日期:</span>
336 <span class="item_value">{{ flowDetail.credentialTime || '--' }}</span>
337 </div>
338 <div class="list_item">
339 <span class="item_label">可信凭证证书:</span>
340 <span class="item_value link" @click="viewVoucherFile">查看</span>
341 </div>
342 <div class="list_item is_block">
343 <span class="item_label">IP地址列表:</span>
344 <span class="item_value">{{ flowDetail.ipAddressList?.join(',') || '--' }}</span>
345 </div>
346 <div class="list_item is_block">
347 <span class="item_label">域名信息:</span>
348 <span class="item_value">{{ flowDetail.domainList?.join(',') || '--' }}</span>
349 </div>
350 </div>
351 </ContentWrap>
352 <ContentWrap title="连接器附属信息" expandSwicth style="margin-top: 15px" :isExpand="expand2"
353 @expand="(v) => expand2 = v">
354 <div class="list_panel">
355 <div class="list_item">
356 <span class="item_label">供应商名称:</span>
357 <span class="item_value"><ellipsis-tooltip
358 :content="flowDetail.tdsConnectorAdditional?.supplierName || '--'" class-name="w100f mr8-i"
359 :refName="'tooltipOver' + 'supplierName'"></ellipsis-tooltip></span>
360 </div>
361 <div class="list_item">
362 <span class="item_label">供应商统一社会信用代码:</span>
363 <span class="item_value"><ellipsis-tooltip
364 :content="flowDetail.tdsConnectorAdditional?.supplierCode || '--'" class-name="w100f mr8-i"
365 :refName="'tooltipOver' + 'supplierCode'"></ellipsis-tooltip></span>
366 </div>
367 <div class="list_item">
368 <span class="item_label">连接器类型:</span>
369 <span class="item_value"><ellipsis-tooltip
370 :content="flowDetail.tdsConnectorAdditional?.connectorType == '0' ? '标准型' : '全功能型'"
371 class-name="w100f mr8-i" :refName="'tooltipOver' + 'connectorType'"></ellipsis-tooltip></span>
372 </div>
373 <div class="list_item">
374 <span class="item_label">可信身份凭证签发单位:</span>
375 <span class="item_value"><ellipsis-tooltip
376 :content="flowDetail.tdsConnectorAdditional?.trustedIdentityCredentialUnit || '--'"
377 class-name="w100f mr8-i" :refName="'tooltipOver' + 'identityIssuingUnit'"></ellipsis-tooltip></span>
378 </div>
379 <div class="list_item">
380 <span class="item_label">产品SN号:</span>
381 <span class="item_value"><ellipsis-tooltip :content="flowDetail.tdsConnectorAdditional?.productSn || '--'"
382 class-name="w100f mr8-i" :refName="'tooltipOver' + 'productSn'"></ellipsis-tooltip></span>
383 </div>
384 <div class="list_item">
385 <span class="item_label">产品版本号:</span>
386 <span class="item_value"><ellipsis-tooltip
387 :content="flowDetail.tdsConnectorAdditional?.productVersion || '--'" class-name="w100f mr8-i"
388 :refName="'tooltipOver' + 'productVersion'"></ellipsis-tooltip></span>
389 </div>
390 <div class="list_item">
391 <span class="item_label">设备MAC地址:</span>
392 <span class="item_value"><ellipsis-tooltip
393 :content="flowDetail.tdsConnectorAdditional?.deviceMacAddress || '--'" class-name="w100f mr8-i"
394 :refName="'tooltipOver' + 'deviceMacAddress'"></ellipsis-tooltip></span>
395 </div>
396 </div>
397 </ContentWrap>
398 <ContentWrap title="连接器可验信息" expandSwicth style="margin-top: 15px" :isExpand="expand3"
399 @expand="(v) => expand3 = v">
400 <div class="list_panel">
401 <template v-for="(field, index) in Object.keys(fileKeyNames || {})">
402 <div
403 v-if="field != 'levelProtectionEvaluationExpirationTime' && flowDetail.tdsConnectorVerifiable?.[field]?.length"
404 class="list_item isFile">
405 <span class="item_label" :style="{ width: 'auto', 'text-align': 'left' }">{{ fileKeyNames[field] }}</span>
406 <!-- <span v-if="!flowDetail.tdsConnectorVerifiable?.[field]?.length" class="item_value">{{ '--' }}</span> -->
407 <span v-for="(item) in (flowDetail.tdsConnectorVerifiable?.[field] || [])" class="item_value"
408 :style="{ 'padding-left': '0px' }">
409 <div class="file-operate">
410 <template
411 v-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'xls' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'xlsx' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'csv'">
412 <img class="file-img" src="../../assets/images/excel.png" />
413 </template>
414 <template
415 v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
416 <img class="file-img" src="../../assets/images/word.png" />
417 </template>
418 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
419 <img class="file-img" src="../../assets/images/zip.png" />
420 </template>
421 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
422 <img class="file-img" src="../../assets/images/RAR.png" />
423 </template>
424 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
425 <img class="file-img" src="../../assets/images/PDF.png" />
426 </template>
427 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
428 <img class="file-img" src="../../assets/images/png.png" />
429 </template>
430 <template
431 v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
432 <img class="file-img" src="../../assets/images/jpg.png" />
433 </template>
434 <div class="file-name"><ellipsis-tooltip :content="item.name ?? ''" class-name="w100f"
435 refName="tooltipOver"></ellipsis-tooltip></div>
436 <div :style="{ right: '36px' }"
437 v-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'png' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'"
438 class="file-preview" @click="onUploadFilePreview(item)">查看</div>
439 <div :style="{ right: '0px' }" class="file-preview" @click="onUploadFileDownload(item)">下载</div>
440 </div>
441 </span>
442 </div>
443 <div v-if="field == 'levelProtectionEvaluationExpirationTime'" class="list_item isFile">
444 <span class="item_label" :style="{ width: 'auto', 'text-align': 'left' }">可信凭证颁发日期</span>
445 <span class="item_value">{{ flowDetail.tdsConnectorVerifiable?.[field] || '--' }}</span>
446 </div>
447 </template>
448 </div>
449 </ContentWrap>
450 <ContentWrap id="id-approveInfo" title="审核信息" expandSwicth style="margin-top: 15px" :isExpand="expandApprove"
451 @expand="(v) => expandApprove = v">
452 <ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
453 :processInstanceId="processInstanceId">
454 </ApprovalProcess>
455 </ContentWrap>
456 <ContentWrap v-if="flowDetail.connectorIdentity" title="连接器凭证信息" expandSwicth style="margin-top: 15px" :isExpand="expandCert"
457 @expand="(v) => expandCert = v">
458 <div class="list_panel">
459 <div class="list_item">
460 <span class="item_label">连接器唯一标识:</span>
461 <span class="item_value"><ellipsis-tooltip :content="flowDetail.connectorIdentity || '--'"
462 class-name="w100f mr8-i" :refName="'tooltipOver' + 'connectorIdentity'"></ellipsis-tooltip></span>
463 </div>
464 <div class="list_item">
465 <span class="item_label">可信凭证证书:</span>
466 <span class="item_value link" @click="viewResultVoucherFile">查看</span>
467 </div>
468 <div class="list_item">
469 <span class="item_label">可信凭证颁发日期:</span>
470 <span class="item_value ">{{ flowDetail.credentialTime || '--' }}</span>
471 </div>
472 </div>
473 </ContentWrap>
474 <ContentWrap id="id-approveInfo" title="审核信息" expandSwicth style="margin-top: 15px" :isExpand="expandApprove"
475 @expand="(v) => expandApprove = v">
476 <ApprovalProcess ref="approvalProcessRef" v-if="deploymentId" :deploymentId="deploymentId"
477 :processInstanceId="processInstanceId">
478 </ApprovalProcess>
479 </ContentWrap>
480 </div>
481 <div class="tool_btns">
482 <div class="btns">
483 <el-button v-for="btn in toolBtns" :type="btn.type" :plain="btn.plain" @click="btnClick(btn)">{{ btn.label
484 }}</el-button>
485 </div>
486 </div>
487 <Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
488 <Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
489 </div>
490 </template>
491
492 <style lang="scss" scoped>
493 .container_wrap {
494 overflow: hidden;
495
496 .content_main {
497 height: calc(100% - 45px);
498 overflow: hidden auto;
499
500 &.panel {
501 padding: 0 16px 16px;
502 }
503
504 &.full {
505 height: 100%;
506 }
507 }
508
509 .tool_btns {
510 height: 44px;
511 margin: 0 -8px;
512 display: flex;
513 justify-content: center;
514 align-items: center;
515 border-top: 1px solid #d9d9d9;
516 }
517 }
518
519 .list_panel {
520 display: flex;
521 flex-wrap: wrap;
522 display: flex;
523 align-items: center;
524
525 .list_item {
526 width: 33.33%;
527 line-height: 32px;
528 font-size: 14px;
529 color: var(--el-text-color-regular);
530 display: flex;
531 justify-content: space-between;
532 min-width: 120px;
533
534 .item_label {
535 text-align: left;
536 }
537
538 .item_value {
539 color: var(--el-color-regular);
540 padding: 0 4px;
541 flex: 1;
542 text-align: justify;
543 min-width: 0;
544
545 &.link {
546 color: var(--el-color-primary);
547 cursor: pointer;
548 }
549 }
550
551 &.is_block {
552 width: 100%;
553
554 .item_value {
555 white-space: pre-wrap;
556 word-wrap: break-word;
557 }
558 }
559
560 &.isFile {
561 width: 33%;
562 display: flex;
563 flex-direction: column;
564 justify-content: space-between;
565
566 .item_label {
567 width: 100px;
568 text-align: right;
569 flex-shrink: 0;
570 }
571
572 .item_value {
573 flex: 1 1 0%;
574 min-width: 100px;
575 white-space: pre-wrap;
576 }
577 }
578
579 .file-operate {
580 display: flex;
581 align-items: center;
582 position: relative;
583
584 .file-img {
585 width: 24px;
586 height: 24px;
587 }
588
589 &:hover {
590 background-color: #f5f5f5;
591 }
592
593 .file-name {
594 width: calc(100% - 120px);
595 color: var(--el-color-regular);
596 margin-left: 4px;
597 }
598
599 .file-preview {
600 position: absolute;
601 cursor: pointer;
602 color: var(--el-color-primary);
603 margin-right: 8px;
604 }
605 }
606 }
607 }
608
609 .panel_wrap {
610
611 .panel_header {
612 .header_title {
613 height: 40px;
614 padding: 0 16px;
615 background-color: #fafafa;
616 box-shadow: 0 0 0 1px #e5e5e5;
617 display: flex;
618 align-items: center;
619 }
620
621 .title_text {
622 line-height: 22px;
623 font-size: 14px;
624 color: var(--el-color-regular);
625 font-weight: 600;
626 display: flex;
627 align-items: center;
628
629 .title_icon {
630 width: 26px;
631 height: 21px;
632 margin-right: 4px;
633 cursor: pointer;
634
635 &.active {
636 transform: rotate(90deg);
637 }
638 }
639 }
640 }
641
642 &.results_panel {
643 margin-top: 15px;
644 box-shadow: 0 0 0 1px #d9d9d9;
645
646 .panel_header {
647 .header_title {
648 background-color: transparent;
649 box-shadow: none;
650
651 .el-icon {
652 margin-right: 8px;
653 width: 20px;
654 height: 20px;
655
656 svg {
657 width: 100%;
658 height: 100%;
659 }
660 }
661 }
662 }
663
664 .panel_body {
665 padding-top: 0;
666 margin-top: 0;
667 box-shadow: none;
668
669 .results_list {
670 display: flex;
671
672 .list_item {
673 display: flex;
674 margin-bottom: 8px;
675 margin-right: 60px;
676 color: #666;
677
678 .item_value {
679 padding: 0 8px;
680 color: var(--el-color-regular);
681 }
682 }
683 }
684 }
685
686 &.reject {
687 background-color: #FDF2F4;
688 box-shadow: 0 0 0 1px #E63E33;
689
690 .panel_header {
691 .header_title {
692 .el-icon {
693 color: #E63E33;
694 }
695 }
696 }
697 }
698 }
699 }
700 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: settleManagement
3 </route>
4
5 <script lang="ts" setup name="settleManagement">
6 import { ref } from 'vue';
7 import TableTools from "@/components/Tools/table_tools.vue";
8 import {
9 getConnectorList,
10 assessMethodList,
11 deleteConnector,
12 checkConnector,
13 } from "@/api/modules/dataRequire";
14 import { ElMessage, ElMessageBox } from 'element-plus';
15 import { passFlowData, rejectFlowData, revokeFlowData } from "@/api/modules/workFlowService";
16 import DialogApproval from '@/components/ApprovalProcess/dialog_approval.vue';
17 import useDataConnectorStore from '@/store/modules/dataConnector';
18
19 const router = useRouter();
20 const route = useRoute();
21 const dataConnectorStore = useDataConnectorStore();
22 const userData = JSON.parse(localStorage.userData)
23 const tenantData = JSON.parse(localStorage.tenantInfo);
24 const { proxy } = getCurrentInstance() as any;
25
26 const searchItemList = ref([
27 {
28 type: "input",
29 label: "",
30 field: "connectorName",
31 default: "",
32 placeholder: "连接器名称",
33 maxlength: 50,
34 clearable: true,
35 },
36 {
37 type: 'select',
38 label: '',
39 field: 'approveState',
40 default: '',
41 placeholder: '审核状态',
42 options: [
43 { label: '草稿中', value: 'N' },
44 { label: '审批中', value: 'A' },
45 { label: '已通过', value: 'Y' },
46 { label: '已驳回', value: 'R' },
47 { label: '已撤销', value: 'C' },
48 ],
49 filterable: true,
50 clearable: true
51 }
52 ]);
53
54 const systemApproveCurrentRowInfo: any = ref({})
55
56 const approvalDialogVisible = ref(false);
57
58 const handleApprovalDialogCancel = () => {
59 approvalDialogVisible.value = false;
60 }
61
62 const tableFields = ref([
63 { label: "序号", type: "index", width: 56, align: "center" },
64 { label: "连接器唯一标识", field: "connectorIdentity", width: 252, },
65 { label: "连接器名称", field: "connectorName", width: 150 },
66 {
67 label: "接入方式", field: "accessMethod", width: 130, getName: (scope) => {
68 return scope.row.accessMethod && assessMethodList.find(a => a.value == scope.row.accessMethod)?.label || '--';
69 }
70 },
71 {
72 label: "审批状态", field: "approveVO", type: "tag", width: 96, align: 'center', getName: (scope) => {
73 const approveVO = scope.row.approveVO || {}
74 switch (approveVO.approveState) {
75 case 'N':
76 return '草稿中';
77 case 'A':
78 return '审批中';
79 case 'Y':
80 return '已通过';
81 case 'R':
82 return '已驳回';
83 case 'C':
84 return '已撤销';
85 case 'I':
86 return '--';
87 default:
88 return '草稿中';
89 }
90 }, tagType: (scope) => {
91 const approveVO = scope.row.approveVO || {}
92 switch (approveVO.approveState) {
93 case 'A':
94 return 'warning';
95 case 'Y':
96 return 'success';
97 case 'R':
98 return 'danger';
99 default:
100 return 'info';
101 }
102 }
103 },
104 // { label: "同步状态", field: "approveVO", type: "tag", },
105 // 专区才需要显示的
106 {
107 label: "主平台审批状态", field: "crossPlatformApproveState", type: "approveTagBtn", width: 170, align: 'center', btn: {
108 label: '查看', visible: (scope) => {
109 return scope.row.crossPlatformApproveState != null;
110 }, click: (scope) => {
111 systemApproveCurrentRowInfo.value = scope.row;
112 approvalDialogVisible.value = true;
113 }
114 }
115 },
116 { label: "法人或其他组织", field: "legalEntity", width: 200 },
117 { label: "修改人", field: "updateUserName", width: 130 },
118 { label: "修改时间", field: "updateTime", width: 170 },
119 ]);
120
121 const page = ref({
122 limit: 50,
123 curr: 1,
124 sizes: [
125 { label: "10", value: 10 },
126 { label: "50", value: 50 },
127 { label: "100", value: 100 },
128 { label: "150", value: 150 },
129 { label: "200", value: 200 },
130 ],
131 connectorName: '',
132 approveState: ''
133 });
134 const currTableData: any = ref({});
135 const tableInfo = ref({
136 id: 'value-asset-table',
137 rowKey: 'guid',
138 loading: false,
139 fields: tableFields.value,
140 data: [],
141 page: {
142 type: "normal",
143 rows: 0,
144 ...page.value,
145 },
146 actionInfo: {
147 label: "操作",
148 type: "btn",
149 width: 180,
150 btns: (scope) => {
151 let row = scope.row;
152 return getTableBtns(row);
153 }
154 }
155 });
156
157 const getTableBtns = (row, includeDetail = true) => {
158 let btnsArr: any[] = [];
159 const approveVO = row.approveVO;
160 const currentStaffGuid = userData.staffGuid
161 const bizApproveState = row.bizApproveState;
162 const approveState = approveVO?.approveState || 'N';
163 const approveStaffGuids = approveVO?.approveStaffGuids || [];
164 const staffGuid = approveVO?.staffGuid || '';
165 let isShowCancel = false;
166 let flowState;
167 if (approveState == 'N') {
168 flowState = 1;
169 }
170 if (approveState == 'A' && approveStaffGuids.indexOf(currentStaffGuid) > -1) {
171 flowState = 2;
172 }
173 if ((approveState == 'C' || approveState == 'R') && staffGuid == currentStaffGuid) {
174 flowState = 3;
175 }
176 if (approveVO && approveVO.approveState == 'A' && staffGuid == currentStaffGuid) {
177 isShowCancel = true;
178 }
179
180 if (flowState === 1) {
181 btnsArr = [{ label: "编辑", value: "edit" }, { label: "删除", value: "delete" }]
182 } else {
183 btnsArr.push({ label: "详情", value: "detail" })
184 if (flowState === 2) {
185 btnsArr.push(...[{ label: "通过", value: "pass" }, { label: "驳回", value: "reject" }])
186 } else if (flowState === 3) {
187 if (bizApproveState != 'D') {
188 btnsArr.push({ label: "重新提交", value: "edit" })
189 }
190 }
191 isShowCancel && btnsArr.push({ label: "撤销", value: "revoke" })
192 flowState === 3 && btnsArr.push({ label: "删除", value: "delete" })
193 }
194 return btnsArr
195 }
196
197
198 const toSearch = (val: any, clear: boolean = false) => {
199 if (clear) {
200 searchItemList.value.map((item) => (item.default = ""));
201 page.value.connectorName = '';
202 page.value.approveState = "";
203 } else {
204 page.value.connectorName = val.connectorName;
205 page.value.approveState = val.approveState;
206 }
207 getTableData();
208 updateCheckConnector();
209 };
210
211 const getTableData = () => {
212 tableInfo.value.loading = true
213 getConnectorList({
214 pageIndex: page.value.curr,
215 pageSize: page.value.limit,
216 connectorName: page.value.connectorName,
217 approveState: page.value.approveState,
218 currentStaffGuid: userData.staffGuid
219 }).then((res: any) => {
220 if (res?.code == proxy.$passCode) {
221 const data = res.data || {}
222 tableInfo.value.data = data.records || []
223 tableInfo.value.page.limit = data.pageSize
224 tableInfo.value.page.curr = data.pageIndex
225 tableInfo.value.page.rows = data.totalRows
226 } else {
227 proxy.$ElMessage({
228 type: 'error',
229 message: res.msg,
230 })
231 }
232 tableInfo.value.loading = false
233 }).catch(() => {
234 tableInfo.value.loading = false
235 })
236 };
237
238 const tableBtnClick = (scope, btn) => {
239 const type = btn.value;
240 const row = scope.row;
241 currTableData.value = row;
242 if (type === "edit") { //草稿中\已驳回\已撤销\已通过 状态,才可以编辑。
243 router.push({
244 name: 'settleStart',
245 query: {
246 guid: row.guid,
247 name: row.connectorName
248 }
249 });
250 } else if (type == "delete") {
251 proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => {
252 let guids = [scope.row.guid];
253 deleteConnector(guids).then((res: any) => {
254 if (res?.code == proxy.$passCode) {
255 page.value.curr = 1;
256 getTableData();
257 proxy.$ElMessage.success('删除成功');
258 updateCheckConnector();
259 } else {
260 proxy.$ElMessage.error(res.msg);
261 }
262 });
263 })
264 } else if (type === 'revoke') { // 撤销,状态为审批中时可以撤销。
265 ElMessageBox.confirm('确定撤销该连接器审批流程吗?', "提示", {
266 confirmButtonText: "确定",
267 cancelButtonText: "取消",
268 type: 'warning',
269 }).then(() => {
270 let params = {
271 guid: row.approveVO.approveGuid,
272 flowType: row.approveVO.flowType,
273 approveStaffGuid: userData.staffGuid,
274 }
275 revokeFlowData(params, currTableData.value.tenantGuid).then((res: any) => {
276 if (res?.code == proxy.$passCode) {
277 if (res.data) {
278 ElMessage.success('该审批流程撤销成功!');
279 getTableData();
280 updateCheckConnector();
281 } else {
282 ElMessage.error('该审批流程撤销失败!');
283 }
284 } else {
285 ElMessage.error(res.msg);
286 }
287 });
288 }).catch(() => {
289 ElMessage.info('已取消撤销');
290 });
291 } else if (type === 'detail') { // 详情, 若是草稿中,详情就是编辑,
292 router.push({
293 name: 'settleDetail',
294 query: {
295 guid: row.guid,
296 name: row.connectorName
297 }
298 });
299 } else if (type === 'pass') {
300 passDialogInfo.value.visible = true;
301 } else if (type == 'reject') {
302 rejectDialogInfo.value.visible = true;
303 }
304 };
305 const tablePageChange = (info) => {
306 page.value.curr = Number(info.curr);
307 page.value.limit = Number(info.limit);
308 tableInfo.value.page.curr = page.value.curr;
309 tableInfo.value.page.limit = page.value.limit;
310 getTableData();
311 updateCheckConnector();
312 };
313
314 const newCreate = () => {
315 if (tenantData.isCertification != 'Y') {
316 proxy.$ElMessage.error('请先进行企业认证,再新增连接器');
317 return;
318 }
319 router.push({
320 name: 'settleStart'
321 });
322 }
323
324 const resubmit = () => {
325 router.push({
326 name: 'settleStart',
327 query: {
328 guid: hasConnectorInfo.value?.guid,
329 name: hasConnectorInfo.value?.connectorName,
330 isChange: 'Y'
331 }
332 });
333 }
334
335 onActivated(() => {
336 if (dataConnectorStore.isRefresh) {//如果是首次加载,则不需要调用
337 page.value.curr = 1;
338 getTableData();
339 dataConnectorStore.set(false);
340 updateCheckConnector();
341 }
342 })
343
344 const fullscreenloading = ref(false);
345
346 /** 该用户企业是否已经包含连接器 */
347 const hasConnectorInfo: any = ref({});
348
349 const updateCheckConnector = () => {
350 fullscreenloading.value = true;
351 checkConnector().then((res: any) => {
352 fullscreenloading.value = false;
353 if (res?.code == proxy.$passCode) {
354 hasConnectorInfo.value = res.data || {};
355 } else {
356 proxy.$ElMessage({
357 type: 'error',
358 message: res.msg,
359 })
360 }
361 }).catch(() => {
362 fullscreenloading.value = false;
363 })
364 }
365
366 onBeforeMount(() => {
367 toSearch({});
368 updateCheckConnector();
369 })
370
371 const passDialogInfo = ref({
372 visible: false,
373 size: 460,
374 direction: "column",
375 header: {
376 title: "通过",
377 },
378 type: '',
379 contents: [
380 {
381 type: 'form',
382 title: '',
383 formInfo: {
384 id: 'batch-pass-form',
385 items: [
386 {
387 label: '',
388 type: "textarea",
389 placeholder: "请填写通过理由(非必填)",
390 field: "approveSuggest",
391 clearable: true,
392 block: true,
393 col: 'margin_b_0',
394 }
395 ]
396 }
397 }
398 ],
399 footer: {
400 btns: [
401 { type: "default", label: "取消", value: "cancel" },
402 { type: "primary", label: "确定", value: "submit", loading: false },
403 ],
404 },
405 });
406
407 const passDialogBtnClick = (btn, info) => {
408 if (btn.value == 'submit') {
409 passDialogInfo.value.footer.btns[1].loading = true;
410 let params = {
411 guid: currTableData.value.approveVO.approveGuid,
412 flowType: currTableData.value.approveVO.flowType,
413 approveSuggest: info.approveSuggest,
414 approveStaffGuid: userData.staffGuid,
415 }
416 passFlowData(params, currTableData.value.tenantGuid).then((res: any) => {
417 passDialogInfo.value.footer.btns[1].loading = false;
418 if (res?.code == proxy.$passCode) {
419 if (res.data) {
420 ElMessage.success('审批成功');
421 passDialogInfo.value.visible = false;
422 getTableData();
423 updateCheckConnector();
424 } else {
425 ElMessage.error('审批失败');
426 }
427 } else {
428 ElMessage.error(res.msg);
429 }
430 }).catch(() => {
431 passDialogInfo.value.footer.btns[1].loading = false;
432 });
433 } else if (btn.value == 'cancel') {
434 passDialogInfo.value.visible = false;
435 }
436 };
437
438 const rejectDialogInfo = ref({
439 visible: false,
440 size: 460,
441 direction: "column",
442 header: {
443 title: "驳回",
444 },
445 type: '',
446 contents: [
447 {
448 type: 'form',
449 title: '',
450 formInfo: {
451 id: 'batch-reject-form',
452 items: [
453 {
454 label: '',
455 type: "textarea",
456 placeholder: "请填写驳回理由(必填)",
457 field: "approveSuggest",
458 clearable: true,
459 block: true,
460 col: 'margin_b_0',
461 }
462 ],
463 }
464 }
465 ],
466 footer: {
467 btns: [
468 { type: "default", label: "取消", value: "cancel" },
469 { type: "primary", label: "确定", value: "submit", loading: false },
470 ],
471 },
472 });
473
474 const rejectDialogBtnClick = (btn, info) => {
475 if (btn.value == 'submit') {
476 if (info.approveSuggest == '') {
477 ElMessage.error('请填写驳回理由');
478 return
479 }
480 rejectDialogInfo.value.footer.btns[1].loading = true;
481 let params = {
482 guid: currTableData.value.approveVO.approveGuid,
483 flowType: currTableData.value.approveVO.flowType,
484 approveSuggest: info.approveSuggest,
485 approveStaffGuid: userData.staffGuid,
486 }
487 rejectFlowData(params, currTableData.value.tenantGuid).then((res: any) => {
488 rejectDialogInfo.value.footer.btns[1].loading = false;
489 if (res?.code == proxy.$passCode) {
490 if (res.data) {
491 ElMessage.success('驳回成功');
492 rejectDialogInfo.value.visible = false;
493 getTableData();
494 updateCheckConnector();
495 } else {
496 ElMessage.error('驳回失败');
497 }
498 } else {
499 ElMessage.error(res.msg);
500 }
501 }).catch(() => {
502 rejectDialogInfo.value.footer.btns[1].loading = false;
503 });
504 } else if (btn.value == 'cancel') {
505 rejectDialogInfo.value.visible = false;
506 }
507 };
508
509 </script>
510
511 <template>
512 <div class="container_wrap" v-loading="fullscreenloading">
513 <div class="table_tool_wrap">
514 <TableTools :searchItems="searchItemList" :searchId="'settle-asset-search'" @search="toSearch" :init="false" />
515 <div class="tools_btns">
516 <!-- v-if="userData.superTubeFlag != 'Y'" TODO, 没有人认证过的不可以申请连接器,此处的条件还需要修改 -->
517 <el-button type="primary" :disabled="hasConnectorInfo?.bizApproveState == 'A' || hasConnectorInfo?.bizApproveState == 'Y' || hasConnectorInfo?.bizApproveState == 'B'" @click="newCreate">新增</el-button>
518 <!-- hasConnectorInfo?.crossPlatformApproveState == 'Y' 主平台不需要有这个判断条件但专区要有 -->
519 <el-button type="primary" v-show="hasConnectorInfo?.bizApproveState == 'Y'" @click="resubmit">变更</el-button>
520 </div>
521 </div>
522 <div class="table_panel_wrap"
523 :style="{ height: 'calc(100% - 88px)' /* userData.superTubeFlag != 'Y' ? 'calc(100% - 88px)' : 'calc(100% - 44px)'*/ }">
524 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
525 </div>
526 <Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
527 <Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
528 <DialogApproval :visible="approvalDialogVisible" :currentRowInfo="systemApproveCurrentRowInfo"
529 @dialog-cancel="handleApprovalDialogCancel"></DialogApproval>
530 </div>
531 </template>
532
533 <style lang="scss" scoped>
534 .container_wrap {
535 padding: 0px 16px;
536 }
537 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: settleStart
3 </route>
4
5 <script lang="ts" setup name="settleStart">
6 import useUserStore from "@/store/modules/user";
7 import { useValidator } from "@/hooks/useValidator";
8 import useDataConnectorStore from "@/store/modules/dataConnector";
9 import { getCamundaDeploymentId } from "@/api/modules/workFlowService";
10 import {
11 saveConnector,
12 updateConnector,
13 changeSaveConnector,
14 getConnectorDetail,
15 assessMethodList
16 } from "@/api/modules/dataRequire";
17 import { getEnterpriseData } from "@/api/modules/dataRequire";
18 import { onUploadFilePreview } from "@/api/modules/common";
19
20 const {
21 required,
22 isUSCCCode,
23 requiredFiles,
24 validateIPList,
25 validateDomainList,
26 } = useValidator();
27 const userStore = useUserStore();
28 const dataConnectorStore = useDataConnectorStore();
29 const userData = JSON.parse(userStore.userData);
30 const tenantData = JSON.parse(localStorage.tenantInfo);
31 const { proxy } = getCurrentInstance() as any;
32 const router = useRouter();
33 const route = useRoute();
34 const fullPath = route.fullPath;
35 const guid = route.query.guid;
36 const fullscreenLoading = ref(false);
37 const restart = ref(false);
38
39 /** 展开收起 */
40 const expandBase = ref(false);
41 const expandImpact = ref(false);
42 const expandValid = ref(false);
43 const approveInfoExpand = ref(false);
44
45 const deploymentId = ref("");
46 const processInstanceId = ref("");
47
48 /** 连接器身份信息表单配置 */
49 const baseInfoFormRef = ref();
50 const baseInfoFormItems = ref([
51 {
52 type: "input",
53 label: "连接器名称",
54 field: "connectorName",
55 default: "",
56 placeholder: "请输入",
57 maxlength: 50,
58 clearable: true,
59 required: true,
60 },
61 {
62 label: "接入方式",
63 type: "radio-group",
64 placeholder: "",
65 field: "accessMethod",
66 default: 1,
67 options: assessMethodList,
68 col: "col2 radio-left",
69 required: true,
70 },
71 {
72 type: "input",
73 label: "法人或其他组织名称",
74 field: "legalEntity",
75 default: "",
76 col: "mr8",
77 placeholder: "-",
78 clearable: true,
79 disabled: true,
80 required: false,
81 },
82 {
83 type: "input",
84 label: "法人或其他组织统一社会信用代码",
85 field: "legalSocialCreditCode",
86 default: "",
87 placeholder: "-",
88 clearable: true,
89 disabled: true,
90 required: false,
91 },
92 {
93 type: "input",
94 label: "可信凭证颁发日期",
95 field: "credentialTime",
96 default: "",
97 placeholder: "-",
98 clearable: true,
99 disabled: true,
100 required: false,
101 col: "width-left no-margin-r",
102 viewBtn: {
103 label: "查看可信身份凭证",
104 click: () => {
105 const url = logonUserDetailInfo.value.trustedIdentityCredential;
106 if (!url) {
107 return;
108 }
109 onUploadFilePreview(url);
110 },
111 },
112 },
113 {
114 type: "input",
115 label: "可信身份凭证url地址",
116 field: "trustedIdentityCredential",
117 default: "",
118 placeholder: "-",
119 clearable: true,
120 disabled: true,
121 visible: false,
122 required: false,
123 },
124 {
125 type: "input",
126 label: "IP地址列表",
127 field: "ipAddressList",
128 default: "",
129 placeholder: "支持以逗号,分隔的多地址配置,格式IPv4/IPv6",
130 clearable: true,
131 required: true,
132 block: true,
133 },
134 {
135 type: "input",
136 label: "域名信息",
137 field: "domainList",
138 default: "",
139 placeholder: "支持以逗号,分隔的多个域名配置",
140 clearable: true,
141 required: true,
142 block: true,
143 },
144 ]);
145
146 const baseInfoFormRules = ref({
147 connectorName: [required("请填写连接器名称")],
148 accessMethod: [required("请选择接入方式")],
149 ipAddressList: [required("请填写IP地址列表"), validateIPList()], //TODO,校验IP地址和域名
150 domainList: [required("请填写域名信息"), validateDomainList()],
151 });
152
153 /** 连接器附属信息表单配置 */
154 const addInfoFormRef = ref();
155 const addInfoFormItems = ref([
156 {
157 type: "input",
158 label: "供应商名称",
159 field: "supplierName",
160 default: "",
161 placeholder: "请输入",
162 maxlength: 50,
163 clearable: true,
164 required: true,
165 },
166 {
167 type: "input",
168 label: "供应商统一社会信用代码",
169 field: "supplierCode",
170 default: "",
171 placeholder: "请输入",
172 maxlength: 50,
173 clearable: true,
174 required: true,
175 },
176 {
177 label: "连接器类型",
178 type: "radio-group",
179 placeholder: "",
180 field: "connectorType",
181 default: 0,
182 options: [
183 {
184 label: "标准型",
185 value: 0,
186 },
187 {
188 label: "全能型",
189 value: 1,
190 },
191 ],
192 required: true,
193 },
194 {
195 type: "input",
196 label: "可信身份凭证签发单位",
197 field: "trustedIdentityCredentialUnit",
198 default: "",
199 placeholder: "-",
200 clearable: true,
201 disabled: true,
202 required: false,
203 },
204 {
205 type: "input",
206 label: "产品SN号",
207 field: "productSn",
208 default: "",
209 placeholder: "请输入出厂唯一SN号",
210 maxlength: 20,
211 clearable: true,
212 required: true,
213 },
214 {
215 type: "input",
216 label: "产品版本号",
217 field: "productVersion",
218 default: "",
219 placeholder: "请输入产品版本号,用于补丁管理和漏洞响应",
220 maxlength: 20,
221 clearable: true,
222 required: true,
223 },
224 {
225 type: "input",
226 label: "设备MAC地址",
227 field: "deviceMacAddress",
228 default: "",
229 placeholder: "物理设备唯一标识符(若有多台,只登记管理服务器mac地址)",
230 maxlength: 50,
231 clearable: true,
232 required: true,
233 },
234 ]);
235
236 const addInfoFormRules = ref({
237 supplierName: [required("请填写供应商名称")],
238 supplierCode: [required('请填写供应商统一社会信用代码'), isUSCCCode()],
239 productSn: [required("请填写出厂唯一SN号")],
240 productVersion: [required("请填写产品版本号")],
241 deviceMacAddress: [required("请填写设备MAC地址")], //校验
242 });
243
244 /** 连接器身份可验证信息 */
245 const validInfoFormRef = ref();
246 const validInfoFormItems = ref([
247 {
248 label: "网络接入资质认证",
249 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
250 type: "upload-file",
251 accept: ".pdf, .png, .jpg",
252 required: false,
253 limitSize: 10,
254 default: [],
255 field: "networkAccessQualification",
256 tooltip: true,
257 tooltipContent: "如工信部核发的互联网接入服务许可、VPN 接入资质等",
258 },
259 {
260 label: "等级保护测评结果",
261 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
262 type: "upload-file",
263 accept: ".pdf, .png, .jpg",
264 required: true,
265 limitSize: 10,
266 default: [],
267 tooltip: true,
268 tooltipContent:
269 "具备国家网络安全等级保护测评资质,含系统/设备测评等级与有效期",
270 field: "levelProtectionEvaluationResults",
271 },
272 {
273 label: "等级保护测评有效期至",
274 type: "date",
275 field: "levelProtectionEvaluationExpirationTime",
276 default: null,
277 placeholder: "请选择",
278 clearable: true,
279 disabledDate: (date) => {
280 const today = new Date();
281 // 将 today 设置为 00:00:00,只比较日期部分(本地时间)
282 const todayStart = new Date(
283 today.getFullYear(),
284 today.getMonth(),
285 today.getDate()
286 );
287
288 // 将 date 也转换为本地日期的开始时间(避免 UTC 问题)
289 const dateStart = new Date(
290 date.getFullYear(),
291 date.getMonth(),
292 date.getDate()
293 );
294
295 // 禁用 dateStart < todayStart 的日期(即今天之前)
296 return dateStart.getTime() < todayStart.getTime();
297 },
298 required: true,
299 },
300 {
301 label: "网络安全产品备案证明",
302 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
303 type: "upload-file",
304 accept: ".pdf, .png, .jpg",
305 required: false,
306 limitSize: 10,
307 default: [],
308 tooltip: true,
309 tooltipContent: "如国家网信办或公安机关备案的防火墙/网关产品登记信息",
310 field: "networkSecurityFilingCertificate",
311 },
312 {
313 label: "加密模块认证",
314 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
315 type: "upload-file",
316 accept: ".pdf, .png, .jpg",
317 limitSize: 10,
318 default: [],
319 tooltip: true,
320 tooltipContent: "如密码管理局颁发的SM系列算法模块认证书",
321 field: "encryptionModuleAuthentication",
322 },
323 {
324 label: "软件供应链合规声明",
325 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
326 type: "upload-file",
327 accept: ".pdf, .png, .jpg",
328 limitSize: 10,
329 default: [],
330 tooltip: true,
331 tooltipContent: "包含安全SBOM清单、安全更新机制合规性声明",
332 field: "softwareScmStatemen",
333 },
334 {
335 label: "安全漏洞修复声明",
336 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
337 type: "upload-file",
338 accept: ".pdf, .png, .jpg",
339 limitSize: 10,
340 default: [],
341 tooltip: true,
342 tooltipContent: "由供应商出具的修复已知漏洞的声明,附漏洞编号与修复记录",
343 field: "securityLoopholeRepairStatement",
344 },
345 {
346 label: "通信协议兼容性认证",
347 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
348 type: "upload-file",
349 accept: ".pdf, .png, .jpg",
350 limitSize: 10,
351 default: [],
352 tooltip: true,
353 tooltipContent: "如支持OIDC/SAML等跨平台协议的互操作性报告",
354 field: "communicationProtocolCompatibilityCertification",
355 },
356 {
357 label: "硬件可信执行环境(TEE)认证",
358 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
359 type: "upload-file",
360 accept: ".pdf, .png, .jpg",
361 limitSize: 10,
362 default: [],
363 tooltip: true,
364 tooltipContent: "具备可信启动、安全执行、物理隔离能力的设备认证",
365 field: "teeCertification",
366 },
367 {
368 label: "接入行为审计合规报告",
369 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
370 type: "upload-file",
371 accept: ".pdf, .png, .jpg",
372 limitSize: 10,
373 default: [],
374 tooltip: true,
375 tooltipContent: "具备行为记录留存、数据访问控制和审计能力的外部审计报告",
376 field: "accessAuditReport",
377 },
378 {
379 label: "第三方认证声明",
380 tip: "支持扩展名:pdf、png、jpg,单个文件不得大于10M",
381 type: "upload-file",
382 accept: ".pdf, .png, .jpg",
383 limitSize: 10,
384 default: [],
385 tooltip: true,
386 tooltipContent:
387 "如由行业联盟、CA 机构等出具的合规性、互操作性、性能认证等声明材料",
388 field: "thirdPartyCertification",
389 },
390 ]);
391
392 const validInfoFormRules = ref({
393 //networkAccessQualification: [requiredFiles()],
394 levelProtectionEvaluationResults: [requiredFiles()],
395 levelProtectionEvaluationExpirationTime: [required("请选择有效期")],
396 //networkSecurityFilingCertificate: [requiredFiles()],
397 // encryptionModuleAuthentication: [requiredFiles()],
398 // softwareScmStatemen: [requiredFiles()],
399 // securityLoopholeRepairStatement: [requiredFiles()],
400 // communicationProtocolCompatibilityCertification: [requiredFiles()],
401 // accessAuditReport: [requiredFiles()],
402 // thirdPartyCertification: [requiredFiles()],
403 });
404
405 const cancel = () => {
406 proxy.$openMessageBox(
407 "当前页面尚未保存,确定放弃修改吗?",
408 () => {
409 userStore.setTabbar(
410 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
411 );
412 router.push({
413 name: "settleManagement",
414 });
415 },
416 () => {
417 proxy.$ElMessage.info("已取消");
418 }
419 );
420 };
421
422 const transferValueInfo = () => {
423 let params: any = {};
424 let baseInfo = baseInfoFormRef.value.formInline;
425 params = { ...baseInfo };
426 params.trustedIdentityCredential = logonUserDetailInfo.value.trustedIdentityCredential;
427 if (params.ipAddressList) {
428 params.ipAddressList = params.ipAddressList.split(",");
429 } else {
430 params.ipAddressList = [];
431 }
432 if (params.domainList) {
433 params.domainList = params.domainList.split(",");
434 } else {
435 params.domainList = [];
436 }
437 let addInfo = addInfoFormRef.value.formInline;
438 params.tdsConnectorAdditional = addInfo;
439 params.tdsConnectorAdditional.guid = connectorDetailInfo.value?.tdsConnectorAdditional?.guid;
440 let validInfo = validInfoFormRef.value.formInline;
441 let tdsConnectorVerifiable = {};
442 for (const key in validInfo) {
443 if (key == "levelProtectionEvaluationExpirationTime") {
444 tdsConnectorVerifiable[key] = validInfo[key];
445 } else {
446 tdsConnectorVerifiable[key] =
447 validInfo[key]?.map((v) => {
448 return {
449 name: v.name,
450 url: v.url,
451 };
452 }) || [];
453 }
454 }
455 params.tdsConnectorVerifiable = tdsConnectorVerifiable;
456 params.tdsConnectorVerifiable.guid = connectorDetailInfo.value?.tdsConnectorVerifiable?.guid;
457 return params;
458 }
459
460 const saveDraft = () => {
461 let params: any = transferValueInfo();
462 params.immediateApprove = false;
463 params.bizApproveState = "N";
464 fullscreenLoading.value = true;
465 if (!guid) {
466 saveConnector(params).then((res: any) => {
467 fullscreenLoading.value = false;
468 if (res?.code == proxy.$passCode) {
469 proxy.$ElMessage.success('保存成功');
470 userStore.setTabbar(
471 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
472 );
473 router.push({
474 name: "settleManagement",
475 });
476 dataConnectorStore.set(true);
477 } else {
478 proxy.$ElMessage.error(res.msg);
479 }
480 });
481 } else {
482 params.guid = guid;
483 updateConnector(params).then((res: any) => {
484 fullscreenLoading.value = false;
485 if (res?.code == proxy.$passCode) {
486 proxy.$ElMessage.success('保存成功');
487 userStore.setTabbar(
488 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
489 );
490 router.push({
491 name: "settleManagement",
492 });
493 dataConnectorStore.set(true);
494 } else {
495 proxy.$ElMessage.error(res.msg);
496 }
497 });
498 }
499 };
500
501 const submit = () => {
502 baseInfoFormRef.value.ruleFormRef.validate((valid1, errorItem1) => {
503 if (valid1) {
504 addInfoFormRef.value.ruleFormRef.validate((valid2, errorItem2) => {
505 if (valid2) {
506 validInfoFormRef.value.ruleFormRef.validate((valid3, errorItem3) => {
507 if (valid3) {
508 let params: any = transferValueInfo();
509 params.immediateApprove = true;
510 params.bizApproveState = 'A';
511 fullscreenLoading.value = true;
512 if (route.query.isChange == 'Y') {
513 params.sourceBizGuid = guid;
514 changeSaveConnector(params).then((res: any) => {
515 fullscreenLoading.value = false;
516 if (res?.code == proxy.$passCode) {
517 proxy.$ElMessage.success('提交成功');
518 userStore.setTabbar(
519 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
520 );
521 router.push({
522 name: "settleManagement",
523 });
524 dataConnectorStore.set(true);
525 } else {
526 proxy.$ElMessage.error(res.msg);
527 }
528 });
529 } else {
530 if (!guid) {
531 saveConnector(params).then((res: any) => {
532 fullscreenLoading.value = false;
533 if (res?.code == proxy.$passCode) {
534 proxy.$ElMessage.success('提交成功');
535 userStore.setTabbar(
536 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
537 );
538 router.push({
539 name: "settleManagement",
540 });
541 dataConnectorStore.set(true);
542 } else {
543 proxy.$ElMessage.error(res.msg);
544 }
545 });
546 } else {
547 params.guid = guid;
548 updateConnector(params).then((res: any) => {
549 fullscreenLoading.value = false;
550 if (res?.code == proxy.$passCode) {
551 proxy.$ElMessage.success('提交成功');
552 userStore.setTabbar(
553 userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)
554 );
555 router.push({
556 name: "settleManagement",
557 });
558 dataConnectorStore.set(true);
559 } else {
560 proxy.$ElMessage.error(res.msg);
561 }
562 });
563 }
564 }
565 } else {
566 expandValid.value = true;
567 var obj = Object.keys(errorItem3);
568 validInfoFormRef.value.ruleFormRef.scrollToField(obj[0]);
569 }
570 });
571 } else {
572 expandImpact.value = true;
573 var obj = Object.keys(errorItem2);
574 addInfoFormRef.value.ruleFormRef.scrollToField(obj[0]);
575 validInfoFormRef.value.ruleFormRef.validate(() => { });
576 }
577 });
578 } else {
579 expandBase.value = true;
580 var obj = Object.keys(errorItem1);
581 baseInfoFormRef.value.ruleFormRef.scrollToField(obj[0]);
582 addInfoFormRef.value.ruleFormRef.validate(() => { });
583 validInfoFormRef.value.ruleFormRef.validate(() => { });
584 }
585 });
586 };
587
588 const logonUserDetailInfo: any = ref({});
589
590 const connectorDetailInfo: any = ref({});
591
592 onBeforeMount(() => {
593 if (!guid) {
594 getCamundaDeploymentId("10031", userData.tenantGuid, userData.staffGuid).then(
595 (res: any) => {
596 if (res.code == proxy.$passCode) {
597 deploymentId.value = res.data;
598 } else {
599 proxy.$ElMessage.error(res.msg);
600 }
601 }
602 );
603 fullscreenLoading.value = true;
604 getEnterpriseData({
605 logonUser: userData.tenantName == "非认证会员" ? userData.logonUser : tenantData.logonUser
606 }).then((res: any) => {
607 fullscreenLoading.value = false;
608 if (res?.code == proxy.$passCode) {
609 const data = res.data || {};
610 logonUserDetailInfo.value = data;
611 baseInfoFormItems.value.forEach((item) => {
612 if (item.field == "legalEntity") {
613 item.default = res.data["tenantName"] || "";
614 } else if (item.field == "legalSocialCreditCode") {
615 item.default = res.data["socialCreditCode"] || "";
616 } else if (item.field == 'credentialTime') {
617 item.default = data.credentialTime || '';
618 } else if (item.field == 'trustedIdentityCredential') {
619 item.default = data.trustedIdentityCredential || '';
620 }
621 });
622 let tenantItem = addInfoFormItems.value.find(item => item.field == "trustedIdentityCredentialUnit");
623 tenantItem && (tenantItem.default = data['trustedIdentityCredentialUnit']);
624 } else {
625 proxy.$ElMessage.error(res.msg);
626 }
627 });
628 } else {
629 fullscreenLoading.value = true;
630 let ps1 = getConnectorDetail(guid);
631 let ps2 = getEnterpriseData({
632 logonUser: userData.tenantName == "非认证会员" ? userData.logonUser : tenantData.logonUser
633 });
634 Promise.all([ps1, ps2]).then((res: any) => {
635 fullscreenLoading.value = false;
636 let res1 = res?.[0];
637 let res2 = res?.[1];
638 let logonUserDetail = logonUserDetailInfo.value = res2?.data || {};
639 if (res2?.code == proxy.$passCode) {
640 } else {
641 proxy.$ElMessage.error(res1.msg);
642 }
643 if (res1?.code == proxy.$passCode) {
644 let connectorDetail = connectorDetailInfo.value = res1?.data || {};
645 deploymentId.value = connectorDetail.approveVO?.camundaDeploymentId || '';
646 processInstanceId.value = connectorDetail.approveVO?.camundaInstanceId || '';
647 if (!deploymentId.value) {
648 getCamundaDeploymentId("10031", userData.tenantGuid, userData.staffGuid).then(
649 (res: any) => {
650 if (res.code == proxy.$passCode) {
651 deploymentId.value = res.data;
652 } else {
653 proxy.$ElMessage.error(res.msg);
654 }
655 }
656 );
657 }
658 let approveVO = connectorDetail.approveVO || {};
659 if ((approveVO.approveState == 'C' || approveVO.approveState == 'R') && approveVO.staffGuid == userData.staffGuid && connectorDetail.bizApproveState != 'D') {
660 restart.value = true;
661 }
662 baseInfoFormItems.value.forEach(item => {
663 if (item.field == "legalEntity") {
664 item.default = connectorDetail[item.field] || logonUserDetail["tenantName"] || "";
665 } else if (item.field == "legalSocialCreditCode") {
666 item.default = connectorDetail[item.field] || logonUserDetail["socialCreditCode"] || "";
667 } else if (item.field == 'credentialTime' || item.field == 'trustedIdentityCredential') {
668 item.default = connectorDetail[item.field] || logonUserDetail[item.field] || "";
669 } else if (item.field == 'ipAddressList' || item.field == 'domainList') {
670 item.default = connectorDetail[item.field]?.join(',') || '';
671 } else {
672 item.default = connectorDetail[item.field] || '';
673 }
674 });
675 addInfoFormItems.value.forEach(item => {
676 if (item.field == "trustedIdentityCredentialUnit") {
677 item.default = connectorDetail[item.field] || logonUserDetail['trustedIdentityCredentialUnit'] || '';
678 } else {
679 item.default = connectorDetail.tdsConnectorAdditional?.[item.field];
680 }
681 })
682 validInfoFormItems.value.forEach(item => {
683 if (item.field == 'levelProtectionEvaluationExpirationTime') {
684 item.default = connectorDetail.tdsConnectorVerifiable?.[item.field] || '';
685 } else {
686 item.default = connectorDetail.tdsConnectorVerifiable?.[item.field] || [];
687 }
688 });
689 } else {
690 proxy.$ElMessage.error(res1.msg);
691 }
692 }).catch(() => {
693 fullscreenLoading.value = false;
694 });
695 }
696 });
697 </script>
698
699 <template>
700 <div class="container_wrap full" v-loading="fullscreenLoading">
701 <div class="content_main panel">
702 <ContentWrap title="连接器身份信息" expandSwicth style="margin-top: 15px" :isExpand="expandBase"
703 @expand="(v) => (expandBase = v)" description="">
704 <Form ref="baseInfoFormRef" formId="base-info-form" :itemList="baseInfoFormItems" :rules="baseInfoFormRules"
705 col="col3" />
706 </ContentWrap>
707 <ContentWrap title="连接器附属信息" expandSwicth style="margin-top: 15px" :isExpand="expandImpact"
708 @expand="(v) => (expandImpact = v)" description="">
709 <Form ref="addInfoFormRef" formId="add-info-form" :itemList="addInfoFormItems" :rules="addInfoFormRules"
710 col="col3" />
711 </ContentWrap>
712 <ContentWrap title="连接器可验信息" expandSwicth style="margin-top: 15px" :isExpand="expandValid"
713 @expand="(v) => (expandValid = v)" description="">
714 <Form ref="validInfoFormRef" formId="valid-info-form" :itemList="validInfoFormItems" :rules="validInfoFormRules"
715 col="col3" />
716 </ContentWrap>
717 <ContentWrap id="id-approveInfo" title="审批信息" :isExpand="approveInfoExpand" expandSwicth style="margin-top: 15px"
718 @expand="(v) => (approveInfoExpand = v)">
719 <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :definitionId="''">
720 </ApprovalProcess>
721 </ContentWrap>
722 </div>
723 <div class="tool_btns">
724 <div class="btns">
725 <el-button @click="cancel">取消</el-button>
726 <el-button type="primary" v-if="!restart && route.query.isChange != 'Y'" @click="saveDraft">保存</el-button>
727 <el-button type="primary" @click="submit">提交</el-button>
728 </div>
729 </div>
730 </div>
731 </template>
732
733 <style lang="scss" scoped>
734 .container_wrap {
735 overflow: hidden;
736
737 .content_main {
738 height: calc(100% - 45px);
739 overflow: hidden auto;
740
741 &.panel {
742 padding: 0 16px 16px;
743 }
744 }
745 }
746
747 .tool_btns {
748 height: 44px;
749 margin: 0 -8px;
750 display: flex;
751 justify-content: center;
752 align-items: center;
753 border-top: 1px solid #d9d9d9;
754 }
755
756 :deep(.el-form) {
757 .width-left {
758 width: calc(100% - 125px);
759 }
760
761 .el-form-item.col2.radio-left {
762 width: calc(66.6% - 12px);
763 }
764 }
765
766 :deep(.dialog-form-inline.col3) {
767 align-items: flex-start;
768 }
769 </style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!