24ba6db6 by lihua

去掉不用的图片等

1 parent 8a799ac8
Showing 154 changed files with 579 additions and 9711 deletions
...@@ -570,3 +570,10 @@ export const getTransactionDetail = (params) => request({ ...@@ -570,3 +570,10 @@ export const getTransactionDetail = (params) => request({
570 export const getDictAllList = () => request({ 570 export const getDictAllList = () => request({
571 url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-all` 571 url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-all`
572 }) 572 })
573
574 // 数据字典树形数据
575 export const getDictionaryTree = (params) => request({
576 url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/tree-list`,
577 method: 'post',
578 params
579 })
...\ No newline at end of file ...\ No newline at end of file
......
1 /** --------------------- 质量评估模型 ------------------------------- */
2
3 import request from "@/utils/request";
4
5 /** 获取质量评估方案资产名称列表 */
6 export const getQualityDamList = () => request({
7 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-name-list`,
8 method: 'get'
9 })
10
11 /** 获取质量评估列表 */
12 export const getQualityList = (params) => request({
13 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-list`,
14 method: 'post',
15 data: params
16 })
17
18 /** 获取可选择的资产目录列表 */
19 export const getDamList = () => request({
20 url: `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/dam-name-list`,
21 method: 'post',
22 data: {}
23 })
24
25 /** 获取资产目录的表列表 */
26 export const getDamTableList = (damGuid) => request({
27 url: `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/get-table-list?damGuid=${damGuid}`,
28 method: 'get'
29 })
30
31 /** 获取资产目录表的详情 */
32 export const getTableFields = (subjectGuid) => request({
33 url:`${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/get-table-detail?subjectGuid=${subjectGuid}`,
34 method: 'get'
35 });
36
37 /** 获取资产表的规则列表 */
38 export const getDamTableRulesList = (params) => request({
39 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/list/rule-by-dam-guid`,
40 method: 'post',
41 data: params
42 })
43
44 /** 批量新增资产表的规则 */
45 export const saveDamTableRules = (params) => request({
46 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/add`,
47 method: 'post',
48 data: params
49 })
50
51 /** 获取资产表的单个规则 */
52 export const getRuleConfDetail = (param) => request({
53 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/detail?ruleConfGuid=${param}`,
54 method: 'get'
55 })
56
57 /** 获取对应执行方案的规则详情 */
58 export const getRecordRuleConfDetail = (param) => request({
59 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model-record/conf/detail?ruleConfGuid=${param.ruleConfGuid}&planExecGuid=${param.planExecGuid}`,
60 method: 'get'
61 });
62
63 /** 编辑资产表的单个规则 */
64 export const updateDamTableRule = (params) => request({
65 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/update`,
66 method: 'post',
67 data: params
68 })
69
70 /** 删除资产表的单个规则 */
71 export const deleteDamTableRule = (ruleConfGuid, planGuid: any = null) => request({
72 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/del?ruleConfGuid=${ruleConfGuid}&planGuid=${planGuid}`,
73 method: 'delete'
74 })
75
76 // 获取规则类型的接口
77 export const getRuleTypeList = () => request({
78 url:`${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-rule/list`,
79 method: 'post',
80 data: {}
81 })
82
83 // 获取规则大类的接口
84 export const getLargeCategoryList = () => request({
85 url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
86 method: 'post',
87 data: { paramCode: "LARGE-CATEGORY" }
88 })
89
90 // 获取规则小类的接口
91 export const getSmallCategoryList = () => request({
92 url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
93 method: 'post',
94 data: { paramCode: "SMALL-CATEGORY" }
95 })
96
97 /** 表的逻辑条件和sql检验。 */
98 export const validateSubjectTableRule = (params) => request({
99 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/sql-operate/check-sql`,
100 method: 'post',
101 data: params
102 })
103
104 /** 自定义sql检验 */
105 export const validateCustomSql = (params) => request({
106 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/check-custom-sql`,
107 method: 'post',
108 data: params
109 })
110
111 /** 批量验证过滤条件 */
112 export const batchValidateSubjectTableRule = (params) => request({
113 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/sql-operate/batch-check-sql`,
114 method: 'post',
115 data: params
116 })
117
118 /** ---------- 第二步,规则权重设置接口 ------ - */
119
120 /** 获取规则大类统计 */
121 export const getModelRuleCount = (params) => request({
122 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/list/model-rule-category-count`,
123 method: 'post',
124 data: params
125 })
126
127 /** 保存质量评估方案 */
128 export const saveQualityPlan = (params) => request({
129 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/add`,
130 method: 'post',
131 data: params
132 })
133
134 /** 更新质量方案 */
135 export const updateQualityPlan = (params) => request({
136 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/update`,
137 method: 'put',
138 data: params
139 })
140
141 /** 删除质量方案 */
142 export const deleteQualityPlan = (guids) => request({
143 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/del`,
144 method: 'delete',
145 data: guids
146 })
147
148 /** 获取方案详情,用于编辑 */
149 export const getPlanDetail = (params) => request({
150 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/detail/${params}`,
151 method: 'get'
152 })
153
154 /** 获取方案详情中的过滤条件,用于编辑 */
155 export const getPlanFilterDetail = (params) => request({
156 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-plan-filter?planGuid=${params}`,
157 method: 'get'
158 })
159
160 /** 手动执行方案 */
161 export const executePlan = (params) => request({
162 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-exec-plan?planGuid=${params.planGuid}&reportGuid=${params.reportGuid}`,
163 method: 'post'
164 })
165
166 /** 获取方案查看详情列表数据。 */
167 export const getAssessDetailTableData = (params) => request({
168 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/page-exec-log-list`,
169 method: 'post',
170 data: params
171 })
172
173 /** 根据执行guid,获取方案执行详情。 */
174 export const getExecPlanDetailTableData = (params) => request({
175 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-exec-detail?&planExecGuid=${params.planExecGuid}`,
176 method: 'get'
177 })
178
179 /** 获取方案详情中每个表的规则详细执行列表数据。 */
180 export const getAssessTableRulesData = (params) => request({
181 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-exec-table-detail?planExecGuid=${params.planExecGuid}&qualityModelGuid=${params.qualityModelGuid}`,
182 method: 'get'
183 })
184
185 /** 下载脏数据 */
186 export const downloadDirtyData = (params) => request({
187 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/down-dirty-data`,
188 method: 'post',
189 data: params,
190 responseType: 'blob'
191 })
192
193 /** html转word接口 */
194 export const htmlToWord = (params) => request({
195 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/download/html-to-word`,
196 method: 'postJsonD',
197 data: params,
198 responseType: 'blob'
199 });
200
201 /** 获取方案执行表规则查看 */
202 export const getTableRuleDetail= (params) => request({
203 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/query-exec-table-rule-detail?reportExecGuid=${params}`,
204 method: 'get'
205 });
206
207 /** 获取数据质量一级指标得分统计 */
208 export const getLargeCategoryScore = (params) => request({
209 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-largeCategory-score?reportExecGuid=${params}`,
210 method: 'get'
211 });
212
213 /** 获取质量分析报告的详细内容,根绝报告guid。 */
214 export const getReportDetail = (params) => request({
215 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-report-data`,
216 method: 'post',
217 data: params
218 });
219
220 /** 获取方案执行明细 */
221 export const getPlanReportDetail= (params) => request({
222 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/query-exec-table-detail?reportExecGuid=${params.reportExecGuid}&planGuid=${params.planGuid}`,
223 method: 'get'
224 });
225
226 /** 下载sql语句执行 */
227 export const downPlanSql = (planGuid) => request({
228 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/down-plan-sql?planGuid=${planGuid}`,
229 method: 'post',
230 responseType: 'blob'
231 })
1 import request from "@/utils/request";
2
3 /** 获取登记详情 */
4 export const getRegiaterDetail = (params) => request({
5 url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/detail`,
6 method: 'get',
7 params
8 })
9
10 /** 获取产品登记详情 */
11 export const getRegisterCatalogDetail = (damGuid) => request({
12 url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/detail-by-dam-guid?damGuid=${damGuid}`,
13 method: 'get'
14 })
15
16 /** 提交登记信息。 */
17 export const registerSave = (params) => request({
18 url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/save`,
19 method: 'post',
20 data: params
21 });
22
23 /** 更新登记信息 */
24 export const registerUpdate = (params) => request({
25 url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/update`,
26 method: 'post',
27 data: params
28 });
29
30 /** 删除登记信息 */
31 export const registerDelete = (params) => request({
32 url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/delete`,
33 method: 'delete',
34 data: params
35 });
36
37 /** 获取可使用的资产目录列表 */
38 export const getRegisterCatalogList = () => request({
39 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-catalog-table/public-data/dam-list?isRegister=${'Y'}&foundMode=4`,
40 method: 'get'
41 })
1 import request from "@/utils/request";
2
3 //获取需求表树形列表
4 export const getDemandTreeList = (params) => {
5 return request({
6 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/page-list`,
7 method: "post",
8 data: params,
9 });
10 };
11
12 //获取所有需求表列表
13 export const getDemandAll = (params) => {
14 return request({
15 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/get-list-data`,
16 method: "get",
17 params
18 });
19 };
20
21 //新增需求列表
22 export const saveDemandTree = (params) => {
23 return request({
24 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/save`,
25 method: "post",
26 data: params,
27 });
28 };
29
30 //修改需求列表
31 export const updateDemandTree = (params) => {
32 return request({
33 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/update`,
34 method: "post",
35 data: params,
36 });
37 };
38
39 // 删除需求列表
40 export const deleteDemandTree = (params) => {
41 return request({
42 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/delete`,
43 method: "delete",
44 data: params,
45 });
46 };
47
48 //获取需求表
49 export const getDemandList = (params) => {
50 return request({
51 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/page-list`,
52 method: "post",
53 data: params,
54 });
55 };
56
57 //获取需求表详情
58 export const getDemandDetail = (params) => {
59 return request({
60 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/detail`,
61 method: "get",
62 params,
63 });
64 };
65
66 //新增需求表
67 export const saveDemand = (params) => {
68 return request({
69 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/save`,
70 method: "post",
71 data: params,
72 });
73 };
74
75 //修改需求表
76 export const updateDemand = (params) => {
77 return request({
78 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/update`,
79 method: "post",
80 data: params,
81 });
82 };
83
84 // 删除需求表
85 export const deleteDemand = (params) => {
86 return request({
87 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/delete`,
88 method: "delete",
89 data: params,
90 });
91 };
92
93 // 获取疾病列表
94 export const getDiseaseList = (params) => {
95 return request({
96 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/page-list`,
97 method: "post",
98 data: params,
99 });
100 };
101
102 //获取所有疾病列表
103 export const getDiseaseAll = () => {
104 return request({
105 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/get-list-data`,
106 method: "post"
107 });
108 };
109
110 // 获取疾病详情
111 export const getDiseaseDetail = (params) => {
112 return request({
113 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/detail`,
114 method: "get",
115 params,
116 });
117 };
118
119 // 新增疾病
120 export const saveDisease = (params) => {
121 return request({
122 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/save`,
123 method: "post",
124 data: params,
125 });
126 };
127
128 // 修改疾病
129 export const updateDisease = (params) => {
130 return request({
131 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/update`,
132 method: "post",
133 data: params,
134 });
135 };
136
137 // 删除疾病
138 export const deleteDisease = (params) => {
139 return request({
140 url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/delete`,
141 method: "delete",
142 data: params,
143 });
144 };
145
146 // 获取定价配置
147 export const getConfigureList = (params) => {
148 return request({
149 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/page-list`,
150 method: "post",
151 data: params,
152 });
153 };
154
155 // 获取配置详情
156 export const getConfigureDetail = (params) => {
157 return request({
158 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/detail`,
159 method: "get",
160 params,
161 });
162 };
163
164 // 新增配置
165 export const saveConfigure = (params) => {
166 return request({
167 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/save`,
168 method: "post",
169 data: params,
170 });
171 };
172
173 // 修改配置
174 export const updateConfigure = (params) => {
175 return request({
176 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/update`,
177 method: "post",
178 data: params,
179 });
180 };
181
182 // 删除配置
183 export const deleteConfigure = (params) => {
184 return request({
185 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/delete`,
186 method: "delete",
187 data: params,
188 });
189 };
190
191 // 复制配置
192 export const addCopyConfigure = (params) => {
193 return request({
194 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/copy`,
195 method: "post",
196 data: params,
197 });
198 };
199
200 // 获取数据定价
201 export const getPriceList = (params) => {
202 return request({
203 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/page-list`,
204 method: "post",
205 data: params,
206 });
207 };
208
209 // 获取数据定价详情
210 export const getPriceDetail = (params) => {
211 return request({
212 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/detail`,
213 method: "get",
214 params,
215 });
216 };
217
218 // 新增数据定价
219 export const savePrice = (params) => {
220 return request({
221 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/save`,
222 method: "post",
223 data: params,
224 });
225 };
226
227 // 修改数据定价
228 export const updatePrice = (params) => {
229 return request({
230 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/update`,
231 method: "post",
232 data: params,
233 });
234 };
235
236 // 获取数据定价结果
237 export const getPriceResult = (params) => {
238 return request({
239 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/pricing-price`,
240 method: "post",
241 data: params,
242 });
243 };
244
245 // 计算数据定价
246 export const calculatPrice = (params) => {
247 return request({
248 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/calculate-price`,
249 method: "post",
250 data: params,
251 });
252 };
253
254 // 删除数据定价
255 export const deletePrice = (params) => {
256 return request({
257 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/delete`,
258 method: "delete",
259 data: params,
260 });
261 };
262
263 // 获取数据资源目录
264 export const getDamCatalogList = (params) => {
265 return request({
266 url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-catalog-table/get-table-select-new`,
267 method: "get",
268 params,
269 });
270 };
271
272 // 获取模型相关需求表
273 export const getModelDemand = (params) => {
274 return request({
275 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/pricing-model`,
276 method: "get",
277 params,
278 });
279 };
280
281 // 获取质量模型评分
282 export const getModelScore = (params) => {
283 return request({
284 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-quality-score-by-dam-guid-v2`,
285 method: "get",
286 params,
287 });
288 };
289
290 export const exportModelScore = (params) => {
291 return request({
292 url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/download-template`,
293 method: "post",
294 data: params,
295 responseType: 'blob'
296 });
297 };
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h341.333333v341.333333H0zM0 682.666667h341.333333v341.333333H0zM682.666667 0h341.333333v341.333333H682.666667zM682.666667 682.666667h341.333333v341.333333H682.666667z" fill="#ffffff" p-id="882"></path></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h341.333333v341.333333H0zM0 682.666667h341.333333v341.333333H0zM682.666667 0h341.333333v341.333333H682.666667zM682.666667 682.666667h341.333333v341.333333H682.666667z" fill="#b2b2b2" p-id="882"></path></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h1024v146.261H0z m0 438.87h1024v146.26H0z m0 438.869h1024V1024H0z" p-id="896" fill="#ffffff"></path></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h1024v146.261H0z m0 438.87h1024v146.26H0z m0 438.869h1024V1024H0z" p-id="896" fill="#b2b2b2"></path></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#DCA54F" d="m136.533 273.067 669.048 422.058c10.65 6.725 15.838 20.48 12.697 33.588-3.106 13.073-13.824 22.186-26.077 22.22H238.42c-27.306 0-50.346-22.425-53.726-52.326l-48.162-425.54z"/><path fill="#DCA54F" d="M834.219 698.607c-3.345 29.9-26.385 52.326-53.692 52.326H245.794c-12.288 0-41.984-9.113-45.124-22.186-3.175-13.073 2.048-26.863 12.697-33.588l668.98-422.092-48.128 425.506z"/><path fill="#E7B15C" d="m512 170.667 298.428 490.598a61.44 61.44 0 0 1 2.184 59.324c-9.489 18.705-27.818 30.344-47.718 30.344H512V170.667z"/><path fill="#F2D59C" d="M512 170.667 196.062 666.01a61.44 61.44 0 0 0-2.185 59.323c9.49 18.705 27.341 25.6 47.24 25.6H512V170.667z"/><path fill="#E7B15C" d="M459.776 153.327c0 18.193 9.967 34.987 26.112 44.1a53.35 53.35 0 0 0 52.224 0c16.145-9.113 26.112-25.941 26.112-44.1 0-28.126-23.381-50.927-52.224-50.927s-52.224 22.801-52.224 50.927zM851.319 255.18c-.41 18.432 9.455 35.67 25.771 45.022 16.316 9.318 36.523 9.318 52.873 0 16.315-9.353 26.18-26.59 25.77-45.056-.614-27.648-23.825-49.8-52.224-49.8-28.364 0-51.541 22.152-52.19 49.834zm-783.018 0c-.444 18.432 9.42 35.67 25.736 45.022 16.316 9.318 36.523 9.318 52.873 0 16.316-9.353 26.18-26.59 25.77-45.056-.614-27.648-23.825-49.8-52.223-49.8-28.365 0-51.542 22.152-52.19 49.834z"/><path fill="#DCA54F" d="M238.933 819.2h546.134q34.133 0 34.133 34.133 0 34.134-34.133 34.134H238.933q-34.133 0-34.133-34.134 0-34.133 34.133-34.133z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 85.333c235.648 0 426.667 191.019 426.667 426.667S747.648 938.667 512 938.667 85.333 747.648 85.333 512 276.352 85.333 512 85.333zm0 85.334a341.333 341.333 0 1 0 0 682.666 341.333 341.333 0 0 0 0-682.666zm0 298.666c85.333 0 156.459 14.208 213.333 42.667a213.333 213.333 0 0 1-426.666 0c56.874-28.459 128-42.667 213.333-42.667zM362.667 298.667A106.667 106.667 0 0 1 467.2 384H258.133a106.667 106.667 0 0 1 104.534-85.333zm298.666 0A106.667 106.667 0 0 1 765.867 384H556.8a106.667 106.667 0 0 1 104.533-85.333z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 938.667C276.352 938.667 85.333 747.648 85.333 512S276.352 85.333 512 85.333 938.667 276.352 938.667 512 747.648 938.667 512 938.667zm0-85.334a341.333 341.333 0 1 0 0-682.666 341.333 341.333 0 0 0 0 682.666zM341.333 554.667h341.334a170.667 170.667 0 1 1-341.334 0zm0-85.334a64 64 0 1 1 0-128 64 64 0 0 1 0 128zm341.334 0a64 64 0 1 1 0-128 64 64 0 0 1 0 128z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 938.667C276.352 938.667 85.333 747.648 85.333 512S276.352 85.333 512 85.333 938.667 276.352 938.667 512 747.648 938.667 512 938.667zm0-85.334a341.333 341.333 0 1 0 0-682.666 341.333 341.333 0 0 0 0 682.666zm-213.333-128a213.333 213.333 0 0 1 426.666 0H640a128 128 0 0 0-256 0h-85.333zm42.666-256a64 64 0 1 1 0-128 64 64 0 0 1 0 128zm341.334 0a64 64 0 1 1 0-128 64 64 0 0 1 0 128z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M704 328a72 72 0 1 0 144 0 72 72 0 1 0-144 0z"/><path d="M999.904 116.608a32 32 0 0 0-21.952-10.912L521.76 73.792a31.552 31.552 0 0 0-27.2 11.904l-92.192 114.848a32 32 0 0 0 .672 40.896l146.144 169.952-147.456 194.656 36.48-173.376a32 32 0 0 0-11.136-31.424L235.616 245.504l79.616-125.696a32 32 0 0 0-29.28-49.024L45.76 87.552a32 32 0 0 0-29.696 34.176l55.808 798.016a32.064 32.064 0 0 0 34.304 29.696l176.512-13.184c17.632-1.312 30.848-16.672 29.504-34.272s-16.576-31.04-34.304-29.536L133.44 883.232l-6.432-92.512 125.312-12.576a32 32 0 0 0 28.672-35.04 32.16 32.16 0 0 0-35.04-28.672L122.56 726.848 82.144 149.184l145.152-10.144-60.96 96.224a32 32 0 0 0 6.848 41.952l198.4 161.344-58.752 279.296a30.912 30.912 0 0 0 .736 14.752 31.68 31.68 0 0 0 1.408 11.04l51.52 154.56a31.968 31.968 0 0 0 27.456 21.76l523.104 47.552a32.064 32.064 0 0 0 34.848-29.632l55.776-798.048a32.064 32.064 0 0 0-7.776-23.232zm-98.912 630.848-412.576-39.648a31.52 31.52 0 0 0-34.912 28.768 32 32 0 0 0 28.8 34.912l414.24 39.808-6.272 89.536-469.728-42.72-39.584-118.72 234.816-310.016a31.936 31.936 0 0 0-1.248-40.192L468.896 219.84l65.088-81.056 407.584 28.48-40.576 580.192z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M165.415 827.077c-11.815 0-19.692-7.877-19.692-19.692V214.646c0-11.815 7.877-19.692 19.692-19.692h159.508c7.877 0 17.723 3.938 23.63 9.846l228.432 287.508c7.877 9.846 7.877 25.6 0 37.415l-230.4 287.508c-5.908 7.877-15.754 11.815-25.6 11.815l-155.57-1.97zm706.954-334.77L641.97 206.77c-9.846-11.815-27.569-15.754-41.354-3.938l-45.292 37.415c-13.785 9.846-15.754 29.539-3.938 41.354L738.462 512 551.385 744.37c-9.847 11.815-7.877 31.507 3.938 41.353l45.292 37.415c13.785 9.847 29.539 7.877 41.354-3.938l230.4-287.508c7.877-15.754 7.877-29.538 0-39.384z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M914.5 653.5c-5.5 0-11 1.1-16 3.3l-.2.1h-.2L510.2 822.2 122.2 657h-.2l-.2-.1c-5-2.1-10.3-3.3-16-3.3-23.1 0-41.8 19.3-41.8 43.1 0 18 10.7 33.3 25.8 39.8l403.9 172.1.4.1c10.2 4.4 21.8 4.4 32 0l.2-.1c.1 0 .1-.1.2-.1l403.9-172.1c15.1-6.5 25.8-21.8 25.8-39.8.1-23.8-18.6-43.1-41.7-43.1zm0-186.5c-7.9-.2-16 3.2-16 3.2L510.2 635.6 121.8 470.2s-10.3-3.2-16-3.2C82.7 467 64 486.2 64 510c0 17.9 10.7 33.3 25.8 39.7l403.9 172c.1 0 .1.1.2.1l.1.1c5 2.1 10.3 3.3 16 3.3 5.7 0 11.1-1.2 16-3.3l.2-.1c.1 0 .1 0 .2-.1l403.9-172c15.1-6.4 25.8-21.8 25.9-39.7.1-23.8-18.6-43-41.7-43zM89.8 363.2l403.9 172.1c.1 0 .1 0 .2.1l.1.1c5 2.1 10.3 3.2 16 3.2 5.5 0 10.9-1.1 16-3.2l.2-.1.2-.1 403.9-172c15.1-6.5 25.8-21.8 25.9-39.7 0-18-10.7-33.3-25.8-39.8L526.5 111.6c-.1 0-.1 0-.2-.1l-.2-.1c-10.2-4.4-21.8-4.4-32 0l-.1.1L89.8 283.7C74.7 290.1 64 305.5 64 323.5c0 17.9 10.7 33.2 25.8 39.7z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="232.422" height="200" class="icon" viewBox="0 0 1190 1024"><path d="M610.533 122.802A890.76 890.76 0 0 1 668.74 51.22a140.855 140.855 0 0 1 212.38 0q132.528 132.014 263.63 265.454a143.25 143.25 0 0 1 1.083 209.243q-223.76 227.667-449.972 452.88a140.484 140.484 0 0 1-205.592-.57Q266.309 755.61 45.374 530.11a142.595 142.595 0 0 1 1.14-209.272q135.18-139.087 273.297-275.18a142.595 142.595 0 0 1 210.698 2.453c22.473 22.416 41.523 48.311 62.114 72.61zm-66.906 55.812c-28.975-24.669-53.415-45.117-77.428-66.05a57.038 57.038 0 0 0-85.3 1.283q-133.897 133.07-266.053 267.85c-30.715 31.37-29.717 57.038.427 90.148 13.09 14.26 27.265 27.72 40.954 41.552L540.86 900.542c30.972 31.114 59.89 36.19 87.61 15.999 15.6-11.408 30.715-23.414 46.058-35.164l1.227-17.111c-25.154-21.333-51.334-41.467-75.12-64.31-28.147-27.15-29.63-49.48-8.555-71.298s44.832-20.619 71.297 6.417c23.072 23.642 43.492 49.88 70.214 80.908l51.733-57.58c-28.946-26.58-57.038-49.822-82.106-76.088s-19.963-61.972 12.663-72.181a69.615 69.615 0 0 1 54.015 13.033 770.98 770.98 0 0 1 72.666 69.928l95.167-93.742-234.796-236.421c-8.556 7.985-20.762 19.706-33.196 31.37a179.27 179.27 0 0 1-221.079 18.196c-55.982-37.503-60.488-79.197-13.118-126.995 32.768-33.054 66.22-65.594 108.172-106.86zM511.43 342.94a93.029 93.029 0 0 0 101.498-21.104c16.541-17.368 33.624-34.223 50.793-51.049 34.907-34.223 54.186-34.223 89.406 1.112q115.131 115.302 229.777 231.003c8.556 8.699 17.739 16.912 34.68 33.025 19.364-23.014 36.19-44.575 54.699-64.538 35.62-38.472 36.019-62-1.512-99.987Q948.938 248.2 826.592 125.569c-39.67-39.756-64.082-39.756-104.151.285q-94.626 94.54-188.538 189.85c-6.788 6.73-12.406 14.859-22.473 27.122z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M487 71.425a75 75 0 0 1 72.575 0l335.7 185.5a75 75 0 0 1 38.75 65.65V690.85a75 75 0 0 1-38.75 65.625l-335.7 185.55a75 75 0 0 1-72.55 0l-335.7-185.5a75 75 0 0 1-38.75-65.675V322.6a75 75 0 0 1 38.75-65.6L487 71.4v.025zM859 322.6 523.275 137.1l-335.7 185.5v368.25l335.7 185.5 335.75-185.5V322.6zm-601.75 37.1A37.5 37.5 0 0 1 308.2 345l215.1 118.875L738.45 345a37.5 37.5 0 0 1 36.25 65.625l-213.9 118.25V764.55a37.5 37.5 0 0 1-75 0v-235.7l-213.9-118.2a37.5 37.5 0 0 1-14.65-51v.05z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200.195" height="200" class="icon" viewBox="0 0 1025 1024"><path d="M960.13 661.73c45.18-217.23-72.82-435.39-279.35-516.48C668.79 62.35 597.7.84 513.93.9 430.17.85 359.09 62.35 347.11 145.25 172.89 213.66 58.28 381.73 58.23 568.91c0 23.86 3.21 54.82 9.53 92.77-39.81 30.79-65.38 78.96-65.38 133.1.02 44.67 17.8 87.5 49.4 119.07a168.43 168.43 0 0 0 119.13 49.27c29.77 0 57.76-7.68 81.95-21.16a454.28 454.28 0 0 0 261.08 82.03c93.38.16 184.54-28.51 261.03-82.08 24.28 13.49 52.23 21.25 81.99 21.25 44.67.03 87.52-17.7 119.13-49.27a168.394 168.394 0 0 0 49.4-119.08 167.91 167.91 0 0 0-65.36-133.08zM512.67 74c51.95 0 94.06 42.1 94.06 93.93.03 51.92-42.03 94.03-93.94 94.07-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.04 93.94-94.06zM171.59 884.57c-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.03 93.94-94.06 51.95 0 94.06 42.1 94.06 93.93.03 51.93-42.03 94.04-93.94 94.07zm536.95-9.94c-57.43 36.55-124.44 56.51-194.61 56.51a360.66 360.66 0 0 1-194.58-56.56 167.297 167.297 0 0 0 20.09-79.75c0-92.97-77.1-175.32-183.55-167.6 0 0-5.72-35.81-4.65-58.32.04-141.03 81.92-269.23 209.87-328.56 27.74 59.34 87.32 97.24 152.82 97.2 66.03 0 123.14-36.47 152.76-97.29 127.98 59.35 209.89 187.58 209.92 328.65 0 19.71-4.74 58.32-4.74 58.32-104.78-9.35-183.46 74.59-183.46 167.6a167.3 167.3 0 0 0 20.13 79.8zm144.05 9.94c-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.03 93.94-94.06 51.95 0 94.06 42.1 94.06 93.93.03 51.93-42.03 94.04-93.94 94.07z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M804.571 530.286v182.857q0 68-48.285 116.286T640 877.714H164.571q-68 0-116.285-48.285T0 713.143V237.714q0-68 48.286-116.285T164.57 73.143h402.286q8 0 13.143 5.143t5.143 13.143V128q0 8-5.143 13.143t-13.143 5.143H164.571q-37.714 0-64.571 26.857t-26.857 64.571v475.429q0 37.714 26.857 64.571t64.571 26.857H640q37.714 0 64.571-26.857t26.858-64.571V530.286q0-8 5.142-13.143T749.714 512h36.572q8 0 13.143 5.143t5.142 13.143zM1024 36.57v292.572q0 14.857-10.857 25.714t-25.714 10.857-25.715-10.857l-100.571-100.57L488.57 626.857q-5.714 5.714-13.142 5.714t-13.143-5.714l-65.143-65.143q-5.714-5.714-5.714-13.143t5.714-13.142l372.571-372.572-100.57-100.571q-10.857-10.857-10.857-25.715t10.857-25.714T694.857 0H987.43q14.857 0 25.714 10.857T1024 36.571z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="m878.6 246.4-328-196.6c-3-1.6-6-3.2-9-4.4-3.2-1.2-6.4-2.4-9.6-3.2-3.2-.8-6.6-1.6-10-2-3.4-.4-6.8-.6-10-.6-3.4 0-6.8.2-10 .6-3.4.4-6.6 1-10 2-3.2.8-6.4 2-9.6 3.2-3.2 1.2-6.2 2.8-9 4.4l-328 196.6c-3 1.8-5.8 3.8-8.4 6s-5.2 4.4-7.6 7c-2.4 2.4-4.6 5.2-6.6 7.8-2 2.8-4 5.6-5.6 8.6-1.6 3-3.2 6.2-4.4 9.4-1.2 3.2-2.4 6.4-3.2 9.8-.8 3.4-1.4 6.8-2 10.2-.4 3.4-.6 6.8-.6 10.4v392.8c0 3.4.2 6.8.6 10.4.4 3.4 1 6.8 2 10.2.8 3.4 2 6.6 3.2 9.8 1.2 3.2 2.8 6.4 4.4 9.4 1.6 3 3.6 6 5.6 8.6 2 2.8 4.2 5.4 6.6 8 2.4 2.4 5 4.8 7.6 7 2.6 2.2 5.6 4.2 8.4 6l86 51.4.4.2c43.4 22.2 60 22.2 79.2 22.2 67.8 0 110-43.8 110-114.6V355.8c0-1.2 0-2.4-.4-3.4s-.6-2.2-1-3.4c-.4-1-1-2.2-1.6-3.2-.6-1-1.4-1.8-2.2-2.8-.8-.8-1.8-1.6-2.6-2.2s-2-1.2-3-1.6c-1-.4-2.2-.8-3.4-1-1.2-.2-2.4-.4-3.4-.4h-47.2c-1.2 0-2.4.2-3.4.4-1.2.2-2.2.6-3.4 1-1 .4-2.2 1-3 1.6-1 .6-1.8 1.4-2.6 2.2-.8.8-1.6 1.8-2.2 2.8-.6 1-1.2 2-1.6 3.2-.4 1-.8 2.2-1 3.4s-.4 2.4-.4 3.4v380.8c0 2.8-.2 5.4-.8 8-.6 2.6-1.6 5.2-2.8 7.6-1.2 2.4-2.8 4.6-4.6 6.6-1.8 2-4 3.8-6.2 5.2-12.4 7.6-30.6 6-51-4.6L190.6 710c-.6-.4-1-1.2-1-2V321c0-1 .4-1.8 1.2-2.2L511 122.6c.6-.2 1-.2 1.6 0L833 318.8c.8.6 1.2 1.4 1.2 2.4v387c0 .8-.2 1.6-1 2.2L512.4 901.6c-.6.2-1.2.2-1.6 0l-82-48.6c-1.2-.8-2.6-1.4-3.8-1.8-1.4-.4-2.8-.8-4.2-.8-1.4 0-2.8 0-4.4.4-1.4.4-2.8.8-4 1.4l-.8.4C389 866 383 869.4 362 877.2c-3.4 1.2-11.4 4.2-12.2 12.2s7 13.6 13.8 17.6L473 974.2c5.8 3.4 12 6.2 18.6 8 6.6 1.8 13.2 2.8 20 2.8h1.2c6.6-.2 13.2-1 19.6-2.8 6.4-1.8 12.4-4.4 18.2-7.8L878.4 778c3-1.8 5.8-3.8 8.4-6 2.6-2.2 5.2-4.6 7.6-7 2.4-2.4 4.6-5.2 6.6-8s4-5.6 5.6-8.8 3.2-6.2 4.4-9.4c1.2-3.2 2.4-6.4 3.2-9.8.8-3.4 1.6-6.8 2-10.2.4-3.4.6-6.8.6-10.4v-393c0-3.4-.2-6.8-.6-10.4-.4-3.4-1-6.8-2-10.2-.8-3.4-2-6.6-3.2-9.8s-2.8-6.4-4.4-9.4c-1.6-3-3.6-6-5.6-8.6-2-2.8-4.2-5.4-6.6-7.8-2.4-2.4-5-4.8-7.6-7-2.6-2-5.4-4-8.2-5.8z"/><path d="M621.4 642.8c-78.6 0-95.4-22-100.4-57.4l-.6-3-1.2-3c-.4-1-1-1.8-1.8-2.6-.6-.8-1.4-1.6-2.2-2.4-.8-.8-1.6-1.4-2.6-1.8-1-.6-1.8-1-2.8-1.4-1-.4-2-.6-3-.8-1-.2-2-.4-3.2-.4H462c-1.2 0-2.4.2-3.4.4-1.2.2-2.2.6-3.4 1-1 .4-2 1-3 1.8-1 .6-1.8 1.4-2.6 2.2-.8.8-1.6 1.8-2.2 2.8-.6 1-1.2 2-1.6 3-.4 1-.8 2.2-1 3.4-.2 1.2-.4 2.4-.2 3.4 0 30.8 10.8 131.2 177 131.2 51.4 0 94.2-12 123.6-34.8 29.4-22.8 45.2-55.8 45.2-95.4 0-79.2-51.6-100.8-153.4-115-103.4-14.4-103.4-21.8-103.4-37.8 0-11.6 0-38.6 74.8-38.6 53.2 0 81.8 6.8 90.8 42.2.2 1 .4 2 .8 2.8.4 1 .8 1.8 1.4 2.6.6.8 1 1.6 1.8 2.4.6.8 1.4 1.4 2.2 2 .8.6 1.6 1.2 2.4 1.6.8.4 1.8 1 2.6 1.2 1 .4 1.8.6 2.8.8s2 .2 3 .2h42c2.4 0 4.8-.6 7.2-1.6 2.2-1 4.2-2.6 5.8-4.4 1.6-1.8 2.8-4 3.6-6.4.8-2.4 1-4.8.8-7.2-5.4-75-60.2-113-167.2-113-97.2 0-155.2 43.8-155.2 117 0 80.4 60 103 150.4 112.4C709 561.2 709 577 709 591c.2 22.6-9 51.8-87.6 51.8z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M440.064 761.856A319.36 319.36 0 0 1 320 512a319.36 319.36 0 0 1 120.064-249.856 256 256 0 1 0 0 499.712zM512 218.624a320 320 0 1 1 0 586.752 320 320 0 1 1 0-586.752zm63.168 376.96L469.76 497.6l-43.52 46.848 150.592 139.968 277.76-277.76-45.248-45.312-234.176 234.24z"/></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M600.874667 128H85.333333v760.021333h472.704v-58.453333H144.426667V186.453333h384.256v207.36h206.890666V426.666667l-0.128 168.490666h59.136L794.666667 426.666667V347.434667L600.874667 128z m-13.098667 73.984l117.76 133.376h-117.76V201.984z" fill="#727272" p-id="1060"></path><path d="M338.688 432h304v50.688H338.602667v-50.688z m0 253.354667h304v50.645333H338.602667v-50.688z m0-126.72h304v50.688H338.602667v-50.645334z" fill="#B2B2B2" p-id="1061"></path><path d="M784.512 938.666667h-55.722667v-111.488H617.386667v-55.722667h111.445333V660.053333h55.722667v111.445334H896v55.722666h-111.488z" fill="#44ABB4" p-id="1062"></path><path d="M186.666667 229.333333h228.010666v75.989334H186.666667V229.333333z m0 173.525334h75.989333v333.141333H186.666667V402.858667z" fill="#0098E6" p-id="1063" /></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M582.485333 128H85.333333v760.021333h455.808v-58.453333H142.336V186.453333h370.517333v207.36h199.466667V426.666667l-0.085333 168.490666h57.002666L769.322667 426.666667V347.434667L582.442667 128z m-12.672 73.984l113.578667 133.376h-113.578667V201.984z" fill="#727272" p-id="920"></path><path d="M212.010667 305.322667h177.322666v50.688H212.010667z" fill="#0098E6" p-id="921"></path><path d="M262.656 457.344h380.032v56.746667H262.613333v-56.746667z m0 171.221333h379.904v56.746667H262.656v-56.746667z" fill="#B2B2B2" p-id="922"></path><path d="M784.512 771.456V660.053333h-55.722667v111.445334H617.386667v55.722666h111.445333V938.666667h55.722667v-111.488H896v-55.722667z" fill="#44ABB4" p-id="923" /></svg>
...\ No newline at end of file ...\ No newline at end of file
1 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M256 213.333333h426.666667v85.333334H256z" fill="#5280C1" p-id="971"></path><path d="M256 426.666667h426.666667v42.666666H256v-42.666666z m0 128h298.666667v42.666666H256v-42.666666z m0 128h256v42.666666H256v-42.666666z" fill="#B2B2B2" p-id="972"></path><path d="M938.666667 636.970667L813.056 512 682.666667 636.970667v93.696l90.666666-62.250667V938.666667h79.445334v-270.250667L938.666667 730.709333z" fill="#5280C1" p-id="973"></path><path d="M629.205333 875.050667H128V85.333333h725.333333v373.802667h-60.416V146.346667H188.416V814.08h440.746667z" fill="#727272" p-id="974" /></svg>
...\ No newline at end of file ...\ No newline at end of file
...@@ -353,521 +353,5 @@ const routes: RouteRecordRaw[] = [ ...@@ -353,521 +353,5 @@ const routes: RouteRecordRaw[] = [
353 } 353 }
354 ], 354 ],
355 }, 355 },
356 // {
357 // path: '/data-asset/register-managemant',
358 // component: Layout,
359 // meta: {
360 // title: '数据登记管理',
361 // icon: 'sidebar-videos',
362 // },
363 // children: [
364 // {
365 // path: '',
366 // name: 'registerManagemant',
367 // component: () => import('@/views/data_asset/registerManagemant.vue'),
368 // meta: {
369 // title: '数据登记管理',
370 // sidebar: false,
371 // breadcrumb: false,
372 // cache: true
373 // },
374 // },
375 // {
376 // path: 'register-start',
377 // name: 'registerStart',
378 // component: () => import('@/views/data_asset/registerStart.vue'),
379 // meta: {
380 // title: '新建资产登记',
381 // sidebar: false,
382 // breadcrumb: false,
383 // cache: true,
384 // editPage: true,
385 // reuse: true
386 // },
387 // beforeEnter: (to, from) => {
388 // if (to.query.type) {
389 // to.meta.title = `详情-`;
390 // return;
391 // }
392 // if (to.query.guid) {
393 // to.meta.title = `编辑-`;
394 // to.meta.editPage = true;
395 // }
396 // }
397 // },
398 // {
399 // path: 'register-detail',
400 // name: 'registerInfoDetail',
401 // component: () => import('@/views/data_asset/registerDetail.vue'),
402 // meta: {
403 // title: '详情-',
404 // sidebar: false,
405 // breadcrumb: false,
406 // cache: true,
407 // reuse: true
408 // }
409 // }
410 // ],
411 // },
412 // {
413 // path: '/data-asset/quality-evaluate',
414 // component: Layout,
415 // meta: {
416 // title: '资产质量评价管理',
417 // icon: 'sidebar-videos',
418 // },
419 // children: [
420 // {
421 // path: '',
422 // name: 'qualityEvaluate',
423 // component: () => import('@/views/data_asset/qualityEvaluate.vue'),
424 // meta: {
425 // title: '资产质量评价管理',
426 // sidebar: false,
427 // breadcrumb: false,
428 // cache: true
429 // },
430 // },
431 // {
432 // path: 'register-detail',
433 // name: 'registerDetail',
434 // component: () => import('@/views/data_asset/registerDetail.vue'),
435 // meta: {
436 // title: '详情-',
437 // sidebar: false,
438 // breadcrumb: false,
439 // cache: true,
440 // reuse: true
441 // }
442 // }
443 // ],
444 // },
445 // {
446 // path: '/data-asset/quality-assess',
447 // component: Layout,
448 // meta: {
449 // title: '质量评估模型',
450 // icon: 'sidebar-videos',
451 // },
452 // children: [
453 // {
454 // path: '',
455 // name: 'damQualityAssess',
456 // component: () => import('@/views/data_asset/damQualityAssess.vue'),
457 // meta: {
458 // title: '质量评估模型',
459 // sidebar: false,
460 // breadcrumb: false,
461 // cache: true
462 // },
463 // },
464 // {
465 // path: 'dam-quality-plan',
466 // name: 'damQualityPlan',
467 // component: () => import('@/views/data_asset/damQualityPlan.vue'),
468 // meta: {
469 // title: '新建质量评估',
470 // sidebar: false,
471 // breadcrumb: false,
472 // cache: true,
473 // editPage: true,
474 // reuse: true
475 // },
476 // beforeEnter: (to, from) => {
477 // if (to.query.guid) {
478 // to.meta.title = `编辑-${to.query.damName}`;
479 // to.meta.editPage = true;
480 // }
481 // }
482 // },
483 // {
484 // path: 'dam-assess-log',
485 // name: 'damQualityAssessLog',
486 // component: () => import('@/views/data_asset/damQualityAssessLog.vue'),
487 // meta: {
488 // title: '执行日志',
489 // sidebar: false,
490 // breadcrumb: false,
491 // cache: true,
492 // reuse: true
493 // },
494 // beforeEnter: (to, from) => {
495 // if (to.query.guid) {
496 // to.meta.title = `日志-${to.query.name}`;
497 // }
498 // }
499 // },
500 // {
501 // path: 'dam-assess-detail',
502 // name: 'damAssessDetail',
503 // component: () => import('@/views/data_asset/damAssessDetail.vue'),
504 // meta: {
505 // title: '查看结果',
506 // sidebar: false,
507 // breadcrumb: false,
508 // cache: true,
509 // reuse: true
510 // },
511 // beforeEnter: (to, from) => {
512 // if (to.query.name) {
513 // to.meta.title = `查看结果-${to.query.name}`;
514 // }
515 // }
516 // },
517 // {
518 // path: 'dam-analysis-report',
519 // name: 'damAnalysisReport',
520 // component: () => import('@/views/data_asset/damAnalysisReport.vue'),
521 // meta: {
522 // title: '分析报告',
523 // sidebar: false,
524 // breadcrumb: false,
525 // cache: true,
526 // reuse: true
527 // },
528 // beforeEnter: (to, from) => {
529 // if (to.query.name) {
530 // to.meta.title = `分析报告-${to.query.name}`;
531 // }
532 // }
533 // },
534 // ],
535 // },
536 // {
537 // path: '/data-asset/value-evaluate',
538 // component: Layout,
539 // meta: {
540 // title: '资产价值评估管理',
541 // icon: 'ep:grid',
542 // },
543 // children: [
544 // {
545 // path: '',
546 // name: 'valueEvaluate',
547 // component: () => import('@/views/data_asset/valueEvaluate.vue'),
548 // meta: {
549 // title: '资产价值评估管理',
550 // sidebar: false,
551 // breadcrumb: false,
552 // cache: true
553 // },
554 // },
555 // {
556 // path: 'register-detail',
557 // name: 'registerValueDetail',
558 // component: () => import('@/views/data_asset/registerDetail.vue'),
559 // meta: {
560 // title: '详情-',
561 // sidebar: false,
562 // breadcrumb: false,
563 // cache: true,
564 // reuse: true
565 // }
566 // }
567 // ],
568 // },
569 // {
570 // path: '/data-asset/certificate-management',
571 // component: Layout,
572 // meta: {
573 // title: '资产证件管理',
574 // icon: 'ep:grid',
575 // },
576 // children: [
577 // {
578 // path: '',
579 // name: 'certificateManagement',
580 // component: () => import('@/views/data_asset/certificateManagement.vue'),
581 // meta: {
582 // title: '资产证件管理',
583 // sidebar: false,
584 // cache: true,
585 // breadcrumb: false,
586 // },
587 // },
588 // {
589 // path: 'register-detail',
590 // name: 'certificateDetail',
591 // component: () => import('@/views/data_asset/registerDetail.vue'),
592 // meta: {
593 // title: '详情-',
594 // sidebar: false,
595 // breadcrumb: false,
596 // cache: true,
597 // reuse: true
598 // }
599 // }
600 // ],
601 // },
602 // {
603 // path: '/data-asset/objection-handle',
604 // component: Layout,
605 // meta: {
606 // title: '公示异议处理',
607 // icon: 'ep:grid',
608 // },
609 // children: [
610 // {
611 // path: '',
612 // name: 'damObjectionHandle',
613 // component: () => import('@/views/data_asset/damObjectionHandle.vue'),
614 // meta: {
615 // title: '公示异议处理',
616 // sidebar: false,
617 // cache: true,
618 // breadcrumb: false,
619 // },
620 // },
621 // ]
622 // },
623 // {
624 // path: '/data-entry/entry-consult',
625 // component: Layout,
626 // meta: {
627 // title: '入表咨询',
628 // icon: 'sidebar-videos',
629 // },
630 // children: [
631 // {
632 // path: '',
633 // name: 'entryConsult',
634 // component: () => import('@/views/data_entry/index.vue'),
635 // meta: {
636 // title: '入表咨询',
637 // sidebar: false,
638 // breadcrumb: false,
639 // cache: true
640 // },
641 // },
642 // ],
643 // },
644 // {
645 // path: '/data-entry/entry-management',
646 // component: Layout,
647 // meta: {
648 // title: '入表管理',
649 // icon: 'sidebar-videos',
650 // },
651 // children: [
652 // {
653 // path: '',
654 // name: 'entryManagement',
655 // component: () => import('@/views/data_transaction/entryManagement.vue'),
656 // meta: {
657 // title: '入表管理',
658 // sidebar: false,
659 // breadcrumb: false,
660 // cache: true
661 // },
662 // },
663 // ],
664 // },
665 // {
666 // path: '/data-product/product-listing',
667 // component: Layout,
668 // meta: {
669 // title: '数据产品上架',
670 // icon: 'sidebar-videos',
671 // },
672 // children: [
673 // {
674 // path: '',
675 // name: 'productListing',
676 // component: () => import('@/views/data_product/productListing.vue'),
677 // meta: {
678 // title: '数据产品上架',
679 // sidebar: false,
680 // breadcrumb: false,
681 // cache: true
682 // },
683 // },
684 // {
685 // path: 'listing-detail',
686 // name: 'productListingDetail',
687 // component: () => import('@/views/data_product/productListingDetail.vue'),
688 // meta: {
689 // title: '新建数据产品',
690 // sidebar: false,
691 // reuse: true,
692 // breadcrumb: false,
693 // cache: true
694 // },
695 // beforeEnter: (to, from) => {
696 // if(to.query.type){
697 // if (to.query.type == 'detail') {
698 // to.meta.title = `详情-${to.query.name}`;
699 // } else {
700 // to.meta.editPage = true;
701 // to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
702 // }
703 // }
704 // }
705 // },
706 // ],
707 // },
708 // {
709 // path: '/data-product/listing-check',
710 // component: Layout,
711 // meta: {
712 // title: '数据产品审核',
713 // icon: 'sidebar-videos',
714 // },
715 // children: [
716 // {
717 // path: '',
718 // name: 'productListingCheck',
719 // component: () => import('@/views/data_product/productListingCheck.vue'),
720 // meta: {
721 // title: '数据产品审核',
722 // sidebar: false,
723 // breadcrumb: false,
724 // cache: true,
725 // },
726 // },
727 // {
728 // path: 'listing-detail',
729 // name: 'productListingCheckDetail',
730 // component: () => import('@/views/data_product/productListingDetail.vue'),
731 // meta: {
732 // title: '产品审核详情',
733 // sidebar: false,
734 // breadcrumb: false,
735 // cache: true,
736 // reuse: true,
737 // },
738 // beforeEnter: (to, from) => {
739 // if (to.query.type == 'check') {
740 // to.meta.editPage = true;
741 // to.meta.title = `详情-${to.query.name}`;
742 // return;
743 // }
744 // }
745 // },
746 // ],
747 // },
748 // {
749 // path: '/data-product/demands-publish',
750 // component: Layout,
751 // meta: {
752 // title: '数据需求发布',
753 // icon: 'sidebar-videos',
754 // },
755 // children: [
756 // {
757 // path: '',
758 // name: 'productDemandsPublish',
759 // component: () => import('@/views/data_product/productDemandsPublish.vue'),
760 // meta: {
761 // title: '数据需求发布',
762 // sidebar: false,
763 // breadcrumb: false,
764 // cache: true
765 // },
766 // },
767 // {
768 // path: 'demands-detail',
769 // name: 'productDemandsDetail',
770 // component: () => import('@/views/data_product/productDemandsDetail.vue'),
771 // meta: {
772 // title: '新建数据需求',
773 // sidebar: false,
774 // breadcrumb: false,
775 // cache: true,
776 // reuse: true,
777 // },
778 // beforeEnter: (to, from) => {
779 // if(to.query.type){
780 // if (to.query.type == 'detail') {
781 // to.meta.title = `详情-${to.query.name}`;
782 // } else {
783 // to.meta.editPage = true;
784 // to.meta.title = to.query.type=='add'? `新建数据需求${to.query.interfaceType == '2' ? '(算法竞赛)' : (to.query.interfaceType == '3' ? '(要素市场)' : '')}`: to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
785 // }
786 // }
787 // }
788 // },
789 // ],
790 // },
791 // {
792 // path: '/data-product/demands-check',
793 // component: Layout,
794 // meta: {
795 // title: '数据需求审核',
796 // icon: 'sidebar-videos',
797 // },
798 // children: [
799 // {
800 // path: '',
801 // name: 'productDemandsCheck',
802 // component: () => import('@/views/data_product/productDemandsCheck.vue'),
803 // meta: {
804 // title: '数据需求审核',
805 // sidebar: false,
806 // breadcrumb: false,
807 // cache: true
808 // },
809 // },
810 // {
811 // path: 'demands-detail',
812 // name: 'productDemandsCheckDetail',
813 // component: () => import('@/views/data_product/productDemandsDetail.vue'),
814 // meta: {
815 // title: '需求审核详情',
816 // sidebar: false,
817 // breadcrumb: false,
818 // cache: true,
819 // reuse: true,
820 // },
821 // beforeEnter: (to, from) => {
822 // if (to.query.type == 'check') {
823 // to.meta.editPage = true;
824 // to.meta.title = `详情-${to.query.name}`;
825 // }
826 // }
827 // },
828 // ],
829 // },
830 // {
831 // path: '/data-guide/transaction-finance',
832 // component: Layout,
833 // meta: {
834 // title: '交易融资指南',
835 // icon: 'sidebar-videos',
836 // },
837 // children: [
838 // {
839 // path: '',
840 // name: 'transactionFinanceGuid',
841 // component: () => import('@/views/data_transaction/transactionFinanceGuide.vue'),
842 // meta: {
843 // title: '交易融资指南',
844 // sidebar: false,
845 // breadcrumb: false,
846 // cache: true
847 // },
848 // },
849 // ],
850 // },
851 {
852 path: '/data-product/transaction-management',
853 component: Layout,
854 meta: {
855 title: '资产交易管理',
856 icon: 'sidebar-videos',
857 },
858 children: [
859 {
860 path: '',
861 name: 'transactionManagement',
862 component: () => import('@/views/data_transaction/transactionManagement.vue'),
863 meta: {
864 title: '资产交易管理',
865 sidebar: false,
866 breadcrumb: false,
867 cache: true
868 },
869 },
870 ],
871 },
872 ] 356 ]
873 export default routes 357 export default routes
......
...@@ -254,27 +254,6 @@ const routes: RouteRecordRaw[] = [ ...@@ -254,27 +254,6 @@ const routes: RouteRecordRaw[] = [
254 ], 254 ],
255 }, 255 },
256 { 256 {
257 path: '/data-asset-register/objection-handle',
258 component: Layout,
259 meta: {
260 title: '公示异议处理',
261 icon: 'ep:grid',
262 },
263 children: [
264 {
265 path: '',
266 name: 'damObjectionHandle',
267 component: () => import('@/views/data_asset/damObjectionHandle.vue'),
268 meta: {
269 title: '公示异议处理',
270 sidebar: false,
271 cache: true,
272 breadcrumb: false,
273 },
274 },
275 ]
276 },
277 {
278 path: '/data-asset-register/register-progress', 257 path: '/data-asset-register/register-progress',
279 component: Layout, 258 component: Layout,
280 meta: { 259 meta: {
......
1
2 import type { RouteRecordRaw } from 'vue-router'
3
4 function Layout() {
5 return import('@/layouts/index.vue')
6 }
7
8 const routes: RouteRecordRaw[] = [
9 {
10 path: '/data-product/product-listing',
11 component: Layout,
12 meta: {
13 title: '数据产品上架',
14 icon: 'sidebar-videos',
15 },
16 children: [
17 {
18 path: '',
19 name: 'productListing',
20 component: () => import('@/views/data_product/productListing.vue'),
21 meta: {
22 title: '数据产品上架',
23 sidebar: false,
24 breadcrumb: false,
25 cache: true
26 },
27 },
28 {
29 path: 'listing-detail',
30 name: 'productListingDetail',
31 component: () => import('@/views/data_product/productListingDetail.vue'),
32 meta: {
33 title: '新建数据产品',
34 sidebar: false,
35 reuse: true,
36 breadcrumb: false,
37 cache: true
38 },
39 beforeEnter: (to, from) => {
40 if(to.query.type){
41 if (to.query.type == 'detail') {
42 to.meta.title = `详情-${to.query.name}`;
43 } else {
44 to.meta.editPage = true;
45 to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
46 }
47 }
48 }
49 },
50 {
51 path: 'product-JQZQ-detail',
52 name: 'productInfoJSZQDetail',
53 component: () => import('@/views/data_asset/registerJSZQDetail.vue'),
54 meta: {
55 title: '详情-',
56 sidebar: false,
57 breadcrumb: false,
58 cache: true,
59 reuse: true
60 },
61 beforeEnter: (to, from) => {
62 if(to.query.type){
63 if (to.query.type == 'detail') {
64 to.meta.title = `详情-${to.query.name}`;
65 } else {
66 to.meta.editPage = true;
67 to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
68 }
69 }
70 }
71 }
72 ],
73 },
74 {
75 path: '/data-product/listing-check',
76 component: Layout,
77 meta: {
78 title: '数据产品审核',
79 icon: 'sidebar-videos',
80 },
81 children: [
82 {
83 path: '',
84 name: 'productListingCheck',
85 component: () => import('@/views/data_product/productListingCheck.vue'),
86 meta: {
87 title: '数据产品审核',
88 sidebar: false,
89 breadcrumb: false,
90 cache: true,
91 },
92 },
93 {
94 path: 'listing-detail',
95 name: 'productListingCheckDetail',
96 component: () => import('@/views/data_product/productListingDetail.vue'),
97 meta: {
98 title: '产品审核详情',
99 sidebar: false,
100 breadcrumb: false,
101 cache: true,
102 reuse: true,
103 },
104 beforeEnter: (to, from) => {
105 if (to.query.type == 'check') {
106 to.meta.editPage = true;
107 to.meta.title = `详情-${to.query.name}`;
108 return;
109 }
110 }
111 },
112 ],
113 },
114 {
115 path: '/data-product/demands-publish',
116 component: Layout,
117 meta: {
118 title: '数据需求发布',
119 icon: 'sidebar-videos',
120 },
121 children: [
122 {
123 path: '',
124 name: 'productDemandsPublish',
125 component: () => import('@/views/data_product/productDemandsPublish.vue'),
126 meta: {
127 title: '数据需求发布',
128 sidebar: false,
129 breadcrumb: false,
130 cache: true
131 },
132 },
133 {
134 path: 'demands-detail',
135 name: 'productDemandsDetail',
136 component: () => import('@/views/data_product/productDemandsDetail.vue'),
137 meta: {
138 title: '新建数据需求',
139 sidebar: false,
140 breadcrumb: false,
141 cache: true,
142 reuse: true,
143 },
144 beforeEnter: (to, from) => {
145 if(to.query.type){
146 if (to.query.type == 'detail') {
147 to.meta.title = `详情-${to.query.name}`;
148 } else {
149 to.meta.editPage = true;
150 to.meta.title = to.query.type=='add'? `新建数据需求${to.query.interfaceType == '2' ? '(算法竞赛)' : (to.query.interfaceType == '3' ? '(要素市场)' : '')}`: to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
151 }
152 }
153 }
154 },
155 ],
156 },
157 {
158 path: '/data-product/demands-check',
159 component: Layout,
160 meta: {
161 title: '数据需求审核',
162 icon: 'sidebar-videos',
163 },
164 children: [
165 {
166 path: '',
167 name: 'productDemandsCheck',
168 component: () => import('@/views/data_product/productDemandsCheck.vue'),
169 meta: {
170 title: '数据需求审核',
171 sidebar: false,
172 breadcrumb: false,
173 cache: true
174 },
175 },
176 {
177 path: 'demands-detail',
178 name: 'productDemandsCheckDetail',
179 component: () => import('@/views/data_product/productDemandsDetail.vue'),
180 meta: {
181 title: '需求审核详情',
182 sidebar: false,
183 breadcrumb: false,
184 cache: true,
185 reuse: true,
186 },
187 beforeEnter: (to, from) => {
188 if (to.query.type == 'check') {
189 to.meta.editPage = true;
190 to.meta.title = `详情-${to.query.name}`;
191 }
192 }
193 },
194 ],
195 },
196 // {
197 // path: '/data-guide/transaction-finance',
198 // component: Layout,
199 // meta: {
200 // title: '交易融资指南',
201 // icon: 'sidebar-videos',
202 // },
203 // children: [
204 // {
205 // path: '',
206 // name: 'transactionFinanceGuid',
207 // component: () => import('@/views/data_transaction/transactionFinanceGuide.vue'),
208 // meta: {
209 // title: '交易融资指南',
210 // sidebar: false,
211 // breadcrumb: false,
212 // cache: true
213 // },
214 // },
215 // ],
216 // },
217 {
218 path: '/data-product/transaction-management',
219 component: Layout,
220 meta: {
221 title: '资产交易管理',
222 icon: 'sidebar-videos',
223 },
224 children: [
225 {
226 path: '',
227 name: 'transactionManagement',
228 component: () => import('@/views/data_transaction/transactionManagement.vue'),
229 meta: {
230 title: '资产交易管理',
231 sidebar: false,
232 breadcrumb: false,
233 cache: true
234 },
235 },
236 ],
237 },
238 ]
239
240 export default routes
...@@ -29,19 +29,11 @@ const constantRoutes: RouteRecordRaw[] = [ ...@@ -29,19 +29,11 @@ const constantRoutes: RouteRecordRaw[] = [
29 // }, 29 // },
30 // }, 30 // },
31 { 31 {
32 path: '/register',
33 name: 'register',
34 component: () => import('@/views/register.vue'),
35 meta: {
36 title: '注册',
37 },
38 },
39 {
40 path: '/:all(.*)*', 32 path: '/:all(.*)*',
41 name: 'notFound', 33 name: 'notFound',
42 component: () => import('@/views/[...all].vue'), 34 component: () => import('@/views/[...all].vue'),
43 meta: { 35 meta: {
44 title: '数据资产管理', 36 title: '可信数据空间',
45 }, 37 },
46 }, 38 },
47 ] 39 ]
...@@ -97,17 +89,8 @@ const systemRoutes: RouteRecordRaw[] = [ ...@@ -97,17 +89,8 @@ const systemRoutes: RouteRecordRaw[] = [
97 89
98 // 动态路由(异步路由、导航栏路由) 90 // 动态路由(异步路由、导航栏路由)
99 const asyncRoutes: RouteRecordRaw[] = [ 91 const asyncRoutes: RouteRecordRaw[] = [
100 ...AssetIndex,
101 ...DataAssess, 92 ...DataAssess,
102 ...DataAssetRegistry, 93 ...DataAssetRegistry,
103 ...DataEntry,
104 ...SecurityMenu,
105 ...DataMeta,
106 ...DataQuality,
107 ...DataInventory,
108 ...DataAnonymization,
109 ...DataTrustedSpace,
110 ...DataPricing
111 ] 94 ]
112 95
113 const constantRoutesByFilesystem = generatedRoutes.filter((item) => { 96 const constantRoutesByFilesystem = generatedRoutes.filter((item) => {
......
1 <template>
2 <div class="guide">
3 <div class="title">{{ data.title }}</div>
4 <div class="content">
5 <div class="guid-item " :class="{
6 qualityAssessment: data.qualityAssessment || false,
7 assetRegistration: data.assetRegistration || false,
8 registration: data.registration || false,
9 }" v-for="item in data.children" :key="item.title">
10 <div class="guid-item-title">{{ item.title }}</div>
11 <div style="padding-right: 30px;">
12 <div class="text" v-for="text in item.children" :key="text" v-html="text"></div>
13 </div>
14 </div>
15 </div>
16 </div>
17 </template>
18 <script setup lang="ts">
19 const props = defineProps({
20 data: {
21 type: Object,
22 default: {} as any
23 }
24 })
25 const data: any = computed(() => props.data)
26 </script>
27 <style lang="scss" scoped>
28 .guide {
29 padding-top: 16px;
30 width: 100%;
31 height: auto;
32 padding-left: 16px;
33 padding-right: 11px;
34 background: #fff;
35 margin-bottom: 16px;
36
37 .title {
38 font-size: 18px;
39 color: #212121;
40 letter-spacing: 0;
41 line-height: 27px;
42 font-weight: 600;
43 padding-top: 10px;
44 }
45
46 .content {
47 display: flex;
48 justify-content: space-around;
49 padding-bottom: 16px;
50
51 .qualityAssessment {
52 background: url("../../../../assets/images/qualityAssessment.png");
53 background-size: auto 100%;
54 background-position: center right;
55 background-repeat: no-repeat;
56 }
57
58 .assetRegistration {
59 background: url("../../../../assets/images/assetRegistration.png");
60 background-size: auto 100%;
61 background-position: center right;
62 background-repeat: no-repeat;
63 }
64
65 .registration {
66 background: url("../../../../assets/images/registration.png");
67 background-size: auto 100%;
68 background-position: center right;
69 background-repeat: no-repeat;
70 }
71
72 .guid-item {
73 width: 100%;
74 height: 171px;
75 border-right: 1px solid rgba(217, 217, 217, 1);
76
77 // background: url("../../../../assets/images/qualityAssessment.png");
78 // width: 100%;
79 // height:171px;
80 // background-size: auto 100%;
81 // background-position: center right;
82 // background-repeat: no-repeat;
83 &>div {
84 margin-left: 24px
85 }
86
87 .guid-item-title {
88 font-size: 20px;
89 color: #2D60B9;
90 letter-spacing: 0;
91 line-height: 30px;
92 font-weight: 500;
93 margin-top: 24px;
94 margin-bottom: 16px;
95 }
96
97 .text {
98 list-style: none;
99 color: #666666;
100 letter-spacing: 0;
101 line-height: 21px;
102 font-weight: 400;
103 margin-bottom: 8px;
104 width: 100%;
105 }
106 }
107 }
108
109 }
110 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: damAnalysisReport
3 </route>
4
5 <script lang="ts" setup name="damAnalysisReport">
6 import { ref } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import {
9 getReportDetail,
10 getLargeCategoryScore,
11 getPlanReportDetail,
12 getTableRuleDetail,
13 htmlToWord
14 } from '@/api/modules/dataAssetQuality';
15 import * as echarts from 'echarts';
16 import { QuestionFilled } from "@element-plus/icons-vue";
17 import { ElMessage, ElMessageBox } from "element-plus";
18 import { changeNum, tagMethod, tagType } from '@/utils/common';
19 //报告导出word
20 import html2canvas from 'html2canvas';
21
22 const route = useRoute();
23 const reportExecGuid = route.query.reportExecGuid;
24 const planGuid = route.query.planGuid;
25 const wordName = ref(route.query.name);
26
27 const { proxy } = getCurrentInstance() as any;
28
29 const detailInfo: any = ref({});
30 const fullscreenLoading = ref(false);
31 const loadingText = ref('报告图表生成中,请勿关闭浏览器...');
32
33 const getReportDetailInfo = () => {
34 let ps: any = [];
35 fullscreenLoading.value = true;
36 loadingText.value = '报告图表生成中,请勿关闭浏览器...';
37 ps.push(getReportDetail({ reportExecGuid: reportExecGuid, planGuid: planGuid }).then((res: any) => {
38 if (res.code == proxy.$passCode) {
39 let data = res.data || {};
40 detailInfo.value = data;
41 barChartData.value = data.qualityScoreLine?.slice(0, 12) || [];
42 planDetailTableInfo.value.data = [{
43 guid: '1',
44 planName: data.planName,
45 planType: data.analysisReportType == 1 ? '表' : (data.analysisReportType == 2 ? '数据库' : (data.analysisReportType == 4 ? '数据同步' : '分组')),
46 execDuration: data.planExecDuration != null ? changeNum(data.planExecDuration ?? 0) : '--',
47 execTime: data.execTime,
48 qualityTableNum: data.qualityTableNum != null ? changeNum(data.qualityTableNum ?? 0) : '--',
49 ruleCount: data.ruleCount != null ? changeNum(data.ruleCount ?? 0) : '--',
50 totalNum: data.totalNum != null ? changeNum(data.totalNum ?? 0) : '--',
51 qualifiedNum: data.qualifiedNum != null ? changeNum(data.qualifiedNum ?? 0) : '--',
52 unqualifiedNum: data.unqualifiedNum != null ? changeNum(data.unqualifiedNum ?? 0) : '--',
53 qualityScore: data.qualityScore ?? '--',
54 qualifiedRate: data.qualifiedRate != null ? (changeNum((data.qualifiedRate ?? 0) * 100, 2, true) + '%') : '--'
55 }]
56 } else {
57 ElMessage.error(res.msg);
58 }
59 }))
60 ps.push(getLargeCategoryScore(reportExecGuid).then((res: any) => {
61 if (res.code == proxy.$passCode) {
62 let data = res.data || {};
63 qualityRuleDetailTableInfo.value.data = data.largeCategoryScoreList || [];
64 if (!qualityRuleDetailTableInfo.value.data.length) {
65 qualityRuleDetailTableInfo.value.footerHtml = '';
66 } else {
67 qualityRuleDetailTableInfo.value.footerHtml = `<span>质量得分</span><span>∑规则得分*权重</span>`;
68 }
69 radarChartData.value = data.largeCategoryScore || {};
70 } else {
71 ElMessage.error(res.msg);
72 }
73 }))
74 /** 表明细,单表时没有。 */
75 ps.push(getPlanReportDetail({ reportExecGuid: reportExecGuid, planGuid: planGuid }).then((res: any) => {
76 if (res.code == proxy.$passCode) {
77 let data = res.data || [];
78 modelDetailTableInfo.value.data = data;
79 } else {
80 ElMessage.error(res.msg);
81 }
82 }))
83 ps.push(getTableRuleDetail(reportExecGuid).then((res: any) => {
84 if (res.code == proxy.$passCode) {
85 let data = res.data || [];
86 modelRuleDetailTableInfo.value.data = data;
87 } else {
88 ElMessage.error(res.msg);
89 }
90 }))
91 Promise.all(ps).then(() => {
92 fullscreenLoading.value = false;
93 });
94 }
95
96 /** 方案明细表。 */
97 const planDetailTableInfo: any = ref({
98 id: "plan-detail-table",
99 loading: false,
100 height: 'auto',
101 minPanelHeight: '60px',
102 minHeight: '60px',
103 fields: [
104 { label: "评估时间", field: "execTime", width: 180, },
105 { label: "耗时(秒)", field: "execDuration", width: 100, align: 'right' },
106 { label: "评估表数", field: "qualityTableNum", width: 100, align: 'right' },
107 { label: "规则数", field: "ruleCount", width: 100, align: 'right' },
108 { label: "评估总数", field: "totalNum", width: 100, align: 'right' },
109 { label: "合格条数", field: "qualifiedNum", width: 100, align: 'right' },
110 { label: "不合格条数", field: "unqualifiedNum", width: 100, align: 'right' },
111 { label: "合格率", field: "qualifiedRate", width: 100, align: 'right' },
112 { label: "质量评分", field: "qualityScore", width: 100, align: "right" }
113 ],
114 data: [],
115 showPage: false,
116 actionInfo: {
117 show: false
118 }
119 });
120
121 /** 数据质量一级指标得分明细 */
122 const qualityRuleDetailTableInfo = ref({
123 id: "quality-rule-detail-table",
124 loading: false,
125 minHeight: '60px',
126 footerClass: 'last-row',
127 footerHtml: `<span>质量得分</span><span></span>`,
128 fields: [
129 { label: "规则大类", field: "largeCategoryName", width: 100 },
130 {
131 label: "规则数", field: "ruleCount", width: 100, align: 'right', getName: (scope) => {
132 return scope.row.ruleCount != null ? changeNum(scope.row.ruleCount ?? 0) : '--';
133 }
134 },
135 {
136 label: "规则得分", field: "largeCategoryScore", width: 100, align: "right", getName: (scope) => {
137 return scope.row.largeCategoryScore != null ? changeNum(scope.row.largeCategoryScore ?? 0, 2, true) : '--';
138 }
139 },
140 {
141 label: "权重", field: "ruleLargeWeight", width: 100, align: "right", getName: (scope) => {
142 return scope.row.ruleLargeWeight != null ? scope.row.ruleLargeWeight.toFixed(2) : '--';
143 }
144 },
145 {
146 label: "质量评分", field: "qualityScore", width: 100, align: "right", getName: (scope) => {
147 return scope.row.qualityScore != null ? changeNum(scope.row.qualityScore ?? 0, 2, true) : '--';
148 }
149 }
150 ],
151 data: [],
152 showPage: false,
153 actionInfo: {
154 show: false
155 }
156 });
157
158 /** 表明细。 */
159 const modelDetailTableInfo = ref({
160 id: "model-detail-table",
161 loading: false,
162 height: 'auto',
163 minPanelHeight: '60px',
164 minHeight: '60px',
165 fields: [
166 { label: "序号", type: "index", width: 56, align: "center" },
167 { label: "表名", field: "qualityModelName", width: 140 },
168 { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
169 { label: "评估时间", field: "execTime", width: 180, },
170 {
171 label: "耗时(秒)", field: "execDuration", width: 100, align: "right", getName: (scope) => {
172 return scope.row.execDuration != null ? changeNum(scope.row.execDuration ?? 0) : '--';
173 }
174 },
175 {
176 label: "规则数", field: "ruleNum", width: 100, align: "right", getName: (scope) => {
177 return scope.row.ruleNum != null ? changeNum(scope.row.ruleNum ?? 0) : '--';
178 }
179 },
180 {
181 label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
182 return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
183 }
184 },
185 {
186 label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
187 return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
188 }
189 },
190 {
191 label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
192 return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
193 }
194 },
195 {
196 label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
197 return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
198 }
199 },
200 { label: "评估范围", field: "dataRange", width: 180 },
201 ],
202 data: [{
203 guid: '1',
204 executeState: 'N'
205 }],
206 showPage: false,
207 actionInfo: {
208 show: false
209 }
210 });
211
212 /** 规则明细。 */
213 const modelRuleDetailTableInfo = ref({
214 id: "model-rule-detail-table",
215 loading: false,
216 height: 'auto',
217 minPanelHeight: '60px',
218 minHeight: '60px',
219 fields: [
220 { label: "序号", type: "index", width: 56, align: "center" },
221 { label: "表名", field: "qualityModelName", width: 140 },
222 { label: "规则类型", field: "ruleName", width: 140 },
223 { label: "规则名称", field: "ruleConfName", width: 140 },
224 { label: "规则大类", field: "largeCategory", width: 100 },
225 { label: "规则小类", field: "smallCategory", width: 140 },
226 { label: "规则字段", field: "ruleField", width: 140 },
227 { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
228 {
229 label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
230 return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
231 }
232 },
233 {
234 label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
235 return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
236 }
237 },
238 {
239 label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
240 return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
241 }
242 },
243 {
244 label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
245 return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
246 }
247 }
248 ],
249 data: [],
250 showPage: false,
251 actionInfo: {
252 show: false
253 }
254 });
255
256 /** 柱形图数据数组 */
257 const barChartData: any = ref([]);
258 /** 雷达图数据数组 */
259 const radarChartData: any = ref([]);
260
261 let barChart: any = null;
262 let radarChart: any = null;
263
264 let barChartWord: any = null;
265 let radarChartWord: any = null;
266
267 /** 设置柱形图option,默认只 展示12次的 */
268 const setBarChartOption = (barChart, isWord = false) => {
269 return new Promise((resolve, reject) => {
270 if (!barChartData.value.length) {
271 let option1 = {
272 title: [
273 {
274 text: "",
275 left: "30px",
276 top: "30px",
277 },
278 {
279 text: "暂无数据",
280 left: "center",
281 top: "center",
282 textStyle: {
283 fontStyle: "normal",
284 fontWeight: "400",
285 fontSize: 18,
286 },
287 },
288 ],
289 };
290 barChart.setOption(option1, true);
291 window.addEventListener("resize", () => {
292 barChart.resize();
293 });
294 return;
295 }
296 let itemXAxisData: any = [];
297 let itemYAxisData1: any = [];
298 let itemYAxisData2: any = [];
299 barChartData.value.forEach(d => {
300 itemXAxisData.push(d['execTime']);
301 itemYAxisData1.push(d['qualityScore']);
302 itemYAxisData2.push((d['qualifiedRate'] ?? 0) * 100);
303 })
304 let option = {
305 textStyle: {
306 fontFamily: 'SimSun'
307 },
308 color: ['#5B8FF9', '#FF4E00', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
309 title: {
310 show: false,
311 text: '评分趋势',
312 left: '30px',
313 top: '30px',
314 },
315 tooltip: {
316 trigger: 'axis',
317 axisPointer: {
318 type: 'cross',
319 crossStyle: {
320 color: '#999'
321 }
322 },
323 textStyle: {
324 align: 'left'
325 },
326 },
327 legend: {
328 right: 0,
329 textStyle: {
330 fontSize: 14
331 },
332 data: ['评分', '合格率']
333 },
334 grid: {
335 left: 30,
336 right: 60,
337 bottom: 5,
338 containLabel: true
339 },
340 xAxis: {
341 type: 'category',
342 boundaryGap: false,
343 nameTextStyle: {
344 color: '#000000'
345 },
346 axisLabel: {
347 interval: isWord ? 'auto' : 0,
348 textStyle: {
349 color: '#000000'
350 },
351 formatter: function (value) {
352 if (!value) {
353 return value;
354 }
355 let v = value.split(' ');
356 return v.join('\n');
357 }
358 },
359 axisTick: {
360 show: false,
361 },
362 axisLine: {
363 lineStyle: {
364 color: '#d9d9d9'
365 }
366 },
367 data: itemXAxisData
368 },
369 yAxis: {
370 type: 'value',
371 name: '',
372 min: 0,
373 max: 100,
374 nameTextStyle: {
375 color: '#000000'
376 },
377 axisLabel: {
378 textStyle: {
379 color: '#000000'
380 }
381 },
382 axisLine: {
383 //y轴
384 show: false
385 }
386 },
387 series: [{
388 name: '评分',
389 type: 'line',
390 data: itemYAxisData1,
391 label: {
392 show: false,
393 },
394 yAxisIndex: 0
395 }, {
396 name: '合格率',
397 type: 'line',
398 data: itemYAxisData2,
399 label: {
400 show: false,
401 },
402 tooltip: {
403 valueFormatter: function (value) {
404 return changeNum(value, 2, true) + '%';
405 }
406 },
407 yAxisIndex: 0
408 }]
409 };
410 option && barChart.setOption(option, true);
411 barChart.on('finished', () => {
412 resolve(true);
413 });
414 window.addEventListener('resize', () => {
415 barChart.resize();
416 });
417 });
418 }
419
420 /** 设置雷达图option. */
421 const setRadarChartOption = (radarChart) => {
422 return new Promise((resolve, reject) => {
423 let indicator = [{ name: '规范性', max: 100, min: 0, color: '#000' },
424 { name: '完整性', max: 100, min: 0, color: '#000' },
425 { name: '一致性', max: 100, min: 0, color: '#000' },
426 { name: '准确性', max: 100, min: 0, color: '#000' },
427 { name: '时效性', max: 100, min: 0, color: '#000' },
428 { name: '可访问性', max: 100, min: 0, color: '#000' }]
429 let data: any = [];
430 for (const key in radarChartData.value) {
431 let index = indicator.findIndex(i => i.name == key);
432 index > -1 && (data[index] = changeNum(radarChartData.value[key] ?? 0, 2));
433 }
434 let option = {
435 textStyle: {
436 fontFamily: 'SimSun'
437 },
438 color: ['#5B8FF9', '#6DD18E', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
439 title: {
440 show: false,
441 text: '数据质量一级指标得分',
442 left: '30px',
443 top: '30px',
444 },
445 tooltip: {
446 axisPointer: {
447 type: 'cross',
448 crossStyle: {
449 color: '#999'
450 }
451 },
452 textStyle: {
453 align: 'left'
454 },
455 },
456 legend: {
457 show: false
458 },
459 grid: {
460 left: 0,
461 bottom: 0,
462 containLabel: true
463 },
464 radar: {
465 indicator: indicator,
466 axisLabel: {
467 show: false
468 },
469 axisLine: {
470 lineStyle: {
471 color: '#d9d9d9'
472 }
473 },
474 axisTick: {
475 lineStyle: {
476 color: '#d9d9d9'
477 }
478 },
479 splitLine: {
480 lineStyle: {
481 color: '#d9d9d9'
482 }
483 }
484 },
485 series: [
486 {
487 type: 'radar',
488 data: [{
489 name: '数据质量一级指标得分',
490 value: data
491 }],
492 label: {
493 show: true,
494 position: 'bottom',
495 distance: 1,
496 color: '#000'
497 },
498 areaStyle: {
499 color: '#e8eefc'
500 }
501 }
502 ]
503 };
504 option && radarChart.setOption(option, true);
505 radarChart.on('finished', () => {
506 resolve(true);
507 });
508 window.addEventListener('resize', () => {
509 radarChart.resize();
510 });
511 });
512 }
513
514 watch(() => barChartData.value, (val) => {
515 setBarChartOption(barChart);
516 barChartWord && setBarChartOption(barChartWord, true);
517 })
518
519 watch(() => radarChartData.value, (val) => {
520 setRadarChartOption(radarChart);
521 radarChartWord && setRadarChartOption(radarChartWord);
522 })
523
524 onBeforeMount(() => {
525 getReportDetailInfo();
526 })
527
528 onMounted(() => {
529 barChart = echarts.init(document.getElementById('bar'));
530 radarChart = echarts.init(document.getElementById('radar'));
531 setBarChartOption(barChart);
532 setRadarChartOption(radarChart);
533 })
534
535 const domClone: any = ref(null);
536
537 const convertChartsToBase64 = (contentDocument) => {
538 // 找到所有的图表 (echart)
539 let canvases = contentDocument.querySelectorAll('#bar-word');
540 // 遍历图表,转换为 base64 静态图片
541 canvases.forEach((canvas, i) => {
542 let url = barChartWord.getDataURL();
543 let img = document.createElement('img');
544 if (url) {
545 // img.src = url.split(',')[1];
546 img.src = url;
547 img.width = 620;
548 img.height = 400;
549 img.crossOrigin = 'Anonymous';
550 }
551 canvas.parentNode.replaceChild(img, canvas);
552 });
553 let canvases1 = contentDocument.querySelectorAll('#radar-word');
554 canvases1.forEach((canvas, i) => {
555 let url = radarChartWord.getDataURL();
556 let img = document.createElement('img');
557 if (url) {
558 // img.src = url.split(',')[1];
559 img.src = url;
560 img.width = 620;
561 img.height = 400;
562 img.crossOrigin = 'Anonymous';
563 }
564 canvas.parentNode.replaceChild(img, canvas);
565 });
566 }
567
568 const convertHtml2Img = (dom, domClone) => {
569 const element = <HTMLElement>dom.querySelector('.kpi-content')
570 if (!element) {
571 return Promise.resolve();
572 }
573 return html2canvas(element, {
574 allowTaint: true,
575 useCORS: true,
576 scale: 1,
577 }).then((canvas: any) => {
578 document.documentElement.scrollTop = 0;
579 document.body.scrollTop = 0;
580 element.parentNode && ((<HTMLElement>element.parentNode).scrollTop = 0);
581 let url = canvas.toDataURL('image/jpeg');
582 let img = document.createElement('img');
583 if (url) {
584 // img.src = url.split(',')[1];
585 img.src = url;
586 img.width = 620;
587 img.height = 80;
588 img.crossOrigin = 'Anonymous';
589 }
590 const copyElement = <HTMLElement>domClone.querySelector('.kpi-content')
591 copyElement.parentNode?.replaceChild(img, copyElement);
592 })
593 }
594
595 const report = ref();
596
597 const isWordStyle = ref(false);
598
599 const isTransfered = ref(false);
600
601 const downloadBtnDisable = ref(false);
602
603 const transfer = () => {
604 isWordStyle.value = true;
605 nextTick(() => {
606 if (!isTransfered.value) {
607 barChartWord = echarts.init(document.getElementById('bar-word'));
608 downloadBtnDisable.value = true;
609 let ps1 = setBarChartOption(barChartWord, true);
610 radarChartWord = echarts.init(document.getElementById('radar-word'));
611 let ps2 = setRadarChartOption(radarChartWord);
612 Promise.all([ps1, ps2]).then(res => {
613 downloadBtnDisable.value = false;
614 isTransfered.value = true;
615 })
616 }
617 });
618 };
619
620 const getHTML = (reportResultContent) => {
621 let html = reportResultContent;
622 html = html.replace(/"/g, "'");
623 return html;
624 };
625
626 const download = () => {
627 let dom = domClone.value || (domClone.value = document.createElement('div'));
628 dom.innerHTML = report.value.innerHTML;
629 convertChartsToBase64(dom);
630 fullscreenLoading.value = true;
631 loadingText.value = '报告正在下载中,请勿关闭浏览器...';
632 convertHtml2Img(report.value, dom).then(() => {
633 htmlToWord({ html: getHTML(dom.innerHTML) }).then((res: any) => {
634 fullscreenLoading.value = false;
635 // let blob = new Blob([res.data], { type: 'application/msword' });
636 let objectUrl = URL.createObjectURL(res);
637 const link = document.createElement('a')
638 link.download = wordName.value + '质量评估报告.docx';
639 link.href = objectUrl
640 link.click()
641 })
642 // // 下载word 需要接口。
643 // const converted = htmlDocx.asBlob(`
644 // <html xmlns:o=\'urn:schemas-microsoft-com:office:office\' xmlns:w=\'urn:schemas-microsoft-com:office:word\' xmlns=\'http://www.w3.org/TR/REC-html40\'><head><style>
645 // ${document.head.outerHTML}
646 // </head>
647 // <body>
648 // ${dom.outerHTML}
649 // </body>
650 // </html>`)
651 // converted.then((res: any) => {
652 // // 导出无样式。
653 // console.log(res);
654 // let objectUrl = URL.createObjectURL(res);
655 // const link = document.createElement('a')
656 // link.download = detailInfo.value.analysisReportName + '.docx';
657 // link.href = objectUrl
658 // link.click()
659 // })
660 })
661 }
662
663 </script>
664
665 <template>
666 <div class="container_wrap" v-loading="fullscreenLoading" :element-loading-text="loadingText">
667 <div v-show="!isWordStyle" class="header-title">
668 <div>
669 <span>{{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</span>
670 <span class="time-detail">{{ '生成时间:' + (detailInfo.execTime ?? '--') }}</span>
671 </div>
672 <el-button type="primary" @click="transfer">生成Word报告</el-button>
673 <!-- <el-button @click="download">下载 Word</el-button> -->
674 </div>
675 <div v-show="!isWordStyle" class="content-main">
676 <div class="title">数据汇总</div>
677 <div class="kpi-content">
678 <div class="border-content">
679 <span class="number score-color">{{ detailInfo.qualityScore ?? '--' }}</span>
680 <div class="text">质量评分<el-tooltip placement="top" effect="light" popper-class="table_tooltip">
681 <template #content>
682 <div style="max-width: 236px;">
683 质量一级指标得分*权重
684 </div>
685 </template>
686 <el-icon style="margin-left: 2px;">
687 <QuestionFilled />
688 </el-icon>
689 </el-tooltip></div>
690 </div>
691 <div v-if="detailInfo.analysisReportType != 1" class="border-content ml16">
692 <span class="number">{{ detailInfo.qualityTableNum != null ? changeNum(detailInfo.qualityTableNum ?? 0) :
693 '--'
694 }}</span>
695 <span class="text">评估表数</span>
696 </div>
697 <div class="border-content ml16">
698 <span class="number num-color">{{ detailInfo.ruleCount != null ? changeNum(detailInfo.ruleCount ?? 0) : '--'
699 }}</span>
700 <span class="text">质量规则数</span>
701 </div>
702 <div class="border-content ml16">
703 <span class="number num-color">{{ detailInfo.totalNum != null ? changeNum(detailInfo.totalNum ?? 0) : '--'
704 }}</span>
705 <span class="text">评估总数</span>
706 </div>
707 <div class="border-content ml16">
708 <span class="number pass-color">{{ detailInfo.qualifiedNum != null ? changeNum(detailInfo.qualifiedNum ?? 0)
709 :
710 '--' }}</span>
711 <span class="text">合格条数</span>
712 </div>
713 <div class="border-content ml16">
714 <span class="number no-pass-color">{{ detailInfo.unqualifiedNum != null ?
715 changeNum(detailInfo.unqualifiedNum ??
716 0) : '--' }}</span>
717 <span class="text">不合格条数</span>
718 </div>
719 <div class="border-content ml16">
720 <span class="number rate-color">{{ detailInfo.qualifiedRate != null ? (changeNum((detailInfo.qualifiedRate
721 ?? 0) *
722 100, 2, true) + '%') : '--' }}</span>
723 <span class="text">合格率</span>
724 </div>
725 </div>
726 <div class="title">评分趋势</div>
727 <div class="content-chart-bar" id="bar">
728 </div>
729 <div class="content-radar-table">
730 <div class="content-two">
731 <div class="title">数据质量一级指标得分</div>
732 <div class="content-chart-radar" id="radar">
733 </div>
734 </div>
735 <div class="content-two">
736 <div class="title">数据质量一级指标得分明细</div>
737 <Table :tableInfo="qualityRuleDetailTableInfo" />
738 </div>
739 </div>
740 <div class="title">评估方案明细</div>
741 <Table :tableInfo="planDetailTableInfo" />
742 <template v-if="detailInfo.analysisReportType != 1">
743 <div class="title">表明细</div>
744 <Table :tableInfo="modelDetailTableInfo" />
745 </template>
746 <div class="title">规则明细</div>
747 <Table :tableInfo="modelRuleDetailTableInfo" />
748 </div>
749 <div v-show="isWordStyle" class="word-report">
750 <div class="word-btn">
751 <span>{{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</span>
752 <div>
753 <el-button @click="isWordStyle = false">返回</el-button>
754 <el-button type="primary" :disabled="downloadBtnDisable" @click="download">下载 Word</el-button>
755 </div>
756 </div>
757 <div class="word-report-main" ref="report">
758 <div style="width: 625px;">
759 <div style="text-align: center;padding: 8px 0px;">
760 <div
761 style="height: 40px;display: block;line-height: 32px;font-size: 18px;color: #212121;font-weight: 600;text-align: center;">
762 {{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</div>
763 <div style="font-size: 14px;color: #666666;font-weight: 400;">{{ '生成时间:' + detailInfo.execTime }}</div>
764 </div>
765 <div
766 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
767 数据汇总</div>
768 <div class="kpi-content">
769 <div class="border-content" style="padding-left: 8px;min-width: 70px;height: 72px">
770 <span class="number score-color">{{ detailInfo.qualityScore ?? '--' }}</span>
771 <div class="text">质量评分</div>
772 </div>
773 <div v-if="detailInfo.analysisReportType != 1" class="border-content"
774 style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
775 <span class="number">{{ detailInfo.qualityTableNum != null ? changeNum(detailInfo.qualityTableNum ?? 0)
776 :
777 '--'
778 }}</span>
779 <span class="text">评估表数</span>
780 </div>
781 <div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 84px;height: 72px">
782 <span class="number num-color">{{ detailInfo.ruleCount != null ? changeNum(detailInfo.ruleCount ?? 0) :
783 '--'
784 }}</span>
785 <span class="text">质量规则数</span>
786 </div>
787 <div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
788 <span class="number num-color">{{ detailInfo.totalNum != null ? changeNum(detailInfo.totalNum ?? 0) :
789 '--'
790 }}</span>
791 <span class="text">评估总数</span>
792 </div>
793 <div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
794 <span class="number pass-color">{{ detailInfo.qualifiedNum != null ? changeNum(detailInfo.qualifiedNum
795 ?? 0)
796 :
797 '--' }}</span>
798 <span class="text">合格条数</span>
799 </div>
800 <div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 84px;height: 72px">
801 <span class="number no-pass-color">{{ detailInfo.unqualifiedNum != null ?
802 changeNum(detailInfo.unqualifiedNum ??
803 0) : '--' }}</span>
804 <span class="text">不合格条数</span>
805 </div>
806 <div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
807 <span class="number rate-color">{{ detailInfo.qualifiedRate != null ?
808 (changeNum((detailInfo.qualifiedRate
809 ?? 0) *
810 100, 2, true) + '%') : '--' }}</span>
811 <span class="text">合格率</span>
812 </div>
813 </div>
814 <div
815 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
816 评分趋势</div>
817 <div class="content-chart-bar" style="border:none;padding: 8px 0px;" id="bar-word">
818 </div>
819 <div
820 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
821 数据质量一级指标得分</div>
822 <div class="content-chart-bar" style="border:none;height: 380px;padding: 8px 0px;" id="radar-word"></div>
823 <div
824 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
825 数据质量一级指标得分明细</div>
826 <table border="1" cellspacing="0"
827 style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
828 <thead>
829 <tr>
830 <th v-for="(item, index) in qualityRuleDetailTableInfo.fields.map(f => f.label)" :key="index">
831 <span>{{ item }}</span>
832 </th>
833 </tr>
834 </thead>
835 <tbody>
836 <tr v-for="(recordItem, j) in qualityRuleDetailTableInfo.data" :key="j">
837 <td v-for="(columnItem, i) in qualityRuleDetailTableInfo.fields" :key="i"
838 :style="{ 'text-align': <any>(columnItem.align ?? 'left') }">
839 <span :style="{ 'word-break': 'break-all' }">
840 {{ columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
841 recordItem[columnItem.field]) ?? '--') }}
842 </span>
843 </td>
844 </tr>
845 </tbody>
846 </table>
847 <div style="
848 background: #FFF1D4;
849 /* border-bottom: 1px solid #000;
850 border-right: 1px solid #000;
851 border-left: 1px solid #000; */
852 "><span>质量得分:</span><span>∑规则得分*权重</span></div>
853 <div
854 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
855 评估方案明细</div>
856 <table border="1" cellspacing="0"
857 style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
858 <thead>
859 <tr>
860 <th v-for="(item, index) in planDetailTableInfo.fields.map(f => f.label)" :key="index">
861 <span>{{ item }}</span>
862 </th>
863 </tr>
864 </thead>
865 <tbody>
866 <tr v-for="(recordItem, j) in planDetailTableInfo.data" :key="j">
867 <td v-for="(columnItem, i) in planDetailTableInfo.fields" :key="i"
868 :style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
869 <span :style="{ 'word-break': 'break-all' }">
870 {{ columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
871 recordItem[columnItem.field]) ?? '--') }}
872 </span>
873 </td>
874 </tr>
875 </tbody>
876 </table>
877 <template v-if="detailInfo.analysisReportType != 1">
878 <div
879 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
880 表明细</div>
881 <table border="1" cellspacing="0"
882 style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
883 <thead>
884 <tr>
885 <th v-for="(item, index) in modelDetailTableInfo.fields.slice(1).map(f => f.label)" :key="index">
886 <span>{{ item }}</span>
887 </th>
888 </tr>
889 </thead>
890 <tbody>
891 <tr v-for="(recordItem, j) in modelDetailTableInfo.data" :key="j">
892 <td v-for="(columnItem, i) in modelDetailTableInfo.fields.slice(1)" :key="i"
893 :style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
894 <span v-if="columnItem.type != 'tag'">
895 {{ (columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
896 recordItem[columnItem.field]) ?? '--')) }}
897 </span>
898 <span v-else :style="{
899 'white-space': 'nowrap', 'font-size': '12px', color: tagType(recordItem, columnItem.field) == 'success' ? '#1BA854' : (tagType(recordItem, columnItem.field) == 'warning' ? '#e6a23c' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FB2323' : '#999999')),
900 background: tagType(recordItem, columnItem.field) == 'success' ? '#F2FFF5' : (tagType(recordItem, columnItem.field) == 'warning' ? '#fdf6ec' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FFF2F4' : '#F5F5F5'))
901 }">
902 {{ (columnItem.field && recordItem[columnItem.field]) ? tagMethod(recordItem, columnItem.field) :
903 '--' }}
904 </span>
905 </td>
906 </tr>
907 </tbody>
908 </table>
909 </template>
910 <div
911 style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
912 规则明细</div>
913 <table border="1" cellspacing="0"
914 style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
915 <thead>
916 <tr>
917 <th v-for="(item, index) in modelRuleDetailTableInfo.fields.slice(1).map(f => f.label)" :key="index">
918 <span>{{ item }}</span>
919 </th>
920 </tr>
921 </thead>
922 <tbody>
923 <tr v-for="(recordItem, j) in modelRuleDetailTableInfo.data" :key="j">
924 <td v-for="(columnItem, i) in modelRuleDetailTableInfo.fields.slice(1)" :key="i"
925 :style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
926 <span v-if="columnItem.type != 'tag'">
927 {{ (columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
928 recordItem[columnItem.field]) ?? '--')) }}
929 </span>
930 <span v-else :style="{
931 'white-space': 'nowrap', 'font-size': '12px', color: tagType(recordItem, columnItem.field) == 'success' ? '#1BA854' : (tagType(recordItem, columnItem.field) == 'warning' ? '#e6a23c' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FB2323' : '#999999')),
932 background: tagType(recordItem, columnItem.field) == 'success' ? '#F2FFF5' : (tagType(recordItem, columnItem.field) == 'warning' ? '#fdf6ec' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FFF2F4' : '#F5F5F5'))
933 }">
934 {{ (columnItem.field && recordItem[columnItem.field]) ? tagMethod(recordItem, columnItem.field) :
935 '--'
936 }}
937 </span>
938 </td>
939 </tr>
940 </tbody>
941 </table>
942 </div>
943 </div>
944 </div>
945 </div>
946 </template>
947
948 <style lang="scss" scoped>
949 .container_wrap {
950 padding: 0;
951 }
952
953 .content-main {
954 height: calc(100% - 64px);
955 border-top: 1px solid #d9d9d9;
956 overflow-y: auto;
957 overflow-x: hidden;
958 padding: 0px 16px 16px;
959 }
960
961 .header-title {
962 margin: 16px 16px 8px;
963 height: 40px;
964 line-height: 32px;
965 display: flex;
966 flex-direction: row;
967 justify-content: space-between;
968 align-items: center;
969 font-size: 18px;
970 color: #212121;
971 font-weight: 600;
972 }
973
974 .time-detail {
975 font-size: 14px;
976 color: #666666;
977 font-weight: 400;
978 margin-left: 16px;
979 }
980
981 .kpi-content {
982 display: flex;
983 flex-direction: row;
984 }
985
986 .border-content {
987 height: 76px;
988 display: flex;
989 flex-direction: column;
990 align-items: left;
991 padding-left: 16px;
992 justify-content: center;
993 border: 1px solid #d9d9d9;
994 width: 160px;
995 min-width: 100px;
996 border-radius: 2px;
997
998 .number {
999 line-height: 30px;
1000 font-weight: 700;
1001 font-size: 20px;
1002 }
1003
1004 .num-color {
1005 color: #212121;
1006 }
1007
1008 .score-color {
1009 color: #FF5F1F;
1010 }
1011
1012 .pass-color {
1013 color: #1BA854;
1014 }
1015
1016 .no-pass-color {
1017 color: #FB2323;
1018 }
1019
1020 .rate-color {
1021 color: #5B8FF9;
1022 }
1023
1024 .text {
1025 font-size: 14px;
1026 color: #666666;
1027 display: flex;
1028
1029 .el-icon {
1030 color: #b2b2b2;
1031 }
1032 }
1033 }
1034
1035 .ml16 {
1036 margin-left: 16px;
1037 }
1038
1039 .ml32 {
1040 margin-left: 32px;
1041 }
1042
1043 .title {
1044 line-height: 24px;
1045 font-size: 16px;
1046 color: #212121;
1047 font-weight: 600;
1048 margin-top: 12px;
1049 margin-bottom: 8px;
1050 }
1051
1052 .content-radar-table {
1053 display: flex;
1054 flex-direction: row;
1055 height: 380px;
1056 justify-content: space-between;
1057
1058 .content-two {
1059 width: calc(50% - 16px);
1060
1061 .table_panel {
1062 min-height: 200px !important;
1063 height: calc(100% - 44px) !important;
1064 }
1065 }
1066
1067 .content-chart-radar {
1068 height: calc(100% - 44px);
1069 width: 100%;
1070 border: 1px solid #d9d9d9;
1071 padding: 8px;
1072 }
1073 }
1074
1075 .content-chart-bar {
1076 height: 300px;
1077 border: 1px solid #d9d9d9;
1078 padding: 8px;
1079 }
1080
1081 .word-report {
1082 height: 100%;
1083 widows: 100%;
1084 background-color: #f1f1f1;
1085
1086 .word-btn {
1087 background-color: #fff;
1088 margin: 8px 0px;
1089 padding: 0px 8px 8px;
1090 height: 48px;
1091 line-height: 32px;
1092 display: flex;
1093 flex-direction: row;
1094 justify-content: space-between;
1095 align-items: center;
1096 font-size: 18px;
1097 color: #212121;
1098 font-weight: 600;
1099 }
1100
1101 }
1102
1103 .word-report-main {
1104 height: calc(100% - 56px);
1105 overflow-y: auto;
1106 overflow-x: hidden;
1107 display: flex;
1108 flex-direction: column;
1109 align-items: center;
1110 background-color: #fff;
1111 padding-bottom: 12px;
1112 }
1113 </style>
1 <route lang="yaml">
2 name: damAssessDetail
3 </route>
4
5 <script lang="ts" setup name="damAssessDetail">
6 import { ref } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import {
9 getRecordRuleConfDetail,
10 getExecPlanDetailTableData,
11 getAssessTableRulesData,
12 downloadDirtyData
13 } from '@/api/modules/dataAssetQuality';
14 import { ElMessage } from "element-plus";
15 import { changeNum, download } from '@/utils/common';
16 import tableRuleForm from "./tableRuleForm.vue";
17
18 const { proxy } = getCurrentInstance() as any;
19
20 const router = useRouter();
21 const route = useRoute();
22
23 const planExecGuid = route.query.planExecGuid;
24
25 const tableInfo = ref({
26 id: "quality-table",
27 loading: false,
28 fields: [
29 { label: "表名", field: "qualityModelName", width: 140 },
30 { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
31 { label: "评估时间", field: "execTime", width: 180, },
32 {
33 label: "耗时(秒)", field: "execDuration", width: 100, align: "right", getName: (scope) => {
34 return scope.row.execDuration != null ? changeNum(scope.row.execDuration ?? 0) : '--';
35 }
36 },
37 {
38 label: "规则数", field: "ruleNum", width: 100, align: "right", getName: (scope) => {
39 return scope.row.ruleNum != null ? changeNum(scope.row.ruleNum ?? 0) : '--';
40 }
41 },
42 {
43 label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
44 return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
45 }
46 },
47 {
48 label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
49 return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
50 }
51 },
52 {
53 label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
54 return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
55 }
56 },
57 {
58 label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
59 return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
60 }
61 },
62 { label: "评估范围", field: "dataRange", width: 180 },
63 ],
64 data: [],
65 showPage: false,
66 actionInfo: {
67 label: "操作",
68 type: "btn",
69 width: 200,
70 fixed: 'right',
71 btns: (scope) => {
72 let unqualifiedNum = scope.row.unqualifiedNum ?? 0;
73 return [
74 { label: "查看规则", value: "rule" },
75 { label: "脏数据下载", value: "download", disabled: unqualifiedNum == 0 || scope.row.isTable == 'Y' },
76 ]
77 },
78 }
79 });
80
81 /** 获取方案详情列表数据。 */
82 const getAssessDetail = () => {
83 tableInfo.value.loading = true;
84 getExecPlanDetailTableData({ planExecGuid: planExecGuid }).then((res: any) => {
85 tableInfo.value.loading = false;
86 if (res.code == proxy.$passCode) {
87 tableInfo.value.data = res.data || []
88 } else {
89 ElMessage.error(res.msg);
90 }
91 });
92 }
93
94 /** 获取每个表的规则详情。 */
95 const getModelRulesDetail = (qualityModelGuid: string) => {
96 rulesDetailTableInfo.value.loading = true;
97 getAssessTableRulesData({ planExecGuid: planExecGuid, qualityModelGuid: qualityModelGuid }).then((res: any) => {
98 rulesDetailTableInfo.value.loading = false;
99 if (res.code == proxy.$passCode) {
100 rulesDetailTableInfo.value.data = res.data || [];
101 } else {
102 ElMessage.error(res.msg);
103 }
104 });
105 }
106
107 /** 下载脏数据。 */
108 const exportDirtyData = (row) => {
109 downloadDirtyData({
110 planExecGuid: row.planExecGuid,
111 qualityModelGuid: row.qualityModelGuid
112 }).then((res: any) => {
113 if (res && !res.msg) {
114 download(res, `脏数据-${row.qualityModelName}.xlsx`, 'excel');
115 } else {
116 res?.msg && ElMessage.error(res?.msg);
117 }
118 })
119 }
120
121 const tableBtnClick = (scope, btn) => {
122 const type = btn.value;
123 const row = scope.row;
124 if (type == 'rule') {
125 rulesDetailDialogVisible.value = true;
126 getModelRulesDetail(row.qualityModelGuid);
127 } else if (type == 'download') {
128 exportDirtyData(row);
129 }
130 };
131
132 onBeforeMount(() => {
133 getAssessDetail();
134 });
135
136 /** 单个规则详情对话框 */
137 const oneRulesDetailDialogVisible = ref(false);
138
139 const toSubjectTables: any = ref([]);
140 const ruleType = ref('');
141 const detailInfo: any = ref({});
142 const detailLoading = ref(false);
143 const ruleTypeList: any = ref([]);
144 const smallCategoryList: any = ref([]);
145 const largeCategoryList: any = ref([]);
146 const detailJson: any = ref({});
147
148 /** 查看表规则详情的对话框显示隐藏。 */
149 const rulesDetailDialogVisible = ref(false);
150
151 const rulesDetailTableInfo: any = ref({
152 id: "rules-detail-table",
153 loading: false,
154 fields: [
155 { label: "序号", type: "index", width: 56, align: "center" },
156 { label: "表名", field: "qualityModelName", width: 140 },
157 { label: "规则类型", field: "ruleName", width: 140 },
158 { label: "规则名称", field: "ruleConfName", width: 140 },
159 { label: "规则大类", field: "largeCategory", width: 100 },
160 { label: "规则小类", field: "smallCategory", width: 140 },
161 { label: "规则字段", field: "ruleField", width: 140 },
162 { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
163 // { label: "规则权重", field: "weight", width: 100, align: 'right' },
164 {
165 label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
166 return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
167 }
168 },
169 {
170 label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
171 return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
172 }
173 },
174 {
175 label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
176 return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
177 }
178 },
179 {
180 label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
181 return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
182 }
183 },
184 { label: "失败原因", field: "errorLog", width: 140 },
185 ],
186 data: [],
187 showPage: false,
188 actionInfo: {
189 label: "操作",
190 type: "btn",
191 width: 90,
192 fixed: 'right',
193 btns: [
194 {
195 label: "规则详情 ", value: "ruleDetail", click: (scope) => {
196 let row = scope.row;
197 detailLoading.value = true;
198 if (detailJson.value[row.ruleConfGuid]) {
199 ruleType.value = detailInfo.value.ruleCode;
200 toSubjectTables.value = [{
201 guid: detailInfo.value.subjectGuid,
202 enName: detailInfo.value.subjectName,
203 chName: detailInfo.value.subjectZhName,
204 label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
205 }]
206 ruleTypeList.value = [{
207 value: detailInfo.value.ruleCode,
208 label: row.ruleName
209 }];
210 smallCategoryList.value = [{
211 paramValue: detailInfo.value.smallCategory,
212 paramName: row.smallCategory
213 }];
214 largeCategoryList.value = [{
215 paramValue: detailInfo.value.largeCategory,
216 paramName: row.largeCategory
217 }];
218 oneRulesDetailDialogVisible.value = true;
219 } else {
220 detailJson.value[row.ruleConfGuid] = { isRequest: true };
221 getRecordRuleConfDetail({ ruleConfGuid: row.ruleConfGuid, planExecGuid: planExecGuid }).then((res: any) => {
222 detailLoading.value = false;
223 oneRulesDetailDialogVisible.value = true;
224 if (res.code == proxy.$passCode) {
225 let data = res.data || {};
226 detailInfo.value = data;
227 detailJson.value[row.ruleConfGuid] = detailInfo.value;
228 detailJson.value[row.ruleConfGuid].isRequest = false;
229 ruleType.value = detailInfo.value.ruleCode;
230 toSubjectTables.value = [{
231 guid: detailInfo.value.subjectGuid,
232 tableName: detailInfo.value.subjectName,
233 tableChName: detailInfo.value.subjectZhName,
234 label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
235 }]
236 ruleTypeList.value = [{
237 value: detailInfo.value.ruleCode,
238 label: row.ruleName
239 }];
240 smallCategoryList.value = [{
241 paramValue: detailInfo.value.smallCategory,
242 paramName: row.smallCategory
243 }];
244 largeCategoryList.value = [{
245 paramValue: detailInfo.value.largeCategory,
246 paramName: row.largeCategory
247 }];
248 } else {
249 ElMessage.error(res.msg);
250 delete detailJson.value[row.ruleConfGuid];
251 }
252 })
253 }
254 }
255 },
256 ],
257 }
258 });
259
260 </script>
261
262 <template>
263 <div class="container_wrap">
264 <div class="table_panel_wrap">
265 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
266 </div>
267 <el-dialog v-model="rulesDetailDialogVisible" title="查看规则" width="800" :modal="true" :close-on-click-modal="false"
268 destroy-on-close align-center>
269 <div class="rules-detail-dialog-content">
270 <Table class="long-tooltip-table" :tableInfo="rulesDetailTableInfo" />
271 </div>
272 </el-dialog>
273 <el-dialog v-model="oneRulesDetailDialogVisible" title="规则详情" width="800" :modal="true"
274 :close-on-click-modal="false" destroy-on-close align-center>
275 <tableRuleForm ref="ruleFormRef" :readonly="true" :toSubjectTables="toSubjectTables" :ruleTypeValue="ruleType"
276 :value="detailInfo" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
277 :smallCategoryList="smallCategoryList">
278 </tableRuleForm>
279 </el-dialog>
280 </div>
281 </template>
282
283 <style lang="scss" scoped>
284 .container_wrap {
285 padding: 16px;
286 }
287
288 .table_panel_wrap {
289 height: 100%;
290 }
291
292 .rules-detail-dialog-content {
293 height: 450px;
294 }
295
296 .long-tooltip-table {
297 :deep(.el-table) {
298 .table_cell_tooltip {
299 max-width: 500px;
300 // max-height: 100px;
301 // overflow: auto;
302 }
303 }
304 }
305 </style>
1 <route lang="yaml">
2 name: damObjectionHandle
3 </route>
4
5 <script lang="ts" setup name="damObjectionHandle">
6 import { ref } from 'vue';
7 import TableTools from "@/components/Tools/table_tools.vue";
8 import {
9 getDissentList,
10 updateDissentState
11 } from "@/api/modules/dataAsset";
12 import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
13 import { useValidator } from '@/hooks/useValidator';
14
15 const router = useRouter();
16 const { proxy } = getCurrentInstance() as any;
17 const { required } = useValidator();
18
19 const searchItemList = ref([
20 {
21 type: "input",
22 label: "",
23 field: "damName",
24 default: "",
25 maxlength: 50,
26 placeholder: "资产名称",
27 clearable: true,
28 },
29 {
30 type: "input",
31 label: "",
32 field: "applyCompany",
33 default: "",
34 maxlength: 50,
35 placeholder: "申请单位",
36 clearable: true,
37 },
38 ]);
39
40 const toSearch = (val: any, clear: boolean = false) => {
41 page.value.curr = 1;
42 if (clear) {
43 searchItemList.value.map((item) => (item.default = ""));
44 page.value.damName = '';
45 page.value.applyCompany = "";
46 } else {
47 page.value.damName = val.damName;
48 page.value.applyCompany = val.applyCompany;
49 }
50 getTableData();
51 };
52
53 const getTableData = () => {
54 tableInfo.value.loading = true;
55 getDissentList({
56 pageSize: page.value.limit,
57 pageIndex: page.value.curr,
58 damName: page.value.damName,
59 applyCompany: page.value.applyCompany
60 }).then((res: any) => {
61 tableInfo.value.loading = false
62 if (res.code == proxy.$passCode) {
63 const data = res.data || {}
64 tableInfo.value.data = data.records || [];
65 tableInfo.value.page.curr = data.pageIndex;
66 tableInfo.value.page.rows = data.totalRows || 0;
67 } else {
68 proxy.$ElMessage.error(res.msg);
69 }
70 })
71 }
72
73 const page = ref({
74 ...commonPageConfig,
75 damName: '',
76 applyCompany: ''
77 });
78
79 const tableInfo = ref({
80 id: 'dissent-data-table',
81 rowKey: 'guid',
82 loading: false,
83 fields: [{ label: "序号", type: "index", width: 56, align: "center" },
84 { label: "数据资产名称", field: "damName", width: 160, align: "left" },
85 { label: "公司名称", field: "companyName", width: 240 },
86 { label: "申请时间", field: "applyTime", width: TableColumnWidth.DATETIME, align: "left" },
87 { label: "申请单位", field: "applyCompany", width: 240 },
88 { label: "申请人", field: "applicant", width: TableColumnWidth.USERNAME },
89 { label: "联系方式", field: "contactTel", width: 120 },
90 { label: "申请事由", field: "applyRemark", width: TableColumnWidth.DESCRIPTION },
91 { label: "状态", field: "state", type: "tag", width: 96, align: 'center' },
92 { label: "操作人", field: "lastApprover", width: TableColumnWidth.USERNAME, align: "left" },
93 { label: "操作时间", field: "lastApprovalTime", width: TableColumnWidth.DATETIME, align: "left" },
94 ],
95 data: [],
96 page: {
97 type: "normal",
98 rows: 0,
99 ...page.value,
100 },
101 actionInfo: {
102 label: "操作",
103 type: "btn",
104 width: 100,
105 btns: (scope) => {
106 let row = scope.row;
107 return getTableBtns(row);
108 }
109 }
110 });
111
112 const getTableBtns = (row) => {
113 let btnsArr: any[] = [];
114 if (row.state != 'Y' && row.state != 'R') {//审批中
115 btnsArr.push({
116 label: "通过", value: "pass", click: (scope) => {
117 currTableData.value = scope.row;
118 passDialogInfo.value.visible = true;
119 passFormItems.value[0].readonly = false;
120 passDialogInfo.value.contents[0].formInfo.items = passFormItems.value;
121 passDialogInfo.value.contents[0].formInfo.items[0].default = ''
122 passDialogInfo.value.footer.visible = true;
123 }
124 });
125 btnsArr.push({
126 label: "驳回", value: "backup", click: (scope) => {
127 currTableData.value = scope.row;
128 rejectDialogInfo.value.visible = true;
129 rejectDialogInfo.value.contents[0].formInfo.items[0].readonly = false;
130 rejectDialogInfo.value.contents[0].formInfo.items[0].default = '';
131 rejectDialogInfo.value.footer.visible = true;
132 }
133 });
134 } else {
135 btnsArr.push({
136 label: "查看", value: "detail", click: (scope) => {
137 if (row.state == 'Y') {
138 passDialogInfo.value.visible = true;
139 passFormItems.value[0].readonly = true;
140 passDialogInfo.value.contents[0].formInfo.items = passFormItems.value;
141 passDialogInfo.value.contents[0].formInfo.items[0].default = row.description;
142 passDialogInfo.value.footer.visible = false;
143 } else {
144 rejectDialogInfo.value.visible = true;
145 rejectDialogInfo.value.contents[0].formInfo.items[0].readonly = true;
146 rejectDialogInfo.value.contents[0].formInfo.items[0].default = row.description;
147 rejectDialogInfo.value.footer.visible = false;
148 }
149 }
150 });
151 }
152 return btnsArr;
153 }
154
155 const currTableData: any = ref({});
156
157 const tablePageChange = (info) => {
158 page.value.curr = Number(info.curr);
159 page.value.limit = Number(info.limit);
160 getTableData();
161 };
162
163 const passFormItems = ref([
164 {
165 label: '',
166 type: "textarea",
167 placeholder: "请填写通过描述,至少五个字符",
168 field: "description",
169 clearable: true,
170 block: true,
171 readonly: false,
172 rows: 5,
173 maxlength: 200,
174 default: '',
175 col: 'margin_b_0',
176 }
177 ]);
178
179 const passFormRules = ref({
180 description: [required('请填写通过描述'), {
181 validator: (rule: any, value: any, callback: any) => {
182 if (value?.length < 5) {
183 callback(new Error('请填写至少五个字符的通过描述'))
184 } else {
185 callback();
186 }
187 },
188 trigger: 'blur'
189 }]
190 });
191
192 const passDialogInfo = ref({
193 visible: false,
194 size: 460,
195 direction: "column",
196 header: {
197 title: "通过描述",
198 },
199 type: '',
200 contents: [
201 {
202 type: 'form',
203 title: '',
204 formInfo: {
205 id: 'dissent-pass-dialog',
206 items: passFormItems.value,
207 rules: passFormRules.value
208 }
209 }
210 ],
211 footer: {
212 visible: true,
213 btns: [
214 { type: "default", label: "取消", value: "cancel" },
215 { type: "primary", label: "确定", loading: false, value: "submit" },
216 ],
217 },
218 });
219
220 const passDialogBtnClick = (btn, info) => {
221 if (btn.value == 'submit') {
222 passDialogInfo.value.footer.btns[1].loading = true;
223 updateDissentState({
224 guid: currTableData.value.guid,
225 damName: currTableData.value.damName,
226 description: info.description,
227 contactTel: currTableData.value.contactTel,
228 damGuid: currTableData.value.damGuid,
229 tenantGuid: currTableData.value.tenantGuid,
230 state: 'Y'
231 }).then((res: any) => {
232 passDialogInfo.value.footer.btns[1].loading = false;
233 if (res?.code == proxy.$passCode) {
234 if (res.data) {
235 proxy.$ElMessage.success('该资产异议受理通过成功');
236 passDialogInfo.value.visible = false;
237 getTableData();
238 } else {
239 proxy.$ElMessage.error('该资产异议受理通过失败');
240 }
241 } else {
242 proxy.$ElMessage.error(res.msg);
243 }
244 }).catch(() => {
245 passDialogInfo.value.footer.btns[1].loading = false;
246 })
247 } else if (btn.value == 'cancel') {
248 passDialogInfo.value.visible = false;
249 }
250 };
251
252 const rejectDialogInfo = ref({
253 visible: false,
254 size: 460,
255 direction: "column",
256 header: {
257 title: "驳回描述",
258 },
259 type: '',
260 contents: [
261 {
262 type: 'form',
263 title: '',
264 formInfo: {
265 id: 'batch-reject-form',
266 items: [
267 {
268 label: '',
269 type: "textarea",
270 placeholder: "请填写驳回描述,至少五个字符",
271 field: "description",
272 clearable: true,
273 block: true,
274 rows: 5,
275 maxlength: 200,
276 default: '',
277 readonly: false,
278 col: 'margin_b_0',
279 }
280 ],
281 rules: {
282 description: [required('请填写驳回描述'), {
283 validator: (rule: any, value: any, callback: any) => {
284 if (value?.length < 5) {
285 callback(new Error('请填写至少五个字符的驳回描述'))
286 } else {
287 callback();
288 }
289 },
290 trigger: 'blur'
291 }]
292 }
293 }
294 }
295 ],
296 footer: {
297 visible: true,
298 btns: [
299 { type: "default", label: "取消", value: "cancel" },
300 { type: "primary", label: "确定", loading: false, value: "submit" },
301 ],
302 },
303 });
304
305 const rejectDialogBtnClick = (btn, info) => {
306 if (btn.value == 'submit') {
307 rejectDialogInfo.value.footer.btns[1].loading = true;
308 updateDissentState({
309 guid: currTableData.value.guid,
310 damName: currTableData.value.damName,
311 description: info.description,
312 contactTel: currTableData.value.contactTel,
313 damGuid: currTableData.value.damGuid,
314 tenantGuid: currTableData.value.tenantGuid,
315 state: 'R'
316 }).then((res: any) => {
317 rejectDialogInfo.value.footer.btns[1].loading = false;
318 if (res?.code == proxy.$passCode) {
319 if (res.data) {
320 proxy.$ElMessage.success('该资产异议受理驳回成功');
321 getTableData();
322 rejectDialogInfo.value.visible = false;
323 } else {
324 proxy.$ElMessage.error('该资产异议受理驳回失败');
325 }
326 } else {
327 proxy.$ElMessage.error(res.msg);
328 }
329 }).catch(() => {
330 rejectDialogInfo.value.footer.btns[1].loading = false;
331 });
332 } else if (btn.value == 'cancel') {
333 rejectDialogInfo.value.visible = false;
334 }
335 };
336
337 </script>
338
339 <template>
340 <div class="container_wrap">
341 <div class="table_tool_wrap">
342 <TableTools :searchItems="searchItemList" :searchId="'register-data-search'" @search="toSearch" :init="true" />
343 </div>
344 <div class="table_panel_wrap">
345 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
346 </div>
347 <Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
348 <Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
349 </div>
350 </template>
351
352 <style scoped lang="scss">
353 .container_wrap {
354 padding: 0 16px;
355 }
356
357 .table_panel_wrap {
358 height: calc(100% - 48px);
359 }
360
361 :deep(.el-dialog) {
362 .dialog_panel {
363 padding: 14px 24px;
364 }
365 }
366 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: damQualityAssess
3 </route>
4
5 <script lang="ts" setup name="damQualityAssess">
6 import { ref } from 'vue';
7 import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
8 import {
9 getQualityList,
10 getQualityDamList,
11 deleteQualityPlan,
12 executePlan,
13 downPlanSql
14 } from "@/api/modules/dataAssetQuality";
15 import useDataAssetStore from "@/store/modules/dataAsset";
16 import { download } from '@/utils/common';
17 import useUserStore from "@/store/modules/user";
18
19 const userStore = useUserStore()
20 const userData = JSON.parse(userStore.userData)
21 const assetStore = useDataAssetStore();
22 const { proxy } = getCurrentInstance() as any;
23 const router = useRouter();
24 const damListData = ref([]);
25 const serachFormRef = ref();
26 const searchItemList = ref([
27 {
28 type: 'select',
29 label: '',
30 field: 'damGuid',
31 default: '',
32 placeholder: '数据资产名称',
33 options: damListData.value,
34 props: {
35 value: 'guid',
36 label: 'damName'
37 },
38 filterable: true,
39 clearable: true,
40 required: true,
41 visible: true
42 }
43 ])
44
45 /** 分页及搜索传参信息配置。 */
46 const page = ref({
47 ...commonPageConfig,
48 damGuid: ''
49 });
50
51 /** 方案表格配置信息。 */
52 const tableInfo = ref({
53 id: 'quality-table',
54 // multiple: true,
55 loading: false,
56 nodeKey: 'guid',
57 fields: [
58 { label: "序号", type: "index", width: TableColumnWidth.INDEX, fixed: "left", align: "center" },
59 {
60 label: "数据资产名称", field: "damName", width: 160, fixed: "left", type: "text_btn", value: "damDetail", columClass: 'text_btn', click: (scope) => {
61 router.push({
62 name: "registerCatalogDetail",
63 query: { guid: scope.row.damGuid },
64 });
65 }
66 },
67 { label: "所属企业", field: "tenantName", width: 240 },
68 { label: "质量评分", field: "qualityScore", width: 120, align: 'right' },
69 { label: "执行状态", field: "execState", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
70 { label: "执行时间", field: "lastExecTime", width: TableColumnWidth.DATETIME, },
71 { label: "创建人", field: "createUserName", width: TableColumnWidth.USERNAME },
72 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
73 { label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME, },
74 ],
75 data: [],
76 page: {
77 type: "normal",
78 rows: 0,
79 ...page.value,
80 },
81 actionInfo: {
82 label: "操作",
83 type: "btn",
84 isMore: true,
85 width: 271,
86 btns: (scope) => {
87 const row = scope.row
88 let btnsArr: any = [{
89 label: "查看报告", value: "reportView", disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
90 router.push({
91 name: 'damAnalysisReport',
92 query: {
93 planGuid: row.guid,
94 name: row.damName,
95 reportExecGuid: row.reportExecGuid
96 }
97 });
98 }
99 }, {
100 label: "查看结果", value: "resultView", disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
101 router.push({
102 name: 'damAssessDetail',
103 query: {
104 name: row.damName,
105 planExecGuid: row.planExecGuid
106 }
107 });
108 }
109 }, {
110 label: "编辑", value: "edit", disabled: row.execState == 1 || row.isExecute, click: (scope) => {
111 router.push({
112 name: 'damQualityPlan',
113 query: {
114 guid: row.guid,
115 damName: row.damName
116 }
117 });
118 }
119 }];
120 if (row.isExecute) {
121 btnsArr.push({ label: "执行中", value: "execute", disabled: true });
122 } else {
123 btnsArr.push({
124 label: "执行", value: "execute", disabled: row.execState == 1 || row.state == 0, click: (scope) => {
125 row.isExecute = true
126 executePlan({ planGuid: row.guid, reportGuid: row.reportGuid }).then((res: any) => {
127 if (res.code == proxy.$passCode) {
128 getTableData();
129 proxy.$ElMessage.success('执行完成');
130 } else {
131 proxy.$ElMessage.error(res.msg);
132 }
133 row.isExecute = false
134 }).catch(() => {
135 row.isExecute = false
136 })
137 }
138 });
139 }
140 btnsArr.push({
141 label: "日志", value: "path_log", disabled: row.execState == 0, click: (scope) => {
142 router.push({
143 name: 'damQualityAssessLog',
144 query: {
145 guid: row.damGuid,
146 name: row.damName,
147 reportGuid: row.reportGuid
148 }
149 });
150 }
151 });
152 btnsArr.push({
153 label: "删除", value: "delete", disabled: row.execState == 1 || row.isExecute, click: (scope) => {
154 if (scope.row.createUserId && userData.userGuid !== scope.row.createUserId) {
155 proxy.$ElMessage.error('只有创建人才可以删除该资产质量评估');
156 return;
157 }
158 proxy.$openMessageBox("确定要删除该资产质量评估吗?", () => {
159 deleteQualityPlan([scope.row.guid]).then((res: any) => {
160 if (res.code == proxy.$passCode) {
161 page.value.curr = 1;
162 /** 将当前查询到的删除了,清除。 */
163 if (page.value.damGuid == row.damGuid) {
164 page.value.damGuid = '';
165 serachFormRef.value?.toolSearch?.formRef?.resetFields?.();
166 getTableData();
167 } else {
168 getTableData();
169 }
170 proxy.$ElMessage.success('删除该资产质量评估成功');
171 } else {
172 proxy.$ElMessage.error(res.msg);
173 }
174 });
175 }, () => {
176 proxy.$ElMessage.info("已取消删除");
177 })
178 }
179 });
180 btnsArr.push({
181 label: 'SQL下载', value: 'sqldown', disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
182 downPlanSql(scope.row.guid).then((res: any) => {
183 if (res && !res.msg) {
184 download(res, `SQL-${scope.row.damName}.zip`, 'zip');
185 } else {
186 res?.msg && proxy.$ElMessage.error(res?.msg);
187 }
188 });
189 }
190 });
191 return btnsArr
192 }
193 }
194 });
195
196 const toSearch = (val: any, clear: boolean = false) => {
197 page.value.curr = 1;
198 if (clear) {
199 searchItemList.value.map(item => item.default = '')
200 page.value.damGuid = '';
201 getTableData(false);
202 return;
203 }
204 page.value.damGuid = val.damGuid;
205 getTableData(false);
206 };
207
208 /**
209 * 调用接口刷新获取方案表格数据
210 * @param refreshData 如果是刷新数据,需要更新查询列表。
211 */
212 const getTableData = (refreshData = true) => {
213 tableInfo.value.loading = true;
214 getQualityList({
215 pageIndex: page.value.curr, pageSize: page.value.limit,
216 damGuid: page.value.damGuid
217 }).then((res: any) => {
218 tableInfo.value.loading = false;
219 if (res === undefined) {
220 return;
221 }
222 if (res.code == proxy.$passCode) {
223 const data = res.data || {}
224 tableInfo.value.data = data.records || []
225 tableInfo.value.page.limit = data.pageSize
226 tableInfo.value.page.curr = data.pageIndex
227 tableInfo.value.page.rows = data.totalRows
228 } else {
229 proxy.$ElMessage.error(res.msg);
230 }
231 })
232 if (refreshData) {
233 getSearchQualityDamList();
234 }
235 };
236
237 /** 监听处理分页事件。 */
238 const tablePageChange = (info) => {
239 page.value.curr = Number(info.curr);
240 page.value.limit = Number(info.limit);
241 getTableData(false);
242 };
243
244 const handleCreate = () => {
245 router.push({
246 name: 'damQualityPlan'
247 });
248 }
249
250 const getSearchQualityDamList = () => {
251 getQualityDamList().then((res: any) => {
252 if (res.code == proxy.$passCode) {
253 const data = res.data || [];
254 searchItemList.value[0].options = data;
255 } else {
256 proxy.$ElMessage.error(res.msg);
257 }
258 });
259 }
260
261 onBeforeMount(() => {
262 if (!assetStore.qualityAssessRefresh) {
263 getSearchQualityDamList();
264 }
265 });
266
267 onActivated(() => {
268 if (assetStore.qualityAssessRefresh) {
269 page.value.curr = 1;
270 getTableData();
271 assetStore.setQualityAssessRefresh(false);
272 }
273 })
274
275 </script>
276
277 <template>
278 <div class="container_wrap">
279 <div class="table_tool_wrap has_search">
280 <Table_tools ref="serachFormRef" :searchItems="searchItemList" searchId="quality-search" @search="toSearch" />
281 <div class="tools_btns">
282 <el-button type="primary" @click="handleCreate">新建</el-button>
283 </div>
284 </div>
285 <div class="table_panel_wrap">
286 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
287 </div>
288 </div>
289 </template>
290
291 <style lang="scss" scoped>
292 .table_tool_wrap {
293 width: 100%;
294 height: 84px !important;
295 padding: 0 8px;
296
297 :deep(.table-tools) {
298 .el-select {
299 width: 230px;
300 }
301 }
302
303 .tools_btns {
304 padding: 8px 0 0;
305 }
306 }
307
308 .table_panel_wrap {
309 width: 100%;
310 height: calc(100% - 84px);
311 padding: 8px 8px 0;
312 }
313 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: damQualityAssessLog
3 </route>
4
5 <script lang="ts" setup name="damQualityAssessLog">
6 import { ref } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import {
9 getAssessDetailTableData,
10 } from '@/api/modules/dataAssetQuality';
11 import { ElMessage } from "element-plus";
12 import { changeNum } from '@/utils/common';
13 import { TableColumnWidth } from "@/utils/enum"
14 const { proxy } = getCurrentInstance() as any;
15
16 const router = useRouter();
17 const route = useRoute();
18 /** 方案guid */
19 const planGuid = route.query.guid;
20 const reportGuid = route.query.reportGuid;
21 const planName = route.query.name;
22 const execType = route.query.type;
23 const page = ref({
24 limit: 50,
25 curr: 1,
26 sizes: [
27 { label: "10", value: 10 },
28 { label: "50", value: 50 },
29 { label: "100", value: 100 },
30 { label: "150", value: 150 },
31 { label: "200", value: 200 },
32 ],
33 });
34 const tableInfo = ref({
35 id: "user-authority-table",
36 fields: [
37 { type: "index", width: TableColumnWidth.INDEX, align: "center", label: "序号" },
38 { label: "数据资产名称", field: "damName", width: 160 },
39 { label: "所属企业", field: "tenantName", width: 240 },
40 { label: "质量评分", field: "qualityScore", width: 120, align: 'right' },
41 { label: "执行状态", field: "execResult", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
42 { label: "执行时间", field: "lastExecTime", width: TableColumnWidth.DATETIME, },
43 { label: "执行人", field: "updateUserName", width: TableColumnWidth.USERNAME },
44 ],
45 loading: false,
46 data: [],
47 page: {
48 type: "normal",
49 rows: 0,
50 ...page.value,
51 },
52 actionInfo: {
53 label: "操作",
54 type: "btn",
55 width: 160,
56 fixed: 'right',
57 btns: (scope) => {
58 return [
59 { label: "查看报告", disabled: scope.row.execResult != 'Y', value: "reportView", click: (scope) => {
60 let row = scope.row;
61 router.push({
62 name: 'damAnalysisReport',
63 query: {
64 planGuid: row.planGuid,
65 name: row.damName,
66 reportExecGuid: row.reportExecGuid
67 }
68 });
69 } },
70 {
71 label: "查看结果", value: "resultView", click: (scope) => {
72 let row = scope.row;
73 router.push({
74 name: 'damAssessDetail',
75 query: {
76 name: row.damName,
77 planExecGuid: row.planExecGuid
78 }
79 });
80 }
81 },
82 ]
83 }
84 }
85 });
86
87 const formTable = ref({
88 type: "table",
89 title: "",
90 col: 'no-margin',
91 tableInfo: {
92 id: "log-detail-table",
93 loading: false,
94 fields: [
95 { label: "执行时间", field: "changeTime", width: 140, },
96 { label: "日志类型", field: "metaCurrValue", width: 120 },
97 { label: "日志级别", field: "collectTaskName", width: 110 },
98 { label: "执行步骤", field: "updateType", width: 240 },
99 ],
100 data: [],
101 showPage: false,
102 actionInfo: {
103 show: false
104 },
105 },
106 })
107
108 const drawerInfo: any = ref({
109 visible: false,
110 direction: "rtl",
111 modalClass: "wrap_width_auto",
112 size: 650,
113 header: {
114 title: "日志详情",
115 },
116 type: '',
117 container: {
118 contents: [
119 formTable.value,
120 ],
121 },
122 footer: {
123 visible: false,
124 },
125 })
126
127 const tablePageChange = (info) => {
128 page.value.curr = Number(info.curr);
129 page.value.limit = Number(info.limit);
130 getTableData();
131 };
132
133 const getTableData = () => {
134 tableInfo.value.loading = true;
135 getAssessDetailTableData({ pageSize: page.value.limit, pageIndex: page.value.curr, damGuid: planGuid, reportGuid: reportGuid }).then((res: any) => {
136 tableInfo.value.loading = false;
137 if (res.code == proxy.$passCode) {
138 const data = res.data || {}
139 tableInfo.value.data = data.records || []
140 tableInfo.value.page.limit = data.pageSize ?? 50;
141 tableInfo.value.page.curr = data.pageIndex
142 tableInfo.value.page.rows = data.totalRows ?? 0;
143 } else {
144 ElMessage.error(res.msg);
145 }
146 });
147 };
148
149 const tableBtnClick = (scope, btn) => {
150 const type = btn.value;
151 const row = scope.row;
152 if (type == 'resultView') {
153 if (!!execType) {
154 router.push({
155 name: 'syncAssessDetail',
156 query: {
157 name: planName,
158 planGuid: row.planGuid,
159 planExecGuid: row.planExecGuid
160 }
161 });
162 } else {
163 router.push({
164 name: 'assessDetail',
165 query: {
166 name: planName,
167 planGuid: row.planGuid,
168 planExecGuid: row.planExecGuid
169 }
170 });
171 }
172
173 } else if (type == 'log') {
174 const params = {
175 logGuid: row.guid
176 }
177 drawerInfo.value.visible = true
178 // formTable.value.tableInfo.loading = true;
179 // getLogDetail(params).then((res: any) => {
180 // formTable.value.tableInfo.loading = false;
181 // if (res.code == proxy.$passCode && res.data) {
182 // const data = res.data
183 // formTable.value.tableInfo.data = data
184 // drawerInfo.value.container.contents[0].listInfo.data = data
185 // drawerInfo.value.visible = true
186 // } else {
187 // ElMessage({
188 // type: "info",
189 // message: res.msg,
190 // });
191 // }
192 // })
193 }
194 };
195
196 const drawerBtnClick = (btn) => {
197 drawerInfo.value.visible = false;
198 };
199
200 onBeforeMount(() => {
201 getTableData();
202 });
203
204 </script>
205
206 <template>
207 <div class="container_wrap">
208 <div class="table_panel_wrap">
209 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
210 </div>
211
212 <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" />
213 </div>
214 </template>
215
216 <style lang="scss" scoped>
217 .container_wrap {
218 padding: 0;
219
220 .table_panel_wrap {
221 height: 100%;
222 padding: 16px 16px 0;
223 }
224 }
225
226 :deep(.el-drawer) {
227 .drawer_panel {
228 height: 100%;
229
230 .table_panel_wrap {
231 height: 100%;
232 }
233 }
234 }
235 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: damQualityPlan
3 </route>
4
5 <script lang="ts" setup name="damQualityPlan">
6 import { onBeforeMount, ref } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import useUserStore from "@/store/modules/user";
9 import { useValidator } from '@/hooks/useValidator';
10 import { CirclePlus } from '@element-plus/icons-vue';
11 import {
12 getDamList,
13 getDamTableRulesList,
14 saveDamTableRules,
15 getDamTableList,
16 getRuleTypeList,
17 getSmallCategoryList,
18 getLargeCategoryList,
19 getRuleConfDetail,
20 updateDamTableRule,
21 deleteDamTableRule,
22 getModelRuleCount,
23 saveQualityPlan,
24 updateQualityPlan,
25 getPlanDetail,
26 getPlanFilterDetail
27 } from "@/api/modules/dataAssetQuality";
28 import tableRules from './tableRules.vue';
29 import tableRuleForm from './tableRuleForm.vue';
30 import { TableColumnWidth } from '@/utils/enum';
31 import { changeNum } from '@/utils/common';
32 import filtersSettingBatch from "./filtersSettingBatch.vue";
33 import useDataAssetStore from "@/store/modules/dataAsset";
34
35 const userStore = useUserStore();
36 const assetStore = useDataAssetStore();
37 const { proxy } = getCurrentInstance() as any;
38 const { required } = useValidator();
39 const router = useRouter();
40 const route = useRoute();
41 const fullPath = route.fullPath;
42 /** 编辑时会有guid */
43 const planGuid = route.query.guid;
44 const fullscreenLoading = ref(false);
45 /** 记录编辑时,规则是否被新增,编辑,删除过。 */
46 const editedTableRule = ref(false);
47
48 const step = ref(0);
49 const stepsInfo = ref({
50 step: step.value,
51 list: [
52 { title: '配置数据质量规则', value: 1 },
53 { title: '设置质量规则权重', value: 2 },
54 { title: '执行配置的质量规则', value: 3 }
55 ]
56 })
57
58 const damListData: any = ref([]);
59
60 const damGuid: any = ref('');
61
62 /** 规则中显示的表 */
63 const toSubjectTables: any = ref([]);
64
65 /** 资产目录表的原始值 */
66 const damSubjectTables: any = ref([]);
67
68 const ruleType: any = ref('');
69 const detailRuleInfo: any = ref({});
70 const tableRuleFormRef = ref();
71 const drawerInfoLoading = ref(false);
72 const damInfoFormRef = ref();
73 const damFormItems = ref([{
74 label: '资产名称',
75 type: 'select',
76 placeholder: '请选择',
77 field: 'damGuid',
78 default: damGuid.value,
79 options: damListData.value,
80 props: {
81 value: 'guid',
82 label: 'damName'
83 },
84 filterable: true,
85 clearable: true,
86 required: true,
87 visible: true,
88 disabled: false
89 }]);
90
91 const damFormRules = ref({
92 damGuid: [required('请选择资产名称')]
93 });
94
95 const modelRuleDetailTableInfo = ref({
96 id: "model-rule-table",
97 loading: false,
98 height: '300px',
99 fields: [
100 { label: "序号", type: "index", width: 56, align: "center" },
101 { label: "表名称", field: "name", width: 140 },
102 { label: "规则名称", field: "ruleConfName", width: 140 },
103 { label: "规则大类", field: "largeCategoryName", width: 100 },
104 { label: "规则小类", field: "smallCategoryName", width: 140 },
105 { label: "规则类型", field: "ruleName", width: 140 },
106 { label: "规则字段", field: "ruleField", width: 140 }
107 ],
108 data: [],
109 showPage: false,
110 actionInfo: {
111 label: "操作",
112 type: "btn",
113 width: 110,
114 btns: [{
115 label: "编辑", value: "edit", click: (scope) => {
116 drawerInfo.value.type = 'edit';
117 drawerInfo.value.header.title = '编辑规则';
118 drawerInfo.value.visible = true;
119 drawerInfoLoading.value = true;
120 getRuleConfDetail(scope.row.guid).then((res: any) => {
121 drawerInfoLoading.value = false;
122 if (res.code == proxy.$passCode) {
123 let data = res.data || {};
124 detailRuleInfo.value = data;
125 ruleType.value = detailRuleInfo.value.ruleCode;
126 toSubjectTables.value = [{
127 guid: detailRuleInfo.value.subjectGuid, //编辑的时候显示的是主题表
128 tableName: detailRuleInfo.value.subjectName,
129 tableChName: detailRuleInfo.value.subjectZhName,
130 label: `${detailRuleInfo.value.subjectName}(${detailRuleInfo.value.subjectZhName})`
131 }]
132 detailRuleInfo.value.qualityModelGuids = [detailRuleInfo.value.subjectGuid];
133 } else {
134 proxy.$ElMessage.error(res.msg);
135 }
136 });
137 }
138 }, {
139 label: "删除", value: "delete", click: (scope) => {
140 proxy.$openMessageBox("确定要删除该资产表规则吗?", () => {
141 deleteDamTableRule(scope.row.guid, planGuid).then((res: any) => {
142 if (res.code == proxy.$passCode) {
143 planGuid && (editedTableRule.value = true);
144 getDamTableRulesData(damGuid.value);
145 proxy.$ElMessage.success('删除该资产表规则成功');
146 } else {
147 proxy.$ElMessage.error(res.msg);
148 }
149 });
150 }, () => {
151 proxy.$ElMessage.info("已取消删除");
152 })
153 }
154 }]
155 }
156 });
157
158 const drawerInfo = ref({
159 visible: false,
160 direction: 'rtl',
161 size: 600,
162 header: {
163 title: '新增规则',
164 },
165 type: '',
166 footer: {
167 btns: [
168 { type: 'default', label: '取消', value: 'cancel' },
169 { type: 'primary', label: '确定', value: 'save' },
170 ]
171 }
172 })
173
174 const ruleTypeList = ref([]);
175 const smallCategoryList = ref([]);
176 const largeCategoryList = ref([]);
177
178 onBeforeMount(() => {
179 if (!planGuid) {
180 getDamList().then((res: any) => {
181 if (res.code == proxy.$passCode) {
182 const data = res.data || [];
183 damListData.value = data;
184 damFormItems.value[0].options = damListData.value;
185 } else {
186 proxy.$ElMessage.error(res.msg);
187 }
188 });
189 } else {
190 fullscreenLoading.value = true;
191 getPlanDetail(planGuid).then((res: any) => {
192 fullscreenLoading.value = false;
193 if (res.code == proxy.$passCode) {
194 const data = res.data || {};
195 damGuid.value = data.damGuid;
196 damFormItems.value[0].default = data.damGuid;
197 damFormItems.value[0].disabled = true;
198 damFormItems.value[0].options = damFormItemsReadOnly.value[0].options = configFormItems.value[0].options = [{
199 guid: damGuid.value,
200 damName: data.damName
201 }]
202 getDamTableRulesData(damGuid.value);
203 getDamTableList(damGuid.value).then((res1: any) => {
204 if (res1.code == proxy.$passCode) {
205 toSubjectTables.value = res1.data || [];
206 damSubjectTables.value = res1.data || [];
207 getPlanFilterDetail(planGuid).then((res1: any) => {
208 fullscreenLoading.value = false;
209 if (res1.code == proxy.$passCode) {
210 let data1 = res1.data || [];
211 data1.forEach(d => {
212 let tables: any = [];
213 for (const id in d.qualityModelInfo) {
214 let table = damSubjectTables.value?.find(m => m.guid == id)
215 tables.push({
216 guid: id,
217 subjectGuid: table?.guid,
218 tableChName: table?.tableChName
219 });
220 }
221 batchFiltersValue.value[d.dataFilterGroup] = {
222 filter: d.dataRange,
223 tables: tables,
224 checked: true
225 }
226 });
227 } else {
228 proxy.$ElMessage.error(res1.msg);
229 }
230 });
231 } else {
232 proxy.$ElMessage.error(res1.msg);
233 }
234 });
235 ruleWeightData.value = data.modelRuleWeights?.map(r => {
236 r.ruleLargeWeight = r.ruleLargeWeight.toFixed(2);
237 return r;
238 }) || [];
239 configFormItems.value.forEach(item => {
240 item.default = data[item.field];
241 });
242 } else {
243 proxy.$ElMessage.error(res.msg);
244 }
245 });
246 }
247 getRuleTypeList().then((res: any) => {
248 if (res.code == proxy.$passCode) {
249 ruleTypeList.value = res.data?.map((d: any) => {
250 d.label = d.ruleName;
251 d.value = d.ruleCode;
252 return d;
253 })?.filter(t => t.value != 'rows_check' && t.value != 'volatility_check') || [];
254 } else {
255 proxy.$ElMessage.error(res.msg);
256 }
257 })
258 getSmallCategoryList().then((res: any) => {
259 if (res.code == proxy.$passCode) {
260 smallCategoryList.value = res.data || [];
261 } else {
262 proxy.$ElMessage.error(res.msg);
263 }
264 })
265 getLargeCategoryList().then((res: any) => {
266 if (res.code == proxy.$passCode) {
267 largeCategoryList.value = res.data || [];
268 } else {
269 proxy.$ElMessage.error(res.msg);
270 }
271 })
272 });
273
274 const handleDamInfoSelectChange = (val) => {
275 damGuid.value = val;
276 if (!val) {
277 modelRuleDetailTableInfo.value.data = [];
278 damGuid.value = '';
279 toSubjectTables.value = [];
280 damSubjectTables.value = [];
281 } else {
282 getDamTableRulesData(val);
283 getDamTableList(val).then((res: any) => {
284 if (res.code == proxy.$passCode) {
285 toSubjectTables.value = res.data || [];
286 damSubjectTables.value = res.data || [];
287 } else {
288 proxy.$ElMessage.error(res.msg);
289 }
290 });
291 }
292 }
293
294 /** 根据资产获取规则列表 */
295 const getDamTableRulesData = (damGuid) => {
296 modelRuleDetailTableInfo.value.loading = true;
297 getDamTableRulesList({
298 damGuid: damGuid,
299 }).then((res: any) => {
300 modelRuleDetailTableInfo.value.loading = false;
301 if (res.code == proxy.$passCode) {
302 modelRuleDetailTableInfo.value.data = res.data || [];
303 } else {
304 proxy.$ElMessage.error(res.msg);
305 }
306 });
307 }
308
309 /** 添加资产表规则 */
310 const addTableRules = () => {
311 drawerInfo.value.type = 'add';
312 tableRulesRef.value && tableRulesRef.value.initValue();
313 drawerInfo.value.visible = true;
314 drawerInfo.value.header.title = '新增规则';
315 toSubjectTables.value = damSubjectTables.value;
316 }
317 const tableRulesRef = ref();
318
319 const submitRulesLoading = ref(false);
320
321 /** 提交编辑修改的资产表规则 */
322 const addSubmitRules = () => {
323 if (drawerInfo.value.type == 'add') {
324 tableRulesRef.value && tableRulesRef.value.saveRules().then((info: any) => {
325 submitRulesLoading.value = true;
326 if (planGuid) {
327 info.forEach(rule => rule.planGuid = planGuid);
328 }
329 saveDamTableRules(info).then((res: any) => {
330 submitRulesLoading.value = false;
331 if (res.code == proxy.$passCode) {
332 planGuid && (editedTableRule.value = true);
333 proxy.$ElMessage.success('新增规则成功');
334 drawerInfo.value.visible = false;
335 tableRulesRef.value && tableRulesRef.value.clearValue();
336 getDamTableRulesData(damGuid.value);
337 } else {
338 proxy.$ElMessage.error(res.msg);
339 }
340 })
341 })
342 } else {
343 let ruleGuid = detailRuleInfo.value.guid;
344 /** 将新建规则之后转化为对应质检表的规则。 */
345 const transformRulesInfo = (info: any) => {
346 if (info.ruleCode == 'null_value_check' || info.ruleCode == 'repeate_data_check') {
347 return Object.assign({}, info, {
348 guid: ruleGuid,
349 qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
350 ruleCode: detailRuleInfo.value.ruleCode,
351 ruleField: info.modelFields[detailRuleInfo.value.subjectZhName] || []
352 });
353 } else if (info.ruleCode === 'logic_check') {
354 let subjectName = detailRuleInfo.value.subjectName;
355 let fields = info.ruleFields[subjectName];
356 return Object.assign({}, info, {
357 guid: ruleGuid,
358 qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
359 ruleCode: detailRuleInfo.value.ruleCode,
360 ruleField: [{
361 guid: fields.guid,
362 enName: fields.enName,
363 chName: fields.chName
364 }],
365 conditionSql: info.conditionSqls?.[subjectName],
366 conditionSqls: '',
367 ruleFields: ''
368 });
369 } else if (info.ruleCode === 'custom_sql') {
370 return Object.assign({}, info, {
371 guid: ruleGuid,
372 qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
373 ruleCode: detailRuleInfo.value.ruleCode,
374 customSql: info.customSqls?.[detailRuleInfo.value.subjectName],
375 ruleField: info.ruleFields?.[detailRuleInfo.value.subjectName]?.map(f => {
376 return {
377 enName: f
378 }
379 }) || [],
380 fieldSelects: info.sqlFieldsList?.[detailRuleInfo.value.subjectName] || [],
381 customSqls: '',
382 ruleFields: ''
383 });
384 }
385 }
386 tableRuleFormRef.value?.ruleFormRef?.ruleFormRef?.validate((valid) => {
387 if (valid) {
388 let v = tableRuleFormRef.value?.getFormInfo();
389 let params = transformRulesInfo(v);
390 submitRulesLoading.value = true;
391 planGuid && (params.planGuid = planGuid);
392 updateDamTableRule(params).then((res: any) => {
393 submitRulesLoading.value = false;
394 if (res.code == proxy.$passCode) {
395 planGuid && (editedTableRule.value = true);
396 proxy.$ElMessage.success(`【${params.ruleConfName}】` + '规则编辑成功');
397 drawerInfo.value.visible = false;
398 tableRulesRef.value && tableRulesRef.value.clearValue();
399 getDamTableRulesData(damGuid.value);
400 } else {
401 proxy.$ElMessage.error(res.msg);
402 }
403 })
404 }
405 });
406 }
407 }
408
409 /** 取消修改资产表的规则 */
410 const cancelEditRules = () => {
411 proxy.$openMessageBox("当前修改内容尚未保存,确定取消吗?", () => {
412 drawerInfo.value.visible = false
413 tableRulesRef.value && tableRulesRef.value.clearValue();
414 }, () => {
415 proxy.$ElMessage.info("已取消");
416 });
417 }
418
419 const previousStep = (val) => {
420 step.value = val - 1;
421 stepsInfo.value.step = val - 1;
422 }
423
424 const nextStep = (val) => {
425 if (val == 1) {
426 damInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
427 if (valid) {
428 if (!modelRuleDetailTableInfo.value.data.length) {
429 proxy.$ElMessage.error('请配置当前资产的质量规则');
430 return;
431 }
432 ruleModelTableInfo.value.data = modelRuleDetailTableInfo.value.data || [];
433 if (!planGuid) {
434 getModelRuleCountListData();
435 } else { //编辑页面,直接读取后端的值即可。
436 if (editedTableRule.value) {
437 getModelRuleCountListData(true);
438 }
439 }
440 damFormItemsReadOnly.value[0].default = damGuid.value;
441 damFormItemsReadOnly.value[0].options = damListData.value;
442 step.value = val;
443 stepsInfo.value.step = val;
444 } else {
445 var obj = Object.keys(errorItem);
446 damInfoFormRef.value.ruleFormRef.scrollToField(obj[0])
447 }
448 });
449 } else if (val == 2) {
450 let sum = 0;
451 ruleWeightData.value.forEach(item => {
452 if (item.ruleLargeWeight != null) {
453 sum += parseFloat(item.ruleLargeWeight);
454 }
455 });
456 sum = changeNum(sum, 2);
457 if (!(sum <= 100.02 && sum >= 99.98)) {// 允许浮动0.01误差
458 proxy.$ElMessage.error('规则权重总分应为100分');
459 return;
460 }
461 configFormItems.value[0].default = damGuid.value;
462 configFormItems.value[0].options = damListData.value;
463 step.value = val;
464 stepsInfo.value.step = val;
465 }
466 }
467
468 /** -------------------- 第二步,权重规则设置 ----------------------------- */
469 const damFormItemsReadOnly = ref([{
470 label: '资产名称',
471 type: 'select',
472 placeholder: '请选择',
473 field: 'damGuid',
474 default: damGuid.value,
475 options: damListData.value,
476 props: {
477 value: 'guid',
478 label: 'damName'
479 },
480 disabled: true,
481 filterable: true,
482 clearable: true,
483 required: true,
484 visible: true
485 }]);
486
487 const ruleModelTableInfo = ref({
488 id: 'rule-model-table',
489 loading: false,
490 height: '200px',
491 fields: [
492 { label: "序号", type: "index", width: 56, align: "center" },
493 { label: "表名称", field: "name", width: 140 },
494 { label: "规则名称", field: "ruleConfName", width: 140 },
495 { label: "规则大类", field: "largeCategoryName", width: 100 },
496 { label: "规则小类", field: "smallCategoryName", width: 140 },
497 { label: "规则类型", field: "ruleName", width: 140 },
498 { label: "规则字段", field: "ruleField", width: 140 }
499 ],
500 data: [],
501 showPage: false,
502 actionInfo: {
503 show: false
504 }
505 })
506
507 /** 选择的所有质检表对应的规则大类数量及权重占比。 */
508 const ruleWeightData: any = ref([]);
509 const ruleWeightDataLoading = ref(false);
510
511 const inputWeightChange = (val, row) => {
512 let strArr = val.split(".");
513 if (strArr.length > 1) {
514 let right = strArr[1];
515 if (right === "" || right.length < 2) {
516 row.ruleLargeWeight = val = parseFloat(val || 0).toFixed(2);
517 }
518 } else {
519 row.ruleLargeWeight = val = parseFloat(val || 0).toFixed(2);
520 }
521 };
522
523 /** 输入框输入触发事件 */
524 const inputEventWeightChange = (val, row) => {
525 row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/[^\d.]/g, "")
526 row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/\.{2,}/g, ".")
527 row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/^\D*(\d{0,3}(?:\.\d{0,2})?).*$/g, "$1")
528 if (row.ruleLargeWeight > 100) {
529 row.ruleLargeWeight = changeNum(100, 2, true);
530 }
531 }
532
533 /** 记录分组json的过滤条件。最后提交时需要转化到table里。 */
534 const batchFiltersValue: any = ref({});
535
536 const batchFiltersValueChange = (value) => {
537 batchFiltersValue.value = value;
538 }
539
540 const batchFilterDialogRef = ref();
541
542 /** 批量配置过滤条件 */
543 const handleFiltersAdd = () => {
544 batchFilterDialogRef.value?.openDialog(batchFiltersValue.value);
545 }
546
547 /** 根据所选择的模型表,获取对应的权重信息。 */
548 const getModelRuleCountListData = (isEdit = false) => {
549 ruleWeightDataLoading.value = true;
550 return getModelRuleCount({ damGuid: damGuid.value }).then((res: any) => {
551 ruleWeightDataLoading.value = false;
552 if (res.code == proxy.$passCode) {
553 if (isEdit) {
554 ruleWeightData.value = res.data?.map(r => {
555 r.ruleLargeWeight = r.ruleLargeWeight.toFixed(2);
556 return r;
557 }) || [];
558 editedTableRule.value = false;
559 return;
560 }
561 //新建时,可能是上一步,再下一步返回的。
562 let largeCategoryList: string[] = [];
563 if (ruleWeightData.value.length) {
564 largeCategoryList = ruleWeightData.value.map(d => d.largeCategory);
565 }
566 let data = res.data || [];
567 if (largeCategoryList.length != data.length) {
568 ruleWeightData.value = data;
569 if (ruleWeightData.value.length) {
570 let v = changeNum(100 / ruleWeightData.value.length, 2, true);
571 ruleWeightData.value.forEach(d => d.ruleLargeWeight = v);
572 }
573 } else {
574 if (data.some(d => !largeCategoryList.includes(d.largeCategory))) {
575 ruleWeightData.value = data;
576 if (ruleWeightData.value.length) {
577 let v = changeNum(100 / ruleWeightData.value.length, 2, true);
578 ruleWeightData.value.forEach(d => d.ruleLargeWeight = v);
579 }
580 } else {
581 // 不处理。使用原始值。
582 }
583 }
584 } else {
585 proxy.$ElMessage.error(res.msg);
586 }
587 });
588 }
589
590 /** ----------------------- 第三步 -------------------------------- */
591 const configInfoFormRef = ref();
592 const configFormItems = ref([
593 {
594 label: '资产名称',
595 type: 'select',
596 placeholder: '请选择',
597 field: 'damGuid',
598 default: damGuid.value,
599 options: damListData.value,
600 props: {
601 value: 'guid',
602 label: 'damName'
603 },
604 disabled: true,
605 filterable: true,
606 clearable: true,
607 required: true,
608 visible: true
609 },
610 {
611 label: '报告保留期数(期)',
612 type: 'input',
613 inputType: 'integerNumber',
614 placeholder: '请输入正整数,不超过20',
615 field: 'reportReserveCycle',
616 default: 7,
617 max: 20,
618 min: 1,
619 clearable: true,
620 required: false,
621 visible: true
622 },
623 {
624 label: "立即执行",
625 type: "radio-group",
626 placeholder: "",
627 field: "isExec",
628 default: 'Y',
629 options: [
630 {
631 label: "是",
632 value: "Y",
633 },
634 {
635 label: "否",
636 value: 'N',
637 },
638 ],
639 required: true,
640 },
641 ]);
642
643 const configFormRules = ref({
644 reportReserveCycle: [required('请填写报告保留期数')]
645 });
646
647 const save = () => {
648 configInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
649 if (valid) {
650 let params = { ...configInfoFormRef.value.formInline, isCreateReport: 'Y', ruleWeights: ruleWeightData.value };
651 let models: any = [];
652 let transferFilters: any = [];
653 for (const key in batchFiltersValue.value) {
654 let info = batchFiltersValue.value[key];
655 if (info.tables.length) {
656 info.tables.forEach(t => {
657 transferFilters.push(Object.assign({}, t, {
658 filter: info.filter,
659 dataFilterGroup: key
660 }));
661 });
662 }
663 }
664 damSubjectTables.value.forEach(t => {
665 let filterInfo = transferFilters.find(b => b.guid == t.guid);
666 let rule: any = ruleModelTableInfo.value.data.find((d: any) => d.subjectGuid == t.guid)
667 models.push({
668 qualityModelGuid: rule?.qualityModelGuid,
669 subjectGuid: t.guid,
670 dataRange: filterInfo?.filter,
671 dataFilterGroup: filterInfo?.dataFilterGroup,
672 });
673 });
674 params.models = models;
675 if (planGuid) {
676 params.guid = planGuid;
677 fullscreenLoading.value = true;
678 updateQualityPlan(params).then((res: any) => {
679 fullscreenLoading.value = false;
680 if (res.code == proxy.$passCode) {
681 proxy.$ElMessage.success('资产质量评估编辑成功');
682 router.push({
683 name: 'damQualityAssess'
684 });
685 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
686 assetStore.setQualityAssessRefresh(true);
687 } else {
688 proxy.$ElMessage.error(res.msg);
689 }
690 })
691 } else {
692 fullscreenLoading.value = true;
693 // params.damName =
694 saveQualityPlan(params).then((res: any) => {
695 fullscreenLoading.value = false;
696 if (res.code == proxy.$passCode) {
697 proxy.$ElMessage.success('新建资产质量评估保存成功');
698 router.push({
699 name: 'damQualityAssess'
700 });
701 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
702 assetStore.setQualityAssessRefresh(true);
703 } else {
704 proxy.$ElMessage.error(res.msg);
705 }
706 })
707 }
708 }
709 })
710 }
711
712 const cancelPlan = () => {
713 proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
714 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
715 router.push({
716 path: '/data-asset/quality-assess'
717 });
718 }, () => {
719 proxy.$ElMessage.info("已取消");
720 });
721 }
722
723 </script>
724
725 <template>
726 <div class="container_wrap full" v-loading="fullscreenLoading">
727 <div class="content_main">
728 <div class="top_tool_wrap">
729 <StepBar :steps-info="stepsInfo" />
730 </div>
731 <div class="operator_panel_wrap" v-show="step == 0">
732 <ContentWrap id="id-baseInfo" title="配置数据资产质量规则" description="">
733 <Form ref="damInfoFormRef" :itemList="damFormItems" formId="dam-base-form" :rules="damFormRules"
734 @select-change="handleDamInfoSelectChange" col="col3" />
735 <Table class="mt4" :tableInfo="modelRuleDetailTableInfo" />
736 <div class="row-add-btn">
737 <el-button :disabled="!damGuid" link @click="addTableRules" :icon="CirclePlus" v-preReClick>新增</el-button>
738 </div>
739 </ContentWrap>
740 </div>
741 <div class="operator_panel_wrap" v-show="step == 1">
742 <ContentWrap id="id-filterInfo" title="批量配置过滤条件" description="" class="mb16">
743 <Form ref="damInfoFormRef" :itemList="damFormItemsReadOnly" formId="dam-base-form2" col="col3" />
744 <div class="tools_btns">
745 <el-button type="primary" @click="handleFiltersAdd">批量配置过滤条件</el-button>
746 <span class="tips_text">批量给表添加质检数据范围,不需要写where关键字,支持函数。未填写默认质检全部数据。</span>
747 </div>
748 <Table :tableInfo="ruleModelTableInfo" />
749 </ContentWrap>
750 <ContentWrap id="id-ruleWeight" title="规则权重" description="">
751 <el-table class="rule-weight-table" ref="ruleWeightTableRef" v-loading="ruleWeightDataLoading"
752 :data="ruleWeightData" height="100%" :highlight-current-row="true" stripe tooltip-effect="light" border
753 :style="{ height: '100%', width: 'auto', 'max-width': '100%', display: 'inline-block' }">
754 <el-table-column prop="largeCategoryName" label="规则大类" width="150px" align="left" show-overflow-tooltip>
755 </el-table-column>
756 <el-table-column prop="ruleCount" label="规则数量" width="150px" header-align="right" align="right"
757 show-overflow-tooltip>
758 </el-table-column>
759 <el-table-column prop="ruleLargeWeight" label="规则权重(总分100)" width="200px" align="left"
760 show-overflow-tooltip>
761 <template #default="scope">
762 <el-input v-model.trim="scope.row['ruleLargeWeight']" placeholder="请输入"
763 @change="(val) => inputWeightChange(val, scope.row)"
764 @input="(val) => inputEventWeightChange(val, scope.row)"></el-input>
765 </template>
766 </el-table-column>
767 </el-table>
768 </ContentWrap>
769 </div>
770 <div class="operator_panel_wrap" v-show="step == 2">
771 <ContentWrap id="id-baseInfo" title="执行配置的质量规则" description="">
772 <Form ref="configInfoFormRef" :itemList="configFormItems" formId="config-base-form" :rules="configFormRules"
773 col="col3" />
774 </ContentWrap>
775 </div>
776 </div>
777 <div class="bottom_tool_wrap">
778 <template v-if="step == 0">
779 <el-button @click="cancelPlan">取消</el-button>
780 <el-button type="primary" @click="nextStep(1)">下一步</el-button>
781 </template>
782 <template v-else-if="step == 1">
783 <el-button @click="cancelPlan">取消</el-button>
784 <el-button type="primary" @click="previousStep(1)">上一步</el-button>
785 <el-button type="primary" @click="nextStep(2)">下一步</el-button>
786 </template>
787 <template v-else>
788 <el-button @click="cancelPlan">取消</el-button>
789 <el-button type="primary" @click="previousStep(2)">上一步</el-button>
790 <el-button type="primary" v-preReClick @click="save">提交</el-button>
791 </template>
792 </div>
793 <filtersSettingBatch ref="batchFilterDialogRef" :subject-tables="damSubjectTables"
794 @filtersValueChange="batchFiltersValueChange"></filtersSettingBatch>
795 <el-drawer v-model="drawerInfo.visible" :size="drawerInfo.size" :close-on-click-modal="false"
796 :close-on-press-escape="false" :before-close="cancelEditRules">
797 <template #header>
798 <span class="title">{{ drawerInfo.header.title }}</span>
799 </template>
800 <template #default>
801 <tableRules v-if="drawerInfo.type == 'add'" ref="tableRulesRef" :damGuid="damGuid"
802 :toSubjectTables="toSubjectTables" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
803 :smallCategoryList="smallCategoryList"></tableRules>
804 <div class="drawer-form-content" v-else v-loading="drawerInfoLoading">
805 <tableRuleForm ref="tableRuleFormRef" :toSubjectTables="toSubjectTables" :ruleTypeValue="ruleType"
806 :value="detailRuleInfo" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
807 :smallCategoryList="smallCategoryList"></tableRuleForm>
808 </div>
809 </template>
810 <template #footer>
811 <div style="flex:auto">
812 <el-button v-preReClick @click="cancelEditRules">取消</el-button>
813 <el-button type="primary" :loading="submitRulesLoading" v-preReClick @click="addSubmitRules">确定</el-button>
814 </div>
815 </template>
816 </el-drawer>
817 </div>
818 </template>
819
820 <style scoped lang="scss">
821 .top_tool_wrap {
822 width: 100%;
823 height: 72px;
824 margin: 8px 0 0px;
825 display: flex;
826 justify-content: center;
827 align-items: center;
828
829 :deep(.el-steps) {
830 width: 50%;
831 justify-content: center;
832 }
833 }
834
835 .content_main {
836 height: calc(100% - 40px);
837 padding: 0 16px;
838 overflow: hidden auto;
839
840 .operator_panel_wrap {
841 height: auto;
842
843 .tools_btns {
844 margin-bottom: 8px;
845
846 .tips_text {
847 margin-left: 8px;
848 font-size: 12px;
849 color: #b2b2b2;
850 }
851 }
852 }
853 }
854
855 .row-add-btn {
856 .el-button:focus-visible {
857 outline: none;
858 }
859
860 .el-button--default {
861 padding: 8px 0px;
862 }
863
864 :deep(.el-icon) {
865 width: 16px;
866 height: 16px;
867
868 svg {
869 width: 16px;
870 height: 16px;
871 }
872 }
873 }
874
875 .bottom_tool_wrap {
876 height: 40px;
877 padding: 0 16px;
878 border-top: 1px solid #d9d9d9;
879 display: flex;
880 justify-content: flex-end;
881 align-items: center;
882 }
883
884 :deep(.el-drawer) {
885 .el-drawer__body {
886 padding: 0px;
887
888 .drawer-form-content {
889 height: 100%;
890 width: 100%;
891
892 &>.el-form {
893 padding: 16px;
894 }
895 }
896 }
897 }
898
899 .mt4 {
900 margin-top: 4px;
901 }
902
903 :deep(.rule-weight-table.el-table) {
904 & td.el-table__cell {
905 padding: 2px 0;
906 height: 36px;
907 }
908 }
909 </style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -8,9 +8,8 @@ import { ...@@ -8,9 +8,8 @@ import {
8 getParamsList, 8 getParamsList,
9 chTransformEn 9 chTransformEn
10 } from "@/api/modules/dataAsset"; 10 } from "@/api/modules/dataAsset";
11 import { pinyin } from 'pinyin-pro';
12 import useUserStore from "@/store/modules/user"; 11 import useUserStore from "@/store/modules/user";
13 import { getDictionaryTree } from '@/api/modules/dataInventory'; 12 import { getDictionaryTree } from '@/api/modules/dataAsset';
14 13
15 const emits = defineEmits([ 14 const emits = defineEmits([
16 "cancelImport", 15 "cancelImport",
......
1 <route lang="yaml">
2 name: assetIndex
3 </route>
4
5 <script lang="ts" setup name="assetIndex">
6 import { ref } from "vue";
7 import * as echarts from "echarts";
8 import {
9 getHomeServiceInfo,
10 getStatisticsInfo,
11 getRegisterInfo,
12 getDaTradeInfo,
13 getQualityInfo,
14 getFinanceInfo,
15 getRegisterUrl,
16 } from "@/api/modules/dataAssetIndex";
17 import { getImageContent } from "@/api/modules/queryService";
18 import { ElMessage } from "element-plus";
19 import { calcColumnWidth } from "@/utils/index";
20 import { changeNum } from "@/utils/common";
21 import useUserStore from "@/store/modules/user";
22 import platformIndex from "./platformIndex.vue";
23 import { useRouter, useRoute } from "vue-router";
24 import Moment from "moment";
25
26 const router = useRouter();
27
28 const userStore = useUserStore();
29 const userData = JSON.parse(userStore.userData);
30
31 const { proxy } = getCurrentInstance() as any;
32
33 const noData = ref(false);
34
35 /** 资产登记数 */
36 const registerNum = ref(0);
37 const registerNumUrl = new URL(
38 "@/assets/images/registerNum.png",
39 import.meta.url
40 ).href;
41
42 /** 价值评估数 */
43 const costAssessNum = ref(0);
44 const costAssessNumUrl = new URL(
45 "@/assets/images/costAssess.png",
46 import.meta.url
47 ).href;
48
49 /** 证书url */
50 const docUrl: any = ref([]);
51
52 const docUrlList: any = ref([
53 [
54 {
55 url: new URL("@/assets/images/icon1.png", import.meta.url).href,
56 },
57 {
58 url: new URL("@/assets/images/icon2.png", import.meta.url).href,
59 },
60 {
61 url: new URL("@/assets/images/icon3.png", import.meta.url).href,
62 },
63 ],
64 [
65 {
66 url: new URL("@/assets/images/icon4.png", import.meta.url).href,
67 },
68 {
69 url: new URL("@/assets/images/icon5.png", import.meta.url).href,
70 },
71 ],
72 ]);
73
74 const cardList = ref([
75 {
76 name: "dataScale",
77 value: 0,
78 label: "数据规模",
79 unit: " GB",
80 },
81 {
82 name: "tableNum",
83 value: 0,
84 label: "表数量",
85 unit: "",
86 },
87 {
88 name: "fieldNum",
89 value: 0,
90 label: "字段数量",
91 unit: "",
92 },
93 {
94 name: "assessmentMoney",
95 value: 0,
96 label: "资产估值",
97 unit: " 万元",
98 },
99 {
100 name: "intableNum",
101 value: 0,
102 label: "入表资产数",
103 unit: "",
104 },
105 {
106 name: "noIntableNum",
107 value: 0,
108 label: "未入表资产数",
109 unit: "",
110 },
111 {
112 name: "lastIntableTime",
113 value: "--",
114 label: "最近入表时间",
115 unit: "",
116 },
117 {
118 name: "dataCategoryNum",
119 value: 0,
120 label: "数据分类",
121 unit: "",
122 },
123 {
124 name: "dataGradeNum",
125 value: 0,
126 label: "数据分级",
127 unit: "",
128 },
129 ]);
130
131 const checkImage = () => {
132 let a: any = document.querySelector(".el-image-viewer__actions__inner");
133 let lenBtn = a.getElementsByClassName("el-icon");
134 if (lenBtn.length == 6) {
135 return;
136 }
137 let ff = document.createElement("i");
138 ff.classList.add("el-icon");
139 ff.addEventListener("click", () => {
140 let imgsrc = (<HTMLImageElement>(
141 document.querySelector(".el-image-viewer__img")
142 ))?.src;
143 let image = new Image();
144 // 解决跨域 Canvas 污染问题
145 image.setAttribute("crossOrigin", "anonymous");
146 image.onload = function () {
147 let canvas = document.createElement("canvas");
148 canvas.width = image.width;
149 canvas.height = image.height;
150 let context: any = canvas.getContext("2d");
151 context.drawImage(image, 0, 0, image.width, image.height);
152 let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
153 let a = document.createElement("a"); // 生成一个a元素
154 let event = new MouseEvent("click"); // 创建一个单击事件
155 a.download = "资产登记证书"; // 设置图片名称
156 a.href = url; // 将生成的URL设置为a.href属性
157 a.dispatchEvent(event); // 触发a的单击事件
158 };
159 image.src = imgsrc;
160 });
161 ff.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" data-v-ea893728=""><path fill="currentColor" d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64m384-253.696 236.288-236.352 45.248 45.248L508.8 704 192 387.2l45.248-45.248L480 584.704V128h64z"></path></svg>`;
162 a.appendChild(ff);
163 };
164
165 const assetPage = ref({
166 limit: 50,
167 curr: 1,
168 sizes: [
169 { label: "10", value: 10 },
170 { label: "50", value: 50 },
171 { label: "100", value: 100 },
172 { label: "150", value: 150 },
173 { label: "200", value: 200 },
174 ],
175 rows: 0,
176 });
177
178 const assetTableInfo = ref({
179 id: "asset-table",
180 multiple: false,
181 fields: [
182 { label: "序号", type: "index", width: 56, align: "center" },
183 {
184 label: "资产名称",
185 field: "daName",
186 width: 140,
187 type: "text_btn",
188 columClass: 'text_btn',
189 value: "detail",
190 },
191 {
192 label: "登记日期",
193 field: "registerTime",
194 width: 120,
195 getName: (scope) => {
196 if (!scope.row.registerTime) {
197 return "--";
198 }
199 return Moment(scope.row.registerTime).format("YYYY-MM-DD");
200 },
201 },
202 { label: "交易所", field: "exchangeName", width: 250 },
203 {
204 label: "资产登记",
205 field: "register",
206 width: 100,
207 getSvg: (scope) => {
208 return scope.row.register == "已登记" ? "icon-success" : "icon-audit";
209 },
210 },
211 {
212 label: "质量评价",
213 field: "quality",
214 width: 100,
215 getSvg: (scope) => {
216 return scope.row.quality == "已评价" ? "icon-success" : "icon-audit";
217 },
218 },
219 {
220 label: "价值评估",
221 field: "cost",
222 width: 100,
223 getSvg: (scope) => {
224 return scope.row.cost == "已评估" ? "icon-success" : "icon-audit";
225 },
226 },
227 {
228 label: "入表",
229 field: "intable",
230 width: 100,
231 getSvg: (scope) => {
232 return scope.row.intable == "已入表" ? "icon-success" : "icon-audit";
233 },
234 },
235 {
236 label: "交易",
237 field: "trade",
238 width: 100,
239 getSvg: (scope) => {
240 return scope.row.trade == "已交易" ? "icon-success" : "icon-audit";
241 },
242 },
243 {
244 label: "融资",
245 field: "financing",
246 width: 100,
247 getSvg: (scope) => {
248 return scope.row.financing == "已融资" ? "icon-success" : "icon-audit";
249 },
250 },
251 ],
252 data: [],
253 page: {
254 type: "concise",
255 showCount: true,
256 ...assetPage.value,
257 },
258 actionInfo: {
259 show: false,
260 },
261 loading: false,
262 });
263
264 const getAssetTableData = () => {
265 assetTableInfo.value.loading = true;
266 getRegisterInfo({
267 pageSize: assetPage.value.limit,
268 pageIndex: assetPage.value.curr,
269 }).then((res: any) => {
270 assetTableInfo.value.loading = false;
271 if (res.code == proxy.$passCode) {
272 let data = res.data || {};
273 assetTableInfo.value.data = data.records || [];
274 assetPage.value.rows = data.totalRows ?? 0;
275 assetTableInfo.value.page.rows = data.totalRows ?? 0;
276 } else {
277 ElMessage.error(res.msg);
278 }
279 });
280 };
281
282 const assetTablePageChange = (info) => {
283 assetPage.value.curr = Number(info.curr);
284 assetPage.value.limit = Number(info.limit);
285 getAssetTableData();
286 };
287
288 const tableBtnClick = (scope, btn) => {
289 const type = btn.value;
290 let row = scope.row;
291 if (type == "detail") {
292 router.push({
293 name: "registerInfoDetail",
294 query: {
295 guid: row.registerGuid,
296 type: "asset",
297 daTenantGuid: userData.tenantGuid,
298 },
299 });
300 }
301 };
302
303 let qualityPieChart: any = null;
304
305 const qualityPieData: any = ref([]);
306
307 /** 设置柱形图option,默认只 展示12次的 */
308 const setPieChartOption = () => {
309 if (!qualityPieData.value.length) {
310 let option1 = {
311 title: [
312 {
313 text: "",
314 left: "30px",
315 top: "30px",
316 },
317 {
318 text: "暂无数据",
319 left: "center",
320 top: "center",
321 textStyle: {
322 fontStyle: "normal",
323 fontWeight: "400",
324 fontSize: 18,
325 },
326 },
327 ],
328 };
329 qualityPieChart.setOption(option1, true);
330 window.addEventListener("resize", () => {
331 qualityPieChart.resize();
332 });
333 return;
334 }
335 let sum = qualityPieData.value
336 .map((d) => d.value)
337 .reduce(function (prev, curr, idx, arr) {
338 return prev + curr;
339 });
340 let option = {
341 textStyle: {
342 fontFamily: "SimSun",
343 },
344 color: ["#4DC5BE", "#40A9FF", "#FF8601"],
345 legend: {
346 // left: "right",
347 orient: "vertical",
348 top: "middle",
349 // right: 50,
350 x: "60%",
351 y: "cenetr",
352 itemGap: 20,
353 icon: "circle",
354 itemHeight: 10,
355 align: "left",
356 textStyle: {
357 color: "#666666",
358 fontSize: 14,
359 },
360 },
361 series: [
362 {
363 name: "quality",
364 type: "pie",
365 center: ["30%", "50%"],
366 radius: ["60%", "80%"],
367 avoidLabelOverlap: false,
368 itemStyle: {
369 borderRadius: 10,
370 borderColor: "#fff",
371 borderWidth: 2,
372 },
373 label: {
374 show: true,
375 position: "center",
376 fontSize: 24,
377 formatter: ["{a|已评估资产}", `{b|${changeNum(sum)}}{c| 个}`].join("\n"),
378 rich: {
379 a: {
380 fontSize: 16,
381 color: "#212121",
382 fontWeight: 600,
383 lineHeight: 27,
384 },
385 b: {
386 fontSize: 24,
387 color: "#212121",
388 lineHeight: 42,
389 fontWeight: 600,
390 },
391 c: {
392 fontSize: 18,
393 color: "#212121",
394 lineHeight: 42,
395 fontWeight: 600,
396 },
397 },
398 },
399 emphasis: {
400 focus: "self",
401 label: {
402 show: true,
403 formatter: (params) => {
404 return [
405 `{a|${params.data.originName}}`,
406 `{b|${params.percent}%}`,
407 ].join("\n");
408 },
409 fontSize: 24,
410 fontWeight: "bold",
411 rich: {
412 a: {
413 fontSize: 16,
414 color: "#212121",
415 fontWeight: 600,
416 lineHeight: 27,
417 },
418 b: {
419 fontSize: 24,
420 color: "#212121",
421 lineHeight: 42,
422 fontWeight: 600,
423 },
424 },
425 },
426 },
427 labelLine: {
428 show: false,
429 },
430 data: qualityPieData.value.map((d) => {
431 return {
432 value: d.value,
433 name: `${d.name} ${(d.value / sum) * 100}% ${changeNum(
434 d.value
435 )}个`,
436 originName: d.name,
437 };
438 }),
439 },
440 ],
441 };
442 option && qualityPieChart.setOption(option, true);
443 window.addEventListener("resize", () => {
444 qualityPieChart.resize();
445 });
446 };
447
448 const tradePage = ref({
449 limit: 50,
450 curr: 1,
451 sizes: [
452 { label: "10", value: 10 },
453 { label: "50", value: 50 },
454 { label: "100", value: 100 },
455 { label: "150", value: 150 },
456 { label: "200", value: 200 },
457 ],
458 });
459
460 const tradeTableInfo = ref({
461 id: "trade-table",
462 multiple: false,
463 fields: [
464 { label: "序号", type: "index", width: 56, align: "center" },
465 {
466 label: "资产名称",
467 field: "daName",
468 width: 140,
469 type: "text_btn",
470 columClass: 'text_btn',
471 value: "detail",
472 },
473 { label: "交易日期", field: "tradeTime", width: 120 },
474 { label: "交易对象", field: "tradeObject", width: 250 },
475 ],
476 data: [],
477 page: {
478 type: "concise",
479 showCount: true,
480 rows: 0,
481 ...tradePage.value,
482 },
483 actionInfo: {
484 show: false,
485 },
486 loading: false,
487 });
488
489 const getTradeTableData = () => {
490 tradeTableInfo.value.loading = true;
491 getDaTradeInfo({
492 pageSize: tradePage.value.limit,
493 pageIndex: tradePage.value.curr,
494 }).then((res: any) => {
495 tradeTableInfo.value.loading = false;
496 if (res.code == proxy.$passCode) {
497 let data = res.data || {};
498 tradeTableInfo.value.data = data.records || [];
499 tradeTableInfo.value.page.rows = data.totalRows ?? 0;
500 } else {
501 ElMessage.error(res.msg);
502 }
503 });
504 };
505
506 const tradeTablePageChange = (info) => {
507 tradePage.value.curr = Number(info.curr);
508 tradePage.value.limit = Number(info.limit);
509 getTradeTableData();
510 };
511
512 const tradeTableBtnClick = (scope, btn) => {
513 const type = btn.value;
514 let row = scope.row;
515 if (type == "detail") {
516 router.push({
517 name: "registerInfoDetail",
518 query: {
519 guid: row.registerGuid,
520 type: "asset",
521 daTenantGuid: userData.tenantGuid,
522 },
523 });
524 }
525 };
526
527 const financingPage = ref({
528 limit: 50,
529 curr: 1,
530 sizes: [
531 { label: "10", value: 10 },
532 { label: "50", value: 50 },
533 { label: "100", value: 100 },
534 { label: "150", value: 150 },
535 { label: "200", value: 200 },
536 ],
537 });
538
539 const financingTableInfo = ref({
540 id: "financing-table",
541 multiple: false,
542 fields: [
543 { label: "序号", type: "index", width: 56, align: "center" },
544 {
545 label: "资产名称",
546 field: "daName",
547 width: 140,
548 type: "text_btn",
549 columClass: 'text_btn',
550 value: "detail",
551 },
552 { label: "授信日期", field: "creditGrantingTime", width: 120 },
553 { label: "授信主体", field: "creditGrantingGenerality", width: 250 },
554 {
555 label: "授信金额(万元)",
556 field: "creditGrantingMoney",
557 width: 140,
558 align: "right",
559 getName: (scope) => {
560 return changeNum(scope.row.creditGrantingMoney ?? 0, 2, true);
561 },
562 },
563 {
564 label: "授信期限(月)",
565 field: "creditGrantingTerm",
566 width: 140,
567 align: "right",
568 getName: (scope) => {
569 return changeNum(scope.row.creditGrantingTerm ?? 0);
570 },
571 },
572 ],
573 data: [],
574 page: {
575 type: "concise",
576 showCount: true,
577 rows: 0,
578 ...financingPage.value,
579 },
580 actionInfo: {
581 show: false,
582 },
583 loading: false,
584 });
585
586 const getFinancingTableData = () => {
587 financingTableInfo.value.loading = true;
588 getFinanceInfo({
589 pageSize: financingPage.value.limit,
590 pageIndex: financingPage.value.curr,
591 }).then((res: any) => {
592 financingTableInfo.value.loading = false;
593 if (res.code == proxy.$passCode) {
594 let data = res.data || {};
595 financingTableInfo.value.data = data.records || [];
596 financingTableInfo.value.page.rows = data.totalRows ?? 0;
597 } else {
598 ElMessage.error(res.msg);
599 }
600 });
601 };
602
603 const financingTablePageChange = (info) => {
604 financingPage.value.curr = Number(info.curr);
605 financingPage.value.limit = Number(info.limit);
606 getFinancingTableData();
607 };
608
609 const financingTableBtnClick = (scope, btn) => {
610 const type = btn.value;
611 let row = scope.row;
612 if (type == "detail") {
613 router.push({
614 name: "registerInfoDetail",
615 query: {
616 guid: row.registerGuid,
617 type: "asset",
618 daTenantGuid: userData.tenantGuid,
619 },
620 });
621 }
622 };
623
624 const serviceDataTitle: any = ref([
625 {
626 url: new URL("@/assets/images/service.png", import.meta.url).href,
627 title: "数据服务经济商",
628 },
629 {
630 url: new URL("@/assets/images/register.png", import.meta.url).href,
631 title: "登记机构",
632 },
633 {
634 url: new URL("@/assets/images/cost.png", import.meta.url).href,
635 title: "价值评估机构",
636 },
637 {
638 url: new URL("@/assets/images/credit.png", import.meta.url).href,
639 title: "授信机构",
640 },
641 {
642 url: new URL("@/assets/images/trade.png", import.meta.url).href,
643 title: "交易机构",
644 },
645 ]);
646
647 const serviceData: any = ref([{}, {}, {}, {}, {}]);
648
649 const calcTableColumnWidth = (data: any[], prop) => {
650 let d: any[] = [];
651 data.forEach((dt) => d.push(dt[prop]));
652 return calcColumnWidth(
653 d,
654 "",
655 {
656 fontSize: 14,
657 fontFamily: "SimSun",
658 },
659 {
660 fontSize: 14,
661 fontFamily: "SimSun",
662 }
663 );
664 };
665
666 /** 记录列宽 */
667 const originTableFieldColumn = ref({});
668 /** 记录最大列值 */
669 const maxLen = ref(0);
670
671 /** 所有列宽和 */
672 const columnSumWidth = computed(() => {
673 let sum = 0;
674 for (const key in originTableFieldColumn.value) {
675 sum += originTableFieldColumn.value[key];
676 }
677 return sum;
678 });
679
680 /** 统计数量加载状态。 */
681 const statisticsInfoLoading = ref(false);
682 /** 服务机构信息加载状态 */
683 const serviceLoading = ref(false);
684
685 /** 饼图数据质量加载状态。 */
686 const qualityPieLoading = ref(false);
687
688 /** 证书图片加载 */
689 const docUrlLoading = ref(false);
690
691 onBeforeMount(() => {
692 if (userData.tenantType == 1) {
693 getAssetTableData();
694 statisticsInfoLoading.value = true;
695 getStatisticsInfo().then((res: any) => {
696 statisticsInfoLoading.value = false;
697 if (res.code == proxy.$passCode) {
698 let data = res.data || {};
699 registerNum.value = data.registerNum ?? 0;
700 costAssessNum.value = data.costAssessNum ?? 0;
701 cardList.value.forEach((card) => {
702 if (card.name == "lastIntableTime") {
703 card.value = data[card.name] ?? "--";
704 } else if (
705 card.name == "assessmentMoney" ||
706 card.name == "dataScale"
707 ) {
708 card.value = changeNum(data[card.name] ?? 0, 2, true);
709 } else {
710 card.value = changeNum(data[card.name] ?? 0);
711 }
712 });
713 } else {
714 ElMessage.error(res.msg);
715 }
716 });
717 qualityPieLoading.value = true;
718 getQualityInfo().then((res: any) => {
719 qualityPieLoading.value = false;
720 qualityPieChart = echarts.init(document.getElementById("pie-quality"));
721 if (res.code == proxy.$passCode) {
722 qualityPieData.value = res.data || [];
723 setPieChartOption();
724 } else {
725 ElMessage.error(res.msg);
726 }
727 });
728 getTradeTableData();
729 getFinancingTableData();
730 docUrlLoading.value = true;
731 getRegisterUrl().then((res: any) => {
732 if (res.code == proxy.$passCode) {
733 let data = res.data || [];
734 if (data.length) {
735 let ps: any = [];
736 for (const d of data) {
737 ps.push(
738 getImageContent(d).then((res: any) => {
739 if (res) {
740 return URL.createObjectURL(res);
741 }
742 })
743 );
744 }
745 Promise.all(ps).then((res: any[]) => {
746 console.log(res);
747 docUrl.value = res;
748 docUrlList.value = res.flatMap((value, index, array) => {
749 if (index % 2 === 0) {
750 return [
751 array.slice(index, index + 2).map((a) => {
752 return { url: a };
753 }),
754 ];
755 }
756 return [];
757 });
758 docUrlLoading.value = false;
759 });
760 } else {
761 docUrl.value = [];
762 docUrlList.value = [];
763 docUrlLoading.value = false;
764 }
765 } else {
766 docUrlLoading.value = false;
767 ElMessage.error(res.msg);
768 }
769 });
770 serviceLoading.value = true;
771 getHomeServiceInfo().then((res: any) => {
772 serviceLoading.value = false;
773 if (res.code == proxy.$passCode) {
774 const data = res.data || {
775 serviceName: ["会员A"],
776 registerOrgName: [
777 "北京国际大数据交易所有限责任公司",
778 "贵阳大数据交易所",
779 ],
780 costOrgName: ["会员A"],
781 creditGrantingOrgName: ["3213"],
782 tradeOrgName: ["hhhmmmm111"],
783 };
784 let serviceName = data.serviceName || [];
785 let registerOrgName = data.registerOrgName || [];
786 let costOrgName = data.costOrgName || [];
787 let creditGrantingOrgName = data.creditGrantingOrgName || [];
788 let tradeOrgName = data.tradeOrgName || [];
789 let maxLength = (maxLen.value = Math.max(
790 serviceName.length,
791 registerOrgName.length,
792 costOrgName.length,
793 creditGrantingOrgName.length,
794 tradeOrgName.length
795 ));
796 for (let i = 0; i < maxLength; i++) {
797 serviceData.value.forEach((s, j) => {
798 s[i + 1 + ""] =
799 j == 0
800 ? serviceName[i]
801 : j == 1
802 ? registerOrgName[i]
803 : j == 2
804 ? costOrgName[i]
805 : j == 3
806 ? creditGrantingOrgName[i]
807 : tradeOrgName[i];
808 });
809 originTableFieldColumn.value[i + 1 + ""] =
810 calcTableColumnWidth(serviceData.value, i + 1 + "") - 20;
811 }
812 console.log(serviceData.value);
813 } else {
814 ElMessage.error(res.msg);
815 }
816 });
817 }
818 });
819 </script>
820
821 <template>
822 <div v-if="userData.tenantType == 1" class="main-scroll">
823 <div class="main-content">
824 <div class="one-row">
825 <div class="left" :style="{ width: 'calc(40% - 4px)' }">
826 <div class="header">
827 <span class="header-title">证书登记情况</span>
828 </div>
829 <div class="content">
830 <div class="icon-sum">
831 <template v-if="!statisticsInfoLoading">
832 <div class="img_tags_card" :style="{ background: '#ECF2FF' }">
833 <img :src="registerNumUrl" alt="" />
834 <div class="tags_item">
835 <p class="tag_text">资产登记数</p>
836 <p class="tag_num">
837 <span>{{ changeNum(registerNum) }}</span><span class="unit"></span>
838 </p>
839 </div>
840 </div>
841 <div class="img_tags_card" :style="{ background: '#FFF0E1' }">
842 <img :src="costAssessNumUrl" alt="" />
843 <div class="tags_item">
844 <p class="tag_text">价值评估数</p>
845 <p class="tag_num">
846 <span>{{ changeNum(costAssessNum) }}</span><span class="unit"></span>
847 </p>
848 </div>
849 </div>
850 </template>
851 <el-skeleton v-else :rows="1" animated :style="{ height: '80px' }" />
852 </div>
853 <el-carousel v-if="!docUrlLoading" :interval="2000">
854 <el-carousel-item class="img-card" v-for="(imgData, i) in docUrlList" :key="i" @click="checkImage">
855 <template v-for="(img, index) in imgData" :key="index">
856 <el-image class="top-img" :src="img.url" :zoom-rate="1.2" :max-scale="10" :min-scale="0.2"
857 :preview-src-list="docUrl" :initial-index="i * 3 + index" :preview-teleported="true" fit="cover" />
858 </template>
859 </el-carousel-item>
860 </el-carousel>
861 <el-skeleton class="el-ske-crousel" v-else>
862 <template #template>
863 <el-skeleton-item class="el-ske-img" variant="image" />
864 </template>
865 </el-skeleton>
866 </div>
867 </div>
868 <div class="right" :style="{ width: 'calc(60% - 4px)' }">
869 <div class="header">
870 <span class="header-title">数据资产情况</span>
871 </div>
872 <div class="num-content">
873 <div class="icon-sum num-sum" v-if="!statisticsInfoLoading" v-for="item in cardList">
874 <div class="tags_item">
875 <p class="tag_text">{{ item.label }}</p>
876 <p class="tag_num">
877 <span>{{ item.value }}</span>
878 <span class="unit">{{ item.unit }}</span>
879 </p>
880 </div>
881 </div>
882 <el-skeleton v-else :rows="5" animated />
883 </div>
884 </div>
885 </div>
886 <div class="second-row">
887 <div class="header">
888 <span class="header-title">资产情况</span>
889 </div>
890 <div class="content">
891 <Table v-if="!assetTableInfo.loading" :tableInfo="assetTableInfo" @tablePageChange="assetTablePageChange"
892 @tableBtnClick="tableBtnClick" />
893 <el-skeleton v-else :rows="6" animated />
894 </div>
895 </div>
896 <div class="three-row">
897 <div class="left" :style="{ width: 'calc(40% - 4px)' }">
898 <div class="header">
899 <span class="header-title">数据资产质量情况</span>
900 </div>
901 <div class="content-chart-pie">
902 <el-skeleton class="content-chart-pie-ske" v-if="qualityPieLoading" :rows="7" animated />
903 <div id="pie-quality" class="pie"></div>
904 </div>
905 </div>
906 <div class="right" :style="{ width: 'calc(60% - 4px)' }">
907 <div class="header">
908 <span class="header-title">服务机构情况</span>
909 </div>
910 <template v-if="!serviceLoading">
911 <div class="content row-layout-left">
912 <template v-for="item in serviceDataTitle">
913 <el-row :gutter="10">
914 <el-col :span="6">
915 <img :src="item.url" :style="{ width: '32px', height: '32px' }" alt="" />
916 </el-col>
917 <el-col :span="14">
918 <div class="title">{{ item.title }}</div>
919 </el-col>
920 </el-row>
921 </template>
922 </div>
923 <div class="content row-layout-right">
924 <div class="scroll-container" :style="{
925 width: `${columnSumWidth * 2}px`,
926 }">
927 <div class="scroll-content" :style="{
928 width: `${columnSumWidth}px`,
929 }">
930 <template v-for="item in 5">
931 <el-row :gutter="10" :style="{ animationDuration: columnSumWidth / 50 + 's' }">
932 <template v-for="sd in maxLen">
933 <el-col :span="originTableFieldColumn[sd + '']">
934 <div class="title" :style="{
935 width: `${originTableFieldColumn[sd + '']}px`,
936 }">
937 {{ serviceData[item - 1][sd + ""] }}
938 </div>
939 </el-col>
940 </template>
941 </el-row>
942 </template>
943 </div>
944 <div class="virtual" :style="{
945 width: `${columnSumWidth + 40}px`,
946 }">
947 <template v-for="item in 5">
948 <el-row :gutter="10">
949 <template v-for="sd in maxLen">
950 <el-col :span="originTableFieldColumn[sd + '']">
951 <div class="title" :style="{
952 width: `${originTableFieldColumn[sd + '']}px`,
953 }">
954 {{ serviceData[item - 1][sd + ""] }}
955 </div>
956 </el-col>
957 </template>
958 </el-row>
959 </template>
960 </div>
961 </div>
962 </div>
963 </template>
964 <el-skeleton v-else :rows="7" animated :style="{ margin: '12px', width: 'calc(100% - 24px)' }" />
965 </div>
966 </div>
967 <div class="four-row">
968 <div class="left" :style="{ width: 'calc(40% - 4px)' }">
969 <div class="header">
970 <span class="header-title">资产交易情况</span>
971 </div>
972 <div class="content trade-con">
973 <Table v-if="!tradeTableInfo.loading" :tableInfo="tradeTableInfo" @tablePageChange="tradeTablePageChange"
974 @tableBtnClick="tradeTableBtnClick" />
975 <el-skeleton v-else :rows="5" animated />
976 </div>
977 </div>
978 <div class="right" :style="{ width: 'calc(60% - 4px)' }">
979 <div class="header">
980 <span class="header-title">资产授信情况</span>
981 </div>
982 <div class="content trade-con">
983 <Table v-if="!financingTableInfo.loading" :tableInfo="financingTableInfo"
984 @tablePageChange="financingTablePageChange" @tableBtnClick="financingTableBtnClick" />
985 <el-skeleton v-else :rows="5" animated />
986 </div>
987 </div>
988 </div>
989 <div class="foot-sty" style="white-space: pre-wrap;">北京传世博润科技有限公司 Copyright @ 2023-2024 <a
990 href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
991 </div>
992 </div>
993 </div>
994 <platformIndex v-else-if="userData.tenantType != 1" />
995 <div v-else class="main-placeholder">
996 <img style="width: 480px; height: 110px;" src="../../../public/swzl_logo.gif" />
997 </div>
998 </template>
999
1000 <style lang="scss" scoped>
1001 .main-placeholder {
1002 height: 100%;
1003 display: flex;
1004 justify-content: center;
1005 align-items: center;
1006 }
1007
1008 .main-scroll {
1009 height: 100%;
1010 overflow-y: auto;
1011 }
1012
1013 .main-content {
1014 background-color: #e2e7ef;
1015 padding: 8px 8px 0px 8px;
1016 }
1017
1018 .one-row {
1019 height: 290px;
1020 display: inline-flex;
1021 width: 100%;
1022 justify-content: space-between;
1023
1024 .icon-sum {
1025 display: inline-flex;
1026 width: 100%;
1027 justify-content: space-between;
1028
1029 &.num-sum {
1030 width: calc(33% - 4px);
1031 }
1032
1033 .img_tags_card {
1034 height: 80px;
1035 width: calc(50% - 4px);
1036 display: flex;
1037 align-items: center;
1038 border-radius: 4px;
1039 padding-left: 12px;
1040
1041 img {
1042 width: 48px;
1043 height: 48px;
1044 margin-right: 12px;
1045 display: flex;
1046 align-items: center;
1047 }
1048 }
1049
1050 .tags_item {
1051 height: 50px;
1052 display: flex;
1053 flex-direction: column;
1054 justify-content: space-between;
1055
1056 p {
1057 font-size: 14px;
1058 color: var(--el-text-color-regular);
1059 margin: 0;
1060 line-height: 21px;
1061
1062 &.tag_num {
1063 color: var(--el-color-regular);
1064 font-size: 24px;
1065 font-weight: 700;
1066
1067 .unit {
1068 font-size: 18px;
1069 }
1070 }
1071 }
1072 }
1073 }
1074 }
1075
1076 .right,
1077 .left {
1078 background-color: #fff;
1079 height: 100%;
1080 }
1081
1082 .header {
1083 height: 40px;
1084 border-bottom: 1px solid #e5e5e5;
1085 display: flex;
1086 align-items: center;
1087
1088 .header-title {
1089 font-size: 14px;
1090 color: #212121;
1091 line-height: 21px;
1092 font-weight: 600;
1093 padding-left: 12px;
1094 }
1095 }
1096
1097 .content {
1098 padding: 12px;
1099 }
1100
1101 .num-content {
1102 padding: 12px;
1103 height: calc(100% - 40px);
1104 display: flex;
1105 flex-wrap: wrap;
1106 justify-content: space-between;
1107 }
1108
1109 .second-row {
1110 height: 322px;
1111 background-color: #fff;
1112 margin-top: 8px;
1113
1114 .content {
1115 height: calc(100% - 40px);
1116 padding-bottom: 0px;
1117 }
1118 }
1119
1120 .three-row {
1121 height: 366px;
1122 display: inline-flex;
1123 width: 100%;
1124 justify-content: space-between;
1125 margin-top: 8px;
1126
1127 .row-layout-left {
1128 width: 200px;
1129 height: calc(100% - 40px);
1130 padding: 12px 0px 0px 12px;
1131 display: inline-block;
1132
1133 &>.el-row:nth-child(odd) {
1134 background-color: #fafafa;
1135 }
1136
1137 .title {
1138 font-size: 14px;
1139 color: #0e5fd8;
1140 line-height: 21px;
1141 }
1142
1143 .el-row {
1144 height: 60px;
1145 margin-left: 0px !important;
1146 margin-right: 0px !important;
1147
1148 .el-col:first-child {
1149 padding-left: 18px !important;
1150 }
1151
1152 .el-col:nth-child(2) {
1153 margin-left: 13px !important;
1154 }
1155
1156 .el-col {
1157 display: flex;
1158 align-items: center;
1159 }
1160 }
1161 }
1162
1163 .row-layout-right {
1164 width: calc(100% - 200px);
1165 height: calc(100% - 40px);
1166 padding: 12px 12px 0px 0px;
1167 display: inline-block;
1168 vertical-align: bottom;
1169 overflow: hidden;
1170
1171 .title {
1172 font-size: 14px;
1173 color: #212121;
1174 line-height: 21px;
1175 }
1176
1177 .el-row {
1178 height: 60px;
1179 margin-left: 0px !important;
1180 margin-right: 0px !important;
1181 flex-wrap: nowrap;
1182
1183 .el-col {
1184 display: flex;
1185 align-items: center;
1186 }
1187 }
1188
1189 .scroll-container {
1190 display: flex;
1191 min-width: 200%;
1192 animation: roll 10s infinite linear;
1193
1194 .scroll-content {
1195 flex-shrink: 0;
1196 min-width: 50%;
1197
1198 &>.el-row:nth-child(odd) {
1199 background-color: #fafafa;
1200 }
1201 }
1202
1203 .virtual {
1204 flex-shrink: 0;
1205 // padding-left: 40px;
1206 min-width: 50%;
1207
1208 .el-row {
1209 padding-left: 10px !important;
1210 }
1211
1212 &>.el-row:nth-child(odd) {
1213 background-color: #fafafa;
1214 }
1215 }
1216 }
1217 }
1218 }
1219
1220 @keyframes roll {
1221 0% {
1222 transform: translateX(0);
1223 }
1224
1225 100% {
1226 transform: translateX(-50%);
1227 }
1228 }
1229
1230 .four-row {
1231 height: 312px;
1232 display: inline-flex;
1233 width: 100%;
1234 justify-content: space-between;
1235 margin-top: 8px;
1236
1237 .trade-con {
1238 height: calc(100% - 40px);
1239 padding-bottom: 0px;
1240 }
1241 }
1242
1243 :deep(.el-carousel) {
1244 height: 140px;
1245 margin-top: 8px;
1246
1247 .el-carousel__arrow--left {
1248 left: 0px;
1249 }
1250
1251 .el-carousel__arrow--right {
1252 right: 0px;
1253 }
1254
1255 .el-carousel__arrow {
1256 width: 20px;
1257 height: 48px;
1258 opacity: 0.5;
1259 background: #000000;
1260 border-radius: 4px 0px 0px 4px;
1261 }
1262
1263 .el-carousel__container {
1264 height: 100%;
1265
1266 .img-card {
1267 width: 100%;
1268 display: flex;
1269 padding: 5px 0px;
1270 justify-content: center;
1271
1272 .top-img {
1273 width: 33%;
1274 margin-right: 15px;
1275 cursor: pointer;
1276
1277 &:last-child {
1278 margin-right: 0px;
1279 }
1280 }
1281 }
1282 }
1283 }
1284
1285 .content-chart-pie {
1286 width: 100%;
1287 height: calc(100% - 40px);
1288 padding: 12px;
1289 position: relative;
1290
1291 .pie {
1292 height: 100%;
1293 width: 100%;
1294 }
1295 }
1296
1297 .content-chart-pie-ske {
1298 position: absolute;
1299 width: calc(100% - 24px);
1300 }
1301
1302 .el-ske-crousel {
1303 display: flex;
1304 justify-content: center;
1305
1306 .el-ske-img {
1307 width: 240px;
1308 height: 140px;
1309 margin-top: 8px;
1310 }
1311 }
1312 </style>
1 <route lang="yaml">
2 name: platformIndex
3 </route>
4
5 <script lang="ts" setup name="platformIndex">
6 import { ref } from "vue";
7 import * as echarts from "echarts";
8 import {
9 getFinanceInfo,
10 getIndustryInfo,
11 getCreditMoneyInfo,
12 getPlatformStatisticsInfo,
13 getPlatformMonth,
14 getPlatformService,
15 } from "@/api/modules/dataAssetIndex";
16 import { ElMessage } from "element-plus";
17 import { changeNum } from "@/utils/common";
18 import { useRouter, useRoute } from "vue-router";
19 import useUserStore from "@/store/modules/user";
20
21 const router = useRouter();
22
23 const userStore = useUserStore();
24 const userData = JSON.parse(userStore.userData);
25
26 const { proxy } = getCurrentInstance() as any;
27
28 const cardList = ref([
29 {
30 name: "dataScale",
31 value: 0,
32 label: "数据规模",
33 unit: " GB",
34 },
35 {
36 name: "tableNum",
37 value: 0,
38 label: "表数量",
39 unit: "",
40 },
41 {
42 name: "fieldNum",
43 value: 0,
44 label: "字段数量",
45 unit: "",
46 },
47 {
48 name: "assessmentMoney",
49 value: 0,
50 label: "资产估值",
51 unit: " 万元",
52 },
53 {
54 name: "tradeNum",
55 value: 0,
56 label: "交易资产数",
57 unit: " 个",
58 },
59 {
60 name: "financingNum",
61 value: 0,
62 label: "融资资产数",
63 unit: " 个",
64 },
65 {
66 name: "daNum",
67 value: "0",
68 label: "数据资产数",
69 unit: " 个",
70 },
71 {
72 name: "registerNum",
73 value: 0,
74 label: "资产登记数",
75 unit: " 张",
76 },
77 {
78 name: "cooperationOrNum",
79 value: 0,
80 label: "合作机构数",
81 unit: " 个",
82 },
83 ]);
84
85 const financingPage = ref({
86 limit: 50,
87 curr: 1,
88 sizes: [
89 { label: "10", value: 10 },
90 { label: "50", value: 50 },
91 { label: "100", value: 100 },
92 { label: "150", value: 150 },
93 { label: "200", value: 200 },
94 ],
95 });
96
97 const financingTableInfo = ref({
98 id: "financing-table",
99 multiple: false,
100 fields: [
101 { label: "序号", type: "index", width: 56, align: "center" },
102 {
103 label: "企业名称",
104 field: "companyName",
105 width: 200,
106 },
107 {
108 label: "资产名称",
109 field: "daName",
110 width: 140,
111 type: "text_btn",
112 columClass: 'text_btn',
113 value: "detail",
114 },
115 { label: "授信日期", field: "creditGrantingTime", width: 120 },
116 { label: "授信主体", field: "creditGrantingGenerality", width: 250 },
117 {
118 label: "授信金额(万元)",
119 field: "creditGrantingMoney",
120 width: 140,
121 align: "right",
122 getName: (scope) => {
123 return changeNum(scope.row.creditGrantingMoney ?? 0, 2, true);
124 },
125 },
126 {
127 label: "授信期限(月)",
128 field: "creditGrantingTerm",
129 width: 140,
130 align: "right",
131 getName: (scope) => {
132 return changeNum(scope.row.creditGrantingTerm ?? 0);
133 },
134 },
135 ],
136 data: [],
137 page: {
138 type: "concise",
139 showCount: true,
140 rows: 0,
141 ...financingPage.value,
142 },
143 actionInfo: {
144 show: false,
145 },
146 loading: false,
147 });
148
149 const getFinancingTableData = () => {
150 financingTableInfo.value.loading = true;
151 getFinanceInfo({
152 pageSize: financingPage.value.limit,
153 pageIndex: financingPage.value.curr,
154 }).then((res: any) => {
155 financingTableInfo.value.loading = false;
156 if (res.code == proxy.$passCode) {
157 let data = res.data || {};
158 financingTableInfo.value.data = data.records || [];
159 financingTableInfo.value.page.rows = data.totalRows ?? 0;
160 } else {
161 ElMessage.error(res.msg);
162 }
163 });
164 };
165
166 const financingTablePageChange = (info) => {
167 financingPage.value.curr = Number(info.curr);
168 financingPage.value.limit = Number(info.limit);
169 getFinancingTableData();
170 };
171
172 const financingTableBtnClick = (scope, btn) => {
173 const type = btn.value;
174 let row = scope.row;
175 if (type == "detail") {
176 router.push({
177 name: "registerInfoDetail",
178 query: {
179 guid: row.registerGuid,
180 type: "asset",
181 daTenantGuid: row.companyGuid,
182 },
183 });
184 }
185 };
186
187 const statisticsInfoLoading = ref(false);
188
189 onBeforeMount(() => {
190 getFinancingTableData();
191 statisticsInfoLoading.value = true;
192 getPlatformStatisticsInfo().then((res: any) => {
193 statisticsInfoLoading.value = false;
194 if (res.code == proxy.$passCode) {
195 let data = res.data || {};
196 cardList.value.forEach((card) => {
197 if (card.name == "assessmentMoney" || card.name == "dataScale") {
198 card.value = changeNum(data[card.name] ?? 0, 2);
199 } else {
200 card.value = changeNum(data[card.name] ?? 0);
201 }
202 });
203 } else {
204 ElMessage.error(res.msg);
205 }
206 });
207 });
208
209 /** 行业类型分布的饼图。 */
210 const industryPieLoading = ref(false);
211
212 let industryPieChart: any = null;
213
214 const industryPieData: any = ref([]);
215
216 const industryPieDataTotal: any = ref(0);/** 服务总家数 */
217
218 /** 授信主体金额加载 */
219 const creditMoneyPieLoading = ref(false);
220
221 let creditMoneyPieChart: any = null;
222
223 const creditMoneyPieData: any = ref([]);
224
225 /** 设置行业类型饼图分布 */
226 const setPieChartOption = () => {
227 if (!industryPieData.value.length) {
228 let option1 = {
229 title: [
230 {
231 text: "",
232 left: "30px",
233 top: "30px",
234 },
235 {
236 text: "暂无数据",
237 left: "center",
238 top: "center",
239 textStyle: {
240 fontStyle: "normal",
241 fontWeight: "400",
242 fontSize: 18,
243 },
244 },
245 ],
246 };
247 industryPieChart.setOption(option1, true);
248 window.addEventListener("resize", () => {
249 industryPieChart.resize();
250 });
251 return;
252 }
253 let sum = industryPieData.value
254 .map((d) => d.value)
255 .reduce(function (prev, curr, idx, arr) {
256 return prev + curr;
257 });
258 let option = {
259 textStyle: {
260 fontFamily: "SimSun",
261 },
262 color: ["#4DC5BE", "#40A9FF", "#FF8601", "#656BE9", "#EA6671", "#60D78D"],
263 legend: {
264 // left: "right",
265 orient: "vertical",
266 top: "middle",
267 //right: 50,
268 x: "60%",
269 y: "cenetr",
270 itemGap: 20,
271 icon: "circle",
272 itemHeight: 10,
273 align: "left",
274 textStyle: {
275 color: "#666666",
276 fontSize: 14,
277 },
278 },
279 series: [
280 {
281 name: "industry",
282 type: "pie",
283 center: ["30%", "50%"],
284 radius: ["60%", "80%"],
285 avoidLabelOverlap: false,
286 itemStyle: {
287 borderRadius: 10,
288 borderColor: "#fff",
289 borderWidth: 2,
290 },
291 label: {
292 show: true,
293 position: "center",
294 fontSize: 24,
295 formatter: ["{a|服务家数}", `{b|${changeNum(industryPieDataTotal.value)}}{c| 家}`].join("\n"),
296 rich: {
297 a: {
298 fontSize: 16,
299 color: "#212121",
300 fontWeight: 600,
301 lineHeight: 27,
302 },
303 b: {
304 fontSize: 24,
305 color: "#212121",
306 lineHeight: 42,
307 fontWeight: 600,
308 },
309 c: {
310 fontSize: 18,
311 color: "#212121",
312 lineHeight: 42,
313 fontWeight: 600,
314 },
315 },
316 },
317 emphasis: {
318 focus: "self",
319 label: {
320 show: true,
321 formatter: (params) => {
322 return [
323 `{a|${params.data.originName}}`,
324 `{b|${params.percent}%}`,
325 ].join("\n");
326 },
327 fontSize: 24,
328 fontWeight: "bold",
329 rich: {
330 a: {
331 fontSize: 16,
332 color: "#212121",
333 fontWeight: 600,
334 lineHeight: 27,
335 },
336 b: {
337 fontSize: 24,
338 color: "#212121",
339 lineHeight: 42,
340 fontWeight: 600,
341 },
342 },
343 },
344 },
345 labelLine: {
346 show: false,
347 },
348 data: industryPieData.value.map((d) => {
349 return {
350 value: d.value,
351 name: `${d.name} ${((d.value / sum) * 100).toFixed(
352 2
353 )}% ${changeNum(d.value)}家`,
354 originName: d.name,
355 };
356 }),
357 },
358 ],
359 };
360 option && industryPieChart.setOption(option, true);
361 window.addEventListener("resize", () => {
362 industryPieChart.resize();
363 });
364 };
365
366 /** 设置授信主体金额饼图分布 */
367 const setCreditPieChartOption = () => {
368 if (!creditMoneyPieData.value.length) {
369 let option1 = {
370 title: [
371 {
372 text: "",
373 left: "30px",
374 top: "30px",
375 },
376 {
377 text: "暂无数据",
378 left: "center",
379 top: "center",
380 textStyle: {
381 fontStyle: "normal",
382 fontWeight: "400",
383 fontSize: 18,
384 },
385 },
386 ],
387 };
388 creditMoneyPieChart.setOption(option1, true);
389 window.addEventListener("resize", () => {
390 creditMoneyPieChart.resize();
391 });
392 return;
393 }
394 let sum = creditMoneyPieData.value
395 .map((d) => d.value)
396 .reduce(function (prev, curr, idx, arr) {
397 return prev + curr;
398 });
399 let option = {
400 textStyle: {
401 fontFamily: "SimSun",
402 },
403 color: ["#4DC5BE", "#40A9FF", "#FF8601", "#656BE9", "#EA6671", "#60D78D"],
404 legend: {
405 // left: "right",
406 orient: "vertical",
407 top: "middle",
408 //right: 50,
409 x: "55%",
410 y: "cenetr",
411 itemGap: 20,
412 icon: "circle",
413 itemHeight: 10,
414 align: "left",
415 textStyle: {
416 color: "#666666",
417 fontSize: 14,
418 overflow: 'break'
419 },
420 },
421 series: [
422 {
423 name: "creditMoney",
424 type: "pie",
425 center: ["30%", "50%"],
426 radius: ["60%", "80%"],
427 avoidLabelOverlap: false,
428 itemStyle: {
429 borderRadius: 10,
430 borderColor: "#fff",
431 borderWidth: 2,
432 },
433 label: {
434 show: true,
435 position: "center",
436 fontSize: 24,
437 formatter: ["{a|总授信额}", `{b|${changeNum(sum, 2, true)}}{c| 万元}`].join("\n"),
438 rich: {
439 a: {
440 fontSize: 16,
441 color: "#212121",
442 fontWeight: 600,
443 lineHeight: 27,
444 },
445 b: {
446 fontSize: 24,
447 color: "#212121",
448 lineHeight: 42,
449 fontWeight: 600,
450 },
451 c: {
452 fontSize: 18,
453 color: "#212121",
454 lineHeight: 42,
455 fontWeight: 600,
456 }
457 },
458 },
459 emphasis: {
460 focus: "self",
461 label: {
462 show: true,
463 formatter: (params) => {
464 return [
465 `{a|${params.data.originName}}`,
466 `{b|${params.percent}%}`,
467 ].join("\n");
468 },
469 fontSize: 24,
470 fontWeight: "bold",
471 rich: {
472 a: {
473 fontSize: 16,
474 color: "#212121",
475 fontWeight: 600,
476 lineHeight: 27,
477 },
478 b: {
479 fontSize: 24,
480 color: "#212121",
481 lineHeight: 42,
482 fontWeight: 600,
483 },
484 },
485 },
486 },
487 labelLine: {
488 show: false,
489 },
490 data: creditMoneyPieData.value.map((d) => {
491 return {
492 value: d.value,
493 name: `${d.name} ${((d.value / sum) * 100).toFixed(
494 2
495 )}% ${changeNum(d.value, 2, true)}万元`,
496 originName: d.name,
497 };
498 }),
499 },
500 ],
501 };
502 creditMoneyPieChart.setOption(option, true);
503 window.addEventListener("resize", () => {
504 creditMoneyPieChart.resize();
505 });
506 };
507
508 /** 行业类型地区分布的柱形图。 */
509 const serviceAreaBarLoading = ref(false);
510
511 let serviceAreaBarChart: any = null;
512
513 const serviceAreaBarData: any = ref([]);
514
515 /** 资产登记月趋势分布的柱形图。 */
516 const platformMonthBarLoading = ref(false);
517
518 let platformMonthBarChart: any = null;
519
520 const platformMonthBarData: any = ref([]);
521
522 /** 设置服务企业地区类型分布-柱形图 */
523 const setBarChartOption = (data, barChart, unit) => {
524 if (!data.length) {
525 let option1 = {
526 title: [
527 {
528 text: "",
529 left: "30px",
530 top: "30px",
531 },
532 {
533 text: "暂无数据",
534 left: "center",
535 top: "center",
536 textStyle: {
537 fontStyle: "normal",
538 fontWeight: "400",
539 fontSize: 18,
540 },
541 },
542 ],
543 };
544 barChart.setOption(option1, true);
545 window.addEventListener("resize", () => {
546 barChart.resize();
547 });
548 return;
549 }
550
551 let xAxisData = data.map((s) => s.name);
552 let xAxisDataLen = xAxisData.length;
553 let option = {
554 textStyle: {
555 fontFamily: "SimSun",
556 },
557 color: [
558 "#5797FF",
559 "#6DD18E",
560 "#867EEC",
561 "#FDBC3E",
562 "#F48A64",
563 "#276FF5",
564 "#46D0B5",
565 ],
566 tooltip: {
567 trigger: "axis",
568 axisPointer: {
569 type: "cross",
570 crossStyle: {
571 color: "#999",
572 },
573 },
574 textStyle: {
575 align: "left",
576 },
577 position: function (point, params, dom, rect, size) {
578 dom.style.transform = "translateZ(0)";
579 },
580 formatter: function (params) {
581 return (
582 params[0].name +
583 ":" +
584 changeNum(params[0].data?.value) +
585 unit +
586 "<br>"
587 );
588 },
589 },
590 legend: {
591 show: false,
592 },
593 grid: {
594 left: "5%",
595 top: "5%",
596 right: "5%",
597 bottom: xAxisData.length <= 10 ? "8%" : "18%",
598 },
599 xAxis: {
600 type: "category",
601 nameTextStyle: {
602 color: "#323233",
603 },
604 axisLabel: {
605 textStyle: {
606 color: "#323233",
607 },
608 },
609 axisTick: {
610 show: false,
611 },
612 data: xAxisData || [],
613 },
614 yAxis: {
615 type: "value",
616 nameTextStyle: {
617 color: "#323233",
618 },
619 axisLabel: {
620 textStyle: {
621 color: "#323233",
622 },
623 },
624 axisLine: {
625 //y轴
626 show: false,
627 },
628 },
629 dataZoom: [
630 {
631 type: "inside",
632 filterMode: "filter", // 设定为 'filter' 从而 X 的窗口变化会影响 Y 的范围。
633 zoomLock: xAxisDataLen <= 12 ? true : false,
634 start: xAxisDataLen <= 12 ? 0 : 80,
635 end: 100,
636 },
637 {
638 type: "slider",
639 show: xAxisDataLen <= 12 ? false : true,
640 height: 25,
641 bottom: 0,
642 start: xAxisDataLen <= 12 ? 0 : 80,
643 end: 100,
644 },
645 ],
646 series: {
647 type: "bar",
648 data: data,
649 },
650 };
651 barChart.setOption(option, true);
652 window.addEventListener("resize", () => {
653 barChart.resize();
654 });
655 };
656
657 onMounted(() => {
658 industryPieChart = echarts.init(document.getElementById("pie-industry"));
659 industryPieLoading.value = true;
660 getIndustryInfo().then((res: any) => {
661 industryPieLoading.value = false;
662 if (res.code == proxy.$passCode) {
663 industryPieData.value = res.data?.homeGraphStatistics || [];
664 industryPieDataTotal.value = res.data?.totalCompanyNum ?? 0;
665 setPieChartOption();
666 } else {
667 ElMessage.error(res.msg);
668 }
669 });
670 creditMoneyPieLoading.value = true;
671 creditMoneyPieChart = echarts.init(
672 document.getElementById("pie-creditMoney")
673 );
674 getCreditMoneyInfo().then((res: any) => {
675 creditMoneyPieLoading.value = false;
676 if (res.code == proxy.$passCode) {
677 creditMoneyPieData.value = res.data || [];
678 setCreditPieChartOption();
679 } else {
680 ElMessage.error(res.msg);
681 }
682 });
683 serviceAreaBarLoading.value = true;
684 serviceAreaBarChart = echarts.init(document.getElementById("bar-area"));
685 getPlatformService().then((res: any) => {
686 serviceAreaBarLoading.value = false;
687 if (res.code == proxy.$passCode) {
688 console.log(res.data);
689 serviceAreaBarData.value = res.data || [];
690 setBarChartOption(serviceAreaBarData.value, serviceAreaBarChart, '家');
691 } else {
692 ElMessage.error(res.msg);
693 }
694 });
695 platformMonthBarLoading.value = true;
696 platformMonthBarChart = echarts.init(document.getElementById("bar-month"));
697 getPlatformMonth().then((res: any) => {
698 platformMonthBarLoading.value = false;
699 if (res.code == proxy.$passCode) {
700 console.log(res.data);
701 platformMonthBarData.value = res.data || [];
702 setBarChartOption(platformMonthBarData.value, platformMonthBarChart, '张');
703 } else {
704 ElMessage.error(res.msg);
705 }
706 });
707 });
708 </script>
709
710 <template>
711 <div class="main-scroll">
712 <div class="main-content">
713 <div class="one-row" :style="{ height: '312px', 'margin-top': '8px' }">
714 <div class="left" :style="{ width: 'calc(50% - 4px)' }">
715 <div class="header">
716 <span class="header-title">服务企业地区分布</span>
717 </div>
718 <div class="content-chart-pie">
719 <el-skeleton
720 class="content-chart-pie-ske"
721 v-if="serviceAreaBarLoading"
722 :rows="6"
723 animated
724 />
725 <div id="bar-area" class="pie"></div>
726 </div>
727 </div>
728 <div class="right" :style="{ width: 'calc(50% - 4px)' }">
729 <div class="header">
730 <span class="header-title">行业类型分布</span>
731 </div>
732 <div class="content-chart-pie">
733 <el-skeleton
734 class="content-chart-pie-ske"
735 v-if="industryPieLoading"
736 :rows="6"
737 animated
738 />
739 <div id="pie-industry" class="pie"></div>
740 </div>
741 </div>
742 </div>
743 <div class="one-row" :style="{ height: '320px', 'margin-top': '8px' }">
744 <div class="left" :style="{ width: 'calc(50% - 4px)' }">
745 <div class="header">
746 <span class="header-title">数据服务资产情况</span>
747 </div>
748 <div class="num-content">
749 <div
750 v-if="!statisticsInfoLoading"
751 class="icon-sum num-sum"
752 v-for="item in cardList"
753 >
754 <div class="tags_item">
755 <p class="tag_text">{{ item.label }}</p>
756 <p class="tag_num">
757 <span>{{ item.value }}</span
758 ><span class="unit">{{ item.unit }}</span>
759 </p>
760 </div>
761 </div>
762 <el-skeleton v-else :rows="6" animated />
763 </div>
764 </div>
765 <div class="right" :style="{ width: 'calc(50% - 4px)' }">
766 <div class="header">
767 <span class="header-title">数据资产登记趋势</span>
768 </div>
769 <div class="content-chart-pie">
770 <el-skeleton
771 class="content-chart-pie-ske"
772 v-if="platformMonthBarLoading"
773 :rows="6"
774 animated
775 />
776 <div id="bar-month" class="pie"></div>
777 </div>
778 </div>
779 </div>
780 <div class="one-row" :style="{ height: '312px', 'margin-top': '8px' }">
781 <div class="left" :style="{ width: 'calc(50% - 4px)' }">
782 <div class="header">
783 <span class="header-title">资产授信情况</span>
784 </div>
785 <div class="content trade-con">
786 <Table
787 v-if="!financingTableInfo.loading"
788 :tableInfo="financingTableInfo"
789 @tableBtnClick="financingTableBtnClick"
790 @tablePageChange="financingTablePageChange"
791 />
792 <el-skeleton v-else :rows="6" animated />
793 </div>
794 </div>
795 <div class="right" :style="{ width: 'calc(50% - 4px)' }">
796 <div class="header">
797 <span class="header-title">授信主体金额分布</span>
798 </div>
799 <div class="content-chart-pie">
800 <el-skeleton
801 class="content-chart-pie-ske"
802 v-if="creditMoneyPieLoading"
803 :rows="6"
804 animated
805 />
806 <div id="pie-creditMoney" class="pie"></div>
807 </div>
808 </div>
809 </div>
810 <div class="foot-sty" style="white-space: pre-wrap;">北京传世博润科技有限公司 Copyright @ 2023-2024 <a href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
811 </div>
812 </div>
813 </div>
814 </template>
815
816 <style lang="scss" scoped>
817 .main-scroll {
818 height: 100%;
819 overflow-y: auto;
820 }
821
822 .main-content {
823 background-color: #e2e7ef;
824 padding: 8px 8px 0px 8px;
825 }
826
827 .one-row {
828 height: 290px;
829 display: inline-flex;
830 width: 100%;
831 justify-content: space-between;
832
833 .trade-con {
834 height: calc(100% - 40px);
835 padding-bottom: 0px;
836 }
837 }
838
839 .num-content {
840 padding: 12px;
841 height: calc(100% - 40px);
842 display: flex;
843 flex-wrap: wrap;
844 justify-content: space-between;
845
846 .icon-sum {
847 display: inline-flex;
848 width: 100%;
849 justify-content: space-between;
850
851 &.num-sum {
852 width: calc(33% - 4px);
853 }
854
855 .tags_item {
856 height: 50px;
857 display: flex;
858 flex-direction: column;
859 justify-content: space-between;
860
861 p {
862 font-size: 14px;
863 color: var(--el-text-color-regular);
864 margin: 0;
865 line-height: 21px;
866
867 &.tag_num {
868 color: var(--el-color-regular);
869 font-size: 24px;
870 font-weight: 700;
871
872 .unit {
873 font-size: 18px;
874 }
875 }
876 }
877 }
878 }
879 }
880
881 .right,
882 .left {
883 background-color: #fff;
884 height: 100%;
885 }
886
887 .header {
888 height: 40px;
889 border-bottom: 1px solid #e5e5e5;
890 display: flex;
891 align-items: center;
892
893 .header-title {
894 font-size: 14px;
895 color: #212121;
896 line-height: 21px;
897 font-weight: 600;
898 padding-left: 12px;
899 }
900 }
901
902 .content {
903 padding: 12px;
904 }
905
906 .content-chart-pie {
907 width: 100%;
908 height: calc(100% - 40px);
909 padding: 12px;
910 position: relative;
911
912 .pie {
913 height: 100%;
914 width: 100%;
915 }
916 }
917
918 .content-chart-pie-ske {
919 position: absolute;
920 width: calc(100% - 24px);
921 }
922 </style>
1 <template>
2 <div class="registerGuide">
3 <div class="box">
4 <template v-for="item in data" :key="item.title">
5 <GuideItem :data="item" />
6 </template>
7 </div>
8 </div>
9 </template>
10 <script setup name="registerGuide">
11 import GuideItem from "./components/GuideItem/index.vue"
12 const data = [
13 {
14 title: "资产登记指南",
15 children: [
16 {
17 title: "1、登记准备",
18 children: ["·数据资产登记合规承诺函盖章", "·数据资产登记信息收集函填写"]
19 },
20 {
21 title: "2、登记录入",
22 children: ["·录入数据资产基本信息", "·上传登记合规承诺函和信息收集函", "·录入数据资产权利主体信息"]
23 },
24 {
25 title: "3、检查提交",
26 children: ["·录入完成后,将填写的相关信息与附件的信息进行核对,避免信息不一致导致重复修改审核"]
27 },
28 {
29 title: "4、审核发证",
30 children: ["·提交后,<span style='color:#1161BF;'>初审1~2个工作日</span>;最终审核发证为<span style='color:#1161BF;'>3~5个工作日</span>"]
31 }
32 ]
33 },
34 {
35 title: "质量评估指南",
36 children: [
37 {
38 title: "1、质量评估准备",
39 children: ["·数据资产质量评估承诺函盖章", "·数据资产质量评估库表结构信息收集表填写"]
40 },
41 {
42 title: "2、质量申请",
43 children: ["·选择已登记的数据资产", "·上传质量评估所需的承诺函和信息收集表",]
44 },
45 {
46 title: "3、质量评估",
47 children: ["·质量申请发起后,<span style='color:#1161BF;'>10</span>张表左右的数据资产质量评估工作日在<span style='color:#1161BF;'>10~15个工作日</span>出具评估结果及报告"]
48 },
49 {
50 title: "4、结果查看",
51 children: ["·查看质量评分及质量评估报告"]
52 }
53 ]
54 },
55 {
56 title: "价值评估指南",
57 children: [
58 {
59 title: "1、价值评估准备",
60 children: ["·填写调查问卷", "·填写收入分成明细表", "·填写数据资产成本明细"]
61 },
62 {
63 title: "2、评估申请",
64 children: ["·选择已登记的数据资产", "·上传价值评估的调查问题、收入分成明细及成本明细",]
65 },
66 {
67 title: "3、价值评估",
68 children: ["·价值评估申请发起后,<span style='color:#1161BF;'>10~15个工作日</span>出具评估结果及报告"]
69 },
70 {
71 title: "4、结果查看",
72 children: ["·查看评估值及价值评估报告"]
73 }
74 ]
75 }
76 ]
77 </script>
78 <style lang="scss" scoped>
79 .entryTableguide {
80 min-width: 1000px;
81 height: 100%;
82 background: rgb(242, 243, 248);
83 overflow: auto;
84 }
85 </style>
1 <route lang="yaml">
2 name: productDemandsCheck
3 </route>
4
5 <script lang="ts" setup name="productDemandsCheck">
6 import { ref, onMounted } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import useUserStore from "@/store/modules/user";
9 import useDataAssetStore from "@/store/modules/dataAsset";
10 import { ElMessage, ElMessageBox } from "element-plus";
11
12 import { getDemandList, getParamsDataList, filterVal } from "@/api/modules/dataProduct";
13 import { registerApproveAllow, registerApproveBackup, } from "@/api/modules/dataAsset";
14 import { TableColumnWidth } from '@/utils/enum';
15
16 import TableTools from "@/components/Tools/table_tools.vue";
17 import Table from "@/components/Table/index.vue";
18 import Dialog from "@/components/Dialog/index.vue";
19
20 const { proxy } = getCurrentInstance() as any;
21 const router = useRouter();
22 const userStore = useUserStore();
23 const assetStore = useDataAssetStore();
24 const userData = JSON.parse(userStore.userData);
25 const interfaceTypes: any = ref([]);
26 const searchItemList: any = ref([
27 {
28 type: "input",
29 label: "",
30 field: "dataName",
31 default: "",
32 placeholder: "需求名称",
33 clearable: true
34 },
35 {
36 type: "select",
37 label: "",
38 field: "interfaceType",
39 default: "",
40 props: {
41 value: 'paramValue',
42 label: 'paramName'
43 },
44 placeholder: "界面类型",
45 options: interfaceTypes.value,
46 clearable: true,
47 },
48 ]);
49 const page = ref({
50 limit: 50,
51 curr: 1,
52 sizes: [
53 { label: "10", value: 10 },
54 { label: "50", value: 50 },
55 { label: "100", value: 100 },
56 { label: "150", value: 150 },
57 { label: "200", value: 200 },
58 ],
59 });
60 const searchItemValue: any = ref({});
61 const tableInfo = ref({
62 id: "mapping-table",
63 fields: [
64 { label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
65 { label: "数据需求名称", field: "dataName", width: 140 },
66 {
67 label: "界面类型", field: "interfaceTypeName", width: 100
68 },
69 { label: "发布主体", field: "tenantName", width: 240,
70 // getName: (scope) => {
71 // return userData.tenantName;
72 // }
73 },
74 { label: "参考价", field: "productPrice", width: 120, },
75 {
76 label: "审核状态", field: "approveState", width: TableColumnWidth.STATE, align: 'center', type: "tag", getName: (scope) => {
77 return filterVal(scope.row.approveState, 'approveState');
78 }
79 },
80 { label: "申请时间", field: "applicationTime", width: TableColumnWidth.DATETIME },
81 { label: "操作时间", field: "updateTime", width: TableColumnWidth.DATETIME },
82 ],
83 loading: false,
84 data: [],
85 page: {
86 type: "normal",
87 rows: 0,
88 ...page.value,
89 },
90 actionInfo: {
91 label: "操作",
92 type: "btn",
93 width: 140,
94 btns: (scope) => {
95 let row = scope.row, btnsArr = [];
96 if (row.approveState == 'A') {
97 if (row.approveTenantGuids?.includes(userData.tenantGuid)) {
98 btnsArr.splice(0, 0, { label: "通过", value: "pass", type: 'primary' }, { label: "驳回", value: "reject", type: 'danger', plain: true });
99 }
100 btnsArr.splice(0, 0, { label: "详情", value: "check" });
101 } else {
102 btnsArr.splice(0, 0, { label: "详情", value: "check" });
103 }
104 return btnsArr;
105 },
106 },
107 });
108
109 const contents = ref({
110 pass: [
111 {
112 type: 'form',
113 title: '',
114 formInfo: {
115 id: 'batch-pass-form',
116 items: [
117 {
118 label: '',
119 type: "textarea",
120 placeholder: "请填写通过备注(选填)",
121 field: "approveSuggest",
122 clearable: true,
123 maxlength: 400,
124 block: true,
125 col: 'margin_b_0',
126 }
127 ]
128 }
129 }
130 ],
131 reject: [
132 {
133 type: 'form',
134 title: '',
135 formInfo: {
136 id: 'batch-reject-form',
137 items: [
138 {
139 label: '',
140 type: "textarea",
141 placeholder: "请填写驳回理由(必填)",
142 field: "approveSuggest",
143 clearable: true,
144 maxlength: 400,
145 block: true,
146 col: 'margin_b_0',
147 }
148 ]
149 }
150 }
151 ],
152 });
153
154 const listingDialogRef = ref();
155 const dialogInfo = ref({
156 visible: false,
157 size: 460,
158 direction: "column",
159 header: {
160 title: "",
161 },
162 type: '',
163 contents: [],
164 footer: {
165 btns: [
166 { type: "default", label: "取消", value: "cancel" },
167 { type: "primary", label: "确定", value: "submit" },
168 ],
169 },
170 });
171
172 const getTableData = () => {
173 tableInfo.value.loading = true;
174 getDemandList(
175 Object.assign({}, searchItemValue.value, {
176 isGrounding: 1,
177 pageIndex: page.value.curr,
178 pageSize: page.value.limit,
179 })
180 )
181 .then((res: any) => {
182 tableInfo.value.loading = false;
183 tableInfo.value.data = res.data.records || [];
184 tableInfo.value.page.curr = res.data.pageIndex;
185 tableInfo.value.page.limit = res.data.pageSize;
186 tableInfo.value.page.rows = res.data.totalRows;
187 })
188 .catch((res) => {
189 tableInfo.value.loading = false;
190 });
191 };
192
193 /** 搜索同步任务列表 */
194 const toSearch = (val: any, clear: boolean = false) => {
195 if (clear) {
196 searchItemList.value.map((item) => (item.default = ""));
197 searchItemValue.value = {};
198 } else {
199 searchItemValue.value = Object.keys(val).length ? { ...val } : {};
200 }
201 page.value.curr = 1;
202 tableInfo.value.page.curr = 1;
203 getTableData();
204 };
205
206 const currTableData: any = ref({});
207 const tableBtnClick = (scope, btn) => {
208 const type = btn.value;
209 const row = scope.row;
210 currTableData.value = row;
211 if (type == "check") {
212 toPatn(type);
213 } else {
214 dialogInfo.value.type = type
215 dialogInfo.value.header.title = type == 'pass' ? '通过' : '驳回'
216 dialogInfo.value.contents = contents.value[type]
217 dialogInfo.value.visible = true
218 }
219 };
220
221 const toPatn = (type) => {
222 router.push({
223 name: "productDemandsCheckDetail",
224 query: {
225 guid: currTableData.value.guid,
226 name: currTableData.value.dataName,
227 type
228 },
229 });
230 }
231
232 const tablePageChange = (info) => {
233 page.value.curr = Number(info.curr);
234 page.value.limit = Number(info.limit);
235 tableInfo.value.page.limit = page.value.limit;
236 tableInfo.value.page.curr = page.value.curr;
237 getTableData();
238 };
239
240 const getFirstPageData = () => {
241 page.value.curr = 1
242 tableInfo.value.page.curr = 1;
243 getTableData();
244 }
245
246 const dialogBtnClick = (btn, info) => {
247 if (btn.value == 'submit') {
248 let params = { ...info }
249 params.bizGuid = currTableData.value.guid
250 params.funcCode = currTableData.value.funcCode
251 if (dialogInfo.value.type == 'pass') {
252 dialogInfo.value.visible = false;
253 registerApproveAllow(params).then((res: any) => {
254 if (res.code == proxy.$passCode) {
255 getFirstPageData();
256 ElMessage({
257 type: 'success',
258 message: '审批成功'
259 })
260 } else {
261 ElMessage({
262 type: 'error',
263 message: res.msg,
264 })
265 }
266 }).catch(() => {
267 })
268 } else if (dialogInfo.value.type == 'reject') {
269 if (info.approveSuggest == '') {
270 ElMessage.error('请填写驳回原因')
271 return
272 }
273 dialogInfo.value.visible = false;
274 registerApproveBackup(params).then((res: any) => {
275 if (res.code == proxy.$passCode) {
276 getFirstPageData();
277 ElMessage({
278 type: 'success',
279 message: '驳回成功'
280 })
281 } else {
282 ElMessage({
283 type: 'error',
284 message: res.msg,
285 })
286 }
287 }).catch(() => {
288
289 })
290 }
291 } else if (btn.value == 'cancel') {
292 nextTick(() => {
293 dialogInfo.value.visible = false;
294 })
295 }
296 };
297
298 onActivated(() => {
299 if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
300 getFirstPageData();
301 assetStore.set(false);
302 }
303 })
304
305 onBeforeMount(() => {
306 getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
307 if (res.code == proxy.$passCode) {
308 interfaceTypes.value = res.data || [];
309 let item = searchItemList.value.find(item => item.field == 'interfaceType');
310 item && (item.options = interfaceTypes.value);
311 } else {
312 proxy.$ElMessage.error(res.msg);
313 }
314 })
315 })
316
317 </script>
318
319 <template>
320 <div class="container_wrap">
321 <div class="table_tool_wrap">
322 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
323 </div>
324 <div class="table_panel_wrap">
325 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
326 </div>
327 <!-- 上架对话框 -->
328 <Dialog ref="listingDialogRef" :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" />
329 </div>
330 </template>
331
332 <style scoped lang="scss">
333 .table_tool_wrap {
334 width: 100%;
335 height: auto;
336 padding: 0 8px;
337 min-height: 44px;
338
339 .tools_btns {
340 padding: 0px 0 0;
341 }
342 }
343
344 .table_panel_wrap {
345 width: 100%;
346 height: calc(100% - 44px);
347 padding: 0px 8px 0;
348 }
349 </style>
1 <route lang="yaml">
2 name: productDemandsDetail
3 </route>
4
5 <script lang="ts" setup name="productDemandsDetail">
6 import { ref } from "vue";
7 import { ElMessage, ElMessageBox } from "element-plus";
8 import { CaretRight, CircleCloseFilled } from '@element-plus/icons-vue'
9 import { useRoute } from "vue-router";
10 import Form from "@/components/Form/index.vue";
11 import Dialog from "@/components/Dialog/index.vue";
12 import useUserStore from "@/store/modules/user";
13 import useDataAssetStore from "@/store/modules/dataAsset";
14 import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common';
15 import { getApproveList, getTenantApprove, registerApproveAllow, registerApproveBackup, getParamsList } from "@/api/modules/dataAsset";
16 import { getDemandDetail, demandSave, competitionSave, marketSave, demandUpdate, competitionUpdate, marketUpdate, checkDemandName, getParamsDataList, getProductTypeList } from "@/api/modules/dataProduct";
17 import { getMatchDetail } from "@/api/modules/dataFinance";
18 import { useValidator } from '@/hooks/useValidator';
19 import { changeNum } from "@/utils/common";
20
21 const { required, checkExistName } = useValidator();
22 const route = useRoute();
23 const userStore = useUserStore();
24 const userData = JSON.parse(userStore.userData);
25 const assetStore = useDataAssetStore();
26 const fullPath = route.fullPath;
27 const guid = route.query.guid as string;
28 const dGuid = route.query.dGuid as string;
29 const damName = route.query.name as string || '';
30 const detailType = <string>route.query.type || '';
31 const { proxy } = getCurrentInstance() as any;
32 const router = useRouter();
33 /** 需求类型 */
34 const demandTypes = ref([]);
35 const damTypes = ref([]);
36 /** 界面类型 */
37 const interfaceTypes: any = ref([]);
38 /** 数据服务数据字典 */
39 const dataServiceDetails: any = ref([]);
40 /** 项目的数据字典 */
41 const projectDetails: any = ref([]);
42 const subjectDomainListData: any = ref([]);
43 /** 竞赛类型 */
44 const competitionTypes: any = ref([]);
45 /** 产品类别树形字典 */
46 const productTypes: any = ref([]);
47 /** 交付方式 */
48 const deliveryWayList: any = ref([]);
49
50 const collapseIcon = ref(false);
51 const collapseIcon1 = ref(false);
52 const collapseIcon2 = ref(false);
53 const flowDetail: any = ref({});
54 const flowDetailLoading = ref(false);
55 const applyDetail: any = ref({});
56 const approveTableInfo: any = ref({
57 id: 'approve-table',
58 rowKey: 'guid',
59 loading: false,
60 height: null,
61 minHeight: '60px',
62 maxHeight: '300',
63 fields: [
64 { label: "节点", field: "tenantType", width: 140, align: "left", getName: (scope) => {
65 if(detailType == 'add'){
66 return scope.row.tenantType;
67 } else {
68 let v = scope.row.tenantType;
69 return v == 1 ? '企业' : (v == 2 ? '服务商' : '交易所');
70 }
71 }
72 },
73 { label: '处理对象', field: 'approvedTenantName', width: 200, align: "left" },
74 { label: "操作时间", field: "approveTime", width: 180 },
75 { label: "审批状态", field: "approveState", type: "tag", width: 96, align: 'center' },
76 { label: "审批原因", field: "approveSuggest", width: 240 }
77 ],
78 data: [],
79 showPage: false,
80 actionInfo: {
81 show: false
82 }
83 });
84
85 /** 界面类型为数据需求时的表单 */
86 const demandFormItems = ref([
87 {
88 label: "界面类型",
89 type: "select",
90 placeholder: "请选择",
91 field: "interfaceType",
92 default: '1',
93 props: {
94 value: 'paramValue',
95 label: 'paramName'
96 },
97 options: interfaceTypes.value,
98 required: true,
99 disabled: true
100 },
101 {
102 label: "数据需求名称",
103 type: "input",
104 placeholder: "请输入",
105 field: "dataName",
106 default: '',
107 maxlength: 20,
108 clearable: true,
109 required: true,
110 }, {
111 label: "需求类型",
112 type: "select",
113 placeholder: "请选择",
114 field: "demandType",
115 default: 'DAM-TYPE',//默认值,数据资源
116 props: {
117 value: 'paramValue',
118 label: 'paramName'
119 },
120 options: demandTypes.value,
121 required: true,
122 },
123 {
124 label: "数据类型",
125 type: "select",
126 placeholder: "请选择",
127 field: "demandTypeDetail-type",
128 default: '',
129 props: {
130 value: 'paramValue',
131 label: 'paramName'
132 },
133 options: damTypes.value,
134 required: true,
135 },
136 {
137 label: "数据服务",
138 type: "select",
139 placeholder: "请选择",
140 field: "demandTypeDetail-service",
141 default: '',
142 props: {
143 value: 'paramValue',
144 label: 'paramName'
145 },
146 options: dataServiceDetails.value,
147 visible: false,
148 required: true,
149 },
150 {
151 label: "项目",
152 type: "select",
153 placeholder: "请选择",
154 field: "demandTypeDetail-project",
155 default: '',
156 props: {
157 value: 'paramValue',
158 label: 'paramName'
159 },
160 options: projectDetails.value,
161 visible: false,
162 required: true,
163 },
164 { //只有需求类型为数据资源时才有
165 label: '所属主题',
166 type: 'tree-select',
167 placeholder: '请选择',
168 field: 'subjectDomain',
169 options: subjectDomainListData.value,
170 showAllLevels: false,
171 checkStrictly: false,//只能选择叶子节点。
172 lazy: false,
173 props: {
174 label: "paramName",
175 value: "paramValue",
176 },
177 filterable: true,
178 clearable: true,
179 disabled: false,
180 default: '',
181 required: true
182 },
183 {
184 label: '产品预算',
185 type: 'checkbox-input-item',
186 placeholder: '面议',
187 field: 'isDiscussPersonally',
188 default: 'Y',
189 trueValue: 'Y',
190 falseValue: 'N',
191 children: [
192 {
193 label: '',
194 type: 'input',
195 placeholder: '请输入预算金额',
196 field: 'productPrice',
197 default: '',
198 maxlength: 10,
199 disabled: false,
200 clearable: true,
201 visible: false,
202 style: {width: '100%', margin: 0}
203 }
204 ],
205 required: true,
206 col: 'checkbox-input'
207 }, {
208 label: '审核后自动上架',
209 type: 'switch',
210 field: 'isApproveGrounding',
211 default: 'Y',
212 activeValue: 'Y',
213 inactiveValue: 'N',
214 required: true,
215 }, {
216 label: '需求描述',
217 placeholder: '该数据资产主要包含的信息,数据更新方式等。',
218 field: 'content',
219 type: 'textarea-rich',
220 id: 'demandDesc',
221 default: '',
222 block: true,
223 clearable: true,
224 required: true,
225 }, {
226 label: '需求图片',
227 tip: '支持扩展名:.jpg .png .jpeg',
228 accept: '.jpg, .png, .jpeg',
229 type: 'upload-file',
230 placeholder: '请选择',
231 field: 'productImg',
232 default: [],
233 limit: 1,
234 block: true,
235 required: false,
236 },
237 ]);
238
239 /** 记录已校验过的信息。 */
240 const checkedInfo: any = ref({});
241
242 /** 检验规则 */
243 const demandRules = ref({
244 dataName: [
245 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
246 ],
247 demandType: [required('请选择需求类型')],
248 'demandTypeDetail-type': [required('请选择数据类型')],
249 'demandTypeDetail-service': [required('请选择数据服务')],
250 productPrice: [
251 { required: true, message: "请填写产品预算", trigger: "blur", },
252 ],
253 content: [
254 { required: true, message: "请填写需求描述", trigger: "blur", },
255 ],
256 // productImg: [
257 // {
258 // validator: (rule: any, value: any, callback: any) => {
259 // if (!value?.length) {
260 // callback(new Error('请上传需求图片'))
261 // } else {
262 // callback();
263 // }
264 // }, trigger: 'change'
265 // },
266 // ],
267 });
268
269 /** 算法竞赛的formItems */
270 const algorithmFormItem = ref([
271 {
272 label: "界面类型",
273 type: "select",
274 placeholder: "请选择",
275 field: "interfaceType",
276 default: '2',
277 props: {
278 value: 'paramValue',
279 label: 'paramName'
280 },
281 options: interfaceTypes.value,
282 required: true,
283 disabled: true
284 },
285 {
286 label: "数据需求名称",
287 type: "input",
288 placeholder: "请输入",
289 field: "dataName",
290 default: '',
291 maxlength: 200,
292 clearable: true,
293 required: true,
294 },
295 {
296 label: "竞赛类型",
297 type: "select",
298 placeholder: "请选择",
299 field: "competitionType",
300 default: '',
301 props: {
302 value: 'paramValue',
303 label: 'paramName'
304 },
305 options: competitionTypes.value,
306 required: true
307 }, {
308 label: '奖金(元)',
309 type: 'input',
310 placeholder: '请输入',
311 inputType: 'moneyNumber',
312 field: 'bonus',
313 default: '',
314 maxlength: 10,
315 disabled: false,
316 clearable: true,
317 visible: true
318 },
319 {
320 label: "报名截止日",
321 type: "datetime",
322 field: "signupEndDate",
323 default: null,
324 placeholder: "请选择",
325 clearable: true,
326 required: true,
327 },
328 {
329 label: '举办方',
330 type: 'input',
331 placeholder: '请输入',
332 field: 'organizer',
333 default: '',
334 maxlength: 200,
335 clearable: true,
336 required: true,
337 },
338 {
339 label: '审核后自动上架',
340 type: 'switch',
341 field: 'isApproveGrounding',
342 default: 'Y',
343 activeValue: 'Y',
344 inactiveValue: 'N',
345 required: true,
346 }, {
347 label: '赛事描述',
348 placeholder: '该数据资产主要包含的信息,数据更新方式等。',
349 field: 'content',
350 type: 'textarea-rich',
351 id: 'demandDesc',
352 default: '',
353 block: true,
354 clearable: true,
355 required: true,
356 },
357 // {
358 // label: '赛事图片',
359 // tip: '支持扩展名:.jpg .png .jpeg',
360 // accept: '.jpg, .png, .jpeg',
361 // type: 'upload-file',
362 // placeholder: '请选择',
363 // field: 'productImg',
364 // default: [],
365 // limit: 1,
366 // block: true,
367 // required: true,
368 // },
369 ]);
370
371 const algorithmFormRules = ref({
372 dataName: [
373 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
374 ],
375 competitionType: [required('请选择竞赛类型')],
376 bonus: [{
377 validator: (rule: any, value: any, callback: any) => {
378 if (value === 0) {
379 callback();
380 return;
381 }
382 if (!value) {
383 callback(new Error('请填写奖金'));
384 return;
385 }
386 callback();
387 },
388 trigger: "blur",
389 }],
390 signupEndDate: [required('请选择报名截止日')],
391 organizer: [required('请填写举办方')],
392 content: [
393 { required: true, message: "请填写赛事描述", trigger: "blur", },
394 ],
395 // productImg: [
396 // {
397 // validator: (rule: any, value: any, callback: any) => {
398 // if (!value?.length) {
399 // callback(new Error('请上赛事图片'))
400 // } else {
401 // callback();
402 // }
403 // }, trigger: 'change'
404 // },
405 // ]
406 });
407
408 /** 要素市场的formItem */
409 const elementFormItems = ref([
410 {
411 label: "界面类型",
412 type: "select",
413 placeholder: "请选择",
414 field: "interfaceType",
415 default: '3',
416 props: {
417 value: 'paramValue',
418 label: 'paramName'
419 },
420 options: interfaceTypes.value,
421 required: true,
422 disabled: true
423 },
424 {
425 label: "数据需求名称",
426 type: "input",
427 placeholder: "请输入",
428 field: "dataName",
429 default: '',
430 maxlength: 200,
431 clearable: true,
432 required: true,
433 },
434 {
435 label: '产品类别',
436 type: 'tree-select',
437 placeholder: '请选择',
438 field: 'productType',
439 options: productTypes.value,
440 showAllLevels: false,
441 checkStrictly: false,//只能选择叶子节点。
442 lazy: false,
443 props: {
444 label: "paramName",
445 value: "paramValue",
446 },
447 filterable: true,
448 clearable: true,
449 disabled: false,
450 default: '',
451 required: true
452 },{
453 label: "交付方式",
454 type: "select",
455 placeholder: "请选择",
456 field: "deliveryWay",
457 default: '',
458 options: deliveryWayList.value,
459 props: {
460 value: 'paramValue',
461 label: 'paramName'
462 },
463 filterable: true,
464 clearable: true,
465 disabled: false,
466 required: true,
467 },
468 {
469 label: '产品预算',
470 type: 'checkbox-input-item',
471 placeholder: '面议',
472 field: 'isDiscussPersonally',
473 default: 'Y',
474 trueValue: 'Y',
475 falseValue: 'N',
476 children: [
477 {
478 label: '',
479 type: 'input',
480 placeholder: '请输入预算金额',
481 field: 'productPrice',
482 default: '',
483 maxlength: 10,
484 disabled: false,
485 clearable: true,
486 visible: false,
487 style: {width: '100%', margin: 0}
488 }
489 ],
490 required: true,
491 col: 'checkbox-input'
492 }, {
493 label: '审核后自动上架',
494 type: 'switch',
495 field: 'isApproveGrounding',
496 default: 'Y',
497 activeValue: 'Y',
498 inactiveValue: 'N',
499 required: true,
500 }, {
501 label: '产品描述',
502 placeholder: '该数据资产主要包含的信息,数据更新方式等。',
503 field: 'content',
504 type: 'textarea-rich',
505 id: 'demandDesc',
506 default: '',
507 block: true,
508 clearable: true,
509 required: true,
510 }, {
511 label: '产品图片',
512 tip: '支持扩展名:.jpg .png .jpeg',
513 accept: '.jpg, .png, .jpeg',
514 type: 'upload-file',
515 placeholder: '请选择',
516 field: 'productImg',
517 default: [],
518 limit: 1,
519 block: true,
520 required: true,
521 },
522 ]);
523
524 const elementFormRules = ref({
525 dataName: [
526 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
527 ],
528 productType: [required('请选择产品类别')],
529 deliveryWay: [
530 required('请选择交付方式')
531 ],
532 content: [
533 { required: true, message: "请填写产品描述", trigger: "blur", },
534 ],
535 productImg: [
536 {
537 validator: (rule: any, value: any, callback: any) => {
538 if (!value?.length) {
539 callback(new Error('请上传产品图片'))
540 } else {
541 callback();
542 }
543 }, trigger: 'change'
544 },
545 ],
546 });
547
548 const listingFormRef = ref();
549 const subForm: any = ref({});
550 const formInfo: any = ref({
551 id: 'check-form',
552 col: 'col3',
553 items: demandFormItems.value,
554 rules: demandRules.value
555 })
556
557 const contents = ref({
558 pass: [
559 {
560 type: 'form',
561 title: '',
562 formInfo: {
563 id: 'batch-pass-form',
564 items: [
565 {
566 label: '',
567 type: "textarea",
568 placeholder: "请填写通过备注(选填)",
569 field: "approveSuggest",
570 clearable: true,
571 maxlength: 400,
572 block: true,
573 col: 'margin_b_0',
574 }
575 ]
576 }
577 }
578 ],
579 reject: [
580 {
581 type: 'form',
582 title: '',
583 formInfo: {
584 id: 'batch-reject-form',
585 items: [
586 {
587 label: '',
588 type: "textarea",
589 placeholder: "请填写驳回理由(必填)",
590 field: "approveSuggest",
591 clearable: true,
592 maxlength: 400,
593 block: true,
594 col: 'margin_b_0',
595 }
596 ]
597 }
598 }
599 ],
600 });
601
602 const listingDialogRef = ref();
603 const dialogInfo = ref({
604 visible: false,
605 size: 460,
606 direction: "column",
607 header: {
608 title: "",
609 },
610 type: '',
611 contents: [],
612 footer: {
613 btns: [
614 { type: "default", label: "取消", value: "cancel" },
615 { type: "primary", label: "确定", value: "submit" },
616 ],
617 },
618 });
619
620 const getProductDetail = () => {
621 flowDetailLoading.value = true;
622 getDemandDetail({ guid }).then((res: any) => {
623 flowDetailLoading.value = false;
624 if (res.code == proxy.$passCode) {
625 flowDetail.value = res.data || {};
626 let interfaceType = flowDetail.value.interfaceType;
627 if (interfaceType) {
628 initMethodByInterfaceType.value[interfaceType]();
629 if (interfaceType == '1') {
630 processDemanTypeChange(flowDetail.value.demandType);
631 if (flowDetail.value.demandType == 'DAM-TYPE') {
632 flowDetail.value['demandTypeDetail-type'] = flowDetail.value.demandTypeDetail;
633 } else if (flowDetail.value.demandType == 'DATA_SERVICE_DETAIL') {
634 flowDetail.value['demandTypeDetail-service'] = flowDetail.value.demandTypeDetail;
635 } else if (flowDetail.value.demandType == 'PROJECT_DETAIL') {
636 flowDetail.value['demandTypeDetail-project'] = flowDetail.value.demandTypeDetail;
637 }
638 demandRules.value.dataName = [
639 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
640 ];
641 if (flowDetail.value.subjectDomainTree?.length) {
642 let item: any = demandFormItems.value.find(item => item.field == 'subjectDomain');
643 let tree = flowDetail.value.subjectDomainTree?.[0];
644 if (item && tree) {
645 if (!tree.children[0]?.children?.[0]?.children) {
646 item.expandKeys = tree.children[0]?.children?.[0].parentGuids;
647 } else if (!tree.children[0]?.children?.[0]?.children?.[0]?.children) {
648 item.expandKeys = tree.children[0]?.children?.[0]?.children?.[0]?.parentGuids;
649 }
650 }
651 }
652 } else if (interfaceType == '2') {
653 if (flowDetail.value.bonus != null) {
654 flowDetail.value.bonus = parseFloat(flowDetail.value.bonus).toFixed(2);
655 }
656 algorithmFormRules.value.dataName = [
657 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
658 ];
659 } else {
660 elementFormRules.value.dataName = [
661 required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
662 ];
663 }
664 }
665 setFormItems(flowDetail.value);
666 } else {
667 ElMessage.error(res.msg);
668 }
669 })
670 }
671
672 // 获取审批信息
673 const getApproveData = () => {
674 if(detailType == 'add'){
675 approveTableInfo.value.loading = true;
676 getTenantApprove({funcCode: 'Demand-base-9'}).then((res: any) => {
677 approveTableInfo.value.loading = false;
678 if (res.code == proxy.$passCode) {
679 approveTableInfo.value.data = res.data?.map(d => {
680 return {
681 tenantType: d.substring(4)
682 }
683 }) || [];
684 } else {
685 ElMessage.error(res.msg);
686 }
687 });
688 } else {
689 approveTableInfo.value.loading = true;
690 getApproveList(guid).then((res: any) => {
691 approveTableInfo.value.loading = false;
692 if (res.code == proxy.$passCode) {
693 console.log(res.data);
694 approveTableInfo.value.data = res.data || [];
695 } else {
696 ElMessage.error(res.msg);
697 }
698 });
699 }
700 }
701
702 // 获取申请信息
703 const getApplyDeatil = () => {
704 getMatchDetail({ guid: dGuid }).then((res: any) => {
705 if (res.code == proxy.$passCode) {
706 const data = res.data || [];
707 applyDetail.value = data;
708 } else {
709 ElMessage({
710 type: "error",
711 message: res.msg,
712 });
713 }
714 }).catch((res) => {
715 ElMessage({
716 type: "error",
717 message: '获取申请信息失败',
718 });
719 });
720 }
721
722 const submitForm = (btn, formEl, tosub = false) => {
723 if (!formEl) return;
724 formEl.validate((valid, fields) => {
725 if (valid) {
726 let params: any = { ...subForm.value }
727 delete params.productImg;
728 delete params.productImgList;
729 params.demandPic = subForm.value.productImg?.length ? { name: subForm.value.productImg[0].name, url: subForm.value.productImg[0].url } : {};
730 flowDetailLoading.value = true;
731 if (detailType == 'add') {
732 if (route.query.interfaceType == '1') {
733 params.interfaceType = '1';
734 if (params.demandType == 'DAM-TYPE') {
735 params.demandTypeDetail = params['demandTypeDetail-type'];
736 } else if (params.demandType == 'DATA_SERVICE_DETAIL') {
737 params.demandTypeDetail = params['demandTypeDetail-service']
738 } else if (params.demandType == 'PROJECT_DETAIL') {
739 params.demandTypeDetail = params['demandTypeDetail-project']
740 }
741 demandSave(params).then((res: any) => {
742 flowDetailLoading.value = false;
743 if (res.code == proxy.$passCode) {
744 ElMessage({
745 type: "success",
746 message: '提交成功',
747 });
748 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
749 assetStore.set(true);
750 router.push({
751 name: "productDemandsPublish",
752 query: {},
753 });
754 } else {
755 ElMessage.error(res.msg);
756 }
757 })
758 } else if (route.query.interfaceType == '2') {
759 params.interfaceType = '2';
760 competitionSave(params).then((res: any) => {
761 flowDetailLoading.value = false;
762 if (res.code == proxy.$passCode) {
763 ElMessage({
764 type: "success",
765 message: '提交成功',
766 });
767 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
768 assetStore.set(true);
769 router.push({
770 name: "productDemandsPublish",
771 query: {},
772 });
773 } else {
774 ElMessage.error(res.msg);
775 }
776 })
777 } else if (route.query.interfaceType == '3') {
778 params.interfaceType = '3';
779 marketSave(params).then((res: any) => {
780 flowDetailLoading.value = false;
781 if (res.code == proxy.$passCode) {
782 ElMessage({
783 type: "success",
784 message: '提交成功',
785 });
786 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
787 assetStore.set(true);
788 router.push({
789 name: "productDemandsPublish",
790 query: {},
791 });
792 } else {
793 ElMessage.error(res.msg);
794 }
795 })
796 }
797 } else {
798 params.guid = guid;
799 if (flowDetail.value.interfaceType == '1') {
800 params.interfaceType = '1';
801 if (params.demandType == 'DAM-TYPE') {
802 params.demandTypeDetail = params['demandTypeDetail-type'];
803 } else if (params.demandType == 'DATA_SERVICE_DETAIL') {
804 params.demandTypeDetail = params['demandTypeDetail-service']
805 } else if (params.demandType == 'PROJECT_DETAIL') {
806 params.demandTypeDetail = params['demandTypeDetail-project']
807 }
808 demandUpdate(params).then((res: any) => {
809 flowDetailLoading.value = false;
810 if (res.code == proxy.$passCode) {
811 ElMessage({
812 type: "success",
813 message: '提交成功',
814 });
815 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
816 assetStore.set(true);
817 router.push({
818 name: "productDemandsPublish",
819 query: {},
820 });
821 } else {
822 ElMessage.error(res.msg);
823 }
824 })
825 } else if (flowDetail.value.interfaceType == '2') {
826 params.interfaceType = '2';
827 competitionUpdate(params).then((res: any) => {
828 flowDetailLoading.value = false;
829 if (res.code == proxy.$passCode) {
830 ElMessage({
831 type: "success",
832 message: '提交成功',
833 });
834 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
835 assetStore.set(true);
836 router.push({
837 name: "productDemandsPublish",
838 query: {},
839 });
840 } else {
841 ElMessage.error(res.msg);
842 }
843 })
844 } else if (flowDetail.value.interfaceType == '3') {
845 params.interfaceType = '3';
846 marketUpdate(params).then((res: any) => {
847 flowDetailLoading.value = false;
848 if (res.code == proxy.$passCode) {
849 ElMessage({
850 type: "success",
851 message: '提交成功',
852 });
853 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
854 assetStore.set(true);
855 router.push({
856 name: "productDemandsPublish",
857 query: {},
858 });
859 } else {
860 ElMessage.error(res.msg);
861 }
862 })
863 }
864 }
865 } else {
866 nextTick(() => {
867 const isError = document.getElementsByClassName('is-error');
868 if (isError[0]) {
869 isError[0].scrollIntoView({
870 behavior: 'smooth',
871 block: 'center',
872 });
873 }
874 })
875 }
876 });
877 };
878
879 const btnClick = (btn) => {
880 if (btn.value == 'submit') {
881 const checkForm = listingFormRef.value;
882 const formEl = checkForm.ruleFormRef;
883 const form = checkForm.formInline;
884 subForm.value = { ...form };
885 submitForm(btn, formEl, true);
886 } else if(btn.value == 'pass' || btn.value == 'reject'){
887 dialogInfo.value.type = btn.value
888 dialogInfo.value.header.title = btn.value == 'pass' ? '通过' : '驳回'
889 dialogInfo.value.contents = contents.value[btn.value]
890 dialogInfo.value.visible = true
891 } else {
892 if(detailType == 'add' || detailType == 'edit'){
893 ElMessageBox.confirm(
894 "当前页面尚未保存,确定放弃修改吗?",
895 "提示",
896 {
897 confirmButtonText: "确定",
898 cancelButtonText: "取消",
899 type: "warning",
900 }
901 ).then(() => {
902 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
903 assetStore.set(true);
904 router.push({
905 name: "productDemandsPublish",
906 query: {},
907 });
908 }).catch(() => {
909 ElMessage({
910 type: "info",
911 message: "已取消",
912 });
913 });
914 } else {
915 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
916 router.push({
917 name: "productDemandsCheck",
918 query: {},
919 });
920 }
921 }
922 }
923
924 const setFormItems = (row: any = null) => {
925 formInfo.value.items.map(item => {
926 if (item.field == 'productImg') {
927 item.default = row ? (row.demandPic?[row.demandPic] : row[item.field] || []) : []
928 } else if (item.field == 'isDiscussPersonally') {
929 item.default = row ? row[item.field] : 'Y'
930 item.children.map(child => {
931 child.default = row ? row[child.field] : child.default;
932 child.visible = item.default == 'N'
933 })
934 } else if(item.field == 'isApproveGrounding') {
935 item.default = row ? row[item.field] : 'Y'
936 } else {
937 item.default = row ? row[item.field] : (item.default || '')
938 }
939 })
940 }
941
942 const checkboxChange = async (val, info, row) => {
943 if(row.field == 'isDiscussPersonally'){
944 let formItem = formInfo.value.items.find(i => i.field == 'isDiscussPersonally');
945 if (formItem) {
946 formItem.default = info.isDiscussPersonally;
947 formItem.children[0].visible = info.isDiscussPersonally != 'Y';
948 await setFormItems(info);
949 }
950 }
951 }
952
953 const switchChange = async (val, info, row) => {
954 if(row.field == 'isApproveGrounding') {
955 let formItem = formInfo.value.items.find(i => i.field == 'autoGrounding');
956 if (formItem) {
957 formItem.children[0].default = val;
958 setFormItems(info);
959 }
960 }
961 }
962
963 /** 用于保留下拉框切换之后的值 */
964 let oldOriginValue = ref({});
965
966 const processDemanTypeChange = (val) => {
967 if (val == 'DAM-TYPE') {
968 demandFormItems.value[3].visible = true;
969 demandFormItems.value[4].visible = false;
970 demandFormItems.value[5].visible = false;
971 demandFormItems.value[6].visible = true;
972 } else if (val == 'DATA_SERVICE_DETAIL') {
973 demandFormItems.value[3].visible = false;
974 demandFormItems.value[4].visible = true;
975 demandFormItems.value[5].visible = false;
976 demandFormItems.value[6].visible = false;
977 } else if (val == 'PROJECT_DETAIL') {
978 demandFormItems.value[3].visible = false;
979 demandFormItems.value[4].visible = false;
980 demandFormItems.value[5].visible = true;
981 demandFormItems.value[6].visible = false;
982 }
983 formInfo.value.items = demandFormItems.value;
984 }
985
986 const handleSelectChange = (val, info, row) => {
987 if (info.field == 'demandType') {
988 processDemanTypeChange(val);
989 let newInfo = Object.assign({}, oldOriginValue.value, row);
990 oldOriginValue.value = { ...newInfo };
991 setFormItems(newInfo);
992 }
993 }
994
995 const dialogBtnClick = (btn, info) => {
996 if (btn.value == 'submit') {
997 let params = { ...info }
998 params.bizGuid = guid
999 params.funcCode = flowDetail.value.funcCode;
1000 if (dialogInfo.value.type == 'pass') {
1001 dialogInfo.value.visible = false;
1002 registerApproveAllow(params).then((res: any) => {
1003 if (res.code == proxy.$passCode) {
1004 ElMessage({
1005 type: 'success',
1006 message: '审批成功'
1007 })
1008 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
1009 assetStore.set(true);
1010 router.push({
1011 name: "productDemandsCheck",
1012 query: {},
1013 });
1014 } else {
1015 ElMessage({
1016 type: 'error',
1017 message: res.msg,
1018 })
1019 }
1020 }).catch(() => {
1021 })
1022 } else if (dialogInfo.value.type == 'reject') {
1023 if (info.approveSuggest == '') {
1024 ElMessage.error('请填写驳回原因')
1025 return
1026 }
1027 dialogInfo.value.visible = false;
1028 registerApproveBackup(params).then((res: any) => {
1029 if (res.code == proxy.$passCode) {
1030 ElMessage({
1031 type: 'success',
1032 message: '驳回成功'
1033 })
1034 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
1035 assetStore.set(true);
1036 router.push({
1037 name: "productDemandsCheck",
1038 query: {},
1039 });
1040 } else {
1041 ElMessage({
1042 type: 'error',
1043 message: res.msg,
1044 })
1045 }
1046 }).catch(() => {
1047
1048 })
1049 }
1050 } else if (btn.value == 'cancel') {
1051 nextTick(() => {
1052 dialogInfo.value.visible = false;
1053 })
1054 }
1055 };
1056
1057 onActivated(() => {
1058 let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath);
1059 if (tab) {
1060 switch(detailType){
1061 case 'add':
1062 tab.meta.title = `新建数据需求${route.query.interfaceType == '2' ? '(算法竞赛)' : (route.query.interfaceType == '3' ? '(要素市场)' : '')}`;
1063 break;
1064 case 'edit':
1065 tab.meta.title = `编辑-${damName}`;
1066 break;
1067 case 'check':
1068 tab.meta.title = `详情-${damName}`;
1069 break;
1070 case 'detail':
1071 tab.meta.title = `详情-${damName}`;
1072 break;
1073 }
1074 }
1075 })
1076
1077 const initMethodByInterfaceType = ref({
1078 '1': () => {
1079 getParamsDataList({ paramCode: 'DEMAND_TYPE' }).then((res: any) => {
1080 if (res.code == proxy.$passCode) {
1081 demandTypes.value = res.data || [];
1082 let item = demandFormItems.value.find(item => item.field == 'demandType');
1083 item && (item.options = demandTypes.value);
1084 } else {
1085 proxy.$ElMessage.error(res.msg);
1086 }
1087 })
1088 getParamsDataList({ paramCode: 'DAM-TYPE' }).then((res: any) => {
1089 if (res.code == proxy.$passCode) {
1090 damTypes.value = res.data || [];
1091 let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-type');
1092 item && (item.options = damTypes.value);
1093 } else {
1094 proxy.$ElMessage.error(res.msg);
1095 }
1096 })
1097 getParamsDataList({ paramCode: 'DATA_SERVICE_DETAIL' }).then((res: any) => {
1098 if (res.code == proxy.$passCode) {
1099 dataServiceDetails.value = res.data || [];
1100 let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-service');
1101 item && (item.options = dataServiceDetails.value);
1102 } else {
1103 proxy.$ElMessage.error(res.msg);
1104 }
1105 })
1106 getParamsDataList({ paramCode: 'PROJECT_DETAIL' }).then((res: any) => {
1107 if (res.code == proxy.$passCode) {
1108 projectDetails.value = res.data || [];
1109 let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-project');
1110 item && (item.options = projectDetails.value);
1111 } else {
1112 proxy.$ElMessage.error(res.msg);
1113 }
1114 })
1115 getParamsList({dictType: 'SUBJECT-DOMAIN'}).then((res: any) => {
1116 if (res.code == proxy.$passCode) {
1117 subjectDomainListData.value = res.data || [];
1118 let item = demandFormItems.value.find(item => item.field == 'subjectDomain');
1119 item && (item.options = subjectDomainListData.value);
1120 } else {
1121 proxy.$ElMessage.error(res.msg);
1122 }
1123 })
1124 demandFormItems.value[0].default = '1';
1125 formInfo.value.items = demandFormItems.value;
1126 formInfo.value.rules = demandRules.value
1127 },
1128 '2': () => {
1129 getParamsDataList({ paramCode: 'COMPETITION_TYPE' }).then((res: any) => {
1130 if (res.code == proxy.$passCode) {
1131 projectDetails.value = res.data || [];
1132 let item = algorithmFormItem.value.find(item => item.field == 'competitionType');
1133 item && (item.options = projectDetails.value);
1134 } else {
1135 proxy.$ElMessage.error(res.msg);
1136 }
1137 })
1138 formInfo.value.items = algorithmFormItem.value;
1139 formInfo.value.rules = algorithmFormRules.value
1140 },
1141 '3': () => {
1142 getProductTypeList().then((res: any) => {
1143 if (res.code == proxy.$passCode) {
1144 productTypes.value = res.data || [];
1145 let item = elementFormItems.value.find(item => item.field == 'productType');
1146 item && (item.options = productTypes.value);
1147 } else {
1148 proxy.$ElMessage.error(res.msg);
1149 }
1150 })
1151 getParamsDataList({ paramCode: 'DELIVERY-WAY' }).then((res: any) => {
1152 if (res.code == proxy.$passCode) {
1153 deliveryWayList.value = res.data || [];
1154 let item = elementFormItems.value.find(item => item.field == 'deliveryWay');
1155 item && (item.options = deliveryWayList.value);
1156 } else {
1157 proxy.$ElMessage.error(res.msg);
1158 }
1159 })
1160 formInfo.value.items = elementFormItems.value;
1161 formInfo.value.rules = elementFormRules.value
1162 }
1163 });
1164
1165 onBeforeMount(() => {
1166 if(detailType && detailType != 'add'){
1167 getProductDetail();
1168 if (detailType == 'detail' && dGuid !== undefined) {
1169 getApplyDeatil();
1170 }
1171 }
1172 getApproveData();
1173 getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
1174 if (res.code == proxy.$passCode) {
1175 interfaceTypes.value = res.data || [];
1176 let item = demandFormItems.value[0];
1177 item && (item.options = interfaceTypes.value);
1178 algorithmFormItem.value[0].options = interfaceTypes.value;
1179 elementFormItems.value[0].options = interfaceTypes.value;
1180 } else {
1181 proxy.$ElMessage.error(res.msg);
1182 }
1183 })
1184 if (detailType == 'add' || detailType == 'edit') {
1185 let interfaceType = route.query.interfaceType;
1186 if (interfaceType == '1') {
1187 initMethodByInterfaceType.value['1']();
1188 } else if (interfaceType == '2') {
1189 initMethodByInterfaceType.value['2']();
1190 } else {
1191 initMethodByInterfaceType.value['3']();
1192 }
1193 }
1194 })
1195 </script>
1196
1197 <template>
1198 <div class="container_wrap" v-loading="flowDetailLoading">
1199 <div class="content_main">
1200 <div v-if="detailType == 'check'"
1201 :class="['panel_wrap', 'results_panel', flowDetail.approveState == 'Y' ? 'success' : (flowDetail.approveState == 'R' ? 'reject' : (flowDetail.approveState == 'C' ? 'revoke' : 'audit'))]">
1202 <div class="panel_header">
1203 <div class="header_title" v-if="flowDetail.approveState == 'Y'">
1204 <el-icon class="title-icon">
1205 <svg-icon name="icon-success" />
1206 </el-icon>
1207 <span class="title_text">审批通过</span>
1208 </div>
1209 <div class="header_title" v-else-if="flowDetail.approveState == 'R'">
1210 <el-icon class="title-icon">
1211 <CircleCloseFilled />
1212 </el-icon>
1213 <span class="title_text">审批被驳回</span>
1214 </div>
1215 <div class="header_title" v-else-if="flowDetail.approveState == 'A'">
1216 <el-icon class="title-icon">
1217 <svg-icon name="icon-audit" />
1218 </el-icon>
1219 <span class="title_text">待审批</span>
1220 </div>
1221 <div class="header_title" v-else-if="flowDetail.approveState == 'C'">
1222 <el-icon class="title-icon">
1223 <svg-icon name="icon-revoke" />
1224 </el-icon>
1225 <span class="title_text">已撤销</span>
1226 </div>
1227 </div>
1228 <div class="panel_body" v-if="flowDetail.approveState != 'A' && flowDetail.approveState != 'C'">
1229 <div class="results_list">
1230 <div class="list_item">
1231 <span class="item_label">审批人:</span>
1232 <span class="item_value">{{ approveTableInfo.data.at(-1)?.approvedTenantName || '--' }}</span>
1233 </div>
1234 <div class="list_item">
1235 <span class="item_label">审批时间:</span>
1236 <span class="item_value">{{ approveTableInfo.data.at(-1)?.approveTime || '--' }}</span>
1237 </div>
1238 <div class="list_item" v-if="flowDetail.approveState == 'R'">
1239 <span class="item_label">审批意见:</span>
1240 <span class="item_value">{{ approveTableInfo.data.at(-1)?.approveSuggest || '--' }}</span>
1241 </div>
1242 </div>
1243 </div>
1244 </div>
1245 <div class="panel_wrap">
1246 <div class="panel_header">
1247 <div class="header_title">
1248 <span class="title_text">
1249 <span>数据需求信息</span>
1250 </span>
1251 </div>
1252 </div>
1253 <div class="panel_body" :class="{collapse: collapseIcon}">
1254 <div class="list_panel" v-if="detailType == 'add' || detailType == 'edit'">
1255 <Form ref="listingFormRef" :itemList="formInfo.items" :formId="formInfo.id" :rules="formInfo.rules"
1256 :col="formInfo.col" @checkboxChange="checkboxChange" @switchChange="switchChange" @selectChange="handleSelectChange" />
1257 </div>
1258 <div class="list_panel" v-else>
1259 <div class="list_item">
1260 <span class="item_label">界面类型:</span>
1261 <span class="item_value">{{ flowDetail.interfaceTypeName || '--' }}</span>
1262 </div>
1263 <div class="list_item">
1264 <span class="item_label">数据需求名称:</span>
1265 <span class="item_value"><ellipsis-tooltip :content="flowDetail.dataName || '--'"
1266 class-name="w100f" :refName="'tooltipOver' + 'dataName'"></ellipsis-tooltip></span>
1267 </div>
1268 <template v-if="flowDetail.interfaceType == '1'">
1269 <div class="list_item" >
1270 <span class="item_label">需求类型:</span>
1271 <span class="item_value">{{ flowDetail.demandTypeName || '--' }}</span>
1272 </div>
1273 <template v-if="flowDetail.demandType == 'DAM-TYPE'">
1274 <div class="list_item">
1275 <span class="item_label">数据类型:</span>
1276 <span class="item_value">{{ flowDetail.demandTypeDetailName || '--' }}</span>
1277 </div>
1278 <div class="list_item">
1279 <span class="item_label">所属主题:</span>
1280 <span class="item_value">{{ flowDetail.subjectDomainName || '--' }}</span>
1281 </div>
1282 </template>
1283 <div v-else class="list_item">
1284 <span class="item_label">{{ flowDetail.demandType == 'DATA_SERVICE_DETAIL' ? '数据服务:' : '项目:' }} </span>
1285 <span class="item_value">{{ flowDetail.demandTypeDetailName || '--' }}</span>
1286 </div>
1287 </template>
1288 <template v-if="flowDetail.interfaceType == '2'">
1289 <div class="list_item">
1290 <span class="item_label">竞赛类型:</span>
1291 <span class="item_value">{{ flowDetail.competitionTypeName || '--' }}</span>
1292 </div>
1293 <div class="list_item">
1294 <span class="item_label">奖金(元):</span>
1295 <span class="item_value">{{ changeNum(flowDetail.bonus, 2) || '--' }}</span>
1296 </div>
1297 <div class="list_item">
1298 <span class="item_label">报名截止日:</span>
1299 <span class="item_value">{{ flowDetail.signupEndDate || '--' }}</span>
1300 </div>
1301 <div class="list_item">
1302 <span class="item_label">举办方:</span>
1303 <span class="item_value">{{ flowDetail.organizer || '--' }}</span>
1304 </div>
1305 </template>
1306 <template v-if="flowDetail.interfaceType == '3'">
1307 <div class="list_item">
1308 <span class="item_label">产品类别:</span>
1309 <span class="item_value">{{ flowDetail.productTypeName || '--' }}</span>
1310 </div>
1311 <div class="list_item">
1312 <span class="item_label">交付方式:</span>
1313 <span class="item_value">{{ flowDetail.deliveryWayName || '--' }}</span>
1314 </div>
1315 </template>
1316 <div class="list_item" v-if="flowDetail.interfaceType != '2'">
1317 <span class="item_label">产品预算:</span>
1318 <span class="item_value">{{ flowDetail.isDiscussPersonally == 'Y'?'面议':(flowDetail.productPrice || '--') }}</span>
1319 </div>
1320 <div class="list_item">
1321 <span class="item_label">审核后上架:</span>
1322 <span class="item_value">{{ flowDetail.isApproveGrounding == 'Y'?`自动上架` : '手动上架' }}</span>
1323 </div>
1324 <div class="list_item is_block">
1325 <div class="file_item" v-if="flowDetail.demandPic && flowDetail.demandPic.name">
1326 <span class="item_label">{{ flowDetail.interfaceType == '3' ? '产品图片:' : (flowDetail.interfaceType == '2' ? '赛事图片' : '需求图片') }}</span>
1327 <span class="item_value">
1328 <div class="file-operate">
1329 <template
1330 v-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'xls' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'xlsx' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'csv'">
1331 <img class="file-img" src="../../assets/images/excel.png" />
1332 </template>
1333 <template
1334 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
1335 <img class="file-img" src="../../assets/images/word.png" />
1336 </template>
1337 <template
1338 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
1339 <img class="file-img" src="../../assets/images/zip.png" />
1340 </template>
1341 <template
1342 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
1343 <img class="file-img" src="../../assets/images/RAR.png" />
1344 </template>
1345 <template
1346 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
1347 <img class="file-img" src="../../assets/images/PDF.png" />
1348 </template>
1349 <template
1350 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
1351 <img class="file-img" src="../../assets/images/png.png" />
1352 </template>
1353 <template
1354 v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
1355 <img class="file-img" src="../../assets/images/jpg.png" />
1356 </template>
1357 <div class="file-name">{{ flowDetail.demandPic.name }}</div>
1358 <div :style="{ right: '36px' }"
1359 v-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'png' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'"
1360 class="file-preview" @click="onUploadFilePreview(flowDetail.demandPic)">查看</div>
1361 <div :style="{ right: '0px' }" class="file-preview"
1362 @click="onUploadFileDownload(flowDetail.demandPic)">下载</div>
1363 </div>
1364 </span>
1365 </div>
1366 </div>
1367 </div>
1368 </div>
1369 </div>
1370 <div class="panel_wrap" v-if="(detailType == 'detail' || detailType == 'check') && (flowDetail.content || flowDetail.demandDesc)">
1371 <div class="panel_header">
1372 <div class="header_title">
1373 <span class="title_text">
1374 <span>{{ flowDetail.interfaceType == '2' ? '赛事描述' : (flowDetail.interfaceType == '3' ? '产品描述' : '需求描述')}}</span>
1375 </span>
1376 </div>
1377 </div>
1378 <div class="panel_body" >
1379 <div class="list_panel">
1380 <div class="list_item is_block">
1381 <span class="item_value" style="padding: 0px" v-html="flowDetail.content || flowDetail.demandDesc || '--'"></span>
1382 </div>
1383 </div>
1384 </div>
1385 </div>
1386 <div class="panel_wrap" v-if="!dGuid">
1387 <div class="panel_header">
1388 <div class="header_title">
1389 <span class="title_text">
1390 <span>审批信息</span>
1391 </span>
1392 </div>
1393 </div>
1394 <div class="panel_body" :class="{collapse: collapseIcon1}">
1395 <div class="list_panel">
1396 <div class="table_panel_wrap">
1397 <Table :tableInfo="approveTableInfo" />
1398 </div>
1399 </div>
1400 </div>
1401 </div>
1402 <div class="panel_wrap" v-if="detailType == 'detail' && dGuid !== undefined">
1403 <div class="panel_header">
1404 <div class="header_title">
1405 <span class="title_text">
1406 <span>申请信息</span>
1407 </span>
1408 </div>
1409 </div>
1410 <div class="panel_body" :class="{ collapse: collapseIcon2 }">
1411 <div class="list_panel">
1412 <div class="list_item">
1413 <span class="item_label">申请人姓名:</span>
1414 <span class="item_value">{{ applyDetail.buyerContact || '--' }}</span>
1415 </div>
1416 <div class="list_item">
1417 <span class="item_label">所在企业:</span>
1418 <span class="item_value"><ellipsis-tooltip :content="applyDetail.buyer ?? '--'" class-name="w100f"
1419 :refName="'tooltipOver' + 'releaseAgency'"></ellipsis-tooltip></span>
1420 </div>
1421 <div class="list_item">
1422 <span class="item_label">联系方式:</span>
1423 <span class="item_value">{{ applyDetail.buyerContactTel || '--' }}</span>
1424 </div>
1425 <div class="list_item is_block">
1426 <span class="item_label">申请事由:</span>
1427 <span class="item_value">{{ applyDetail.buyerRemark || '--' }}</span>
1428 </div>
1429 </div>
1430 </div>
1431 </div>
1432 </div>
1433 <div class="tool_btns" v-if="detailType == 'add' || detailType == 'edit'">
1434 <div class="btns">
1435 <el-button @click="btnClick({ value: 'cancel' })">取消</el-button>
1436 <el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button>
1437 </div>
1438 </div>
1439 <div class="tool_btns" v-else-if="detailType == 'check'">
1440 <div class="btns">
1441 <el-button plain @click="btnClick({ value: 'cancel' })">关闭</el-button>
1442 <el-button type="primary" @click="btnClick({ value: 'pass' })" v-if="flowDetail.approveState == 'A' && flowDetail.approveTenantGuids?.includes(userData.tenantGuid)">通过</el-button>
1443 <el-button plain type="danger" @click="btnClick({ value: 'reject' })" v-if="flowDetail.approveState == 'A' && flowDetail.approveTenantGuids?.includes(userData.tenantGuid)">驳回</el-button>
1444 </div>
1445 </div>
1446
1447 <!-- 审核对话框 -->
1448 <Dialog ref="listingDialogRef" :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" />
1449 </div>
1450 </template>
1451
1452 <style lang="scss" scoped>
1453 .container_wrap {
1454 padding: 0;
1455 height: 100%;
1456 overflow: hidden;
1457
1458 &>.content_main {
1459 padding: 16px;
1460 height: calc(100% - 44px);
1461 overflow: hidden auto;
1462
1463 &.full {
1464 height: 100%;
1465 }
1466 }
1467 }
1468
1469 .panel_wrap {
1470 .panel_header {
1471 .header_title {
1472 height: 40px;
1473 padding: 0 16px;
1474 background-color: #fafafa;
1475 box-shadow: 0 0 0 1px #e5e5e5;
1476 display: flex;
1477 align-items: center;
1478 }
1479
1480 .title_text {
1481 line-height: 22px;
1482 font-size: 14px;
1483 color: var(--el-color-regular);
1484 font-weight: 600;
1485 display: flex;
1486 align-items: center;
1487
1488 .title_icon {
1489 width: 26px;
1490 height: 21px;
1491 margin-right: 4px;
1492 cursor: pointer;
1493
1494 &.active {
1495 transform: rotate(90deg);
1496 }
1497 }
1498 }
1499 }
1500
1501 .panel_body {
1502 padding: 8px 16px;
1503 box-shadow: 0 0 0 1px rgba(229, 229, 229, 1);
1504 border-top: none;
1505 margin-top: 1px;
1506
1507 .list_panel {
1508 display: flex;
1509 flex-wrap: wrap;
1510
1511 .list_item {
1512 width: 33.33%;
1513 line-height: 32px;
1514 font-size: 14px;
1515 color: #666666;
1516 display: flex;
1517 justify-content: space-between;
1518
1519 .item_label {
1520 width: 100px;
1521 text-align: right;
1522 }
1523
1524 .file_item {
1525 width: 50%;
1526 display: flex;
1527 justify-content: space-between;
1528 }
1529
1530 .item_value {
1531 color: var(--el-color-regular);
1532 padding: 0 16px;
1533 flex: 1;
1534 text-align: justify;
1535 min-width: 0;
1536
1537 .file-operate {
1538 display: flex;
1539 align-items: center;
1540 position: relative;
1541
1542 .file-img {
1543 width: 24px;
1544 height: 24px;
1545 }
1546
1547 &:hover {
1548 background-color: #f5f5f5;
1549 }
1550
1551 .file-name {
1552 color: var(--el-color-regular);
1553 margin-left: 4px;
1554 }
1555
1556 .file-preview {
1557 position: absolute;
1558 cursor: pointer;
1559 color: var(--el-color-primary);
1560 margin-right: 8px;
1561 }
1562 }
1563
1564 .area_text +.area_text{
1565 &::before {
1566 content: '、',
1567 }
1568 }
1569 }
1570
1571 &.is_block {
1572 width: 100%;
1573 .item_value {
1574 white-space: pre-wrap;
1575 }
1576 }
1577 }
1578
1579 :deep(.el-form) {
1580 width: 100%;
1581 }
1582
1583 :deep(.panel_body) {
1584 box-shadow: none;
1585 }
1586
1587 &.label_auto {
1588 .list_item {
1589 .item_label {
1590 width: auto;
1591 }
1592
1593 .item_value {
1594 padding-left: 0;
1595 }
1596 }
1597 }
1598 }
1599
1600 .table_panel_wrap {
1601 .table_panel {
1602 padding: 0;
1603 min-height: unset;
1604 }
1605 }
1606
1607 .process_panel {
1608 height: 500px;
1609
1610 .iframe-sty {
1611 width: 100%;
1612 height: 100%;
1613 border: none;
1614 }
1615
1616 :deep(.property-panel) {
1617 height: calc(100% - 50px) !important;
1618 }
1619 }
1620
1621 &.collapse {
1622 height: 0;
1623 padding: 0;
1624 overflow: hidden;
1625 }
1626 }
1627
1628 +.panel_wrap {
1629 margin-top: 16px;
1630 }
1631
1632 &.results_panel {
1633 box-shadow: 0 0 0 1px #d9d9d9;
1634
1635 .panel_header {
1636 .header_title {
1637 background-color: transparent;
1638 box-shadow: none;
1639
1640 .el-icon {
1641 margin-right: 8px;
1642 width: 20px;
1643 height: 20px;
1644
1645 svg {
1646 width: 100%;
1647 height: 100%;
1648 }
1649 }
1650 }
1651 }
1652
1653 .panel_body {
1654 padding-top: 0;
1655 margin-top: 0;
1656 box-shadow: none;
1657
1658 .results_list {
1659 display: flex;
1660
1661 .list_item {
1662 display: flex;
1663 margin-bottom: 8px;
1664 margin-right: 60px;
1665 color: #666;
1666
1667 .item_value {
1668 padding: 0 8px;
1669 color: var(--el-color-regular);
1670 }
1671 }
1672 }
1673 }
1674
1675 &.success {
1676 background-color: #F4FEF6;
1677 box-shadow: 0 0 0 1px #4FA55D;
1678
1679 .panel_header {
1680 .header_title {
1681 .el-icon {
1682 color: #4FA55D;
1683 }
1684 }
1685 }
1686 }
1687
1688 &.reject {
1689 background-color: #FDF2F4;
1690 box-shadow: 0 0 0 1px #E63E33;
1691
1692 .panel_header {
1693 .header_title {
1694 .el-icon {
1695 color: #E63E33;
1696 }
1697 }
1698 }
1699 }
1700
1701 &.audit {
1702 background-color: #FEFBF3;
1703 box-shadow: 0 0 0 1px #F19E40;
1704
1705 .panel_header {
1706 .header_title {
1707 .el-icon {
1708 color: #F19E40;
1709 }
1710 }
1711 }
1712 }
1713
1714 &.revoke {
1715 background-color: #F5F5F5;
1716 box-shadow: 0 0 0 1px #CCCCCC;
1717
1718 .panel_header {
1719 .header_title {
1720 .el-icon {
1721 color: #666666;
1722 }
1723 }
1724 }
1725 }
1726 }
1727 }
1728
1729 .tool_btns {
1730 display: flex;
1731 justify-content: center;
1732 align-items: center;
1733 height: 44px;
1734 padding: 0 16px;
1735 border-top: 1px solid #d9d9d9;
1736 }
1737
1738 :deep(.list_panel) {
1739 .list_item .item_value {
1740 p {
1741 margin: 0px;
1742 }
1743
1744 img {
1745 max-width: 100%;
1746 }
1747 }
1748 }
1749 </style>
1 <route lang="yaml">
2 name: productDemandsPublish
3 </route>
4
5 <script lang="ts" setup name="productDemandsPublish">
6 import { ref, onMounted } from "vue";
7 import { useRouter, useRoute } from "vue-router";
8 import useUserStore from "@/store/modules/user";
9 import { ElMessage, ElMessageBox } from "element-plus";
10 import useDataAssetStore from "@/store/modules/dataAsset";
11 import { changeNum } from "@/utils/common";
12 import { getDemandList, demandDelete, demandUpdateStatus, filterVal, getParamsDataList } from "@/api/modules/dataProduct";
13 import { TableColumnWidth } from '@/utils/enum';
14
15 import TableTools from "@/components/Tools/table_tools.vue";
16 import Table from "@/components/Table/index.vue";
17
18 const { proxy } = getCurrentInstance() as any;
19 const router = useRouter();
20 const assetStore = useDataAssetStore();
21 const interfaceTypes = ref([]);
22 const searchItemList: any = ref([
23 {
24 type: "input",
25 label: "",
26 field: "dataName",
27 default: "",
28 placeholder: "需求名称",
29 clearable: true
30 },
31 {
32 type: "select",
33 label: "",
34 field: "interfaceType",
35 default: "",
36 props: {
37 value: 'paramValue',
38 label: 'paramName'
39 },
40 placeholder: "界面类型",
41 options: interfaceTypes.value,
42 clearable: true,
43 }
44 ]);
45 const page = ref({
46 limit: 50,
47 curr: 1,
48 sizes: [
49 { label: "10", value: 10 },
50 { label: "50", value: 50 },
51 { label: "100", value: 100 },
52 { label: "150", value: 150 },
53 { label: "200", value: 200 },
54 ],
55 });
56 const searchItemValue: any = ref({});
57 const currTableData: any = ref({});
58 const tableInfo = ref({
59 id: "mapping-table",
60 fields: [
61 { label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
62 { label: "数据需求名称", field: "dataName", width: 200 },
63 {
64 label: "界面类型", field: "interfaceTypeName", width: 140
65 },
66 { label: "产品预算", field: "productPrice", width: 120, },
67 {
68 label: "审核状态", field: "approveState", width: TableColumnWidth.STATE, align: 'center', type: "tag", getName: (scope) => {
69 return filterVal(scope.row.approveState, 'approveState');
70 }
71 },
72 {
73 label: '上架状态', field: 'listingStatus', type: 'switch', activeValue: 'Y', inactiveValue: 'N', switchWidth: 28, width: 96, align: 'center', isDisabled: (scope) => {
74 return scope.row.approveState != 'Y';
75 }
76 },
77 { label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
78 ],
79 loading: false,
80 data: [],
81 page: {
82 type: "normal",
83 rows: 0,
84 ...page.value,
85 },
86 actionInfo: {
87 label: "操作",
88 type: "btn",
89 width: 140,
90 btns: (scope) => {
91 let row = scope.row, btnArr: any = [];
92 if(row.approveState == 'Y'){
93 if(row.listingStatus == 'Y'){
94 btnArr.splice(0, 0, { label: "详情", value: "detail" });
95 } else {
96 btnArr.splice(0, 0, { label: "编辑", value: "edit" }, { label: "详情", value: "detail" }, { label: "删除", value: "delete" });
97 }
98 } else {
99 if(row.approveState == 'A'){
100 btnArr.splice(0, 0, { label: "详情", value: "detail" });
101 } else {
102 btnArr.splice(0, 0, { label: "编辑", value: "edit" }, { label: "详情", value: "detail" }, { label: "删除", value: "delete" });
103 }
104 }
105 return btnArr;
106 },
107 },
108 });
109
110 const getTableData = () => {
111 tableInfo.value.loading = true;
112 getDemandList(
113 Object.assign({}, searchItemValue.value, {
114 pageIndex: page.value.curr,
115 pageSize: page.value.limit,
116 })
117 )
118 .then((res: any) => {
119 tableInfo.value.loading = false;
120 tableInfo.value.data = res.data.records || [];
121 tableInfo.value.page.curr = res.data.pageIndex;
122 tableInfo.value.page.limit = res.data.pageSize;
123 tableInfo.value.page.rows = res.data.totalRows;
124 })
125 .catch((res) => {
126 tableInfo.value.loading = false;
127 });
128 };
129
130 /** 搜索同步任务列表 */
131 const toSearch = (val: any, clear: boolean = false) => {
132 if (clear) {
133 searchItemList.value.map((item) => (item.default = ""));
134 searchItemValue.value = {};
135 } else {
136 searchItemValue.value = Object.keys(val).length ? { ...val } : {};
137 }
138 page.value.curr = 1;
139 tableInfo.value.page.curr = 1;
140 getTableData();
141 };
142
143 const tableSwitchBeforeChange = (scope, field, callback) => {
144 const msg = `确定${scope.row[field] == 'Y'?'下架':'上架'}该需求吗?`
145 ElMessageBox.confirm(
146 msg,
147 '提示',
148 {
149 confirmButtonText: '确定',
150 cancelButtonText: '取消',
151 type: 'warning',
152 }
153 ).then(() => {
154 const state = scope.row[field] == 'Y'?'N':'Y';
155 const result = tableSwitchChange(state, scope, field)
156 callback(result)
157 }).catch(() => {
158 callback(false)
159 })
160 }
161
162 const tableSwitchChange = (val, scope, field) => {
163 return new Promise((resolve, reject) => {
164 let params = {
165 guid: scope.row.guid,
166 listingStatus: val
167 }
168 demandUpdateStatus(params).then((res: any) => {
169 if (res.code == proxy.$passCode && res.data) {
170 getFirstPageData();
171 ElMessage({
172 type: "success",
173 message: `该产品${val == 'Y' ? '上架' : '下架'}成功`,
174 });
175 resolve(true)
176 } else {
177 ElMessage({
178 type: "error",
179 message: res.msg,
180 });
181 getTableData();
182 reject(false)
183 }
184 }).catch(() => {
185 getTableData();
186 reject(false)
187 })
188 })
189 }
190
191 const tableBtnClick = (scope, btn) => {
192 const type = btn.value;
193 const row = scope.row;
194 currTableData.value = row;
195 if (type == "detail" || type === "edit") {
196 router.push({
197 name: "productDemandsDetail",
198 query: {
199 guid: currTableData.value.guid,
200 name: currTableData.value.dataName,
201 type
202 },
203 });
204 } else if (type === "delete") {
205 open("此操作将永久删除,是否继续?", "warning");
206 }
207 };
208
209 const handleCreateCommand = (command) => {
210 router.push({
211 name: "productDemandsDetail",
212 query: {
213 type: 'add',
214 interfaceType: command
215 },
216 });
217 }
218
219 const tablePageChange = (info) => {
220 page.value.curr = Number(info.curr);
221 page.value.limit = Number(info.limit);
222 tableInfo.value.page.limit = page.value.limit;
223 tableInfo.value.page.curr = page.value.curr;
224 getTableData();
225 };
226
227 const open = (msg, type, isBatch = false) => {
228 ElMessageBox.confirm(msg, "提示", {
229 confirmButtonText: "确定",
230 cancelButtonText: "取消",
231 type: type,
232 }).then(() => {
233 const guids = [currTableData.value.guid];
234 demandDelete(guids).then((res: any) => {
235 if (res.code == proxy.$passCode) {
236 getFirstPageData();
237 ElMessage({
238 type: "success",
239 message: "删除成功",
240 });
241 } else {
242 ElMessage({
243 type: "error",
244 message: res.msg,
245 });
246 }
247 }).catch((res) => {
248 tableInfo.value.loading = false;
249 });
250 });
251 };
252
253 const getFirstPageData = () => {
254 page.value.curr = 1
255 tableInfo.value.page.curr = 1;
256 getTableData();
257 }
258
259 onActivated(() => {
260 if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
261 getFirstPageData();
262 assetStore.set(false);
263 }
264 })
265
266 onBeforeMount(() => {
267 getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
268 if (res.code == proxy.$passCode) {
269 interfaceTypes.value = res.data || [];
270 let item = searchItemList.value.find(item => item.field == 'interfaceType');
271 item && (item.options = interfaceTypes.value);
272 } else {
273 proxy.$ElMessage.error(res.msg);
274 }
275 })
276 })
277
278 </script>
279
280 <template>
281 <div class="container_wrap">
282 <div class="table_tool_wrap">
283 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
284 <div class="tools_btns">
285 <el-dropdown popper-class="table-create-menu-noicon" @command="handleCreateCommand" placement="bottom-start"
286 trigger="click">
287 <span class="el-dropdown-link">
288 <el-button type="primary" >新建</el-button>
289 </span>
290 <template #dropdown>
291 <el-dropdown-menu>
292 <el-dropdown-item command="1">
293 <div class="item-content">
294 <span class="item-content-title">数据需求</span>
295 </div>
296 </el-dropdown-item>
297 </el-dropdown-menu>
298 <el-dropdown-menu>
299 <el-dropdown-item command="2">
300 <div class="item-content">
301 <span class="item-content-title">算法竞赛</span>
302 </div>
303 </el-dropdown-item>
304 </el-dropdown-menu>
305 <el-dropdown-menu>
306 <el-dropdown-item command="3">
307 <div class="item-content">
308 <span class="item-content-title">要素市场</span>
309 </div>
310 </el-dropdown-item>
311 </el-dropdown-menu>
312 </template>
313 </el-dropdown>
314 </div>
315 </div>
316 <div class="table_panel_wrap">
317 <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" @tableSwitchBeforeChange="tableSwitchBeforeChange" />
318 </div>
319 </div>
320 </template>
321
322 <style scoped lang="scss">
323 .table_tool_wrap {
324 width: 100%;
325 height: 84px !important;
326 padding: 0 8px;
327
328 .tools_btns {
329 padding: 0px 0 0;
330 }
331 }
332
333 .table_panel_wrap {
334 width: 100%;
335 height: calc(100% - 84px);
336 padding: 0px 8px 0;
337 }
338 </style>
...@@ -19,7 +19,6 @@ import { ...@@ -19,7 +19,6 @@ import {
19 getProductList, getFileByDamGuid, productRejectFlowData, 19 getProductList, getFileByDamGuid, productRejectFlowData,
20 getListingDetail, listingSave, listingUpdate, listingSavePortal, getParamsDataList, listingUpdateGateway, getDataExchangeProductList, getTemplateFile, getListingList 20 getListingDetail, listingSave, listingUpdate, listingSavePortal, getParamsDataList, listingUpdateGateway, getDataExchangeProductList, getTemplateFile, getListingList
21 } from "@/api/modules/dataProduct"; 21 } from "@/api/modules/dataProduct";
22 import { getMatchDetail } from "@/api/modules/dataFinance";
23 import { useValidator } from '@/hooks/useValidator'; 22 import { useValidator } from '@/hooks/useValidator';
24 import { getCamundaDeploymentId, rejectFlowData, passFlowData, isMyFirstNode, revokeFlowData } from "@/api/modules/workFlowService"; 23 import { getCamundaDeploymentId, rejectFlowData, passFlowData, isMyFirstNode, revokeFlowData } from "@/api/modules/workFlowService";
25 24
...@@ -769,26 +768,6 @@ const getApproveData = () => { ...@@ -769,26 +768,6 @@ const getApproveData = () => {
769 } 768 }
770 769
771 770
772 // 获取申请信息
773 const getApplyDeatil = () => {
774 getMatchDetail({ guid: dGuid }).then((res: any) => {
775 if (res.code == proxy.$passCode) {
776 const data = res.data || [];
777 applyDetail.value = data;
778 } else {
779 ElMessage({
780 type: "error",
781 message: res.msg,
782 });
783 }
784 }).catch((res) => {
785 ElMessage({
786 type: "error",
787 message: '获取申请信息失败',
788 });
789 });
790 }
791
792 const submitForm = (btn, formEl, tosub = false) => { 771 const submitForm = (btn, formEl, tosub = false) => {
793 if (!formEl) return; 772 if (!formEl) return;
794 formEl.validate((valid, fields) => { 773 formEl.validate((valid, fields) => {
......
...@@ -27,7 +27,7 @@ import { ...@@ -27,7 +27,7 @@ import {
27 } from '@/api/modules/obsService'; 27 } from '@/api/modules/obsService';
28 import { 28 import {
29 getDictionaryTree 29 getDictionaryTree
30 } from '@/api/modules/dataInventory'; 30 } from '@/api/modules/dataAsset';
31 import { commonPageConfig } from '@/utils/enum'; 31 import { commonPageConfig } from '@/utils/enum';
32 import { getDemandTreeList, getDiseaseAll } from '@/api/modules/dataPricing'; 32 import { getDemandTreeList, getDiseaseAll } from '@/api/modules/dataPricing';
33 33
......
1 <route lang="yaml">
2 meta:
3 title: 登录
4 constant: true
5 layout: false
6 </route>
7 <script lang="ts" setup name="login">
8 import type { FormInstance, FormRules } from 'element-plus'
9 import { ElMessage } from 'element-plus'
10 import useUserStore from '@/store/modules/user'
11 import { autoSalt } from '@/utils/common'
12 import Form from "@/components/Form/index.vue";
13 import { checkCompanyName, getImgCodeSrc, getRegisterCode, checkImgCode, checkRegisterCode, registerInfoSave } from "@/api/modules/dataPartners";
14 import { getParamsList } from "@/api/modules/queryHomeService";
15
16 const banner = new URL('../assets/images/login-left.png', import.meta.url).href
17 const { proxy } = getCurrentInstance() as any;
18
19 const tenantNatureList: any = ref([]);
20
21 const loading = ref(false)
22 const registerFormRef = ref()
23 const subInfo = ref({});
24 const registerForm = ref({
25 items: [
26 {
27 label: '注册类型',
28 type: 'radio-group-panel',
29 children: [
30 {
31 label: "",
32 type: "radio-group",
33 placeholder: "",
34 field: 'registerType',
35 default: 2,
36 options: [
37 {
38 label: "服务端",
39 value: 2,
40 tips: '为申请数据资产服务的企业提供专业的合规登记入表等服务'
41 },
42 {
43 label: "企业端",
44 value: 1,
45 tips: '企业发起数据资产登记入表服务的操作'
46 }
47 ],
48 },
49 ],
50 required: true,
51 block: true
52 }, {
53 label: '申请人姓名',
54 type: 'input',
55 placeholder: '请输入',
56 field: 'contacts',
57 default: '',
58 maxlength: 20,
59 clearable: true,
60 required: true,
61 },
62 {
63 label: '职务',
64 type: 'input',
65 placeholder: '请输入',
66 field: 'contactDuties',
67 default: '',
68 maxlength: 10,
69 clearable: true,
70 required: false,
71 },
72 {
73 label: '所在企业',
74 type: 'input',
75 placeholder: '请输入',
76 field: 'companyName',
77 default: '',
78 maxlength: 200,
79 clearable: true,
80 required: true,
81 block: true
82 },
83 {
84 label: '企业类型',
85 type: 'select',
86 placeholder: '请选择',
87 field: 'tenantNature',
88 default: '',
89 options: tenantNatureList.value,
90 props: {
91 value: 'paramValue',
92 label: 'paramName'
93 },
94 clearable: true,
95 required: true,
96 block: true
97 },
98 {
99 label: '联系方式',
100 type: 'input',
101 placeholder: '请输入',
102 field: 'contactTel',
103 maxlength: 11,
104 default: '',
105 clearable: true,
106 required: true,
107 },
108 {
109 label: '短信验证码',
110 type: 'input-append-code-verify',
111 col: 'input_append',
112 placeholder: '请输入',
113 field: 'smsCode',
114 default: '',
115 maxlength: 6,
116 appendTxt: '获取短信验证码',
117 appendDisabled: false,
118 clearable: true,
119 required: true,
120 },
121 {
122 label: '注册事由',
123 type: 'textarea',
124 placeholder: '请输入',
125 field: 'remark',
126 default: '',
127 maxlength: 200,
128 clearable: true,
129 required: true,
130 block: true
131 },
132 ],
133 rules: {
134 registerType: [
135 { required: true, trigger: 'change', message: '请选择注册类型' },
136 ],
137 contacts: [
138 { required: true, trigger: 'blur', message: '请填写申请人姓名' },
139 {
140 min: 1,
141 max: 20,
142 message: '请填写申请人姓名',
143 trigger: 'change',
144 },
145 ],
146 companyName: [
147 {
148 validator: (rule: any, value: any, callback: any) => {
149 if (value === '') {
150 callback(new Error('请填写企业名称'))
151 } else {
152 if(value.length > 200){
153 return callback(new Error('企业名称长度不能超过200个字符'))
154 }
155 let params: any = {
156 companyName: value,
157 };
158 checkCompanyName(params).then((res: any) => {
159 if (res.code == proxy.$passCode) {
160 if (res.data) {
161 callback(new Error("该企业名称已存在,请填写其他企业名称"));
162 } else {
163 callback();
164 }
165 } else {
166 callback(new Error(res.msg));
167 }
168 }).catch((xhr) => {
169 callback(new Error(xhr.msg));
170 });
171 }
172 },
173 trigger: 'blur'
174 },
175 {
176 min: 1,
177 max: 200,
178 message: '请填写企业名称',
179 trigger: 'change',
180 },
181 ],
182 tenantNature: [
183 { required: true, trigger: 'change', message: '请选择企业类型' },
184 ],
185 contactTel: [
186 {
187 validator: (rule: any, value: any, callback: any) => {
188 if (value === '') {
189 callback(new Error('请填写手机号'))
190 } else {
191 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})$/
192 if (regs.test(value)) {
193 callback();
194 } else {
195 callback(new Error('请填写正确的手机号'))
196 }
197 }
198 },
199 trigger: 'blur'
200 },
201 {
202 min: 1,
203 max: 11,
204 message: '请填写手机号',
205 trigger: 'change',
206 },
207 ],
208 smsCode: [
209 { required: true, trigger: 'blur', message: '请填写短信验证码' },
210 {
211 min: 1,
212 max: 6,
213 message: '请填写短信验证码',
214 trigger: 'change',
215 },
216 ],
217 remark: [
218 { required: true, trigger: 'blur', message: '请填写注册事由' },
219 {
220 min: 1,
221 max: 200,
222 message: '请填写注册事由',
223 trigger: 'change',
224 },
225 ]
226 }
227 })
228 const centerDialogVisible = ref(false);
229 const imgCodePath = ref('')
230 const imgCodeGuid = ref('');
231 const ruleFormRef = ref();
232 const ruleForm = ref({
233 captcha: ''
234 })
235 const rules = ref({
236 captcha: [
237 {
238 validator: (rule: any, value: any, callback: any) => {
239 if (value === '') {
240 callback(new Error('请填写图形验证码'))
241 } else {
242 let params: any = {
243 captcha: value,
244 captchaGuid: imgCodeGuid.value
245 };
246 checkImgCode(params).then((res: any) => {
247 if (res.code == proxy.$passCode) {
248 if (!res.data) {
249 callback(new Error("验证码错误,请重新填写"));
250 } else {
251 callback();
252 }
253 } else {
254 callback(new Error(res.msg));
255 }
256 }).catch((xhr) => {
257 callback(new Error(xhr.msg));
258 });
259 }
260 }, trigger: 'blur'
261 },
262 {
263 min: 1,
264 message: '请填写图形验证码',
265 trigger: 'change',
266 },
267 ]
268 })
269
270 const getImgCode = () => {
271 getImgCodeSrc({width: 180, height: 40}).then((res) => {
272 imgCodeGuid.value = res.data?.guid || '';
273 imgCodePath.value = res.data?.imageBase64 || '';
274 if(!centerDialogVisible.value) {
275 ruleForm.value.captcha = '';
276 centerDialogVisible.value = true;
277 nextTick(() => {
278 ruleFormRef.value.clearValidate();
279 })
280 }
281 })
282 }
283
284 const getSmsCode = (info) => {
285 if(registerForm.value.items.at(-2).col.indexOf('is_disabled') > -1) return
286 const formObj = registerFormRef.value;
287 const formEl = formObj.ruleFormRef;
288 formEl.validateField('contactTel', (valid) => {
289 if (valid) {
290 subInfo.value = info;
291 getImgCode();
292 }
293 });
294 }
295
296 const sendCode = () => {
297 const formEl = ruleFormRef.value;
298 if (!formEl) return;
299 formEl.validate((valid, fields) => {
300 if (valid) {
301 centerDialogVisible.value = false;
302 toRegister();
303 }
304 })
305 }
306
307 const toRegister = () => {
308 registerForm.value.items.at(-2).col = 'input_append is_disabled';
309 let count = 59;
310 const intervalId = setInterval(() => {
311 // 如果倒计时大于0,则减少1秒
312 if (count > 0) {
313 registerForm.value.items.at(-2).appendTxt = `再次发送(${count})s`;
314 count--;
315 } else {
316 // 如果倒计时到0,清除间隔调用并可以做其他操作
317 clearInterval(intervalId);
318 registerForm.value.items.at(-2).appendTxt = '获取短信验证码';
319 registerForm.value.items.at(-2).col = 'input_append';
320 }
321 }, 1000);
322 let params: any = {
323 mobileNo: subInfo.value.contactTel,
324 captcha: ruleForm.value.captcha,
325 captchaGuid: imgCodeGuid.value,
326 type: 1
327 };
328 getRegisterCode(params).then((res: any) => {
329 if (res.code == proxy.$passCode) {
330 ElMessage({
331 message: '验证码发送成功',
332 type: 'success',
333 })
334 } else {
335 ElMessage({
336 message: '验证码发送失败',
337 type: 'error',
338 })
339 }
340 }).catch((xhr) => {
341 ElMessage({
342 message: '验证码发送失败',
343 type: 'error',
344 })
345 });
346 }
347
348 const submitForm = (formEl, info) => {
349 if (!formEl) return;
350 formEl.validate((valid, fields) => {
351 if (valid) {
352 let param: any = {
353 mobileNo: info.contactTel,
354 code: info.smsCode
355 };
356 checkRegisterCode(param).then((res: any) => {
357 if (res.code == proxy.$passCode) {
358 if (res.data) {
359 let params = { ...info };
360 delete params.smsCode;
361
362 registerInfoSave(params).then((res: any) => {
363 if (res.code == proxy.$passCode) {
364 ElMessage({
365 type: "success",
366 message: '注册成功',
367 });
368 } else {
369 ElMessage({
370 type: "error",
371 message: res.msg,
372 });
373 }
374 loading.value = false;
375 }).catch((res) => {
376 ElMessage({
377 type: "error",
378 message: '注册失败',
379 });
380 loading.value = false;
381 });
382 } else {
383 ElMessage({
384 message: '验证码不正确',
385 type: 'error',
386 })
387 loading.value = false;
388 }
389 } else {
390 ElMessage({
391 message: res.msg,
392 type: 'error',
393 })
394 loading.value = false;
395 }
396 }).catch((xhr) => {
397 ElMessage({
398 message: '验证码校验失败',
399 type: 'error',
400 })
401 loading.value = false;
402 });
403 } else {
404 console.log("error submit!", fields);
405 loading.value = false;
406 }
407 });
408 };
409
410 function handleRegister() {
411 loading.value = true;
412 const formObj = registerFormRef.value;
413 const formEl = formObj.ruleFormRef;
414 const form = formObj.formInline;
415 submitForm(formEl, { ...form });
416 }
417
418 onBeforeMount(() => {
419 getParamsList({ paramCode: 'TENANT-NATURE' }).then((res: any) => {
420 if (res.code == proxy.$passCode) {
421 tenantNatureList.value = res.data || [];
422 let item = registerForm.value.items?.find(c => c.field == 'tenantNature');
423 if (item) {
424 item.options = tenantNatureList.value;
425 // registerForm.value
426 }
427 } else {
428 proxy.$ElMessage.error(res.msg);
429 }
430 });
431 })
432
433 </script>
434 <template>
435 <div>
436 <div class="bg-banner" />
437 <div id="login-box">
438 <div class="login-banner">
439 <div>
440 <img :src="banner" class="banner">
441 <div class="banner_desc">
442 <h4>数据资产管理系统</h4>
443 <span>激活数据流通体系,释放数据要素新质生产力</span>
444 </div>
445 </div>
446 </div>
447 <div class="login_form_panel">
448 <div class="login_form">
449 <Form ref="registerFormRef" :itemList="registerForm.items" formId="partnerRegisterForm"
450 :rules="registerForm.rules" @inputAppendClick="getSmsCode"/>
451 <el-button type="primary" @click="handleRegister" :loading="loading" size="large" style="width: 100%; margin-top: 12px;">注册</el-button>
452 </div>
453 </div>
454 </div>
455 <div class="footer">
456 北京传世博润科技有限公司 Copyright @ 2023-2024 <a href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
457 </div>
458 <el-dialog
459 v-model="centerDialogVisible"
460 width="360"
461 title="图形验证码"
462 align-center
463 >
464 <template #default>
465 <div class="img-code">
466 <el-form
467 ref="ruleFormRef"
468 :model="ruleForm"
469 :rules="rules"
470 class="demo-ruleForm"
471 @submit.native.prevent
472 >
473 <el-form-item>
474 <div class="img_code">
475 <img :src="imgCodePath"/>
476 <span>看不清?<span class="text_btn" @click="getImgCode">换一张</span></span>
477 </div>
478 </el-form-item>
479 <el-form-item prop="captcha">
480 <el-input v-model="ruleForm.captcha" placeholder="请输入图形验证码" clearable @keyup.enter="sendCode" />
481 </el-form-item>
482 </el-form>
483 </div>
484 </template>
485 <template #footer>
486 <div class="dialog-footer">
487 <el-button type="primary" size="large" @click="sendCode">确定</el-button>
488 </div>
489 </template>
490 </el-dialog>
491 </div>
492 </template>
493 <style lang="scss" scoped>
494 .footer {
495 position: absolute;
496 bottom: 20px;
497 left: 0;
498 width: 100%;
499 text-align: center;
500 font-size: 12px;
501 color: #606060;
502 font-weight: 200;
503 }
504 [data-mode="mobile"] {
505 #login-box {
506 position: relative;
507 width: 100%;
508 height: 100%;
509 top: inherit;
510 left: inherit;
511 transform: translateX(0) translateY(0);
512 flex-direction: column;
513 justify-content: start;
514 border-radius: 0;
515 box-shadow: none;
516 .login-banner {
517 width: 100%;
518 padding: 20px 0;
519 .banner {
520 position: relative;
521 right: inherit;
522 width: 100%;
523 max-width: 375px;
524 margin: 0 auto;
525 display: inherit;
526 top: inherit;
527 transform: translateY(0);
528 }
529 }
530 .login-form {
531 width: 100%;
532 min-height: auto;
533 padding: 30px;
534 }
535 }
536 .copyright {
537 position: relative;
538 bottom: 0;
539 padding-bottom: 10px;
540 }
541 }
542 :deep(input[type="password"]::-ms-reveal) {
543 display: none;
544 }
545 :deep(.el-form) {
546 .el-form-item {
547 display: flex;
548 flex-direction: column;
549 align-items: flex-start;
550 .el-form-item__content {
551 width: 100%;
552 }
553 .el-select {
554 width: 100%;
555 }
556 }
557 }
558 .bg-banner {
559 position: fixed;
560 z-index: 0;
561 width: 100%;
562 height: 100%;
563 background: url('@/assets/images/login-bg.png') center/100% 100% no-repeat;
564 }
565 #login-box {
566 width: 100%;
567 height: 100%;
568 display: flex;
569 justify-content: space-around;
570 position: absolute;
571 top: 50%;
572 left: 50%;
573 transform: translateX(-50%) translateY(-50%);
574 overflow: hidden;
575 max-width: 1280px;
576 min-width: 900px;
577 padding-bottom: 20px;
578 .login-banner {
579 height: 100%;
580 overflow: hidden;
581 display: flex;
582 justify-content: center;
583 align-items: center;
584 >div {
585 display: flex;
586 flex-direction: column;
587 align-items: center;
588 }
589 .banner {
590 width: 495px;
591 }
592 .banner_desc {
593 width: 496px;
594 text-align: justify;
595 font-size: 24px;
596 color: #414141;
597 font-weight: 200;
598 margin-top: -32px;
599 h4 {
600 text-align: center;
601 margin: 0 0 8px;
602 font-size: 28px;
603 color: #414141;
604 font-weight: 600;
605 }
606 }
607 }
608 .login_form_panel {
609 display: flex;
610 align-items: center;
611 justify-content: center;
612 position: relative;
613 .login_form {
614 width: 600px;
615 height: 635px;
616 padding: 32px;
617 background: #FFFFFF;
618 box-shadow: 0px 4px 10px 0px rgba(0,0,0,0.2);
619 .title_img {
620 margin-top: 54px;
621 margin-bottom: 47px;
622 }
623 .form-content {
624 margin: 0px 30px;
625 }
626 }
627 .title-container {
628 text-align: center;
629 >img {
630 width: 263px;
631 }
632 .form_title {
633 height: 42px;
634 font-size: 28px;
635 color: #8D8D8E;
636 letter-spacing: 0;
637 text-align: center;
638 line-height: 42px;
639 font-weight: 400;
640 margin: 32px 0;
641 }
642 }
643 }
644 .login-form {
645 display: flex;
646 flex-direction: column;
647 justify-content: center;
648 overflow: hidden;
649 .title-container {
650 position: relative;
651 .title {
652 font-size: 1.3em;
653 color: var(--el-text-color-primary);
654 margin: 0 auto 30px;
655 font-weight: bold;
656 }
657 }
658 }
659 .el-form-item {
660 margin-bottom: 24px;
661 :deep(.el-input) {
662 height: 44px;
663 line-height: inherit;
664 width: 100%;
665 input {
666 height: 44px;
667 font-size: 14px;
668 &:-webkit-autofill::first-line {
669 font-size: 14px;
670 }
671 }
672 .el-input__icon {
673 width: 20px;
674 height: 15px;
675 svg {
676 width: 100%;
677 height: 100%;
678 }
679 }
680 .el-input__prefix,
681 .el-input__suffix {
682 display: flex;
683 align-items: center;
684 }
685 .el-input__prefix {
686 left: 10px;
687 }
688 .el-input__suffix {
689 right: 10px;
690 }
691 .el-input__wrapper {
692 // border-radius: 0;
693 // box-shadow: none;
694 // border-bottom: 1px solid #e5e5e5;
695 &:hover {
696 // box-shadow: none;
697 }
698 }
699 }
700 }
701 .flex-bar {
702 display: flex;
703 align-items: center;
704 justify-content: space-between;
705 margin-bottom: 20px;
706 }
707 .sub-link {
708 display: flex;
709 align-items: center;
710 justify-content: center;
711 margin-top: 20px;
712 font-size: 14px;
713 color: var(--el-text-color-secondary);
714 .text {
715 margin-right: 10px;
716 }
717 }
718 }
719 .login-btn {
720 margin: 24px 30px 0 30px;
721 height: 44px;
722 width: auto;
723 font-size: 20px;
724 }
725
726 :deep(.el-dialog){
727 padding: 0;
728 .el-dialog__header {
729 height: 40px;
730
731 .el-dialog__headerbtn {
732 height: 40px;
733 line-height: 40px;
734 }
735 }
736 .el-dialog__footer {
737 border-top: 0;
738 height: 68px;
739 padding: 0 24px;
740
741 .dialog-footer {
742 display: block;
743
744 >.el-button {
745 width: 100%;
746 >span {
747 letter-spacing: 2px;
748 }
749 }
750 }
751 }
752 .img_code {
753 display: flex;
754 flex-wrap: wrap;
755 justify-content: center;
756 align-items: center;
757 margin: 8px 0;
758 >span {
759 display: block;
760 width: 100%;
761 text-align: center;
762 margin-top: 16px;
763 }
764 }
765 }
766 </style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!