全景地图地址修改
Showing
53 changed files
with
15872 additions
and
50 deletions
| ... | @@ -83,6 +83,9 @@ VITE_APP_ATTACHMENT_TEMPLATE = ms-daop-personel-service | ... | @@ -83,6 +83,9 @@ VITE_APP_ATTACHMENT_TEMPLATE = ms-daop-personel-service |
| 83 | #人员服务 | 83 | #人员服务 |
| 84 | VITE_APP_PERSONAL_URL = 'ms-daop-personel-service' | 84 | VITE_APP_PERSONAL_URL = 'ms-daop-personel-service' |
| 85 | 85 | ||
| 86 | #元数据标准 | ||
| 87 | VITE_APP_STANDARD_URL = 'ms-daop-meta-standard-service' | ||
| 88 | |||
| 86 | #流通平台地址 | 89 | #流通平台地址 |
| 87 | VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ | 90 | VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ |
| 88 | # 测试环境访问地址 | 91 | # 测试环境访问地址 |
| ... | @@ -91,7 +94,6 @@ VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ | ... | @@ -91,7 +94,6 @@ VITE_APP_CIRCULATION = https://daop-lt-test.zgsjzc.com/ |
| 91 | #数据加工交付 | 94 | #数据加工交付 |
| 92 | VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/ | 95 | VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/ |
| 93 | 96 | ||
| 94 | |||
| 95 | # 本地访问地址 | 97 | # 本地访问地址 |
| 96 | # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation | 98 | # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation |
| 97 | 99 | ... | ... |
| ... | @@ -110,6 +110,9 @@ VITE_API_ASSET_BASEURL = ms-swzl-data-dam-service | ... | @@ -110,6 +110,9 @@ VITE_API_ASSET_BASEURL = ms-swzl-data-dam-service |
| 110 | #数据同步接口地址 | 110 | #数据同步接口地址 |
| 111 | VITE_API_DATA_SYNC = ms-swzl-data-sync-service | 111 | VITE_API_DATA_SYNC = ms-swzl-data-sync-service |
| 112 | 112 | ||
| 113 | #元数据标准 | ||
| 114 | VITE_APP_STANDARD_URL = 'ms-daop-meta-standard-service' | ||
| 115 | |||
| 113 | #消息接口 | 116 | #消息接口 |
| 114 | VITE_API_MESSAGE = ms-daop-message-service | 117 | VITE_API_MESSAGE = ms-daop-message-service |
| 115 | 118 | ... | ... |
| ... | @@ -27,6 +27,7 @@ declare module '@vue/runtime-core' { | ... | @@ -27,6 +27,7 @@ declare module '@vue/runtime-core' { |
| 27 | FileUpload: typeof import('./src/components/FileUpload/index.vue')['default'] | 27 | FileUpload: typeof import('./src/components/FileUpload/index.vue')['default'] |
| 28 | FixedActionBar: typeof import('./src/components/FixedActionBar/index.vue')['default'] | 28 | FixedActionBar: typeof import('./src/components/FixedActionBar/index.vue')['default'] |
| 29 | Form: typeof import('./src/components/Form/index.vue')['default'] | 29 | Form: typeof import('./src/components/Form/index.vue')['default'] |
| 30 | GraphTopbar: typeof import('./src/components/RelationNetwork/graphTopbar.vue')['default'] | ||
| 30 | Hour: typeof import('./src/components/Schedule/component/hour.vue')['default'] | 31 | Hour: typeof import('./src/components/Schedule/component/hour.vue')['default'] |
| 31 | ImagePreview: typeof import('./src/components/ImagePreview/index.vue')['default'] | 32 | ImagePreview: typeof import('./src/components/ImagePreview/index.vue')['default'] |
| 32 | ImagesUpload: typeof import('./src/components/ImagesUpload/index.vue')['default'] | 33 | ImagesUpload: typeof import('./src/components/ImagesUpload/index.vue')['default'] |
| ... | @@ -41,6 +42,7 @@ declare module '@vue/runtime-core' { | ... | @@ -41,6 +42,7 @@ declare module '@vue/runtime-core' { |
| 41 | PageNav: typeof import('./src/components/PageNav/index.vue')['default'] | 42 | PageNav: typeof import('./src/components/PageNav/index.vue')['default'] |
| 42 | PcasCascader: typeof import('./src/components/PcasCascader/index.vue')['default'] | 43 | PcasCascader: typeof import('./src/components/PcasCascader/index.vue')['default'] |
| 43 | Popover: typeof import('./src/components/Popover/index.vue')['default'] | 44 | Popover: typeof import('./src/components/Popover/index.vue')['default'] |
| 45 | RelationNetwork: typeof import('./src/components/RelationNetwork/index.vue')['default'] | ||
| 44 | RouterLink: typeof import('vue-router')['RouterLink'] | 46 | RouterLink: typeof import('vue-router')['RouterLink'] |
| 45 | RouterView: typeof import('vue-router')['RouterView'] | 47 | RouterView: typeof import('vue-router')['RouterView'] |
| 46 | Schedule: typeof import('./src/components/Schedule/index.vue')['default'] | 48 | Schedule: typeof import('./src/components/Schedule/index.vue')['default'] | ... | ... |
| ... | @@ -552,3 +552,8 @@ export const getContractDetail = (params) => request({ | ... | @@ -552,3 +552,8 @@ export const getContractDetail = (params) => request({ |
| 552 | method: 'get', | 552 | method: 'get', |
| 553 | params | 553 | params |
| 554 | }) | 554 | }) |
| 555 | |||
| 556 | // 获取所有字典 | ||
| 557 | export const getDictAllList = () => request({ | ||
| 558 | url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-all` | ||
| 559 | }) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -249,3 +249,297 @@ export const delMetaDataSource = (databaseGuid) => request({ | ... | @@ -249,3 +249,297 @@ export const delMetaDataSource = (databaseGuid) => request({ |
| 249 | url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/del-by-database-guid?databaseGuid=${databaseGuid}`, | 249 | url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/del-by-database-guid?databaseGuid=${databaseGuid}`, |
| 250 | method: 'delete', | 250 | method: 'delete', |
| 251 | }) | 251 | }) |
| 252 | |||
| 253 | /** 元数据-标准代码分页查询 */ | ||
| 254 | export const getStandardCodeList = (params) => request({ | ||
| 255 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/page-list`, | ||
| 256 | method: 'post', | ||
| 257 | data: params | ||
| 258 | }) | ||
| 259 | /** 元数据-标准代码新增 */ | ||
| 260 | export const saveStandardCode = (params) => request({ | ||
| 261 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/save`, | ||
| 262 | method: 'post', | ||
| 263 | data: params | ||
| 264 | }) | ||
| 265 | /** 元数据-标准代码修改 */ | ||
| 266 | export const updateStandardCode = (params) => request({ | ||
| 267 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/update`, | ||
| 268 | method: 'put', | ||
| 269 | data: params | ||
| 270 | }) | ||
| 271 | /** 元数据-标准代码详情 */ | ||
| 272 | export const getStandardCodeDetail = (guid) => request({ | ||
| 273 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/detail?guid=${guid}`, | ||
| 274 | method: 'get', | ||
| 275 | }) | ||
| 276 | /** 元数据-标准代码删除 */ | ||
| 277 | export const deleteStandardCode = (params) => request({ | ||
| 278 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/delete`, | ||
| 279 | method: 'delete', | ||
| 280 | data: params | ||
| 281 | }) | ||
| 282 | /** 元数据-查询标准列表 */ | ||
| 283 | export const getStandardCodeStandard = (standardTypeCode) => request({ | ||
| 284 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/get-standard?standardTypeCode=${standardTypeCode}`, | ||
| 285 | method: 'get' | ||
| 286 | }) | ||
| 287 | /** 元数据-查询代码列表 */ | ||
| 288 | export const getStandardCodeDataList = (params) => request({ | ||
| 289 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/data/get-data`, | ||
| 290 | method: 'post', | ||
| 291 | data: params | ||
| 292 | }) | ||
| 293 | /** 元数据-查询代码字段数据 */ | ||
| 294 | export const getStandardCodeFields = (standardGuid) => request({ | ||
| 295 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/get-field?standardGuid=${standardGuid}`, | ||
| 296 | method: 'get' | ||
| 297 | }) | ||
| 298 | /** 元数据-保存标准代码数据 */ | ||
| 299 | export const saveStandardCodeFieldsData = (params) => request({ | ||
| 300 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/data/save-data`, | ||
| 301 | method: 'post', | ||
| 302 | data: params | ||
| 303 | }) | ||
| 304 | /** 元数据-删除标准代码数据 */ | ||
| 305 | export const deleteStandardCodeFieldsData = (params) => request({ | ||
| 306 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/data/remove-data`, | ||
| 307 | method: 'post', | ||
| 308 | data: params | ||
| 309 | }) | ||
| 310 | /** 元数据-导出 */ | ||
| 311 | export const exportStandardCodeData = (params) => request({ | ||
| 312 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/data/data-export`, | ||
| 313 | method: 'post', | ||
| 314 | data: params, | ||
| 315 | responseType: 'blob' | ||
| 316 | }) | ||
| 317 | /** 元数据标准-树形列表 */ | ||
| 318 | export const getMetaStandardTree = () => request({ | ||
| 319 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/list-tree`, | ||
| 320 | method: 'get' | ||
| 321 | }) | ||
| 322 | /** 元数据标准-新增 */ | ||
| 323 | export const saveMetaStandard = (params) => request({ | ||
| 324 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/save`, | ||
| 325 | method: 'post', | ||
| 326 | data: params | ||
| 327 | }) | ||
| 328 | /** 元数据标准-修改 */ | ||
| 329 | export const updateMetaStandard = (params) => request({ | ||
| 330 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/update`, | ||
| 331 | method: 'put', | ||
| 332 | data: params | ||
| 333 | }) | ||
| 334 | /** 元数据标准-删除 */ | ||
| 335 | export const deleteMetaStandard = (params) => request({ | ||
| 336 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/delete`, | ||
| 337 | method: 'delete', | ||
| 338 | data: params | ||
| 339 | }) | ||
| 340 | /** 元数据标准-详情 */ | ||
| 341 | export const getMetaStandardDetail = (guid) => request({ | ||
| 342 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/detail?guid=${guid}`, | ||
| 343 | method: 'get' | ||
| 344 | }) | ||
| 345 | /** 元数据标准-标准数据 */ | ||
| 346 | export const getMetaStandardDataList = (params) => request({ | ||
| 347 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/page-list`, | ||
| 348 | method: 'post', | ||
| 349 | data: params | ||
| 350 | }) | ||
| 351 | /** 元数据标准-标准字段 */ | ||
| 352 | export const getMetaStandardDataFields = (metaStandardGuid) => request({ | ||
| 353 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/get-standard-field?metaStandardGuid=${metaStandardGuid}`, | ||
| 354 | method: 'get' | ||
| 355 | }) | ||
| 356 | /** 元数据标准-标准字段保存 */ | ||
| 357 | export const saveMetaStandardDataFields = (params) => request({ | ||
| 358 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/save-or-update`, | ||
| 359 | method: 'post', | ||
| 360 | data: params | ||
| 361 | }) | ||
| 362 | /** 元数据标准-标准字段删除 */ | ||
| 363 | export const deleteMetaStandardDataFields = (params) => request({ | ||
| 364 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/del`, | ||
| 365 | method: 'delete', | ||
| 366 | data: params | ||
| 367 | }) | ||
| 368 | /** 元数据标准-导出 */ | ||
| 369 | export const exportMetaStandardData = (params) => request({ | ||
| 370 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/data-export`, | ||
| 371 | method: 'post', | ||
| 372 | data: params, | ||
| 373 | responseType: 'blob' | ||
| 374 | }) | ||
| 375 | /** 标准代码-树形表 */ | ||
| 376 | export const getStandardCodeTree = () => request({ | ||
| 377 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/standard-code/code-tree`, | ||
| 378 | method: 'get' | ||
| 379 | }) | ||
| 380 | |||
| 381 | /** 元数据标准树形列表查询 */ | ||
| 382 | export const getMetaStandardTreeList = (guid) => request({ | ||
| 383 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/list-tree?metaStandardGuid=${guid}`, | ||
| 384 | method: 'get' | ||
| 385 | }) | ||
| 386 | |||
| 387 | /** 元数据标准guid查询只展示的字段 */ | ||
| 388 | export const getMetaStandardField = (guid) => request({ | ||
| 389 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/list-by-meta-standard-guid?metaStandardGuid=${guid}`, | ||
| 390 | method: 'get' | ||
| 391 | }) | ||
| 392 | /** 元数据标准字段详情 */ | ||
| 393 | export const getMetaStandardFieldsDetail = (guid) => request({ | ||
| 394 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/detail?guid=${guid}`, | ||
| 395 | method: 'get' | ||
| 396 | }) | ||
| 397 | |||
| 398 | /** 根据元数据标准展示字段去获取未展示的详情信息 */ | ||
| 399 | export const getMetaStandardFieldDetail = (guid) => request({ | ||
| 400 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/data/convert-detail?guid=${guid}`, | ||
| 401 | method: 'get' | ||
| 402 | }) | ||
| 403 | |||
| 404 | /** 获取桑基图数据 */ | ||
| 405 | export const getSankeyData = (guid) => request({ | ||
| 406 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/sankey-data?metaStandardGuid=${guid}`, | ||
| 407 | method: 'get' | ||
| 408 | }) | ||
| 409 | |||
| 410 | /** 数仓目录树列表查询 */ | ||
| 411 | export const getDataWareCatalogList = (params) => request({ | ||
| 412 | // url: `${import.meta.env.VITE_APP_DATA_DELIVERY}delivery/ms-daop-data-plan-service/data-catalog-directory/tree-list`, | ||
| 413 | url: `${import.meta.env.VITE_API_BASEURL}delivery/api/ms-daop-data-plan-service/data-catalog-directory/tree-list`, | ||
| 414 | method: 'post', | ||
| 415 | data: params | ||
| 416 | }) | ||
| 417 | |||
| 418 | export const getAllFlowData = (dictType) => request({ | ||
| 419 | url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${dictType}`, | ||
| 420 | method: 'get', | ||
| 421 | }) | ||
| 422 | |||
| 423 | /** 元数据标准guid查询新建数据集字段 */ | ||
| 424 | export const getMetaStandardDsField = (guid) => request({ | ||
| 425 | url: `${import.meta.env.VITE_APP_STANDARD_URL}/meta-standard/get-standard?metaStandardGuid=${guid}`, | ||
| 426 | method: 'get' | ||
| 427 | }) | ||
| 428 | |||
| 429 | /** 表分类类型 */ | ||
| 430 | export const tableCategoryList = [ | ||
| 431 | { | ||
| 432 | value: 1, | ||
| 433 | label: "明细表", | ||
| 434 | }, | ||
| 435 | { | ||
| 436 | value: 2, | ||
| 437 | label: "汇总表", | ||
| 438 | }, | ||
| 439 | { | ||
| 440 | value: 3, | ||
| 441 | label: "应用表", | ||
| 442 | }, | ||
| 443 | { | ||
| 444 | value: 6, | ||
| 445 | label: "业务表", | ||
| 446 | }, | ||
| 447 | // { | ||
| 448 | // value: 4, | ||
| 449 | // label: "维度表", | ||
| 450 | // }, | ||
| 451 | // { | ||
| 452 | // value: 5, | ||
| 453 | // label: "缓慢变化维", | ||
| 454 | // } | ||
| 455 | ]; | ||
| 456 | |||
| 457 | /** 同步策略 */ | ||
| 458 | export const syncPolicys = [ | ||
| 459 | { | ||
| 460 | value: 1, | ||
| 461 | label: "实时", | ||
| 462 | }, | ||
| 463 | { | ||
| 464 | value: 2, | ||
| 465 | label: "增量", | ||
| 466 | }, | ||
| 467 | { | ||
| 468 | value: 3, | ||
| 469 | label: "全量", | ||
| 470 | }, | ||
| 471 | { | ||
| 472 | value: 4, | ||
| 473 | label: "增量加更新", | ||
| 474 | }, | ||
| 475 | ]; | ||
| 476 | |||
| 477 | /** 维表类型 */ | ||
| 478 | export const dimTypeList = [{ | ||
| 479 | label: "列表", | ||
| 480 | value: 1, | ||
| 481 | }, | ||
| 482 | { | ||
| 483 | label: "层级", | ||
| 484 | value: 2, | ||
| 485 | }, | ||
| 486 | { | ||
| 487 | label: "螺旋", | ||
| 488 | value: 3, | ||
| 489 | }, | ||
| 490 | { | ||
| 491 | label: "通用", | ||
| 492 | value: 4, | ||
| 493 | }]; | ||
| 494 | |||
| 495 | /** 表模型分类 */ | ||
| 496 | export const tableModels = [ | ||
| 497 | { | ||
| 498 | label: "主键模型", | ||
| 499 | value: 1, | ||
| 500 | }, | ||
| 501 | { | ||
| 502 | label: "聚合模型", | ||
| 503 | value: 2, | ||
| 504 | }, | ||
| 505 | { | ||
| 506 | label: "明细模型", | ||
| 507 | value: 3, | ||
| 508 | } | ||
| 509 | ]; | ||
| 510 | |||
| 511 | /** 聚合方式 */ | ||
| 512 | export const aggMethodList = [{ | ||
| 513 | value: 'SUM', | ||
| 514 | }, { | ||
| 515 | value: 'MAX' | ||
| 516 | }, { | ||
| 517 | value: 'MIN' | ||
| 518 | }, { | ||
| 519 | value: 'REPLACE' | ||
| 520 | }, { | ||
| 521 | value: 'REPLACE_IF_NOT_NULL' | ||
| 522 | }, { | ||
| 523 | value: 'HLL_UNION' | ||
| 524 | }, { | ||
| 525 | value: 'BITMAP_UNION' | ||
| 526 | }]; | ||
| 527 | |||
| 528 | /** 保存主题表设置,直接入库 */ | ||
| 529 | export const saveSubjectTable = (params) => request({ | ||
| 530 | url: `${import.meta.env.VITE_API_BASEURL}delivery/api/ms-daop-data-plan-service/data-catalog-subject/add`, | ||
| 531 | method: 'post', | ||
| 532 | data: params | ||
| 533 | }) | ||
| 534 | |||
| 535 | /** 获取字典列表 */ | ||
| 536 | export const getDictionary = (params) => request({ | ||
| 537 | url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/list-all?state=1`, | ||
| 538 | method: 'post' | ||
| 539 | }) | ||
| 540 | |||
| 541 | /** 获取维度列表 */ | ||
| 542 | export const getDimList = () => request({ | ||
| 543 | url: `${import.meta.env.VITE_API_BASEURL}delivery/api/ms-daop-data-plan-service/data-catalog-subject/get-dim-list`, | ||
| 544 | method: 'get' | ||
| 545 | }) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/api/modules/dataPricing.ts
0 → 100644
| 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 deletePrice = (params) => { | ||
| 247 | return request({ | ||
| 248 | url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/delete`, | ||
| 249 | method: "delete", | ||
| 250 | data: params, | ||
| 251 | }); | ||
| 252 | }; | ||
| 253 | |||
| 254 | // 获取数据资源目录 | ||
| 255 | export const getDamCatalogList = (params) => { | ||
| 256 | return request({ | ||
| 257 | url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-catalog-table/get-table-select-new`, | ||
| 258 | method: "get", | ||
| 259 | params, | ||
| 260 | }); | ||
| 261 | }; | ||
| 262 | |||
| 263 | // 获取模型相关需求表 | ||
| 264 | export const getModelDemand = (params) => { | ||
| 265 | return request({ | ||
| 266 | url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/pricing-model`, | ||
| 267 | method: "get", | ||
| 268 | params, | ||
| 269 | }); | ||
| 270 | }; | ||
| 271 | |||
| 272 | // 获取质量模型评分 | ||
| 273 | export const getModelScore = (params) => { | ||
| 274 | return request({ | ||
| 275 | url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-quality-score-by-dam-guid-v2`, | ||
| 276 | method: "get", | ||
| 277 | params, | ||
| 278 | }); | ||
| 279 | }; | ||
| 280 | |||
| 281 | export const exportModelScore = (params) => { | ||
| 282 | return request({ | ||
| 283 | url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/download-template`, | ||
| 284 | method: "post", | ||
| 285 | data: params, | ||
| 286 | responseType: 'blob' | ||
| 287 | }); | ||
| 288 | }; |
| ... | @@ -303,3 +303,10 @@ export const getCurrentUserInfo = (params) => { | ... | @@ -303,3 +303,10 @@ export const getCurrentUserInfo = (params) => { |
| 303 | params | 303 | params |
| 304 | }); | 304 | }); |
| 305 | }; | 305 | }; |
| 306 | |||
| 307 | /** 下载文件模板 */ | ||
| 308 | export const exportTemplate = (params) => request({ | ||
| 309 | url: `${import.meta.env.VITE_APP_ADD_FILE}/import-config/export-template?bizGuid=${params.bizGuid}&importType=${params.importType}`, | ||
| 310 | method: 'post', | ||
| 311 | responseType: 'blob' | ||
| 312 | }); | ... | ... |
| ... | @@ -1182,3 +1182,12 @@ | ... | @@ -1182,3 +1182,12 @@ |
| 1182 | max-width: 100%; | 1182 | max-width: 100%; |
| 1183 | } | 1183 | } |
| 1184 | } | 1184 | } |
| 1185 | |||
| 1186 | .el-drawer__title { | ||
| 1187 | font-size: 18px; | ||
| 1188 | color: #212121; | ||
| 1189 | } | ||
| 1190 | .el-form-item--default .el-form-item__label { | ||
| 1191 | height: 26px; | ||
| 1192 | line-height: 26px; | ||
| 1193 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -44,6 +44,7 @@ const emits = defineEmits([ | ... | @@ -44,6 +44,7 @@ const emits = defineEmits([ |
| 44 | "uploadBtnClick", | 44 | "uploadBtnClick", |
| 45 | "beforeUPload", | 45 | "beforeUPload", |
| 46 | "uploadFile", | 46 | "uploadFile", |
| 47 | 'deleteFile', | ||
| 47 | "onUpload", | 48 | "onUpload", |
| 48 | "scheduleChange", | 49 | "scheduleChange", |
| 49 | "cascaderChange", | 50 | "cascaderChange", |
| ... | @@ -668,7 +669,7 @@ defineExpose({ | ... | @@ -668,7 +669,7 @@ defineExpose({ |
| 668 | <template v-else-if="con.type.indexOf('upload') > -1"> | 669 | <template v-else-if="con.type.indexOf('upload') > -1"> |
| 669 | <UploadFiles ref="formUploadRef" :upload-info="con.uploadInfo" @onUpload="onUpload" | 670 | <UploadFiles ref="formUploadRef" :upload-info="con.uploadInfo" @onUpload="onUpload" |
| 670 | @beforeUPload="beforeUPload" @uploadFile="uploadFile" @uploadBtnClick="uploadBtnClick" | 671 | @beforeUPload="beforeUPload" @uploadFile="uploadFile" @uploadBtnClick="uploadBtnClick" |
| 671 | @cascaderChange="cascaderChange" @selectChange="uploadSelectChange" /> | 672 | @cascaderChange="cascaderChange" @selectChange="uploadSelectChange" @deleteFile="() => emits('deleteFile')"/> |
| 672 | </template> | 673 | </template> |
| 673 | <template v-else> | 674 | <template v-else> |
| 674 | <div v-if="con.formInfo.tools"> | 675 | <div v-if="con.formInfo.tools"> | ... | ... |
| ... | @@ -70,7 +70,15 @@ const onMouseOver = (str) => { | ... | @@ -70,7 +70,15 @@ const onMouseOver = (str) => { |
| 70 | </script> | 70 | </script> |
| 71 | 71 | ||
| 72 | <template> | 72 | <template> |
| 73 | <el-tooltip class="item" placement="top" effect="light" :popper-class="popperClass ?? 'table_tooltip'" :disabled="isShowTooltip" :open-delay="400" :content="content"> | 73 | <el-tooltip |
| 74 | class="item" | ||
| 75 | placement="top" | ||
| 76 | effect="light" | ||
| 77 | :popper-class="popperClass ?? 'table_tooltip'" | ||
| 78 | :disabled="isShowTooltip" | ||
| 79 | :open-delay="400" | ||
| 80 | :content="content" | ||
| 81 | > | ||
| 74 | <p class="over-flow" :class="className" @mouseover="onMouseOver(refName)"> | 82 | <p class="over-flow" :class="className" @mouseover="onMouseOver(refName)"> |
| 75 | <span :ref="(el) => setRefMap(el, refName)" v-html="content || '-'"></span> | 83 | <span :ref="(el) => setRefMap(el, refName)" v-html="content || '-'"></span> |
| 76 | </p> | 84 | </p> |
| ... | @@ -92,3 +100,9 @@ p { | ... | @@ -92,3 +100,9 @@ p { |
| 92 | margin: 0; | 100 | margin: 0; |
| 93 | } | 101 | } |
| 94 | </style> | 102 | </style> |
| 103 | |||
| 104 | <style lang="scss"> | ||
| 105 | .el-popper.tree-popper { | ||
| 106 | max-width: 280px!important; | ||
| 107 | } | ||
| 108 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -741,6 +741,7 @@ onMounted(() => { | ... | @@ -741,6 +741,7 @@ onMounted(() => { |
| 741 | toolRef.value.isFull = true | 741 | toolRef.value.isFull = true |
| 742 | } | 742 | } |
| 743 | }, 500) | 743 | }, 500) |
| 744 | return; | ||
| 744 | } | 745 | } |
| 745 | const container: any = containerRef.value; | 746 | const container: any = containerRef.value; |
| 746 | const width = container.clientWidth; | 747 | const width = container.clientWidth; | ... | ... |
| 1 | <script lang="ts" setup name="topbar"> | ||
| 2 | import { ref, watch } from 'vue'; | ||
| 3 | |||
| 4 | const props = defineProps({ | ||
| 5 | isGraphDisplay: { | ||
| 6 | type: Boolean, | ||
| 7 | default: true | ||
| 8 | }, | ||
| 9 | }); | ||
| 10 | |||
| 11 | const isGraph = ref(false); | ||
| 12 | |||
| 13 | watch(() => props.isGraphDisplay, (val) => { | ||
| 14 | isGraph.value = val; | ||
| 15 | }, { | ||
| 16 | immediate: true | ||
| 17 | }) | ||
| 18 | |||
| 19 | const emits = defineEmits(["displaySwitchChange"]); | ||
| 20 | |||
| 21 | const switchChange = (val) => { | ||
| 22 | isGraph.value = val | ||
| 23 | emits('displaySwitchChange', val); | ||
| 24 | } | ||
| 25 | |||
| 26 | </script> | ||
| 27 | |||
| 28 | <template> | ||
| 29 | <div className='g6-component-topbar-content'> | ||
| 30 | <div :class="isGraph ? 'selected g6-component-topbar-item' : 'g6-component-topbar-item'" @click="switchChange(true)"> | ||
| 31 | 关系网 | ||
| 32 | </div> | ||
| 33 | <div :class="!isGraph ? 'selected g6-component-topbar-item' : 'g6-component-topbar-item'" @click="switchChange(false)"> | ||
| 34 | 桑基图 | ||
| 35 | </div> | ||
| 36 | </div> | ||
| 37 | </template> | ||
| 38 | |||
| 39 | <style scoped lang="scss"> | ||
| 40 | .g6-component-topbar-content { | ||
| 41 | display: flex; | ||
| 42 | flex-direction: row; | ||
| 43 | justify-content: center; | ||
| 44 | align-items: center; | ||
| 45 | background: #fff; | ||
| 46 | border: 1px solid var(--el-color-primary); | ||
| 47 | border-radius: 32px; | ||
| 48 | padding: 4px; | ||
| 49 | width: 138px; | ||
| 50 | height: 32px; | ||
| 51 | } | ||
| 52 | |||
| 53 | .g6-component-topbar-item { | ||
| 54 | width: 50%; | ||
| 55 | height: 100%; | ||
| 56 | display: flex; | ||
| 57 | align-items: center; | ||
| 58 | justify-content: center; | ||
| 59 | font-size: 14px; | ||
| 60 | color: #999999; | ||
| 61 | cursor: pointer; | ||
| 62 | |||
| 63 | &.selected { | ||
| 64 | background: #4FA1A4; | ||
| 65 | border-radius: 32px; | ||
| 66 | color: #fff; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/components/RelationNetwork/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div ref="containerRef" className='canvas-wrapper'> | ||
| 3 | <div class="main" ref="tooltip1Ref" style="display: none;position: absolute;" v-loading="detailLoading"> | ||
| 4 | <div class="title">{{ detailInfoLabel }}</div> | ||
| 5 | <div class="row" v-for="item in Object.keys(detailInfo)"> | ||
| 6 | <span>{{ item + ':' }}</span> | ||
| 7 | <span>{{ detailInfo[item] == null || detailInfo[item] == '' ? '-' : detailInfo[item] }}</span> | ||
| 8 | </div> | ||
| 9 | </div> | ||
| 10 | </div> | ||
| 11 | </template> | ||
| 12 | |||
| 13 | <script lang="ts" setup name="RelationNetwork"> | ||
| 14 | import { ref, onMounted } from 'vue' | ||
| 15 | import G6 from '@antv/g6'; | ||
| 16 | import insertCss from 'insert-css'; | ||
| 17 | import { | ||
| 18 | getMetaStandardFieldDetail | ||
| 19 | } from '@/api/modules/dataMetaService'; | ||
| 20 | import { ElMessage } from 'element-plus'; | ||
| 21 | |||
| 22 | const props = defineProps({ | ||
| 23 | treeData: { | ||
| 24 | type: Object, | ||
| 25 | default: {} | ||
| 26 | }, | ||
| 27 | noContextMenu: { //关系查看页面,显示右键菜单定位到详情。标准查询页面,显示引用标准新建数据集 | ||
| 28 | type: Boolean, | ||
| 29 | default: false | ||
| 30 | } | ||
| 31 | }) | ||
| 32 | |||
| 33 | const emits = defineEmits([ | ||
| 34 | 'nodeItemClick', | ||
| 35 | 'contextMenu' | ||
| 36 | ]); | ||
| 37 | |||
| 38 | const { proxy } = getCurrentInstance() as any; | ||
| 39 | |||
| 40 | const maxChineseCount = ref(16); | ||
| 41 | |||
| 42 | const maxEnglishCount = ref(26); | ||
| 43 | |||
| 44 | const detailLoading = ref(false); | ||
| 45 | |||
| 46 | const detailInfo: any = ref({}); | ||
| 47 | |||
| 48 | const detailInfoLabel = ref(''); | ||
| 49 | |||
| 50 | const containerRef = ref(); | ||
| 51 | |||
| 52 | const graphRef = ref(); | ||
| 53 | |||
| 54 | watch(() => props.treeData, (val) => { | ||
| 55 | if (!graphRef.value && val?.guid) { | ||
| 56 | nextTick(() => { | ||
| 57 | initGraph(); | ||
| 58 | }) | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | if (!graphRef.value) { | ||
| 62 | return; | ||
| 63 | } | ||
| 64 | tooltip1Ref.value.style.display = 'none'; | ||
| 65 | if (lastSelectNode.value) { | ||
| 66 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 67 | labelCfg: { | ||
| 68 | color: '#212121' | ||
| 69 | }, | ||
| 70 | style: { | ||
| 71 | stroke: '#4fa1a4', | ||
| 72 | fill: '#ebf6f7', | ||
| 73 | cursor: 'pointer' | ||
| 74 | } | ||
| 75 | }); | ||
| 76 | } | ||
| 77 | lastSelectNode.value = null; | ||
| 78 | if (val) { | ||
| 79 | renderGraph(graphRef.value, val); | ||
| 80 | } | ||
| 81 | }) | ||
| 82 | |||
| 83 | const renderGraph = (graph: any, lineageData: any) => { | ||
| 84 | if (!graph || !lineageData) return; | ||
| 85 | graph.setMinZoom(1); | ||
| 86 | graph.setMaxZoom(1); | ||
| 87 | graph.data(lineageData); | ||
| 88 | graph.render(); | ||
| 89 | |||
| 90 | graph.fitView(40, { direction: 'both' }); | ||
| 91 | graph.fitCenter(); | ||
| 92 | |||
| 93 | graph.setMinZoom(0.5); | ||
| 94 | graph.setMaxZoom(5); | ||
| 95 | |||
| 96 | }; | ||
| 97 | |||
| 98 | const detectLanguage = (text) => { | ||
| 99 | if (!text) { | ||
| 100 | return 'English'; | ||
| 101 | } | ||
| 102 | let chineseCount = 0; | ||
| 103 | let englishCount = 0; | ||
| 104 | |||
| 105 | for (let char of text) { | ||
| 106 | if (/[\u4e00-\u9fa5]/.test(char)) { | ||
| 107 | chineseCount++; | ||
| 108 | } else if (/[a-zA-Z]/.test(char)) { | ||
| 109 | englishCount++; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | if (chineseCount > englishCount) { | ||
| 114 | return 'Chinese'; | ||
| 115 | } else if (englishCount > chineseCount) { | ||
| 116 | return 'English'; | ||
| 117 | } | ||
| 118 | return 'English'; | ||
| 119 | } | ||
| 120 | |||
| 121 | const handleLabelLength = (label: string) => { | ||
| 122 | if (detectLanguage(label) == 'English') { | ||
| 123 | return label?.length > maxEnglishCount.value ? label.slice(0, maxEnglishCount.value) + '...' : label; | ||
| 124 | } | ||
| 125 | let arr = label.split('\n'); | ||
| 126 | let maxLen = Math.max(...arr.map(s => s.length)); | ||
| 127 | return maxLen > maxChineseCount.value ? label.slice(0, maxChineseCount.value) + '...' : label; | ||
| 128 | }; | ||
| 129 | |||
| 130 | insertCss(` | ||
| 131 | .g6-component-contextmenu { | ||
| 132 | padding: 8px 0px; | ||
| 133 | background-color: #fff; | ||
| 134 | } | ||
| 135 | .context-menu { | ||
| 136 | display: flex; | ||
| 137 | flex-direction: column; | ||
| 138 | } | ||
| 139 | .menu-item { | ||
| 140 | line-height: 32px; | ||
| 141 | color: #212121; | ||
| 142 | cursor: pointer; | ||
| 143 | padding: 0 12px; | ||
| 144 | } | ||
| 145 | .menu-item:hover { | ||
| 146 | background-color: #f5f5f5; | ||
| 147 | } | ||
| 148 | `); | ||
| 149 | |||
| 150 | const tooltip = ref(); | ||
| 151 | |||
| 152 | const initGraph = () => { | ||
| 153 | const container: any = containerRef.value; | ||
| 154 | const width = container.clientWidth; | ||
| 155 | const height = container.clientHeight - 10; | ||
| 156 | |||
| 157 | tooltip.value = new G6.Tooltip({ | ||
| 158 | offsetX: 10, | ||
| 159 | offsetY: 10, | ||
| 160 | trigger: 'mouseenter', | ||
| 161 | // 允许出现 tooltip 的 item 类型 | ||
| 162 | itemTypes: ['node'], | ||
| 163 | // 自定义 tooltip 内容 | ||
| 164 | shouldBegin: (evt: any) => { | ||
| 165 | const { item, target } = evt; | ||
| 166 | const currentAnchor = target.get('name'); | ||
| 167 | const name = item._cfg.model?.label; | ||
| 168 | if (currentAnchor == 'text-shape') { | ||
| 169 | if (detectLanguage(name) == 'English') { | ||
| 170 | return name?.length > maxEnglishCount.value; | ||
| 171 | } | ||
| 172 | let arr = name.split('\n'); | ||
| 173 | let maxLen = Math.max(...arr.map(s => s.length)); | ||
| 174 | return maxLen > maxChineseCount.value; | ||
| 175 | } | ||
| 176 | return false; | ||
| 177 | }, | ||
| 178 | getContent: (e: any) => { | ||
| 179 | |||
| 180 | const { item, target } = e; | ||
| 181 | const currentAnchor = target.get('name'); | ||
| 182 | const outDiv = document.createElement('div'); | ||
| 183 | outDiv.className = 'node'; | ||
| 184 | outDiv.style.width = 'fit-content'; | ||
| 185 | const name = item._cfg.model.isField ? item._cfg.model.metaStandardId : item._cfg.model.standardName; | ||
| 186 | if (currentAnchor == 'text-shape') { | ||
| 187 | outDiv.innerHTML = `<h4>${name}</h4>` | ||
| 188 | } | ||
| 189 | return outDiv; | ||
| 190 | }, | ||
| 191 | }); | ||
| 192 | |||
| 193 | const contextMenu = new G6.Menu({ | ||
| 194 | getContent(evt: any) { | ||
| 195 | const { item, target } = evt; | ||
| 196 | let model = item._cfg.model; | ||
| 197 | if (props.noContextMenu) { | ||
| 198 | return ` | ||
| 199 | <div class='context-menu'> | ||
| 200 | <span class='menu-item'>查看标准管理</span> | ||
| 201 | </div>` | ||
| 202 | } else { | ||
| 203 | return ` | ||
| 204 | <div class='context-menu'> | ||
| 205 | <span class='menu-item'>引用标准新建数据集</span> | ||
| 206 | </div>` | ||
| 207 | } | ||
| 208 | }, | ||
| 209 | shouldBegin: (evt: any) => { | ||
| 210 | const { item, target } = evt; | ||
| 211 | let model = item._cfg.model; | ||
| 212 | if (props.noContextMenu) { | ||
| 213 | // return false; | ||
| 214 | if (model && !model.isField) { | ||
| 215 | return true; | ||
| 216 | } | ||
| 217 | return false; | ||
| 218 | } | ||
| 219 | if (model && !model.isField && !model.children?.length) { | ||
| 220 | return true; | ||
| 221 | } | ||
| 222 | if (model.children?.length && model.children[0].isField) { | ||
| 223 | return true; | ||
| 224 | } | ||
| 225 | return false; | ||
| 226 | }, | ||
| 227 | handleMenuClick: (target, item: any) => { | ||
| 228 | let model = item._cfg?.model; | ||
| 229 | if (!model) { | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | emits('contextMenu', model); | ||
| 233 | }, | ||
| 234 | // offsetX and offsetY include the padding of the parent container | ||
| 235 | // 需要加上父级容器的 padding-left 16 与自身偏移量 10 | ||
| 236 | offsetX: 16, | ||
| 237 | // 需要加上父级容器的 padding-top 24 、画布兄弟元素高度、与自身偏移量 10 | ||
| 238 | offsetY: 0, | ||
| 239 | // the types of items that allow the menu show up | ||
| 240 | // 在哪些类型的元素上响应 | ||
| 241 | itemTypes: ['node'], | ||
| 242 | }); | ||
| 243 | |||
| 244 | const graph = new G6.TreeGraph({ | ||
| 245 | container: container, | ||
| 246 | width, | ||
| 247 | height, | ||
| 248 | // animate: false, | ||
| 249 | plugins: [contextMenu, tooltip.value], | ||
| 250 | fitCenter: true, | ||
| 251 | fitView: true, | ||
| 252 | fitViewPadding: 40, | ||
| 253 | minZoom: 0.7, | ||
| 254 | maxZoom: 1, | ||
| 255 | modes: { | ||
| 256 | default: [ | ||
| 257 | { | ||
| 258 | type: 'collapse-expand', | ||
| 259 | onChange: (item, collapsed) => { | ||
| 260 | if (!item) { | ||
| 261 | return; | ||
| 262 | } | ||
| 263 | const data = item.getModel(); | ||
| 264 | data.collapsed = collapsed; | ||
| 265 | setTimeout(() => { | ||
| 266 | graph.focusItem(item, true, { | ||
| 267 | duration: 400 // 动画时长为500ms | ||
| 268 | }); | ||
| 269 | }, 500) | ||
| 270 | return true; | ||
| 271 | }, | ||
| 272 | shouldBegin: (e) => { | ||
| 273 | // 若当前操作的节点 id 为 'node1',则不发生 collapse-expand | ||
| 274 | if (e.item && e.item.getModel().isLoading == true) return false; | ||
| 275 | return true; | ||
| 276 | }, | ||
| 277 | }, | ||
| 278 | 'drag-canvas', | ||
| 279 | 'zoom-canvas', | ||
| 280 | ], | ||
| 281 | }, | ||
| 282 | defaultNode: { | ||
| 283 | size: 16, | ||
| 284 | anchorPoints: [ | ||
| 285 | [0, 0.5], | ||
| 286 | [1, 0.5], | ||
| 287 | ], | ||
| 288 | style: { | ||
| 289 | // stroke: '#4fa1a4', | ||
| 290 | fill: '#ebf6f7', | ||
| 291 | cursor: 'pointer' | ||
| 292 | }, | ||
| 293 | }, | ||
| 294 | defaultEdge: { | ||
| 295 | type: 'cubic-horizontal', | ||
| 296 | }, | ||
| 297 | layout: { | ||
| 298 | type: 'compactBox', | ||
| 299 | direction: 'LR', | ||
| 300 | getId: function getId(d) { | ||
| 301 | return d.id; | ||
| 302 | }, | ||
| 303 | getHeight: function getHeight() { | ||
| 304 | return 16; | ||
| 305 | }, | ||
| 306 | getWidth: function getWidth() { | ||
| 307 | return 16; | ||
| 308 | }, | ||
| 309 | getVGap: function getVGap(node) { | ||
| 310 | if (node.isField) { | ||
| 311 | return 6; | ||
| 312 | } | ||
| 313 | return 20; | ||
| 314 | }, | ||
| 315 | getHGap: function getHGap() { | ||
| 316 | return 120; | ||
| 317 | }, | ||
| 318 | }, | ||
| 319 | }); | ||
| 320 | graphRef.value = graph; | ||
| 321 | graph.node((node) => { | ||
| 322 | return { | ||
| 323 | size: node.isField ? 11 : 16, | ||
| 324 | id: node.guid as string, | ||
| 325 | label: handleLabelLength((node.isField ? node.metaStandardId : node.standardName) as string), | ||
| 326 | collapsed: node.children?.length ? false : true, | ||
| 327 | labelCfg: { | ||
| 328 | offset: node.isField ? 4 : 7, | ||
| 329 | style: { | ||
| 330 | fontSize: 13, | ||
| 331 | fill: '#212121', | ||
| 332 | fontWeight: 500, | ||
| 333 | cursor: 'pointer' | ||
| 334 | }, | ||
| 335 | position: !node.isField ? 'left' : 'right', //只有字段是最后一层级,不需要展开 | ||
| 336 | }, | ||
| 337 | style: { | ||
| 338 | stroke: '#4fa1a4', | ||
| 339 | cursor: 'pointer' | ||
| 340 | } | ||
| 341 | }; | ||
| 342 | }); | ||
| 343 | // data不是数组,第一级是根节点 | ||
| 344 | props.treeData?.guid && graph.data(props.treeData); | ||
| 345 | graph.render(); | ||
| 346 | graph.fitView(40, { direction: 'both' }); | ||
| 347 | graph.fitCenter(); | ||
| 348 | |||
| 349 | graph.setMinZoom(0.5); | ||
| 350 | graph.setMaxZoom(5); | ||
| 351 | bindEvents(); | ||
| 352 | observeResize(); | ||
| 353 | } | ||
| 354 | |||
| 355 | onMounted(() => { | ||
| 356 | nextTick(() => { | ||
| 357 | if (!graphRef.value && props.treeData?.guid) { | ||
| 358 | initGraph(); | ||
| 359 | } | ||
| 360 | }) | ||
| 361 | |||
| 362 | }) | ||
| 363 | |||
| 364 | const observeResize = () => { | ||
| 365 | window.addEventListener('resize', (e) => { | ||
| 366 | let domWidth = document.documentElement.clientWidth; | ||
| 367 | if (lastSelectNode.value) { | ||
| 368 | tooltip1Ref.value.style.display = 'none'; | ||
| 369 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 370 | labelCfg: { | ||
| 371 | style: { | ||
| 372 | fill: '#212121', | ||
| 373 | }, | ||
| 374 | }, | ||
| 375 | style: { | ||
| 376 | stroke: '#4fa1a4', | ||
| 377 | fill: '#ebf6f7', | ||
| 378 | cursor: 'pointer' | ||
| 379 | } | ||
| 380 | }); | ||
| 381 | } | ||
| 382 | lastSelectNode.value = null; | ||
| 383 | if (domWidth < 992) {//根据setting.ts里的设置,小于992,会隐藏左边的菜单栏, | ||
| 384 | setTimeout(() => { | ||
| 385 | const container: any = containerRef.value; | ||
| 386 | const width = container.clientWidth; | ||
| 387 | const height = container.clientHeight - 10; | ||
| 388 | if (!width) {//会把隐藏的给消失。 | ||
| 389 | return; | ||
| 390 | } | ||
| 391 | graphRef.value.changeSize(width, height); | ||
| 392 | graphRef.value.setMinZoom(1); | ||
| 393 | graphRef.value.setMaxZoom(1); | ||
| 394 | graphRef.value.fitView(40, { direction: 'both' }); | ||
| 395 | graphRef.value.fitCenter(); | ||
| 396 | graphRef.value.setMinZoom(0.5); | ||
| 397 | graphRef.value.setMaxZoom(5); | ||
| 398 | }, 500) | ||
| 399 | return; | ||
| 400 | } | ||
| 401 | const container: any = containerRef.value; | ||
| 402 | const width = container.clientWidth; | ||
| 403 | const height = container.clientHeight - 10; | ||
| 404 | if (!width) {//会把隐藏的给消失。 | ||
| 405 | return; | ||
| 406 | } | ||
| 407 | graphRef.value.changeSize(width, height); | ||
| 408 | graphRef.value.setMinZoom(1); | ||
| 409 | graphRef.value.setMaxZoom(1); | ||
| 410 | graphRef.value.fitView(40, { direction: 'both' }); | ||
| 411 | graphRef.value.fitCenter(); | ||
| 412 | graphRef.value.setMinZoom(0.5); | ||
| 413 | graphRef.value.setMaxZoom(5); | ||
| 414 | }); | ||
| 415 | } | ||
| 416 | |||
| 417 | |||
| 418 | const tooltip1Ref = ref(); | ||
| 419 | |||
| 420 | // 更新tooltip的位置 | ||
| 421 | function updateTooltipPosition(evt) { | ||
| 422 | var width = graphRef.value.get("width"); | ||
| 423 | var height = graphRef.value.get("height"); | ||
| 424 | var offsetX = 10; | ||
| 425 | var offsetY = 10; | ||
| 426 | var point = graphRef.value.getPointByClient(evt.clientX, evt.clientY); | ||
| 427 | var _a2 = graphRef.value.getCanvasByPoint(point.x, point.y), x4 = _a2.x, y4 = _a2.y; | ||
| 428 | var graphContainer = graphRef.value.getContainer(); | ||
| 429 | var res = { | ||
| 430 | x: x4 + graphContainer.offsetLeft + offsetX, | ||
| 431 | y: y4 + graphContainer.offsetTop + offsetY | ||
| 432 | }; | ||
| 433 | let bbox = tooltip1Ref.value.getBoundingClientRect(); | ||
| 434 | let bboxHeight = bbox.height; | ||
| 435 | if (x4 + 320 + offsetX > width) { | ||
| 436 | res.x -= 320 + offsetX; | ||
| 437 | } | ||
| 438 | if (y4 + bboxHeight + offsetY > height) { | ||
| 439 | res.y -= bboxHeight + offsetY; | ||
| 440 | if (res.y < 0) { | ||
| 441 | res.y = 0; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | tooltip1Ref.value.style.left = `${res.x}px`; | ||
| 445 | tooltip1Ref.value.style.top = `${res.y}px`; | ||
| 446 | tooltip1Ref.value.style.display = 'block'; | ||
| 447 | } | ||
| 448 | |||
| 449 | const lastSelectNode = ref(null); | ||
| 450 | |||
| 451 | const bindEvents = () => { | ||
| 452 | let graph = graphRef.value; | ||
| 453 | if (!graph) { | ||
| 454 | return; | ||
| 455 | } | ||
| 456 | graph.on('node:click', function (evt) { | ||
| 457 | const item = evt.item; | ||
| 458 | if (!item) { | ||
| 459 | return; | ||
| 460 | } | ||
| 461 | const nodeId = item.get('guid'); | ||
| 462 | const model = <any>item.getModel(); | ||
| 463 | if (lastSelectNode.value) { | ||
| 464 | if (lastSelectNode.value == item) { | ||
| 465 | return; | ||
| 466 | } | ||
| 467 | tooltip1Ref.value.style.display = 'none'; | ||
| 468 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 469 | labelCfg: { | ||
| 470 | style: { | ||
| 471 | fill: '#212121', | ||
| 472 | } | ||
| 473 | }, | ||
| 474 | style: { | ||
| 475 | stroke: '#4fa1a4', | ||
| 476 | fill: '#ebf6f7', | ||
| 477 | cursor: 'pointer' | ||
| 478 | } | ||
| 479 | }); | ||
| 480 | lastSelectNode.value = null; | ||
| 481 | } | ||
| 482 | const children = model.children; | ||
| 483 | if (children?.length && !model.isField) { | ||
| 484 | return; | ||
| 485 | } | ||
| 486 | if (model.isField) { //是字段级别,就不需要再展开了 | ||
| 487 | graphRef.value.updateItem(item, { | ||
| 488 | labelCfg: { | ||
| 489 | style: { | ||
| 490 | fill: '#4fa1a4' | ||
| 491 | } | ||
| 492 | }, | ||
| 493 | style: { | ||
| 494 | stroke: '#4fa1a4', | ||
| 495 | fill: '#4fa1a4', | ||
| 496 | cursor: 'pointer' | ||
| 497 | } | ||
| 498 | }); | ||
| 499 | lastSelectNode.value = item; | ||
| 500 | detailInfo.value = {}; | ||
| 501 | // detailInfo.value.guid = model.guid; | ||
| 502 | detailInfoLabel.value = model.metaStandardId || {}; | ||
| 503 | detailLoading.value = true; | ||
| 504 | nextTick(() => { | ||
| 505 | tooltip1Ref.value.style.display = 'block'; | ||
| 506 | updateTooltipPosition(evt); | ||
| 507 | getMetaStandardFieldDetail(model.guid).then((res: any) => { | ||
| 508 | |||
| 509 | if (res?.code == proxy.$passCode) { | ||
| 510 | detailInfo.value = res.data?.metaStandardValue || {}; | ||
| 511 | detailInfoLabel.value = model.metaStandardId; | ||
| 512 | detailLoading.value = false; | ||
| 513 | nextTick(() => { | ||
| 514 | tooltip1Ref.value.style.display = 'block'; | ||
| 515 | updateTooltipPosition(evt); | ||
| 516 | }) | ||
| 517 | } else { | ||
| 518 | ElMessage.error(res.msg); | ||
| 519 | } | ||
| 520 | }) | ||
| 521 | }) | ||
| 522 | return; | ||
| 523 | } | ||
| 524 | evt.preventDefault(); | ||
| 525 | evt.stopPropagation(); | ||
| 526 | model.isLoading = true; | ||
| 527 | emits('nodeItemClick', graph, item); | ||
| 528 | }); | ||
| 529 | graph.on('dragstart', (evt: any) => { | ||
| 530 | if (evt.item?.getType() == 'node') { | ||
| 531 | return; | ||
| 532 | } | ||
| 533 | // 清除状态 | ||
| 534 | if (lastSelectNode.value) { | ||
| 535 | tooltip1Ref.value.style.display = 'none'; | ||
| 536 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 537 | labelCfg: { | ||
| 538 | style: { | ||
| 539 | fill: '#212121', | ||
| 540 | }, | ||
| 541 | }, | ||
| 542 | style: { | ||
| 543 | stroke: '#4fa1a4', | ||
| 544 | fill: '#ebf6f7', | ||
| 545 | cursor: 'pointer' | ||
| 546 | } | ||
| 547 | }); | ||
| 548 | } | ||
| 549 | lastSelectNode.value = null; | ||
| 550 | }) | ||
| 551 | graph.on('click', (evt: any) => { | ||
| 552 | if (evt.item?.getType() == 'node') { | ||
| 553 | return; | ||
| 554 | } | ||
| 555 | // 清除状态 | ||
| 556 | if (lastSelectNode.value) { | ||
| 557 | tooltip1Ref.value.style.display = 'none'; | ||
| 558 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 559 | labelCfg: { | ||
| 560 | style: { | ||
| 561 | fill: '#212121', | ||
| 562 | }, | ||
| 563 | }, | ||
| 564 | style: { | ||
| 565 | stroke: '#4fa1a4', | ||
| 566 | fill: '#ebf6f7', | ||
| 567 | cursor: 'pointer' | ||
| 568 | } | ||
| 569 | }); | ||
| 570 | } | ||
| 571 | lastSelectNode.value = null; | ||
| 572 | }); | ||
| 573 | graph.on('canvas:click', (evt: any) => { | ||
| 574 | // 清除状态 | ||
| 575 | if (lastSelectNode.value) { | ||
| 576 | tooltip1Ref.value.style.display = 'none'; | ||
| 577 | graphRef.value.updateItem(lastSelectNode.value, { | ||
| 578 | labelCfg: { | ||
| 579 | style: { | ||
| 580 | fill: '#212121', | ||
| 581 | }, | ||
| 582 | }, | ||
| 583 | style: { | ||
| 584 | stroke: '#4fa1a4', | ||
| 585 | fill: '#ebf6f7', | ||
| 586 | cursor: 'pointer' | ||
| 587 | } | ||
| 588 | }); | ||
| 589 | } | ||
| 590 | lastSelectNode.value = null; | ||
| 591 | }); | ||
| 592 | } | ||
| 593 | |||
| 594 | const destroy = () => { | ||
| 595 | graphRef.value?.destroy(); | ||
| 596 | } | ||
| 597 | |||
| 598 | defineExpose({ | ||
| 599 | destroy, | ||
| 600 | }); | ||
| 601 | |||
| 602 | </script> | ||
| 603 | |||
| 604 | <style lang="scss" scoped> | ||
| 605 | .canvas-wrapper { | ||
| 606 | width: 100%; | ||
| 607 | height: 100%; | ||
| 608 | position: relative; | ||
| 609 | overflow: hidden; | ||
| 610 | } | ||
| 611 | |||
| 612 | .canvas-wrapper:-webkit-full-screen { | ||
| 613 | background-color: white; | ||
| 614 | } | ||
| 615 | |||
| 616 | .canvas-wrapper:-moz-full-screen { | ||
| 617 | background-color: white; | ||
| 618 | } | ||
| 619 | |||
| 620 | .canvas-wrapper:-ms-fullscreen { | ||
| 621 | background-color: white; | ||
| 622 | } | ||
| 623 | |||
| 624 | .canvas-wrapper:fullscreen { | ||
| 625 | background-color: white; | ||
| 626 | } | ||
| 627 | |||
| 628 | .main { | ||
| 629 | padding: 16px; | ||
| 630 | box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.08); | ||
| 631 | background-color: #fff; | ||
| 632 | width: 320px; | ||
| 633 | min-height: 100px; | ||
| 634 | max-height: 400px; | ||
| 635 | overflow-y: auto; | ||
| 636 | |||
| 637 | .title { | ||
| 638 | font-size: 14px; | ||
| 639 | color: #212121; | ||
| 640 | line-height: 24px; | ||
| 641 | font-weight: 600; | ||
| 642 | } | ||
| 643 | |||
| 644 | .row { | ||
| 645 | margin-top: 8px; | ||
| 646 | font-size: 12px; | ||
| 647 | color: #666666; | ||
| 648 | word-break: break-all; | ||
| 649 | line-height: 18px; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -248,6 +248,7 @@ onMounted(() => { | ... | @@ -248,6 +248,7 @@ onMounted(() => { |
| 248 | :show-header="props.tableInfo.showHeader ?? true" stripe :border="props.tableInfo.border | 248 | :show-header="props.tableInfo.showHeader ?? true" stripe :border="props.tableInfo.border |
| 249 | ?? true" :height="props.tableInfo.height === null ? null : (props.tableInfo.height ?? '100%')" | 249 | ?? true" :height="props.tableInfo.height === null ? null : (props.tableInfo.height ?? '100%')" |
| 250 | :max-height="maxHeight" :row-key="rowKey" :current-row-key="currentRowKey" :row-class-name="rowClassName" | 250 | :max-height="maxHeight" :row-key="rowKey" :current-row-key="currentRowKey" :row-class-name="rowClassName" |
| 251 | :tree-props="props.tableInfo.treeProps" :default-expand-all="props.tableInfo.expandAll ?? false" | ||
| 251 | :expand-row-keys="props.tableInfo.expandedKey" v-loading="tableDataLoading" @row-click="rowClick" | 252 | :expand-row-keys="props.tableInfo.expandedKey" v-loading="tableDataLoading" @row-click="rowClick" |
| 252 | @row-dblclick="rowDblClick" @selection-change="selectionChange" @select="tableCheckboxSelectChange" | 253 | @row-dblclick="rowDblClick" @selection-change="selectionChange" @select="tableCheckboxSelectChange" |
| 253 | @select-all="tableCheckboxAllSelectChange" style="width: 100%; display: inline-block" | 254 | @select-all="tableCheckboxAllSelectChange" style="width: 100%; display: inline-block" | ... | ... |
| ... | @@ -42,20 +42,20 @@ const checkKeys = computed(() => { | ... | @@ -42,20 +42,20 @@ const checkKeys = computed(() => { |
| 42 | return props.treeInfo.checkedKey ?? [] | 42 | return props.treeInfo.checkedKey ?? [] |
| 43 | }); | 43 | }); |
| 44 | const currentNodeKey = computed(() => { | 44 | const currentNodeKey = computed(() => { |
| 45 | // if (props.treeInfo.currentNodeKey) { | 45 | if (props.treeInfo.currentNodeKey) { |
| 46 | // nextTick(() => { | 46 | nextTick(() => { |
| 47 | // let domItems = treeRef.value?.$el.getElementsByClassName('el-tree-node'); | 47 | let domItems = treeRef.value?.$el.getElementsByClassName('el-tree-node'); |
| 48 | // let clientHeight = treeRef.value?.$el.clientHeight; | 48 | let clientHeight = treeRef.value?.$el.clientHeight; |
| 49 | // for (const item of domItems) { | 49 | for (const item of domItems) { |
| 50 | // if (item.getAttribute('data-key') == props.treeInfo.currentNodeKey) { | 50 | if (item.getAttribute('data-key') == props.treeInfo.currentNodeKey) { |
| 51 | // if (item.offsetTop > clientHeight) { | 51 | if (item.offsetTop > clientHeight) { |
| 52 | // item.scrollIntoView({ block: "end", inline: "nearest" }); | 52 | item.scrollIntoView({ block: "end", inline: "nearest" }); |
| 53 | // } | 53 | } |
| 54 | // break; | 54 | break; |
| 55 | // } | 55 | } |
| 56 | // } | 56 | } |
| 57 | // }) | 57 | }) |
| 58 | // } | 58 | } |
| 59 | return props.treeInfo.currentNodeKey ?? '' | 59 | return props.treeInfo.currentNodeKey ?? '' |
| 60 | }); | 60 | }); |
| 61 | const customInfo = computed(() => { | 61 | const customInfo = computed(() => { |
| ... | @@ -70,6 +70,9 @@ const editTreeItem = computed(() => { | ... | @@ -70,6 +70,9 @@ const editTreeItem = computed(() => { |
| 70 | const expendAll = computed(() => { | 70 | const expendAll = computed(() => { |
| 71 | return props.treeInfo.expendAll ?? false | 71 | return props.treeInfo.expendAll ?? false |
| 72 | }) | 72 | }) |
| 73 | const ellipsis = computed(() => { | ||
| 74 | return props.treeInfo.ellipsis ?? true | ||
| 75 | }) | ||
| 73 | 76 | ||
| 74 | interface Tree { | 77 | interface Tree { |
| 75 | [key: string]: any; | 78 | [key: string]: any; |
| ... | @@ -182,6 +185,21 @@ const appendChildren = (key, data) => { | ... | @@ -182,6 +185,21 @@ const appendChildren = (key, data) => { |
| 182 | 185 | ||
| 183 | const visibleNodes = ref({}); //解决点击树item,下拉菜单不消失的问题,原因是树的点击事件阻止冒泡了。 | 186 | const visibleNodes = ref({}); //解决点击树item,下拉菜单不消失的问题,原因是树的点击事件阻止冒泡了。 |
| 184 | 187 | ||
| 188 | function formatNodeLabel (node) { | ||
| 189 | let sliceLength = 8 | ||
| 190 | switch (node.level) { | ||
| 191 | case 2: | ||
| 192 | sliceLength = 9 | ||
| 193 | break | ||
| 194 | case 3: | ||
| 195 | sliceLength = 6 | ||
| 196 | break | ||
| 197 | case 4: | ||
| 198 | sliceLength = 6 | ||
| 199 | break | ||
| 200 | } | ||
| 201 | return node.label.slice(0, sliceLength) | ||
| 202 | } | ||
| 185 | defineExpose({ | 203 | defineExpose({ |
| 186 | getCheckedNodes, | 204 | getCheckedNodes, |
| 187 | getCheckedKeys, | 205 | getCheckedKeys, |
| ... | @@ -225,8 +243,14 @@ defineExpose({ | ... | @@ -225,8 +243,14 @@ defineExpose({ |
| 225 | </span> | 243 | </span> |
| 226 | <template v-else-if="editTreeItem && data.showEdit !== false"> | 244 | <template v-else-if="editTreeItem && data.showEdit !== false"> |
| 227 | <span class="list-item-text"> | 245 | <span class="list-item-text"> |
| 228 | <ellipsis-tooltip v-if="!customInfo" :content="node.label" class-name="w100f" | 246 | <template v-if="!ellipsis"> |
| 247 | <span>{{ formatNodeLabel(node) }}</span> | ||
| 248 | </template> | ||
| 249 | <template v-else> | ||
| 250 | <ellipsis-tooltip v-if="!customInfo" :content="node.label" class-name="w100f" popper-class="tree-popper" | ||
| 229 | :refName="'tooltipOver' + node.id"></ellipsis-tooltip> | 251 | :refName="'tooltipOver' + node.id"></ellipsis-tooltip> |
| 252 | </template> | ||
| 253 | |||
| 230 | </span> | 254 | </span> |
| 231 | <div class="tags-list-right" :class="visibleNodes[node.data.guid] ? 'active' : ''"> | 255 | <div class="tags-list-right" :class="visibleNodes[node.data.guid] ? 'active' : ''"> |
| 232 | <el-popover v-model:visible="visibleNodes[node.data.guid]" placement="bottom" width="96" trigger="click" | 256 | <el-popover v-model:visible="visibleNodes[node.data.guid]" placement="bottom" width="96" trigger="click" | ... | ... |
| ... | @@ -4,7 +4,7 @@ import { ElMessage, genFileId } from "element-plus"; | ... | @@ -4,7 +4,7 @@ import { ElMessage, genFileId } from "element-plus"; |
| 4 | import { Plus, Download, Upload, } from "@element-plus/icons-vue"; | 4 | import { Plus, Download, Upload, } from "@element-plus/icons-vue"; |
| 5 | import type { UploadRawFile } from 'element-plus' | 5 | import type { UploadRawFile } from 'element-plus' |
| 6 | 6 | ||
| 7 | const emits = defineEmits(["onUpload", "beforeUPload", "uploadFile", "uploadBtnClick", "cascaderChange", "selectChange"]); | 7 | const emits = defineEmits(["onUpload", "beforeUPload", "uploadFile", "uploadBtnClick", "cascaderChange", "selectChange", 'deleteFile']); |
| 8 | const props = defineProps({ | 8 | const props = defineProps({ |
| 9 | uploadInfo: { | 9 | uploadInfo: { |
| 10 | type: Object, | 10 | type: Object, |
| ... | @@ -75,6 +75,7 @@ const btnClick = (file, type) => { | ... | @@ -75,6 +75,7 @@ const btnClick = (file, type) => { |
| 75 | if (type == 'remove') { | 75 | if (type == 'remove') { |
| 76 | const fileUpload = fileUploadRef.value[0] || fileUploadRef.value | 76 | const fileUpload = fileUploadRef.value[0] || fileUploadRef.value |
| 77 | fileUpload?.handleRemove(file) | 77 | fileUpload?.handleRemove(file) |
| 78 | emits('deleteFile') | ||
| 78 | } else if (type == 'upload') { | 79 | } else if (type == 'upload') { |
| 79 | file.show = false | 80 | file.show = false |
| 80 | emits('uploadFile', file) | 81 | emits('uploadFile', file) |
| ... | @@ -113,11 +114,14 @@ defineExpose({ | ... | @@ -113,11 +114,14 @@ defineExpose({ |
| 113 | <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label | 114 | <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label |
| 114 | }}:</span> | 115 | }}:</span> |
| 115 | <el-select v-model="extraParams[item.selectInfo.field]" :placeholder="item.selectInfo.placeholder" | 116 | <el-select v-model="extraParams[item.selectInfo.field]" :placeholder="item.selectInfo.placeholder" |
| 116 | :disabled="item.selectInfo.disabled" @change="selectChange"> | 117 | :disabled="item.selectInfo.disabled" @change="selectChange" :filterable="item.selectInfo.filterable" :style="item.selectInfo.style"> |
| 117 | <el-option v-for="opts in item.selectInfo.options" :label="opts.label" :value="opts.value" /> | 118 | <el-option v-for="opts in item.selectInfo.options" |
| 119 | :label="item.selectInfo.props?.label ? opts[item.selectInfo.props.label] : opts.label" | ||
| 120 | :value="item.selectInfo.props?.value ? opts[item.selectInfo.props.value] : opts.value" | ||
| 121 | :disabled="opts.disabled" /> | ||
| 118 | </el-select> | 122 | </el-select> |
| 119 | </div> | 123 | </div> |
| 120 | <div class="form_item" v-if="item.type == 'tree-select'"> | 124 | <div class="form_item" v-else-if="item.type == 'tree-select'"> |
| 121 | <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label | 125 | <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label |
| 122 | }}:</span> | 126 | }}:</span> |
| 123 | <el-tree-select | 127 | <el-tree-select |
| ... | @@ -176,7 +180,7 @@ defineExpose({ | ... | @@ -176,7 +180,7 @@ defineExpose({ |
| 176 | </el-button> | 180 | </el-button> |
| 177 | </div> | 181 | </div> |
| 178 | <el-upload v-else ref="fileUploadRef" class="upload_panel" :class="[props.uploadInfo.col]" | 182 | <el-upload v-else ref="fileUploadRef" class="upload_panel" :class="[props.uploadInfo.col]" |
| 179 | v-model:file-list="fileList" :action="item.uploadInfo.action" :auto-upload="item.uploadInfo.auto ?? ''" | 183 | v-model:file-list="fileList" :action="item.uploadInfo.action ?? ''" :auto-upload="item.uploadInfo.auto ?? ''" |
| 180 | :drag="item.uploadInfo.drag ?? false" :accept="item.uploadInfo.accept" :limit="item.uploadInfo.limit ?? 1" | 184 | :drag="item.uploadInfo.drag ?? false" :accept="item.uploadInfo.accept" :limit="item.uploadInfo.limit ?? 1" |
| 181 | :on-change="onUpload" :on-exceed="val => exceedFile(val, item.uploadInfo.cover ?? false)" | 185 | :on-change="onUpload" :on-exceed="val => exceedFile(val, item.uploadInfo.cover ?? false)" |
| 182 | :on-error="handleError" :on-success="handleSuccess" :before-upload="beforeUPload" | 186 | :on-error="handleError" :on-success="handleSuccess" :before-upload="beforeUPload" | ... | ... |
| ... | @@ -4,6 +4,7 @@ import { useRouter } from "vue-router"; | ... | @@ -4,6 +4,7 @@ import { useRouter } from "vue-router"; |
| 4 | import useUserStore from "@/store/modules/user"; | 4 | import useUserStore from "@/store/modules/user"; |
| 5 | import useKeepAliveStore from '@/store/modules/keepAlive' | 5 | import useKeepAliveStore from '@/store/modules/keepAlive' |
| 6 | import { ElMessageBox, ElMessage } from "element-plus"; | 6 | import { ElMessageBox, ElMessage } from "element-plus"; |
| 7 | import { isEqual } from "lodash-es"; | ||
| 7 | 8 | ||
| 8 | const router = useRouter(); | 9 | const router = useRouter(); |
| 9 | const route = useRoute(); | 10 | const route = useRoute(); |
| ... | @@ -26,7 +27,7 @@ watch( | ... | @@ -26,7 +27,7 @@ watch( |
| 26 | if (tab.fullPath.includes(jionPath)) { | 27 | if (tab.fullPath.includes(jionPath)) { |
| 27 | pathIndex.value = index | 28 | pathIndex.value = index |
| 28 | } | 29 | } |
| 29 | return tab.fullPath === newRouter.fullPath; | 30 | return tab.fullPath === newRouter.fullPath || (tab.path == newRouter.path && isEqual(tab.query, newRouter.query)); |
| 30 | }); | 31 | }); |
| 31 | if (isExist.length == 0) { | 32 | if (isExist.length == 0) { |
| 32 | if (pathIndex.value != -1 && routerLength > 3) { | 33 | if (pathIndex.value != -1 && routerLength > 3) { |
| ... | @@ -45,11 +46,8 @@ watch( | ... | @@ -45,11 +46,8 @@ watch( |
| 45 | 46 | ||
| 46 | } | 47 | } |
| 47 | } | 48 | } |
| 48 | list.map(item => { | ||
| 49 | item.fullPath = item.fullPath; | ||
| 50 | }) | ||
| 51 | tabbarList.value = list; | 49 | tabbarList.value = list; |
| 52 | tabbarActive.value = newRouter.fullPath; | 50 | tabbarActive.value = isExist[0]?.fullPath || newRouter.fullPath; |
| 53 | userStore.setTabbar(tabbarList.value); | 51 | userStore.setTabbar(tabbarList.value); |
| 54 | userStore.setActiveTabbar(combPath, newRouter.fullPath); | 52 | userStore.setActiveTabbar(combPath, newRouter.fullPath); |
| 55 | }, | 53 | }, |
| ... | @@ -58,7 +56,7 @@ watch( | ... | @@ -58,7 +56,7 @@ watch( |
| 58 | const changeTab = (pane: any, ev: any) => { | 56 | const changeTab = (pane: any, ev: any) => { |
| 59 | const tabIndex = Number(pane.index); | 57 | const tabIndex = Number(pane.index); |
| 60 | const paneData: any = tabbarList.value[tabIndex]; | 58 | const paneData: any = tabbarList.value[tabIndex]; |
| 61 | if (paneData.name == 'budgetDataIndex' || paneData.name == 'iframePage') { | 59 | if (paneData.name == 'budgetDataIndex' || paneData.name == 'iframePage' || paneData.name == 'portraitMap' || paneData.name == 'portraitMaps') { |
| 62 | router.push(paneData.fullPath); | 60 | router.push(paneData.fullPath); |
| 63 | } else { | 61 | } else { |
| 64 | router.push({ | 62 | router.push({ | ... | ... |
| ... | @@ -144,7 +144,7 @@ const routes: RouteRecordRaw[] = [ | ... | @@ -144,7 +144,7 @@ const routes: RouteRecordRaw[] = [ |
| 144 | { | 144 | { |
| 145 | path: 'budgetDataIndex', | 145 | path: 'budgetDataIndex', |
| 146 | name: 'budgetDataIndex', | 146 | name: 'budgetDataIndex', |
| 147 | component: () => import('@/views/data_catalog/budgetDataIndex.vue'), | 147 | component: () => import('@/views/data_meta/budgetDataIndex.vue'), |
| 148 | meta: { | 148 | meta: { |
| 149 | title: '', | 149 | title: '', |
| 150 | // sidebar: false, | 150 | // sidebar: false, |
| ... | @@ -166,7 +166,7 @@ const routes: RouteRecordRaw[] = [ | ... | @@ -166,7 +166,7 @@ const routes: RouteRecordRaw[] = [ |
| 166 | { | 166 | { |
| 167 | path: 'iframePage', | 167 | path: 'iframePage', |
| 168 | name: 'iframePage', | 168 | name: 'iframePage', |
| 169 | component: () => import('@/views/data_catalog/budgetDataIndex.vue'), | 169 | component: () => import('@/views/data_meta/budgetDataIndex.vue'), |
| 170 | meta: { | 170 | meta: { |
| 171 | title: '', | 171 | title: '', |
| 172 | sidebar: true, | 172 | sidebar: true, |
| ... | @@ -175,6 +175,19 @@ const routes: RouteRecordRaw[] = [ | ... | @@ -175,6 +175,19 @@ const routes: RouteRecordRaw[] = [ |
| 175 | reuse: true, | 175 | reuse: true, |
| 176 | activeMenu: '/data-meta/reports/iframePage', | 176 | activeMenu: '/data-meta/reports/iframePage', |
| 177 | }, | 177 | }, |
| 178 | }, | ||
| 179 | { | ||
| 180 | path: 'portraitMaps', | ||
| 181 | name: 'portraitMaps', | ||
| 182 | component: () => import('@/views/data_meta/portraitMap.vue'), | ||
| 183 | meta: { | ||
| 184 | title: '全景地图', | ||
| 185 | sidebar: true, | ||
| 186 | breadcrumb: false, | ||
| 187 | cache: true, | ||
| 188 | reuse: true, | ||
| 189 | activeMenu: '/data-meta/reports/portraitMaps', | ||
| 190 | }, | ||
| 178 | } | 191 | } |
| 179 | ] | 192 | ] |
| 180 | }, | 193 | }, |
| ... | @@ -199,6 +212,119 @@ const routes: RouteRecordRaw[] = [ | ... | @@ -199,6 +212,119 @@ const routes: RouteRecordRaw[] = [ |
| 199 | }, | 212 | }, |
| 200 | } | 213 | } |
| 201 | ] | 214 | ] |
| 215 | }, | ||
| 216 | { | ||
| 217 | path: '/data-meta/metadata-standard', | ||
| 218 | component: Layout, | ||
| 219 | meta: { title: '元数据标准', icon: 'ep:grid' }, | ||
| 220 | children: [ | ||
| 221 | { | ||
| 222 | path: '', | ||
| 223 | name: 'metadataStandard', | ||
| 224 | component: () => import('@/views/data_meta/standard.vue'), | ||
| 225 | meta: { | ||
| 226 | title: '元数据标准管理', | ||
| 227 | breadcrumb: false, | ||
| 228 | cache: true | ||
| 229 | } | ||
| 230 | }, | ||
| 231 | { | ||
| 232 | path: 'standard-query', | ||
| 233 | name: 'metadataStandardQuery', | ||
| 234 | component: () => import('@/views/data_meta/standard-query.vue'), | ||
| 235 | meta: { | ||
| 236 | title: '元数据标准查询', | ||
| 237 | breadcrumb: false, | ||
| 238 | cache: true | ||
| 239 | } | ||
| 240 | }, | ||
| 241 | { | ||
| 242 | path: 'standard-query-view', | ||
| 243 | name: 'metadataStandardQueryView', | ||
| 244 | component: () => import('@/views/data_meta/standard-query-view.vue'), | ||
| 245 | meta: { | ||
| 246 | title: '元数据标准查看', | ||
| 247 | breadcrumb: false, | ||
| 248 | cache: true, | ||
| 249 | activeMenu: '/data-meta/metadata-standard' | ||
| 250 | }, | ||
| 251 | beforeEnter: (to, from) => { | ||
| 252 | if (to.query.name) { | ||
| 253 | to.meta.title = `元数据标准查看-${to.query.name}`; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | }, | ||
| 257 | { | ||
| 258 | path: 'table-create-manual', | ||
| 259 | name: 'tableCreateManual', | ||
| 260 | component: () => import('@/views/data_meta/tableCreateManual.vue'), | ||
| 261 | meta: { | ||
| 262 | title: '新建表', | ||
| 263 | sidebar: false, | ||
| 264 | breadcrumb: false, | ||
| 265 | cache: true, | ||
| 266 | reuse: true, | ||
| 267 | activeMenu: '/data-meta/metadata-standard/standard-query' | ||
| 268 | }, | ||
| 269 | beforeEnter: (to, from) => { | ||
| 270 | if (to.query.domainName) { | ||
| 271 | to.meta.title = `新建表(${to.query.domainName})-${to.query.standardName}`; | ||
| 272 | to.meta.editPage = true; | ||
| 273 | } | ||
| 274 | } | ||
| 275 | }, | ||
| 276 | { | ||
| 277 | path: 'dim-table-create-manual', | ||
| 278 | name: 'dimTableCreateManual', | ||
| 279 | component: () => import('@/views/data_meta/dimTableCreateManual.vue'), | ||
| 280 | meta: { | ||
| 281 | title: '新建表', | ||
| 282 | sidebar: false, | ||
| 283 | breadcrumb: false, | ||
| 284 | cache: true, | ||
| 285 | reuse: true, | ||
| 286 | activeMenu: '/data-meta/metadata-standard/standard-query' | ||
| 287 | }, | ||
| 288 | beforeEnter: (to, from) => { | ||
| 289 | if (to.query.domainName) { | ||
| 290 | to.meta.title = `新建表(${to.query.domainName})-${to.query.standardName}`; | ||
| 291 | to.meta.editPage = true; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | }, | ||
| 295 | { | ||
| 296 | path: 'standard-codetable', | ||
| 297 | name: 'metadataStandardCodetable', | ||
| 298 | component: () => import('@/views/data_meta/standard-codetable.vue'), | ||
| 299 | meta: { | ||
| 300 | title: '标准代码表', | ||
| 301 | breadcrumb: false, | ||
| 302 | cache: true | ||
| 303 | } | ||
| 304 | }, | ||
| 305 | { | ||
| 306 | path: 'standard-import', | ||
| 307 | name: 'metadataStandardImport', | ||
| 308 | component: () => import('@/views/data_meta/standard-import.vue'), | ||
| 309 | meta: { | ||
| 310 | title: '标准代码导入', | ||
| 311 | breadcrumb: false, | ||
| 312 | cache: true, | ||
| 313 | activeMenu: '/data-meta/metadata-standard/standard-codetable' | ||
| 314 | } | ||
| 315 | }, | ||
| 316 | { | ||
| 317 | path: 'standard-meta-import', | ||
| 318 | name: 'standardMetaImport', | ||
| 319 | component: () => import('@/views/data_meta/standard-meta-import.vue'), | ||
| 320 | meta: { | ||
| 321 | title: '元数据标准导入', | ||
| 322 | breadcrumb: false, | ||
| 323 | cache: true, | ||
| 324 | activeMenu: '/data-meta/metadata-standard' | ||
| 325 | } | ||
| 326 | } | ||
| 327 | ] | ||
| 202 | } | 328 | } |
| 203 | ] | 329 | ] |
| 204 | 330 | ... | ... |
src/router/modules/dataPricing.ts
0 → 100644
| 1 | import type { RouteRecordRaw } from 'vue-router' | ||
| 2 | |||
| 3 | function Layout() { | ||
| 4 | return import('@/layouts/index.vue') | ||
| 5 | } | ||
| 6 | |||
| 7 | const routes: RouteRecordRaw[] = [ | ||
| 8 | { | ||
| 9 | path: '/data-pricing/pricing-manage', | ||
| 10 | component: Layout, | ||
| 11 | meta: { | ||
| 12 | title: '定价管理', | ||
| 13 | icon: 'ep:grid', | ||
| 14 | }, | ||
| 15 | children: [ | ||
| 16 | { | ||
| 17 | path: 'demand-manage', | ||
| 18 | name: 'demandManage', | ||
| 19 | component: () => import('@/views/data_pricing/demandManage.vue'), | ||
| 20 | meta: { | ||
| 21 | title: '需求表管理', | ||
| 22 | breadcrumb: false, | ||
| 23 | cache: true | ||
| 24 | }, | ||
| 25 | }, | ||
| 26 | { | ||
| 27 | path: 'import-file-demand-manage', | ||
| 28 | name: 'importFileDemandManage', | ||
| 29 | component: () => import('@/views/importFile.vue'), | ||
| 30 | meta: { | ||
| 31 | title: '导入数据-需求表管理', | ||
| 32 | sidebar: false, | ||
| 33 | breadcrumb: false, | ||
| 34 | cache: true, | ||
| 35 | reuse: true, | ||
| 36 | activeMenu: '/data-pricing/pricing-manage/demand-manage' | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | path: 'disease-manage', | ||
| 41 | name: 'diseaseManage', | ||
| 42 | component: () => import('@/views/data_pricing/diseaseManage.vue'), | ||
| 43 | meta: { | ||
| 44 | title: '疾病管理', | ||
| 45 | breadcrumb: false, | ||
| 46 | cache: true | ||
| 47 | }, | ||
| 48 | }, | ||
| 49 | { | ||
| 50 | path: 'import-file-disease', | ||
| 51 | name: 'importFileDisease', | ||
| 52 | component: () => import('@/views/importFile.vue'), | ||
| 53 | meta: { | ||
| 54 | title: '导入数据-疾病管理', | ||
| 55 | sidebar: false, | ||
| 56 | breadcrumb: false, | ||
| 57 | cache: true, | ||
| 58 | reuse: true, | ||
| 59 | activeMenu: '/data-pricing/pricing-manage/disease-manage' | ||
| 60 | } | ||
| 61 | }, | ||
| 62 | { | ||
| 63 | path: 'price-config', | ||
| 64 | name: 'priceConfig', | ||
| 65 | component: () => import('@/views/data_pricing/priceConfig.vue'), | ||
| 66 | meta: { | ||
| 67 | title: '定价配置', | ||
| 68 | breadcrumb: false, | ||
| 69 | cache: true | ||
| 70 | }, | ||
| 71 | }, | ||
| 72 | { | ||
| 73 | path: 'price-model', | ||
| 74 | name: 'priceModel', | ||
| 75 | component: () => import('@/views/data_pricing/priceModel.vue'), | ||
| 76 | meta: { | ||
| 77 | title: '新增配置', | ||
| 78 | sidebar: false, | ||
| 79 | breadcrumb: false, | ||
| 80 | cache: true, | ||
| 81 | reuse: true, | ||
| 82 | editPage: true, | ||
| 83 | activeMenu: '/data-pricing/pricing-manage/price-config' | ||
| 84 | }, | ||
| 85 | beforeEnter: (to, from) => { | ||
| 86 | if (to.query.guid) { | ||
| 87 | to.meta.title = `编辑-${to.query.name}`; | ||
| 88 | } else { | ||
| 89 | to.meta.title = `新增配置`; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | path: 'price-calculate', | ||
| 95 | name: 'priceCalculate', | ||
| 96 | component: () => import('@/views/data_pricing/priceCalculate.vue'), | ||
| 97 | meta: { | ||
| 98 | title: '数据定价', | ||
| 99 | breadcrumb: false, | ||
| 100 | cache: true | ||
| 101 | } | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | path: 'calculate-config', | ||
| 105 | name: 'calculateConfig', | ||
| 106 | component: () => import('@/views/data_pricing/calculateConfig.vue'), | ||
| 107 | meta: { | ||
| 108 | title: '新增数据定价', | ||
| 109 | sidebar: false, | ||
| 110 | breadcrumb: false, | ||
| 111 | cache: true, | ||
| 112 | reuse: true, | ||
| 113 | editPage: true, | ||
| 114 | activeMenu: '/data-pricing/pricing-manage/price-calculate' | ||
| 115 | }, | ||
| 116 | beforeEnter: (to, from) => { | ||
| 117 | if (to.query.guid) { | ||
| 118 | to.meta.title = `编辑-${to.query.name}`; | ||
| 119 | } else { | ||
| 120 | to.meta.title = `新增数据定价`; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | }, | ||
| 124 | ], | ||
| 125 | }, | ||
| 126 | ] | ||
| 127 | |||
| 128 | export default routes |
| ... | @@ -10,6 +10,7 @@ import DataTrustedSpace from './modules/dataTrustedSpace'; | ... | @@ -10,6 +10,7 @@ import DataTrustedSpace from './modules/dataTrustedSpace'; |
| 10 | import DataAssetRegistry from './modules/dataAssetRegistry'; | 10 | import DataAssetRegistry from './modules/dataAssetRegistry'; |
| 11 | import DataEntry from './modules/dataEntry'; | 11 | import DataEntry from './modules/dataEntry'; |
| 12 | import SecurityMenu from './modules/securityMenu'; | 12 | import SecurityMenu from './modules/securityMenu'; |
| 13 | import DataPricing from './modules/dataPricing'; | ||
| 13 | 14 | ||
| 14 | import useSettingsStore from '@/store/modules/settings' | 15 | import useSettingsStore from '@/store/modules/settings' |
| 15 | 16 | ||
| ... | @@ -112,7 +113,8 @@ const asyncRoutes: RouteRecordRaw[] = [ | ... | @@ -112,7 +113,8 @@ const asyncRoutes: RouteRecordRaw[] = [ |
| 112 | ...DataMeta, | 113 | ...DataMeta, |
| 113 | ...DataQuality, | 114 | ...DataQuality, |
| 114 | ...DataInventory, | 115 | ...DataInventory, |
| 115 | ...DataTrustedSpace | 116 | ...DataTrustedSpace, |
| 117 | ...DataPricing | ||
| 116 | ] | 118 | ] |
| 117 | 119 | ||
| 118 | const constantRoutesByFilesystem = generatedRoutes.filter((item) => { | 120 | const constantRoutesByFilesystem = generatedRoutes.filter((item) => { | ... | ... |
| ... | @@ -174,7 +174,10 @@ const useMenuStore = defineStore( | ... | @@ -174,7 +174,10 @@ const useMenuStore = defineStore( |
| 174 | else { | 174 | else { |
| 175 | // 如果是 string 类型,则认为是路由,需要查找对应的主导航索引 | 175 | // 如果是 string 类型,则认为是路由,需要查找对应的主导航索引 |
| 176 | const findIndex = allMenus.value.findIndex(item => item.children.some(r => { | 176 | const findIndex = allMenus.value.findIndex(item => item.children.some(r => { |
| 177 | if ((data== "/data-meta/reports/iframePage" || data== "/data-meta/report/budgetDataIndex") && r.path?.includes('/data-meta/report')) { | 177 | if ((data== "/data-meta/reports/iframePage" || data == '/data-meta/reports/portraitMaps' || data== "/data-meta/report/budgetDataIndex") && r.path?.includes('/data-meta/report')) { |
| 178 | return true; | ||
| 179 | } | ||
| 180 | if (data== "/data-meta/portraitMap" && r.path?.includes('/data-meta/portraitMap')) { | ||
| 178 | return true; | 181 | return true; |
| 179 | } | 182 | } |
| 180 | if (data== "/data-meta/portraitMap" && r.path?.includes('/data-meta/portraitMap')) { | 183 | if (data== "/data-meta/portraitMap" && r.path?.includes('/data-meta/portraitMap')) { | ... | ... |
| ... | @@ -157,7 +157,7 @@ const useRouteStore = defineStore( | ... | @@ -157,7 +157,7 @@ const useRouteStore = defineStore( |
| 157 | }; | 157 | }; |
| 158 | } | 158 | } |
| 159 | r = routes.find((route: any) => { | 159 | r = routes.find((route: any) => { |
| 160 | return route.path === path || route.path === m.path || `/${route.path}` === m.path || ((path.includes('budgetDataIndex') && path.includes('/data-meta/report') && route.path.includes('/data-meta/report')) || (path.includes('iframePage') && path.includes('/data-meta/report')) || (path.includes('/data-meta/portraitMap') && route.path.includes('/data-meta/portraitMap'))); | 160 | return route.path === path || route.path === m.path || `/${route.path}` === m.path || ((path.includes('budgetDataIndex') && path.includes('/data-meta/report') && route.path.includes('/data-meta/report')) || (path.includes('iframePage') && path.includes('/data-meta/report')) || (path.includes('portraitMaps') && path.includes('/data-meta/report')) || (path.includes('/data-meta/portraitMap') && route.path.includes('/data-meta/portraitMap'))); |
| 161 | }); | 161 | }); |
| 162 | if (r && (path.includes('budgetDataIndex') || path.includes('iframePage')) || path.includes('portraitMap')) { | 162 | if (r && (path.includes('budgetDataIndex') || path.includes('iframePage')) || path.includes('portraitMap')) { |
| 163 | r.path = path; | 163 | r.path = path; | ... | ... |
| ... | @@ -27,6 +27,7 @@ declare module '@vue/runtime-core' { | ... | @@ -27,6 +27,7 @@ declare module '@vue/runtime-core' { |
| 27 | FileUpload: typeof import('./../components/FileUpload/index.vue')['default'] | 27 | FileUpload: typeof import('./../components/FileUpload/index.vue')['default'] |
| 28 | FixedActionBar: typeof import('./../components/FixedActionBar/index.vue')['default'] | 28 | FixedActionBar: typeof import('./../components/FixedActionBar/index.vue')['default'] |
| 29 | Form: typeof import('./../components/Form/index.vue')['default'] | 29 | Form: typeof import('./../components/Form/index.vue')['default'] |
| 30 | GraphTopbar: typeof import('./../components/RelationNetwork/graphTopbar.vue')['default'] | ||
| 30 | Hour: typeof import('./../components/Schedule/component/hour.vue')['default'] | 31 | Hour: typeof import('./../components/Schedule/component/hour.vue')['default'] |
| 31 | ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default'] | 32 | ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default'] |
| 32 | ImagesUpload: typeof import('./../components/ImagesUpload/index.vue')['default'] | 33 | ImagesUpload: typeof import('./../components/ImagesUpload/index.vue')['default'] |
| ... | @@ -41,6 +42,7 @@ declare module '@vue/runtime-core' { | ... | @@ -41,6 +42,7 @@ declare module '@vue/runtime-core' { |
| 41 | PageNav: typeof import('./../components/PageNav/index.vue')['default'] | 42 | PageNav: typeof import('./../components/PageNav/index.vue')['default'] |
| 42 | PcasCascader: typeof import('./../components/PcasCascader/index.vue')['default'] | 43 | PcasCascader: typeof import('./../components/PcasCascader/index.vue')['default'] |
| 43 | Popover: typeof import('./../components/Popover/index.vue')['default'] | 44 | Popover: typeof import('./../components/Popover/index.vue')['default'] |
| 45 | RelationNetwork: typeof import('./../components/RelationNetwork/index.vue')['default'] | ||
| 44 | RouterLink: typeof import('vue-router')['RouterLink'] | 46 | RouterLink: typeof import('vue-router')['RouterLink'] |
| 45 | RouterView: typeof import('vue-router')['RouterView'] | 47 | RouterView: typeof import('vue-router')['RouterView'] |
| 46 | Schedule: typeof import('./../components/Schedule/index.vue')['default'] | 48 | Schedule: typeof import('./../components/Schedule/index.vue')['default'] | ... | ... |
| ... | @@ -120,6 +120,9 @@ export const filterCascaderData = (data, field, val, type = 'disabled') => { | ... | @@ -120,6 +120,9 @@ export const filterCascaderData = (data, field, val, type = 'disabled') => { |
| 120 | } | 120 | } |
| 121 | // 数字千分位 保留两位小数 | 121 | // 数字千分位 保留两位小数 |
| 122 | export const changeNum = (num, fixed = 0, round = false) => { | 122 | export const changeNum = (num, fixed = 0, round = false) => { |
| 123 | if(num === '' || num === null || num === undefined){ | ||
| 124 | return ''; | ||
| 125 | } | ||
| 123 | num = parseFloat(num); | 126 | num = parseFloat(num); |
| 124 | if (round) { | 127 | if (round) { |
| 125 | let parts = num.toFixed(fixed).split(".") | 128 | let parts = num.toFixed(fixed).split(".") | ... | ... |
| ... | @@ -884,7 +884,7 @@ const matchEnValue = ref({ | ... | @@ -884,7 +884,7 @@ const matchEnValue = ref({ |
| 884 | <div class="data-label"> | 884 | <div class="data-label"> |
| 885 | <div class="container_wrap full flex"> | 885 | <div class="container_wrap full flex"> |
| 886 | <div class="aside_wrap"> | 886 | <div class="aside_wrap"> |
| 887 | <div class="aside_title">分类分级目录</div> | 887 | <div class="aside_title">分类分级模板</div> |
| 888 | <Tree :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="handleTreeItemMenuClick" /> | 888 | <Tree :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="handleTreeItemMenuClick" /> |
| 889 | </div> | 889 | </div> |
| 890 | <div class="main_wrap"> | 890 | <div class="main_wrap"> | ... | ... |
| ... | @@ -1293,6 +1293,7 @@ const loadDrawer = async () => { | ... | @@ -1293,6 +1293,7 @@ const loadDrawer = async () => { |
| 1293 | drawerInfo.value.footer.btns.at(-2).visible = false | 1293 | drawerInfo.value.footer.btns.at(-2).visible = false |
| 1294 | drawerInfo.value.footer.btns.at(-3).visible = false | 1294 | drawerInfo.value.footer.btns.at(-3).visible = false |
| 1295 | drawerInfo.value.visible = true | 1295 | drawerInfo.value.visible = true |
| 1296 | console.log('table', formTable.value) | ||
| 1296 | }; | 1297 | }; |
| 1297 | 1298 | ||
| 1298 | const batching = (type) => { | 1299 | const batching = (type) => { | ... | ... |
src/views/data_meta/components/Sankey.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div ref="containerRef" class='canvas-wrapper'> | ||
| 3 | |||
| 4 | </div> | ||
| 5 | </template> | ||
| 6 | |||
| 7 | <script lang="ts" setup name="topbar"> | ||
| 8 | import { ref, watch } from 'vue'; | ||
| 9 | import * as echarts from "echarts"; | ||
| 10 | |||
| 11 | const props = defineProps({ | ||
| 12 | treeData: { | ||
| 13 | type: Array<any>, | ||
| 14 | default: [ | ||
| 15 | { | ||
| 16 | source: 'a', | ||
| 17 | target: 'a1', | ||
| 18 | value: 5 | ||
| 19 | }, | ||
| 20 | { | ||
| 21 | source: 'a', | ||
| 22 | target: 'a2', | ||
| 23 | value: 3 | ||
| 24 | }, | ||
| 25 | { | ||
| 26 | source: 'b', | ||
| 27 | target: 'b1', | ||
| 28 | value: 8 | ||
| 29 | }, | ||
| 30 | { | ||
| 31 | source: 'a', | ||
| 32 | target: 'b1', | ||
| 33 | value: 3 | ||
| 34 | }, | ||
| 35 | { | ||
| 36 | source: 'b1', | ||
| 37 | target: 'a1', | ||
| 38 | value: 1 | ||
| 39 | }, | ||
| 40 | { | ||
| 41 | source: 'b1', | ||
| 42 | target: 'c', | ||
| 43 | value: 2 | ||
| 44 | } | ||
| 45 | ] | ||
| 46 | }, | ||
| 47 | names: { | ||
| 48 | type: Array<any>, | ||
| 49 | default: [ | ||
| 50 | { | ||
| 51 | name: 'a' | ||
| 52 | }, | ||
| 53 | { | ||
| 54 | name: 'b' | ||
| 55 | }, | ||
| 56 | { | ||
| 57 | name: 'a1' | ||
| 58 | }, | ||
| 59 | { | ||
| 60 | name: 'a2' | ||
| 61 | }, | ||
| 62 | { | ||
| 63 | name: 'b1' | ||
| 64 | }, | ||
| 65 | { | ||
| 66 | name: 'c' | ||
| 67 | } | ||
| 68 | ] | ||
| 69 | } | ||
| 70 | }) | ||
| 71 | |||
| 72 | watch(() => props.treeData, (val) => { | ||
| 73 | setChartsOption(); | ||
| 74 | }) | ||
| 75 | |||
| 76 | const sankeyInstance: any = ref(); | ||
| 77 | |||
| 78 | const containerRef = ref(); | ||
| 79 | |||
| 80 | const setChartsOption = () => { | ||
| 81 | |||
| 82 | let option = { | ||
| 83 | tooltip: { | ||
| 84 | trigger: 'item', | ||
| 85 | formatter: (params) => { | ||
| 86 | if (params.data.name) { | ||
| 87 | return null; | ||
| 88 | } | ||
| 89 | return params.data.source + ' > ' + params.data.target | ||
| 90 | } | ||
| 91 | }, | ||
| 92 | color: ["#3DBCBE", "#6b67d1", "#7BBCE0", "#2B8EF3", "#51dca2", "#E19D46"], | ||
| 93 | series: [ | ||
| 94 | { | ||
| 95 | type: 'sankey', | ||
| 96 | top: 60, | ||
| 97 | bottom: 20, | ||
| 98 | draggable: false, | ||
| 99 | left: 50, | ||
| 100 | emphasis: { | ||
| 101 | focus: 'trajectory' | ||
| 102 | }, | ||
| 103 | labelLayout: { | ||
| 104 | hideOverlap: true, | ||
| 105 | }, | ||
| 106 | right: 100, | ||
| 107 | label: { | ||
| 108 | fontSize: 10, | ||
| 109 | }, | ||
| 110 | data: props.names?.map(n => { | ||
| 111 | if (n.isLast) { | ||
| 112 | return { | ||
| 113 | ...n, | ||
| 114 | label: { | ||
| 115 | width: 97, | ||
| 116 | overflow: 'breakAll' | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | return n; | ||
| 121 | }), | ||
| 122 | links: props.treeData, | ||
| 123 | lineStyle: { | ||
| 124 | color: 'source', | ||
| 125 | curveness: 0.5 | ||
| 126 | }, | ||
| 127 | } | ||
| 128 | ] | ||
| 129 | } | ||
| 130 | sankeyInstance.value.setOption(option); | ||
| 131 | sankeyInstance.value.resize(); | ||
| 132 | } | ||
| 133 | |||
| 134 | const resizeObserver = ref(); | ||
| 135 | |||
| 136 | const observeResize = () => { | ||
| 137 | window.addEventListener('resize', (e) => { | ||
| 138 | sankeyInstance.value?.resize(); | ||
| 139 | }); | ||
| 140 | } | ||
| 141 | |||
| 142 | onMounted(() => { | ||
| 143 | nextTick(() => { | ||
| 144 | sankeyInstance.value = echarts.init(containerRef.value); | ||
| 145 | setChartsOption(); | ||
| 146 | observeResize(); | ||
| 147 | }) | ||
| 148 | }) | ||
| 149 | |||
| 150 | </script> | ||
| 151 | |||
| 152 | <style lang="scss" scoped> | ||
| 153 | .canvas-wrapper { | ||
| 154 | width: 100%; | ||
| 155 | height: 100%; | ||
| 156 | position: relative; | ||
| 157 | } | ||
| 158 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <route lang="yaml"> | ||
| 2 | name: dictFileds | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="dictFileds"> | ||
| 6 | import { ref } from 'vue' | ||
| 7 | import router from '@/router' | ||
| 8 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 9 | import Table from '@/components/Table/index.vue' | ||
| 10 | // import Dialog from '@/components/Dialog/index.vue' | ||
| 11 | import useCatchStore from "@/store/modules/catch"; | ||
| 12 | import { chunk } from '@/utils/common' | ||
| 13 | import { getStandardCodeDataList, getStandardCodeFields, | ||
| 14 | saveStandardCodeFieldsData, deleteStandardCodeFieldsData, | ||
| 15 | exportStandardCodeData | ||
| 16 | } from '@/api/modules/dataMetaService' | ||
| 17 | import { download } from '@/utils/common' | ||
| 18 | |||
| 19 | import { | ||
| 20 | saveDictionaryData, | ||
| 21 | getDictionaryFileds, | ||
| 22 | deleteDictionaryData, | ||
| 23 | checkDictionaryData, | ||
| 24 | showDictionary, | ||
| 25 | getDictionaryRuleData | ||
| 26 | } from '@/api/modules/dataInventory'; | ||
| 27 | |||
| 28 | const emits = defineEmits(["exportData"]) | ||
| 29 | const { proxy } = getCurrentInstance() as any; | ||
| 30 | |||
| 31 | const tableEl = ref() | ||
| 32 | const cacheStore = useCatchStore() | ||
| 33 | const standardGuid = ref("") | ||
| 34 | const standardName = ref('') | ||
| 35 | const tableSearchInput = ref('') | ||
| 36 | const tableFields: any = ref([]) | ||
| 37 | const orginData: any = ref([]) | ||
| 38 | const currTableData: any = ref<Object>({}); | ||
| 39 | const selectRowData = ref([]) | ||
| 40 | const page = ref({ | ||
| 41 | limit: 50, | ||
| 42 | curr: 1, | ||
| 43 | sizes: [ | ||
| 44 | { label: "10", value: 10 }, | ||
| 45 | { label: "50", value: 50 }, | ||
| 46 | { label: "100", value: 100 }, | ||
| 47 | { label: "200", value: 200 }, | ||
| 48 | { label: "300", value: 300 }, | ||
| 49 | ], | ||
| 50 | }); | ||
| 51 | const tableChunkData: any = ref([]) | ||
| 52 | const tableData: any = ref([]) | ||
| 53 | const tableInfo: any = ref({ | ||
| 54 | id: 'data-fileds-table', | ||
| 55 | multiple: true, | ||
| 56 | fields: [], | ||
| 57 | data: [], | ||
| 58 | page: { | ||
| 59 | type: "normal", | ||
| 60 | rows: 0, | ||
| 61 | ...page.value, | ||
| 62 | }, | ||
| 63 | // showPage: false, | ||
| 64 | actionInfo: { | ||
| 65 | label: "操作", | ||
| 66 | type: "btn", | ||
| 67 | width: 92, | ||
| 68 | btns: (scope) => { | ||
| 69 | return [ | ||
| 70 | { label: "编辑", value: "edit", visible: scope.row['STATE'] !== 'Running' }, | ||
| 71 | { label: "删除", value: "remove", visible: scope.row['STATE'] !== 'Running' }, | ||
| 72 | // { label: "保存", value: "save", visible: scope.row['STATE'] === 'Running' }, | ||
| 73 | { label: "取消", value: "cancel", visible: scope.row['STATE'] === 'Running' }, | ||
| 74 | ] | ||
| 75 | }, | ||
| 76 | }, | ||
| 77 | editInfo: {}, | ||
| 78 | loading: false | ||
| 79 | }) | ||
| 80 | |||
| 81 | const uploadFiles = ref([]) | ||
| 82 | const uploadInfo = ref({ | ||
| 83 | type: 'upload', | ||
| 84 | title: '', | ||
| 85 | col: '', | ||
| 86 | uploadInfo: { | ||
| 87 | id: 'upload-file-form', | ||
| 88 | type: 'panel', | ||
| 89 | action: '', | ||
| 90 | auto: false, | ||
| 91 | cover: true, | ||
| 92 | fileList: [], | ||
| 93 | accept: '.xlsx, .xls', | ||
| 94 | triggerBtn: { | ||
| 95 | label: '导入', | ||
| 96 | value: 'import_file', | ||
| 97 | icon: 'Upload', | ||
| 98 | }, | ||
| 99 | tips: '当前支持xls、xlsx文件,默认使用第一个sheet' | ||
| 100 | }, | ||
| 101 | }) | ||
| 102 | |||
| 103 | const dialogInfo = ref({ | ||
| 104 | visible: false, | ||
| 105 | size: 640, | ||
| 106 | direction: "column", | ||
| 107 | header: { | ||
| 108 | title: "新建", | ||
| 109 | }, | ||
| 110 | type: '', | ||
| 111 | contents: [ | ||
| 112 | uploadInfo.value | ||
| 113 | ], | ||
| 114 | footer: { | ||
| 115 | visible: true, | ||
| 116 | btns: [ | ||
| 117 | { type: "default", label: "取消", value: "cancel" }, | ||
| 118 | { type: "primary", label: "开始导入", value: "submit" }, | ||
| 119 | ], | ||
| 120 | }, | ||
| 121 | }) | ||
| 122 | |||
| 123 | |||
| 124 | const getFirstPageData = () => { | ||
| 125 | page.value.curr = 1; | ||
| 126 | toSearch({}) | ||
| 127 | } | ||
| 128 | |||
| 129 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 130 | let params = { | ||
| 131 | pageIndex: page.value.curr, | ||
| 132 | pageSize: page.value.limit, | ||
| 133 | standardGuid : standardGuid.value | ||
| 134 | } | ||
| 135 | getTableData(params); | ||
| 136 | }; | ||
| 137 | |||
| 138 | const getTableData = (params) => { | ||
| 139 | tableInfo.value.loading = true | ||
| 140 | Promise.all([getStandardCodeFields(standardGuid.value), getStandardCodeDataList(params)]).then((resList:any) => { | ||
| 141 | console.log(resList) | ||
| 142 | let schemaDataVOS = resList[0].data || [] | ||
| 143 | let jsonArray = resList[1].data.records || [] | ||
| 144 | let data = resList[1].data | ||
| 145 | tableInfo.value.page.limit = data.pageSize | ||
| 146 | tableInfo.value.page.curr = data.pageIndex | ||
| 147 | tableInfo.value.page.rows = data.totalRows | ||
| 148 | setUploadDataInfo({schemaDataVOS,jsonArray}, true) | ||
| 149 | |||
| 150 | }).finally(() => tableInfo.value.loading = false) | ||
| 151 | }; | ||
| 152 | |||
| 153 | const tableSelectionChange = (val, tId) => { | ||
| 154 | selectRowData.value = val; | ||
| 155 | }; | ||
| 156 | |||
| 157 | const tablePageChange = (info) => { | ||
| 158 | console.log('pageChange') | ||
| 159 | const toChange = checkSave() | ||
| 160 | const changeCont = () => { | ||
| 161 | page.value.curr = Number(info.curr) | ||
| 162 | page.value.limit = Number(info.limit) | ||
| 163 | toSearch({}) | ||
| 164 | } | ||
| 165 | if (!toChange) { | ||
| 166 | ElMessageBox.confirm( | ||
| 167 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 168 | '提示', | ||
| 169 | { | ||
| 170 | confirmButtonText: '确定', | ||
| 171 | cancelButtonText: '取消', | ||
| 172 | type: 'warning', | ||
| 173 | } | ||
| 174 | ).then(() => { | ||
| 175 | changeCont() | ||
| 176 | }) | ||
| 177 | } else { | ||
| 178 | changeCont() | ||
| 179 | } | ||
| 180 | |||
| 181 | }; | ||
| 182 | |||
| 183 | const saveDisabled = ref(true) | ||
| 184 | const toolBtnClick = (btn) => { | ||
| 185 | const type = btn.value | ||
| 186 | if (type == 'export') { | ||
| 187 | exportData() | ||
| 188 | } else if (type == 'import') { | ||
| 189 | const info = [ | ||
| 190 | { standardGuid: standardGuid.value, standardName: standardName.value } | ||
| 191 | ] | ||
| 192 | cacheStore.setCatch('uploadSetting', info) | ||
| 193 | nextTick(() => { | ||
| 194 | router.push({ | ||
| 195 | path: '/data-meta/metadata-standard/standard-import', | ||
| 196 | query: { bizGuid: standardGuid.value } | ||
| 197 | }); | ||
| 198 | }) | ||
| 199 | } else if (type == 'submit') { | ||
| 200 | saveData() | ||
| 201 | } else if (type == 'add_row') { | ||
| 202 | let rowInfo: any = {} | ||
| 203 | tableFields.value.map(item => { | ||
| 204 | rowInfo[item.field] = '' | ||
| 205 | }) | ||
| 206 | rowInfo.guid = undefined; | ||
| 207 | rowInfo.STATE = 'Running' | ||
| 208 | rowInfo.STATUS = 'edit' | ||
| 209 | rowInfo.ROWID = `upload_${tableData.value.length}` | ||
| 210 | tableData.value.unshift(rowInfo) | ||
| 211 | orginData.value.unshift(rowInfo) | ||
| 212 | // tableInfo.value.page.rows = tableData.value.length | ||
| 213 | saveDisabled.value = false | ||
| 214 | // 表格滚动到第一行 | ||
| 215 | let $tableEl = tableEl.value.tableRef | ||
| 216 | $tableEl.setCurrentRow(rowInfo) | ||
| 217 | let table = $tableEl.layout.table.refs | ||
| 218 | let tableScrollEle = | ||
| 219 | table.bodyWrapper.firstElementChild.firstElementChild | ||
| 220 | tableScrollEle.scrollTop = 0 | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | const tableBtnClick = (scope, btn) => { | ||
| 225 | const type = btn.value; | ||
| 226 | let row = scope.row; | ||
| 227 | currTableData.value = row; | ||
| 228 | if (type == "edit") { | ||
| 229 | row.STATE = 'Running' | ||
| 230 | row.STATUS = 'edit' | ||
| 231 | tableData.value[scope.$index] = row | ||
| 232 | saveDisabled.value = false | ||
| 233 | } else if (type == 'save') { | ||
| 234 | saveData(scope) | ||
| 235 | } else if (type == 'cancel') { | ||
| 236 | if (row.guid != undefined) { | ||
| 237 | // row = orginData.value[(page.value.curr - 1) * page.value.limit + scope.$index] | ||
| 238 | row = JSON.parse(JSON.stringify(orginData.value[scope.$index])) | ||
| 239 | row.STATE = '' | ||
| 240 | row.STATUS = '' | ||
| 241 | tableData.value[scope.$index] = row | ||
| 242 | } else { | ||
| 243 | tableData.value.splice(scope.$index, 1) | ||
| 244 | orginData.value.splice(scope.$index, 1) | ||
| 245 | } | ||
| 246 | // tableInfo.value.page.rows = tableData.value.length | ||
| 247 | let haveState = tableData.value.some(item => item.STATE) | ||
| 248 | saveDisabled.value = !haveState | ||
| 249 | } else if (type == 'remove') { | ||
| 250 | open("是否确定删除所选数据?", "warning"); | ||
| 251 | } | ||
| 252 | }; | ||
| 253 | |||
| 254 | const onUpload = (file, fileList) => { | ||
| 255 | uploadFiles.value = fileList | ||
| 256 | } | ||
| 257 | |||
| 258 | const uploadBtnClick = (btn) => { | ||
| 259 | exportData('model') | ||
| 260 | } | ||
| 261 | |||
| 262 | const exportData = (type: any = null) => { | ||
| 263 | // emits('exportData', type) | ||
| 264 | let body = { | ||
| 265 | standardCodeGuid: standardGuid.value, | ||
| 266 | standardCodeDataGuids: selectRowData.value.map(v => v.guid) | ||
| 267 | } | ||
| 268 | exportStandardCodeData(body).then((res:any) => { | ||
| 269 | if (res && !res.msg) { | ||
| 270 | download(res, `${standardName.value}.xlsx`, 'excel') | ||
| 271 | } else { | ||
| 272 | res?.msg && ElMessage.error(res?.msg); | ||
| 273 | } | ||
| 274 | }) | ||
| 275 | } | ||
| 276 | |||
| 277 | const importData = (file: any = null) => { | ||
| 278 | let params = new FormData() | ||
| 279 | if (file) { | ||
| 280 | params.append("file", file.raw); | ||
| 281 | } else { | ||
| 282 | if (uploadFiles.value.length) { | ||
| 283 | uploadFiles.value.forEach((item: any, index: number) => { | ||
| 284 | params.append("file", item.raw); | ||
| 285 | }); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | params.append("standardGuid", standardGuid.value); | ||
| 290 | showDictionary(params).then((res: any) => { | ||
| 291 | if (res.code == proxy.$passCode) { | ||
| 292 | dialogInfo.value.visible = false | ||
| 293 | let data = res.data ?? [] | ||
| 294 | // data.map((item: any, i) => { | ||
| 295 | // item.index = tableData.value.length + i | ||
| 296 | // }) | ||
| 297 | const tData = { jsonArray: data } | ||
| 298 | setUploadDataInfo(tData) | ||
| 299 | // saveData(null, tData) | ||
| 300 | } else { | ||
| 301 | ElMessage({ | ||
| 302 | type: "error", | ||
| 303 | message: res.msg, | ||
| 304 | }); | ||
| 305 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 306 | } | ||
| 307 | }).catch(() => { | ||
| 308 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 309 | }); | ||
| 310 | } | ||
| 311 | |||
| 312 | const checkSave = () => { | ||
| 313 | const toSaveData = tableData.value.filter(item => item.STATE === 'Running') | ||
| 314 | return toSaveData.length == 0 ? true : false | ||
| 315 | } | ||
| 316 | |||
| 317 | const checkParamsData = (scope: any = null) => { | ||
| 318 | let addJsonArray: any = [], upJsonArray: any = [], jsonArray: any = [], pass = true | ||
| 319 | let passArr = scope ? [scope.row] : tableData.value | ||
| 320 | passArr.map((item, index) => { | ||
| 321 | const obj = JSON.parse(JSON.stringify(item)) | ||
| 322 | delete obj.STATUS | ||
| 323 | delete obj.NOTES | ||
| 324 | delete obj.STATE | ||
| 325 | delete obj.ROWID | ||
| 326 | if (obj.guid !== undefined) { | ||
| 327 | upJsonArray.push(obj) | ||
| 328 | } else { | ||
| 329 | addJsonArray.push(obj) | ||
| 330 | } | ||
| 331 | if (scope) { | ||
| 332 | // obj.index = scope.$index | ||
| 333 | jsonArray.push(obj) | ||
| 334 | } else { | ||
| 335 | // obj.index = index | ||
| 336 | jsonArray.push(obj) | ||
| 337 | } | ||
| 338 | }) | ||
| 339 | return { pass, addJsonArray, upJsonArray, jsonArray } | ||
| 340 | } | ||
| 341 | |||
| 342 | const loading = ref(false) | ||
| 343 | const saveData = async (scope: any = null, checkParamData: any = null) => { | ||
| 344 | let passInfo: any = {} | ||
| 345 | if (checkParamData) { | ||
| 346 | passInfo = checkParamData | ||
| 347 | } else { | ||
| 348 | passInfo = await checkParamsData(scope) | ||
| 349 | console.log('passInfo', passInfo) | ||
| 350 | if (!passInfo.pass) { | ||
| 351 | ElMessage({ | ||
| 352 | type: 'error', | ||
| 353 | message: '请填写所有数据项' | ||
| 354 | }) | ||
| 355 | return | ||
| 356 | } | ||
| 357 | } | ||
| 358 | let params = passInfo.jsonArray.map(item => { | ||
| 359 | let standardCodeValue = {} | ||
| 360 | tableFields.value.forEach(fieldObj => { | ||
| 361 | standardCodeValue[fieldObj.field] = item[fieldObj.field] | ||
| 362 | }) | ||
| 363 | let obj = { | ||
| 364 | standardGuid: standardGuid.value, | ||
| 365 | standardCodeValue, | ||
| 366 | // guid: item.guid || null, | ||
| 367 | // standardCodeId: item.standardCodeId || null, | ||
| 368 | // parentId: item.parentId || null | ||
| 369 | } | ||
| 370 | if (item.guid) { | ||
| 371 | obj.guid = item.guid | ||
| 372 | } | ||
| 373 | if (item.standardCodeId) { | ||
| 374 | obj.standardCodeId = item.standardCodeId | ||
| 375 | } | ||
| 376 | if (item.parentId) { | ||
| 377 | obj.parentId = item.parentId | ||
| 378 | } | ||
| 379 | return obj | ||
| 380 | }) | ||
| 381 | loading.value = true | ||
| 382 | tableInfo.value.loading = true | ||
| 383 | saveStandardCodeFieldsData(params).then((res: any) => { | ||
| 384 | if (res.code == proxy.$passCode) { | ||
| 385 | getFirstPageData(); | ||
| 386 | ElMessage({ | ||
| 387 | type: 'success', | ||
| 388 | message: '保存成功' | ||
| 389 | }) | ||
| 390 | } else { | ||
| 391 | ElMessage({ | ||
| 392 | type: 'error', | ||
| 393 | message: res.msg, | ||
| 394 | }) | ||
| 395 | tableInfo.value.loading = false | ||
| 396 | } | ||
| 397 | }).finally(() => loading.value = false) | ||
| 398 | } | ||
| 399 | |||
| 400 | const addColumn = (info: any = null) => { | ||
| 401 | const fields = tableFields.value | ||
| 402 | const existIndex = fields.findIndex(item => item.field == 'NOTES') | ||
| 403 | if (info) { | ||
| 404 | if (existIndex == -1) { | ||
| 405 | fields.push({ | ||
| 406 | label: '备注', | ||
| 407 | field: 'NOTES', | ||
| 408 | width: 200 | ||
| 409 | }) | ||
| 410 | } | ||
| 411 | for (var d in info) { | ||
| 412 | tableData.value[d].NOTES = info[d].join(',') | ||
| 413 | } | ||
| 414 | } else { | ||
| 415 | if (existIndex > -1) { | ||
| 416 | fields.splice(existIndex, 1) | ||
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | // 生成表头 | ||
| 422 | const setUploadDataFields = (data) => { | ||
| 423 | let fields: any = [], editInfo: any = {} | ||
| 424 | data.map(item => { | ||
| 425 | let fieldItem: any = { | ||
| 426 | label: item.fieldName, field: item.fieldName, width: 140 | ||
| 427 | } | ||
| 428 | fieldItem.type = 'edit' | ||
| 429 | fieldItem.columClass = 'edit-colum' | ||
| 430 | editInfo[item.fieldName] = { | ||
| 431 | label: '', | ||
| 432 | type: 'input', | ||
| 433 | placeholder: '', | ||
| 434 | maxlength: 50, | ||
| 435 | field: item.fieldName, | ||
| 436 | default: '', | ||
| 437 | disabled: item.codeRuleGuid ? true : false, | ||
| 438 | clearable: true, | ||
| 439 | } | ||
| 440 | fields.push(fieldItem) | ||
| 441 | }) | ||
| 442 | tableFields.value = fields | ||
| 443 | tableInfo.value.fields = tableFields.value | ||
| 444 | tableInfo.value.editInfo = editInfo | ||
| 445 | } | ||
| 446 | |||
| 447 | // 生成表数据 | ||
| 448 | const setUploadDataInfo = async (info, setField = false) => { | ||
| 449 | if (setField) { | ||
| 450 | const fields = info.schemaDataVOS ?? [] | ||
| 451 | await setUploadDataFields(fields) | ||
| 452 | } | ||
| 453 | let data = info.jsonArray ?? [] | ||
| 454 | // 设置表数据 | ||
| 455 | // data.map((item, i) => { | ||
| 456 | // item.ROWID = `upload_${tableData.value.length + i}` | ||
| 457 | // }) | ||
| 458 | data.forEach(item => { | ||
| 459 | Object.keys(item.standardCodeValue).forEach(key => { | ||
| 460 | item[key] = item.standardCodeValue[key] | ||
| 461 | }) | ||
| 462 | }) | ||
| 463 | if (setField) { | ||
| 464 | tableData.value = data | ||
| 465 | } else { | ||
| 466 | tableData.value = [...tableData.value, ...data] | ||
| 467 | } | ||
| 468 | orginData.value = JSON.parse(JSON.stringify(tableData.value)) | ||
| 469 | tableInfo.value.data = tableData.value | ||
| 470 | // tableInfo.value.page.rows = tableData.value.length | ||
| 471 | // if (setField) { | ||
| 472 | // orginData.value = data | ||
| 473 | // } else { | ||
| 474 | // orginData.value = [...orginData.value, ...data] | ||
| 475 | // } | ||
| 476 | // chunkData() | ||
| 477 | } | ||
| 478 | |||
| 479 | const chunkData = () => { | ||
| 480 | const data = orginData.value | ||
| 481 | tableChunkData.value = chunk(data, page.value.limit) | ||
| 482 | tableData.value = tableChunkData.value[page.value.curr - 1] | ||
| 483 | tableInfo.value.data = tableData.value | ||
| 484 | tableInfo.value.page.limit = page.value.limit | ||
| 485 | tableInfo.value.page.curr = page.value.curr | ||
| 486 | tableInfo.value.page.rows = orginData.value.length | ||
| 487 | } | ||
| 488 | |||
| 489 | const batching = (type) => { | ||
| 490 | if (type == 'delete') { | ||
| 491 | if (selectRowData.value.length == 0) { | ||
| 492 | ElMessage({ | ||
| 493 | type: 'error', | ||
| 494 | message: '请选择需要删除的数据', | ||
| 495 | }) | ||
| 496 | return | ||
| 497 | } | ||
| 498 | open("是否确定删除所选数据?", "warning", true); | ||
| 499 | } | ||
| 500 | }; | ||
| 501 | |||
| 502 | const open = (msg, type, isBatch = false) => { | ||
| 503 | ElMessageBox.confirm(msg, "提示", { | ||
| 504 | confirmButtonText: "确定", | ||
| 505 | cancelButtonText: "取消", | ||
| 506 | type: type, | ||
| 507 | }).then(() => { | ||
| 508 | let guids: any = [] | ||
| 509 | if (isBatch) { | ||
| 510 | const list = selectRowData.value.filter((item: any) => item.guid !== undefined) | ||
| 511 | if (list.length) { | ||
| 512 | guids = list.map((l: any) => l.guid) | ||
| 513 | } | ||
| 514 | const newRows = selectRowData.value.filter((item: any) => item.guid == undefined) | ||
| 515 | newRows.map((n: any, r) => { | ||
| 516 | const existIndex = tableData.value.findIndex(t => t.ROWID == n.ROWID) | ||
| 517 | if (existIndex > -1) { | ||
| 518 | tableData.value.splice(existIndex, 1) | ||
| 519 | orginData.value.splice(existIndex, 1) | ||
| 520 | } | ||
| 521 | // const existIndex = orginData.value.findIndex(t => t.id == n.id) | ||
| 522 | // existIndex > -1 && orginData.value.splice(existIndex, 1) | ||
| 523 | // if (r == newRows.length - 1) { | ||
| 524 | // page.value.curr = 1 | ||
| 525 | // chunkData() | ||
| 526 | // } | ||
| 527 | }) | ||
| 528 | tableInfo.value.page.rows = tableData.value.length | ||
| 529 | } else { | ||
| 530 | guids = [currTableData.value.guid] | ||
| 531 | } | ||
| 532 | if (guids.length) { | ||
| 533 | const params = { | ||
| 534 | guid: standardGuid.value, | ||
| 535 | delGuids: guids | ||
| 536 | } | ||
| 537 | // console.log(params) | ||
| 538 | // return | ||
| 539 | deleteStandardCodeFieldsData(guids).then((res: any) => { | ||
| 540 | if (res.code == proxy.$passCode) { | ||
| 541 | getFirstPageData(); | ||
| 542 | ElMessage({ | ||
| 543 | type: "success", | ||
| 544 | message: "删除成功", | ||
| 545 | }); | ||
| 546 | } else { | ||
| 547 | ElMessage({ | ||
| 548 | type: "error", | ||
| 549 | message: res.msg, | ||
| 550 | }); | ||
| 551 | } | ||
| 552 | }); | ||
| 553 | } | ||
| 554 | }); | ||
| 555 | }; | ||
| 556 | |||
| 557 | const dialogBtnClick = (btn, info) => { | ||
| 558 | if (btn.value == 'submit') { | ||
| 559 | // dialogInfo.value.footer.btns.map((item: any) => item.disabled = true) | ||
| 560 | importData() | ||
| 561 | } else if (btn.value == 'cancel') { | ||
| 562 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 563 | nextTick(() => { | ||
| 564 | dialogInfo.value.visible = false; | ||
| 565 | }) | ||
| 566 | } | ||
| 567 | }; | ||
| 568 | |||
| 569 | defineExpose({ | ||
| 570 | standardGuid, | ||
| 571 | standardName, | ||
| 572 | getFirstPageData, | ||
| 573 | checkSave | ||
| 574 | }); | ||
| 575 | |||
| 576 | </script> | ||
| 577 | |||
| 578 | <template> | ||
| 579 | <div class="container_wrap full flex"> | ||
| 580 | <div class="main_wrap"> | ||
| 581 | <div class="table_tool_wrap"> | ||
| 582 | <div class="tools_btns"> | ||
| 583 | <el-button type="primary" @click="toolBtnClick({ value: 'add_row' })" v-preReClick :disabled="loading">新增行</el-button> | ||
| 584 | <el-button type="primary" plain @click="toolBtnClick({ value: 'submit' })" v-preReClick :disabled="saveDisabled || loading">保存数据</el-button> | ||
| 585 | <el-button @click="batching('delete')" v-preReClick :disabled="loading">批量删除</el-button> | ||
| 586 | <el-button @click="toolBtnClick({ value: 'import' })" v-preReClick :disabled="loading">导入数据</el-button> | ||
| 587 | <el-button @click="toolBtnClick({ value: 'export' })" v-preReClick :disabled="loading">导出数据</el-button> | ||
| 588 | <el-button @click="getFirstPageData" v-preReClick :disabled="loading">刷新结果</el-button> | ||
| 589 | </div> | ||
| 590 | <!-- <el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="输入名称搜索" :suffix-icon="Search" clearable | ||
| 591 | @change="val => toSearch({})" /> --> | ||
| 592 | </div> | ||
| 593 | <div class="table_panel_wrap full"> | ||
| 594 | <Table | ||
| 595 | ref="tableEl" | ||
| 596 | :tableInfo="tableInfo" | ||
| 597 | @tableBtnClick="tableBtnClick" | ||
| 598 | @tableSelectionChange="tableSelectionChange" | ||
| 599 | @tablePageChange="tablePageChange" | ||
| 600 | /> | ||
| 601 | </div> | ||
| 602 | </div> | ||
| 603 | |||
| 604 | <!-- <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @onUpload="onUpload" @uploadBtnClick="uploadBtnClick" /> --> | ||
| 605 | </div> | ||
| 606 | </template> | ||
| 607 | |||
| 608 | <style lang="scss" scoped> | ||
| 609 | .container_wrap { | ||
| 610 | width: calc(100% - 200px); | ||
| 611 | |||
| 612 | .main_wrap { | ||
| 613 | width: 100%; | ||
| 614 | |||
| 615 | .table_panel_wrap { | ||
| 616 | height: calc(100% - 44px); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | } | ||
| 620 | </style> |
src/views/data_meta/components/drawer.vue
0 → 100644
| 1 | <script lang="ts" setup name="Drawer"> | ||
| 2 | import { computed } from "vue"; | ||
| 3 | import { ClickOutside as vClickOutside } from "element-plus"; | ||
| 4 | import type { FormInstance } from "element-plus"; | ||
| 5 | import { Download, Upload, CirclePlus } from "@element-plus/icons-vue"; | ||
| 6 | import Table from "@/components/Table/index.vue"; | ||
| 7 | import Form from "@/components/Form/index.vue"; | ||
| 8 | import Tree from "@/components/Tree/index.vue"; | ||
| 9 | import ListPanel from "@/components/ListPanel/index.vue"; | ||
| 10 | import UploadFiles from "@/components/Upload/index.vue"; | ||
| 11 | |||
| 12 | const emits = defineEmits([ | ||
| 13 | "drawerBtnClick", | ||
| 14 | "radioGroupChange", | ||
| 15 | "drawerSelectChange", | ||
| 16 | "drawerTableSelectChange", | ||
| 17 | "drawerTableBtnClick", | ||
| 18 | "drawerTableToolBtnClick", | ||
| 19 | "drawerFormBtnClick", | ||
| 20 | "listItemClick", | ||
| 21 | "drawerTableInputChange", | ||
| 22 | "drawerToolBtnClick", | ||
| 23 | "drawerTableSelectionChange", | ||
| 24 | "drawerTablePageChange", | ||
| 25 | "uploadBtnClick", | ||
| 26 | "beforeUPload", | ||
| 27 | "uploadFile", | ||
| 28 | "onUpload", | ||
| 29 | "onClickOutside", | ||
| 30 | ]); | ||
| 31 | |||
| 32 | const props = defineProps({ | ||
| 33 | drawerInfo: { | ||
| 34 | type: Object, | ||
| 35 | default: {}, | ||
| 36 | }, | ||
| 37 | }); | ||
| 38 | |||
| 39 | const drawerTableRef = ref(); | ||
| 40 | const drawerFormRef = ref(); | ||
| 41 | const selectRowData = ref([]); | ||
| 42 | const formListRef = ref(); | ||
| 43 | const formTreeRef = ref(); | ||
| 44 | const uploadRef = ref(); | ||
| 45 | |||
| 46 | const drawerVisible = computed(() => { | ||
| 47 | nextTick(() => { | ||
| 48 | if (props.drawerInfo.visible) { | ||
| 49 | drawerOpen(); | ||
| 50 | } | ||
| 51 | }) | ||
| 52 | return props.drawerInfo.visible; | ||
| 53 | }); | ||
| 54 | const drawerDirection = computed(() => { | ||
| 55 | return props.drawerInfo.direction; | ||
| 56 | }); | ||
| 57 | const drawerModal = computed(() => { | ||
| 58 | return props.drawerInfo.modal ?? true; | ||
| 59 | }); | ||
| 60 | const modalClose = computed(() => { | ||
| 61 | return props.drawerInfo.modalClose ?? false; | ||
| 62 | }); | ||
| 63 | const drawerModalClass = computed(() => { | ||
| 64 | nextTick(() => { | ||
| 65 | drawerOpen(); | ||
| 66 | }) | ||
| 67 | return props.drawerInfo.modalClass ?? ""; | ||
| 68 | }); | ||
| 69 | const drawerSize = computed(() => { | ||
| 70 | return props.drawerInfo.size ?? "30%"; | ||
| 71 | }); | ||
| 72 | const drawerType = computed(() => { | ||
| 73 | return props.drawerInfo.type ?? "form"; | ||
| 74 | }); | ||
| 75 | const drawerTitle = computed(() => { | ||
| 76 | return props.drawerInfo.header.title; | ||
| 77 | }); | ||
| 78 | const selectOptions = computed(() => { | ||
| 79 | return props.drawerInfo.container.relateOptions ?? []; | ||
| 80 | }); | ||
| 81 | const formItems = computed(() => { | ||
| 82 | return props.drawerInfo.container.formItems ?? []; | ||
| 83 | }); | ||
| 84 | const formRules = computed(() => { | ||
| 85 | return props.drawerInfo.container.rules ?? {}; | ||
| 86 | }); | ||
| 87 | const selectData = computed(() => { | ||
| 88 | return props.drawerInfo.container.selectData ?? []; | ||
| 89 | }); | ||
| 90 | const contents = computed(() => { | ||
| 91 | return props.drawerInfo.container.contents ?? []; | ||
| 92 | }); | ||
| 93 | const footer = computed(() => { | ||
| 94 | return props.drawerInfo.footer; | ||
| 95 | }); | ||
| 96 | |||
| 97 | const onClickOutside = (e: any) => { | ||
| 98 | emits("onClickOutside"); | ||
| 99 | }; | ||
| 100 | |||
| 101 | const getDrawerConRef = (refName) => { | ||
| 102 | console.log(refName, '----------') | ||
| 103 | if (refName == 'drawerTableRef') { | ||
| 104 | const dtf = drawerTableRef.value[0] || drawerTableRef.value | ||
| 105 | return dtf?.tableRef | ||
| 106 | } | ||
| 107 | // const drawerForm = drawerFormRef.value[0] || drawerFormRef.value; | ||
| 108 | if (refName == 'drawerFormRef') { | ||
| 109 | const drawerForm = drawerFormRef.value?.[0] || drawerFormRef.value; | ||
| 110 | return drawerForm | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | defineExpose({ | ||
| 115 | // selections, | ||
| 116 | getDrawerConRef | ||
| 117 | }); | ||
| 118 | |||
| 119 | const toolBtnClick = (btn, type: any = null) => { | ||
| 120 | if (type && type == "table") { | ||
| 121 | let selectData = []; | ||
| 122 | if (drawerTableRef.value) { | ||
| 123 | const drawerTable = drawerTableRef.value[0] || drawerTableRef.value; | ||
| 124 | selectData = drawerTable.tableRef.getSelectionRows(); | ||
| 125 | } | ||
| 126 | emits("drawerTableToolBtnClick", btn, selectData); | ||
| 127 | } else { | ||
| 128 | emits("drawerToolBtnClick", btn); | ||
| 129 | } | ||
| 130 | }; | ||
| 131 | |||
| 132 | const tableSelectionChange = (val, tId) => { | ||
| 133 | selectRowData.value = val; | ||
| 134 | emits("drawerTableSelectionChange", val, tId); | ||
| 135 | }; | ||
| 136 | |||
| 137 | const tableSelectChange = (val, scope) => { | ||
| 138 | emits("drawerTableSelectChange", val, scope); | ||
| 139 | }; | ||
| 140 | |||
| 141 | const tableInputChange = (val, scope) => { | ||
| 142 | emits("drawerTableInputChange", val, scope); | ||
| 143 | }; | ||
| 144 | |||
| 145 | const tablePageChange = (info) => { | ||
| 146 | emits("drawerTablePageChange", info); | ||
| 147 | } | ||
| 148 | |||
| 149 | const tableBtnClick = (scope, btn) => { | ||
| 150 | emits("drawerTableBtnClick", scope, btn); | ||
| 151 | }; | ||
| 152 | |||
| 153 | const submitForm = async (formEl: FormInstance | undefined, btn) => { | ||
| 154 | if (!formEl) return; | ||
| 155 | await formEl.validate((valid, fields) => { | ||
| 156 | const drawerForm = drawerFormRef.value[0] || drawerFormRef.value; | ||
| 157 | if (valid) { | ||
| 158 | const formInfo = drawerForm.formInline; | ||
| 159 | emits("drawerBtnClick", btn, formInfo); | ||
| 160 | } else { | ||
| 161 | var obj = fields && Object.keys(fields); | ||
| 162 | obj?.[0] && formEl?.scrollToField(obj?.[0]) | ||
| 163 | console.log("error submit!", fields); | ||
| 164 | } | ||
| 165 | }); | ||
| 166 | }; | ||
| 167 | |||
| 168 | const btnClick = (btn, type) => { | ||
| 169 | if (btn.disabled) return; | ||
| 170 | if ( | ||
| 171 | btn.value != "cancel" && | ||
| 172 | (btn.value.indexOf("submit") > -1 || btn.value.indexOf("save") > -1) | ||
| 173 | ) { | ||
| 174 | if (drawerFormRef.value) { | ||
| 175 | const drawerForm = drawerFormRef.value[0] || drawerFormRef.value; | ||
| 176 | const formRef = drawerForm.ruleFormRef; | ||
| 177 | submitForm(formRef, btn); | ||
| 178 | } else { | ||
| 179 | emits("drawerBtnClick", btn); | ||
| 180 | } | ||
| 181 | } else { | ||
| 182 | emits("drawerBtnClick", btn); | ||
| 183 | } | ||
| 184 | }; | ||
| 185 | |||
| 186 | const radioGroupChange = (val, info) => { | ||
| 187 | emits("radioGroupChange", val, info); | ||
| 188 | }; | ||
| 189 | |||
| 190 | const formSelectChange = (val, row, info) => { | ||
| 191 | emits("drawerSelectChange", val, row, info); | ||
| 192 | }; | ||
| 193 | |||
| 194 | const formBtnClick = (btn) => { | ||
| 195 | emits("drawerFormBtnClick", btn); | ||
| 196 | }; | ||
| 197 | |||
| 198 | const listItemClick = (row) => { | ||
| 199 | emits("listItemClick", row); | ||
| 200 | }; | ||
| 201 | |||
| 202 | const onUpload = (file, fileList) => { | ||
| 203 | emits("onUpload", file, fileList); | ||
| 204 | }; | ||
| 205 | |||
| 206 | const beforeUPload = (file) => { | ||
| 207 | emits("beforeUPload", file); | ||
| 208 | }; | ||
| 209 | |||
| 210 | const uploadFile = (file) => { | ||
| 211 | emits("uploadFile", file); | ||
| 212 | }; | ||
| 213 | |||
| 214 | const uploadBtnClick = (btn) => { | ||
| 215 | emits("uploadBtnClick", btn); | ||
| 216 | }; | ||
| 217 | |||
| 218 | const drawerOpen = () => { | ||
| 219 | const wrap: any = drawerModalClass.value && document.getElementsByClassName(drawerModalClass.value)[0]; | ||
| 220 | if (wrap) { | ||
| 221 | wrap.style.width = `${drawerSize.value + 1}px` | ||
| 222 | } else { | ||
| 223 | const dom: any = document.getElementsByClassName('el-overlay')[0]; | ||
| 224 | dom && (dom.style.width = '100%'); | ||
| 225 | } | ||
| 226 | }; | ||
| 227 | |||
| 228 | const drawerClose = () => { | ||
| 229 | btnClick({ value: "cancel" }, null); | ||
| 230 | if (drawerFormRef.value) { | ||
| 231 | const drawerForm = drawerFormRef.value[0] || drawerFormRef.value; | ||
| 232 | const formRef = drawerForm.ruleFormRef; | ||
| 233 | drawerForm?.resetForm(formRef); | ||
| 234 | } | ||
| 235 | }; | ||
| 236 | </script> | ||
| 237 | |||
| 238 | <template> | ||
| 239 | <el-drawer v-model="drawerVisible" :direction="drawerDirection" :size="drawerSize" :modal="drawerModal" | ||
| 240 | :close-on-click-modal="modalClose" :close-on-press-escape="modalClose" :modal-class="drawerModalClass" | ||
| 241 | destroy-on-close :z-index="props.drawerInfo.zIndex ?? null" @close="drawerClose"> | ||
| 242 | <template #header> | ||
| 243 | <span class="title">{{ drawerTitle }}</span> | ||
| 244 | </template> | ||
| 245 | <template #default> | ||
| 246 | <div class="drawer-body-loading" v-if="drawerInfo.loading ?? false" v-loading="drawerInfo.loading ?? false"></div> | ||
| 247 | <div v-else class="drawer_panel" :class="[con.col]" :style="con.style" v-for="con in contents"> | ||
| 248 | <div class="panel_title" v-if="con.title">{{ con.title }}</div> | ||
| 249 | <template v-if="con.type && con.type.indexOf('table') > -1"> | ||
| 250 | <div class="table_tool float-right"> | ||
| 251 | <template v-for="bar in con.tableTool.btns.slice(1)"> | ||
| 252 | <el-popover v-if="bar.popover" :visible="bar.popover.visible" :title="bar.popover.title" | ||
| 253 | :popper-class="bar.popover.class ?? ''" placement="bottom-start" :width="bar.popover.width ?? 200" | ||
| 254 | trigger="click"> | ||
| 255 | <template #reference> | ||
| 256 | <el-button :type="bar.type" @click="toolBtnClick(bar, con.type)" v-click-outside="onClickOutside" | ||
| 257 | v-preReClick>{{ bar.label }}</el-button> | ||
| 258 | </template> | ||
| 259 | <template #default> | ||
| 260 | <span v-html="bar.popover.content"></span> | ||
| 261 | </template> | ||
| 262 | </el-popover> | ||
| 263 | <el-button :type="bar.type" :plain="bar.plain" v-else @click="toolBtnClick(bar, 'table')" v-preReClick>{{ | ||
| 264 | bar.label | ||
| 265 | }}</el-button> | ||
| 266 | </template> | ||
| 267 | </div> | ||
| 268 | <div class="table_panel_wrap" :style="con.tableInfo.style"> | ||
| 269 | <Table ref="drawerTableRef" :class="[con.tableInfo.col]" :tableInfo="con.tableInfo" | ||
| 270 | @tableSelectChange="tableSelectChange" @tableBtnClick="tableBtnClick" | ||
| 271 | @tableSelectionChange="tableSelectionChange" @tableInputChange="tableInputChange" | ||
| 272 | @tablePageChange="tablePageChange" /> | ||
| 273 | </div> | ||
| 274 | <div class="table_tool" :class="[con.tableTool.col]" v-if="con.tableTool && (con.tableTool.visible ?? true)"> | ||
| 275 | <template v-for="bar in con.tableTool.btns.slice(0, 1)"> | ||
| 276 | <!-- <el-popover v-if="bar.popover" :visible="bar.popover.visible" :title="bar.popover.title" | ||
| 277 | :popper-class="bar.popover.class ?? ''" placement="bottom-start" :width="bar.popover.width ?? 200" | ||
| 278 | trigger="click"> | ||
| 279 | <template #reference> | ||
| 280 | <el-button :type="bar.type" @click="toolBtnClick(bar, con.type)" v-click-outside="onClickOutside" | ||
| 281 | v-preReClick>{{ bar.label }}</el-button> | ||
| 282 | </template> | ||
| 283 | <template #default> | ||
| 284 | <span v-html="bar.popover.content"></span> | ||
| 285 | </template> | ||
| 286 | </el-popover> --> | ||
| 287 | <!-- <el-button :type="bar.type" :plain="bar.plain" @click="toolBtnClick(bar, 'table')" v-preReClick>{{ | ||
| 288 | bar.label | ||
| 289 | }}</el-button> --> | ||
| 290 | <div class="operation-icon" @click="toolBtnClick(bar, 'table')" v-preReClick> | ||
| 291 | <el-icon color="#4fa1a4"> | ||
| 292 | <CirclePlus /> | ||
| 293 | </el-icon> | ||
| 294 | <span>{{ bar.label }}</span> | ||
| 295 | </div> | ||
| 296 | </template> | ||
| 297 | </div> | ||
| 298 | </template> | ||
| 299 | <template v-else-if="con.type && con.type.indexOf('tree') > -1"> | ||
| 300 | <div class="list_tree" v-if="con.type.indexOf('list') > -1"> | ||
| 301 | <ListPanel ref="formListRef" :listInfo="con.listInfo" @itemClick="listItemClick" /> | ||
| 302 | <Tree ref="formTreeRef" :treeInfo="con.treeInfo" /> | ||
| 303 | </div> | ||
| 304 | <Tree ref="formTreeRef" :treeInfo="con.treeInfo" v-else /> | ||
| 305 | </template> | ||
| 306 | <template v-else-if="con.type && con.type == 'field-list'"> | ||
| 307 | <div class="field_list_panel" v-if="con.listInfo.data.length > 0"> | ||
| 308 | <div class="list_item" v-for="item in con.listInfo.data"> | ||
| 309 | <span class="item_field">{{ item[con.listInfo.field] }}</span> | ||
| 310 | <span class="item_text">{{ item[con.listInfo.label] }}</span> | ||
| 311 | </div> | ||
| 312 | </div> | ||
| 313 | <div class="field_list_panel"> | ||
| 314 | <div class="empty_tips">暂无数据</div> | ||
| 315 | </div> | ||
| 316 | </template> | ||
| 317 | <template v-else-if="con.type && con.type.indexOf('upload') > -1"> | ||
| 318 | <div class="upload_tool"> | ||
| 319 | <UploadFiles ref="uploadRef" :upload-info="con.uploadInfo" @onUpload="onUpload" @beforeUPload="beforeUPload" | ||
| 320 | @uploadFile="uploadFile" @uploadBtnClick="uploadBtnClick" /> | ||
| 321 | <div class="tool_btns" v-if="con.tools && con.tools.visible"> | ||
| 322 | <template v-for="btn in con.tools.btns"> | ||
| 323 | <el-button v-if="btn.visible ?? true" :type="btn.type" :plain="btn.plain" | ||
| 324 | @click="toolBtnClick(btn, 'table')" v-preReClick> | ||
| 325 | <el-icon v-if="btn.icon && btn.icon == 'Upload'"> | ||
| 326 | <Upload /> | ||
| 327 | </el-icon> | ||
| 328 | <el-icon v-else-if="btn.icon && btn.icon == 'Download'"> | ||
| 329 | <Download /> | ||
| 330 | </el-icon> | ||
| 331 | <span>{{ btn.label }}</span> | ||
| 332 | </el-button> | ||
| 333 | </template> | ||
| 334 | </div> | ||
| 335 | </div> | ||
| 336 | <div class="upload_table_panel_wrap" v-if="con.tableInfo && Object.keys(con.tableInfo).length"> | ||
| 337 | <Table ref="drawerTableRef" :class="[con.tableInfo.col]" :tableInfo="con.tableInfo" | ||
| 338 | @tableSelectChange="tableSelectChange" @tableBtnClick="tableBtnClick" | ||
| 339 | @tableSelectionChange="tableSelectionChange" @tableInputChange="tableInputChange" | ||
| 340 | @tablePageChange="tablePageChange" /> | ||
| 341 | </div> | ||
| 342 | </template> | ||
| 343 | <template v-else> | ||
| 344 | <Form ref="drawerFormRef" :itemList="con.formInfo.items" :formId="con.formInfo.id" :rules="con.formInfo.rules" | ||
| 345 | :col="con.formInfo.col" :readonly="con.formInfo.readonly" @radioGroupChange="radioGroupChange" | ||
| 346 | @selectChange="formSelectChange" @btnClick="formBtnClick"> | ||
| 347 | </Form> | ||
| 348 | <!-- 插槽内容 --> | ||
| 349 | <slot></slot> | ||
| 350 | </template> | ||
| 351 | </div> | ||
| 352 | </template> | ||
| 353 | <template #footer v-if="footer.visible ?? true"> | ||
| 354 | <div style="flex: auto"> | ||
| 355 | <template v-for="btn in footer.btns"> | ||
| 356 | <el-button v-if="btn.visible ?? true" :type="btn.type" :disabled="btn.disabled ?? false" | ||
| 357 | @click="btnClick(btn, null)" v-preReClick :loading="btn.loading ?? false">{{ btn.label }}</el-button> | ||
| 358 | </template> | ||
| 359 | </div> | ||
| 360 | </template> | ||
| 361 | </el-drawer> | ||
| 362 | </template> | ||
| 363 | |||
| 364 | <style lang="scss" scoped> | ||
| 365 | .operation-icon { | ||
| 366 | display: flex; | ||
| 367 | align-items: center; | ||
| 368 | cursor: pointer; | ||
| 369 | > span { | ||
| 370 | margin-left: 4px; | ||
| 371 | color: #4fa1a4; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | .drawer-body-loading { | ||
| 375 | height: 100%; | ||
| 376 | } | ||
| 377 | |||
| 378 | .drawer_panel { | ||
| 379 | position: relative; | ||
| 380 | |||
| 381 | &.no-margin { | ||
| 382 | margin-top: 0; | ||
| 383 | } | ||
| 384 | |||
| 385 | &.height_auto { | ||
| 386 | .table_panel_wrap { | ||
| 387 | .table_panel { | ||
| 388 | min-height: unset; | ||
| 389 | } | ||
| 390 | } | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | .panel_title { | ||
| 395 | line-height: 40px; | ||
| 396 | font-size: 14px; | ||
| 397 | color: var(--el-color-regular); | ||
| 398 | font-weight: 600; | ||
| 399 | } | ||
| 400 | |||
| 401 | .table_tool { | ||
| 402 | height: 40px; | ||
| 403 | display: flex; | ||
| 404 | align-items: center; | ||
| 405 | |||
| 406 | &.float-right { | ||
| 407 | position: absolute; | ||
| 408 | top: 0; | ||
| 409 | right: 0; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | .table_panel_wrap { | ||
| 414 | height: auto!important; | ||
| 415 | .table_panel { | ||
| 416 | padding: 0; | ||
| 417 | min-height: auto; | ||
| 418 | &.auto-height { | ||
| 419 | min-height: unset; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | .list_tree { | ||
| 425 | max-height: 400px; | ||
| 426 | display: flex; | ||
| 427 | justify-content: space-between; | ||
| 428 | box-shadow: 0 0 0 1px #d9d9d9; | ||
| 429 | |||
| 430 | .list_panel_wrap { | ||
| 431 | width: 158px; | ||
| 432 | box-shadow: 1px 0 0 0 #d9d9d9; | ||
| 433 | } | ||
| 434 | |||
| 435 | .tree_panel { | ||
| 436 | width: calc(100% - 159px); | ||
| 437 | |||
| 438 | :deep(.el-tree) { | ||
| 439 | margin: 0; | ||
| 440 | height: 100%; | ||
| 441 | overflow: hidden auto; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | .field_list_panel { | ||
| 447 | width: 100%; | ||
| 448 | height: calc(100vh - 70px); | ||
| 449 | position: relative; | ||
| 450 | |||
| 451 | .list_item { | ||
| 452 | display: flex; | ||
| 453 | font-size: 12px; | ||
| 454 | color: var(--el-color-regular); | ||
| 455 | margin: 4px 0; | ||
| 456 | |||
| 457 | .item_field { | ||
| 458 | width: 130px; | ||
| 459 | color: var(--el-text-color-regular); | ||
| 460 | } | ||
| 461 | |||
| 462 | .item_text { | ||
| 463 | width: calc(100% - 130px); | ||
| 464 | word-wrap: break-word; | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | .empty_tips { | ||
| 469 | text-align: center; | ||
| 470 | color: var(--el-disabled-text-color); | ||
| 471 | position: absolute; | ||
| 472 | top: 50px; | ||
| 473 | left: 50%; | ||
| 474 | transform: translate(-50%); | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | .upload_tool { | ||
| 479 | margin-bottom: 8px; | ||
| 480 | position: relative; | ||
| 481 | |||
| 482 | .tool_btns { | ||
| 483 | position: absolute; | ||
| 484 | top: 0; | ||
| 485 | right: 0; | ||
| 486 | } | ||
| 487 | } | ||
| 488 | |||
| 489 | .upload_table_panel_wrap { | ||
| 490 | .table_panel { | ||
| 491 | min-height: unset; | ||
| 492 | } | ||
| 493 | } | ||
| 494 | </style> |
| 1 | <script lang="ts" setup name="existingTableSelect"> | ||
| 2 | import { ref } from "vue"; | ||
| 3 | import Dialog from "@/components/Dialog/index.vue"; | ||
| 4 | |||
| 5 | const emits = defineEmits([ | ||
| 6 | "expandValueChange" | ||
| 7 | ]); | ||
| 8 | |||
| 9 | const props = defineProps({ | ||
| 10 | tableCreateInfo: { | ||
| 11 | type: Object, | ||
| 12 | default: {}, | ||
| 13 | }, | ||
| 14 | partitionAttribute: { | ||
| 15 | type: Object, | ||
| 16 | default: {}, | ||
| 17 | }, | ||
| 18 | isLook: { | ||
| 19 | type: Boolean, | ||
| 20 | default: false | ||
| 21 | } | ||
| 22 | }); | ||
| 23 | |||
| 24 | const expandProperties: any = computed(() => { | ||
| 25 | let partitionAttribute = props.tableCreateInfo.partitionAttribute; | ||
| 26 | return { | ||
| 27 | partitionMode: partitionAttribute?.partitionMode || 'dynamic', | ||
| 28 | staticPartitionType: partitionAttribute?.staticPartitionType || 'Range', | ||
| 29 | partitionCol: partitionAttribute?.partitionCol || "", | ||
| 30 | partitionTimeUnit: partitionAttribute?.partitionTimeUnit || "DAY", | ||
| 31 | dynamicPartitionEnd: partitionAttribute?.dynamicPartitionEnd == null ? 3 : partitionAttribute?.dynamicPartitionEnd, | ||
| 32 | staticPartitionRange: partitionAttribute?.staticPartitionRangeBegin ? [partitionAttribute?.staticPartitionRangeBegin, | ||
| 33 | partitionAttribute?.staticPartitionRangeEnd] : null, | ||
| 34 | dynamicPartitionHistory: partitionAttribute?.dynamicPartitionHistory === "Y", | ||
| 35 | dynamicPartitionHistoryNum: partitionAttribute?.dynamicPartitionHistoryNum, | ||
| 36 | staticPartitionEnum: partitionAttribute?.staticPartitionEnum, | ||
| 37 | } | ||
| 38 | }) | ||
| 39 | |||
| 40 | const formItems: any = ref([ | ||
| 41 | { | ||
| 42 | label: "分区模式", | ||
| 43 | type: "radio-panel", | ||
| 44 | placeholder: "", | ||
| 45 | field: "partitionMode", | ||
| 46 | default: "dynamic", | ||
| 47 | options: [ | ||
| 48 | { label: "动态分区", value: "dynamic" }, | ||
| 49 | { label: "静态分区", value: "static" }, | ||
| 50 | ], | ||
| 51 | children: [], | ||
| 52 | required: true, | ||
| 53 | block: true, | ||
| 54 | col: "no-wrap col2", | ||
| 55 | }, | ||
| 56 | { | ||
| 57 | label: "分区类型", | ||
| 58 | type: "select", | ||
| 59 | placeholder: "请选择", | ||
| 60 | options: [ | ||
| 61 | { | ||
| 62 | label: "Range", | ||
| 63 | value: "Range", | ||
| 64 | }, | ||
| 65 | { | ||
| 66 | label: "List", | ||
| 67 | value: "List", | ||
| 68 | }, | ||
| 69 | ], | ||
| 70 | field: "staticPartitionType", | ||
| 71 | default: 'Range', | ||
| 72 | required: true, | ||
| 73 | visible: false, | ||
| 74 | }, | ||
| 75 | { | ||
| 76 | label: "分区字段", | ||
| 77 | type: "select", | ||
| 78 | placeholder: "请选择", | ||
| 79 | options: [], | ||
| 80 | field: "partitionCol", | ||
| 81 | default: "", | ||
| 82 | props: { | ||
| 83 | label: 'chName', | ||
| 84 | value: 'enName' | ||
| 85 | }, | ||
| 86 | tooltip: true, | ||
| 87 | tooltipContent: '分区字段为日期、日期时间类型且为主键的字段。', | ||
| 88 | clearable: true, | ||
| 89 | required: true, | ||
| 90 | visible: true, | ||
| 91 | }, | ||
| 92 | { | ||
| 93 | label: "分区单位", | ||
| 94 | type: "select", | ||
| 95 | placeholder: "请选择", | ||
| 96 | options: [ | ||
| 97 | { | ||
| 98 | value: "DAY", | ||
| 99 | label: "按天", | ||
| 100 | }, | ||
| 101 | { | ||
| 102 | value: "WEEK", | ||
| 103 | label: "按星期", | ||
| 104 | }, | ||
| 105 | { | ||
| 106 | value: "MONTH", | ||
| 107 | label: "按月", | ||
| 108 | }, | ||
| 109 | { | ||
| 110 | value: "YEAR", | ||
| 111 | label: "按年", | ||
| 112 | }, | ||
| 113 | ], | ||
| 114 | default: "DAY", | ||
| 115 | field: "partitionTimeUnit", | ||
| 116 | required: true, | ||
| 117 | visible: false, | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | type: "select-group", | ||
| 121 | field: "dynamicPartitionTimeUnit", | ||
| 122 | children: [ | ||
| 123 | { | ||
| 124 | label: "分区单位", | ||
| 125 | type: "select", | ||
| 126 | placeholder: "请选择", | ||
| 127 | options: [ | ||
| 128 | { | ||
| 129 | value: "HOUR", | ||
| 130 | label: "按小时", | ||
| 131 | }, | ||
| 132 | { | ||
| 133 | value: "DAY", | ||
| 134 | label: "按天", | ||
| 135 | }, | ||
| 136 | { | ||
| 137 | value: "WEEK", | ||
| 138 | label: "按星期", | ||
| 139 | }, | ||
| 140 | { | ||
| 141 | value: "MONTH", | ||
| 142 | label: "按月", | ||
| 143 | }, | ||
| 144 | { | ||
| 145 | value: "YEAR", | ||
| 146 | label: "按年", | ||
| 147 | }, | ||
| 148 | ], | ||
| 149 | default: "DAY", | ||
| 150 | field: "partitionTimeUnit", | ||
| 151 | required: true, | ||
| 152 | visible: true, | ||
| 153 | }, | ||
| 154 | { | ||
| 155 | label: " ", | ||
| 156 | type: "input", | ||
| 157 | placeholder: "结束偏移量", | ||
| 158 | default: 3, | ||
| 159 | field: "dynamicPartitionEnd", | ||
| 160 | required: true, | ||
| 161 | visible: true, | ||
| 162 | }, | ||
| 163 | ], | ||
| 164 | col: "col2", | ||
| 165 | visible: true | ||
| 166 | }, | ||
| 167 | { | ||
| 168 | label: "分区范围", | ||
| 169 | type: "date-picker", | ||
| 170 | field: "staticPartitionRange", | ||
| 171 | default: null, | ||
| 172 | placeholder: "开始时间~截止时间", | ||
| 173 | clearable: true, | ||
| 174 | required: true, | ||
| 175 | visible: false, | ||
| 176 | }, | ||
| 177 | { | ||
| 178 | type: "checkbox-input", | ||
| 179 | placeholder: "创建历史分区", | ||
| 180 | field: "dynamicPartitionHistory", | ||
| 181 | default: false, | ||
| 182 | children: [ | ||
| 183 | { | ||
| 184 | label: "", | ||
| 185 | type: "input", | ||
| 186 | placeholder: "历史分区数量", | ||
| 187 | field: "dynamicPartitionHistoryNum", | ||
| 188 | default: 1, | ||
| 189 | required: false, | ||
| 190 | visible: false, | ||
| 191 | }, | ||
| 192 | ], | ||
| 193 | class: "dialog-checkbox-input", | ||
| 194 | visible: true, | ||
| 195 | required: false, | ||
| 196 | }, | ||
| 197 | { | ||
| 198 | label: "分区枚举值", | ||
| 199 | type: "textarea", | ||
| 200 | placeholder: "请使用“,”号分隔", | ||
| 201 | field: "staticPartitionEnum", | ||
| 202 | default: "", | ||
| 203 | clearable: true, | ||
| 204 | required: true, | ||
| 205 | block: true, | ||
| 206 | visible: false, | ||
| 207 | }, | ||
| 208 | ]); | ||
| 209 | const formRules = ref({ | ||
| 210 | staticPartitionType: [ | ||
| 211 | { | ||
| 212 | validator: (rule: any, value: any, callback: any) => { | ||
| 213 | if (!value) { | ||
| 214 | callback(new Error("分区类型不为空")); | ||
| 215 | } else { | ||
| 216 | callback(); | ||
| 217 | } | ||
| 218 | }, | ||
| 219 | trigger: "blur", | ||
| 220 | }, | ||
| 221 | ], | ||
| 222 | partitionCol: [{ | ||
| 223 | validator: (rule: any, value: any, callback: any) => { | ||
| 224 | if (!value) { | ||
| 225 | callback(new Error("分区字段不为空")); | ||
| 226 | } else { | ||
| 227 | callback(); | ||
| 228 | } | ||
| 229 | }, | ||
| 230 | trigger: "blur", | ||
| 231 | }], | ||
| 232 | staticPartitionRange: [{ | ||
| 233 | validator: (rule: any, value: any, callback: any) => { | ||
| 234 | if (!value?.length) { | ||
| 235 | callback(new Error("分区范围不为空")); | ||
| 236 | } else { | ||
| 237 | callback(); | ||
| 238 | } | ||
| 239 | }, | ||
| 240 | trigger: "blur", | ||
| 241 | }], | ||
| 242 | staticPartitionEnum: [{ | ||
| 243 | trigger: "blur", | ||
| 244 | required: true, | ||
| 245 | message: '分区枚举值不能为空' | ||
| 246 | }], | ||
| 247 | dynamicPartitionHistoryNum: { | ||
| 248 | validator: (rule: any, value: any, callback: any) => { | ||
| 249 | const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头) | ||
| 250 | if (value && !r.test(value)) { | ||
| 251 | callback(new Error('请填写大于或等于零整数')); | ||
| 252 | return; | ||
| 253 | } | ||
| 254 | if ((value + '').length > 6) { | ||
| 255 | callback(new Error('请填写小于7位的整数')); | ||
| 256 | return; | ||
| 257 | } | ||
| 258 | callback(); | ||
| 259 | }, | ||
| 260 | trigger: "blur", | ||
| 261 | }, | ||
| 262 | dynamicPartitionEnd: { | ||
| 263 | validator: (rule: any, value: any, callback: any) => { | ||
| 264 | const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头) | ||
| 265 | if (value && !r.test(value)) { | ||
| 266 | callback(new Error('请填写大于或等于零整数')); | ||
| 267 | return; | ||
| 268 | } | ||
| 269 | if ((value + '').length > 6) { | ||
| 270 | callback(new Error('请填写小于7位的整数')); | ||
| 271 | return; | ||
| 272 | } | ||
| 273 | callback(); | ||
| 274 | }, | ||
| 275 | trigger: "blur", | ||
| 276 | }, | ||
| 277 | }); | ||
| 278 | |||
| 279 | const expandPropertyDialogInfo = ref({ | ||
| 280 | readonly: false, | ||
| 281 | visible: false, | ||
| 282 | size: 700, | ||
| 283 | height: "270px", | ||
| 284 | header: { | ||
| 285 | title: "扩展属性", | ||
| 286 | }, | ||
| 287 | direction: "column", | ||
| 288 | type: "", | ||
| 289 | contents: [ | ||
| 290 | { | ||
| 291 | type: "form", | ||
| 292 | title: "", | ||
| 293 | formInfo: { | ||
| 294 | readonly: false, | ||
| 295 | id: "edit-expand-property", | ||
| 296 | items: formItems.value, | ||
| 297 | rules: formRules.value, | ||
| 298 | }, | ||
| 299 | }, | ||
| 300 | ], | ||
| 301 | footer: { | ||
| 302 | visible: true, | ||
| 303 | btns: [ | ||
| 304 | { type: "default", label: "取消", value: "cancel" }, | ||
| 305 | { type: "primary", label: "确定", value: "submit" }, | ||
| 306 | ], | ||
| 307 | }, | ||
| 308 | }); | ||
| 309 | |||
| 310 | /** 记录对话框编辑过程中的扩展属性。提交之后才会记录在expandProperties */ | ||
| 311 | const editExpandProperties: any = ref({}); | ||
| 312 | |||
| 313 | /** 扩展属性弹出对话框 */ | ||
| 314 | const handleClickExpand = () => { | ||
| 315 | expandPropertyDialogInfo.value.visible = true; | ||
| 316 | if (props.isLook || props.tableCreateInfo.isCreate) { | ||
| 317 | expandPropertyDialogInfo.value.contents[0].formInfo.readonly = true; | ||
| 318 | expandPropertyDialogInfo.value.footer.visible = false; | ||
| 319 | } else { | ||
| 320 | expandPropertyDialogInfo.value.contents[0].formInfo.readonly = false; | ||
| 321 | expandPropertyDialogInfo.value.footer.visible = true; | ||
| 322 | } | ||
| 323 | if (expandProperties.value.partitionMode === 'dynamic') { | ||
| 324 | formItems.value[1].visible = false; | ||
| 325 | formItems.value[2].visible = true; | ||
| 326 | formItems.value[3].visible = false; | ||
| 327 | formItems.value[4].visible = true; | ||
| 328 | formItems.value[5].visible = false; | ||
| 329 | formItems.value[6].visible = true; | ||
| 330 | formItems.value[7].visible = false; | ||
| 331 | formItems.value[6].children[0].visible = expandProperties.value.dynamicPartitionHistory; | ||
| 332 | formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || []; | ||
| 333 | formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。'; | ||
| 334 | } else { | ||
| 335 | formItems.value[1].visible = true; | ||
| 336 | formItems.value[2].visible = true; | ||
| 337 | formItems.value[3].visible = true; | ||
| 338 | formItems.value[4].visible = false; | ||
| 339 | formItems.value[5].visible = true; | ||
| 340 | formItems.value[6].visible = false; | ||
| 341 | formItems.value[7].visible = false; | ||
| 342 | let val = expandProperties.value.staticPartitionType; | ||
| 343 | formItems.value[3].visible = val !== 'List'; | ||
| 344 | formItems.value[5].visible = val !== 'List'; | ||
| 345 | formItems.value[7].visible = val === 'List'; | ||
| 346 | if (val !== 'List') { | ||
| 347 | formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || []; | ||
| 348 | formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。'; | ||
| 349 | } else { | ||
| 350 | formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y') || []; | ||
| 351 | formItems.value[2].tooltipContent = '分区字段为主键字段。'; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | expandPropertyDialogInfo.value.contents[0].formInfo.items = formItems.value; | ||
| 355 | editExpandProperties.value = Object.assign({}, expandProperties.value); | ||
| 356 | setFormItems(editExpandProperties.value); | ||
| 357 | }; | ||
| 358 | |||
| 359 | /** 重置formItems的值 */ | ||
| 360 | const setFormItems = (row: any = null) => { | ||
| 361 | formItems.value.forEach(item => { | ||
| 362 | if (item.field === 'dynamicPartitionTimeUnit') { | ||
| 363 | item.children.forEach(child => { | ||
| 364 | child.default = row[child.field]; | ||
| 365 | }); | ||
| 366 | } else if (item.field === 'dynamicPartitionHistory') { | ||
| 367 | item.default = row[item.field]; | ||
| 368 | item.children.forEach(child => { | ||
| 369 | child.default = row[child.field]; | ||
| 370 | }); | ||
| 371 | } else { | ||
| 372 | item.default = row[item.field]; | ||
| 373 | } | ||
| 374 | }) | ||
| 375 | } | ||
| 376 | |||
| 377 | const radioGroupChange = (val, info) => { | ||
| 378 | formItems.value[0].default = val; | ||
| 379 | if (val == "dynamic") { | ||
| 380 | formItems.value[1].visible = false; | ||
| 381 | formItems.value[2].visible = true; | ||
| 382 | formItems.value[3].visible = false; | ||
| 383 | formItems.value[4].visible = true; | ||
| 384 | formItems.value[5].visible = false; | ||
| 385 | formItems.value[6].visible = true; | ||
| 386 | formItems.value[7].visible = false; | ||
| 387 | } else if (val == "static") { | ||
| 388 | formItems.value[1].visible = true; | ||
| 389 | formItems.value[2].visible = true; | ||
| 390 | formItems.value[3].visible = true; | ||
| 391 | formItems.value[4].visible = false; | ||
| 392 | formItems.value[5].visible = true; | ||
| 393 | formItems.value[6].visible = false; | ||
| 394 | formItems.value[7].visible = false; | ||
| 395 | } | ||
| 396 | expandPropertyDialogInfo.value.contents[0].formInfo.items = formItems.value; | ||
| 397 | editExpandProperties.value = Object.assign({}, editExpandProperties.value, info) | ||
| 398 | setFormItems(editExpandProperties.value); | ||
| 399 | }; | ||
| 400 | |||
| 401 | const dialogCheckboxChange = (val, info) => { | ||
| 402 | let opts: any = formItems.value[6].children; | ||
| 403 | opts[0].visible = val; | ||
| 404 | editExpandProperties.value = Object.assign({}, editExpandProperties.value, info) | ||
| 405 | setFormItems(editExpandProperties.value); | ||
| 406 | }; | ||
| 407 | |||
| 408 | const dialogSelectChange = (val, row, info) => { | ||
| 409 | if (row.field == 'staticPartitionType') { | ||
| 410 | formItems.value[3].visible = val !== 'List'; | ||
| 411 | formItems.value[5].visible = val !== 'List'; | ||
| 412 | formItems.value[7].visible = val === 'List'; | ||
| 413 | if (val !== 'List') { | ||
| 414 | formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || []; | ||
| 415 | formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。'; | ||
| 416 | } else { | ||
| 417 | formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y') || []; | ||
| 418 | formItems.value[2].tooltipContent = '分区字段为主键字段。'; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | editExpandProperties.value = Object.assign({}, editExpandProperties.value, info) | ||
| 422 | setFormItems(editExpandProperties.value); | ||
| 423 | } | ||
| 424 | |||
| 425 | const expandPropertyDialogBtnClick = (btn, info) => { | ||
| 426 | if (btn.value == 'submit') { | ||
| 427 | emits('expandValueChange', info); | ||
| 428 | expandPropertyDialogInfo.value.visible = false; | ||
| 429 | } else if (btn.value == 'cancel') { | ||
| 430 | expandPropertyDialogInfo.value.visible = false; | ||
| 431 | } | ||
| 432 | }; | ||
| 433 | |||
| 434 | defineExpose({ | ||
| 435 | handleClickExpand | ||
| 436 | }); | ||
| 437 | |||
| 438 | </script> | ||
| 439 | |||
| 440 | <template> | ||
| 441 | <Dialog ref="expandPropertyDialogRef" :dialogInfo="expandPropertyDialogInfo" @radioGroupChange="radioGroupChange" | ||
| 442 | @checkboxChange="dialogCheckboxChange" @selectChange="dialogSelectChange" @btnClick="expandPropertyDialogBtnClick" /> | ||
| 443 | </template> | ||
| 444 | |||
| 445 | <style scoped lang="scss"></style> | ||
| 446 |
| 1 | <template> | ||
| 2 | <el-drawer | ||
| 3 | v-model="visible" | ||
| 4 | :title="title" | ||
| 5 | size="760px" | ||
| 6 | class="standard-modal" | ||
| 7 | :close-on-click-modal="false" | ||
| 8 | > | ||
| 9 | <el-form | ||
| 10 | :rules="formRules" :model="form" ref="formEl" | ||
| 11 | require-asterisk-position="right" | ||
| 12 | v-loading="loading" | ||
| 13 | > | ||
| 14 | <el-row> | ||
| 15 | <el-col :span="12" style="padding-right:10px"> | ||
| 16 | <el-form-item label="元数据标准名称" prop="standardName"> | ||
| 17 | <el-input v-model="form.standardName" placeholder="请输入" maxlength="50"/> | ||
| 18 | </el-form-item> | ||
| 19 | </el-col> | ||
| 20 | <el-col :span="12" style="padding-right:10px"> | ||
| 21 | <el-form-item label="上级标准" prop="parentGuid"> | ||
| 22 | <el-tree-select | ||
| 23 | v-model="form.parentGuid" | ||
| 24 | :data="treeSelectData" | ||
| 25 | :props="standardProps" | ||
| 26 | node-key="guid" | ||
| 27 | :highlight-current="true" | ||
| 28 | |||
| 29 | check-strictly | ||
| 30 | placeholder="请选择" | ||
| 31 | :disabled="treeSelectDisabled" | ||
| 32 | clearable | ||
| 33 | @check="parentGuidCheck" | ||
| 34 | @clear="parentGuidClear" | ||
| 35 | @nodeClick="parentGuidCheck" | ||
| 36 | /> | ||
| 37 | <!-- <el-cascader | ||
| 38 | v-model="form.parentGuid" | ||
| 39 | :options="standardOptions" | ||
| 40 | :props="standardProps" | ||
| 41 | :show-all-levels="false" | ||
| 42 | style="width:100%" | ||
| 43 | clearable | ||
| 44 | @change="parentGuidChange" | ||
| 45 | /> --> | ||
| 46 | </el-form-item> | ||
| 47 | </el-col> | ||
| 48 | <el-col :span="12" style="padding-right:10px"> | ||
| 49 | <el-form-item label="标准编号" prop="standardCode"> | ||
| 50 | <el-input v-model="form.standardCode" placeholder="请输入" maxlength="20"/> | ||
| 51 | </el-form-item> | ||
| 52 | </el-col> | ||
| 53 | <el-col :span="12" style="padding-right:10px"> | ||
| 54 | <el-form-item label="排序" prop="orderNum"> | ||
| 55 | <el-input v-model="form.orderNum" placeholder="请输入" type="number" maxlength="2"/> | ||
| 56 | </el-form-item> | ||
| 57 | </el-col> | ||
| 58 | <el-col :span="12" style="padding-right:10px"> | ||
| 59 | <el-form-item label="发布单位" prop="publishingUnitCode"> | ||
| 60 | <el-select v-model="form.publishingUnitCode" placeholder="请选择"> | ||
| 61 | <el-option v-for="item in publishUnitOptions" :label="item.label" :value="item.value" :key="item.value"></el-option> | ||
| 62 | </el-select> | ||
| 63 | </el-form-item> | ||
| 64 | </el-col> | ||
| 65 | |||
| 66 | <el-col :span="24"> | ||
| 67 | <el-form-item label="描述" prop="description"> | ||
| 68 | <el-input | ||
| 69 | v-model="form.description" | ||
| 70 | placeholder="请输入" | ||
| 71 | type="textarea" maxlength="200" | ||
| 72 | rows="4" | ||
| 73 | show-word-limit | ||
| 74 | /> | ||
| 75 | </el-form-item> | ||
| 76 | </el-col> | ||
| 77 | <el-col :span="24"> | ||
| 78 | <el-form-item label="自定义字段选择" v-if="fieldsTableShow" required> | ||
| 79 | <div class="table-form"> | ||
| 80 | <div class="table-form-wrapper" v-for="item,index in form.fieldRQVOS" :key="index"> | ||
| 81 | <div class="table-form-item"> | ||
| 82 | <el-select v-model="item.fileNameCode" style="width:160px" filterable clearable :disabled="fieldsDisabled"> | ||
| 83 | <el-option v-for="item in fieldOptions" :label="item.label" :value="item.value" :key="item.value"></el-option> | ||
| 84 | </el-select> | ||
| 85 | </div> | ||
| 86 | <div class="table-form-item"> | ||
| 87 | <el-select v-model="item.isNotnull" style="width: 96px" placeholder="是否必填" clearable :disabled="fieldsDisabled"> | ||
| 88 | <el-option v-for="item in isBooleanOptions" :label="item.label" :value="item.value" :key="item.value"></el-option> | ||
| 89 | </el-select> | ||
| 90 | </div> | ||
| 91 | <div class="table-form-item"> | ||
| 92 | <el-select v-model="item.isDisplay" style="width:96px" placeholder="是否展示" clearable :disabled="fieldsDisabled"> | ||
| 93 | <el-option v-for="item in isBooleanOptions" :label="item.label" :value="item.value" :key="item.value"></el-option> | ||
| 94 | </el-select> | ||
| 95 | </div> | ||
| 96 | <div class="table-form-item"> | ||
| 97 | <el-select v-model="item.inputTypeCode" style="width:130px" clearable :disabled="fieldsDisabled" | ||
| 98 | @change="v => inputTypeChange(v, item)"> | ||
| 99 | <el-option v-for="item in inputOptions" :label="item.label" :value="item.value" :key="item.value"></el-option> | ||
| 100 | </el-select> | ||
| 101 | </div> | ||
| 102 | <div class="table-form-item"> | ||
| 103 | <el-select | ||
| 104 | v-if="item.inputTypeCode == 2" | ||
| 105 | v-model="item.dataTypeCode" | ||
| 106 | style="width:160px" filterable clearable | ||
| 107 | :disabled="fieldsDisabled"> | ||
| 108 | <el-option v-for="item in allDictOptions" :label="item.dictTypeName" :value="item.dictTypeName" :key="item.guid"></el-option> | ||
| 109 | </el-select> | ||
| 110 | <el-input | ||
| 111 | v-else-if="item.inputTypeCode == 3" | ||
| 112 | v-model="item.validateExpression" | ||
| 113 | :disabled="fieldsDisabled" | ||
| 114 | placeholder="请输入" | ||
| 115 | ></el-input> | ||
| 116 | </div> | ||
| 117 | <div class="table-form-operation" v-if="!fieldsDisabled"> | ||
| 118 | <!-- <el-icon color="#4fa1a4" @click="() => addTableItem(index)"> | ||
| 119 | <CirclePlus /> | ||
| 120 | </el-icon> --> | ||
| 121 | <el-icon color="#b2b2b2" @click="() => deleteTableItem(index)" :size="22" class="custom-icon" style="margin-top:3px"><Delete /></el-icon> | ||
| 122 | </div> | ||
| 123 | </div> | ||
| 124 | <div class="table-form-add" v-if="!fieldsDisabled"> | ||
| 125 | <el-icon color="#4fa1a4" @click="() => addTableItem(index)" :size="20" class="custom-icon"> | ||
| 126 | <CirclePlus /> | ||
| 127 | </el-icon> | ||
| 128 | <span @click="() => addTableItem(index)" style="cursor: pointer;">添加字段</span> | ||
| 129 | </div> | ||
| 130 | </div> | ||
| 131 | </el-form-item> | ||
| 132 | </el-col> | ||
| 133 | </el-row> | ||
| 134 | </el-form> | ||
| 135 | <template #footer> | ||
| 136 | <div style="text-align:right"> | ||
| 137 | <el-button @click="visible = false" :disabled="confirmLoading">取消</el-button> | ||
| 138 | <el-button type="primary" @click="confirm" :loading="confirmLoading">确认</el-button> | ||
| 139 | </div> | ||
| 140 | </template> | ||
| 141 | |||
| 142 | </el-drawer> | ||
| 143 | </template> | ||
| 144 | |||
| 145 | <script setup lang="ts"> | ||
| 146 | // import { cloneDeep } from 'lodesh-es' | ||
| 147 | import { watch } from 'vue' | ||
| 148 | import { Search, CirclePlus, Delete } from '@element-plus/icons-vue' | ||
| 149 | import { saveMetaStandard, deleteMetaStandard, | ||
| 150 | updateMetaStandard, getMetaStandardDetail, | ||
| 151 | getMetaStandardTree | ||
| 152 | } from '@/api/modules/dataMetaService' | ||
| 153 | import { | ||
| 154 | getParamsList, getDictAllList | ||
| 155 | } from '@/api/modules/dataAsset' | ||
| 156 | import { ElMessage } from "element-plus"; | ||
| 157 | |||
| 158 | const { proxy } = getCurrentInstance() as any; | ||
| 159 | |||
| 160 | const props = defineProps({ | ||
| 161 | modelValue: Boolean, | ||
| 162 | standardOptions: { | ||
| 163 | type: Array, | ||
| 164 | default: () => ([]) | ||
| 165 | }, | ||
| 166 | type: { | ||
| 167 | type: String, | ||
| 168 | default: 'add' | ||
| 169 | }, | ||
| 170 | guid: { | ||
| 171 | type: String, | ||
| 172 | default: '' | ||
| 173 | }, | ||
| 174 | currentNode: { | ||
| 175 | type: Object, | ||
| 176 | default: () => ({}) | ||
| 177 | } | ||
| 178 | }) | ||
| 179 | const emit = defineEmits(['update:modelValue', 'success', 'confirm']); | ||
| 180 | const visible = computed({ | ||
| 181 | get() { | ||
| 182 | return props.modelValue; | ||
| 183 | }, | ||
| 184 | set(val) { | ||
| 185 | emit('update:modelValue', val); | ||
| 186 | } | ||
| 187 | }) | ||
| 188 | const title = computed(() => { | ||
| 189 | return props.type === 'add' ? '新增元数据标准' : '编辑元数据标准' | ||
| 190 | }) | ||
| 191 | |||
| 192 | /** | ||
| 193 | * 配置项列表 | ||
| 194 | */ | ||
| 195 | const publishUnitOptions = ref([]) | ||
| 196 | const standardProps = { | ||
| 197 | label: 'standardName', | ||
| 198 | value: 'guid', | ||
| 199 | checkStrictly: true, | ||
| 200 | emitPath: false | ||
| 201 | } | ||
| 202 | const standardTreeProps = { | ||
| 203 | label: 'standardName', | ||
| 204 | value: 'guid', | ||
| 205 | } | ||
| 206 | const fieldOptions = ref([]) | ||
| 207 | const isBooleanOptions = [ | ||
| 208 | { label: '是', value: 'Y' }, | ||
| 209 | { label: '否', value: 'N' }, | ||
| 210 | ] | ||
| 211 | const inputOptions = ref([]) | ||
| 212 | const allDictOptions = ref([]) | ||
| 213 | /**表单 */ | ||
| 214 | const formEl = ref() | ||
| 215 | const formTpl = { | ||
| 216 | standardName: '', | ||
| 217 | standardCode: '', | ||
| 218 | orderNum: '', | ||
| 219 | publishingUnitCode: '', | ||
| 220 | parentGuid: '', | ||
| 221 | description: '', | ||
| 222 | fieldRQVOS: null | ||
| 223 | } | ||
| 224 | const form = ref({...formTpl}) | ||
| 225 | const formRules = { | ||
| 226 | standardName: { required: true, message: '请填写元数据标准名称' }, | ||
| 227 | orderNum: { required: true, message: '请填写排序' }, | ||
| 228 | publishingUnitCode: { required: true, message: '请选择发布的单位' } | ||
| 229 | } | ||
| 230 | |||
| 231 | function parentGuidChange (val) { | ||
| 232 | console.log(val) | ||
| 233 | if (!val) { | ||
| 234 | form.value.fieldRQVOS = [] | ||
| 235 | return | ||
| 236 | } | ||
| 237 | const isFirst = props.standardOptions.find(item => item.guid === val) | ||
| 238 | if (isFirst) { | ||
| 239 | form.value.fieldRQVOS = [{...tableFormTpl}] | ||
| 240 | } | ||
| 241 | } | ||
| 242 | /** 上级标准树选择 */ | ||
| 243 | const treeSelectData = ref([]) | ||
| 244 | const treeCurrentNode = ref({}) | ||
| 245 | const treeSelectDisabled = ref(false) | ||
| 246 | const fieldsDisabled = ref(false) | ||
| 247 | const fieldsTableShow = ref(false) | ||
| 248 | watch( | ||
| 249 | () => treeCurrentNode, | ||
| 250 | (currentNode:any) => { | ||
| 251 | console.log('currentNode', currentNode.value) | ||
| 252 | let { level, isHaveData } = currentNode.value | ||
| 253 | fieldsTableShow.value = level ? true : false | ||
| 254 | fieldsDisabled.value = false | ||
| 255 | if (!level) { | ||
| 256 | form.value.fieldRQVOS = null | ||
| 257 | return | ||
| 258 | } | ||
| 259 | if (props.type === 'add') { | ||
| 260 | if (level == 1) { | ||
| 261 | // 所选为一级节点,当前二级节点 | ||
| 262 | form.value.fieldRQVOS = [{...tableFormTpl}] | ||
| 263 | } | ||
| 264 | if (level >= 2) { | ||
| 265 | // 所选为二级节点,当前三级节点以下,只读 | ||
| 266 | fieldsDisabled.value = true | ||
| 267 | } | ||
| 268 | } else if (props.type === 'edit') { | ||
| 269 | if (level == 1) { | ||
| 270 | // 所选为一级节点,当前二级节点 | ||
| 271 | form.value.fieldRQVOS = [{...tableFormTpl}] | ||
| 272 | fieldsDisabled.value = false | ||
| 273 | } | ||
| 274 | if (level >= 2) { | ||
| 275 | fieldsDisabled.value = true | ||
| 276 | } | ||
| 277 | } | ||
| 278 | }, | ||
| 279 | { deep: true} | ||
| 280 | ) | ||
| 281 | function parentGuidCheck (node, {checkedKeys}) { | ||
| 282 | console.log('node', node) | ||
| 283 | // fieldsControlDisabled.value = false | ||
| 284 | treeCurrentNode.value = node | ||
| 285 | // if (checkedKeys.length === 0) { | ||
| 286 | // treeCurrentNode.value = {} | ||
| 287 | // return | ||
| 288 | // } | ||
| 289 | if (node.level == 1) return | ||
| 290 | |||
| 291 | // 上级标准带出标准编号和发布单位 | ||
| 292 | // loading.value = true | ||
| 293 | getMetaStandardDetail(node.guid).then((res:any) => { | ||
| 294 | if (res.code === proxy.$passCode) { | ||
| 295 | const data = res.data | ||
| 296 | if (!form.value.standardCode) { | ||
| 297 | form.value.standardCode = data.standardCode | ||
| 298 | } | ||
| 299 | if (!form.value.publishingUnitCode) { | ||
| 300 | form.value.publishingUnitCode = data.publishingUnitCode | ||
| 301 | } | ||
| 302 | form.value.fieldRQVOS = data.fieldRSVOS | ||
| 303 | } | ||
| 304 | }) | ||
| 305 | } | ||
| 306 | function parentGuidClear () { | ||
| 307 | treeCurrentNode.value = {} | ||
| 308 | } | ||
| 309 | |||
| 310 | const tableFormTpl = { | ||
| 311 | fileNameCode: '', | ||
| 312 | isNotnull: 'N', | ||
| 313 | isDisplay: 'N', | ||
| 314 | inputTypeCode: '', | ||
| 315 | dataTypeCode: null, | ||
| 316 | validateExpression: null | ||
| 317 | } | ||
| 318 | function addTableItem (index) { | ||
| 319 | const tableObj = { ...tableFormTpl } | ||
| 320 | // form.value.fieldRQVOS.splice(index + 1, 0, tableObj) | ||
| 321 | form.value.fieldRQVOS.push(tableObj) | ||
| 322 | nextTick(() => { | ||
| 323 | let scrollBody = document.querySelector('.el-drawer__body') | ||
| 324 | scrollBody.scrollTop = scrollBody.scrollHeight | ||
| 325 | }) | ||
| 326 | } | ||
| 327 | function deleteTableItem (index) { | ||
| 328 | form.value.fieldRQVOS.splice(index, 1) | ||
| 329 | } | ||
| 330 | function inputTypeChange (val, item) { | ||
| 331 | console.log(val) | ||
| 332 | if (val == 2) { | ||
| 333 | // 下拉框 | ||
| 334 | item.validateExpression = null | ||
| 335 | } else if (val == 3) { | ||
| 336 | item.dataTypeCode = null | ||
| 337 | } else { | ||
| 338 | item.validateExpression = null | ||
| 339 | item.dataTypeCode = null | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | const loading = ref(false) | ||
| 344 | function getDetail () { | ||
| 345 | loading.value = true | ||
| 346 | return getMetaStandardDetail(props.guid).then((res:any) => { | ||
| 347 | if (res.code === proxy.$passCode) { | ||
| 348 | const data = res.data | ||
| 349 | data.fieldRQVOS = data.fieldRSVOS | ||
| 350 | form.value = { ...data } | ||
| 351 | let { level, isChildHaveData, children } = treeCurrentNode.value | ||
| 352 | if (level == 1) { | ||
| 353 | // 所选为一级节点,当前二级节点 | ||
| 354 | fieldsTableShow.value = false | ||
| 355 | } | ||
| 356 | if (level == 2) { | ||
| 357 | fieldsDisabled.value = isChildHaveData === 'Y' ? true : false | ||
| 358 | } | ||
| 359 | if (level >= 3) { | ||
| 360 | fieldsDisabled.value = true | ||
| 361 | } | ||
| 362 | if ((children && children.length) || isChildHaveData === 'Y') { | ||
| 363 | treeSelectDisabled.value = true | ||
| 364 | } | ||
| 365 | } | ||
| 366 | }).finally(() => loading.value = false) | ||
| 367 | } | ||
| 368 | const confirmLoading = ref(false) | ||
| 369 | function confirm () { | ||
| 370 | formEl.value.validate(valid => { | ||
| 371 | if (!valid) return | ||
| 372 | let body = { ...form.value } | ||
| 373 | if (!body.parentGuid) { | ||
| 374 | body.parentGuid = null | ||
| 375 | } | ||
| 376 | delete body.fieldRSVOS | ||
| 377 | // return | ||
| 378 | const request = props.type === 'add' ? saveMetaStandard : updateMetaStandard | ||
| 379 | confirmLoading.value = true | ||
| 380 | request(body).then((res:any) => { | ||
| 381 | if (res.code === proxy.$passCode) { | ||
| 382 | ElMessage.success('操作成功') | ||
| 383 | emit('success', props.type === 'add' ? res.data : body.guid) | ||
| 384 | visible.value = false | ||
| 385 | return | ||
| 386 | } | ||
| 387 | ElMessage.error(res.msg) | ||
| 388 | }).finally(() => confirmLoading.value = false) | ||
| 389 | }) | ||
| 390 | } | ||
| 391 | |||
| 392 | function getTreeSelectOptions () { | ||
| 393 | return getMetaStandardTree().then((res:any) => { | ||
| 394 | if (res.code === proxy.$passCode) { | ||
| 395 | let data = res.data || [] | ||
| 396 | data.forEach(item => { | ||
| 397 | item.showEdit = true | ||
| 398 | item.level = 1 | ||
| 399 | }) | ||
| 400 | treeSelectData.value = data | ||
| 401 | } | ||
| 402 | }) | ||
| 403 | } | ||
| 404 | |||
| 405 | watch( | ||
| 406 | () => visible.value, | ||
| 407 | (v) => { | ||
| 408 | if (!v) return | ||
| 409 | // console.log(props.currentNode) | ||
| 410 | // 上级标准:不能选自己,有数据的标准不能选 | ||
| 411 | // treeSelectData.value = JSON.parse(JSON.stringify(props.standardOptions)) | ||
| 412 | treeSelectDisabled.value = false | ||
| 413 | if (props.type === 'edit') { | ||
| 414 | // fieldsControlDisabled.value = false | ||
| 415 | |||
| 416 | getTreeSelectOptions().then(() => { | ||
| 417 | getDetail().then(() => formatOptions(treeSelectData.value)) | ||
| 418 | }) | ||
| 419 | treeCurrentNode.value = props.currentNode | ||
| 420 | } else { | ||
| 421 | // fieldsControlDisabled.value = true | ||
| 422 | form.value = { ...formTpl } | ||
| 423 | getTreeSelectOptions().then(() => { | ||
| 424 | formatOptions(treeSelectData.value) | ||
| 425 | }) | ||
| 426 | treeCurrentNode.value = {} | ||
| 427 | } | ||
| 428 | setTimeout(() => { | ||
| 429 | formEl.value.clearValidate() | ||
| 430 | |||
| 431 | }, 100) | ||
| 432 | } | ||
| 433 | ) | ||
| 434 | function formatOptions (options, level = 1) { | ||
| 435 | options.forEach((item:any) => { | ||
| 436 | let disabled = form.value.guid === item.guid ? true : false | ||
| 437 | if (item.isHaveData === 'Y') { | ||
| 438 | disabled = true | ||
| 439 | } | ||
| 440 | item.disabled = disabled | ||
| 441 | item.level = level | ||
| 442 | if (item.children) { | ||
| 443 | formatOptions(item.children, level + 1) | ||
| 444 | } | ||
| 445 | }) | ||
| 446 | } | ||
| 447 | onBeforeMount(() => { | ||
| 448 | getParamsList({ dictType: '发布单位' }).then((res:any) => { | ||
| 449 | if (res.code === proxy.$passCode) { | ||
| 450 | const data = res.data || [] | ||
| 451 | publishUnitOptions.value = data | ||
| 452 | } | ||
| 453 | }) | ||
| 454 | getParamsList({ dictType: '字段名代码' }).then((res:any) => { | ||
| 455 | if (res.code === proxy.$passCode) { | ||
| 456 | const data = res.data || [] | ||
| 457 | fieldOptions.value = data | ||
| 458 | } | ||
| 459 | }) | ||
| 460 | getParamsList({ dictType: '输入框类型' }).then((res:any) => { | ||
| 461 | if (res.code === proxy.$passCode) { | ||
| 462 | const data = res.data || [] | ||
| 463 | inputOptions.value = data | ||
| 464 | } | ||
| 465 | }) | ||
| 466 | getDictAllList().then((res:any) => { | ||
| 467 | if (res.code === proxy.$passCode) { | ||
| 468 | const data = res.data || [] | ||
| 469 | allDictOptions.value = data | ||
| 470 | } | ||
| 471 | }) | ||
| 472 | }) | ||
| 473 | </script> | ||
| 474 | |||
| 475 | <style lang="scss"> | ||
| 476 | .standard-modal { | ||
| 477 | .el-form-item { | ||
| 478 | flex-direction: column; | ||
| 479 | .el-form-item__label { | ||
| 480 | justify-content: flex-start; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | .el-drawer__footer { | ||
| 484 | padding: 10px; | ||
| 485 | justify-content: flex-end; | ||
| 486 | } | ||
| 487 | .el-dialog__body { | ||
| 488 | height: 500px; | ||
| 489 | overflow: auto; | ||
| 490 | } | ||
| 491 | .table-form-wrapper { | ||
| 492 | display: flex; | ||
| 493 | margin-bottom: 5px; | ||
| 494 | .table-form-item { | ||
| 495 | padding-right: 10px; | ||
| 496 | } | ||
| 497 | .table-form-operation { | ||
| 498 | flex: 0 0 30px; | ||
| 499 | // padding-left: 6px; | ||
| 500 | } | ||
| 501 | } | ||
| 502 | .table-form-add { | ||
| 503 | display: flex; | ||
| 504 | align-items: center; | ||
| 505 | color: #4fa1a4; | ||
| 506 | > span { | ||
| 507 | margin-left: 4px; | ||
| 508 | } | ||
| 509 | } | ||
| 510 | } | ||
| 511 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <template> | ||
| 2 | <el-drawer | ||
| 3 | v-model="visible" | ||
| 4 | :title="title" | ||
| 5 | size="520px" | ||
| 6 | class="standard-meta-modal" | ||
| 7 | :close-on-click-modal="false" | ||
| 8 | > | ||
| 9 | <el-form | ||
| 10 | :model="form" | ||
| 11 | :rules="formRules" | ||
| 12 | ref="formEl" | ||
| 13 | style="min-height: 200px;" | ||
| 14 | require-asterisk-position="right" | ||
| 15 | v-loading="loading" | ||
| 16 | > | ||
| 17 | <el-row> | ||
| 18 | <el-col v-for="item,index in fields" :key="index" :span="12" style="padding-right:10px;"> | ||
| 19 | <el-form-item :label="item.fileNameCodeName" :prop="item.fileNameCode"> | ||
| 20 | <el-input | ||
| 21 | v-if="item.inputTypeCode == '1' || item.inputTypeCode == '3'" | ||
| 22 | v-model="form[item.fileNameCode]" | ||
| 23 | placeholder="请输入" | ||
| 24 | /> | ||
| 25 | <el-select | ||
| 26 | v-else-if="item.inputTypeCode == '2'" | ||
| 27 | v-model="form[item.fileNameCode]" | ||
| 28 | filterable | ||
| 29 | clearable | ||
| 30 | placeholder="请选择" | ||
| 31 | > | ||
| 32 | <el-option v-for="op in formOptions[item.fileNameCode]" :label="op.label" :value="op.value" :key="op.value"></el-option> | ||
| 33 | </el-select> | ||
| 34 | <el-tree-select | ||
| 35 | v-else-if="item.inputTypeCode == '4'" | ||
| 36 | v-model="form[item.fileNameCode]" | ||
| 37 | :data="standardCodeTree" | ||
| 38 | :props="treeSelectProps" | ||
| 39 | placeholder="请选择" | ||
| 40 | filterable | ||
| 41 | clearable | ||
| 42 | /> | ||
| 43 | </el-form-item> | ||
| 44 | </el-col> | ||
| 45 | </el-row> | ||
| 46 | </el-form> | ||
| 47 | <template #footer> | ||
| 48 | <div style="text-align:right"> | ||
| 49 | <el-button @click="visible = false" :disabled="confirmLoading">取消</el-button> | ||
| 50 | <el-button type="primary" @click="confirm" :loading="confirmLoading">确认</el-button> | ||
| 51 | </div> | ||
| 52 | </template> | ||
| 53 | </el-drawer> | ||
| 54 | </template> | ||
| 55 | |||
| 56 | <script setup lang="ts"> | ||
| 57 | import { watch } from 'vue' | ||
| 58 | import { ElMessage } from "element-plus"; | ||
| 59 | import { getParamsList } from '@/api/modules/dataAsset' | ||
| 60 | import { saveMetaStandardDataFields, getMetaStandardFieldsDetail, getStandardCodeTree } from '@/api/modules/dataMetaService' | ||
| 61 | |||
| 62 | const { proxy } = getCurrentInstance() as any; | ||
| 63 | const props = defineProps({ | ||
| 64 | modelValue: Boolean, | ||
| 65 | fields: { | ||
| 66 | type: Array, | ||
| 67 | default: () => ([]) | ||
| 68 | }, | ||
| 69 | metaStandardGuid: { | ||
| 70 | type: String, | ||
| 71 | default: '' | ||
| 72 | }, | ||
| 73 | type: { | ||
| 74 | type: String, | ||
| 75 | default: 'add' | ||
| 76 | }, | ||
| 77 | data: { | ||
| 78 | type: Object, | ||
| 79 | default: () => ({}) | ||
| 80 | } | ||
| 81 | }) | ||
| 82 | const emit = defineEmits(['update:modelValue', 'success', 'confirm']) | ||
| 83 | const visible = computed({ | ||
| 84 | get() { | ||
| 85 | return props.modelValue; | ||
| 86 | }, | ||
| 87 | set(val) { | ||
| 88 | emit('update:modelValue', val); | ||
| 89 | } | ||
| 90 | }) | ||
| 91 | const title = computed(() => { | ||
| 92 | return props.type === 'add' ? '新增字段标准' : '编辑字段标准' | ||
| 93 | }) | ||
| 94 | |||
| 95 | const formEl = ref() | ||
| 96 | const form = ref({}) | ||
| 97 | const formRules = ref({}) | ||
| 98 | const formOptions = ref({}) | ||
| 99 | const detail = ref({}) | ||
| 100 | |||
| 101 | async function initForm () { | ||
| 102 | const { fields, type, data } = props | ||
| 103 | console.log(data) | ||
| 104 | if (!fields) return | ||
| 105 | let formData = {} | ||
| 106 | let formRuleData = {} | ||
| 107 | let formOptionData = {} | ||
| 108 | let detailData:any = {} | ||
| 109 | if (type === 'edit') { | ||
| 110 | detailData = await getDetail() | ||
| 111 | detail.value = detailData | ||
| 112 | } | ||
| 113 | fields.forEach(async (item:any) => { | ||
| 114 | formData[item.fileNameCode] = type === 'add' ? '' : detailData.metaStandardValue[item.fileNameCode] | ||
| 115 | formRuleData[item.fileNameCode] = { | ||
| 116 | required: item.isNotnull === 'Y' ? true : false, | ||
| 117 | message: `缺少${item.fileNameCodeName}` | ||
| 118 | } | ||
| 119 | // formOptionData[item.fileNameCode] = await getOptions(item.dataTypeCode) | ||
| 120 | if (item.inputTypeCode == '2') { | ||
| 121 | formOptions.value[item.fileNameCode] = await getOptions(item.dataTypeCode) | ||
| 122 | } | ||
| 123 | }) | ||
| 124 | // formOptions.value = formOptionData | ||
| 125 | form.value = formData | ||
| 126 | formRules.value = formRuleData | ||
| 127 | nextTick(() => formEl.value.clearValidate()) | ||
| 128 | setTimeout(() => { | ||
| 129 | formEl.value.clearValidate() | ||
| 130 | }, 100) | ||
| 131 | } | ||
| 132 | function getOptions (dictType) { | ||
| 133 | return new Promise((resolve, reject) => { | ||
| 134 | getParamsList({ dictType }).then((res:any) => { | ||
| 135 | if (res.code === proxy.$passCode) { | ||
| 136 | resolve(res.data) | ||
| 137 | } | ||
| 138 | }) | ||
| 139 | }) | ||
| 140 | } | ||
| 141 | const loading = ref(false) | ||
| 142 | function getDetail () { | ||
| 143 | return new Promise((resolve) => { | ||
| 144 | loading.value = true | ||
| 145 | getMetaStandardFieldsDetail(props.data.guid).then((res:any) => { | ||
| 146 | if (res.code === proxy.$passCode) { | ||
| 147 | resolve(res.data) | ||
| 148 | } | ||
| 149 | }).finally(() => loading.value = false) | ||
| 150 | }) | ||
| 151 | } | ||
| 152 | |||
| 153 | const confirmLoading = ref(false) | ||
| 154 | function confirm () { | ||
| 155 | console.log(form.value) | ||
| 156 | formEl.value.validate(valid => { | ||
| 157 | if (!valid) return | ||
| 158 | let body = { | ||
| 159 | metaStandardGuid: props.type === 'edit' ? detail.value.metaStandardGuid : props.metaStandardGuid, | ||
| 160 | metaStandardValue: { ...form.value } | ||
| 161 | } | ||
| 162 | if (props.type === 'edit') { | ||
| 163 | body.guid = props.data.guid | ||
| 164 | } | ||
| 165 | confirmLoading.value = true | ||
| 166 | saveMetaStandardDataFields(body).then((res:any) => { | ||
| 167 | if (res.code === proxy.$passCode) { | ||
| 168 | ElMessage.success('操作成功') | ||
| 169 | emit('success') | ||
| 170 | visible.value = false | ||
| 171 | } else { | ||
| 172 | ElMessage.error(res.msg) | ||
| 173 | } | ||
| 174 | }).finally(() => confirmLoading.value = false) | ||
| 175 | }) | ||
| 176 | } | ||
| 177 | |||
| 178 | const standardCodeTree = ref([]) | ||
| 179 | const treeSelectProps = { | ||
| 180 | label: 'name', | ||
| 181 | value: 'guid', | ||
| 182 | isLeaf: 'isCode' | ||
| 183 | } | ||
| 184 | function getStandardCodeTreeList () { | ||
| 185 | getStandardCodeTree().then((res:any) => { | ||
| 186 | if (res.code === proxy.$passCode) { | ||
| 187 | const data = res.data | ||
| 188 | data.forEach(item => { | ||
| 189 | if (item.children) { | ||
| 190 | item.children.forEach(subItem => { | ||
| 191 | // 二级的标准名字作为key | ||
| 192 | subItem.guid = subItem.name | ||
| 193 | // subItem.value = subItem.name | ||
| 194 | }) | ||
| 195 | } | ||
| 196 | }) | ||
| 197 | standardCodeTree.value = data | ||
| 198 | } | ||
| 199 | }) | ||
| 200 | } | ||
| 201 | |||
| 202 | watch( | ||
| 203 | () => visible.value, | ||
| 204 | (v) => { | ||
| 205 | if (!v) return | ||
| 206 | initForm() | ||
| 207 | } | ||
| 208 | ) | ||
| 209 | |||
| 210 | onBeforeMount(() => { | ||
| 211 | getStandardCodeTreeList() | ||
| 212 | }) | ||
| 213 | </script> | ||
| 214 | |||
| 215 | <style lang="scss"> | ||
| 216 | .standard-meta-modal { | ||
| 217 | .el-form-item { | ||
| 218 | flex-direction: column; | ||
| 219 | .el-form-item__label { | ||
| 220 | justify-content: flex-start; | ||
| 221 | } | ||
| 222 | } | ||
| 223 | .el-drawer__footer { | ||
| 224 | padding: 10px; | ||
| 225 | justify-content: flex-end; | ||
| 226 | } | ||
| 227 | |||
| 228 | .table-form-wrapper { | ||
| 229 | display: flex; | ||
| 230 | margin-bottom: 5px; | ||
| 231 | .table-form-item { | ||
| 232 | padding-right: 10px; | ||
| 233 | } | ||
| 234 | .table-form-operation { | ||
| 235 | flex: 0 0 70px; | ||
| 236 | padding-left: 6px; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <template> | ||
| 2 | <el-select v-if="!readonly && isEdit && isSelectType(dbType, scope)" v-model="scope.row['defaultValue']" placeholder="请选择" collapse-tags-tooltip | ||
| 3 | filterable allow-create default-first-option :reserve-keyword="false"> | ||
| 4 | <el-option v-for="opt in optionsConfig[dataType]" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 5 | </el-select> | ||
| 6 | <el-date-picker v-else-if="!readonly && isEdit && dataType === 'date'" v-model="scope.row['defaultValue']" type="date" | ||
| 7 | format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择" /> | ||
| 8 | <el-date-picker v-else-if="!readonly && isEdit && dbType === 'mysql' && dataType === 'datetime'" | ||
| 9 | v-model="scope.row['defaultValue']" placeholder="请选择" type="datetime" format="YYYY-MM-DD HH:mm:ss" | ||
| 10 | value-format="YYYY-MM-DD HH:mm:ss" /> | ||
| 11 | <el-input v-else-if="!readonly && isEdit" v-model.trim="scope.row['defaultValue']" placeholder="请填写" | ||
| 12 | @input="(val) => inputChange(val, scope.row.dataType, scope)" /> | ||
| 13 | <span v-else>{{ scope.row["defaultValue"] == null ? '-' : (isSelectType(dbType, scope) ? | ||
| 14 | (optionsConfig[dataType].find(s => s.value == scope.row["defaultValue"])?.label ?? | ||
| 15 | scope.row["defaultValue"]) : scope.row["defaultValue"]) }}</span> | ||
| 16 | </template> | ||
| 17 | |||
| 18 | <script lang="ts" setup name="tableDefaultValue"> | ||
| 19 | import { ref } from "vue"; | ||
| 20 | import { useDefault } from "@/hooks/useDefault"; | ||
| 21 | const { optionsConfig, inputChange, isSelectType } = useDefault() | ||
| 22 | |||
| 23 | const props = defineProps({ | ||
| 24 | dbType: { | ||
| 25 | type: String, | ||
| 26 | default: '' | ||
| 27 | }, | ||
| 28 | scope: { | ||
| 29 | type: Object, | ||
| 30 | default: {} | ||
| 31 | }, | ||
| 32 | readonly: { | ||
| 33 | type: Boolean, | ||
| 34 | default: false | ||
| 35 | } | ||
| 36 | }) | ||
| 37 | |||
| 38 | const isEdit = computed(() => { | ||
| 39 | return props.scope.row['isEdit']; | ||
| 40 | }); | ||
| 41 | |||
| 42 | const dataType = computed(() => { | ||
| 43 | return props.scope.row['dataType']; | ||
| 44 | }); | ||
| 45 | |||
| 46 | </script> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/data_meta/dimTableCreateManual.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: dimTableCreateManual | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="dimTableCreateManual"> | ||
| 6 | import { ref } from "vue"; | ||
| 7 | import { useRouter, useRoute } from "vue-router"; | ||
| 8 | import { ElMessage, ElMessageBox, ElTable } from "element-plus"; | ||
| 9 | import { QuestionFilled } from "@element-plus/icons-vue"; | ||
| 10 | import { | ||
| 11 | getDatabase, | ||
| 12 | saveSubjectTable, | ||
| 13 | dimTypeList, | ||
| 14 | syncPolicys, | ||
| 15 | tableModels, | ||
| 16 | aggMethodList, | ||
| 17 | getMetaStandardDsField, | ||
| 18 | getAllFlowData | ||
| 19 | } from "@/api/modules/dataMetaService"; | ||
| 20 | import useUserStore from "@/store/modules/user"; | ||
| 21 | import expandPropertyDialog from "./components/expandPropertyDialog.vue"; | ||
| 22 | import tableDefaultValue from "./components/tableDefaultValue.vue"; | ||
| 23 | import { useDefault } from "@/hooks/useDefault" | ||
| 24 | import { getCamundaDeploymentId } from "@/api/modules/workFlowService" | ||
| 25 | |||
| 26 | const userStore = useUserStore(); | ||
| 27 | const { checkDefault } = useDefault() | ||
| 28 | |||
| 29 | const router = useRouter(); | ||
| 30 | const route = useRoute(); | ||
| 31 | const fullPath = route.fullPath; | ||
| 32 | const isLook = <any>route.query.isLook == 1; | ||
| 33 | const subjectDomainGuid: any = ref(route.query.domainGuid); | ||
| 34 | |||
| 35 | const tableCreateInfoLoading = ref(false); | ||
| 36 | |||
| 37 | const { proxy } = getCurrentInstance() as any; | ||
| 38 | const fieldStandardTableRef = ref<InstanceType<typeof ElTable>>(); | ||
| 39 | |||
| 40 | /** 表模型,只有doris数据库才有 */ | ||
| 41 | const dbType = ref(""); | ||
| 42 | |||
| 43 | const databaseList: any = ref([]); | ||
| 44 | |||
| 45 | const tableFieldsLoading = ref(false); | ||
| 46 | |||
| 47 | //记录当前正在编辑的表创建信息。 | ||
| 48 | const tableCreateInfo: Ref<any> = ref({ | ||
| 49 | guid: "", | ||
| 50 | isCreate: false, | ||
| 51 | inputNameValue: '', | ||
| 52 | tableCreateType: 1, | ||
| 53 | tableData: [ | ||
| 54 | { | ||
| 55 | //数据库表信息。 | ||
| 56 | dataSourceGuid: '', | ||
| 57 | dataServerName: "", | ||
| 58 | dataServerChName: "", | ||
| 59 | enName: "", | ||
| 60 | chName: "", | ||
| 61 | subjectDomain: route.query.domainName, | ||
| 62 | subjectDomainGuid: subjectDomainGuid.value, | ||
| 63 | dimType: 1, | ||
| 64 | codeColumn: '', | ||
| 65 | codeName: '', | ||
| 66 | syncPolicy: 3, | ||
| 67 | tableCategory: 4, | ||
| 68 | characterSet: 'utf8mb3', | ||
| 69 | tableModel: 1, //若是聚合模型,下方出现一列聚合方式选择。处了主键列,其余列都需要选择。每个表里都要有主键。 | ||
| 70 | description: "", | ||
| 71 | }, | ||
| 72 | ], | ||
| 73 | partitionAttribute: {}, | ||
| 74 | tableFields: [], // 字段标准数组。 | ||
| 75 | }); | ||
| 76 | |||
| 77 | const selectTableFieldRows = ref([]); | ||
| 78 | |||
| 79 | //字段类型 | ||
| 80 | const fieldTypes: any = ref([]); | ||
| 81 | |||
| 82 | //字符集 | ||
| 83 | const characterList: any = ref([]); | ||
| 84 | |||
| 85 | //是否列表 | ||
| 86 | const isNotList = ref([ | ||
| 87 | { | ||
| 88 | label: "Y", | ||
| 89 | value: "Y", | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | label: "N", | ||
| 93 | value: "N", | ||
| 94 | }, | ||
| 95 | ]); | ||
| 96 | |||
| 97 | const fullscreenLoading = ref(false); | ||
| 98 | |||
| 99 | /** 表里有数据时删除字段时提示。 */ | ||
| 100 | const hasSubjectData = ref(false); | ||
| 101 | |||
| 102 | const expandProperties = ref({}); | ||
| 103 | |||
| 104 | const deploymentId = ref(''); | ||
| 105 | const flowExpand = ref(true); | ||
| 106 | |||
| 107 | onBeforeMount(() => { | ||
| 108 | getDatabaseList(); | ||
| 109 | getFieldTypeList(); | ||
| 110 | getCharacterListData(); | ||
| 111 | if (route.query.metaStandard) { | ||
| 112 | tableCreateInfo.value.tableData[0].chName = route.query.standardName; | ||
| 113 | fullscreenLoading.value = true; | ||
| 114 | getMetaStandardDsField(route.query.metaStandard).then((res: any) => { | ||
| 115 | fullscreenLoading.value = false; | ||
| 116 | if (res.code == proxy.$passCode) { | ||
| 117 | tableCreateInfo.value.tableFields = res.data?.map((d, i) => { | ||
| 118 | d.orderNum = i; | ||
| 119 | d.isEdit = true; | ||
| 120 | return d; | ||
| 121 | }) || []; | ||
| 122 | } else { | ||
| 123 | proxy.$ElMessage.error(res.msg); | ||
| 124 | } | ||
| 125 | }) | ||
| 126 | } | ||
| 127 | getCamundaDeploymentId('10025').then((res: any) => { | ||
| 128 | if (res.code == proxy.$passCode) { | ||
| 129 | deploymentId.value = res.data; | ||
| 130 | } else { | ||
| 131 | proxy.$ElMessage.error(res.msg); | ||
| 132 | } | ||
| 133 | }) | ||
| 134 | }) | ||
| 135 | |||
| 136 | onMounted(() => { | ||
| 137 | }) | ||
| 138 | |||
| 139 | onActivated(() => { | ||
| 140 | }); | ||
| 141 | |||
| 142 | const getDatabaseList = () => { | ||
| 143 | getDatabase({ connectStatus: 1 }).then((res: any) => { | ||
| 144 | databaseList.value = []; | ||
| 145 | if (res.code == proxy.$passCode) { | ||
| 146 | databaseList.value = res.data || []; | ||
| 147 | } else { | ||
| 148 | ElMessage.error(res.msg); | ||
| 149 | } | ||
| 150 | }) | ||
| 151 | }; | ||
| 152 | |||
| 153 | const getFieldTypeList = () => { | ||
| 154 | getAllFlowData('字段类型').then((res: any) => { | ||
| 155 | fieldTypes.value = []; | ||
| 156 | if (res.code == proxy.$passCode) { | ||
| 157 | fieldTypes.value = res.data || []; | ||
| 158 | } else { | ||
| 159 | ElMessage.error(res.msg); | ||
| 160 | } | ||
| 161 | }) | ||
| 162 | } | ||
| 163 | |||
| 164 | const getCharacterListData = () => { | ||
| 165 | getAllFlowData('Mysql字符集').then((res: any) => { | ||
| 166 | characterList.value = []; | ||
| 167 | if (res.code == proxy.$passCode) { | ||
| 168 | characterList.value = res.data || []; | ||
| 169 | } else { | ||
| 170 | ElMessage.error(res.msg); | ||
| 171 | } | ||
| 172 | }) | ||
| 173 | } | ||
| 174 | |||
| 175 | /** 限制长度输入框只能输入整型数字,表,字段英文名称,限制输入字符,数字和下划线。 */ | ||
| 176 | const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null) => { | ||
| 177 | scope.row[field] = scope.row[field].replace(regexp, ''); | ||
| 178 | if (field == 'fieldLength' && scope.row.dataType == 'decimal') { | ||
| 179 | max = 65; | ||
| 180 | } | ||
| 181 | /** 最大值设置2000 */ | ||
| 182 | if (max && scope.row[field] > max) { | ||
| 183 | scope.row[field] = max; | ||
| 184 | } | ||
| 185 | if (min !== null && scope.row[field] != '' && scope.row[field] <= min) { | ||
| 186 | scope.row[field] = min; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 190 | /** 保存表 */ | ||
| 191 | const saveTable = () => { | ||
| 192 | let tableData = tableCreateInfo.value.tableData[0]; | ||
| 193 | if (!tableData.chName) { | ||
| 194 | ElMessage({ | ||
| 195 | type: "error", | ||
| 196 | message: "主题表名称不能为空", | ||
| 197 | }); | ||
| 198 | return; | ||
| 199 | } | ||
| 200 | if (!tableData.dataServerName) { | ||
| 201 | ElMessage({ | ||
| 202 | type: "error", | ||
| 203 | message: "数据源不能为空", | ||
| 204 | }); | ||
| 205 | return; | ||
| 206 | } | ||
| 207 | if (tableData.dataServerName.indexOf('-') > -1) { | ||
| 208 | ElMessage.error('数据库表名称不能包含中划线,可以改为下划线'); | ||
| 209 | return; | ||
| 210 | } | ||
| 211 | if (!tableCreateInfo.value.inputNameValue) { | ||
| 212 | ElMessage({ | ||
| 213 | type: "error", | ||
| 214 | message: "主题表名称不能为空", | ||
| 215 | }); | ||
| 216 | return; | ||
| 217 | } | ||
| 218 | if (!tableData.codeColumn) { | ||
| 219 | ElMessage({ | ||
| 220 | type: "error", | ||
| 221 | message: "编码字段不能为空", | ||
| 222 | }); | ||
| 223 | return; | ||
| 224 | } | ||
| 225 | if (!tableData.codeName) { | ||
| 226 | ElMessage({ | ||
| 227 | type: "error", | ||
| 228 | message: "编码名称不能为空", | ||
| 229 | }); | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 233 | if (!tableFields.length) { | ||
| 234 | ElMessage({ | ||
| 235 | type: "error", | ||
| 236 | message: "表字段不能为0行", | ||
| 237 | }); | ||
| 238 | return; | ||
| 239 | } | ||
| 240 | // 若开启了字段标准,则不能为空。 | ||
| 241 | // 必须含有主键。若是聚合模型,则除了主键必须有聚合方式。 | ||
| 242 | let isSumModel = tableData.tableModel === 2; | ||
| 243 | let hasPrimary = false; | ||
| 244 | let enNames: any = []; | ||
| 245 | let chNames: any = []; | ||
| 246 | const regex = /^[a-zA-Z]/; | ||
| 247 | for (const field of tableFields) { | ||
| 248 | if (!field.enName) { | ||
| 249 | ElMessage.error(`第 ${field.orderNum} 个字段的英文名称不能为空`); | ||
| 250 | return; | ||
| 251 | } | ||
| 252 | if (!regex.test(field.enName)) { | ||
| 253 | ElMessage.error(`第 ${field.orderNum} 个字段的英文名称必须以英文字符开头`); | ||
| 254 | return; | ||
| 255 | } | ||
| 256 | if (!field.dataType) { | ||
| 257 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型不能为空`); | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | if (enNames.indexOf(field.enName) > -1) { | ||
| 261 | ElMessage.error(`字段的英文名称 ${field.enName} 不能重复`); | ||
| 262 | return; | ||
| 263 | } | ||
| 264 | if (chNames.indexOf(field.chName) > -1) { | ||
| 265 | ElMessage.error(`字段的中文名称 ${field.chName} 不能重复`); | ||
| 266 | return; | ||
| 267 | } | ||
| 268 | if (field.dataType === "decimal" && (!field.fieldPrecision && field.fieldPrecision != 0)) { | ||
| 269 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为浮点型时,精度不能为空`); | ||
| 270 | return; | ||
| 271 | } | ||
| 272 | if (field.dataType === "varchar" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 273 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为字符型时,长度不能为空`); | ||
| 274 | return; | ||
| 275 | } | ||
| 276 | if (field.dataType === "char" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 277 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为单字符型时,长度不能为空`); | ||
| 278 | return; | ||
| 279 | } | ||
| 280 | if (field.dataType === "decimal" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 281 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为浮点符型时,长度不能为空`); | ||
| 282 | return; | ||
| 283 | } | ||
| 284 | if (field.isPrimary === 'Y') { | ||
| 285 | hasPrimary = true; | ||
| 286 | if (field.notNull != 'Y') { | ||
| 287 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,应设置为必填`); | ||
| 288 | return; | ||
| 289 | } | ||
| 290 | if (field.dataType == 'text') { | ||
| 291 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘大字段型’`); | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | if (field.dataType == 'json') { | ||
| 295 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘JSON类型’`); | ||
| 296 | return; | ||
| 297 | } | ||
| 298 | if (field.dataType == 'bit') { | ||
| 299 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘布尔类型’`); | ||
| 300 | return; | ||
| 301 | } | ||
| 302 | } else { | ||
| 303 | if (!field.aggWay && isSumModel) { | ||
| 304 | ElMessage.error(`聚合模型的非主键字段必须设置聚合方式`); | ||
| 305 | return; | ||
| 306 | } | ||
| 307 | } | ||
| 308 | if (field.isEdit) { | ||
| 309 | if (checkDefault[field.dataType]) { | ||
| 310 | if (!field.fieldLength) { } | ||
| 311 | if (!checkDefault[field.dataType]({ row: field })) { | ||
| 312 | return; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | } | ||
| 316 | enNames.push(field.enName); | ||
| 317 | chNames.push(field.chName); | ||
| 318 | field.fieldStandardGuid = route.query.metaStandard; | ||
| 319 | } | ||
| 320 | if (!hasPrimary) { | ||
| 321 | ElMessage.error(`字段至少有一个主键字段!`); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | let addInfo = Object.assign({}, tableCreateInfo.value.tableData[0], { | ||
| 325 | enName: tableCreateInfo.value.inputNameValue, | ||
| 326 | tableCreateType: tableCreateInfo.value.tableCreateType, | ||
| 327 | saveFlag: 1, | ||
| 328 | dbType: dbType.value, | ||
| 329 | dataState: 1, | ||
| 330 | partitionAttribute: !Object.keys(tableCreateInfo.value.partitionAttribute).length ? null : Object.assign({}, tableCreateInfo.value.partitionAttribute, { | ||
| 331 | dynamicPartitionHistory: tableCreateInfo.value.partitionAttribute ? "Y" : 'N' | ||
| 332 | }), | ||
| 333 | subjectFieldAddDTOS: tableCreateInfo.value.tableFields.map((field, i) => { | ||
| 334 | return Object.assign({}, field, { orderNum: i + 1 }); | ||
| 335 | }), | ||
| 336 | }) | ||
| 337 | if (!tableCreateInfo.value.guid) { //添加 | ||
| 338 | fullscreenLoading.value = true; | ||
| 339 | saveSubjectTable(addInfo).then((res: any) => { | ||
| 340 | fullscreenLoading.value = false; | ||
| 341 | if (res.code == proxy.$passCode) { | ||
| 342 | ElMessage.success('新建表提交成功!'); | ||
| 343 | router.push({ | ||
| 344 | name: 'metadataStandardQuery' | ||
| 345 | }); | ||
| 346 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 347 | } else { | ||
| 348 | ElMessage.error(res.msg); | ||
| 349 | } | ||
| 350 | }).catch((err) => { | ||
| 351 | ElMessage.error(err); | ||
| 352 | fullscreenLoading.value = false; | ||
| 353 | }); | ||
| 354 | } | ||
| 355 | }; | ||
| 356 | |||
| 357 | //数据库选择改变,对应的表名称是否需要变化。需要根据此属性带出表名前缀,以及是否是doris数据库。 | ||
| 358 | const selectDatabaseChange = (val) => { | ||
| 359 | let oldDbType = dbType.value; | ||
| 360 | let d = databaseList.value.find(d => d.guid === val); | ||
| 361 | if (d) { | ||
| 362 | dbType.value = d.databaseType; | ||
| 363 | tableCreateInfo.value.tableData[0].dataSourceGuid = d.guid; | ||
| 364 | tableCreateInfo.value.tableData[0].dataServerName = d.databaseNameEn; | ||
| 365 | } else { | ||
| 366 | dbType.value = ""; | ||
| 367 | tableCreateInfo.value.tableData[0].dataSourceGuid = ''; | ||
| 368 | tableCreateInfo.value.tableData[0].dataServerName = ''; | ||
| 369 | } | ||
| 370 | if (oldDbType != dbType.value) { | ||
| 371 | tableCreateInfo.value.tableFields.forEach((tableField: any) => { | ||
| 372 | if (tableField['dataType'] === "datetime") { | ||
| 373 | tableField.defaultValue = "" | ||
| 374 | } | ||
| 375 | }) | ||
| 376 | } | ||
| 377 | }; | ||
| 378 | |||
| 379 | /** 添加字段标准 */ | ||
| 380 | const addField = () => { | ||
| 381 | let len = tableCreateInfo.value.tableFields.length; | ||
| 382 | tableCreateInfo.value.tableFields.push({ | ||
| 383 | orderNum: len + 1, | ||
| 384 | isDim: "N", | ||
| 385 | isPrimary: "N", | ||
| 386 | notNull: "N", | ||
| 387 | isEdit: true | ||
| 388 | }); | ||
| 389 | //设置选中表格当前新增行。 | ||
| 390 | fieldStandardTableRef.value?.setCurrentRow( | ||
| 391 | tableCreateInfo.value.tableFields[tableCreateInfo.value.tableFields.length - 1] | ||
| 392 | ); | ||
| 393 | nextTick(() => { | ||
| 394 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 395 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 396 | let rect = domScroll.getBoundingClientRect(); | ||
| 397 | let maxNum = len + 1; | ||
| 398 | if (maxNum * 36 > rect.height + domScroll.scrollTop) { | ||
| 399 | fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2) | ||
| 400 | } | ||
| 401 | }) | ||
| 402 | }; | ||
| 403 | |||
| 404 | /** 勾选字段标准选中变化。 */ | ||
| 405 | const selectionFieldsChange = (val) => { | ||
| 406 | selectTableFieldRows.value = val; | ||
| 407 | }; | ||
| 408 | |||
| 409 | /** | ||
| 410 | * 上移规则: | ||
| 411 | * 勾选多个时先从最上面开始逐个上移一行,若已经移到最上面一行,则不处理。 | ||
| 412 | */ | ||
| 413 | const moveUp = () => { | ||
| 414 | let selectRows = fieldStandardTableRef.value?.getSelectionRows(); | ||
| 415 | if (!selectRows.length) { | ||
| 416 | ElMessage.error('请先选择需要勾选的数据进行上移'); | ||
| 417 | return; | ||
| 418 | } | ||
| 419 | let data = tableCreateInfo.value.tableFields; | ||
| 420 | let selectRowIndexs: number[] = []; | ||
| 421 | let minNum: number = 0; | ||
| 422 | selectRows.forEach((row, i) => { | ||
| 423 | let orderNum = data.findIndex(d => d === row) + 1; | ||
| 424 | if (orderNum == 1) { | ||
| 425 | selectRowIndexs.push(orderNum); | ||
| 426 | minNum = orderNum; | ||
| 427 | return; | ||
| 428 | } | ||
| 429 | if (selectRowIndexs.includes(orderNum - 1)) { | ||
| 430 | //下一行也是选中的,则不做转换。 | ||
| 431 | return; | ||
| 432 | } | ||
| 433 | let topNum = orderNum - 1; | ||
| 434 | if (i === 0) { | ||
| 435 | minNum = topNum; | ||
| 436 | } | ||
| 437 | row.orderNum = topNum; | ||
| 438 | let changeRow = data[topNum - 1]; | ||
| 439 | changeRow.orderNum = orderNum; | ||
| 440 | selectRowIndexs.push(topNum); | ||
| 441 | data[topNum] = changeRow; | ||
| 442 | data[topNum - 1] = row; | ||
| 443 | }); | ||
| 444 | nextTick().then(() => { | ||
| 445 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 446 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 447 | if ((minNum * 36 - 36 - 2) < domScroll.scrollTop) { | ||
| 448 | fieldStandardTableRef.value?.setScrollTop((domScroll.scrollTop - 36 - 2) < 0 ? 0 : (domScroll.scrollTop - 36 - 2)) | ||
| 449 | } | ||
| 450 | }); | ||
| 451 | } | ||
| 452 | |||
| 453 | /** | ||
| 454 | * 下移规则: | ||
| 455 | * 勾选多个时先从最下面开始逐个下移一行,若已经移到最下面一行,则不处理。 | ||
| 456 | */ | ||
| 457 | const moveDown = () => { | ||
| 458 | let selectRows = fieldStandardTableRef.value?.getSelectionRows(); | ||
| 459 | if (!selectRows.length) { | ||
| 460 | ElMessage.error('请先选择需要勾选的数据进行下移'); | ||
| 461 | return; | ||
| 462 | } | ||
| 463 | let data = tableCreateInfo.value.tableFields; | ||
| 464 | let selectRowIndexs: number[] = []; | ||
| 465 | let maxNum: number = 0; | ||
| 466 | selectRows.slice(0).reverse().forEach((row, i) => { | ||
| 467 | let orderNum = data.findIndex(d => d === row) + 1; | ||
| 468 | if (orderNum === data.length) { | ||
| 469 | maxNum = orderNum; | ||
| 470 | selectRowIndexs.push(orderNum); | ||
| 471 | return; | ||
| 472 | } | ||
| 473 | if (selectRowIndexs.includes(orderNum + 1)) { | ||
| 474 | //下一行也是选中的,则不做转换。 | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | let bottomNum = orderNum + 1; | ||
| 478 | row.orderNum = bottomNum; | ||
| 479 | if (i === 0) { | ||
| 480 | maxNum = bottomNum; | ||
| 481 | } | ||
| 482 | let changeRow = data[bottomNum - 1]; | ||
| 483 | changeRow.orderNum = orderNum; | ||
| 484 | selectRowIndexs.push(bottomNum); | ||
| 485 | data[orderNum - 1] = changeRow; | ||
| 486 | data[bottomNum - 1] = row; | ||
| 487 | }); | ||
| 488 | nextTick(() => { | ||
| 489 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 490 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 491 | let rect = domScroll.getBoundingClientRect(); | ||
| 492 | if (maxNum * 36 > rect.height + domScroll.scrollTop) { | ||
| 493 | fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2) | ||
| 494 | } | ||
| 495 | }) | ||
| 496 | } | ||
| 497 | |||
| 498 | |||
| 499 | /** 批量删除字段标准 */ | ||
| 500 | const delFeilds = () => { | ||
| 501 | if (selectTableFieldRows.value.length == 0) { | ||
| 502 | ElMessage({ | ||
| 503 | type: "info", | ||
| 504 | message: "请选择需要删除的字段", | ||
| 505 | }); | ||
| 506 | return; | ||
| 507 | } | ||
| 508 | if (tableCreateInfo.value.isCreate) { | ||
| 509 | if (selectTableFieldRows.value.find((row: any) => row.isPrimary === 'Y')) { | ||
| 510 | ElMessage.error('已建表不能删除主键字段'); | ||
| 511 | return; | ||
| 512 | } | ||
| 513 | } | ||
| 514 | let hasCreateField = selectTableFieldRows.value.some((row: any) => row.isCreate === 'Y'); | ||
| 515 | ElMessageBox.confirm(hasCreateField && hasSubjectData.value ? '已选择的字段中含有已创建的表字段且有数据,此操作将永久删除,是否继续?' : "此操作将永久删除,是否继续?", "提示", { | ||
| 516 | confirmButtonText: "确定", | ||
| 517 | cancelButtonText: "取消", | ||
| 518 | type: "warning", | ||
| 519 | }) | ||
| 520 | .then(() => { | ||
| 521 | //此删除是直接从库里删除,还是点击保存后再删除呢??如果是入库删除,后,调用接口获取数据。 | ||
| 522 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 523 | let tableData = tableCreateInfo.value.tableData[0]; | ||
| 524 | selectTableFieldRows.value.forEach((r: any) => { | ||
| 525 | let index = tableFields.findIndex((t: any) => t.orderNum === r.orderNum); | ||
| 526 | if (index !== -1) { | ||
| 527 | let row = tableFields[index]; | ||
| 528 | tableFields.splice(index, 1); | ||
| 529 | if (tableData.codeName == row.enName) { | ||
| 530 | tableData.codeName = ""; | ||
| 531 | } | ||
| 532 | if (tableData.codeColumn == row.enName) { | ||
| 533 | tableData.codeColumn = ""; | ||
| 534 | } | ||
| 535 | } | ||
| 536 | }); | ||
| 537 | fieldStandardTableRef.value?.clearSelection(); | ||
| 538 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 539 | field.orderNum = i + 1; | ||
| 540 | }); | ||
| 541 | ElMessage({ | ||
| 542 | type: "success", | ||
| 543 | message: "删除成功", | ||
| 544 | }); | ||
| 545 | }) | ||
| 546 | .catch(() => { | ||
| 547 | ElMessage({ | ||
| 548 | type: "info", | ||
| 549 | message: "已取消删除", | ||
| 550 | }); | ||
| 551 | }); | ||
| 552 | }; | ||
| 553 | |||
| 554 | //点击编辑按钮 | ||
| 555 | const handleFieldClickEdit = (scope) => { | ||
| 556 | scope.row['isEdit'] = true; | ||
| 557 | }; | ||
| 558 | |||
| 559 | //点击保存按钮 | ||
| 560 | const handleFieldClickSave = (scope) => { | ||
| 561 | if (!scope.row.fieldStandardCode) { | ||
| 562 | ElMessage({ | ||
| 563 | type: "error", | ||
| 564 | message: "该主题域开启了字段标准,当前行字段标准不能为空!", | ||
| 565 | }); | ||
| 566 | return; | ||
| 567 | } | ||
| 568 | if (!scope.row.enName) { | ||
| 569 | ElMessage({ | ||
| 570 | type: "error", | ||
| 571 | message: "字段英文名不能为空!", | ||
| 572 | }); | ||
| 573 | return; | ||
| 574 | } | ||
| 575 | scope.row['isEdit'] = false; | ||
| 576 | }; | ||
| 577 | |||
| 578 | const handleFieldDelete = (scope) => { | ||
| 579 | ElMessageBox.confirm(scope.row['isCreate'] === 'Y' && hasSubjectData.value ? '该字段已被创建且表中有数据,此操作将永久删除,是否继续?' : "此操作将永久删除,是否继续?", "提示", { | ||
| 580 | confirmButtonText: "确定", | ||
| 581 | cancelButtonText: "取消", | ||
| 582 | type: "warning", | ||
| 583 | }) | ||
| 584 | .then(() => { | ||
| 585 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 586 | tableFields.splice(scope.$index, 1); | ||
| 587 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 588 | field.orderNum = i + 1; | ||
| 589 | }); | ||
| 590 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 591 | field.orderNum = i + 1; | ||
| 592 | }); | ||
| 593 | let row = scope.row; | ||
| 594 | let tableData = tableCreateInfo.value.tableData[0]; | ||
| 595 | if (tableData.codeName == row.enName) { | ||
| 596 | tableData.codeName = ""; | ||
| 597 | } | ||
| 598 | if (tableData.codeColumn == row.enName) { | ||
| 599 | tableData.codeColumn = ""; | ||
| 600 | } | ||
| 601 | ElMessage({ | ||
| 602 | type: "success", | ||
| 603 | message: "删除成功", | ||
| 604 | }); | ||
| 605 | }) | ||
| 606 | .catch(() => { | ||
| 607 | ElMessage({ | ||
| 608 | type: "info", | ||
| 609 | message: "已取消删除", | ||
| 610 | }); | ||
| 611 | }); | ||
| 612 | } | ||
| 613 | |||
| 614 | const dataTypeChange = (val, scope) => { | ||
| 615 | scope.row['defaultValue'] = '' | ||
| 616 | scope.row['fieldLength'] = undefined | ||
| 617 | scope.row['fieldPrecision'] = undefined | ||
| 618 | } | ||
| 619 | |||
| 620 | /** 扩展属性弹出对话框 */ | ||
| 621 | const expandPropertyDialogRef = ref(); | ||
| 622 | |||
| 623 | /** 扩展属性弹出对话框 */ | ||
| 624 | const handleClickExpand = () => { | ||
| 625 | expandPropertyDialogRef.value?.handleClickExpand(); | ||
| 626 | } | ||
| 627 | |||
| 628 | const expandDialogValueChange = (val) => { | ||
| 629 | tableCreateInfo.value.partitionAttribute = val; | ||
| 630 | expandProperties.value = val; | ||
| 631 | } | ||
| 632 | |||
| 633 | const tableSelectFields = computed(() => { | ||
| 634 | return tableCreateInfo.value.tableFields.filter(t => !!t.enName); | ||
| 635 | }) | ||
| 636 | |||
| 637 | </script> | ||
| 638 | |||
| 639 | <template> | ||
| 640 | <div class="table_tool_wrap" v-loading="fullscreenLoading"> | ||
| 641 | <div class="tools_btns"> | ||
| 642 | <!-- <el-button type="primary" :disabled="isLook" @click="saveDraftTable" v-preReClick>保存为草稿</el-button> --> | ||
| 643 | <el-button type="primary" :disabled="isLook" @click="saveTable" v-preReClick>提交</el-button> | ||
| 644 | </div> | ||
| 645 | <el-table ref="tableRef" :data="tableCreateInfo.tableData" v-loading="tableCreateInfoLoading" | ||
| 646 | :highlight-current-row="true" stripe border height="100%" tooltip-effect="light" row-key="guid" :style="{ | ||
| 647 | width: '100%', | ||
| 648 | height: 'auto', | ||
| 649 | display: 'inline-block', | ||
| 650 | }"> | ||
| 651 | <el-table-column prop="dataSourceGuid" label="数据源" width="200px" align="left" show-overflow-tooltip> | ||
| 652 | <template #header> | ||
| 653 | <span>数据源</span> | ||
| 654 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 655 | </template> | ||
| 656 | <template #default="scope"> | ||
| 657 | <el-select v-if="!isLook" v-model="scope.row['dataSourceGuid']" placeholder="请选择" | ||
| 658 | :disabled="tableCreateInfo.isCreate" @change="(val) => selectDatabaseChange(val)" clearable filterable> | ||
| 659 | <el-option v-for="opt in databaseList" :key="opt['guid']" :label="opt['databaseNameZh']" | ||
| 660 | :value="opt['guid']" /> | ||
| 661 | </el-select> | ||
| 662 | <span v-else>{{ scope.row["dataServerChName"] }}</span> | ||
| 663 | </template> | ||
| 664 | </el-table-column> | ||
| 665 | <el-table-column prop="enName" label="数据库表" width="200px" align="left" show-overflow-tooltip> | ||
| 666 | <template #header> | ||
| 667 | <span>数据库表</span> | ||
| 668 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 669 | </template> | ||
| 670 | <template #default="scope"> | ||
| 671 | <template v-if="!isLook"> | ||
| 672 | <div class="prefix-or-suffix-cell"> | ||
| 673 | <el-input :disabled="tableCreateInfo.isCreate" v-model.trim="tableCreateInfo.inputNameValue" | ||
| 674 | :maxlength="50" placeholder="必填" /> | ||
| 675 | </div> | ||
| 676 | </template> | ||
| 677 | <span v-else>{{ scope.row["enName"] }}</span> | ||
| 678 | </template> | ||
| 679 | </el-table-column> | ||
| 680 | <el-table-column prop="chName" label="主题表名称" width="200px" align="left" show-overflow-tooltip> | ||
| 681 | <template #header> | ||
| 682 | <span>主题表名称</span> | ||
| 683 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 684 | </template> | ||
| 685 | <template #default="scope"> | ||
| 686 | <el-input v-if="!isLook" v-model.trim="scope.row['chName']" placeholder="必填" :maxlength="50" /> | ||
| 687 | <span v-else>{{ scope.row["chName"] }}</span> | ||
| 688 | </template> | ||
| 689 | </el-table-column> | ||
| 690 | <el-table-column prop="subjectDomain" label="主题域" width="180px" align="left" show-overflow-tooltip> | ||
| 691 | <template #default="scope"> | ||
| 692 | <el-input v-if="!isLook" disabled v-model.trim="scope.row['subjectDomain']" /> | ||
| 693 | <span v-else>{{ scope.row["subjectDomain"] }}</span> | ||
| 694 | </template> | ||
| 695 | </el-table-column> | ||
| 696 | <el-table-column prop="tableModel" label="表模型" :width="isLook ? '100px' : '150px'" align="left" | ||
| 697 | show-overflow-tooltip> | ||
| 698 | <template #default="scope"> | ||
| 699 | <el-select v-if="dbType == 'doris' && !isLook" v-model="scope.row['tableModel']" placeholder="请选择" | ||
| 700 | :disabled="tableCreateInfo.isCreate"> | ||
| 701 | <el-option v-for="opt in tableModels" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 702 | </el-select> | ||
| 703 | <span v-else-if="dbType == 'doris'">{{tableModels.find(t => t.value === scope.row["tableModel"])?.label || | ||
| 704 | '-' | ||
| 705 | }}</span> | ||
| 706 | <span v-else>--</span> | ||
| 707 | </template> | ||
| 708 | </el-table-column> | ||
| 709 | <el-table-column prop="dimType" label="维表类型" :width="isLook ? '100px' : '150px'" align="left" | ||
| 710 | show-overflow-tooltip> | ||
| 711 | <template #default="scope"> | ||
| 712 | <el-select v-if="!isLook" v-model="scope.row['dimType']" placeholder="请选择"> | ||
| 713 | <el-option v-for="opt in dimTypeList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 714 | </el-select> | ||
| 715 | <span v-else>{{dimTypeList.find(t => t.value === scope.row["dimType"])?.label || '-'}}</span> | ||
| 716 | </template> | ||
| 717 | </el-table-column> | ||
| 718 | <el-table-column prop="codeColumn" label="编码字段" :width="isLook ? '100px' : '150px'" align="left" | ||
| 719 | show-overflow-tooltip> | ||
| 720 | <template #header> | ||
| 721 | <div class="header_title"> | ||
| 722 | <span>编码字段</span> | ||
| 723 | <span v-if="!isLook" style="color:red;margin-left: 2px;margin-right: 8px;">*</span> | ||
| 724 | <el-tooltip placement="top" effect="light" popper-class="table_tooltip"> | ||
| 725 | <template #content> | ||
| 726 | <div style="max-width: 236px;"> | ||
| 727 | 下拉列表来自于该表的字段。 | ||
| 728 | </div> | ||
| 729 | </template> | ||
| 730 | <el-icon> | ||
| 731 | <QuestionFilled /> | ||
| 732 | </el-icon> | ||
| 733 | </el-tooltip> | ||
| 734 | </div> | ||
| 735 | </template> | ||
| 736 | <template #default="scope"> | ||
| 737 | <el-select v-if="!isLook" v-model="scope.row['codeColumn']" placeholder="请选择"> | ||
| 738 | <el-option v-for="opt in tableSelectFields" :key="opt['enName']" :label="opt['chName']" | ||
| 739 | :value="opt['enName']" /> | ||
| 740 | </el-select> | ||
| 741 | <span v-else>{{ scope.row["codeColumn"] || '-' }}</span> | ||
| 742 | </template> | ||
| 743 | </el-table-column> | ||
| 744 | <el-table-column prop="codeName" label="编码名称" :width="isLook ? '100px' : '150px'" align="left" | ||
| 745 | show-overflow-tooltip> | ||
| 746 | <template #header> | ||
| 747 | <div class="header_title"> | ||
| 748 | <span>编码名称</span> | ||
| 749 | <span v-if="!isLook" style="color:red;margin-left: 2px;margin-right: 8px;">*</span> | ||
| 750 | <el-tooltip placement="top" effect="light" popper-class="table_tooltip"> | ||
| 751 | <template #content> | ||
| 752 | <div style="max-width: 236px;"> | ||
| 753 | 下拉列表来自于该表的字段。 | ||
| 754 | </div> | ||
| 755 | </template> | ||
| 756 | <el-icon> | ||
| 757 | <QuestionFilled /> | ||
| 758 | </el-icon> | ||
| 759 | </el-tooltip> | ||
| 760 | </div> | ||
| 761 | </template> | ||
| 762 | <template #default="scope"> | ||
| 763 | <el-select v-if="!isLook" v-model="scope.row['codeName']" placeholder="请选择"> | ||
| 764 | <el-option v-for="opt in tableSelectFields" :key="opt['enName']" :label="opt['chName']" | ||
| 765 | :value="opt['enName']" /> | ||
| 766 | </el-select> | ||
| 767 | <span v-else>{{ scope.row["codeName"] || '-' }}</span> | ||
| 768 | </template> | ||
| 769 | </el-table-column> | ||
| 770 | <el-table-column prop="syncPolicy" label="同步策略" :width="isLook ? '100px' : '150px'" align="left" | ||
| 771 | show-overflow-tooltip> | ||
| 772 | <template #default="scope"> | ||
| 773 | <el-select v-if="!isLook" v-model="scope.row['syncPolicy']" placeholder="请选择"> | ||
| 774 | <el-option v-for="opt in syncPolicys" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 775 | </el-select> | ||
| 776 | <span v-else>{{syncPolicys.find(s => s.value === scope.row["syncPolicy"])?.label || '-'}}</span> | ||
| 777 | </template> | ||
| 778 | </el-table-column> | ||
| 779 | <el-table-column prop="characterSet" label="字符集" :width="isLook ? '100px' : '150px'" align="left" | ||
| 780 | show-overflow-tooltip> | ||
| 781 | <template #default="scope"> | ||
| 782 | <el-select v-if="!isLook" v-model="scope.row['characterSet']" placeholder="请选择"> | ||
| 783 | <el-option v-for="opt in characterList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 784 | </el-select> | ||
| 785 | <span v-else>{{characterList.find(c => c.value === scope.row["characterSet"])?.label || '-' | ||
| 786 | }}</span> | ||
| 787 | </template> | ||
| 788 | </el-table-column> | ||
| 789 | <el-table-column prop="description" label="描述" width="220px" align="left" show-overflow-tooltip> | ||
| 790 | <template #default="scope"> | ||
| 791 | <el-input v-if="!isLook" v-model.trim="scope.row['description']" /> | ||
| 792 | <span v-else>{{ scope.row["description"] || '-' }}</span> | ||
| 793 | </template> | ||
| 794 | </el-table-column> | ||
| 795 | <el-table-column label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip> | ||
| 796 | <template #default="scope"> | ||
| 797 | <span class="text_btn" @click="handleClickExpand()" v-preReClick>扩展属性</span> | ||
| 798 | </template> | ||
| 799 | </el-table-column> | ||
| 800 | </el-table> | ||
| 801 | <div class="tools_btns"> | ||
| 802 | <el-button type="primary" :disabled="isLook" @click="addField">新增</el-button> | ||
| 803 | <el-button @click="moveUp" :disabled="isLook">上移</el-button> | ||
| 804 | <el-button @click="moveDown" :disabled="isLook">下移</el-button> | ||
| 805 | <el-button @click="delFeilds" :disabled="isLook">批量删除</el-button> | ||
| 806 | </div> | ||
| 807 | <div class="table_panel"> | ||
| 808 | <el-table ref="fieldStandardTableRef" :data="tableCreateInfo.tableFields" v-loading="tableFieldsLoading" | ||
| 809 | :highlight-current-row="true" stripe border height="100%" row-key="guid" | ||
| 810 | @selection-change="selectionFieldsChange" tooltip-effect="light" :style="{ | ||
| 811 | width: '100%', | ||
| 812 | 'max-height': 'calc(100% - 16px)', | ||
| 813 | display: 'inline-block', | ||
| 814 | }"> | ||
| 815 | <el-table-column type="selection" v-if="!isLook" :width="32" align="center" /> | ||
| 816 | <el-table-column label="排序" type="index" width="56px" align="center" show-overflow-tooltip> | ||
| 817 | </el-table-column> | ||
| 818 | <el-table-column prop="chName" label="字段中文名称" width="150px" align="left" show-overflow-tooltip> | ||
| 819 | <template #default="scope"> | ||
| 820 | <el-input v-if="scope.row['isEdit']" placeholder="请输入" v-model.trim="scope.row['chName']" /> | ||
| 821 | <span v-else>{{ scope.row["chName"] || '-' }}</span> | ||
| 822 | </template> | ||
| 823 | </el-table-column> | ||
| 824 | <el-table-column prop="enName" label="字段英文名" width="150px" align="left" show-overflow-tooltip> | ||
| 825 | <template #default="scope"> | ||
| 826 | <el-input v-if="scope.row['isEdit'] && !(scope.row['guid'] && tableCreateInfo.isCreate)" | ||
| 827 | v-model.trim="scope.row['enName']" placeholder="必填" | ||
| 828 | @input="inputLengthKeyUp(/[^a-zA-Z0-9_]/g, scope, 'enName')" /> | ||
| 829 | <span v-else>{{ scope.row["enName"] || '-' }}</span> | ||
| 830 | </template> | ||
| 831 | </el-table-column> | ||
| 832 | <el-table-column prop="dataType" label="字段类型" width="120px" align="left" show-overflow-tooltip> | ||
| 833 | <template #default="scope"> | ||
| 834 | <el-select v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y')" | ||
| 835 | v-model="scope.row['dataType']" placeholder="请选择" @change="(val) => dataTypeChange(val, scope)"> | ||
| 836 | <el-option v-for="opt in fieldTypes" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 837 | </el-select> | ||
| 838 | <span v-else>{{fieldTypes.find(f => f.value === scope.row["dataType"])?.label || '-'}}</span> | ||
| 839 | </template> | ||
| 840 | </el-table-column> | ||
| 841 | <el-table-column prop="fieldLength" label="长度" width="115px" align="left" show-overflow-tooltip> | ||
| 842 | <template #default="scope"> | ||
| 843 | <el-input | ||
| 844 | v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y') && (scope.row['dataType'] == 'varchar' || scope.row['dataType'] == 'decimal' || scope.row['dataType'] == 'char')" | ||
| 845 | v-model.trim="scope.row['fieldLength']" placeholder="必填" | ||
| 846 | @input="inputLengthKeyUp(/\D/g, scope, 'fieldLength', 2000, 1)" /> | ||
| 847 | <span v-else>{{ scope.row["fieldLength"] == null ? '-' : scope.row["fieldLength"] }}</span> | ||
| 848 | </template> | ||
| 849 | </el-table-column> | ||
| 850 | <el-table-column prop="fieldPrecision" label="精度" width="115px" align="left" show-overflow-tooltip> | ||
| 851 | <template #default="scope"> | ||
| 852 | <el-input | ||
| 853 | v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y') && scope.row['dataType'] == 'decimal'" | ||
| 854 | v-model.trim="scope.row['fieldPrecision']" placeholder="必填" | ||
| 855 | @input="inputLengthKeyUp(/\D/g, scope, 'fieldPrecision', 30, 1)" /> | ||
| 856 | <span v-else>{{ scope.row["fieldPrecision"] == null ? '-' : scope.row["fieldPrecision"] }}</span> | ||
| 857 | </template> | ||
| 858 | </el-table-column> | ||
| 859 | <el-table-column prop="isPrimary" label="是否主键" width="90px" align="left" show-overflow-tooltip> | ||
| 860 | <template #default="scope"> | ||
| 861 | <el-select v-if="scope.row['isEdit'] && !tableCreateInfo.isCreate" v-model="scope.row['isPrimary']" | ||
| 862 | placeholder="请选择"> | ||
| 863 | <el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 864 | </el-select> | ||
| 865 | <span v-else>{{ scope.row["isPrimary"] || '-' }}</span> | ||
| 866 | </template> | ||
| 867 | </el-table-column> | ||
| 868 | <el-table-column v-if="tableCreateInfo.tableData[0].tableModel == 2" prop="aggWay" label="聚合方式" width="120px" | ||
| 869 | align="left" show-overflow-tooltip> | ||
| 870 | <template #default="scope"> | ||
| 871 | <el-select v-if="scope.row['isEdit']" v-model="scope.row['aggWay']" placeholder="请选择"> | ||
| 872 | <el-option v-for="opt in aggMethodList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 873 | </el-select> | ||
| 874 | <span v-else>{{ scope.row["aggWay"] || '-' }}</span> | ||
| 875 | </template> | ||
| 876 | </el-table-column> | ||
| 877 | <el-table-column prop="notNull" label="是否必填" width="90px" align="left" show-overflow-tooltip> | ||
| 878 | <template #default="scope"> | ||
| 879 | <el-select v-if="scope.row['isEdit'] && !(scope.row.isCreate == 'Y' && scope.row['notNull'] == 'N')" | ||
| 880 | v-model="scope.row['notNull']" placeholder="请选择"> | ||
| 881 | <el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 882 | </el-select> | ||
| 883 | <span v-else>{{ scope.row["notNull"] || '-' }}</span> | ||
| 884 | </template> | ||
| 885 | </el-table-column> | ||
| 886 | <el-table-column prop="defaultValue" label="默认值" width="205px" align="left" show-overflow-tooltip> | ||
| 887 | <template #default="scope"> | ||
| 888 | <tableDefaultValue :scope="scope" :dbType="dbType" | ||
| 889 | :readonly="dbType == 'doris' && scope.row.isCreate == 'Y'"></tableDefaultValue> | ||
| 890 | </template> | ||
| 891 | </el-table-column> | ||
| 892 | <el-table-column v-if="!isLook" label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip> | ||
| 893 | <template #default="scope"> | ||
| 894 | <template v-if="!(tableCreateInfo.isCreate && scope.row['isPrimary'] === 'Y')"> | ||
| 895 | <span class="text_btn" v-if="!scope.row['isEdit']" @click="handleFieldClickEdit(scope)" | ||
| 896 | v-preReClick>编辑</span> | ||
| 897 | <span class="text_btn" v-else @click="handleFieldClickSave(scope)" v-preReClick>保存</span> | ||
| 898 | <el-divider direction="vertical" /> | ||
| 899 | <span class="text_btn" @click="handleFieldDelete(scope)">删除</span> | ||
| 900 | </template> | ||
| 901 | <span v-else>--</span> | ||
| 902 | </template> | ||
| 903 | </el-table-column> | ||
| 904 | </el-table> | ||
| 905 | </div> | ||
| 906 | <ContentWrap title="流程审批" description="" :isExpand="flowExpand" :expand-swicth="true" class="mb16" | ||
| 907 | @expand="(v) => flowExpand = v"> | ||
| 908 | <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :definitionId="''"> | ||
| 909 | </ApprovalProcess> | ||
| 910 | </ContentWrap> | ||
| 911 | <expandPropertyDialog ref="expandPropertyDialogRef" :is-look="isLook" :partitionAttribute="expandProperties" | ||
| 912 | :table-create-info="tableCreateInfo" @expandValueChange="expandDialogValueChange" /> | ||
| 913 | </div> | ||
| 914 | </template> | ||
| 915 | |||
| 916 | <style lang="scss" scoped> | ||
| 917 | .table_tool_wrap { | ||
| 918 | width: 100%; | ||
| 919 | height: 100%; | ||
| 920 | padding: 0 16px; | ||
| 921 | overflow: hidden auto; | ||
| 922 | |||
| 923 | .tools_btns { | ||
| 924 | padding: 8px 0; | ||
| 925 | } | ||
| 926 | |||
| 927 | :deep(.el-table) { | ||
| 928 | .cell { | ||
| 929 | |||
| 930 | .prefix-or-suffix-cell { | ||
| 931 | display: inline-flex; | ||
| 932 | align-items: center; | ||
| 933 | } | ||
| 934 | } | ||
| 935 | } | ||
| 936 | |||
| 937 | .table_panel { | ||
| 938 | height: 268px; | ||
| 939 | |||
| 940 | :deep(.el-table) { | ||
| 941 | & td.el-table__cell { | ||
| 942 | padding: 2px 0; | ||
| 943 | height: 36px; | ||
| 944 | } | ||
| 945 | } | ||
| 946 | } | ||
| 947 | } | ||
| 948 | |||
| 949 | :deep(.el-dialog) { | ||
| 950 | .dialog-form-inline { | ||
| 951 | .checkbox_input { | ||
| 952 | display: flex; | ||
| 953 | flex-direction: column; | ||
| 954 | |||
| 955 | .input_panel { | ||
| 956 | margin: 0; | ||
| 957 | } | ||
| 958 | } | ||
| 959 | |||
| 960 | .select_group { | ||
| 961 | .el-form-item__content>.el-input { | ||
| 962 | margin-top: 21px; | ||
| 963 | } | ||
| 964 | } | ||
| 965 | |||
| 966 | .radio_panel { | ||
| 967 | .panel_content { | ||
| 968 | display: none; | ||
| 969 | } | ||
| 970 | } | ||
| 971 | } | ||
| 972 | } | ||
| 973 | |||
| 974 | :deep(.batchDialog) { | ||
| 975 | .el-tree-node__content { | ||
| 976 | padding-left: 8px !important; | ||
| 977 | |||
| 978 | .el-icon { | ||
| 979 | display: none; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | } | ||
| 983 | |||
| 984 | .header_title { | ||
| 985 | margin-left: 8px; | ||
| 986 | display: flex; | ||
| 987 | align-items: center; | ||
| 988 | |||
| 989 | .el-icon { | ||
| 990 | color: #b2b2b2; | ||
| 991 | width: 16px; | ||
| 992 | height: 16px; | ||
| 993 | } | ||
| 994 | } | ||
| 995 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -26,8 +26,8 @@ function encrypt(txt) { | ... | @@ -26,8 +26,8 @@ function encrypt(txt) { |
| 26 | } | 26 | } |
| 27 | const userStore = useUserStore() | 27 | const userStore = useUserStore() |
| 28 | const userInfoData = JSON.parse(localStorage.userData) | 28 | const userInfoData = JSON.parse(localStorage.userData) |
| 29 | // const url: any = 'https://scm.cs4pl.com/portraitBMap?fUrl=portraitMap'; | 29 | const url: any = 'https://scm-operation-test.csbr.cn/portraitBMap?fUrl=portraitMap&tUrl=portraitBMap'; |
| 30 | const url: any = 'http://localhost:8086/portraitBMap?fUrl=portraitMap'; | 30 | // const url: any = 'http://localhost:8086/portraitBMap?fUrl=portraitMap&tUrl=portraitBMap'; |
| 31 | 31 | ||
| 32 | const link = ref('') | 32 | const link = ref('') |
| 33 | const loading = ref(true); | 33 | const loading = ref(true); | ... | ... |
src/views/data_meta/standard-codetable.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: metadataStandardCodetable | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="metadataStandardCodetable"> | ||
| 6 | import { ref } from 'vue' | ||
| 7 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 8 | import { Search } from '@element-plus/icons-vue' | ||
| 9 | import Tree from '@/components/Tree/index.vue' | ||
| 10 | import Table from '@/components/Table/index.vue' | ||
| 11 | import Drawer from './components/drawer.vue' | ||
| 12 | import DictFileds from './components/dictFileds.vue' | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { download } from '@/utils/common' | ||
| 15 | import { getParamsList } from '@/api/modules/dataAsset' | ||
| 16 | import { getStandardCodeList, saveStandardCode, | ||
| 17 | updateStandardCode, getStandardCodeDetail, | ||
| 18 | deleteStandardCode, getStandardCodeStandard, exportStandardCodeData, | ||
| 19 | getStandardCodeDataList, getStandardCodeTree | ||
| 20 | } from '@/api/modules/dataMetaService' | ||
| 21 | import { | ||
| 22 | addDictionary, | ||
| 23 | deleteDictionary, | ||
| 24 | getDictionary, | ||
| 25 | updateDictionary, | ||
| 26 | getDictionaryTree, | ||
| 27 | getDictionaryDetail, | ||
| 28 | exportDictionary, | ||
| 29 | showDictionary, | ||
| 30 | getDataBaseList, | ||
| 31 | getCoderuleList, | ||
| 32 | saveDictionaryData, | ||
| 33 | getDictionaryFileds, | ||
| 34 | updateDictionaryState, | ||
| 35 | getDictionaryRuleData, | ||
| 36 | exportDictionaryFileds, | ||
| 37 | checkDeleteDictionary, | ||
| 38 | checkDeleteDictionaryScheme, | ||
| 39 | checkDictionaryData, | ||
| 40 | getNewDataTypeList | ||
| 41 | } from '@/api/modules/dataInventory'; | ||
| 42 | import router from '@/router' | ||
| 43 | import { TableColumnWidth } from '@/utils/enum'; | ||
| 44 | |||
| 45 | const { proxy } = getCurrentInstance() as any; | ||
| 46 | |||
| 47 | const cacheStore = useCatchStore() | ||
| 48 | // 禁用字段 | ||
| 49 | const forbidFields = [ | ||
| 50 | 'guid', | ||
| 51 | 'sharding_flag', | ||
| 52 | 'create_user_id', | ||
| 53 | 'create_user_name', | ||
| 54 | 'update_user_id', | ||
| 55 | 'update_user_name', | ||
| 56 | 'create_time', | ||
| 57 | 'update_time', | ||
| 58 | 'is_deleted' | ||
| 59 | ] | ||
| 60 | const showFiledsPage = ref(false) | ||
| 61 | const dictFiledsRef = ref() | ||
| 62 | const dataTypeList = ref([]) | ||
| 63 | const dataBaseList = ref([]) | ||
| 64 | const codeRuleList = ref([]) | ||
| 65 | const dictTreeRef = ref() | ||
| 66 | const dictType = ref(-1) | ||
| 67 | const dictGuid = ref('') | ||
| 68 | const expandedKey: any = ref([]) | ||
| 69 | const currentNodeKey = ref('') | ||
| 70 | const showLoading = ref(true) | ||
| 71 | const treeData = ref([]) | ||
| 72 | const treeInfo = ref({ | ||
| 73 | id: "data-pickup-tree", | ||
| 74 | filter: true, | ||
| 75 | queryValue: "", | ||
| 76 | queryPlaceholder: "请输入关键字搜索", | ||
| 77 | props: { | ||
| 78 | label: "label", | ||
| 79 | value: "value", | ||
| 80 | isLeaf: "isLeaf", | ||
| 81 | }, | ||
| 82 | // lazy: true, | ||
| 83 | nodeKey: 'value', | ||
| 84 | expandedKey: ['01'], | ||
| 85 | currentNodeKey: '01', | ||
| 86 | data: [], | ||
| 87 | expandOnNodeClick: false, | ||
| 88 | loading: false, | ||
| 89 | currentObj: {} | ||
| 90 | }); | ||
| 91 | |||
| 92 | const standardOptions = ref([]) | ||
| 93 | const publishingUnitCodeOptions = ref([]) | ||
| 94 | |||
| 95 | const tableSearchInput = ref('') | ||
| 96 | const currTableData: any = ref<Object>({}); | ||
| 97 | const page = ref({ | ||
| 98 | limit: 50, | ||
| 99 | curr: 1, | ||
| 100 | sizes: [ | ||
| 101 | { label: "10", value: 10 }, | ||
| 102 | { label: "50", value: 50 }, | ||
| 103 | { label: "100", value: 100 }, | ||
| 104 | { label: "150", value: 150 }, | ||
| 105 | { label: "200", value: 200 }, | ||
| 106 | ], | ||
| 107 | }); | ||
| 108 | const selectRowData = ref([]) | ||
| 109 | const selectedRowData = ref([]) | ||
| 110 | const tableInfo: any = ref({ | ||
| 111 | id: 'data-source-table', | ||
| 112 | multiple: true, | ||
| 113 | fixedSelection: true, | ||
| 114 | fields: [ | ||
| 115 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 116 | { label: '代码名称', field: 'codeName', width: 140 }, | ||
| 117 | // { label: '代码编码', field: 'code', width: 140 }, | ||
| 118 | { label: '标准号', field: 'standard', width: 140 }, | ||
| 119 | { label: '标准名称', field: 'standardName', width: 140 }, | ||
| 120 | // { label: '启用状态', field: 'bizState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 100, align: 'center' }, | ||
| 121 | { label: '启用状态', field: 'bizState', type: 'tag', width: 100, align: 'center',getName: (scope) => { | ||
| 122 | let status = scope.row.bizState; | ||
| 123 | return status == 'Y' ? '启用' : '停用'; | ||
| 124 | } }, | ||
| 125 | { label: '创建时间', field: 'createTime', width: TableColumnWidth } | ||
| 126 | ], | ||
| 127 | data: [], | ||
| 128 | page: { | ||
| 129 | type: "normal", | ||
| 130 | rows: 0, | ||
| 131 | ...page.value, | ||
| 132 | }, | ||
| 133 | actionInfo: { | ||
| 134 | label: "操作", | ||
| 135 | type: "btn", | ||
| 136 | width: 172, //不要刚好90.缩小浏览器会因为小数点的差距而换行, | ||
| 137 | fixed: 'right', | ||
| 138 | btns: [ | ||
| 139 | { label: '查看', value: 'detail'}, | ||
| 140 | { label: "编辑", value: "edit" }, | ||
| 141 | { label: '复制', value: 'copy' }, | ||
| 142 | { label: "删除", value: "delete" }, | ||
| 143 | ], | ||
| 144 | }, | ||
| 145 | loading: false | ||
| 146 | }) | ||
| 147 | |||
| 148 | const dictionaryType = ref(1) | ||
| 149 | const orginOptions = [ | ||
| 150 | { label: 'code', value: 'code' }, | ||
| 151 | { label: 'name', value: 'name' }, | ||
| 152 | ] | ||
| 153 | let codeOptions = ref([]) | ||
| 154 | const formItems: any = ref([ | ||
| 155 | { | ||
| 156 | label: '标准类型', | ||
| 157 | type: 'select', | ||
| 158 | placeholder: '请选择', | ||
| 159 | field: 'standardTypeCode', | ||
| 160 | default: '', | ||
| 161 | options: standardOptions, | ||
| 162 | clearable: true, | ||
| 163 | required: true | ||
| 164 | }, | ||
| 165 | { | ||
| 166 | label: '代码名称', | ||
| 167 | type: 'input', | ||
| 168 | placeholder: '请输入', | ||
| 169 | field: 'codeName', | ||
| 170 | default: '', | ||
| 171 | maxlength: 30, | ||
| 172 | clearable: true, | ||
| 173 | required: true | ||
| 174 | }, | ||
| 175 | { | ||
| 176 | label: '代码编码', | ||
| 177 | type: 'input', | ||
| 178 | placeholder: '请输入', | ||
| 179 | field: 'code', | ||
| 180 | default: '', | ||
| 181 | maxlength: 30, | ||
| 182 | clearable: true, | ||
| 183 | // required: true | ||
| 184 | }, | ||
| 185 | { | ||
| 186 | label: '标准号', | ||
| 187 | type: 'input', | ||
| 188 | placeholder: '请输入', | ||
| 189 | field: 'standard', | ||
| 190 | default: '', | ||
| 191 | maxlength: 50, | ||
| 192 | clearable: true, | ||
| 193 | required: true | ||
| 194 | }, | ||
| 195 | { | ||
| 196 | label: '标准名称', | ||
| 197 | type: 'input', | ||
| 198 | placeholder: '请输入', | ||
| 199 | field: 'standardName', | ||
| 200 | default: '', | ||
| 201 | maxlength: 30, | ||
| 202 | clearable: true, | ||
| 203 | required: true | ||
| 204 | }, | ||
| 205 | { | ||
| 206 | label: '发布单位', | ||
| 207 | type: 'select', | ||
| 208 | placeholder: '请选择', | ||
| 209 | field: 'publishingUnitCode', | ||
| 210 | default: '', | ||
| 211 | options: publishingUnitCodeOptions, | ||
| 212 | clearable: true, | ||
| 213 | required: true | ||
| 214 | }, | ||
| 215 | { | ||
| 216 | label: '排序', | ||
| 217 | type: 'input', | ||
| 218 | placeholder: '请输入', | ||
| 219 | field: 'orderNum', | ||
| 220 | default: '', | ||
| 221 | maxlength: 2, | ||
| 222 | clearable: true, | ||
| 223 | required: true | ||
| 224 | }, | ||
| 225 | { | ||
| 226 | label: '启用状态', | ||
| 227 | type: 'switch', | ||
| 228 | field: 'bizState', | ||
| 229 | default: 'Y', | ||
| 230 | activeValue: 'Y', | ||
| 231 | inactiveValue: 'N' | ||
| 232 | }, | ||
| 233 | { | ||
| 234 | label: '代码类型', | ||
| 235 | type: 'radio-panel', | ||
| 236 | placeholder: '请选择', | ||
| 237 | field: 'typeCode', | ||
| 238 | default: '1', | ||
| 239 | block: true, | ||
| 240 | options: [ | ||
| 241 | { label: '列表结构', value: '1' }, | ||
| 242 | { label: '层级结构', value: '2' } | ||
| 243 | ], | ||
| 244 | clearable: true, | ||
| 245 | required: true | ||
| 246 | }, | ||
| 247 | { | ||
| 248 | label: '编码字段', | ||
| 249 | type: 'select', | ||
| 250 | placeholder: '请选择', | ||
| 251 | field: 'codeFields', | ||
| 252 | default: [], | ||
| 253 | options: codeOptions, | ||
| 254 | clearable: true, | ||
| 255 | required: true, | ||
| 256 | multiple: true, | ||
| 257 | tagsTooltip: true, | ||
| 258 | collapse: true, | ||
| 259 | filterable: true, | ||
| 260 | visible: true | ||
| 261 | }, | ||
| 262 | { | ||
| 263 | label: '编码名称', | ||
| 264 | type: 'select', | ||
| 265 | placeholder: '请选择', | ||
| 266 | field: 'codeFieldName', | ||
| 267 | default: '', | ||
| 268 | options: codeOptions, | ||
| 269 | clearable: true, | ||
| 270 | required: true, | ||
| 271 | visible: true | ||
| 272 | }, | ||
| 273 | { | ||
| 274 | label: '层级结构', | ||
| 275 | type: 'input', | ||
| 276 | placeholder: '请输入', | ||
| 277 | field: 'hierarchy', | ||
| 278 | default: '', | ||
| 279 | clearable: true, | ||
| 280 | visible: false | ||
| 281 | } | ||
| 282 | ]) | ||
| 283 | const formRules: any = ref({ | ||
| 284 | standardTypeCode: { required: true, message: '请选择标准类型' }, | ||
| 285 | codeName: { required: true, message: '请输入代码名称' }, | ||
| 286 | // code: { required: true, message: '请输入代码编码' }, | ||
| 287 | standard: { required: true, message: '请输入标准号' }, | ||
| 288 | standardName: { required: true, message: '请输入标准名称' }, | ||
| 289 | publishingUnitCode: { required: true, message: '请选择发布单位' }, | ||
| 290 | orderNum: { | ||
| 291 | required: true, | ||
| 292 | validator: (rule, value, callback) => { | ||
| 293 | if (value === 0) { | ||
| 294 | callback(); | ||
| 295 | return; | ||
| 296 | } | ||
| 297 | if (!value) { | ||
| 298 | callback(new Error('请填写排序')); | ||
| 299 | return; | ||
| 300 | } | ||
| 301 | const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头) | ||
| 302 | if (value && !r.test(value)) { | ||
| 303 | callback(new Error('请填写大于或等于零整数')); | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | callback(); | ||
| 307 | } | ||
| 308 | }, | ||
| 309 | typeCode: { required: true, message: '请选择代码类型' }, | ||
| 310 | codeFields: { required: true, message: '请选择编码字段' }, | ||
| 311 | codeFieldName: { required: true, message: '请选择编码名称' } | ||
| 312 | }) | ||
| 313 | const formInfo = ref({ | ||
| 314 | type: 'form', | ||
| 315 | title: '', | ||
| 316 | col: 'span', | ||
| 317 | formInfo: { | ||
| 318 | id: 'add-dict-form', | ||
| 319 | col: 'col2', | ||
| 320 | readonly: false, | ||
| 321 | items: formItems.value, | ||
| 322 | rules: formRules.value | ||
| 323 | } | ||
| 324 | }) | ||
| 325 | |||
| 326 | const orginData = [ | ||
| 327 | { | ||
| 328 | ROWID: 'field_0', | ||
| 329 | fieldName: '代码', | ||
| 330 | description: '编码字段', | ||
| 331 | fieldType: 'varchar', | ||
| 332 | fieldLength: '10', | ||
| 333 | fieldPrecision: '', | ||
| 334 | // orderNum: '1', | ||
| 335 | codeRuleGuid: '', | ||
| 336 | STATUS: 'edit', | ||
| 337 | STATE: 'Running' | ||
| 338 | }, { | ||
| 339 | ROWID: 'field_1', | ||
| 340 | fieldName: '名称', | ||
| 341 | description: '编码名称', | ||
| 342 | fieldType: 'varchar', | ||
| 343 | fieldLength: '20', | ||
| 344 | fieldPrecision: '', | ||
| 345 | // orderNum: '2', | ||
| 346 | codeRuleGuid: '', | ||
| 347 | STATUS: 'edit', | ||
| 348 | STATE: 'Running' | ||
| 349 | } | ||
| 350 | ] | ||
| 351 | const orginFields = [ | ||
| 352 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 353 | { label: "字段名称", field: "fieldName", width: 140 } | ||
| 354 | ] | ||
| 355 | const formTableData: any = ref([]) | ||
| 356 | const formTableSelectRowData: any = ref([]) | ||
| 357 | const editTableInfo = ref({ | ||
| 358 | fieldName: { | ||
| 359 | label: '字段名称', | ||
| 360 | type: 'input', | ||
| 361 | maxlength: 50, | ||
| 362 | placeholder: '', | ||
| 363 | field: 'fieldName', | ||
| 364 | default: '', | ||
| 365 | clearable: true, | ||
| 366 | required: true, | ||
| 367 | } | ||
| 368 | }) | ||
| 369 | const formTable = ref({ | ||
| 370 | type: "table", | ||
| 371 | title: "定义表结构", | ||
| 372 | col: 'no-margin', | ||
| 373 | style: { | ||
| 374 | // height: 'calc(100% - 234px)' | ||
| 375 | height: 'auto' | ||
| 376 | }, | ||
| 377 | tableInfo: { | ||
| 378 | id: "role-authority-table", | ||
| 379 | multiple: true, | ||
| 380 | minHeight: 'unset', | ||
| 381 | maxHeight: '100%', | ||
| 382 | fields: [], | ||
| 383 | data: [], | ||
| 384 | showPage: false, | ||
| 385 | actionInfo: { | ||
| 386 | show: true, | ||
| 387 | label: "操作", | ||
| 388 | type: "btn", | ||
| 389 | width: 60, | ||
| 390 | fixed: 'right', | ||
| 391 | btns: [ | ||
| 392 | { label: "删除", value: "remove" }, | ||
| 393 | ] | ||
| 394 | }, | ||
| 395 | editInfo: {}, | ||
| 396 | readonly: false, | ||
| 397 | // col: 'auto-height', | ||
| 398 | style: { | ||
| 399 | // height: 'calc(100% - 40px)' | ||
| 400 | }, | ||
| 401 | loading: false | ||
| 402 | }, | ||
| 403 | tableTool: { | ||
| 404 | // col: 'float-right', | ||
| 405 | visible: false, | ||
| 406 | btns: [ | ||
| 407 | { label: "新增行", value: "add-row", type: 'primary' }, | ||
| 408 | { label: "批量删除", value: "remove_batch" }, | ||
| 409 | ] | ||
| 410 | }, | ||
| 411 | }) | ||
| 412 | |||
| 413 | const fieldSheetInfo: any = ref({}) | ||
| 414 | const uploadTableData: any = ref([]) | ||
| 415 | const uploadSelectRowData: any = ref([]) | ||
| 416 | const uploadTableFields: any = ref([]) | ||
| 417 | const uploadTableInfo = ref({ | ||
| 418 | id: "role-authority-table", | ||
| 419 | multiple: true, | ||
| 420 | // minHeight: 'unset', | ||
| 421 | // maxHeight: '100%', | ||
| 422 | fields: [], | ||
| 423 | data: [], | ||
| 424 | showPage: false, | ||
| 425 | actionInfo: { | ||
| 426 | label: "操作", | ||
| 427 | type: "btn", | ||
| 428 | width: 60, | ||
| 429 | btns: [ | ||
| 430 | { label: "删除", value: "remove" }, | ||
| 431 | ], | ||
| 432 | }, | ||
| 433 | editInfo: {}, | ||
| 434 | readonly: false, | ||
| 435 | loading: false | ||
| 436 | }) | ||
| 437 | const uploadFiles: any = ref([]) | ||
| 438 | const uploadInfo = ref({ | ||
| 439 | type: 'upload', | ||
| 440 | title: '添加表数据', | ||
| 441 | col: 'row-reverse', | ||
| 442 | uploadInfo: { | ||
| 443 | id: 'upload-file-form', | ||
| 444 | action: '', | ||
| 445 | auto: false, | ||
| 446 | fileList: [], | ||
| 447 | accept: '.xlsx, .xls', | ||
| 448 | cover: true, | ||
| 449 | triggerBtn: { | ||
| 450 | label: '导入文件', | ||
| 451 | value: 'import_file', | ||
| 452 | icon: 'Upload', | ||
| 453 | plain: true, | ||
| 454 | }, | ||
| 455 | toolBar: [ | ||
| 456 | { label: '下载模板', value: 'export_model', plain: true, icon: 'Download' }, | ||
| 457 | ] | ||
| 458 | // showList: false, | ||
| 459 | }, | ||
| 460 | tableInfo: {}, | ||
| 461 | tools: { | ||
| 462 | col: 'right', | ||
| 463 | visible: true, | ||
| 464 | btns: [ | ||
| 465 | { label: '树形显示', value: 'show_tree', type: 'primary', plain: true, visible: false }, | ||
| 466 | { label: '新增行', value: 'add_row', type: 'primary', plain: true }, | ||
| 467 | { label: '批量删除', value: 'remove_batch', plain: true }, | ||
| 468 | ] | ||
| 469 | } | ||
| 470 | }) | ||
| 471 | const fieldTableInfo = ref({ | ||
| 472 | type: 'field-table', | ||
| 473 | title: '表数据', | ||
| 474 | tableInfo: { | ||
| 475 | id: 'dict-field-table', | ||
| 476 | minHeight: 'unset', | ||
| 477 | maxHeight: '100%', | ||
| 478 | fields: [], | ||
| 479 | data: [], | ||
| 480 | loading: false, | ||
| 481 | showPage: false, | ||
| 482 | actionInfo: { | ||
| 483 | show: false | ||
| 484 | }, | ||
| 485 | col: 'auto-height' | ||
| 486 | } | ||
| 487 | }) | ||
| 488 | |||
| 489 | const contents = ref({ | ||
| 490 | add: [ | ||
| 491 | formInfo.value, | ||
| 492 | formTable.value, | ||
| 493 | ], | ||
| 494 | upload: [ | ||
| 495 | formInfo.value, | ||
| 496 | uploadInfo.value, | ||
| 497 | ], | ||
| 498 | sheet: [ | ||
| 499 | formInfo.value, | ||
| 500 | formTable.value, | ||
| 501 | ], | ||
| 502 | field: [ | ||
| 503 | formInfo.value, | ||
| 504 | fieldTableInfo.value, | ||
| 505 | ] | ||
| 506 | }) | ||
| 507 | |||
| 508 | const drawerRef = ref() | ||
| 509 | const drawerInfo: any = ref({ | ||
| 510 | visible: false, | ||
| 511 | direction: "rtl", | ||
| 512 | modalClass: "", | ||
| 513 | modalClose: false, | ||
| 514 | modal: true, | ||
| 515 | size: 700, | ||
| 516 | header: { | ||
| 517 | title: "新增", | ||
| 518 | }, | ||
| 519 | type: '', | ||
| 520 | container: { | ||
| 521 | contents: [], | ||
| 522 | }, | ||
| 523 | footer: { | ||
| 524 | btns: [ | ||
| 525 | { type: 'default', label: '取消', value: 'cancel' }, | ||
| 526 | { type: 'primary', label: '保存', value: 'submit', visible: true }, | ||
| 527 | { type: 'primary', label: '保存并添加数据', value: 'saveAndAdd', visible: true }, | ||
| 528 | ] | ||
| 529 | }, | ||
| 530 | }) | ||
| 531 | |||
| 532 | const setFormItems = (row: any = null) => { | ||
| 533 | // formItems.value = JSON.parse(JSON.stringify(orginItems)) | ||
| 534 | formItems.value.map(item => { | ||
| 535 | item.default = row ? row[item.field] : '' | ||
| 536 | |||
| 537 | }) | ||
| 538 | formInfo.value.formInfo.readonly = drawerInfo.value.type == 'detail' | ||
| 539 | formInfo.value.formInfo.items = formItems.value | ||
| 540 | // for(var e in editTableInfo.value){ | ||
| 541 | // const editItem = editTableInfo.value[e] | ||
| 542 | // if(editItem.field != 'description' && editItem.field != 'codeRuleGuid'){ | ||
| 543 | // editItem.disabled = drawerInfo.value.type != 'add' | ||
| 544 | // } | ||
| 545 | // } | ||
| 546 | } | ||
| 547 | |||
| 548 | // 获取数据类型列表 | ||
| 549 | const getDataType = () => { | ||
| 550 | let params = { | ||
| 551 | dictType: "字段类型" | ||
| 552 | } | ||
| 553 | getNewDataTypeList(params).then((res: any) => { | ||
| 554 | if (res.code == proxy.$passCode) { | ||
| 555 | const data = res.data | ||
| 556 | editTableInfo.value['fieldType'].options = data | ||
| 557 | } else { | ||
| 558 | ElMessage({ | ||
| 559 | type: 'error', | ||
| 560 | message: res.msg, | ||
| 561 | }) | ||
| 562 | } | ||
| 563 | }) | ||
| 564 | } | ||
| 565 | |||
| 566 | // 获取数据库列表 | ||
| 567 | const getDataBase = () => { | ||
| 568 | const params = { | ||
| 569 | pageIndex: 1, | ||
| 570 | connectStatus: '1' | ||
| 571 | } | ||
| 572 | getDataBaseList(params).then((res: any) => { | ||
| 573 | if (res.code == proxy.$passCode) { | ||
| 574 | const data = res.data ?? [] | ||
| 575 | data.map(item => { | ||
| 576 | item.label = item.databaseNameZh | ||
| 577 | item.value = item.guid | ||
| 578 | }) | ||
| 579 | dataBaseList.value = data | ||
| 580 | } else { | ||
| 581 | ElMessage({ | ||
| 582 | type: 'error', | ||
| 583 | message: res.msg, | ||
| 584 | }) | ||
| 585 | } | ||
| 586 | }) | ||
| 587 | } | ||
| 588 | |||
| 589 | // 获取编码规则列表 | ||
| 590 | const getCodeRuleData = () => { | ||
| 591 | let params = {} | ||
| 592 | getCoderuleList(params).then((res: any) => { | ||
| 593 | if (res.code == proxy.$passCode) { | ||
| 594 | const data = res.data | ||
| 595 | data?.map(item => { | ||
| 596 | item.label = item.ruleName | ||
| 597 | item.value = item.guid | ||
| 598 | }) | ||
| 599 | codeRuleList.value = data | ||
| 600 | editTableInfo.value['codeRuleGuid'].options = data | ||
| 601 | } else { | ||
| 602 | ElMessage({ | ||
| 603 | type: 'error', | ||
| 604 | message: res.msg, | ||
| 605 | }) | ||
| 606 | } | ||
| 607 | }) | ||
| 608 | } | ||
| 609 | |||
| 610 | const treePromise = ref(); | ||
| 611 | |||
| 612 | const getTreeData = (needClick = false, currData = {}) => { | ||
| 613 | return getParamsList({ dictType: '标准类型'}).then((res:any) => { | ||
| 614 | if (res.code === proxy.$passCode) { | ||
| 615 | const data = res.data || [] | ||
| 616 | data.forEach(item => { | ||
| 617 | item.treeLevel = 1 | ||
| 618 | }) | ||
| 619 | treeInfo.value.data = data | ||
| 620 | standardOptions.value = data | ||
| 621 | |||
| 622 | } | ||
| 623 | }) | ||
| 624 | } | ||
| 625 | |||
| 626 | const getFirstPageData = () => { | ||
| 627 | page.value.curr = 1; | ||
| 628 | toSearch({}) | ||
| 629 | } | ||
| 630 | |||
| 631 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 632 | let params: any = Object.keys(val).length ? { ...val } : {} | ||
| 633 | let { currentNodeKey, currentObj } = treeInfo.value | ||
| 634 | console.log('currentObj', currentObj) | ||
| 635 | params.pageIndex = page.value.curr; | ||
| 636 | params.pageSize = page.value.limit; | ||
| 637 | params.keyWord = tableSearchInput.value | ||
| 638 | if (currentObj.treeLevel === 1) { | ||
| 639 | params.standardTypeCode = currentNodeKey | ||
| 640 | } else if (currentObj.treeLevel === 2) { | ||
| 641 | params.standardTypeCode = currentObj.standardTypeCode | ||
| 642 | params.standardName = currentObj.value | ||
| 643 | } | ||
| 644 | getTableData(params); | ||
| 645 | }; | ||
| 646 | |||
| 647 | const getTableData = (params) => { | ||
| 648 | tableInfo.value.loading = true | ||
| 649 | getStandardCodeList(params).then((res:any) => { | ||
| 650 | if (res.code === proxy.$passCode) { | ||
| 651 | let data = res.data | ||
| 652 | let list = res.data.records || [] | ||
| 653 | list = list.map((item,index) => { | ||
| 654 | item.label = item.codeName | ||
| 655 | item.value = item.guid | ||
| 656 | item.index = index | ||
| 657 | return item | ||
| 658 | }) | ||
| 659 | tableInfo.value.data = list | ||
| 660 | tableInfo.value.page.limit = data.pageSize | ||
| 661 | tableInfo.value.page.curr = data.pageIndex | ||
| 662 | tableInfo.value.page.rows = data.totalRows | ||
| 663 | } | ||
| 664 | tableInfo.value.loading = false | ||
| 665 | }).catch(xhr => { | ||
| 666 | tableInfo.value.loading = false | ||
| 667 | }) | ||
| 668 | }; | ||
| 669 | |||
| 670 | const tableSelectionChange = (val, tId) => { | ||
| 671 | val.sort((pre, cur) => pre.index - cur.index) | ||
| 672 | if (drawerInfo.value.visible) { | ||
| 673 | if (formItems.value.length == 2) { | ||
| 674 | uploadSelectRowData.value = val | ||
| 675 | } else { | ||
| 676 | formTableSelectRowData.value = val | ||
| 677 | } | ||
| 678 | } else { | ||
| 679 | selectRowData.value = val.map((item) => item.guid); | ||
| 680 | selectedRowData.value = val | ||
| 681 | } | ||
| 682 | }; | ||
| 683 | |||
| 684 | const tablePageChange = (info) => { | ||
| 685 | page.value.curr = Number(info.curr); | ||
| 686 | page.value.limit = Number(info.limit); | ||
| 687 | toSearch({}); | ||
| 688 | }; | ||
| 689 | |||
| 690 | const tableInputChange = (val, scope) => { | ||
| 691 | if (forbidFields.indexOf(val) > -1) { | ||
| 692 | ElMessage({ | ||
| 693 | type: "error", | ||
| 694 | message: '该名称已存在,请填写其他名称', | ||
| 695 | }); | ||
| 696 | return | ||
| 697 | } | ||
| 698 | setCodeOptions() | ||
| 699 | } | ||
| 700 | |||
| 701 | const setCodeOptions = () => { | ||
| 702 | let opts: any = [] | ||
| 703 | formTableData.value.map(item => { | ||
| 704 | if (item.fieldName) { | ||
| 705 | const row = JSON.parse(JSON.stringify(item)) | ||
| 706 | row.label = item.fieldName | ||
| 707 | row.value = item.fieldName | ||
| 708 | opts.push(row) | ||
| 709 | } | ||
| 710 | }) | ||
| 711 | codeOptions.value = opts | ||
| 712 | } | ||
| 713 | |||
| 714 | const toolBtnClick = (btn, data) => { | ||
| 715 | console.log(formItems.value.length) | ||
| 716 | const type = btn.value | ||
| 717 | if (data) { | ||
| 718 | if (type.indexOf('add') > -1) { | ||
| 719 | if (formItems.value.length == 2) { | ||
| 720 | const params = { | ||
| 721 | guid: fieldSheetInfo.value.guid | ||
| 722 | } | ||
| 723 | uploadTableInfo.value.loading = true | ||
| 724 | getDictionaryRuleData(params).then((res: any) => { | ||
| 725 | if (res.code == proxy.$passCode) { | ||
| 726 | const data = res.data ?? {} | ||
| 727 | let rowInfo: any = {} | ||
| 728 | uploadTableFields.value.map(item => { | ||
| 729 | rowInfo[item.field] = data[item.field] ?? '' | ||
| 730 | }) | ||
| 731 | rowInfo.STATUS = 'edit' | ||
| 732 | rowInfo.STATE = 'Running' | ||
| 733 | rowInfo.ROWID = `upload_${uploadTableData.value.length}` | ||
| 734 | uploadTableData.value.push(rowInfo) | ||
| 735 | uploadTableInfo.value.data = uploadTableData.value | ||
| 736 | scrollTable(rowInfo) | ||
| 737 | } else { | ||
| 738 | ElMessage({ | ||
| 739 | type: 'error', | ||
| 740 | message: res.msg | ||
| 741 | }) | ||
| 742 | } | ||
| 743 | uploadTableInfo.value.loading = false | ||
| 744 | }).catch(() => { | ||
| 745 | uploadTableInfo.value.loading = false | ||
| 746 | }) | ||
| 747 | } else { | ||
| 748 | const rowInfo = { | ||
| 749 | ROWID: `formData_${formTableData.value.length}`, | ||
| 750 | fieldName: '', | ||
| 751 | description: '', | ||
| 752 | fieldType: '', | ||
| 753 | fieldLength: '', | ||
| 754 | fieldPrecision: '', | ||
| 755 | orderNum: '', | ||
| 756 | codeRuleGuid: '', | ||
| 757 | STATUS: 'edit', | ||
| 758 | STATE: 'Running' | ||
| 759 | } | ||
| 760 | let list: any = formTableData.value | ||
| 761 | list.push(rowInfo) | ||
| 762 | formTable.value.tableInfo.data = list | ||
| 763 | scrollTable(rowInfo) | ||
| 764 | } | ||
| 765 | } else if (type.indexOf('remove') > -1) { | ||
| 766 | if (formItems.value.length == 2) { | ||
| 767 | if (uploadSelectRowData.value.length == 0) { | ||
| 768 | ElMessage({ | ||
| 769 | type: "error", | ||
| 770 | message: '请选择需要删除的数据', | ||
| 771 | }); | ||
| 772 | return | ||
| 773 | } | ||
| 774 | uploadSelectRowData.value.map(item => { | ||
| 775 | const existIndex = uploadTableData.value.findIndex(s => s.ROWID == item.ROWID) | ||
| 776 | existIndex > -1 && uploadTableData.value.splice(existIndex, 1) | ||
| 777 | }) | ||
| 778 | } else { | ||
| 779 | if (formTableSelectRowData.value.length == 0) { | ||
| 780 | ElMessage({ | ||
| 781 | type: "error", | ||
| 782 | message: '请选择需要删除的数据', | ||
| 783 | }); | ||
| 784 | return | ||
| 785 | } | ||
| 786 | const removeRows = () => { | ||
| 787 | formTableSelectRowData.value.map(item => { | ||
| 788 | const existIndex = formTableData.value.findIndex(s => s.ROWID == item.ROWID) | ||
| 789 | existIndex > -1 && formTableData.value.splice(existIndex, 1) | ||
| 790 | }) | ||
| 791 | } | ||
| 792 | if (drawerInfo.value.type == 'edit') { | ||
| 793 | const editRows = formTableSelectRowData.value.filter(item => item.guid !== undefined) | ||
| 794 | if (editRows.length) { | ||
| 795 | // formTable.value.tableInfo.loading = true | ||
| 796 | checkDelete().then((res: any) => { | ||
| 797 | if (res) { | ||
| 798 | ElMessageBox.confirm("数据字典有数据, 确定是否继续删除?", "提示", { | ||
| 799 | confirmButtonText: "确定", | ||
| 800 | cancelButtonText: "取消", | ||
| 801 | type: 'warning', | ||
| 802 | }).then(() => { | ||
| 803 | removeRows() | ||
| 804 | }) | ||
| 805 | } else { | ||
| 806 | removeRows() | ||
| 807 | } | ||
| 808 | // formTable.value.tableInfo.loading = false | ||
| 809 | }).catch(xhr => { | ||
| 810 | ElMessage({ | ||
| 811 | type: 'error', | ||
| 812 | message: xhr | ||
| 813 | }) | ||
| 814 | formTable.value.tableInfo.loading = false | ||
| 815 | }) | ||
| 816 | } else { | ||
| 817 | removeRows() | ||
| 818 | } | ||
| 819 | } else { | ||
| 820 | removeRows() | ||
| 821 | } | ||
| 822 | } | ||
| 823 | } | ||
| 824 | } else { | ||
| 825 | if (type == 'export_model') { | ||
| 826 | exportData('model') | ||
| 827 | } else if (type == 'import_file') { | ||
| 828 | importData() | ||
| 829 | } | ||
| 830 | } | ||
| 831 | } | ||
| 832 | |||
| 833 | const tableSwitchBeforeChange = (scope, field, callback) => { | ||
| 834 | const msg = '确定修改状态?' | ||
| 835 | ElMessageBox.confirm( | ||
| 836 | msg, | ||
| 837 | '提示', | ||
| 838 | { | ||
| 839 | confirmButtonText: '确定', | ||
| 840 | cancelButtonText: '取消', | ||
| 841 | type: 'warning', | ||
| 842 | } | ||
| 843 | ).then(() => { | ||
| 844 | const state = scope.row[field] == 1 ? 0 : 1 | ||
| 845 | const result = tableSwitchChange(state, scope, field) | ||
| 846 | callback(result) | ||
| 847 | }).catch(() => { | ||
| 848 | callback(false) | ||
| 849 | }) | ||
| 850 | } | ||
| 851 | |||
| 852 | const tableSwitchChange = (val, scope, field) => { | ||
| 853 | return new Promise((resolve, reject) => { | ||
| 854 | let params = { | ||
| 855 | guid: scope.row.guid, | ||
| 856 | dictionaryState: val | ||
| 857 | } | ||
| 858 | updateDictionaryState(params).then((res: any) => { | ||
| 859 | if (res.code == proxy.$passCode && res.data) { | ||
| 860 | getFirstPageData() | ||
| 861 | ElMessage({ | ||
| 862 | type: "success", | ||
| 863 | message: '状态修改成功', | ||
| 864 | }); | ||
| 865 | resolve(true) | ||
| 866 | } else { | ||
| 867 | ElMessage({ | ||
| 868 | type: "error", | ||
| 869 | message: res.msg, | ||
| 870 | }); | ||
| 871 | reject(false) | ||
| 872 | } | ||
| 873 | }).catch(() => { | ||
| 874 | reject(false) | ||
| 875 | }) | ||
| 876 | }) | ||
| 877 | } | ||
| 878 | |||
| 879 | const tableBtnClick = (scope, btn) => { | ||
| 880 | |||
| 881 | const type = btn.value; | ||
| 882 | const row = scope.row; | ||
| 883 | if (type == "edit" || type === 'copy') { | ||
| 884 | fieldTableInfo.value.tableInfo.fields = [] | ||
| 885 | fieldTableInfo.value.tableInfo.data = [] | ||
| 886 | drawerInfo.value.header.title = type == 'edit' ? "编辑标准代码" : "复制标准代码"; | ||
| 887 | // drawerInfo.value.modalClass = type == 'edit' ? '' : 'wrap_width_auto' | ||
| 888 | drawerInfo.value.type = type | ||
| 889 | drawerInfo.value.footer.btns.forEach(item => { | ||
| 890 | if (item.value === 'submit' || item.value === 'saveAndAdd') { | ||
| 891 | item.visible = type === 'detail' ? false : true | ||
| 892 | } | ||
| 893 | }) | ||
| 894 | drawerInfo.value.visible = true; | ||
| 895 | drawerInfo.value.loading = true; | ||
| 896 | formTable.value.tableInfo.actionInfo.show = type === 'detail' ? false : true | ||
| 897 | formTable.value.tableTool.visible = type === 'detail' ? false : true | ||
| 898 | formTable.value.tableInfo.loading = true | ||
| 899 | getStandardCodeDetail(row.guid).then((res: any) => { | ||
| 900 | if (res.code == proxy.$passCode && res.data) { | ||
| 901 | let data = res.data | ||
| 902 | currTableData.value = data; | ||
| 903 | setDetailInfo(type) | ||
| 904 | if (type === 'edit') { | ||
| 905 | checkDelete().then((res:any) => { | ||
| 906 | formItems.value.find(v => v.field === 'typeCode')['disabled'] = res ? true : false | ||
| 907 | }) | ||
| 908 | } | ||
| 909 | |||
| 910 | } else { | ||
| 911 | ElMessage({ | ||
| 912 | type: "error", | ||
| 913 | message: res.msg, | ||
| 914 | }); | ||
| 915 | } | ||
| 916 | formTable.value.tableInfo.loading = false | ||
| 917 | drawerInfo.value.loading = false; | ||
| 918 | }).catch(() => { | ||
| 919 | formTable.value.tableInfo.loading = false | ||
| 920 | drawerInfo.value.loading = false; | ||
| 921 | }) | ||
| 922 | // 代码有数据后不允许编辑代码类型 | ||
| 923 | |||
| 924 | } else if (type === 'remove') { | ||
| 925 | let removeRows = () => { | ||
| 926 | const existIndex = formTableData.value.findIndex(s => { | ||
| 927 | if (s.ROWID) { | ||
| 928 | return s.ROWID == row.ROWID | ||
| 929 | } | ||
| 930 | return s.guid == row.guid | ||
| 931 | }) | ||
| 932 | existIndex > -1 && formTableData.value.splice(existIndex, 1) | ||
| 933 | } | ||
| 934 | if (drawerInfo.value.type == 'edit') { | ||
| 935 | checkDelete().then((res:any) => { | ||
| 936 | if (res) { | ||
| 937 | ElMessageBox.confirm("标准代码有数据, 确定是否继续删除?", "提示", { | ||
| 938 | confirmButtonText: "确定", | ||
| 939 | cancelButtonText: "取消", | ||
| 940 | type: 'warning', | ||
| 941 | }).then(() => { | ||
| 942 | removeRows() | ||
| 943 | }) | ||
| 944 | } else { | ||
| 945 | removeRows() | ||
| 946 | } | ||
| 947 | }) | ||
| 948 | } else { | ||
| 949 | removeRows() | ||
| 950 | } | ||
| 951 | } | ||
| 952 | else if (type == "delete") { | ||
| 953 | currTableData.value = row; | ||
| 954 | tableInfo.value.loading = true | ||
| 955 | open("此操作将永久删除, 是否继续?", "warning"); | ||
| 956 | tableInfo.value.loading = false | ||
| 957 | } else if (type == 'detail') { | ||
| 958 | showFiledsPage.value = true | ||
| 959 | nextTick(() => { | ||
| 960 | dictFiledsRef.value.standardGuid = row.guid | ||
| 961 | dictFiledsRef.value.standardName = row.standardName | ||
| 962 | treeCurrentNodeKey.value = row.guid | ||
| 963 | treeInfo.value.currentNodeKey = row.guid | ||
| 964 | dictFiledsRef.value.getFirstPageData() | ||
| 965 | }) | ||
| 966 | } | ||
| 967 | } | ||
| 968 | |||
| 969 | const checkDelete = (isBatch: any = false) => { | ||
| 970 | return new Promise((resolve, reject) => { | ||
| 971 | let params: any = { | ||
| 972 | pageIndex: 1, | ||
| 973 | pageSize: -1, | ||
| 974 | standardGuid: currTableData.value.guid | ||
| 975 | } | ||
| 976 | |||
| 977 | getStandardCodeDataList(params).then((res: any) => { | ||
| 978 | if (res.code == proxy.$passCode) { | ||
| 979 | if (res.data.records.length) { | ||
| 980 | resolve(res.data) | ||
| 981 | } else { | ||
| 982 | resolve(null) | ||
| 983 | } | ||
| 984 | } else { | ||
| 985 | reject(res.msg) | ||
| 986 | } | ||
| 987 | }).catch((xhr: any) => { | ||
| 988 | reject(xhr.msg) | ||
| 989 | }) | ||
| 990 | }) | ||
| 991 | } | ||
| 992 | |||
| 993 | const open = (msg, type, isBatch = false) => { | ||
| 994 | ElMessageBox.confirm(msg, "提示", { | ||
| 995 | confirmButtonText: "确定", | ||
| 996 | cancelButtonText: "取消", | ||
| 997 | type: type, | ||
| 998 | }).then(() => { | ||
| 999 | let guids = [currTableData.value.guid] | ||
| 1000 | if (isBatch) { | ||
| 1001 | guids = selectRowData.value | ||
| 1002 | } | ||
| 1003 | tableInfo.value.loading = true | ||
| 1004 | deleteStandardCode(guids).then((res: any) => { | ||
| 1005 | if (res.code == proxy.$passCode) { | ||
| 1006 | initTree().then(() => getFirstPageData()) | ||
| 1007 | // getFirstPageData() | ||
| 1008 | ElMessage({ | ||
| 1009 | type: "success", | ||
| 1010 | message: "删除成功", | ||
| 1011 | }); | ||
| 1012 | } else { | ||
| 1013 | ElMessage({ | ||
| 1014 | type: "error", | ||
| 1015 | message: res.msg, | ||
| 1016 | }); | ||
| 1017 | } | ||
| 1018 | tableInfo.value.loading = false | ||
| 1019 | }).catch(() => { | ||
| 1020 | tableInfo.value.loading = false | ||
| 1021 | }); | ||
| 1022 | }); | ||
| 1023 | }; | ||
| 1024 | |||
| 1025 | const onUpload = (file, fileList) => { | ||
| 1026 | uploadFiles.value = fileList | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | const uploadFile = (file) => { | ||
| 1030 | importData(file) | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | const exportData = (type: any = null) => { | ||
| 1034 | let body = { | ||
| 1035 | standardCodeGuid: treeCurrentNodeKey.value, | ||
| 1036 | standardCodeDataGuids: [] | ||
| 1037 | } | ||
| 1038 | exportStandardCodeData(body).then((res:any) => { | ||
| 1039 | if (res && !res.msg) { | ||
| 1040 | download(res, '标准代码表.xlsx', 'excel') | ||
| 1041 | } else { | ||
| 1042 | res?.msg && ElMessage.error(res?.msg); | ||
| 1043 | } | ||
| 1044 | }) | ||
| 1045 | return | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | const importData = (file: any = null) => { | ||
| 1049 | let params = new FormData() | ||
| 1050 | if (file) { | ||
| 1051 | params.append("file", file.raw); | ||
| 1052 | } else { | ||
| 1053 | if (uploadFiles.value.length) { | ||
| 1054 | uploadFiles.value.forEach((item: any, index: number) => { | ||
| 1055 | params.append("file", item.raw); | ||
| 1056 | }); | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | params.append("dictionaryGuid", fieldSheetInfo.value.guid); | ||
| 1061 | showDictionary(params).then((res: any) => { | ||
| 1062 | if (res.code == proxy.$passCode) { | ||
| 1063 | let data = res.data ?? [] | ||
| 1064 | setUploadDataInfo(data) | ||
| 1065 | } else { | ||
| 1066 | ElMessage({ | ||
| 1067 | type: "error", | ||
| 1068 | message: res.msg, | ||
| 1069 | }); | ||
| 1070 | } | ||
| 1071 | }) | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | // 生成表头 | ||
| 1075 | const setUploadDataFields = (data) => { | ||
| 1076 | let fields: any = [], editInfo: any = {} | ||
| 1077 | data.map(item => { | ||
| 1078 | let fieldItem: any = { | ||
| 1079 | label: item.description, field: item.fieldName, width: 140 | ||
| 1080 | } | ||
| 1081 | if (drawerInfo.value.type != 'detail') { | ||
| 1082 | fieldItem.type = 'edit' | ||
| 1083 | fieldItem.columClass = 'edit-colum' | ||
| 1084 | editInfo[item.fieldName] = { | ||
| 1085 | label: '', | ||
| 1086 | type: 'input', | ||
| 1087 | placeholder: '', | ||
| 1088 | field: item.fieldName, | ||
| 1089 | default: '', | ||
| 1090 | disabled: item.codeRuleGuid ? true : false, | ||
| 1091 | clearable: true, | ||
| 1092 | } | ||
| 1093 | } | ||
| 1094 | fields.push(fieldItem) | ||
| 1095 | }) | ||
| 1096 | uploadTableFields.value = fields | ||
| 1097 | if (drawerInfo.value.type == 'detail') { | ||
| 1098 | fieldTableInfo.value.tableInfo.fields = uploadTableFields.value | ||
| 1099 | } else { | ||
| 1100 | uploadTableInfo.value.fields = uploadTableFields.value | ||
| 1101 | uploadTableInfo.value.editInfo = editInfo | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | // 生成表数据 | ||
| 1106 | const setUploadDataInfo = async (info) => { | ||
| 1107 | let data = info | ||
| 1108 | if (drawerInfo.value.type == 'detail') { | ||
| 1109 | data = info.jsonArray ?? [] | ||
| 1110 | const fields = info.schemaDataVOS ?? [] | ||
| 1111 | setUploadDataFields(fields) | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | if (drawerInfo.value.type == 'detail') { | ||
| 1115 | fieldTableInfo.value.tableInfo.data = data | ||
| 1116 | drawerInfo.value.container.contents = contents.value['field'] | ||
| 1117 | } else { | ||
| 1118 | // 设置表数据 | ||
| 1119 | data.map((item, i) => { | ||
| 1120 | item.STATUS = 'edit' | ||
| 1121 | item.STATE = 'Running' | ||
| 1122 | item.ROWID = `upload_${i}` | ||
| 1123 | }) | ||
| 1124 | uploadTableData.value = data | ||
| 1125 | uploadTableInfo.value.data = uploadTableData.value | ||
| 1126 | } | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | const loadDrawer = async () => { | ||
| 1130 | drawerInfo.value.visible = true; | ||
| 1131 | drawerInfo.value.type = 'add'; | ||
| 1132 | drawerInfo.value.header.title = '新增标准代码'; | ||
| 1133 | drawerInfo.value.footer.visible = true; | ||
| 1134 | // drawerInfo.value.header.title = '新增数据字典' | ||
| 1135 | // drawerInfo.value.type = 'add' | ||
| 1136 | // drawerInfo.value.modalClass = ''; | ||
| 1137 | // await setFormItems() | ||
| 1138 | let fields = JSON.parse(JSON.stringify(orginFields)) | ||
| 1139 | fields.map((item: any) => { | ||
| 1140 | if (!item.type || item.type != 'index') { | ||
| 1141 | item.type = 'edit' | ||
| 1142 | item.columClass = 'edit-colum' | ||
| 1143 | } | ||
| 1144 | }) | ||
| 1145 | formTable.value.tableInfo.fields = fields | ||
| 1146 | formItems.value.forEach(item => { | ||
| 1147 | if (item.field === 'bizState') { | ||
| 1148 | item.default = 'Y' | ||
| 1149 | } else if (item.field === 'typeCode') { | ||
| 1150 | item.default = '1' | ||
| 1151 | } else if (item.field === 'hierarchy') { | ||
| 1152 | item.default = '' | ||
| 1153 | item.visible = false | ||
| 1154 | } | ||
| 1155 | else { | ||
| 1156 | item.default = '' | ||
| 1157 | } | ||
| 1158 | item.disabled = false | ||
| 1159 | }) | ||
| 1160 | |||
| 1161 | formInfo.value.formInfo.items = formItems.value | ||
| 1162 | formTableData.value = JSON.parse(JSON.stringify(orginData)) | ||
| 1163 | formTable.value.tableInfo.data = formTableData.value | ||
| 1164 | formTable.value.tableInfo.editInfo = JSON.parse(JSON.stringify(editTableInfo.value)) | ||
| 1165 | formTable.value.tableInfo.readonly = false | ||
| 1166 | formTable.value.tableInfo.multiple = true | ||
| 1167 | formTable.value.tableInfo.actionInfo.show = true | ||
| 1168 | formTable.value.tableTool.visible = true | ||
| 1169 | drawerInfo.value.container.contents = contents.value['add'] | ||
| 1170 | drawerInfo.value.footer.btns.forEach(item => { | ||
| 1171 | item.visible = true | ||
| 1172 | }) | ||
| 1173 | drawerInfo.value.visible = true | ||
| 1174 | console.log('table', formTable.value) | ||
| 1175 | console.log('formInfo', formInfo) | ||
| 1176 | setCodeOptions() | ||
| 1177 | }; | ||
| 1178 | |||
| 1179 | const treeCurrentNodeKey = ref('') | ||
| 1180 | const batching = (type) => { | ||
| 1181 | if (type == 'delete') { | ||
| 1182 | if (selectRowData.value.length == 0) { | ||
| 1183 | ElMessage({ | ||
| 1184 | type: 'error', | ||
| 1185 | message: '请选择需要删除的数据', | ||
| 1186 | }) | ||
| 1187 | return | ||
| 1188 | } | ||
| 1189 | tableInfo.value.loading = true | ||
| 1190 | open("此操作将永久删除, 是否继续?", "warning", true); | ||
| 1191 | tableInfo.value.loading = false | ||
| 1192 | } | ||
| 1193 | if (type == 'export') { | ||
| 1194 | if (selectRowData.value.length == 0) { | ||
| 1195 | ElMessage({ | ||
| 1196 | type: 'error', | ||
| 1197 | message: '请选择代码名称', | ||
| 1198 | }) | ||
| 1199 | return | ||
| 1200 | } | ||
| 1201 | if (selectRowData.value.length > 30) { | ||
| 1202 | ElMessage.error('选择的代码名称不能超过30个') | ||
| 1203 | return | ||
| 1204 | } | ||
| 1205 | // console.log(selectedRowData) | ||
| 1206 | let uploadSetting = selectedRowData.value.map(item => { | ||
| 1207 | return { | ||
| 1208 | standardName: item.codeName, | ||
| 1209 | standardGuid: item.guid | ||
| 1210 | } | ||
| 1211 | }) | ||
| 1212 | cacheStore.setCatch('uploadSetting', uploadSetting) | ||
| 1213 | router.push({ | ||
| 1214 | path: '/data-meta/metadata-standard/standard-import', | ||
| 1215 | }); | ||
| 1216 | } | ||
| 1217 | }; | ||
| 1218 | |||
| 1219 | const nodeClick = (data) => { | ||
| 1220 | console.log('treeNodeClick', data) | ||
| 1221 | drawerInfo.value.visible = false | ||
| 1222 | const changeCont = () => { | ||
| 1223 | nextTick(() => { | ||
| 1224 | treeInfo.value.currentNodeKey = data.value | ||
| 1225 | treeInfo.value.currentObj = data | ||
| 1226 | if (data.isLeaf) { | ||
| 1227 | showFiledsPage.value = true | ||
| 1228 | nextTick(() => { | ||
| 1229 | dictFiledsRef.value.standardGuid = data.value | ||
| 1230 | dictFiledsRef.value.standardName = data.label | ||
| 1231 | treeCurrentNodeKey.value = data.value | ||
| 1232 | dictFiledsRef.value.getFirstPageData() | ||
| 1233 | }) | ||
| 1234 | } else { | ||
| 1235 | showFiledsPage.value = false | ||
| 1236 | getFirstPageData() | ||
| 1237 | } | ||
| 1238 | }) | ||
| 1239 | } | ||
| 1240 | if (showFiledsPage.value) { | ||
| 1241 | const toChange = dictFiledsRef.value.checkSave() | ||
| 1242 | if (!toChange) { | ||
| 1243 | ElMessageBox.confirm( | ||
| 1244 | '存在未保存的数据,切换后会丢失,是否确定切换', | ||
| 1245 | '提示', | ||
| 1246 | { | ||
| 1247 | confirmButtonText: '确定', | ||
| 1248 | cancelButtonText: '取消', | ||
| 1249 | type: 'warning', | ||
| 1250 | } | ||
| 1251 | ).then(() => { | ||
| 1252 | changeCont() | ||
| 1253 | }).catch(() => { | ||
| 1254 | treeInfo.value.currentNodeKey = dictGuid.value | ||
| 1255 | }) | ||
| 1256 | } else { | ||
| 1257 | changeCont() | ||
| 1258 | } | ||
| 1259 | } else { | ||
| 1260 | changeCont() | ||
| 1261 | } | ||
| 1262 | } | ||
| 1263 | function loadTreeNode (node, resolve) { | ||
| 1264 | console.log('node', node) | ||
| 1265 | if (node.isLeaf) { | ||
| 1266 | return resolve([]); | ||
| 1267 | } | ||
| 1268 | if (node.level === 1) { | ||
| 1269 | let standardTypeCode = node.data.value | ||
| 1270 | getStandardCodeStandard(standardTypeCode).then((res:any) => { | ||
| 1271 | if (res.code === proxy.$passCode) { | ||
| 1272 | let data = res.data || [] | ||
| 1273 | let uniqList = Array.from(new Set(data)).map(item => { | ||
| 1274 | return { | ||
| 1275 | label: item, | ||
| 1276 | value: item, | ||
| 1277 | treeLevel: 2, | ||
| 1278 | standardTypeCode | ||
| 1279 | } | ||
| 1280 | }) | ||
| 1281 | resolve(uniqList) | ||
| 1282 | } | ||
| 1283 | }) | ||
| 1284 | } | ||
| 1285 | if (node.level === 2) { | ||
| 1286 | let params = { | ||
| 1287 | pageIndex: 1, | ||
| 1288 | pageSize: -1, | ||
| 1289 | standardTypeCode: node.data.standardTypeCode, | ||
| 1290 | standardName: node.data.value | ||
| 1291 | } | ||
| 1292 | getStandardCodeList(params).then((res:any) => { | ||
| 1293 | if (res.code === proxy.$passCode) { | ||
| 1294 | const list = res.data.records || [] | ||
| 1295 | list.forEach(item => { | ||
| 1296 | item.isLeaf = true | ||
| 1297 | item.label = item.codeName | ||
| 1298 | item.value = item.guid | ||
| 1299 | }) | ||
| 1300 | resolve(list) | ||
| 1301 | } | ||
| 1302 | }) | ||
| 1303 | } | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | // 设置详情信息 | ||
| 1307 | const setDetailInfo = (type) => { | ||
| 1308 | console.log('type', type) | ||
| 1309 | const row = JSON.parse(JSON.stringify(currTableData.value)) | ||
| 1310 | formItems.value.forEach(item => { | ||
| 1311 | item.default = row[item.field] || '' | ||
| 1312 | item.disabled = type === 'detail' ? true : false | ||
| 1313 | }) | ||
| 1314 | formInfo.value.formInfo.items = formItems.value | ||
| 1315 | formTableData.value = row.standardCodeFields.map(item => { | ||
| 1316 | item.STATUS = 'edit' | ||
| 1317 | return item | ||
| 1318 | }) | ||
| 1319 | |||
| 1320 | let fields = JSON.parse(JSON.stringify(orginFields)) | ||
| 1321 | fields.map((item: any) => { | ||
| 1322 | if (item.type != 'index') { | ||
| 1323 | item.type = 'edit' | ||
| 1324 | item.columClass = 'edit-colum' | ||
| 1325 | } | ||
| 1326 | }) | ||
| 1327 | formTable.value.tableInfo.fields = fields | ||
| 1328 | formTable.value.tableInfo.data = formTableData.value | ||
| 1329 | formTable.value.tableInfo.editInfo = JSON.parse(JSON.stringify(editTableInfo.value)) | ||
| 1330 | formTable.value.tableInfo.readonly = type === 'detail' ? true : false | ||
| 1331 | formTable.value.tableInfo.multiple = true | ||
| 1332 | // formTable.value.tableInfo.actionInfo.show = true | ||
| 1333 | // formTable.value.tableTool.visible = true | ||
| 1334 | drawerInfo.value.container.contents = contents.value['add'] | ||
| 1335 | drawerInfo.value.visible = true | ||
| 1336 | |||
| 1337 | // if (row.typeCode) | ||
| 1338 | formItems.value.find(v => v.field === 'hierarchy')['visible'] = row.typeCode == 1 ? false : true | ||
| 1339 | |||
| 1340 | setCodeOptions() | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | const saveData = async (params, btnValue) => { | ||
| 1344 | // const passInfo = await checkParamsData() | ||
| 1345 | console.log('params', params) | ||
| 1346 | let request = drawerInfo.value.type === 'edit' ? updateStandardCode : saveStandardCode | ||
| 1347 | request(params).then((res:any) => { | ||
| 1348 | if (res.code === proxy.$passCode) { | ||
| 1349 | ElMessage.success('操作成功') | ||
| 1350 | initTree().then(() => { | ||
| 1351 | drawerInfo.value.visible = false | ||
| 1352 | if (btnValue === 'saveAndAdd') { | ||
| 1353 | // 跳转代码详情 | ||
| 1354 | toStandardCodeDetail(res.data) | ||
| 1355 | } else { | ||
| 1356 | getFirstPageData() | ||
| 1357 | } | ||
| 1358 | }) | ||
| 1359 | } else { | ||
| 1360 | ElMessage.error(res.msg) | ||
| 1361 | } | ||
| 1362 | }).finally(() => { | ||
| 1363 | drawerInfo.value.footer.btns.map((item: any) => item.disabled = false) | ||
| 1364 | }) | ||
| 1365 | } | ||
| 1366 | function toStandardCodeDetail (guid) { | ||
| 1367 | if (drawerInfo.value.type === 'add' || drawerInfo.value.type === 'copy') { | ||
| 1368 | getStandardCodeDetail(guid).then((res:any) => { | ||
| 1369 | if (res.code == proxy.$passCode) { | ||
| 1370 | let { guid, codeName } = res.data | ||
| 1371 | showFiledsPage.value = true | ||
| 1372 | nextTick(() => { | ||
| 1373 | dictFiledsRef.value.standardGuid = guid | ||
| 1374 | dictFiledsRef.value.standardName = codeName | ||
| 1375 | treeCurrentNodeKey.value = guid | ||
| 1376 | treeInfo.value.currentNodeKey = guid | ||
| 1377 | dictFiledsRef.value.getFirstPageData() | ||
| 1378 | }) | ||
| 1379 | } | ||
| 1380 | }) | ||
| 1381 | } else { | ||
| 1382 | console.log('currentData', currTableData.value) | ||
| 1383 | let { guid, codeName } = currTableData.value | ||
| 1384 | showFiledsPage.value = true | ||
| 1385 | nextTick(() => { | ||
| 1386 | dictFiledsRef.value.standardGuid = guid | ||
| 1387 | dictFiledsRef.value.standardName = codeName | ||
| 1388 | treeCurrentNodeKey.value = guid | ||
| 1389 | treeInfo.value.currentNodeKey = guid | ||
| 1390 | dictFiledsRef.value.getFirstPageData() | ||
| 1391 | }) | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | } | ||
| 1395 | |||
| 1396 | const scrollTable = (rowInfo) => { | ||
| 1397 | nextTick(() => { | ||
| 1398 | const drawerBody = document.getElementsByClassName('el-drawer__body')[0]; | ||
| 1399 | const tableListRef = drawerRef.value.getDrawerConRef("drawerTableRef"); | ||
| 1400 | if (!tableListRef) return; | ||
| 1401 | //设置选中表格当前新增行。 | ||
| 1402 | tableListRef.setCurrentRow(rowInfo); | ||
| 1403 | drawerBody.scrollTop = drawerBody.scrollHeight; | ||
| 1404 | let table = tableListRef.layout.table.refs; | ||
| 1405 | // 获取表格滚动元素 | ||
| 1406 | let tableScrollEle = | ||
| 1407 | table.bodyWrapper.firstElementChild.firstElementChild; | ||
| 1408 | // 设置表格滚动的位置 | ||
| 1409 | tableScrollEle.scrollTop = tableScrollEle.scrollHeight; | ||
| 1410 | }); | ||
| 1411 | }; | ||
| 1412 | |||
| 1413 | const drawerBtnClick = (btn, info) => { | ||
| 1414 | console.log('btn', btn, info) | ||
| 1415 | console.log('table', formTable.value) | ||
| 1416 | |||
| 1417 | let params = { | ||
| 1418 | standardCodeFields: formTable.value.tableInfo.data.map(item => { | ||
| 1419 | let obj = { | ||
| 1420 | fieldName: item.fieldName, | ||
| 1421 | guid: item.guid || null, | ||
| 1422 | standardGuid: item.standardGuid || null | ||
| 1423 | } | ||
| 1424 | return obj | ||
| 1425 | }), | ||
| 1426 | ...info | ||
| 1427 | } | ||
| 1428 | if (params.typeCode === '1' || !params.hierarchy) { | ||
| 1429 | delete params.hierarchy | ||
| 1430 | } | ||
| 1431 | if (drawerInfo.value.type === 'edit') { | ||
| 1432 | params.guid = currTableData.value.guid | ||
| 1433 | } | ||
| 1434 | if (btn.value == 'submit' || btn.value == 'saveAndAdd') { | ||
| 1435 | let uniqFieldNameList = Array.from(new Set(formTable.value.tableInfo.data.map(item => item.fieldName))) | ||
| 1436 | if (uniqFieldNameList.length !== formTable.value.tableInfo.data.length) { | ||
| 1437 | ElMessage.error('表结构字段名称需唯一,不允许重名') | ||
| 1438 | return | ||
| 1439 | } | ||
| 1440 | let standardCodeFields = params.standardCodeFields.map(v => v.fieldName).join() | ||
| 1441 | let codeFieldName = params.codeFieldName | ||
| 1442 | let codeFields = params.codeFields | ||
| 1443 | let fieldValidate = false | ||
| 1444 | if (standardCodeFields.includes(codeFieldName) && codeFields.every(v => standardCodeFields.includes(v))) { | ||
| 1445 | fieldValidate = true | ||
| 1446 | } | ||
| 1447 | if (!fieldValidate) { | ||
| 1448 | ElMessage.error('所选的编码字段和编码名称必须在字段名称中有') | ||
| 1449 | return | ||
| 1450 | } | ||
| 1451 | drawerInfo.value.footer.btns.map((item: any) => item.disabled = true) | ||
| 1452 | saveData(params,btn.value) | ||
| 1453 | } else { | ||
| 1454 | drawerInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 1455 | nextTick(() => { | ||
| 1456 | drawerInfo.value.visible = false | ||
| 1457 | }) | ||
| 1458 | } | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | const radioGroupChange = async (val, info) => { | ||
| 1462 | // console.log(val, info) | ||
| 1463 | await setFormItems(info) | ||
| 1464 | // setGroup() | ||
| 1465 | if (val == 1) { | ||
| 1466 | // 列表结构 | ||
| 1467 | formItems.value.find(v => v.field === 'hierarchy')['visible'] = false | ||
| 1468 | } else { | ||
| 1469 | formItems.value.find(v => v.field === 'hierarchy')['visible'] = true | ||
| 1470 | } | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | function initTree () { | ||
| 1474 | return Promise.all([getParamsList({ dictType: '标准类型'}), getStandardCodeTree()]).then((resList:any) => { | ||
| 1475 | let treeRoot = resList[0].data || [] | ||
| 1476 | let treeData = resList[1].data || [] | ||
| 1477 | // console.log('treeRoot', treeRoot) | ||
| 1478 | // console.log('treeData', treeData) | ||
| 1479 | treeData.forEach(item => { | ||
| 1480 | if (item.children) { | ||
| 1481 | item.children.forEach(subItem => { | ||
| 1482 | // 二级标准name 为 value | ||
| 1483 | subItem.treeLevel = 2 | ||
| 1484 | subItem.label = subItem.name | ||
| 1485 | subItem.value = subItem.name | ||
| 1486 | if (subItem.children) { | ||
| 1487 | subItem.children.forEach(threeItem => { | ||
| 1488 | threeItem.label = threeItem.name | ||
| 1489 | threeItem.value = threeItem.guid | ||
| 1490 | threeItem.isLeaf = threeItem.isCode | ||
| 1491 | }) | ||
| 1492 | } | ||
| 1493 | }) | ||
| 1494 | } | ||
| 1495 | }) | ||
| 1496 | let tree = treeRoot.map(item => { | ||
| 1497 | item.treeLevel = 1 | ||
| 1498 | let target = treeData.find(v => v.guid === item.value) | ||
| 1499 | item.children = target ? target.children : null | ||
| 1500 | return item | ||
| 1501 | }) | ||
| 1502 | // console.log('treeData', treeData) | ||
| 1503 | // console.log('tree', tree) | ||
| 1504 | standardOptions.value = treeRoot | ||
| 1505 | treeInfo.value.data = tree | ||
| 1506 | }) | ||
| 1507 | } | ||
| 1508 | |||
| 1509 | onBeforeMount(() => { | ||
| 1510 | // getDataType() | ||
| 1511 | initTree().then(() => { | ||
| 1512 | nodeClick(treeInfo.value.data[0]) | ||
| 1513 | }) | ||
| 1514 | // getTreeData().then(() => { | ||
| 1515 | // // 默认展开第一个 | ||
| 1516 | // let data = treeInfo.value.data | ||
| 1517 | // if (data.length === 0) return | ||
| 1518 | // let params = { | ||
| 1519 | // pageIndex: 1, | ||
| 1520 | // pageSize: 50, | ||
| 1521 | // standardTypeCode: data[0].value, | ||
| 1522 | // // codeName: '标准类型' | ||
| 1523 | // } | ||
| 1524 | // getStandardCodeList(params).then((res:any) => { | ||
| 1525 | // if (res.code === proxy.$passCode) { | ||
| 1526 | // let data = res.data | ||
| 1527 | // data.records && data.records.forEach((item,index) => item.index = index) | ||
| 1528 | // tableInfo.value.data = data.records | ||
| 1529 | // tableInfo.value.page.limit = data.pageSize | ||
| 1530 | // tableInfo.value.page.curr = data.pageIndex | ||
| 1531 | // tableInfo.value.page.rows = data.totalRows | ||
| 1532 | // } | ||
| 1533 | // }) | ||
| 1534 | // }) | ||
| 1535 | getParamsList({ dictType: '发布单位' }).then((res:any) => { | ||
| 1536 | if (res.code === proxy.$passCode) { | ||
| 1537 | const data = res.data || [] | ||
| 1538 | publishingUnitCodeOptions.value = data | ||
| 1539 | } | ||
| 1540 | }) | ||
| 1541 | }) | ||
| 1542 | |||
| 1543 | onMounted(() => { | ||
| 1544 | |||
| 1545 | }); | ||
| 1546 | |||
| 1547 | </script> | ||
| 1548 | |||
| 1549 | <template> | ||
| 1550 | <div class="container_wrap full flex"> | ||
| 1551 | <div class="aside_wrap"> | ||
| 1552 | <div class="aside_title">标准代码列表</div> | ||
| 1553 | <!-- <Tree ref="dictTreeRef" :treeInfo="treeInfo" @nodeClick="nodeClick" @loadNode="loadTreeNode"/> --> | ||
| 1554 | <Tree ref="dictTreeRef" :treeInfo="treeInfo" @nodeClick="nodeClick" /> | ||
| 1555 | </div> | ||
| 1556 | <DictFileds ref="dictFiledsRef" v-if="showFiledsPage" @exportData="exportData" /> | ||
| 1557 | <div class="main_wrap" v-else> | ||
| 1558 | <div class="table_tool_wrap"> | ||
| 1559 | <div class="tools_btns"> | ||
| 1560 | <el-button type="primary" @click="loadDrawer" v-preReClick>新建</el-button> | ||
| 1561 | <el-button @click="batching('export')" v-preReClick>批量导入</el-button> | ||
| 1562 | <el-button @click="batching('delete')" v-preReClick>批量删除</el-button> | ||
| 1563 | </div> | ||
| 1564 | <el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="请输入关键字搜索" | ||
| 1565 | :suffix-icon="Search" clearable @change="val => getFirstPageData()" /> | ||
| 1566 | </div> | ||
| 1567 | <div class="table_panel_wrap full"> | ||
| 1568 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange" | ||
| 1569 | @tablePageChange="tablePageChange" @tableSwitchBeforeChange="tableSwitchBeforeChange" /> | ||
| 1570 | </div> | ||
| 1571 | </div> | ||
| 1572 | <Drawer ref="drawerRef" | ||
| 1573 | class="table-no-scorll" | ||
| 1574 | :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" | ||
| 1575 | @radioGroupChange="radioGroupChange" @drawerTableBtnClick="tableBtnClick" | ||
| 1576 | @drawerTableSelectionChange="tableSelectionChange" @drawerTableToolBtnClick="toolBtnClick" | ||
| 1577 | @drawerTableInputChange="tableInputChange" @drawerToolBtnClick="toolBtnClick" @onUpload="onUpload" | ||
| 1578 | @uploadFile="uploadFile" @uploadBtnClick="toolBtnClick" /> | ||
| 1579 | </div> | ||
| 1580 | </template> | ||
| 1581 | |||
| 1582 | <style lang="scss" scoped> | ||
| 1583 | .container_wrap { | ||
| 1584 | .aside_wrap { | ||
| 1585 | width: 200px; | ||
| 1586 | } | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | .tree_panel { | ||
| 1590 | height: 100%; | ||
| 1591 | padding-top: 0; | ||
| 1592 | |||
| 1593 | :deep(.el-tree) { | ||
| 1594 | margin: 0; | ||
| 1595 | height: calc(100% - 68px); | ||
| 1596 | overflow: hidden auto; | ||
| 1597 | } | ||
| 1598 | |||
| 1599 | } | ||
| 1600 | </style> | ||
| 1601 | <style lang="scss"> | ||
| 1602 | .table-no-scorll { | ||
| 1603 | .el-scrollbar__bar.is-vertical { | ||
| 1604 | display: none!important; | ||
| 1605 | } | ||
| 1606 | } | ||
| 1607 | /* .el-scrollbar__bar.is-vertical { | ||
| 1608 | display: none!important; | ||
| 1609 | } */ | ||
| 1610 | </style> |
| 1 | <route lang="yaml"> | ||
| 2 | name: metadataStandardCodetable | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="metadataStandardCodetable"> | ||
| 6 | import { ref, reactive } from 'vue'; | ||
| 7 | import { ElMessage } from "element-plus"; | ||
| 8 | import Tree from '@/components/Tree/index.vue'; | ||
| 9 | import TableTools from '@/components/Tools/table_tools.vue'; | ||
| 10 | import { Search } from '@element-plus/icons-vue' | ||
| 11 | import { useRouter, useRoute } from "vue-router"; | ||
| 12 | import { TableColumnWidth } from '@/utils/enum'; | ||
| 13 | import { commonPageConfig } from '@/components/PageNav/index'; | ||
| 14 | import { getParamsList } from '@/api/modules/dataAsset' | ||
| 15 | import { getStandardCodeList, saveStandardCode, updateStandardCode } from '@/api/modules/dataMetaService' | ||
| 16 | |||
| 17 | const { proxy } = getCurrentInstance() as any; | ||
| 18 | const router = useRouter(); | ||
| 19 | |||
| 20 | const treeInfo:any = reactive({ | ||
| 21 | id: "data-pickup-tree", | ||
| 22 | filter: true, | ||
| 23 | queryValue: "", | ||
| 24 | queryPlaceholder: "请输入关键字搜索", | ||
| 25 | props: { | ||
| 26 | label: "label", | ||
| 27 | value: "value", | ||
| 28 | }, | ||
| 29 | nodeKey: 'value', | ||
| 30 | expandedKey: ['01'], | ||
| 31 | currentNodeKey: '01', | ||
| 32 | expandOnNodeClick: false, | ||
| 33 | data: [], | ||
| 34 | loading: false | ||
| 35 | }); | ||
| 36 | function nodeClick (data) { | ||
| 37 | |||
| 38 | } | ||
| 39 | |||
| 40 | /** 分页及搜索传参信息配置。 */ | ||
| 41 | const tableSearchInput = ref('') | ||
| 42 | function getFirstPageData () { | ||
| 43 | page.value.curr = 1 | ||
| 44 | toSearch({}) | ||
| 45 | } | ||
| 46 | function toSearch (val: any, clear: boolean = false) { | ||
| 47 | let params: any = Object.keys(val).length ? { ...val } : {} | ||
| 48 | params.pageIndex = page.value.curr; | ||
| 49 | params.pageSize = page.value.limit; | ||
| 50 | params.name = tableSearchInput.value | ||
| 51 | getTableData(params); | ||
| 52 | } | ||
| 53 | const page = ref({ | ||
| 54 | ...commonPageConfig, | ||
| 55 | collectTaskName: '', | ||
| 56 | dataSourceGuid: '', | ||
| 57 | taskState: null | ||
| 58 | }); | ||
| 59 | const tableInfo = ref({ | ||
| 60 | id: 'data-source-table', | ||
| 61 | fields: [ | ||
| 62 | { label: '序号', type: 'index', width: TableColumnWidth.INDEX, align: 'center' }, | ||
| 63 | { label: '代码名称', field: '1', width: 140 }, | ||
| 64 | { label: '标准号', field: '2', width: 140 }, | ||
| 65 | { label: '标准名称', field: '3', width: 140 }, | ||
| 66 | { label: '启用状态', field: '4', width: 140 }, | ||
| 67 | { label: '创建时间', field: '5', width: 140 } | ||
| 68 | ], | ||
| 69 | data: [], | ||
| 70 | page: { | ||
| 71 | type: 'normal', | ||
| 72 | rows: 0, | ||
| 73 | ...page.value | ||
| 74 | }, | ||
| 75 | actionInfo: { | ||
| 76 | label: '操作', | ||
| 77 | type: 'btn', | ||
| 78 | width: 160, | ||
| 79 | btns: scope => { | ||
| 80 | let row = scope.row | ||
| 81 | return [ | ||
| 82 | { label: '编辑', value: 'edit' }, | ||
| 83 | { label: '删除', value: 'delete' }, | ||
| 84 | ] | ||
| 85 | } | ||
| 86 | }, | ||
| 87 | loading: false | ||
| 88 | }) | ||
| 89 | function tableBtnClick (scope, btn) { | ||
| 90 | |||
| 91 | } | ||
| 92 | function tablePageChange (info) { | ||
| 93 | page.value.curr = Number(info.curr); | ||
| 94 | page.value.limit = Number(info.limit); | ||
| 95 | // getTableData(); | ||
| 96 | } | ||
| 97 | function getTableData (params) { | ||
| 98 | |||
| 99 | } | ||
| 100 | function handleCreate () { | ||
| 101 | drawerInfo.value.visible = true; | ||
| 102 | drawerInfo.value.type = 'add'; | ||
| 103 | drawerInfo.value.header.title = '新增标准代码'; | ||
| 104 | drawerInfo.value.footer.visible = true; | ||
| 105 | } | ||
| 106 | |||
| 107 | // drawer form | ||
| 108 | const standardOptions = ref([]) | ||
| 109 | const publishingUnitCodeOptions = ref([]) | ||
| 110 | const formRef = ref() | ||
| 111 | const formItems: any = ref([ | ||
| 112 | { | ||
| 113 | label: '标准类型', | ||
| 114 | type: 'select', | ||
| 115 | placeholder: '请选择', | ||
| 116 | field: 'standardTypeCode', | ||
| 117 | default: '', | ||
| 118 | options: standardOptions, | ||
| 119 | clearable: true, | ||
| 120 | required: true | ||
| 121 | }, | ||
| 122 | { | ||
| 123 | label: '代码名称', | ||
| 124 | type: 'input', | ||
| 125 | placeholder: '请输入', | ||
| 126 | field: 'codeName', | ||
| 127 | default: '', | ||
| 128 | maxlength: 20, | ||
| 129 | clearable: true, | ||
| 130 | required: true | ||
| 131 | }, | ||
| 132 | { | ||
| 133 | label: '标准号', | ||
| 134 | type: 'input', | ||
| 135 | placeholder: '请输入', | ||
| 136 | field: 'standard', | ||
| 137 | default: '', | ||
| 138 | maxlength: 50, | ||
| 139 | clearable: true, | ||
| 140 | required: true | ||
| 141 | }, | ||
| 142 | { | ||
| 143 | label: '标准名称', | ||
| 144 | type: 'input', | ||
| 145 | placeholder: '请输入', | ||
| 146 | field: 'standardName', | ||
| 147 | default: '', | ||
| 148 | maxlength: 20, | ||
| 149 | clearable: true, | ||
| 150 | required: true | ||
| 151 | }, | ||
| 152 | { | ||
| 153 | label: '发布单位', | ||
| 154 | type: 'select', | ||
| 155 | placeholder: '请输入', | ||
| 156 | field: 'publishingUnitCode', | ||
| 157 | default: '', | ||
| 158 | options: publishingUnitCodeOptions, | ||
| 159 | clearable: true, | ||
| 160 | required: true | ||
| 161 | }, | ||
| 162 | { | ||
| 163 | label: '排序', | ||
| 164 | type: 'inputNumber', | ||
| 165 | placeholder: '请输入', | ||
| 166 | field: 'orderNum', | ||
| 167 | default: '', | ||
| 168 | maxlength: 2, | ||
| 169 | clearable: true, | ||
| 170 | required: true | ||
| 171 | }, | ||
| 172 | { | ||
| 173 | label: '启用状态', | ||
| 174 | type: 'switch', | ||
| 175 | field: 'bizState', | ||
| 176 | default: false | ||
| 177 | }, | ||
| 178 | { | ||
| 179 | label: '代码类型', | ||
| 180 | type: 'select', | ||
| 181 | placeholder: '请选择', | ||
| 182 | field: 'typeCode', | ||
| 183 | default: '1', | ||
| 184 | options: [ | ||
| 185 | { label: '列表结构', value: '1' }, | ||
| 186 | { label: '层级结构', value: '2' } | ||
| 187 | ], | ||
| 188 | clearable: true, | ||
| 189 | required: true | ||
| 190 | }, | ||
| 191 | { | ||
| 192 | label: '编码字段', | ||
| 193 | type: 'select', | ||
| 194 | placeholder: '请选择', | ||
| 195 | field: 'codeFields', | ||
| 196 | default: [], | ||
| 197 | options: [ | ||
| 198 | { label: 'code', value: 'code' }, | ||
| 199 | { label: 'name', value: 'name' } | ||
| 200 | ], | ||
| 201 | clearable: true, | ||
| 202 | required: true, | ||
| 203 | multiple: true | ||
| 204 | }, | ||
| 205 | { | ||
| 206 | label: '编码名称', | ||
| 207 | type: 'select', | ||
| 208 | placeholder: '请选择', | ||
| 209 | field: 'codeFieldName', | ||
| 210 | default: '', | ||
| 211 | options: [ | ||
| 212 | { label: 'code', value: 'code' }, | ||
| 213 | { label: 'name', value: 'name' } | ||
| 214 | ], | ||
| 215 | clearable: true, | ||
| 216 | required: true | ||
| 217 | }, | ||
| 218 | { | ||
| 219 | label: '层级结构', | ||
| 220 | type: 'input', | ||
| 221 | placeholder: '请输入', | ||
| 222 | field: 'hierarchy', | ||
| 223 | default: '', | ||
| 224 | clearable: true, | ||
| 225 | required: true | ||
| 226 | } | ||
| 227 | ]) | ||
| 228 | const formRules = ref({ | ||
| 229 | |||
| 230 | }) | ||
| 231 | const formInfo = ref({ | ||
| 232 | type: 'form', | ||
| 233 | title: '', | ||
| 234 | col: 'span', | ||
| 235 | formInfo: { | ||
| 236 | id: 'add-dict-form', | ||
| 237 | col: 'col2', | ||
| 238 | items: formItems.value, | ||
| 239 | formRules: formRules.value | ||
| 240 | } | ||
| 241 | }) | ||
| 242 | const formTable = reactive({ | ||
| 243 | type: "table", | ||
| 244 | title: "定义表结构", | ||
| 245 | col: 'no-margin', | ||
| 246 | style: { | ||
| 247 | height: 'calc(100% - 234px)' | ||
| 248 | }, | ||
| 249 | tableInfo: { | ||
| 250 | id: "role-authority-table", | ||
| 251 | multiple: true, | ||
| 252 | minHeight: 'unset', | ||
| 253 | maxHeight: '100%', | ||
| 254 | fields: [ | ||
| 255 | { label: '序号', type: 'index', width: 56, align: 'center' }, | ||
| 256 | { label: '字段名称', field: 'fieldName', width: 140, type: 'edit', customClass: 'edit-colum'} | ||
| 257 | ], | ||
| 258 | data: [{ fieldName: '1', index: 0}], | ||
| 259 | showPage: false, | ||
| 260 | actionInfo: { | ||
| 261 | show: true, | ||
| 262 | label: "操作", | ||
| 263 | type: "btn", | ||
| 264 | width: 60, | ||
| 265 | fixed: 'right', | ||
| 266 | btns: [{ label: "删除", value: "remove" }] | ||
| 267 | }, | ||
| 268 | editInfo: { | ||
| 269 | fieldName: { | ||
| 270 | field: 'fieldName', | ||
| 271 | label: '字段名称', | ||
| 272 | type: 'input', | ||
| 273 | clearable: true, | ||
| 274 | maxlength: 20 | ||
| 275 | } | ||
| 276 | }, | ||
| 277 | readonly: false, | ||
| 278 | col: 'auto-height', | ||
| 279 | style: { height: 'calc(100% - 40px)'}, | ||
| 280 | loading: false | ||
| 281 | }, | ||
| 282 | tableTool: { | ||
| 283 | col: 'float-right', | ||
| 284 | visible: true, | ||
| 285 | btns: [ | ||
| 286 | { label: "新增行", value: "tableAdd", type: 'primary' }, | ||
| 287 | { label: "批量删除", value: "tableDelete" }, | ||
| 288 | ] | ||
| 289 | }, | ||
| 290 | }) | ||
| 291 | // 新增drawer | ||
| 292 | const drawerInfo = ref({ | ||
| 293 | visible: false, | ||
| 294 | direction: 'rtl', | ||
| 295 | size: 550, | ||
| 296 | header: { | ||
| 297 | title: '新增标准代码', | ||
| 298 | }, | ||
| 299 | type: '', | ||
| 300 | container: { | ||
| 301 | contents: [formInfo.value, formTable], | ||
| 302 | }, | ||
| 303 | footer: { | ||
| 304 | visible: true, | ||
| 305 | btns: [ | ||
| 306 | { type: 'default', label: '取消', value: 'cancel' }, | ||
| 307 | { type: 'primary', label: '保存', value: 'save' }, | ||
| 308 | { type: 'primary', label: '保存并添加数据', value: 'saveAndAdd', visible: true } | ||
| 309 | ] | ||
| 310 | } | ||
| 311 | }) | ||
| 312 | async function drawerBtnClick (btn, info) { | ||
| 313 | |||
| 314 | } | ||
| 315 | function drawerTableToolBtnClick (btn, data) { | ||
| 316 | console.log(btn, data) | ||
| 317 | if (btn.value === 'tableAdd') { | ||
| 318 | // 定义表结构新增行 | ||
| 319 | let rowInfo = { fieldName: '' } | ||
| 320 | formTable.tableInfo.data.push(rowInfo) | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 324 | onMounted(() => { | ||
| 325 | getParamsList({ dictType: '标准类型'}).then((res:any) => { | ||
| 326 | if (res.code === proxy.$passCode) { | ||
| 327 | const data = res.data || [] | ||
| 328 | treeInfo.data = data | ||
| 329 | standardOptions.value = data | ||
| 330 | // 默认展开第一个 | ||
| 331 | if (data.length === 0) return | ||
| 332 | let params = { | ||
| 333 | pageIndex: 1, | ||
| 334 | pageSize: 100, | ||
| 335 | standardTypeCode: data[0].value, | ||
| 336 | codeName: '标准类型' | ||
| 337 | } | ||
| 338 | getStandardCodeList(params) | ||
| 339 | } | ||
| 340 | }) | ||
| 341 | getParamsList({ dictType: '发布单位' }).then((res:any) => { | ||
| 342 | if (res.code === proxy.$passCode) { | ||
| 343 | const data = res.data || [] | ||
| 344 | publishingUnitCodeOptions.value = data | ||
| 345 | } | ||
| 346 | }) | ||
| 347 | }) | ||
| 348 | </script> | ||
| 349 | |||
| 350 | <template> | ||
| 351 | <div class="container_wrap full flex"> | ||
| 352 | <div class="aside_wrap"> | ||
| 353 | <div class="aside_title">标准代码列表</div> | ||
| 354 | <Tree :treeInfo="treeInfo" @nodeClick="nodeClick" /> | ||
| 355 | </div> | ||
| 356 | <div class="main_wrap"> | ||
| 357 | <div class="table_tool_wrap"> | ||
| 358 | <div class="tools_btns"> | ||
| 359 | <el-button type="primary" @click="handleCreate">新建</el-button> | ||
| 360 | <el-button>批量删除</el-button> | ||
| 361 | <el-button>批量导入</el-button> | ||
| 362 | </div> | ||
| 363 | <el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="代码名称搜索" | ||
| 364 | :suffix-icon="Search" clearable @change="val => getFirstPageData()" /> | ||
| 365 | </div> | ||
| 366 | <div class="table_panel_wrap"> | ||
| 367 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" | ||
| 368 | /> | ||
| 369 | </div> | ||
| 370 | </div> | ||
| 371 | <Drawer | ||
| 372 | :drawerInfo="drawerInfo" | ||
| 373 | @drawerBtnClick="drawerBtnClick" | ||
| 374 | ref="drawerRef" | ||
| 375 | @drawerTableToolBtnClick="drawerTableToolBtnClick" | ||
| 376 | > | ||
| 377 | <!-- <Form ref="formRef" | ||
| 378 | :itemList="formItems" | ||
| 379 | formId="basic-info-form" | ||
| 380 | :rules="formRules" | ||
| 381 | /> --> | ||
| 382 | </Drawer> | ||
| 383 | </div> | ||
| 384 | </template> | ||
| 385 | |||
| 386 | <style scoped lang="scss"> | ||
| 387 | .container_wrap { | ||
| 388 | |||
| 389 | .aside_wrap { | ||
| 390 | width: 200px; | ||
| 391 | } | ||
| 392 | |||
| 393 | .main_wrap { | ||
| 394 | padding: 10px 20px; | ||
| 395 | |||
| 396 | |||
| 397 | :deep(.el-tabs) { | ||
| 398 | height: 100%; | ||
| 399 | |||
| 400 | .el-tabs__header { | ||
| 401 | margin-bottom: 0; | ||
| 402 | } | ||
| 403 | |||
| 404 | .el-tabs__item { | ||
| 405 | height: 32px; | ||
| 406 | padding: 0px; | ||
| 407 | width: 144px; | ||
| 408 | |||
| 409 | &:last-child { | ||
| 410 | width: 130px; | ||
| 411 | } | ||
| 412 | } | ||
| 413 | |||
| 414 | .el-tabs__content { | ||
| 415 | height: calc(100% - 32px); | ||
| 416 | } | ||
| 417 | |||
| 418 | .el-tab-pane { | ||
| 419 | padding: 0px 16px; | ||
| 420 | height: 100%; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | } | ||
| 426 | |||
| 427 | .tree_panel { | ||
| 428 | height: calc(100% - 36px); | ||
| 429 | padding-top: 0; | ||
| 430 | |||
| 431 | :deep(.el-tree) { | ||
| 432 | margin: 0; | ||
| 433 | overflow: hidden auto; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | .table_tool_wrap { | ||
| 438 | display: flex; | ||
| 439 | flex-direction: column; | ||
| 440 | |||
| 441 | .el-input { | ||
| 442 | width: 230px; | ||
| 443 | height: 32px; | ||
| 444 | } | ||
| 445 | |||
| 446 | :deep(.el-input) { | ||
| 447 | .el-input__suffix-inner { | ||
| 448 | flex-direction: row-reverse; | ||
| 449 | -webkit-flex-direction: row-reverse; | ||
| 450 | display: flex; | ||
| 451 | } | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | .table_panel_wrap { | ||
| 456 | height: calc(100% - 44px); | ||
| 457 | } | ||
| 458 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/data_meta/standard-import.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: metadataStandardImport | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="metadataStandardImport"> | ||
| 6 | import { ref } from "vue"; | ||
| 7 | import { useRoute, useRouter } from "vue-router" | ||
| 8 | import useUserStore from "@/store/modules/user"; | ||
| 9 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 10 | import Tabs from '@/components/Tabs/index.vue' | ||
| 11 | import Table from '@/components/Table/index.vue' | ||
| 12 | import Dialog from '@/components/Dialog/index.vue' | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { download, downFileByBob, downFile } from '@/utils/common' | ||
| 15 | import { | ||
| 16 | addImportData, | ||
| 17 | deleteImportData, | ||
| 18 | getImportData, | ||
| 19 | exportDictionary, | ||
| 20 | exportCollectTask, | ||
| 21 | // getImageContent | ||
| 22 | } from '@/api/modules/queryService'; | ||
| 23 | import { | ||
| 24 | parseAndDecodeUrl, | ||
| 25 | getDownFileSignByUrl, | ||
| 26 | obsDownloadRequest | ||
| 27 | } from '@/api/modules/obsService'; | ||
| 28 | import { | ||
| 29 | getDictionaryTree | ||
| 30 | } from '@/api/modules/dataInventory'; | ||
| 31 | import { commonPageConfig } from '@/utils/enum'; | ||
| 32 | import * as XLSX from 'xlsx'; | ||
| 33 | |||
| 34 | const { proxy } = getCurrentInstance() as any; | ||
| 35 | |||
| 36 | const userStore = useUserStore() | ||
| 37 | const route = useRoute() | ||
| 38 | const router = useRouter() | ||
| 39 | /** 2表示资产目录的。3是主数据; 4是元数据导入 */ | ||
| 40 | const isfileImport = route.query.isfileImport | ||
| 41 | const userData = JSON.parse(userStore.userData) | ||
| 42 | const cacheStore = useCatchStore() | ||
| 43 | const standardSetList = ref([]) | ||
| 44 | const standardSetGuid = ref('') | ||
| 45 | const dictionaryList = ref([]) | ||
| 46 | const dictionaryGuid = ref('') | ||
| 47 | const tabsActiveName = ref('') | ||
| 48 | const uploadSetting: any = ref([]) | ||
| 49 | const importType = ref('') | ||
| 50 | const defaulttabs = [ | ||
| 51 | // { label: '标准集导入', name: 'standard' }, | ||
| 52 | // { label: '字段标准导入', name: 'field' }, | ||
| 53 | // { label: '命名标准导入', name: 'naming' }, | ||
| 54 | { label: '数据字典导入', name: 'dictionary' }, | ||
| 55 | // { label: '质量模型导入', name: 'qualityModelGroup' }, | ||
| 56 | // { label: '质量规则导入', name: 'qualityRule' }, | ||
| 57 | ] | ||
| 58 | const importTabs = [ | ||
| 59 | { label: '导入文件数据', name: 'importFile' }, | ||
| 60 | // { label: '质量模型导入', name: 'qualityModelGroup' }, | ||
| 61 | // { label: '质量规则导入', name: 'qualityRule' }, | ||
| 62 | ] | ||
| 63 | const tabsInfo = ref({ | ||
| 64 | activeName: '', | ||
| 65 | tabs: isfileImport ? importTabs : defaulttabs | ||
| 66 | }) | ||
| 67 | |||
| 68 | const currTableData: any = ref<Object>({}); | ||
| 69 | const page = ref(commonPageConfig); | ||
| 70 | const selectRowData = ref([]) | ||
| 71 | const tableInfo = ref({ | ||
| 72 | id: 'data-source-table', | ||
| 73 | multiple: true, | ||
| 74 | fields: [ | ||
| 75 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 76 | { label: "文件名称", field: "fileName", width: 240, }, | ||
| 77 | { label: "状态", field: "importState", type: 'tag', width: 110, align: 'center' }, | ||
| 78 | { label: "导入结果", field: "importMessage", width: 280 }, | ||
| 79 | { label: "导入时间", field: "createTime", width: 180 }, | ||
| 80 | ], | ||
| 81 | data: [], | ||
| 82 | page: { | ||
| 83 | type: "normal", | ||
| 84 | rows: 0, | ||
| 85 | ...page.value, | ||
| 86 | }, | ||
| 87 | actionInfo: { | ||
| 88 | label: "操作", | ||
| 89 | type: "btn", | ||
| 90 | width: 220, | ||
| 91 | fixed: 'right', | ||
| 92 | btns: (scope) => { | ||
| 93 | const row = scope.row | ||
| 94 | let btnsArr = [ | ||
| 95 | { label: '下载文件', value: 'export_file' }, | ||
| 96 | { label: '删除', value: 'delete' } | ||
| 97 | ] | ||
| 98 | if (row.importState != 0 && row.importState != 1) { | ||
| 99 | btnsArr.splice(1, 0, { label: '下载异常数据', value: 'export_abnormal_data' }) | ||
| 100 | } | ||
| 101 | return btnsArr | ||
| 102 | }, | ||
| 103 | }, | ||
| 104 | loading: false | ||
| 105 | }) | ||
| 106 | |||
| 107 | const uploadFiles = ref([]) | ||
| 108 | const uploadSteps: any = ref([]) | ||
| 109 | const uploadInfo = ref({ | ||
| 110 | type: 'upload', | ||
| 111 | title: '', | ||
| 112 | col: '', | ||
| 113 | uploadInfo: { | ||
| 114 | id: 'upload-file-form', | ||
| 115 | type: 'panel', | ||
| 116 | steps: [], | ||
| 117 | extraParams: {dictionaryGuid: 'xx'}, | ||
| 118 | }, | ||
| 119 | }) | ||
| 120 | |||
| 121 | const dialogInfo: any = ref({ | ||
| 122 | visible: false, | ||
| 123 | size: 560, | ||
| 124 | direction: "column", | ||
| 125 | header: { | ||
| 126 | title: "新建", | ||
| 127 | }, | ||
| 128 | type: 'upload', | ||
| 129 | contents: [ | ||
| 130 | uploadInfo.value | ||
| 131 | ], | ||
| 132 | footer: { | ||
| 133 | visible: true, | ||
| 134 | btns: [ | ||
| 135 | { type: "default", label: "取消", value: "cancel" }, | ||
| 136 | { type: "primary", loading: false, label: "开始导入", value: "submit" }, | ||
| 137 | ], | ||
| 138 | }, | ||
| 139 | }) | ||
| 140 | |||
| 141 | // // 获取所有数据字典 | ||
| 142 | const getDictList = () => { | ||
| 143 | const params = { | ||
| 144 | paramCode: '数据字典类型' | ||
| 145 | } | ||
| 146 | getDictionaryTree(params).then((res: any) => { | ||
| 147 | if (res.code == proxy.$passCode) { | ||
| 148 | const data = res.data ?? [] | ||
| 149 | const treeList = data.filter(item => item.children && item.children.length) | ||
| 150 | dictionaryList.value = treeList | ||
| 151 | } else { | ||
| 152 | ElMessage({ | ||
| 153 | type: 'error', | ||
| 154 | message: res.msg, | ||
| 155 | }) | ||
| 156 | } | ||
| 157 | }) | ||
| 158 | } | ||
| 159 | |||
| 160 | const tabsChange = (name) => { | ||
| 161 | tabsActiveName.value = name | ||
| 162 | let info: any = { | ||
| 163 | type: name | ||
| 164 | } | ||
| 165 | if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') { | ||
| 166 | info.standardSetGuid = standardSetGuid.value | ||
| 167 | } else if (tabsActiveName.value == 'dictionary') { | ||
| 168 | info.dictionaryGuid = dictionaryGuid.value | ||
| 169 | } else if (tabsActiveName.value == 'importFile') { | ||
| 170 | |||
| 171 | } | ||
| 172 | cacheStore.setCatch('uploadSetting', info) | ||
| 173 | setUploadInfo() | ||
| 174 | } | ||
| 175 | |||
| 176 | const getFirstPageData = () => { | ||
| 177 | page.value.curr = 1 | ||
| 178 | toSearch({}) | ||
| 179 | |||
| 180 | console.log('store', cacheStore.getCatch('uploadSetting')) | ||
| 181 | } | ||
| 182 | |||
| 183 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 184 | let params: any = Object.keys(val).length ? { ...val } : {} | ||
| 185 | params.pageIndex = page.value.curr; | ||
| 186 | params.pageSize = page.value.limit; | ||
| 187 | params.staffGuid = userData.staffGuid; | ||
| 188 | params.importType = importType.value; | ||
| 189 | |||
| 190 | params.bizGuid = route.query.bizGuid || '' | ||
| 191 | getTableData(params); | ||
| 192 | }; | ||
| 193 | |||
| 194 | const getTableData = (params) => { | ||
| 195 | tableInfo.value.loading = true | ||
| 196 | getImportData(params).then((res: any) => { | ||
| 197 | if (res.code == proxy.$passCode) { | ||
| 198 | const data = res.data || {} | ||
| 199 | tableInfo.value.data = data.records || [] | ||
| 200 | tableInfo.value.page.limit = data.pageSize | ||
| 201 | tableInfo.value.page.curr = data.pageIndex | ||
| 202 | tableInfo.value.page.rows = data.totalRows | ||
| 203 | } else { | ||
| 204 | ElMessage({ | ||
| 205 | type: 'error', | ||
| 206 | message: res.msg, | ||
| 207 | }) | ||
| 208 | } | ||
| 209 | tableInfo.value.loading = false | ||
| 210 | }).catch(xhr => { | ||
| 211 | tableInfo.value.loading = false | ||
| 212 | }) | ||
| 213 | }; | ||
| 214 | |||
| 215 | const tableSelectionChange = (val) => { | ||
| 216 | selectRowData.value = val.map(item => item.guid); | ||
| 217 | }; | ||
| 218 | |||
| 219 | const tablePageChange = (info) => { | ||
| 220 | page.value.curr = Number(info.curr); | ||
| 221 | page.value.limit = Number(info.limit); | ||
| 222 | toSearch({}); | ||
| 223 | }; | ||
| 224 | |||
| 225 | const tableBtnClick = async (scope, btn) => { | ||
| 226 | const type = btn.value; | ||
| 227 | const row = scope.row; | ||
| 228 | currTableData.value = row; | ||
| 229 | if (type == "export_file") { | ||
| 230 | const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.filePath).fileName); | ||
| 231 | if (!refSignInfo?.data) { | ||
| 232 | refSignInfo?.msg && ElMessage.error(refSignInfo?.msg); | ||
| 233 | return; | ||
| 234 | } | ||
| 235 | obsDownloadRequest(refSignInfo?.data).then((res: any) => { | ||
| 236 | if (res && !res.msg) { | ||
| 237 | downFileByBob(res, row.fileName); | ||
| 238 | } else { | ||
| 239 | res?.msg && ElMessage.error(res?.msg); | ||
| 240 | } | ||
| 241 | }); | ||
| 242 | //downFile(row.filePath, row.fileName) | ||
| 243 | } else if (type == 'export_abnormal_data') { | ||
| 244 | //downFile(row.errorFilePath, '') | ||
| 245 | const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.errorFilePath).fileName); | ||
| 246 | if (!refSignInfo?.data) { | ||
| 247 | refSignInfo?.msg && ElMessage.error(refSignInfo?.msg); | ||
| 248 | return; | ||
| 249 | } | ||
| 250 | obsDownloadRequest(refSignInfo?.data).then((res: any) => { | ||
| 251 | if (res && !res.msg) { | ||
| 252 | let name = row.errorFilePath; | ||
| 253 | let fileName = name ? name.substring(name.lastIndexOf('/') + 1) : '' | ||
| 254 | downFileByBob(res, fileName); | ||
| 255 | } else { | ||
| 256 | res?.msg && ElMessage.error(res?.msg); | ||
| 257 | } | ||
| 258 | }); | ||
| 259 | } else if (type == "delete") { | ||
| 260 | open("此操作将永久删除, 是否继续?", "warning"); | ||
| 261 | } | ||
| 262 | }; | ||
| 263 | |||
| 264 | const batching = (type) => { | ||
| 265 | if (type == 'import') { | ||
| 266 | dialogInfo.value.header.title = '导入数据' | ||
| 267 | dialogInfo.value.type = 'upload' | ||
| 268 | dialogInfo.value.size = 560 | ||
| 269 | uploadFiles.value = [] | ||
| 270 | // if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') { | ||
| 271 | // uploadSteps.value[0].selectInfo.options = standardSetList.value | ||
| 272 | // } else if (tabsActiveName.value == 'dictionary') { | ||
| 273 | // uploadSteps.value[0].cascaderInfo.options = dictionaryList.value | ||
| 274 | // } | ||
| 275 | uploadInfo.value.uploadInfo.steps = uploadSteps.value | ||
| 276 | uploadSetting.value.forEach(item => item.value = '') | ||
| 277 | sheetNameList.value = [] | ||
| 278 | const content: any = [uploadInfo.value] | ||
| 279 | dialogInfo.value.contents = content | ||
| 280 | dialogInfo.value.visible = true | ||
| 281 | } else if (type == 'delete') { | ||
| 282 | if (selectRowData.value.length == 0) { | ||
| 283 | ElMessage({ | ||
| 284 | type: 'error', | ||
| 285 | message: '请选择需要删除的数据', | ||
| 286 | }) | ||
| 287 | return | ||
| 288 | } | ||
| 289 | open("此操作将永久删除, 是否继续?", "warning", true); | ||
| 290 | } else if (type === 'importFile') { | ||
| 291 | if (isfileImport == '2' || isfileImport == '4') { | ||
| 292 | dialogInfo.value.header.title = '导入数据' | ||
| 293 | dialogInfo.value.type = 'upload' | ||
| 294 | dialogInfo.value.size = isfileImport == '4' ? 560 : 560; | ||
| 295 | uploadFiles.value = [] | ||
| 296 | uploadInfo.value.uploadInfo.steps = uploadSteps.value | ||
| 297 | const content: any = [uploadInfo.value] | ||
| 298 | dialogInfo.value.contents = content | ||
| 299 | dialogInfo.value.visible = true | ||
| 300 | } else { | ||
| 301 | router.push({ | ||
| 302 | name: "importData", | ||
| 303 | query: route.query | ||
| 304 | }) | ||
| 305 | } | ||
| 306 | } | ||
| 307 | }; | ||
| 308 | |||
| 309 | const open = (msg, type, isBatch = false) => { | ||
| 310 | ElMessageBox.confirm(msg, "提示", { | ||
| 311 | confirmButtonText: "确定", | ||
| 312 | cancelButtonText: "取消", | ||
| 313 | type: type, | ||
| 314 | }).then(() => { | ||
| 315 | let guids = [currTableData.value.guid] | ||
| 316 | if (isBatch) { | ||
| 317 | guids = selectRowData.value | ||
| 318 | } | ||
| 319 | deleteImportData(guids).then((res: any) => { | ||
| 320 | if (res.code == proxy.$passCode) { | ||
| 321 | getFirstPageData(); | ||
| 322 | ElMessage({ | ||
| 323 | type: "success", | ||
| 324 | message: "删除成功", | ||
| 325 | }); | ||
| 326 | } else { | ||
| 327 | ElMessage({ | ||
| 328 | type: "error", | ||
| 329 | message: res.msg, | ||
| 330 | }); | ||
| 331 | } | ||
| 332 | }); | ||
| 333 | }); | ||
| 334 | }; | ||
| 335 | |||
| 336 | const sheetNameList = ref([]) | ||
| 337 | const onUpload = (file, fileList) => { | ||
| 338 | // console.log('file', file) | ||
| 339 | uploadFiles.value = fileList | ||
| 340 | const reader = new FileReader() | ||
| 341 | reader.onload = function (e) { | ||
| 342 | let data = new Uint8Array(e.target.result) | ||
| 343 | let wb = XLSX.read(data, { type: 'array', raw: false, cellDates: true }) | ||
| 344 | console.log('wb', wb) | ||
| 345 | sheetNameList.value = wb.SheetNames | ||
| 346 | } | ||
| 347 | reader.readAsArrayBuffer(file.raw) | ||
| 348 | } | ||
| 349 | |||
| 350 | const uploadBtnClick = (btn) => { | ||
| 351 | exportData() | ||
| 352 | } | ||
| 353 | |||
| 354 | const cascaderChange = (val) => { | ||
| 355 | dictionaryGuid.value = val ? val.at(-1) : '' | ||
| 356 | } | ||
| 357 | |||
| 358 | const selectChange = (val) => { | ||
| 359 | standardSetGuid.value = val | ||
| 360 | } | ||
| 361 | |||
| 362 | const exportData = (ids: any = null) => { | ||
| 363 | if (tabsActiveName.value == 'standard') { | ||
| 364 | const fieldTemplate = "/files/set.xlsx"; | ||
| 365 | downFile(fieldTemplate, '标准集模板.xlsx') | ||
| 366 | } else if (tabsActiveName.value == 'field') { | ||
| 367 | const fieldTemplate = "/files/field.xlsx"; | ||
| 368 | downFile(fieldTemplate, '字段标准模板.xlsx') | ||
| 369 | } else if (tabsActiveName.value == 'naming') { | ||
| 370 | const namingTemplate = "/files/naming.xlsx"; | ||
| 371 | downFile(namingTemplate, '命名标准模板.xlsx') | ||
| 372 | } else if (tabsActiveName.value == 'dictionary') { | ||
| 373 | const params = { | ||
| 374 | guid: dictionaryGuid.value | ||
| 375 | } | ||
| 376 | exportDictionary(params).then((res: any) => { | ||
| 377 | if (res && !res.msg) { | ||
| 378 | download(res, '数据字典模板.xlsx', 'excel'); | ||
| 379 | } else { | ||
| 380 | res?.msg && ElMessage.error(res?.msg); | ||
| 381 | } | ||
| 382 | }); | ||
| 383 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '4') { | ||
| 384 | exportCollectTask({ | ||
| 385 | importTypes: [ | ||
| 386 | "0042" | ||
| 387 | ] | ||
| 388 | }).then((res: any) => { | ||
| 389 | if (res && !res.msg) { | ||
| 390 | download(res, '元数据模板.xlsx', 'excel'); | ||
| 391 | } else { | ||
| 392 | res?.msg && ElMessage.error(res?.msg); | ||
| 393 | } | ||
| 394 | }); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | const importData = (info) => { | ||
| 399 | let params = new FormData() | ||
| 400 | if (uploadFiles.value.length == 0) { | ||
| 401 | ElMessage({ | ||
| 402 | type: 'error', | ||
| 403 | message: '请选择上传文件' | ||
| 404 | }) | ||
| 405 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 406 | return | ||
| 407 | } | ||
| 408 | let sheetPass = uploadSetting.value.some(item => item.value) | ||
| 409 | if (!sheetPass) { | ||
| 410 | ElMessage.error('导入失败,没有导入数据') | ||
| 411 | dialogInfo.value.visible = false; | ||
| 412 | return | ||
| 413 | } | ||
| 414 | let sheetNum = uploadSetting.value.filter(item => item.value)['length'] | ||
| 415 | if (sheetNum > 30) { | ||
| 416 | ElMessage.error('最多只能导入30个sheet页的数据。') | ||
| 417 | return | ||
| 418 | } | ||
| 419 | let paramUrl = ''; | ||
| 420 | uploadFiles.value.forEach((item: any, index: number) => { | ||
| 421 | params.append("file", item.raw); | ||
| 422 | }); | ||
| 423 | let sheetMaps = {} | ||
| 424 | uploadSetting.value.forEach(item => { | ||
| 425 | if (item.value) { | ||
| 426 | sheetMaps[item.value] = item.standardGuid | ||
| 427 | } | ||
| 428 | }) | ||
| 429 | sheetMaps = encodeURIComponent(JSON.stringify(sheetMaps)) | ||
| 430 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-batch-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}&sheetMaps=${sheetMaps}` | ||
| 431 | dialogInfo.value.footer.btns[1].loading = true; | ||
| 432 | addImportData(paramUrl, params).then((res: any) => { | ||
| 433 | dialogInfo.value.footer.btns[1].loading = false; | ||
| 434 | if (res.code == proxy.$passCode) { | ||
| 435 | getFirstPageData(); | ||
| 436 | ElMessage({ | ||
| 437 | type: "success", | ||
| 438 | message: '导入成功', | ||
| 439 | }); | ||
| 440 | dialogInfo.value.visible = false; | ||
| 441 | } else { | ||
| 442 | ElMessage({ | ||
| 443 | type: "error", | ||
| 444 | message: res.msg, | ||
| 445 | }); | ||
| 446 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 447 | } | ||
| 448 | }).catch(() => { | ||
| 449 | dialogInfo.value.footer.btns[1].loading = false; | ||
| 450 | }) | ||
| 451 | } | ||
| 452 | |||
| 453 | const dialogBtnClick = (btn, info) => { | ||
| 454 | if (btn.value == 'submit') { | ||
| 455 | // dialogInfo.value.footer.btns.map((item: any) => item.disabled = true) | ||
| 456 | if (dialogInfo.value.type == 'upload') { | ||
| 457 | if (tabsActiveName.value == 'dictionary') { | ||
| 458 | importData({ bizGuid: dictionaryGuid.value }) | ||
| 459 | } else { | ||
| 460 | importData(info) | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } else if (btn.value == 'cancel') { | ||
| 464 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 465 | nextTick(() => { | ||
| 466 | dialogInfo.value.visible = false; | ||
| 467 | }) | ||
| 468 | }; | ||
| 469 | } | ||
| 470 | |||
| 471 | const setUploadInfo = () => { | ||
| 472 | importType.value = '0101' | ||
| 473 | tabsInfo.value.activeName = tabsActiveName.value | ||
| 474 | getFirstPageData() | ||
| 475 | uploadSteps.value = [ | ||
| 476 | { | ||
| 477 | title: '1、选择准备好的文件导入', | ||
| 478 | type: 'btn_upload', | ||
| 479 | uploadInfo: { | ||
| 480 | action: '', | ||
| 481 | auto: false, | ||
| 482 | cover: true, | ||
| 483 | fileList: [], | ||
| 484 | accept: '.xlsx, .xls', | ||
| 485 | tips: '当前支持xls、xlsx文件,支持一个文件多个sheet批量导入,一次最多只能导入30个sheet页数据。' | ||
| 486 | } | ||
| 487 | } | ||
| 488 | ] | ||
| 489 | } | ||
| 490 | |||
| 491 | function deleteFile () { | ||
| 492 | sheetNameList.value = [] | ||
| 493 | uploadSetting.value.forEach(item => item.value = null) | ||
| 494 | } | ||
| 495 | |||
| 496 | onActivated(() => { | ||
| 497 | let list = cacheStore.getCatch('uploadSetting') || [] | ||
| 498 | uploadSetting.value = list.map(item => { | ||
| 499 | item.value = null | ||
| 500 | return item | ||
| 501 | }) | ||
| 502 | console.log('uploadSetting', uploadSetting.value) | ||
| 503 | setUploadInfo() | ||
| 504 | }) | ||
| 505 | |||
| 506 | </script> | ||
| 507 | |||
| 508 | <template> | ||
| 509 | <div class="container_wrap"> | ||
| 510 | <!-- <Tabs v-if="!isfileImport" :tabs-info="tabsInfo" @tabChange="tabsChange" /> --> | ||
| 511 | <div class="table_tool_wrap"> | ||
| 512 | <div class="tools_btns"> | ||
| 513 | <el-button type="primary" @click="batching('import')" v-if="tabsActiveName !== 'importFile'" | ||
| 514 | v-preReClick>批量导入</el-button> | ||
| 515 | <el-button type="primary" @click="batching('importFile')" v-if="tabsActiveName == 'importFile'" | ||
| 516 | v-preReClick>文件导入</el-button> | ||
| 517 | <el-button @click="batching('delete')" v-preReClick>批量删除</el-button> | ||
| 518 | <el-button @click="getFirstPageData" v-preReClick>刷新结果</el-button> | ||
| 519 | </div> | ||
| 520 | <span class="tips_text">请及时刷新查看最终结果</span> | ||
| 521 | </div> | ||
| 522 | <div class="table_panel_wrap" :style="{ height: !isfileImport ? 'calc(100% - 71px)' : 'calc(100% - 44px)' }"> | ||
| 523 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange" | ||
| 524 | @tablePageChange="tablePageChange" /> | ||
| 525 | </div> | ||
| 526 | <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @onUpload="onUpload" @uploadBtnClick="uploadBtnClick" | ||
| 527 | @cascaderChange="cascaderChange" @selectChange="selectChange" @deleteFile="deleteFile"> | ||
| 528 | <div style="overflow: auto;"> | ||
| 529 | <div class="title" style="color:#333;margin:20px 0 10px">2、导入前请先导入文件的sheet与标准做对应</div> | ||
| 530 | <el-table :data="uploadSetting" border height="310"> | ||
| 531 | <el-table-column type="index" label="序号" width="55" align="center"/> | ||
| 532 | <el-table-column label="代码名称" prop="standardName"></el-table-column> | ||
| 533 | <el-table-column label="选择sheet页"> | ||
| 534 | <template #default="scope"> | ||
| 535 | <el-select v-model="scope.row.value" placeholder="请选择" style="width:200px" clearable> | ||
| 536 | <el-option v-for="item,i in sheetNameList" :label="item" :value="item" :key="i"></el-option> | ||
| 537 | </el-select> | ||
| 538 | </template> | ||
| 539 | </el-table-column> | ||
| 540 | </el-table> | ||
| 541 | </div> | ||
| 542 | </Dialog> | ||
| 543 | </div> | ||
| 544 | </template> | ||
| 545 | |||
| 546 | <style lang="scss" scoped> | ||
| 547 | .container_wrap { | ||
| 548 | padding: 0; | ||
| 549 | |||
| 550 | :deep(.el-tabs) { | ||
| 551 | |||
| 552 | .el-tabs__header { | ||
| 553 | margin-bottom: 0; | ||
| 554 | } | ||
| 555 | |||
| 556 | .el-tabs__item { | ||
| 557 | height: 32px; | ||
| 558 | |||
| 559 | &:nth-child(2) { | ||
| 560 | padding-left: 16px; | ||
| 561 | } | ||
| 562 | |||
| 563 | &:last-child { | ||
| 564 | padding-right: 16px; | ||
| 565 | } | ||
| 566 | |||
| 567 | &::after { | ||
| 568 | content: ''; | ||
| 569 | width: 100%; | ||
| 570 | height: 2px; | ||
| 571 | background-color: transparent; | ||
| 572 | position: absolute; | ||
| 573 | left: 0; | ||
| 574 | bottom: 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | &.is-active { | ||
| 578 | &::after { | ||
| 579 | background-color: var(--el-color-primary); | ||
| 580 | } | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | .el-tabs__active-bar { | ||
| 585 | display: none; | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | .table_tool_wrap { | ||
| 590 | padding: 0 16px; | ||
| 591 | display: flex; | ||
| 592 | align-items: center; | ||
| 593 | |||
| 594 | .tips_text { | ||
| 595 | margin-left: 16px; | ||
| 596 | font-size: 14px; | ||
| 597 | color: #b2b2b2; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | .table_panel_wrap { | ||
| 602 | padding: 0 16px; | ||
| 603 | height: calc(100% - 71px); | ||
| 604 | } | ||
| 605 | |||
| 606 | } | ||
| 607 | </style> | ||
| 608 | <style lang="scss"> | ||
| 609 | .upload_panel_wrap .upload_panel .file_panel .file_item .file_btn { | ||
| 610 | word-break: keep-all; | ||
| 611 | } | ||
| 612 | .upload_panel_wrap .upload_step_panel .upload_panel { | ||
| 613 | padding-top: 42px!important; | ||
| 614 | } | ||
| 615 | </style> |
src/views/data_meta/standard-meta-import.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: standardMetaImport | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="standardMetaImport"> | ||
| 6 | import { ref } from "vue"; | ||
| 7 | import { useRoute, useRouter } from "vue-router" | ||
| 8 | import useUserStore from "@/store/modules/user"; | ||
| 9 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 10 | import Tabs from '@/components/Tabs/index.vue' | ||
| 11 | import Table from '@/components/Table/index.vue' | ||
| 12 | import Dialog from '@/components/Dialog/index.vue' | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { download, downFileByBob, downFile } from '@/utils/common' | ||
| 15 | import { | ||
| 16 | addImportData, | ||
| 17 | deleteImportData, | ||
| 18 | getImportData, | ||
| 19 | exportDictionary, | ||
| 20 | exportCollectTask, | ||
| 21 | // getImageContent | ||
| 22 | } from '@/api/modules/queryService'; | ||
| 23 | import { | ||
| 24 | parseAndDecodeUrl, | ||
| 25 | getDownFileSignByUrl, | ||
| 26 | obsDownloadRequest | ||
| 27 | } from '@/api/modules/obsService'; | ||
| 28 | import { | ||
| 29 | getDictionaryTree | ||
| 30 | } from '@/api/modules/dataInventory'; | ||
| 31 | import { commonPageConfig } from '@/utils/enum'; | ||
| 32 | import * as XLSX from 'xlsx'; | ||
| 33 | |||
| 34 | const { proxy } = getCurrentInstance() as any; | ||
| 35 | |||
| 36 | const userStore = useUserStore() | ||
| 37 | const route = useRoute() | ||
| 38 | const router = useRouter() | ||
| 39 | /** 2表示资产目录的。3是主数据; 4是元数据导入 */ | ||
| 40 | const isfileImport = route.query.isfileImport | ||
| 41 | const userData = JSON.parse(userStore.userData) | ||
| 42 | const cacheStore = useCatchStore() | ||
| 43 | const standardSetList = ref([]) | ||
| 44 | const standardSetGuid = ref('') | ||
| 45 | const dictionaryList = ref([]) | ||
| 46 | const dictionaryGuid = ref('') | ||
| 47 | const tabsActiveName = ref('') | ||
| 48 | const uploadSetting: any = ref([]) | ||
| 49 | const importType = ref('') | ||
| 50 | const defaulttabs = [ | ||
| 51 | // { label: '标准集导入', name: 'standard' }, | ||
| 52 | // { label: '字段标准导入', name: 'field' }, | ||
| 53 | // { label: '命名标准导入', name: 'naming' }, | ||
| 54 | { label: '数据字典导入', name: 'dictionary' }, | ||
| 55 | // { label: '质量模型导入', name: 'qualityModelGroup' }, | ||
| 56 | // { label: '质量规则导入', name: 'qualityRule' }, | ||
| 57 | ] | ||
| 58 | const importTabs = [ | ||
| 59 | { label: '导入文件数据', name: 'importFile' }, | ||
| 60 | // { label: '质量模型导入', name: 'qualityModelGroup' }, | ||
| 61 | // { label: '质量规则导入', name: 'qualityRule' }, | ||
| 62 | ] | ||
| 63 | const tabsInfo = ref({ | ||
| 64 | activeName: '', | ||
| 65 | tabs: isfileImport ? importTabs : defaulttabs | ||
| 66 | }) | ||
| 67 | |||
| 68 | const currTableData: any = ref<Object>({}); | ||
| 69 | const page = ref(commonPageConfig); | ||
| 70 | const selectRowData = ref([]) | ||
| 71 | const tableInfo = ref({ | ||
| 72 | id: 'data-source-table', | ||
| 73 | multiple: true, | ||
| 74 | fields: [ | ||
| 75 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 76 | { label: "文件名称", field: "fileName", width: 240, }, | ||
| 77 | { label: "状态", field: "importState", type: 'tag', width: 110, align: 'center' }, | ||
| 78 | { label: "导入结果", field: "importMessage", width: 280 }, | ||
| 79 | { label: "导入时间", field: "createTime", width: 180 }, | ||
| 80 | ], | ||
| 81 | data: [], | ||
| 82 | page: { | ||
| 83 | type: "normal", | ||
| 84 | rows: 0, | ||
| 85 | ...page.value, | ||
| 86 | }, | ||
| 87 | actionInfo: { | ||
| 88 | label: "操作", | ||
| 89 | type: "btn", | ||
| 90 | width: 220, | ||
| 91 | fixed: 'right', | ||
| 92 | btns: (scope) => { | ||
| 93 | const row = scope.row | ||
| 94 | let btnsArr = [ | ||
| 95 | { label: '下载文件', value: 'export_file' }, | ||
| 96 | { label: '删除', value: 'delete' } | ||
| 97 | ] | ||
| 98 | if (row.importState != 0 && row.importState != 1) { | ||
| 99 | btnsArr.splice(1, 0, { label: '下载异常数据', value: 'export_abnormal_data' }) | ||
| 100 | } | ||
| 101 | return btnsArr | ||
| 102 | }, | ||
| 103 | }, | ||
| 104 | loading: false | ||
| 105 | }) | ||
| 106 | |||
| 107 | const uploadFiles = ref([]) | ||
| 108 | const uploadSteps: any = ref([]) | ||
| 109 | const uploadInfo = ref({ | ||
| 110 | type: 'upload', | ||
| 111 | title: '', | ||
| 112 | col: '', | ||
| 113 | uploadInfo: { | ||
| 114 | id: 'upload-file-form', | ||
| 115 | type: 'panel', | ||
| 116 | steps: [], | ||
| 117 | extraParams: {dictionaryGuid: 'xx'}, | ||
| 118 | }, | ||
| 119 | }) | ||
| 120 | |||
| 121 | const dialogInfo: any = ref({ | ||
| 122 | visible: false, | ||
| 123 | size: 560, | ||
| 124 | direction: "column", | ||
| 125 | header: { | ||
| 126 | title: "新建", | ||
| 127 | }, | ||
| 128 | type: 'upload', | ||
| 129 | contents: [ | ||
| 130 | uploadInfo.value | ||
| 131 | ], | ||
| 132 | footer: { | ||
| 133 | visible: true, | ||
| 134 | btns: [ | ||
| 135 | { type: "default", label: "取消", value: "cancel" }, | ||
| 136 | { type: "primary", loading: false, label: "开始导入", value: "submit" }, | ||
| 137 | ], | ||
| 138 | }, | ||
| 139 | }) | ||
| 140 | |||
| 141 | // // 获取所有数据字典 | ||
| 142 | const getDictList = () => { | ||
| 143 | const params = { | ||
| 144 | paramCode: '数据字典类型' | ||
| 145 | } | ||
| 146 | getDictionaryTree(params).then((res: any) => { | ||
| 147 | if (res.code == proxy.$passCode) { | ||
| 148 | const data = res.data ?? [] | ||
| 149 | const treeList = data.filter(item => item.children && item.children.length) | ||
| 150 | dictionaryList.value = treeList | ||
| 151 | } else { | ||
| 152 | ElMessage({ | ||
| 153 | type: 'error', | ||
| 154 | message: res.msg, | ||
| 155 | }) | ||
| 156 | } | ||
| 157 | }) | ||
| 158 | } | ||
| 159 | |||
| 160 | const tabsChange = (name) => { | ||
| 161 | tabsActiveName.value = name | ||
| 162 | let info: any = { | ||
| 163 | type: name | ||
| 164 | } | ||
| 165 | if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') { | ||
| 166 | info.standardSetGuid = standardSetGuid.value | ||
| 167 | } else if (tabsActiveName.value == 'dictionary') { | ||
| 168 | info.dictionaryGuid = dictionaryGuid.value | ||
| 169 | } else if (tabsActiveName.value == 'importFile') { | ||
| 170 | |||
| 171 | } | ||
| 172 | cacheStore.setCatch('uploadSetting', info) | ||
| 173 | setUploadInfo() | ||
| 174 | } | ||
| 175 | |||
| 176 | const getFirstPageData = () => { | ||
| 177 | page.value.curr = 1 | ||
| 178 | toSearch({}) | ||
| 179 | |||
| 180 | console.log('store', cacheStore.getCatch('uploadSetting')) | ||
| 181 | } | ||
| 182 | |||
| 183 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 184 | let params: any = Object.keys(val).length ? { ...val } : {} | ||
| 185 | params.pageIndex = page.value.curr; | ||
| 186 | params.pageSize = page.value.limit; | ||
| 187 | params.staffGuid = userData.staffGuid; | ||
| 188 | params.importType = importType.value; | ||
| 189 | |||
| 190 | params.bizGuid = route.query.bizGuid || '' | ||
| 191 | getTableData(params); | ||
| 192 | }; | ||
| 193 | |||
| 194 | const getTableData = (params) => { | ||
| 195 | tableInfo.value.loading = true | ||
| 196 | getImportData(params).then((res: any) => { | ||
| 197 | if (res.code == proxy.$passCode) { | ||
| 198 | const data = res.data || {} | ||
| 199 | tableInfo.value.data = data.records || [] | ||
| 200 | tableInfo.value.page.limit = data.pageSize | ||
| 201 | tableInfo.value.page.curr = data.pageIndex | ||
| 202 | tableInfo.value.page.rows = data.totalRows | ||
| 203 | } else { | ||
| 204 | ElMessage({ | ||
| 205 | type: 'error', | ||
| 206 | message: res.msg, | ||
| 207 | }) | ||
| 208 | } | ||
| 209 | tableInfo.value.loading = false | ||
| 210 | }).catch(xhr => { | ||
| 211 | tableInfo.value.loading = false | ||
| 212 | }) | ||
| 213 | }; | ||
| 214 | |||
| 215 | const tableSelectionChange = (val) => { | ||
| 216 | selectRowData.value = val.map(item => item.guid); | ||
| 217 | }; | ||
| 218 | |||
| 219 | const tablePageChange = (info) => { | ||
| 220 | page.value.curr = Number(info.curr); | ||
| 221 | page.value.limit = Number(info.limit); | ||
| 222 | toSearch({}); | ||
| 223 | }; | ||
| 224 | |||
| 225 | const tableBtnClick = async (scope, btn) => { | ||
| 226 | const type = btn.value; | ||
| 227 | const row = scope.row; | ||
| 228 | currTableData.value = row; | ||
| 229 | if (type == "export_file") { | ||
| 230 | const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.filePath).fileName); | ||
| 231 | if (!refSignInfo?.data) { | ||
| 232 | refSignInfo?.msg && ElMessage.error(refSignInfo?.msg); | ||
| 233 | return; | ||
| 234 | } | ||
| 235 | obsDownloadRequest(refSignInfo?.data).then((res: any) => { | ||
| 236 | if (res && !res.msg) { | ||
| 237 | downFileByBob(res, row.fileName); | ||
| 238 | } else { | ||
| 239 | res?.msg && ElMessage.error(res?.msg); | ||
| 240 | } | ||
| 241 | }); | ||
| 242 | //downFile(row.filePath, row.fileName) | ||
| 243 | } else if (type == 'export_abnormal_data') { | ||
| 244 | //downFile(row.errorFilePath, '') | ||
| 245 | const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.errorFilePath).fileName); | ||
| 246 | if (!refSignInfo?.data) { | ||
| 247 | refSignInfo?.msg && ElMessage.error(refSignInfo?.msg); | ||
| 248 | return; | ||
| 249 | } | ||
| 250 | obsDownloadRequest(refSignInfo?.data).then((res: any) => { | ||
| 251 | if (res && !res.msg) { | ||
| 252 | let name = row.errorFilePath; | ||
| 253 | let fileName = name ? name.substring(name.lastIndexOf('/') + 1) : '' | ||
| 254 | downFileByBob(res, fileName); | ||
| 255 | } else { | ||
| 256 | res?.msg && ElMessage.error(res?.msg); | ||
| 257 | } | ||
| 258 | }); | ||
| 259 | } else if (type == "delete") { | ||
| 260 | open("此操作将永久删除, 是否继续?", "warning"); | ||
| 261 | } | ||
| 262 | }; | ||
| 263 | |||
| 264 | const batching = (type) => { | ||
| 265 | if (type == 'import') { | ||
| 266 | dialogInfo.value.header.title = '导入数据' | ||
| 267 | dialogInfo.value.type = 'upload' | ||
| 268 | dialogInfo.value.size = 560 | ||
| 269 | uploadFiles.value = [] | ||
| 270 | // if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') { | ||
| 271 | // uploadSteps.value[0].selectInfo.options = standardSetList.value | ||
| 272 | // } else if (tabsActiveName.value == 'dictionary') { | ||
| 273 | // uploadSteps.value[0].cascaderInfo.options = dictionaryList.value | ||
| 274 | // } | ||
| 275 | uploadInfo.value.uploadInfo.steps = uploadSteps.value | ||
| 276 | uploadSetting.value.forEach(item => item.value = '') | ||
| 277 | sheetNameList.value = [] | ||
| 278 | const content: any = [uploadInfo.value] | ||
| 279 | dialogInfo.value.contents = content | ||
| 280 | dialogInfo.value.visible = true | ||
| 281 | } else if (type == 'delete') { | ||
| 282 | if (selectRowData.value.length == 0) { | ||
| 283 | ElMessage({ | ||
| 284 | type: 'error', | ||
| 285 | message: '请选择需要删除的数据', | ||
| 286 | }) | ||
| 287 | return | ||
| 288 | } | ||
| 289 | open("此操作将永久删除, 是否继续?", "warning", true); | ||
| 290 | } else if (type === 'importFile') { | ||
| 291 | if (isfileImport == '2' || isfileImport == '4') { | ||
| 292 | dialogInfo.value.header.title = '导入数据' | ||
| 293 | dialogInfo.value.type = 'upload' | ||
| 294 | dialogInfo.value.size = isfileImport == '4' ? 560 : 560; | ||
| 295 | uploadFiles.value = [] | ||
| 296 | uploadInfo.value.uploadInfo.steps = uploadSteps.value | ||
| 297 | const content: any = [uploadInfo.value] | ||
| 298 | dialogInfo.value.contents = content | ||
| 299 | dialogInfo.value.visible = true | ||
| 300 | } else { | ||
| 301 | router.push({ | ||
| 302 | name: "importData", | ||
| 303 | query: route.query | ||
| 304 | }) | ||
| 305 | } | ||
| 306 | } | ||
| 307 | }; | ||
| 308 | |||
| 309 | const open = (msg, type, isBatch = false) => { | ||
| 310 | ElMessageBox.confirm(msg, "提示", { | ||
| 311 | confirmButtonText: "确定", | ||
| 312 | cancelButtonText: "取消", | ||
| 313 | type: type, | ||
| 314 | }).then(() => { | ||
| 315 | let guids = [currTableData.value.guid] | ||
| 316 | if (isBatch) { | ||
| 317 | guids = selectRowData.value | ||
| 318 | } | ||
| 319 | deleteImportData(guids).then((res: any) => { | ||
| 320 | if (res.code == proxy.$passCode) { | ||
| 321 | getFirstPageData(); | ||
| 322 | ElMessage({ | ||
| 323 | type: "success", | ||
| 324 | message: "删除成功", | ||
| 325 | }); | ||
| 326 | } else { | ||
| 327 | ElMessage({ | ||
| 328 | type: "error", | ||
| 329 | message: res.msg, | ||
| 330 | }); | ||
| 331 | } | ||
| 332 | }); | ||
| 333 | }); | ||
| 334 | }; | ||
| 335 | |||
| 336 | const sheetNameList = ref([]) | ||
| 337 | const onUpload = (file, fileList) => { | ||
| 338 | // console.log('file', file) | ||
| 339 | uploadFiles.value = fileList | ||
| 340 | const reader = new FileReader() | ||
| 341 | reader.onload = function (e) { | ||
| 342 | let data = new Uint8Array(e.target.result) | ||
| 343 | let wb = XLSX.read(data, { type: 'array', raw: false, cellDates: true }) | ||
| 344 | console.log('wb', wb) | ||
| 345 | sheetNameList.value = wb.SheetNames | ||
| 346 | } | ||
| 347 | reader.readAsArrayBuffer(file.raw) | ||
| 348 | } | ||
| 349 | |||
| 350 | const uploadBtnClick = (btn) => { | ||
| 351 | exportData() | ||
| 352 | } | ||
| 353 | |||
| 354 | const cascaderChange = (val) => { | ||
| 355 | dictionaryGuid.value = val ? val.at(-1) : '' | ||
| 356 | } | ||
| 357 | |||
| 358 | const selectChange = (val) => { | ||
| 359 | standardSetGuid.value = val | ||
| 360 | } | ||
| 361 | |||
| 362 | const exportData = (ids: any = null) => { | ||
| 363 | if (tabsActiveName.value == 'standard') { | ||
| 364 | const fieldTemplate = "/files/set.xlsx"; | ||
| 365 | downFile(fieldTemplate, '标准集模板.xlsx') | ||
| 366 | } else if (tabsActiveName.value == 'field') { | ||
| 367 | const fieldTemplate = "/files/field.xlsx"; | ||
| 368 | downFile(fieldTemplate, '字段标准模板.xlsx') | ||
| 369 | } else if (tabsActiveName.value == 'naming') { | ||
| 370 | const namingTemplate = "/files/naming.xlsx"; | ||
| 371 | downFile(namingTemplate, '命名标准模板.xlsx') | ||
| 372 | } else if (tabsActiveName.value == 'dictionary') { | ||
| 373 | const params = { | ||
| 374 | guid: dictionaryGuid.value | ||
| 375 | } | ||
| 376 | exportDictionary(params).then((res: any) => { | ||
| 377 | if (res && !res.msg) { | ||
| 378 | download(res, '数据字典模板.xlsx', 'excel'); | ||
| 379 | } else { | ||
| 380 | res?.msg && ElMessage.error(res?.msg); | ||
| 381 | } | ||
| 382 | }); | ||
| 383 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '4') { | ||
| 384 | exportCollectTask({ | ||
| 385 | importTypes: [ | ||
| 386 | "0042" | ||
| 387 | ] | ||
| 388 | }).then((res: any) => { | ||
| 389 | if (res && !res.msg) { | ||
| 390 | download(res, '元数据模板.xlsx', 'excel'); | ||
| 391 | } else { | ||
| 392 | res?.msg && ElMessage.error(res?.msg); | ||
| 393 | } | ||
| 394 | }); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | const importData = (info) => { | ||
| 399 | let params = new FormData() | ||
| 400 | if (uploadFiles.value.length == 0) { | ||
| 401 | ElMessage({ | ||
| 402 | type: 'error', | ||
| 403 | message: '请选择上传文件' | ||
| 404 | }) | ||
| 405 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 406 | return | ||
| 407 | } | ||
| 408 | let sheetPass = uploadSetting.value.some(item => item.value) | ||
| 409 | if (!sheetPass) { | ||
| 410 | ElMessage.error('导入失败,没有导入数据') | ||
| 411 | dialogInfo.value.visible = false; | ||
| 412 | return | ||
| 413 | } | ||
| 414 | let sheetNum = uploadSetting.value.filter(item => item.value)['length'] | ||
| 415 | if (sheetNum > 30) { | ||
| 416 | ElMessage.error('最多只能导入30个sheet页的数据。') | ||
| 417 | return | ||
| 418 | } | ||
| 419 | let paramUrl = ''; | ||
| 420 | uploadFiles.value.forEach((item: any, index: number) => { | ||
| 421 | params.append("file", item.raw); | ||
| 422 | }); | ||
| 423 | let sheetMaps = {} | ||
| 424 | uploadSetting.value.forEach(item => { | ||
| 425 | if (item.value) { | ||
| 426 | sheetMaps[item.value] = item.standardGuid | ||
| 427 | } | ||
| 428 | }) | ||
| 429 | sheetMaps = encodeURIComponent(JSON.stringify(sheetMaps)) | ||
| 430 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-batch-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}&sheetMaps=${sheetMaps}` | ||
| 431 | dialogInfo.value.footer.btns[1].loading = true; | ||
| 432 | addImportData(paramUrl, params).then((res: any) => { | ||
| 433 | dialogInfo.value.footer.btns[1].loading = false; | ||
| 434 | if (res.code == proxy.$passCode) { | ||
| 435 | getFirstPageData(); | ||
| 436 | ElMessage({ | ||
| 437 | type: "success", | ||
| 438 | message: '导入成功', | ||
| 439 | }); | ||
| 440 | dialogInfo.value.visible = false; | ||
| 441 | } else { | ||
| 442 | ElMessage({ | ||
| 443 | type: "error", | ||
| 444 | message: res.msg, | ||
| 445 | }); | ||
| 446 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 447 | } | ||
| 448 | }).catch(() => { | ||
| 449 | dialogInfo.value.footer.btns[1].loading = false; | ||
| 450 | }) | ||
| 451 | } | ||
| 452 | |||
| 453 | const dialogBtnClick = (btn, info) => { | ||
| 454 | if (btn.value == 'submit') { | ||
| 455 | // dialogInfo.value.footer.btns.map((item: any) => item.disabled = true) | ||
| 456 | if (dialogInfo.value.type == 'upload') { | ||
| 457 | if (tabsActiveName.value == 'dictionary') { | ||
| 458 | importData({ bizGuid: dictionaryGuid.value }) | ||
| 459 | } else { | ||
| 460 | importData(info) | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } else if (btn.value == 'cancel') { | ||
| 464 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | ||
| 465 | nextTick(() => { | ||
| 466 | dialogInfo.value.visible = false; | ||
| 467 | }) | ||
| 468 | }; | ||
| 469 | } | ||
| 470 | |||
| 471 | const setUploadInfo = () => { | ||
| 472 | importType.value = '0102' | ||
| 473 | tabsInfo.value.activeName = tabsActiveName.value | ||
| 474 | getFirstPageData() | ||
| 475 | uploadSteps.value = [ | ||
| 476 | { | ||
| 477 | title: '1、选择准备好的文件导入', | ||
| 478 | type: 'btn_upload', | ||
| 479 | uploadInfo: { | ||
| 480 | action: '', | ||
| 481 | auto: false, | ||
| 482 | cover: true, | ||
| 483 | fileList: [], | ||
| 484 | accept: '.xlsx, .xls', | ||
| 485 | tips: '当前支持xls、xlsx文件,支持一个文件多个sheet批量导入,一次最多只能导入30个sheet页数据。' | ||
| 486 | } | ||
| 487 | } | ||
| 488 | ] | ||
| 489 | } | ||
| 490 | |||
| 491 | function deleteFile () { | ||
| 492 | sheetNameList.value = [] | ||
| 493 | uploadSetting.value.forEach(item => item.value = null) | ||
| 494 | } | ||
| 495 | |||
| 496 | onActivated(() => { | ||
| 497 | let list = cacheStore.getCatch('uploadSetting') || [] | ||
| 498 | uploadSetting.value = list.map(item => { | ||
| 499 | item.value = null | ||
| 500 | return item | ||
| 501 | }) | ||
| 502 | console.log('uploadSetting', uploadSetting.value) | ||
| 503 | setUploadInfo() | ||
| 504 | }) | ||
| 505 | |||
| 506 | </script> | ||
| 507 | |||
| 508 | <template> | ||
| 509 | <div class="container_wrap"> | ||
| 510 | <!-- <Tabs v-if="!isfileImport" :tabs-info="tabsInfo" @tabChange="tabsChange" /> --> | ||
| 511 | <div class="table_tool_wrap"> | ||
| 512 | <div class="tools_btns"> | ||
| 513 | <el-button type="primary" @click="batching('import')" v-if="tabsActiveName !== 'importFile'" | ||
| 514 | v-preReClick>批量导入</el-button> | ||
| 515 | <el-button type="primary" @click="batching('importFile')" v-if="tabsActiveName == 'importFile'" | ||
| 516 | v-preReClick>文件导入</el-button> | ||
| 517 | <el-button @click="batching('delete')" v-preReClick>批量删除</el-button> | ||
| 518 | <el-button @click="getFirstPageData" v-preReClick>刷新结果</el-button> | ||
| 519 | </div> | ||
| 520 | <span class="tips_text">请及时刷新查看最终结果</span> | ||
| 521 | </div> | ||
| 522 | <div class="table_panel_wrap" :style="{ height: !isfileImport ? 'calc(100% - 71px)' : 'calc(100% - 44px)' }"> | ||
| 523 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange" | ||
| 524 | @tablePageChange="tablePageChange" /> | ||
| 525 | </div> | ||
| 526 | <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @onUpload="onUpload" @uploadBtnClick="uploadBtnClick" | ||
| 527 | @cascaderChange="cascaderChange" @selectChange="selectChange" @deleteFile="deleteFile"> | ||
| 528 | <div style="overflow: auto;"> | ||
| 529 | <div class="title" style="color:#333;margin:20px 0 10px">2、导入前请先导入文件的sheet与标准做对应</div> | ||
| 530 | <el-table :data="uploadSetting" border height="310"> | ||
| 531 | <el-table-column type="index" label="序号" width="55" align="center"/> | ||
| 532 | <el-table-column label="标准名称" prop="standardName"></el-table-column> | ||
| 533 | <el-table-column label="选择sheet页"> | ||
| 534 | <template #default="scope"> | ||
| 535 | <el-select v-model="scope.row.value" placeholder="请选择" style="width:200px" clearable> | ||
| 536 | <el-option v-for="item,i in sheetNameList" :label="item" :value="item" :key="i"></el-option> | ||
| 537 | </el-select> | ||
| 538 | </template> | ||
| 539 | </el-table-column> | ||
| 540 | </el-table> | ||
| 541 | </div> | ||
| 542 | </Dialog> | ||
| 543 | </div> | ||
| 544 | </template> | ||
| 545 | |||
| 546 | <style lang="scss" scoped> | ||
| 547 | .container_wrap { | ||
| 548 | padding: 0; | ||
| 549 | |||
| 550 | :deep(.el-tabs) { | ||
| 551 | |||
| 552 | .el-tabs__header { | ||
| 553 | margin-bottom: 0; | ||
| 554 | } | ||
| 555 | |||
| 556 | .el-tabs__item { | ||
| 557 | height: 32px; | ||
| 558 | |||
| 559 | &:nth-child(2) { | ||
| 560 | padding-left: 16px; | ||
| 561 | } | ||
| 562 | |||
| 563 | &:last-child { | ||
| 564 | padding-right: 16px; | ||
| 565 | } | ||
| 566 | |||
| 567 | &::after { | ||
| 568 | content: ''; | ||
| 569 | width: 100%; | ||
| 570 | height: 2px; | ||
| 571 | background-color: transparent; | ||
| 572 | position: absolute; | ||
| 573 | left: 0; | ||
| 574 | bottom: 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | &.is-active { | ||
| 578 | &::after { | ||
| 579 | background-color: var(--el-color-primary); | ||
| 580 | } | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | .el-tabs__active-bar { | ||
| 585 | display: none; | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | .table_tool_wrap { | ||
| 590 | padding: 0 16px; | ||
| 591 | display: flex; | ||
| 592 | align-items: center; | ||
| 593 | |||
| 594 | .tips_text { | ||
| 595 | margin-left: 16px; | ||
| 596 | font-size: 14px; | ||
| 597 | color: #b2b2b2; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | .table_panel_wrap { | ||
| 602 | padding: 0 16px; | ||
| 603 | height: calc(100% - 71px); | ||
| 604 | } | ||
| 605 | |||
| 606 | } | ||
| 607 | </style> | ||
| 608 | <style lang="scss"> | ||
| 609 | .upload_panel_wrap .upload_panel .file_panel .file_item .file_btn { | ||
| 610 | word-break: keep-all; | ||
| 611 | } | ||
| 612 | .upload_panel_wrap .upload_step_panel .upload_panel { | ||
| 613 | padding-top: 42px!important; | ||
| 614 | } | ||
| 615 | </style> |
src/views/data_meta/standard-query-view.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: metadataStandardQueryView | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <template> | ||
| 6 | <div class="main_wrap" v-loading="graphDataLoading"> | ||
| 7 | <div className='g6-component-topbar'> | ||
| 8 | <graphTopbar ref="topBarRef" @displaySwitchChange="displaySwitchChange" :isGraphDisplay="isGraphDisplay" /> | ||
| 9 | </div> | ||
| 10 | <RelationNetwork v-show="graphTreeData?.guid && isGraphDisplay" ref="relationNetworkRef" :tree-data="graphTreeData" | ||
| 11 | :noContextMenu="true" @nodeItemClick="handleNodeItemClick" @contextMenu="handleContextMenu"> | ||
| 12 | </RelationNetwork> | ||
| 13 | <Sankey v-show="!isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)" v-loading="sankeyDataLoading" | ||
| 14 | :tree-data="sankeyData" :names="sankeyNames"> | ||
| 15 | </Sankey> | ||
| 16 | <div v-show="(isGraphDisplay ? !graphTreeData?.guid : (!sankeyDataLoading && !sankeyNames?.length))" | ||
| 17 | class="main-placeholder"> | ||
| 18 | <img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" /> | ||
| 19 | <div class="empty-text">暂无数据</div> | ||
| 20 | </div> | ||
| 21 | </div> | ||
| 22 | </template> | ||
| 23 | |||
| 24 | <script lang="ts" setup name="metadataStandardQueryView"> | ||
| 25 | import { | ||
| 26 | getMetaStandardField, | ||
| 27 | getSankeyData, | ||
| 28 | getMetaStandardTreeList | ||
| 29 | } from '@/api/modules/dataMetaService'; | ||
| 30 | import Sankey from './components/Sankey.vue'; | ||
| 31 | import { ElMessage } from 'element-plus'; | ||
| 32 | |||
| 33 | const router = useRouter(); | ||
| 34 | const route = useRoute() | ||
| 35 | |||
| 36 | const metaGuid = ref(route.query.guid); | ||
| 37 | |||
| 38 | const { proxy } = getCurrentInstance() as any; | ||
| 39 | |||
| 40 | const relationNetworkRef = ref(); | ||
| 41 | |||
| 42 | const graphDataLoading = ref(false); | ||
| 43 | |||
| 44 | /** 关系网树形数据 */ | ||
| 45 | const graphTreeData: any = ref({}); | ||
| 46 | |||
| 47 | onBeforeUnmount(() => { | ||
| 48 | relationNetworkRef.value.destroy(); | ||
| 49 | }) | ||
| 50 | |||
| 51 | const sankeyDataLoading = ref(false); | ||
| 52 | |||
| 53 | const sankeyData: any = ref([]); | ||
| 54 | |||
| 55 | const sankeyNames: any = ref([]); | ||
| 56 | |||
| 57 | const isGraphDisplay = ref(true); | ||
| 58 | |||
| 59 | const displaySwitchChange = (val) => { | ||
| 60 | if (val == isGraphDisplay.value) { | ||
| 61 | return; | ||
| 62 | } | ||
| 63 | isGraphDisplay.value = val; | ||
| 64 | if (!val) { | ||
| 65 | getSankeyDataList(); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | const getSankeyDataList = () => { | ||
| 70 | sankeyDataLoading.value = true; | ||
| 71 | getSankeyData(metaGuid.value).then((res: any) => { | ||
| 72 | sankeyDataLoading.value = false; | ||
| 73 | if (res?.code == proxy.$passCode) { | ||
| 74 | sankeyData.value = res.data?.links || []; | ||
| 75 | sankeyNames.value = res.data?.data || []; | ||
| 76 | } else { | ||
| 77 | ElMessage.error(res.msg); | ||
| 78 | } | ||
| 79 | }) | ||
| 80 | } | ||
| 81 | |||
| 82 | const handleNodeItemClick = (graph, nodeItem) => { | ||
| 83 | const nodeId = nodeItem.get('id'); | ||
| 84 | let parentData = graph.findDataById(nodeId); | ||
| 85 | if (!parentData.children) { | ||
| 86 | parentData.children = []; | ||
| 87 | } | ||
| 88 | if (parentData.isHaveData == 'N') { | ||
| 89 | ElMessage.warning('没有可展开的下级字段'); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | // graph.updateConfig({ animate: false }); | ||
| 93 | // graph.refresh(); | ||
| 94 | nodeItem.getModel().collapsed = false; | ||
| 95 | parentData.collapsed = false; | ||
| 96 | graphDataLoading.value = true; | ||
| 97 | getMetaStandardField(nodeId).then((res: any) => { | ||
| 98 | graphDataLoading.value = false; | ||
| 99 | if (res?.code == proxy.$passCode) { | ||
| 100 | parentData = graph.findDataById(nodeId); | ||
| 101 | const data = res.data || []; | ||
| 102 | parentData.children = []; | ||
| 103 | if (!data?.length) { | ||
| 104 | parentData.isHaveData = 'N'; | ||
| 105 | ElMessage.warning('没有可展开的下级字段'); | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | data.forEach(d => { | ||
| 109 | parentData.children.push(d); | ||
| 110 | }) | ||
| 111 | parentData.isLoading = false; | ||
| 112 | nodeItem.getModel().collapsed = false; | ||
| 113 | parentData.collapsed = false; | ||
| 114 | graph.updateItem(nodeItem, { | ||
| 115 | ...nodeItem.getModel(), | ||
| 116 | collapsed: false | ||
| 117 | }); | ||
| 118 | graph.layout(); | ||
| 119 | setTimeout(() => { | ||
| 120 | // graph.updateConfig({ animate: true }); | ||
| 121 | // graph.refresh(); | ||
| 122 | graph.updateItem(nodeItem, { | ||
| 123 | ...nodeItem.getModel(), | ||
| 124 | collapsed: false | ||
| 125 | }); | ||
| 126 | graph.setMinZoom(1); | ||
| 127 | graph.setMaxZoom(1); | ||
| 128 | graph.layout(); | ||
| 129 | graph.setMinZoom(0.5); | ||
| 130 | graph.setMaxZoom(5); | ||
| 131 | graph.focusItem(nodeItem, true, { | ||
| 132 | duration: 400 // 动画时长为500ms | ||
| 133 | }); | ||
| 134 | }, 500); | ||
| 135 | } else { | ||
| 136 | parentData.isLoading = false; | ||
| 137 | ElMessage.error(res.msg); | ||
| 138 | } | ||
| 139 | }) | ||
| 140 | } | ||
| 141 | |||
| 142 | const handleContextMenu = (model) => { | ||
| 143 | router.push({ | ||
| 144 | name: 'metadataStandard', | ||
| 145 | query: { | ||
| 146 | standardGuid: model.guid, | ||
| 147 | name: model.standardName | ||
| 148 | } | ||
| 149 | }); | ||
| 150 | } | ||
| 151 | |||
| 152 | onBeforeMount(() => { | ||
| 153 | graphDataLoading.value = true | ||
| 154 | getMetaStandardTreeList(metaGuid.value).then((res: any) => { | ||
| 155 | graphDataLoading.value = false; | ||
| 156 | if (res?.code == proxy.$passCode) { | ||
| 157 | const data = res.data || []; | ||
| 158 | let resultData = data?.[0] || {}; | ||
| 159 | if (!resultData?.children?.length && resultData.isHaveData == 'Y') { | ||
| 160 | graphDataLoading.value = true; | ||
| 161 | getMetaStandardField(resultData.guid).then((res: any) => { | ||
| 162 | graphDataLoading.value = false; | ||
| 163 | if (res?.code == proxy.$passCode) { | ||
| 164 | resultData.children = res.data || []; | ||
| 165 | graphTreeData.value = resultData; | ||
| 166 | } else { | ||
| 167 | graphTreeData.value = resultData; | ||
| 168 | ElMessage.error(res.msg); | ||
| 169 | } | ||
| 170 | }); | ||
| 171 | } else { | ||
| 172 | graphTreeData.value = resultData; | ||
| 173 | } | ||
| 174 | } else { | ||
| 175 | ElMessage.error(res.msg); | ||
| 176 | } | ||
| 177 | }) | ||
| 178 | }) | ||
| 179 | |||
| 180 | </script> | ||
| 181 | |||
| 182 | <style lang="scss" scoped> | ||
| 183 | .main_wrap { | ||
| 184 | height: 100%; | ||
| 185 | width: 100%; | ||
| 186 | position: relative; | ||
| 187 | |||
| 188 | :deep(.canvas-wrapper) { | ||
| 189 | background-color: #f7f7f9; | ||
| 190 | } | ||
| 191 | |||
| 192 | .main-placeholder { | ||
| 193 | height: 100%; | ||
| 194 | display: flex; | ||
| 195 | justify-content: center; | ||
| 196 | align-items: center; | ||
| 197 | flex-direction: column; | ||
| 198 | |||
| 199 | .empty-text { | ||
| 200 | font-size: 14px; | ||
| 201 | color: #b2b2b2; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | .g6-component-topbar { | ||
| 207 | position: absolute; | ||
| 208 | left: 24px; | ||
| 209 | bottom: unset; | ||
| 210 | top: 14px; | ||
| 211 | padding: 0; | ||
| 212 | text-align: center; | ||
| 213 | z-index: 999; | ||
| 214 | } | ||
| 215 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/views/data_meta/standard-query.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: metadataStandardQuery | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="metadataStandardQuery"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 8 | import Sankey from './components/Sankey.vue'; | ||
| 9 | import Tree from '@/components/Tree/index.vue'; | ||
| 10 | import RelationNetwork from '@/components/RelationNetwork/index.vue'; | ||
| 11 | import { | ||
| 12 | getDataWareCatalogList, | ||
| 13 | getMetaStandardTreeList, | ||
| 14 | getMetaStandardField, | ||
| 15 | getSankeyData | ||
| 16 | } from '@/api/modules/dataMetaService'; | ||
| 17 | import { useRouter, useRoute } from "vue-router"; | ||
| 18 | import useDataMetaStore from "@/store/modules/dataMeta" | ||
| 19 | import { cloneDeep } from 'lodash-es'; | ||
| 20 | |||
| 21 | import { useValidator } from '@/hooks/useValidator'; | ||
| 22 | |||
| 23 | const { required } = useValidator(); | ||
| 24 | |||
| 25 | const router = useRouter(); | ||
| 26 | const route = useRoute() | ||
| 27 | |||
| 28 | const { proxy } = getCurrentInstance() as any; | ||
| 29 | |||
| 30 | const relationNetworkRef = ref(); | ||
| 31 | |||
| 32 | const treeInfo = ref({ | ||
| 33 | id: "data-meta-standard-tree", | ||
| 34 | filter: true, | ||
| 35 | queryValue: "", | ||
| 36 | queryPlaceholder: "请输入关键字搜索", | ||
| 37 | props: { | ||
| 38 | label: "standardName", | ||
| 39 | value: "guid", | ||
| 40 | isLeaf: "isLeaf", | ||
| 41 | }, | ||
| 42 | nodeKey: 'guid', | ||
| 43 | expandedKey: [], | ||
| 44 | currentNodeKey: '', | ||
| 45 | expandOnNodeClick: false, | ||
| 46 | data: <any>[], | ||
| 47 | loading: false | ||
| 48 | }); | ||
| 49 | |||
| 50 | /** 获取左侧树数据. */ | ||
| 51 | const getTreeData = async () => { | ||
| 52 | treeInfo.value.loading = true | ||
| 53 | getMetaStandardTreeList('').then((res: any) => { | ||
| 54 | treeInfo.value.loading = false; | ||
| 55 | if (res?.code == proxy.$passCode) { | ||
| 56 | const data = res.data || []; | ||
| 57 | data.forEach(d => { | ||
| 58 | d.disabled = true; | ||
| 59 | }) | ||
| 60 | treeInfo.value.data = data; | ||
| 61 | if (data.length) { | ||
| 62 | treeInfo.value.currentNodeKey = data[0]?.children?.[0]?.guid; | ||
| 63 | treeInfo.value.expandedKey = <any>[data[0].guid]; | ||
| 64 | nodeClick(treeInfo.value.data[0]?.children?.[0]) | ||
| 65 | } | ||
| 66 | } else { | ||
| 67 | ElMessage.error(res.msg); | ||
| 68 | } | ||
| 69 | }) | ||
| 70 | } | ||
| 71 | /** 左侧树的的组件引用. */ | ||
| 72 | const treeInfoRef = ref(); | ||
| 73 | |||
| 74 | /** 当前选中的树节点数据data */ | ||
| 75 | const lastClickNode: any = ref({}); | ||
| 76 | |||
| 77 | const treeDataLoading = ref(false); | ||
| 78 | |||
| 79 | /** 点击左侧树节点,更新对应的血缘关系图. */ | ||
| 80 | const nodeClick = (data) => { | ||
| 81 | const ele = <HTMLElement>document.querySelector(".g6-component-contextmenu") | ||
| 82 | if (ele) { | ||
| 83 | ele.style.visibility = "hidden" | ||
| 84 | } | ||
| 85 | if (data.disabled) { | ||
| 86 | treeInfo.value.currentNodeKey = data.guid; | ||
| 87 | nextTick(() => { | ||
| 88 | treeInfo.value.currentNodeKey = lastClickNode.value.guid; | ||
| 89 | }); | ||
| 90 | // lastClickNode.value = {}; | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | treeInfo.value.currentNodeKey = data.guid; | ||
| 94 | treeInfo.value.expandedKey = <any>[data.guid]; | ||
| 95 | lastClickNode.value = cloneDeep(data); | ||
| 96 | if (!isGraphDisplay.value) { | ||
| 97 | getSankeyDataList(); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /** 选中树节点后自动滚动到可视范围内. */ | ||
| 102 | const scrollToNode = (nodeId) => { | ||
| 103 | nextTick(() => { | ||
| 104 | const nodeElement = treeInfoRef.value.treeRef.$el.querySelector(`[data-key="${nodeId}"]`); | ||
| 105 | if (nodeElement) { | ||
| 106 | nodeElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); | ||
| 107 | } | ||
| 108 | }); | ||
| 109 | } | ||
| 110 | |||
| 111 | /** 处理从详情处跳转而来的默认展示. */ | ||
| 112 | const processRouter = () => { | ||
| 113 | const { guid, databaseName, tableName, databaseChName, databaseGuid, fieldGuid, fieldEnName, set } = useDataMetaStore() | ||
| 114 | let isFL = useDataMetaStore().isFieldLineage; | ||
| 115 | if (fieldGuid) {//查看字段血缘的 | ||
| 116 | nextTick(() => { | ||
| 117 | treeInfo.value.expandedKey = <any>[databaseGuid, guid]; | ||
| 118 | treeInfo.value.currentNodeKey = fieldGuid as string; | ||
| 119 | scrollToNode(fieldGuid); | ||
| 120 | treeInfoRef.value.setCurrentKey(fieldGuid); | ||
| 121 | }) | ||
| 122 | lastClickNode.value = { guid: fieldGuid, tableGuid: guid, databaseGuid: databaseGuid, enName: fieldEnName, tableName, databaseName, type: 4, isLeaf: true, databaseChName }; | ||
| 123 | // getTableFieldLineageMap(); | ||
| 124 | set() | ||
| 125 | } else if (guid) { | ||
| 126 | treeInfo.value.currentNodeKey = guid as string; | ||
| 127 | treeInfo.value.expandedKey = <any>[databaseGuid, guid]; | ||
| 128 | lastClickNode.value = { guid: guid, tableName, databaseName, type: 3, databaseChName }; | ||
| 129 | scrollToNode(guid); | ||
| 130 | // if (isFL) { | ||
| 131 | // getAllTableFieldLineageMap(); | ||
| 132 | // } else { | ||
| 133 | // getTableLineageMap() | ||
| 134 | // } | ||
| 135 | set() | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | onActivated(() => { | ||
| 140 | //processRouter(); | ||
| 141 | }); | ||
| 142 | |||
| 143 | onBeforeMount(async () => { | ||
| 144 | await getTreeData() | ||
| 145 | // processRouter(); | ||
| 146 | }) | ||
| 147 | |||
| 148 | onMounted(() => { }) | ||
| 149 | |||
| 150 | const sankeyDataLoading = ref(false); | ||
| 151 | |||
| 152 | const sankeyData: any = ref([]); | ||
| 153 | |||
| 154 | const sankeyNames: any = ref([]); | ||
| 155 | |||
| 156 | const isGraphDisplay = ref(true); | ||
| 157 | |||
| 158 | const displaySwitchChange = (val) => { | ||
| 159 | if (val == isGraphDisplay.value) { | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | isGraphDisplay.value = val; | ||
| 163 | if (!val) { | ||
| 164 | getSankeyDataList(); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | const getSankeyDataList = () => { | ||
| 169 | sankeyDataLoading.value = true; | ||
| 170 | getSankeyData(lastClickNode.value.guid).then((res: any) => { | ||
| 171 | sankeyDataLoading.value = false; | ||
| 172 | if (res?.code == proxy.$passCode) { | ||
| 173 | sankeyData.value = res.data?.links || []; | ||
| 174 | sankeyNames.value = res.data?.data || []; | ||
| 175 | } else { | ||
| 176 | ElMessage.error(res.msg); | ||
| 177 | } | ||
| 178 | }) | ||
| 179 | } | ||
| 180 | |||
| 181 | const handleNodeItemClick = (graph, nodeItem) => { | ||
| 182 | const nodeId = nodeItem.get('id'); | ||
| 183 | const parentData = graph.findDataById(nodeId); | ||
| 184 | if (!parentData.children) { | ||
| 185 | parentData.children = []; | ||
| 186 | } | ||
| 187 | if (parentData.noData) { | ||
| 188 | ElMessage.warning('没有可展开的下级字段'); | ||
| 189 | return; | ||
| 190 | } | ||
| 191 | treeDataLoading.value = true; | ||
| 192 | getMetaStandardField(nodeId).then((res: any) => { | ||
| 193 | treeDataLoading.value = false; | ||
| 194 | if (res?.code == proxy.$passCode) { | ||
| 195 | const data = res.data || []; | ||
| 196 | parentData.children = []; | ||
| 197 | if (!data?.length) { | ||
| 198 | parentData.noData = true; | ||
| 199 | ElMessage.warning('没有可展开的下级字段'); | ||
| 200 | return; | ||
| 201 | } | ||
| 202 | data.forEach(d => { | ||
| 203 | parentData.children.push(d); | ||
| 204 | }) | ||
| 205 | parentData.isLoading = false; | ||
| 206 | parentData.collapsed = false; | ||
| 207 | graph.layout(); | ||
| 208 | setTimeout(() => { | ||
| 209 | graph.updateItem(nodeItem, { | ||
| 210 | ...nodeItem.getModel(), | ||
| 211 | collapsed: false | ||
| 212 | }); | ||
| 213 | graph.setMinZoom(1); | ||
| 214 | graph.setMaxZoom(1); | ||
| 215 | graph.layout(); | ||
| 216 | graph.setMinZoom(0.5); | ||
| 217 | graph.setMaxZoom(5); | ||
| 218 | graph.focusItem(nodeItem, true, { | ||
| 219 | duration: 500 // 动画时长为500ms | ||
| 220 | }); | ||
| 221 | }, 500); | ||
| 222 | } else { | ||
| 223 | parentData.isLoading = false; | ||
| 224 | ElMessage.error(res.msg); | ||
| 225 | } | ||
| 226 | }) | ||
| 227 | } | ||
| 228 | |||
| 229 | const handleContextMenu = (model) => { | ||
| 230 | if (model.isHaveData == 'N') { | ||
| 231 | ElMessage.warning('当前标准下无字段,请先添加字段'); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | contextNodeData.value = model; | ||
| 235 | dialogInfo.value.visible = true; | ||
| 236 | formItems.value[0].default = ''; | ||
| 237 | getDataWareCatalogList({}).then((res: any) => { | ||
| 238 | if (res?.code == proxy.$passCode) { | ||
| 239 | dataCatalogList.value = res.data || []; | ||
| 240 | formItems.value[0].options = dataCatalogList.value; | ||
| 241 | } else { | ||
| 242 | ElMessage.error(res.msg); | ||
| 243 | } | ||
| 244 | }) | ||
| 245 | } | ||
| 246 | |||
| 247 | onBeforeUnmount(() => { | ||
| 248 | relationNetworkRef.value.destroy(); | ||
| 249 | }) | ||
| 250 | |||
| 251 | /** 数仓目录树形列表 */ | ||
| 252 | const dataCatalogList = ref([]); | ||
| 253 | |||
| 254 | const formItems = ref([{ | ||
| 255 | label: "数仓目录", | ||
| 256 | type: "tree-select", | ||
| 257 | placeholder: "请选择", | ||
| 258 | field: "domainGuid", | ||
| 259 | default: '', | ||
| 260 | options: dataCatalogList.value, | ||
| 261 | props: { | ||
| 262 | label: 'name', | ||
| 263 | value: 'guid' | ||
| 264 | }, | ||
| 265 | showAllLevels: false, | ||
| 266 | checkStrictly: false,//只能选择叶子节点。 | ||
| 267 | lazy: false, | ||
| 268 | filterable: true, | ||
| 269 | clearable: true, | ||
| 270 | required: true, | ||
| 271 | }]); | ||
| 272 | |||
| 273 | const formRules = ref({ | ||
| 274 | domainGuid: [required('请选择数仓目录')], | ||
| 275 | }); | ||
| 276 | |||
| 277 | const dialogInfo = ref({ | ||
| 278 | visible: false, | ||
| 279 | size: 400, | ||
| 280 | direction: "column", | ||
| 281 | header: { | ||
| 282 | title: "引用标准新建数据集", | ||
| 283 | }, | ||
| 284 | type: '', | ||
| 285 | contents: [ | ||
| 286 | { | ||
| 287 | type: 'form', | ||
| 288 | title: '', | ||
| 289 | formInfo: { | ||
| 290 | id: 'select-subject-domain-list', | ||
| 291 | items: formItems.value, | ||
| 292 | rules: formRules.value | ||
| 293 | } | ||
| 294 | } | ||
| 295 | ], | ||
| 296 | footer: { | ||
| 297 | btns: [ | ||
| 298 | { type: "default", label: "取消", value: "cancel" }, | ||
| 299 | { type: "primary", label: "确定", value: "submit", loading: false }, | ||
| 300 | ], | ||
| 301 | }, | ||
| 302 | }); | ||
| 303 | |||
| 304 | const contextNodeData: any = ref({}); | ||
| 305 | |||
| 306 | const selectDataCatalogNodeObj: any = ref({}); | ||
| 307 | |||
| 308 | const handleTreeSelectNodeChange = (node, item, nodeObj) => { | ||
| 309 | selectDataCatalogNodeObj.value = nodeObj; | ||
| 310 | } | ||
| 311 | |||
| 312 | const dialogBtnClick = (btn, info) => { | ||
| 313 | if (btn.value == 'submit') { | ||
| 314 | dialogInfo.value.visible = false; | ||
| 315 | if (selectDataCatalogNodeObj.value.parent.data.layereAttribute == 2) { //维度 | ||
| 316 | router.push({ | ||
| 317 | name: 'dimTableCreateManual', | ||
| 318 | query: { | ||
| 319 | domainGuid: info.domainGuid, | ||
| 320 | domainName: selectDataCatalogNodeObj.value.data.name, | ||
| 321 | metaStandard: contextNodeData.value.guid, | ||
| 322 | standardName: contextNodeData.value.label | ||
| 323 | } | ||
| 324 | }); | ||
| 325 | } else { | ||
| 326 | if (selectDataCatalogNodeObj.value.parent.data.layereAttribute == 4) { | ||
| 327 | router.push({ | ||
| 328 | name: 'tableCreateManual', | ||
| 329 | query: { | ||
| 330 | domainGuid: info.domainGuid, | ||
| 331 | domainName: selectDataCatalogNodeObj.value.data.name, | ||
| 332 | metaStandard: contextNodeData.value.guid, | ||
| 333 | layereAttribute: selectDataCatalogNodeObj.value.parent.data.layereAttribute, | ||
| 334 | standardName: contextNodeData.value.label | ||
| 335 | } | ||
| 336 | }); | ||
| 337 | } else { | ||
| 338 | router.push({ | ||
| 339 | name: 'tableCreateManual', | ||
| 340 | query: { | ||
| 341 | domainGuid: info.domainGuid, | ||
| 342 | domainName: selectDataCatalogNodeObj.value.data.name, | ||
| 343 | metaStandard: contextNodeData.value.guid, | ||
| 344 | standardName: contextNodeData.value.label | ||
| 345 | } | ||
| 346 | }); | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } else if (btn.value == 'cancel') { | ||
| 350 | dialogInfo.value.visible = false; | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | </script> | ||
| 355 | |||
| 356 | <template> | ||
| 357 | <div class="container_wrap full flex"> | ||
| 358 | <div class="aside_wrap"> | ||
| 359 | <div class="aside_title">元数据标准列表</div> | ||
| 360 | <Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" /> | ||
| 361 | </div> | ||
| 362 | <div class="main_wrap"> | ||
| 363 | <div v-show="lastClickNode?.guid" className='g6-component-topbar'> | ||
| 364 | <graphTopbar ref="topBarRef" @displaySwitchChange="displaySwitchChange" :isGraphDisplay="isGraphDisplay" /> | ||
| 365 | </div> | ||
| 366 | <RelationNetwork v-show="lastClickNode?.guid && isGraphDisplay" ref="relationNetworkRef" | ||
| 367 | :tree-data="lastClickNode" v-loading="treeDataLoading" @nodeItemClick="handleNodeItemClick" | ||
| 368 | @contextMenu="handleContextMenu"> | ||
| 369 | </RelationNetwork> | ||
| 370 | <Sankey v-show="lastClickNode?.guid && !isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)" | ||
| 371 | v-loading="sankeyDataLoading" :tree-data="sankeyData" :names="sankeyNames"> | ||
| 372 | </Sankey> | ||
| 373 | <div | ||
| 374 | v-show="(!lastClickNode?.guid || !treeInfo.data?.length) && !treeInfo.loading || (!isGraphDisplay && !sankeyDataLoading && !sankeyNames?.length)" | ||
| 375 | class="main-placeholder"> | ||
| 376 | <img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" /> | ||
| 377 | <div class="empty-text">{{ treeInfo.data.length && !lastClickNode?.guid ? '请选中二级及以下级别标准查看' : '暂无数据' }}</div> | ||
| 378 | </div> | ||
| 379 | </div> | ||
| 380 | <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @treeSelectNodeChange="handleTreeSelectNodeChange" /> | ||
| 381 | </div> | ||
| 382 | </template> | ||
| 383 | |||
| 384 | <style scoped lang="scss"> | ||
| 385 | .container_wrap { | ||
| 386 | |||
| 387 | .aside_wrap { | ||
| 388 | width: 200px; | ||
| 389 | margin-right: 1px; | ||
| 390 | } | ||
| 391 | |||
| 392 | .main_wrap { | ||
| 393 | position: relative; | ||
| 394 | |||
| 395 | :deep(.canvas-wrapper) { | ||
| 396 | background-color: #f7f7f9; | ||
| 397 | } | ||
| 398 | |||
| 399 | .main-placeholder { | ||
| 400 | height: 100%; | ||
| 401 | display: flex; | ||
| 402 | justify-content: center; | ||
| 403 | align-items: center; | ||
| 404 | flex-direction: column; | ||
| 405 | |||
| 406 | .empty-text { | ||
| 407 | font-size: 14px; | ||
| 408 | color: #b2b2b2; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | } | ||
| 414 | |||
| 415 | .g6-component-topbar { | ||
| 416 | position: absolute; | ||
| 417 | left: 24px; | ||
| 418 | bottom: unset; | ||
| 419 | top: 14px; | ||
| 420 | padding: 0; | ||
| 421 | text-align: center; | ||
| 422 | z-index: 999; | ||
| 423 | } | ||
| 424 | |||
| 425 | .container_wrap.flex .main_wrap { | ||
| 426 | padding: 0px; | ||
| 427 | } | ||
| 428 | |||
| 429 | .tree_panel { | ||
| 430 | height: calc(100% - 36px); | ||
| 431 | padding-top: 0; | ||
| 432 | |||
| 433 | :deep(.el-tree) { | ||
| 434 | margin: 0; | ||
| 435 | overflow: hidden auto; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 | .card-noData { | ||
| 440 | height: 100%; | ||
| 441 | width: 100%; | ||
| 442 | background: #fafafa; | ||
| 443 | display: flex; | ||
| 444 | flex-direction: column; | ||
| 445 | justify-content: center; | ||
| 446 | align-items: center; | ||
| 447 | color: #909399; | ||
| 448 | font-size: 14px; | ||
| 449 | } | ||
| 450 | |||
| 451 | :deep(.el-form .el-form-item) { | ||
| 452 | width: calc(100%); | ||
| 453 | // margin-right: 8px; | ||
| 454 | } | ||
| 455 | |||
| 456 | :deep(.el-message) { | ||
| 457 | position: fixed; | ||
| 458 | /* 使用fixed或absolute定位 */ | ||
| 459 | z-index: 10000; | ||
| 460 | /* 设置一个较高的z-index值确保在最上层显示 */ | ||
| 461 | } | ||
| 462 | </style> |
src/views/data_meta/standard.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | ame: metadataStandard | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="metadataStandard"> | ||
| 6 | import { ref, reactive, computed } from 'vue' | ||
| 7 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 8 | import { Search, CirclePlus } from '@element-plus/icons-vue' | ||
| 9 | import Tree from '@/components/Tree/index.vue' | ||
| 10 | import Table from '@/components/Table/index.vue' | ||
| 11 | import Drawer from '@/components/Drawer/index.vue' | ||
| 12 | import DictFileds from './components/dictFileds.vue' | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { download } from '@/utils/common' | ||
| 15 | import { getParamsList } from '@/api/modules/dataAsset' | ||
| 16 | import { getMetaStandardTree, deleteMetaStandard, | ||
| 17 | getMetaStandardDataList, getMetaStandardDataFields, | ||
| 18 | deleteMetaStandardDataFields, exportMetaStandardData | ||
| 19 | } from '@/api/modules/dataMetaService' | ||
| 20 | import router from '@/router' | ||
| 21 | import { TableColumnWidth } from '@/utils/enum'; | ||
| 22 | import StandardDialog from './components/standardDialog.vue' | ||
| 23 | import StandardFieldsDialog from './components/standardFieldsDialog.vue' | ||
| 24 | function getAssetsImages(name) { | ||
| 25 | return new URL(`../../assets/images/${name}`, import.meta.url).href; | ||
| 26 | } | ||
| 27 | const { proxy } = getCurrentInstance() as any; | ||
| 28 | |||
| 29 | const route = useRoute(); | ||
| 30 | |||
| 31 | const cacheStore = useCatchStore() | ||
| 32 | const showFiledsPage = ref(false) | ||
| 33 | |||
| 34 | // 树菜单 | ||
| 35 | const dictTreeRef = ref() | ||
| 36 | const treeInfo = ref({ | ||
| 37 | id: "data-pickup-tree", | ||
| 38 | filter: true, | ||
| 39 | queryValue: "", | ||
| 40 | queryPlaceholder: "请输入关键字搜索", | ||
| 41 | props: { | ||
| 42 | label: "standardName", | ||
| 43 | value: "guid", | ||
| 44 | isLeaf: "isLeaf", | ||
| 45 | }, | ||
| 46 | // lazy: true, | ||
| 47 | nodeKey: 'guid', | ||
| 48 | expandedKey: [], | ||
| 49 | currentNodeKey: '', | ||
| 50 | data: [], | ||
| 51 | expandOnNodeClick: false, | ||
| 52 | loading: false, | ||
| 53 | currentObj: {}, | ||
| 54 | editTreeItem: true, | ||
| 55 | // className: 'tree-list', | ||
| 56 | ellipsis: false | ||
| 57 | }) | ||
| 58 | function nodeClick (data) { | ||
| 59 | console.log('nodeData', data) | ||
| 60 | treeInfo.value.currentObj = data | ||
| 61 | if (data.level == 1) return | ||
| 62 | getTableFields() | ||
| 63 | getFirstPageData() | ||
| 64 | } | ||
| 65 | function treeCustomClick (node, type) { | ||
| 66 | console.log(node, type) | ||
| 67 | if (type === 'edit') { | ||
| 68 | // 编辑 | ||
| 69 | standardDialog.type = 'edit' | ||
| 70 | standardDialog.guid = node.data.guid | ||
| 71 | node.data.level = node.level | ||
| 72 | standardDialog.currentNode = node.data | ||
| 73 | standardDialog.visible = true | ||
| 74 | return | ||
| 75 | } | ||
| 76 | if (type === 'delete') { | ||
| 77 | // 删除 | ||
| 78 | ElMessageBox.confirm('确定删除吗?', '提示', { | ||
| 79 | confirmButtonText: '确定', | ||
| 80 | cancelButtonText: '取消', | ||
| 81 | type: 'warning' | ||
| 82 | }).then(() => deleteTreeNode(node.data.guid)) | ||
| 83 | } | ||
| 84 | } | ||
| 85 | function getTree (refresh = false, initLocate = false) { | ||
| 86 | treeInfo.value.loading = true; | ||
| 87 | getMetaStandardTree().then((res:any) => { | ||
| 88 | treeInfo.value.loading = false; | ||
| 89 | if (res.code === proxy.$passCode) { | ||
| 90 | let data = res.data || [] | ||
| 91 | data.forEach(item => { | ||
| 92 | item.showEdit = true | ||
| 93 | item.level = 1 | ||
| 94 | }) | ||
| 95 | treeInfo.value.data = data | ||
| 96 | if (!initLocate) { | ||
| 97 | // treeInfo.value.expandedKey = [data[0].guid] | ||
| 98 | // treeInfo.value.currentNodeKey = data[0].guid | ||
| 99 | console.log('data', data) | ||
| 100 | let firstNode = data[0] | ||
| 101 | if (firstNode.children) { | ||
| 102 | firstNode = firstNode.children[0] | ||
| 103 | } | ||
| 104 | treeInfo.value.expandedKey = [firstNode.guid] | ||
| 105 | treeInfo.value.currentNodeKey = firstNode.guid | ||
| 106 | nodeClick(firstNode) | ||
| 107 | } | ||
| 108 | } | ||
| 109 | }) | ||
| 110 | } | ||
| 111 | function refreshTree (treeGuid) { | ||
| 112 | treeInfo.value.loading = true; | ||
| 113 | getMetaStandardTree().then((res:any) => { | ||
| 114 | treeInfo.value.loading = false; | ||
| 115 | if (res.code === proxy.$passCode) { | ||
| 116 | let data = res.data || [] | ||
| 117 | data.forEach(item => { | ||
| 118 | item.showEdit = true | ||
| 119 | item.level = 1 | ||
| 120 | }) | ||
| 121 | treeInfo.value.data = data | ||
| 122 | if (treeGuid) { | ||
| 123 | setTreeCurrentNode(treeGuid) | ||
| 124 | } | ||
| 125 | } | ||
| 126 | }) | ||
| 127 | } | ||
| 128 | function refreshTreeAndPage () { | ||
| 129 | refreshTree() | ||
| 130 | getFirstPageData() | ||
| 131 | } | ||
| 132 | function setTreeCurrentNode (treeGuid) { | ||
| 133 | treeInfo.value.currentNodeKey = treeGuid | ||
| 134 | let { data } = treeInfo.value | ||
| 135 | const format = (list) => { | ||
| 136 | list.forEach(item => { | ||
| 137 | if (item.guid === treeGuid) { | ||
| 138 | nodeClick(item) | ||
| 139 | return | ||
| 140 | } | ||
| 141 | if (item.children) { | ||
| 142 | format(item.children) | ||
| 143 | } | ||
| 144 | }) | ||
| 145 | } | ||
| 146 | format(data) | ||
| 147 | } | ||
| 148 | |||
| 149 | function deleteTreeNode (guid) { | ||
| 150 | deleteMetaStandard([guid]).then((res:any) => { | ||
| 151 | if (res.code === proxy.$passCode) { | ||
| 152 | ElMessage.success('删除成功') | ||
| 153 | getTree() | ||
| 154 | } else { | ||
| 155 | ElMessage.error(res.msg) | ||
| 156 | } | ||
| 157 | }) | ||
| 158 | } | ||
| 159 | |||
| 160 | const tableSearchInput = ref('') | ||
| 161 | const currTableData: any = ref<Object>({}); | ||
| 162 | const page = ref({ | ||
| 163 | limit: 50, | ||
| 164 | curr: 1, | ||
| 165 | sizes: [ | ||
| 166 | { label: "10", value: 10 }, | ||
| 167 | { label: "50", value: 50 }, | ||
| 168 | { label: "100", value: 100 }, | ||
| 169 | { label: "150", value: 150 }, | ||
| 170 | { label: "200", value: 200 }, | ||
| 171 | ] | ||
| 172 | }) | ||
| 173 | const selectRowData = ref([]) | ||
| 174 | const selectedRowData = ref([]) | ||
| 175 | const tableInfo: any = ref({ | ||
| 176 | id: 'data-source-table', | ||
| 177 | multiple: true, | ||
| 178 | fixedSelection: true, | ||
| 179 | fields: [ | ||
| 180 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 181 | // { label: '数据源标识符', field: 'codeName', width: 140 }, | ||
| 182 | // { label: '数据元名称', field: 'standard', width: 140 }, | ||
| 183 | // { label: '定义', field: 'standardName', width: 140 }, | ||
| 184 | // { label: '数据类型', field: '', width: 120 }, | ||
| 185 | // { label: '表示格式', field: 'createTime', width: TableColumnWidth } | ||
| 186 | ], | ||
| 187 | data: [], | ||
| 188 | page: { | ||
| 189 | type: "normal", | ||
| 190 | rows: 0, | ||
| 191 | ...page.value, | ||
| 192 | }, | ||
| 193 | actionInfo: { | ||
| 194 | label: "操作", | ||
| 195 | type: "btn", | ||
| 196 | width: 92, //不要刚好90.缩小浏览器会因为小数点的差距而换行, | ||
| 197 | fixed: 'right', | ||
| 198 | btns: [ | ||
| 199 | // { label: '查看', value: 'detail'}, | ||
| 200 | { label: "编辑", value: "edit" }, | ||
| 201 | { label: "删除", value: "delete" }, | ||
| 202 | ], | ||
| 203 | }, | ||
| 204 | loading: false | ||
| 205 | }) | ||
| 206 | const standardFields = ref([]) | ||
| 207 | function getFirstPageData () { | ||
| 208 | page.value.curr = 1 | ||
| 209 | toSearch({}) | ||
| 210 | } | ||
| 211 | function toSearch (val: any, clear: boolean = false) { | ||
| 212 | let params: any = Object.keys(val).length ? { ...val } : {} | ||
| 213 | let { currentNodeKey, currentObj } = treeInfo.value | ||
| 214 | params.pageIndex = page.value.curr; | ||
| 215 | params.pageSize = page.value.limit; | ||
| 216 | params.metaStandardGuid = currentObj.guid | ||
| 217 | params.keyWords = tableSearchInput.value | ||
| 218 | getTable(params) | ||
| 219 | } | ||
| 220 | function getTable (params) { | ||
| 221 | tableInfo.value.loading = true | ||
| 222 | getMetaStandardDataList(params).then((res:any) => { | ||
| 223 | if (res.code === proxy.$passCode) { | ||
| 224 | let data = res.data | ||
| 225 | let list = res.data.records || [] | ||
| 226 | list.forEach((item:any) => { | ||
| 227 | Object.keys(item.metaStandardValue).forEach(key => { | ||
| 228 | item[key] = item.metaStandardValue[key] | ||
| 229 | }) | ||
| 230 | }) | ||
| 231 | tableInfo.value.data = list | ||
| 232 | tableInfo.value.page.limit = data.pageSize | ||
| 233 | tableInfo.value.page.curr = data.pageIndex | ||
| 234 | tableInfo.value.page.rows = data.totalRows | ||
| 235 | } | ||
| 236 | }).finally(() => tableInfo.value.loading = false) | ||
| 237 | } | ||
| 238 | function getTableFields () { | ||
| 239 | let { currentObj } = treeInfo.value | ||
| 240 | const indexField = { label: '序号', type: 'index', width: 56, align: 'center' } | ||
| 241 | getMetaStandardDataFields(currentObj.guid).then((res:any) => { | ||
| 242 | if (res.code === proxy.$passCode && res.data) { | ||
| 243 | const data = res.data | ||
| 244 | standardFields.value = data | ||
| 245 | const fields = data.map(item => { | ||
| 246 | return { | ||
| 247 | label: item.fileNameCodeName, | ||
| 248 | field: item.fileNameCode, | ||
| 249 | width: 140 | ||
| 250 | } | ||
| 251 | }) | ||
| 252 | fields.unshift(indexField) | ||
| 253 | tableInfo.value.fields = fields | ||
| 254 | } else { | ||
| 255 | tableInfo.value.fields = [indexField] | ||
| 256 | } | ||
| 257 | }) | ||
| 258 | } | ||
| 259 | function tablePageChange (info) { | ||
| 260 | page.value.curr = Number(info.curr) | ||
| 261 | page.value.limit = Number(info.limit) | ||
| 262 | toSearch({}) | ||
| 263 | } | ||
| 264 | function tableBtnClick (scope, btn) { | ||
| 265 | console.log(scope, btn) | ||
| 266 | const type = btn.value | ||
| 267 | const row = scope.row | ||
| 268 | if (type === 'edit') { | ||
| 269 | openStandardFieldsDialog(type, row) | ||
| 270 | } else if (type === 'delete') { | ||
| 271 | ElMessageBox.confirm('确定删除吗?', '提示', { | ||
| 272 | confirmButtonText: "确定", | ||
| 273 | cancelButtonText: "取消", | ||
| 274 | type: 'warning', | ||
| 275 | }).then(() => deleteStandardFields(row)) | ||
| 276 | } | ||
| 277 | } | ||
| 278 | function deleteStandardFields (row) { | ||
| 279 | deleteMetaStandardDataFields([row.guid]).then((res:any) => { | ||
| 280 | if (res.code === proxy.$passCode) { | ||
| 281 | ElMessage.success('删除成功') | ||
| 282 | refreshTreeAndPage() | ||
| 283 | } else { | ||
| 284 | ElMessage.error(res.msg) | ||
| 285 | } | ||
| 286 | }) | ||
| 287 | } | ||
| 288 | |||
| 289 | const formItems: any = ref([ | ||
| 290 | { | ||
| 291 | label: '中文名称', | ||
| 292 | type: 'input', | ||
| 293 | placeholder: '请输入', | ||
| 294 | field: 'codeName', | ||
| 295 | default: '', | ||
| 296 | maxlength: 20, | ||
| 297 | clearable: true, | ||
| 298 | required: true | ||
| 299 | }, | ||
| 300 | { | ||
| 301 | label: '英文生成规则', | ||
| 302 | type: 'select', | ||
| 303 | placeholder: '请选择', | ||
| 304 | field: 'publishingUnitCode', | ||
| 305 | default: '', | ||
| 306 | options: [], | ||
| 307 | clearable: true, | ||
| 308 | required: true | ||
| 309 | }, | ||
| 310 | { | ||
| 311 | label: '英文名称', | ||
| 312 | type: 'input', | ||
| 313 | placeholder: '请输入', | ||
| 314 | field: 'orderNum', | ||
| 315 | default: '', | ||
| 316 | maxlength: 2, | ||
| 317 | clearable: true, | ||
| 318 | required: true | ||
| 319 | }, | ||
| 320 | { | ||
| 321 | label: '标准编号', | ||
| 322 | type: 'input', | ||
| 323 | placeholder: '请选择', | ||
| 324 | field: 'codeFieldName', | ||
| 325 | default: '', | ||
| 326 | clearable: true, | ||
| 327 | required: true, | ||
| 328 | visible: true | ||
| 329 | }, | ||
| 330 | { | ||
| 331 | label: '标准集', | ||
| 332 | type: 'Select', | ||
| 333 | placeholder: '请选择', | ||
| 334 | field: 'hierarchy', | ||
| 335 | default: '', | ||
| 336 | options: [], | ||
| 337 | clearable: true, | ||
| 338 | visible: false | ||
| 339 | }, | ||
| 340 | { | ||
| 341 | label: '字段类型', | ||
| 342 | type: 'Select', | ||
| 343 | placeholder: '请选择', | ||
| 344 | field: 'hierarchy', | ||
| 345 | default: '', | ||
| 346 | options: [], | ||
| 347 | clearable: true, | ||
| 348 | visible: false | ||
| 349 | }, | ||
| 350 | { | ||
| 351 | label: '数据分类', | ||
| 352 | type: 'Select', | ||
| 353 | placeholder: '请选择', | ||
| 354 | field: 'hierarchy', | ||
| 355 | default: '', | ||
| 356 | options: [], | ||
| 357 | clearable: true, | ||
| 358 | visible: false | ||
| 359 | }, | ||
| 360 | { | ||
| 361 | label: '数据加密等级', | ||
| 362 | type: 'Select', | ||
| 363 | placeholder: '请选择', | ||
| 364 | field: 'hierarchy', | ||
| 365 | default: '', | ||
| 366 | options: [], | ||
| 367 | clearable: true, | ||
| 368 | visible: false | ||
| 369 | }, | ||
| 370 | { | ||
| 371 | label: '关联数据字典', | ||
| 372 | type: 'checkbox', | ||
| 373 | placeholder: '请选择', | ||
| 374 | field: 'hierarchy', | ||
| 375 | default: '', | ||
| 376 | options: [], | ||
| 377 | clearable: true, | ||
| 378 | visible: false | ||
| 379 | }, | ||
| 380 | { | ||
| 381 | label: '业务定义', | ||
| 382 | type: 'textarea', | ||
| 383 | placeholder: '请选择', | ||
| 384 | field: 'hierarchy', | ||
| 385 | default: '', | ||
| 386 | options: [], | ||
| 387 | clearable: true, | ||
| 388 | visible: false | ||
| 389 | } | ||
| 390 | ]) | ||
| 391 | const formRules: any = ref({ | ||
| 392 | standardTypeCode: { required: true, message: '请选择标准类型' }, | ||
| 393 | codeName: { required: true, message: '请输入代码名称' }, | ||
| 394 | standard: { required: true, message: '请输入标准号' }, | ||
| 395 | standardName: { required: true, message: '请输入标准名称' }, | ||
| 396 | publishingUnitCode: { required: true, message: '请选择发布单位' }, | ||
| 397 | orderNum: { required: true, message: '请输入排序' }, | ||
| 398 | typeCode: { required: true, message: '请选择代码类型' }, | ||
| 399 | codeFields: { required: true, message: '请选择编码字段' }, | ||
| 400 | codeFieldName: { required: true, message: '请选择编码名称' } | ||
| 401 | }) | ||
| 402 | const formInfo = ref({ | ||
| 403 | type: 'form', | ||
| 404 | title: '', | ||
| 405 | col: 'span', | ||
| 406 | formInfo: { | ||
| 407 | id: 'add-dict-form', | ||
| 408 | col: 'col2', | ||
| 409 | readonly: false, | ||
| 410 | items: formItems.value, | ||
| 411 | rules: formRules.value | ||
| 412 | } | ||
| 413 | }) | ||
| 414 | |||
| 415 | // 元标准dialog | ||
| 416 | const standardDialog = reactive({ | ||
| 417 | visible: false, | ||
| 418 | type: 'add', | ||
| 419 | guid: null, | ||
| 420 | currentNode: null | ||
| 421 | }) | ||
| 422 | function openStandardDialog () { | ||
| 423 | standardDialog.type = 'add' | ||
| 424 | standardDialog.visible = true | ||
| 425 | } | ||
| 426 | // 元标准数据dialog | ||
| 427 | const standardFieldsDialog = reactive({ | ||
| 428 | visible: false, | ||
| 429 | type: 'add', | ||
| 430 | metaStandardGuid: null, | ||
| 431 | data: {} | ||
| 432 | }) | ||
| 433 | function openStandardFieldsDialog (type, data = {}) { | ||
| 434 | standardFieldsDialog.type = type | ||
| 435 | standardFieldsDialog.metaStandardGuid = treeInfo.value.currentObj.guid | ||
| 436 | standardFieldsDialog.data = data | ||
| 437 | standardFieldsDialog.visible = true | ||
| 438 | } | ||
| 439 | |||
| 440 | function importData () { | ||
| 441 | let currentTreeObj:any = treeInfo.value.currentObj | ||
| 442 | console.log('currentTree', currentTreeObj) | ||
| 443 | let uploadSetting:any = [] | ||
| 444 | if (currentTreeObj.children) { | ||
| 445 | formatChildrenLastItem(currentTreeObj.children, uploadSetting) | ||
| 446 | } else { | ||
| 447 | uploadSetting = [{ | ||
| 448 | standardName: currentTreeObj.standardName, | ||
| 449 | standardGuid: currentTreeObj.guid | ||
| 450 | }] | ||
| 451 | } | ||
| 452 | cacheStore.setCatch('uploadSetting', uploadSetting) | ||
| 453 | router.push({ | ||
| 454 | path: '/data-meta/metadata-standard/standard-meta-import', | ||
| 455 | }); | ||
| 456 | } | ||
| 457 | function formatChildrenLastItem (list, returnList = []) { | ||
| 458 | list.forEach((item:any) => { | ||
| 459 | if (!item.children) { | ||
| 460 | returnList.push({ | ||
| 461 | standardName: item.standardName, | ||
| 462 | standardGuid: item.guid | ||
| 463 | }) | ||
| 464 | } else { | ||
| 465 | formatChildrenLastItem(item.children, returnList) | ||
| 466 | } | ||
| 467 | }) | ||
| 468 | } | ||
| 469 | |||
| 470 | function exportData () { | ||
| 471 | let body = [treeInfo.value.currentObj.guid] | ||
| 472 | exportMetaStandardData(body).then((res:any) => { | ||
| 473 | if (res && !res.msg) { | ||
| 474 | download(res, '元数据标准表.xlsx', 'excel') | ||
| 475 | } else { | ||
| 476 | res?.msg && ElMessage.error(res?.msg); | ||
| 477 | } | ||
| 478 | }) | ||
| 479 | } | ||
| 480 | |||
| 481 | function tableSelectionChange (list) { | ||
| 482 | selectedRowData.value = list | ||
| 483 | } | ||
| 484 | function batchDelete () { | ||
| 485 | // console.log(selectedRowData.value) | ||
| 486 | let selectRowGuids = selectedRowData.value.map(v => v.guid) | ||
| 487 | if (selectRowGuids.length === 0) { | ||
| 488 | ElMessage.error('请选择需要删除的数据') | ||
| 489 | return | ||
| 490 | } | ||
| 491 | ElMessageBox.confirm('确定删除吗?', '提示', { | ||
| 492 | confirmButtonText: "确定", | ||
| 493 | cancelButtonText: "取消", | ||
| 494 | type: 'warning', | ||
| 495 | }).then(() => { | ||
| 496 | deleteMetaStandardDataFields(selectRowGuids).then((res:any) => { | ||
| 497 | if (res.code === proxy.$passCode) { | ||
| 498 | ElMessage.success('删除成功') | ||
| 499 | refreshTreeAndPage() | ||
| 500 | } else { | ||
| 501 | ElMessage.error(res.msg) | ||
| 502 | } | ||
| 503 | }) | ||
| 504 | }) | ||
| 505 | } | ||
| 506 | |||
| 507 | /** 从关系网定位打开此页面,需定位到对应的树节点。 route.query.standardGuid */ | ||
| 508 | |||
| 509 | onActivated(() => { | ||
| 510 | if (route.query.standardGuid) { | ||
| 511 | treeInfo.value.currentNodeKey = route.query.standardGuid as string; | ||
| 512 | let obj = { | ||
| 513 | guid: route.query.standardGuid, | ||
| 514 | standardName: route.query.name | ||
| 515 | } | ||
| 516 | treeInfo.value.currentObj = obj; | ||
| 517 | nodeClick(obj); | ||
| 518 | } | ||
| 519 | }) | ||
| 520 | |||
| 521 | onBeforeMount(() => { | ||
| 522 | getTree(false, route.query.standardGuid != null) | ||
| 523 | }) | ||
| 524 | |||
| 525 | const viewGraph = () => { | ||
| 526 | router.push({ | ||
| 527 | name: 'metadataStandardQueryView', | ||
| 528 | query: { | ||
| 529 | guid: treeInfo.value.currentObj?.guid, | ||
| 530 | name: treeInfo.value.currentObj?.standardName, | ||
| 531 | } | ||
| 532 | }); | ||
| 533 | } | ||
| 534 | |||
| 535 | </script> | ||
| 536 | |||
| 537 | <template> | ||
| 538 | <div class="container_wrap full flex standard"> | ||
| 539 | <div class="aside_wrap"> | ||
| 540 | <div class="aside_title"> | ||
| 541 | 元数据标准列表 | ||
| 542 | <el-icon color="#4fa1a4" @click="openStandardDialog" :size="20" class="custom-icon"> | ||
| 543 | <CirclePlus /> | ||
| 544 | </el-icon> | ||
| 545 | </div> | ||
| 546 | <Tree ref="dictTreeRef" :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="treeCustomClick"> | ||
| 547 | <template #default="{ node, data }"> | ||
| 548 | {{ node.label }} | ||
| 549 | </template> | ||
| 550 | </Tree> | ||
| 551 | </div> | ||
| 552 | <div class="main_wrap"> | ||
| 553 | <template v-if="treeInfo.currentObj.level != 1"> | ||
| 554 | <div class="header" style="font-size:16px;font-weight:bold;margin-top:8px;color:#212121">{{ treeInfo.currentObj.standardName }}</div> | ||
| 555 | <div class="table_tool_wrap"> | ||
| 556 | <div class="tools_btns"> | ||
| 557 | <el-button type="primary" | ||
| 558 | @click="() => openStandardFieldsDialog('add')" | ||
| 559 | :disabled="treeInfo.currentObj.children" | ||
| 560 | v-preReClick>新建</el-button> | ||
| 561 | <el-button @click="importData" v-preReClick>导入</el-button> | ||
| 562 | <el-button @click="exportData" v-preReClick>导出</el-button> | ||
| 563 | <el-button @click="viewGraph" v-preReClick>查看</el-button> | ||
| 564 | <el-button @click="batchDelete">批量删除</el-button> | ||
| 565 | </div> | ||
| 566 | <el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="请输入关键字搜索" | ||
| 567 | :suffix-icon="Search" clearable @change="val => getFirstPageData()" /> | ||
| 568 | </div> | ||
| 569 | <div class="table_panel_wrap full" style="height:calc(100% - 84px)"> | ||
| 570 | <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange" | ||
| 571 | @tablePageChange="tablePageChange"/> | ||
| 572 | </div> | ||
| 573 | </template> | ||
| 574 | |||
| 575 | <div v-else class="no-content"> | ||
| 576 | <img :src="getAssetsImages('no-data.png')" :style="{ width: '96px', height: '96px' }" /> | ||
| 577 | <span>请选择标准表</span> | ||
| 578 | </div> | ||
| 579 | </div> | ||
| 580 | <StandardDialog | ||
| 581 | v-model="standardDialog.visible" | ||
| 582 | :standardOptions="treeInfo.data" | ||
| 583 | :type="standardDialog.type" | ||
| 584 | :guid="standardDialog.guid" | ||
| 585 | :currentNode="standardDialog.currentNode" | ||
| 586 | @success="refreshTree" | ||
| 587 | /> | ||
| 588 | <StandardFieldsDialog | ||
| 589 | v-model="standardFieldsDialog.visible" | ||
| 590 | :fields="standardFields" | ||
| 591 | :type="standardFieldsDialog.type" | ||
| 592 | :metaStandardGuid="standardFieldsDialog.metaStandardGuid" | ||
| 593 | :data="standardFieldsDialog.data" | ||
| 594 | @success="refreshTreeAndPage" | ||
| 595 | /> | ||
| 596 | </div> | ||
| 597 | </template> | ||
| 598 | |||
| 599 | <style lang="scss"> | ||
| 600 | |||
| 601 | </style> | ||
| 602 | <style lang="scss" scoped> | ||
| 603 | .no-content { | ||
| 604 | height: 96%; | ||
| 605 | display: flex; | ||
| 606 | flex-direction: column; | ||
| 607 | justify-content: center; | ||
| 608 | align-items: center; | ||
| 609 | } | ||
| 610 | .container_wrap { | ||
| 611 | .aside_wrap { | ||
| 612 | width: 200px; | ||
| 613 | } | ||
| 614 | .aside_title { | ||
| 615 | display: flex; | ||
| 616 | justify-content: space-between; | ||
| 617 | align-items: center; | ||
| 618 | } | ||
| 619 | } | ||
| 620 | |||
| 621 | .tree_panel { | ||
| 622 | height: 100%; | ||
| 623 | padding-top: 0; | ||
| 624 | |||
| 625 | :deep(.el-tree) { | ||
| 626 | margin: 0; | ||
| 627 | height: calc(100% - 68px); | ||
| 628 | overflow: hidden auto; | ||
| 629 | } | ||
| 630 | } | ||
| 631 | </style> | ||
| 632 | |||
| 633 | <style lang="scss"> | ||
| 634 | .standard { | ||
| 635 | .custom-icon { | ||
| 636 | svg { | ||
| 637 | width: auto; | ||
| 638 | height: auto; | ||
| 639 | } | ||
| 640 | } | ||
| 641 | } | ||
| 642 | .tree_panel .el-tree .el-tree-node__content { | ||
| 643 | position: relative; | ||
| 644 | .list-item-text { | ||
| 645 | width: calc(100% - 58px)!important; | ||
| 646 | } | ||
| 647 | .tags-list-right { | ||
| 648 | position: absolute; | ||
| 649 | right: 2px; | ||
| 650 | top:8px; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | </style> |
src/views/data_meta/tableCreateManual.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: tableCreateManual | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="tableCreateManual"> | ||
| 6 | import { ref } from "vue"; | ||
| 7 | import { useRouter, useRoute } from "vue-router"; | ||
| 8 | import { ElMessage, ElMessageBox, ElTable } from "element-plus"; | ||
| 9 | import { QuestionFilled } from "@element-plus/icons-vue"; | ||
| 10 | import { | ||
| 11 | getDatabase, | ||
| 12 | saveSubjectTable, | ||
| 13 | syncPolicys, | ||
| 14 | tableModels, | ||
| 15 | tableCategoryList, | ||
| 16 | getDimList, | ||
| 17 | getDictionary, | ||
| 18 | aggMethodList, | ||
| 19 | getMetaStandardDsField, | ||
| 20 | getAllFlowData | ||
| 21 | } from "@/api/modules/dataMetaService"; | ||
| 22 | import useUserStore from "@/store/modules/user"; | ||
| 23 | import expandPropertyDialog from "./components/expandPropertyDialog.vue"; | ||
| 24 | import tableDefaultValue from "./components/tableDefaultValue.vue"; | ||
| 25 | import { useDefault } from "@/hooks/useDefault" | ||
| 26 | import { getCamundaDeploymentId } from "@/api/modules/workFlowService" | ||
| 27 | |||
| 28 | const userStore = useUserStore(); | ||
| 29 | const { checkDefault } = useDefault() | ||
| 30 | const router = useRouter(); | ||
| 31 | const route = useRoute(); | ||
| 32 | const flowExpand = ref(true); | ||
| 33 | const deploymentId = ref(''); | ||
| 34 | const fullPath = route.fullPath; | ||
| 35 | const isLook = <any>route.query.isLook == 1; | ||
| 36 | const subjectDomainGuid: any = ref(route.query.domainGuid); | ||
| 37 | const { proxy } = getCurrentInstance() as any; | ||
| 38 | const fieldStandardTableRef = ref<InstanceType<typeof ElTable>>(); | ||
| 39 | |||
| 40 | /** 表模型,只有doris数据库才有 */ | ||
| 41 | const dbType = ref(""); | ||
| 42 | |||
| 43 | const databaseList: any = ref([]); | ||
| 44 | |||
| 45 | const tableFieldsLoading = ref(false); | ||
| 46 | |||
| 47 | const tableCreateInfoLoading = ref(false); | ||
| 48 | |||
| 49 | //记录当前正在编辑的表创建信息。 | ||
| 50 | const tableCreateInfo: Ref<any> = ref({ | ||
| 51 | guid: "", | ||
| 52 | isCreate: false, | ||
| 53 | inputNameValue: '', | ||
| 54 | tableCreateType: 1, | ||
| 55 | tableData: [ | ||
| 56 | { | ||
| 57 | //数据库表信息。 | ||
| 58 | dataSourceGuid: '', | ||
| 59 | dataServerName: "", | ||
| 60 | dataServerChName: "", | ||
| 61 | enName: "", | ||
| 62 | chName: "", | ||
| 63 | subjectDomain: route.query.domainName, | ||
| 64 | subjectDomainGuid: subjectDomainGuid.value, | ||
| 65 | tableCategory: route.query.layereAttribute == '3' ? 6 : 1, | ||
| 66 | syncPolicy: 3, | ||
| 67 | characterSet: 'utf8mb3', | ||
| 68 | tableModel: 1, //若是聚合模型,下方出现一列聚合方式选择。处了主键列,其余列都需要选择。每个表里都要有主键。 | ||
| 69 | description: "", | ||
| 70 | }, | ||
| 71 | ], | ||
| 72 | partitionAttribute: {}, | ||
| 73 | tableFields: [], // 字段标准数组。 | ||
| 74 | }); | ||
| 75 | |||
| 76 | const selectTableFieldRows = ref([]); | ||
| 77 | |||
| 78 | //字段类型 | ||
| 79 | const fieldTypes: any = ref([]); | ||
| 80 | |||
| 81 | //字符集 | ||
| 82 | const characterList: any = ref([]); | ||
| 83 | |||
| 84 | //是否列表 | ||
| 85 | const isNotList = ref([ | ||
| 86 | { | ||
| 87 | label: "Y", | ||
| 88 | value: "Y", | ||
| 89 | }, | ||
| 90 | { | ||
| 91 | label: "N", | ||
| 92 | value: "N", | ||
| 93 | }, | ||
| 94 | ]); | ||
| 95 | |||
| 96 | //字典列表 | ||
| 97 | const dictionaryList: any = ref([]); | ||
| 98 | |||
| 99 | // 可选择的关联维度的列表。 | ||
| 100 | const dimListData: any = ref([]); | ||
| 101 | |||
| 102 | const fullscreenLoading = ref(false); | ||
| 103 | |||
| 104 | /** 表里有数据时不能修改字段类型,长度,精度 */ | ||
| 105 | const hasSubjectData = ref(false); | ||
| 106 | |||
| 107 | const expandProperties = ref({}); | ||
| 108 | |||
| 109 | onBeforeMount(() => { | ||
| 110 | getDatabaseList(); | ||
| 111 | getFieldTypeList(); | ||
| 112 | getCharacterListData(); | ||
| 113 | if (route.query.metaStandard) { | ||
| 114 | tableCreateInfo.value.tableData[0].chName = route.query.standardName; | ||
| 115 | fullscreenLoading.value = true; | ||
| 116 | getMetaStandardDsField(route.query.metaStandard).then((res: any) => { | ||
| 117 | fullscreenLoading.value = false; | ||
| 118 | if (res.code == proxy.$passCode) { | ||
| 119 | tableCreateInfo.value.tableFields = res.data?.map((d, i) => { | ||
| 120 | d.orderNum = i; | ||
| 121 | d.isEdit = true; | ||
| 122 | return d; | ||
| 123 | }) || []; | ||
| 124 | } else { | ||
| 125 | proxy.$ElMessage.error(res.msg); | ||
| 126 | } | ||
| 127 | }) | ||
| 128 | } | ||
| 129 | getCamundaDeploymentId('10025').then((res: any) => { | ||
| 130 | if (res.code == proxy.$passCode) { | ||
| 131 | deploymentId.value = res.data; | ||
| 132 | } else { | ||
| 133 | proxy.$ElMessage.error(res.msg); | ||
| 134 | } | ||
| 135 | }) | ||
| 136 | }) | ||
| 137 | |||
| 138 | onActivated(() => { | ||
| 139 | console.log("activated"); | ||
| 140 | getDictionaryList(); | ||
| 141 | getDimListData(); | ||
| 142 | }); | ||
| 143 | |||
| 144 | |||
| 145 | const getDatabaseList = () => { | ||
| 146 | getDatabase({ connectStatus: 1 }).then((res: any) => { | ||
| 147 | databaseList.value = []; | ||
| 148 | if (res.code == proxy.$passCode) { | ||
| 149 | databaseList.value = res.data || []; | ||
| 150 | } else { | ||
| 151 | ElMessage.error(res.msg); | ||
| 152 | } | ||
| 153 | }) | ||
| 154 | }; | ||
| 155 | |||
| 156 | const getDictionaryList = () => { | ||
| 157 | getDictionary({}).then((res: any) => { | ||
| 158 | dictionaryList.value = []; | ||
| 159 | if (res.code == proxy.$passCode) { | ||
| 160 | dictionaryList.value = res.data || []; | ||
| 161 | dimOrDictList.value[0].children = dictionaryList.value; | ||
| 162 | dimOrDictList.value[0].disabled = !dictionaryList.value.length; | ||
| 163 | } else { | ||
| 164 | ElMessage.error(res.msg); | ||
| 165 | } | ||
| 166 | }) | ||
| 167 | }; | ||
| 168 | |||
| 169 | const getDimListData = () => { | ||
| 170 | getDimList().then((res: any) => { | ||
| 171 | dimListData.value = []; | ||
| 172 | if (res.code == proxy.$passCode) { | ||
| 173 | dimListData.value = res.data?.map(r => { | ||
| 174 | return { | ||
| 175 | guid: r.guid, | ||
| 176 | chName: r.chName, | ||
| 177 | subjectDomainName: r.subjectDomainName, | ||
| 178 | parentGuid: '2' | ||
| 179 | } | ||
| 180 | }) || []; | ||
| 181 | dimOrDictList.value[1].children = dimListData.value; | ||
| 182 | dimOrDictList.value[1].disabled = !dimListData.value.length; | ||
| 183 | } else { | ||
| 184 | ElMessage.error(res.msg); | ||
| 185 | } | ||
| 186 | }) | ||
| 187 | }; | ||
| 188 | |||
| 189 | const getFieldTypeList = () => { | ||
| 190 | getAllFlowData('字段类型').then((res: any) => { | ||
| 191 | fieldTypes.value = []; | ||
| 192 | if (res.code == proxy.$passCode) { | ||
| 193 | fieldTypes.value = res.data || []; | ||
| 194 | } else { | ||
| 195 | ElMessage.error(res.msg); | ||
| 196 | } | ||
| 197 | }) | ||
| 198 | } | ||
| 199 | |||
| 200 | const getCharacterListData = () => { | ||
| 201 | getAllFlowData('Mysql字符集').then((res: any) => { | ||
| 202 | characterList.value = []; | ||
| 203 | if (res.code == proxy.$passCode) { | ||
| 204 | characterList.value = res.data || []; | ||
| 205 | } else { | ||
| 206 | ElMessage.error(res.msg); | ||
| 207 | } | ||
| 208 | }) | ||
| 209 | } | ||
| 210 | |||
| 211 | /** 限制长度输入框只能输入整型数字,表,字段英文名称,限制输入字符,数字和下划线。 */ | ||
| 212 | const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null) => { | ||
| 213 | scope.row[field] = scope.row[field].replace(regexp, ''); | ||
| 214 | if (field == 'fieldLength' && scope.row.dataType == 'decimal') { | ||
| 215 | max = 65; | ||
| 216 | } | ||
| 217 | /** 最大值设置2000 */ | ||
| 218 | if (max && scope.row[field] > max) { | ||
| 219 | scope.row[field] = max; | ||
| 220 | } | ||
| 221 | if (min !== null && scope.row[field] != '' && scope.row[field] <= min) { | ||
| 222 | scope.row[field] = min; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | /** 保存表 */ | ||
| 227 | const saveTable = () => { | ||
| 228 | let tableData = tableCreateInfo.value.tableData[0]; | ||
| 229 | if (!tableData.chName) { | ||
| 230 | ElMessage({ | ||
| 231 | type: "error", | ||
| 232 | message: "主题表名称不能为空", | ||
| 233 | }); | ||
| 234 | return; | ||
| 235 | } | ||
| 236 | if (!tableData.dataServerName) { | ||
| 237 | ElMessage({ | ||
| 238 | type: "error", | ||
| 239 | message: "数据源不能为空", | ||
| 240 | }); | ||
| 241 | return; | ||
| 242 | } | ||
| 243 | if (tableData.dataServerName.indexOf('-') > -1) { | ||
| 244 | ElMessage.error('数据库表名称不能包含中划线,可以改为下划线'); | ||
| 245 | return; | ||
| 246 | } | ||
| 247 | if (!tableCreateInfo.value.inputNameValue) { | ||
| 248 | ElMessage({ | ||
| 249 | type: "error", | ||
| 250 | message: "主题表名称不能为空", | ||
| 251 | }); | ||
| 252 | return; | ||
| 253 | } | ||
| 254 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 255 | if (!tableFields.length) { | ||
| 256 | ElMessage({ | ||
| 257 | type: "error", | ||
| 258 | message: "表字段不能为0行", | ||
| 259 | }); | ||
| 260 | return; | ||
| 261 | } | ||
| 262 | // 若开启了字段标准,则不能为空。 | ||
| 263 | // 必须含有主键。若是聚合模型,则除了主键必须有聚合方式。 | ||
| 264 | let isSumModel = tableData.tableModel === 2; | ||
| 265 | let hasPrimary = false; | ||
| 266 | let enNames: any = []; | ||
| 267 | let chNames: any = []; | ||
| 268 | const regex = /^[a-zA-Z]/; | ||
| 269 | for (const field of tableFields) { | ||
| 270 | if (!field.enName) { | ||
| 271 | ElMessage.error(`第 ${field.orderNum} 个字段的英文名称不能为空`); | ||
| 272 | return; | ||
| 273 | } | ||
| 274 | if (!regex.test(field.enName)) { | ||
| 275 | ElMessage.error(`第 ${field.orderNum} 个字段的英文名称必须以英文字符开头`); | ||
| 276 | return; | ||
| 277 | } | ||
| 278 | if (!field.dataType) { | ||
| 279 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型不能为空`); | ||
| 280 | return; | ||
| 281 | } | ||
| 282 | if (enNames.indexOf(field.enName) > -1) { | ||
| 283 | ElMessage.error(`字段的英文名称 ${field.enName} 不能重复`); | ||
| 284 | return; | ||
| 285 | } | ||
| 286 | if (chNames.indexOf(field.chName) > -1) { | ||
| 287 | ElMessage.error(`字段的中文名称 ${field.chName} 不能重复`); | ||
| 288 | return; | ||
| 289 | } | ||
| 290 | if (field.dataType === "decimal" && (!field.fieldPrecision && field.fieldPrecision != 0)) { | ||
| 291 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为浮点型时,精度不能为空`); | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | if (field.dataType === "varchar" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 295 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为字符型时,长度不能为空`); | ||
| 296 | return; | ||
| 297 | } | ||
| 298 | if (field.dataType === "char" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 299 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为单字符型时,长度不能为空`); | ||
| 300 | return; | ||
| 301 | } | ||
| 302 | if (field.dataType === "decimal" && (!field.fieldLength && field.fieldLength != 0)) { | ||
| 303 | ElMessage.error(`第 ${field.orderNum} 个字段的字段类型为浮点符型时,长度不能为空`); | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | if (field.isPrimary === 'Y') { | ||
| 307 | hasPrimary = true; | ||
| 308 | if (field.notNull != 'Y') { | ||
| 309 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,应设置为必填`); | ||
| 310 | return; | ||
| 311 | } | ||
| 312 | if (field.dataType == 'text') { | ||
| 313 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘大字段型’`); | ||
| 314 | return; | ||
| 315 | } | ||
| 316 | if (field.dataType == 'json') { | ||
| 317 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘JSON类型’`); | ||
| 318 | return; | ||
| 319 | } | ||
| 320 | if (field.dataType == 'bit') { | ||
| 321 | ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘布尔类型’`); | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | } else { | ||
| 325 | if (!field.aggWay && isSumModel) { | ||
| 326 | ElMessage.error(`聚合模型的非主键字段必须设置聚合方式`); | ||
| 327 | return; | ||
| 328 | } | ||
| 329 | } | ||
| 330 | if (field.isEdit) { | ||
| 331 | if (checkDefault[field.dataType]) { | ||
| 332 | if (!field.fieldLength) { } | ||
| 333 | if (!checkDefault[field.dataType]({ row: field })) { | ||
| 334 | return; | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | field.fieldStandardGuid = route.query.metaStandard; | ||
| 339 | enNames.push(field.enName); | ||
| 340 | chNames.push(field.chName); | ||
| 341 | } | ||
| 342 | if (!hasPrimary) { | ||
| 343 | ElMessage.error(`字段至少有一个主键字段!`); | ||
| 344 | return; | ||
| 345 | } | ||
| 346 | let addInfo = Object.assign({}, tableCreateInfo.value.tableData[0], { | ||
| 347 | enName: tableCreateInfo.value.inputNameValue, | ||
| 348 | tableCreateType: tableCreateInfo.value.tableCreateType, | ||
| 349 | saveFlag: 1, | ||
| 350 | layereAttribute: route.query.layereAttribute, | ||
| 351 | dbType: dbType.value, | ||
| 352 | dataState: 1, | ||
| 353 | immediateApprove: true, | ||
| 354 | partitionAttribute: !Object.keys(tableCreateInfo.value.partitionAttribute).length ? null : Object.assign({}, tableCreateInfo.value.partitionAttribute, { | ||
| 355 | dynamicPartitionHistory: tableCreateInfo.value.partitionAttribute ? "Y" : 'N' | ||
| 356 | }), | ||
| 357 | subjectFieldAddDTOS: tableCreateInfo.value.tableFields.map((field, i) => { | ||
| 358 | return Object.assign({}, field, { orderNum: i + 1 }); | ||
| 359 | }) | ||
| 360 | }) | ||
| 361 | if (!tableCreateInfo.value.guid) { //添加 | ||
| 362 | fullscreenLoading.value = true; | ||
| 363 | saveSubjectTable(addInfo).then((res: any) => { | ||
| 364 | fullscreenLoading.value = false; | ||
| 365 | if (res.code == proxy.$passCode) { | ||
| 366 | ElMessage.success('新建表提交成功!'); | ||
| 367 | router.push({ | ||
| 368 | name: 'metadataStandardQuery' | ||
| 369 | }); | ||
| 370 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 371 | } else { | ||
| 372 | ElMessage.error(res.msg); | ||
| 373 | } | ||
| 374 | }); | ||
| 375 | } | ||
| 376 | }; | ||
| 377 | |||
| 378 | //数据库选择改变,对应的表名称是否需要变化。需要根据此属性带出表名前缀,以及是否是doris数据库。 | ||
| 379 | const selectDatabaseChange = (val) => { | ||
| 380 | let d = databaseList.value.find(d => d.guid === val); | ||
| 381 | if (d) { | ||
| 382 | dbType.value = d.databaseType; | ||
| 383 | tableCreateInfo.value.tableData[0].dataSourceGuid = d.guid; | ||
| 384 | tableCreateInfo.value.tableData[0].dataServerName = d.databaseNameEn; | ||
| 385 | } else { | ||
| 386 | dbType.value = ""; | ||
| 387 | tableCreateInfo.value.tableData[0].dataSourceGuid = ''; | ||
| 388 | tableCreateInfo.value.tableData[0].dataServerName = ''; | ||
| 389 | } | ||
| 390 | tableCreateInfo.value.tableFields.forEach((tableField: any) => { | ||
| 391 | if (tableField['dataType'] === "datetime") { | ||
| 392 | tableField.defaultValue = "" | ||
| 393 | } | ||
| 394 | }) | ||
| 395 | }; | ||
| 396 | |||
| 397 | /** 添加字段标准 */ | ||
| 398 | const addField = () => { | ||
| 399 | let len = tableCreateInfo.value.tableFields.length; | ||
| 400 | tableCreateInfo.value.tableFields.push({ | ||
| 401 | orderNum: len + 1, | ||
| 402 | isDim: "N", | ||
| 403 | isPrimary: "N", | ||
| 404 | notNull: "N", | ||
| 405 | isEdit: true | ||
| 406 | }); | ||
| 407 | //设置选中表格当前新增行。 | ||
| 408 | fieldStandardTableRef.value?.setCurrentRow( | ||
| 409 | tableCreateInfo.value.tableFields[tableCreateInfo.value.tableFields.length - 1] | ||
| 410 | ); | ||
| 411 | nextTick(() => { | ||
| 412 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 413 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 414 | let rect = domScroll.getBoundingClientRect(); | ||
| 415 | let maxNum = len + 1; | ||
| 416 | if (maxNum * 36 > rect.height + domScroll.scrollTop) { | ||
| 417 | fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2) | ||
| 418 | } | ||
| 419 | }) | ||
| 420 | }; | ||
| 421 | |||
| 422 | /** 勾选字段标准选中变化。 */ | ||
| 423 | const selectionFieldsChange = (val) => { | ||
| 424 | selectTableFieldRows.value = val; | ||
| 425 | }; | ||
| 426 | |||
| 427 | /** | ||
| 428 | * 上移规则: | ||
| 429 | * 勾选多个时先从最上面开始逐个上移一行,若已经移到最上面一行,则不处理。 | ||
| 430 | */ | ||
| 431 | const moveUp = () => { | ||
| 432 | let selectRows = fieldStandardTableRef.value?.getSelectionRows(); | ||
| 433 | if (!selectRows.length) { | ||
| 434 | ElMessage.error('请先选择需要勾选的数据进行上移'); | ||
| 435 | return; | ||
| 436 | } | ||
| 437 | let data = tableCreateInfo.value.tableFields; | ||
| 438 | let selectRowIndexs: number[] = []; | ||
| 439 | let minNum: number = 0; | ||
| 440 | selectRows.forEach((row, i) => { | ||
| 441 | let orderNum = data.findIndex(d => d === row) + 1; | ||
| 442 | if (orderNum == 1) { | ||
| 443 | selectRowIndexs.push(orderNum); | ||
| 444 | minNum = orderNum; | ||
| 445 | return; | ||
| 446 | } | ||
| 447 | let topNum = orderNum - 1; | ||
| 448 | if (selectRowIndexs.includes(topNum)) { | ||
| 449 | //下一行也是选中的,则不做转换。 | ||
| 450 | return; | ||
| 451 | } | ||
| 452 | if (i === 0) { | ||
| 453 | minNum = topNum; | ||
| 454 | } | ||
| 455 | row.orderNum = topNum; | ||
| 456 | let changeRow = data[topNum - 1]; | ||
| 457 | changeRow.orderNum = orderNum; | ||
| 458 | selectRowIndexs.push(topNum); | ||
| 459 | data[topNum] = changeRow; | ||
| 460 | data[topNum - 1] = row; | ||
| 461 | }); | ||
| 462 | nextTick().then(() => { | ||
| 463 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 464 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 465 | if ((minNum * 36 - 38) < domScroll.scrollTop) { | ||
| 466 | let top = domScroll.scrollTop - 38; | ||
| 467 | fieldStandardTableRef.value?.setScrollTop(top < 0 ? 0 : top) | ||
| 468 | } | ||
| 469 | }); | ||
| 470 | } | ||
| 471 | |||
| 472 | /** | ||
| 473 | * 下移规则: | ||
| 474 | * 勾选多个时先从最下面开始逐个下移一行,若已经移到最下面一行,则不处理。 | ||
| 475 | */ | ||
| 476 | const moveDown = () => { | ||
| 477 | let selectRows = fieldStandardTableRef.value?.getSelectionRows(); | ||
| 478 | if (!selectRows.length) { | ||
| 479 | ElMessage.error('请先选择需要勾选的数据进行下移'); | ||
| 480 | return; | ||
| 481 | } | ||
| 482 | let data = tableCreateInfo.value.tableFields; | ||
| 483 | let selectRowIndexs: number[] = []; | ||
| 484 | let maxNum: number = 0; | ||
| 485 | selectRows.slice(0).reverse().forEach((row, i) => { | ||
| 486 | let orderNum = data.findIndex(d => d === row) + 1; | ||
| 487 | if (orderNum === data.length) { | ||
| 488 | maxNum = orderNum; | ||
| 489 | selectRowIndexs.push(orderNum); | ||
| 490 | return; | ||
| 491 | } | ||
| 492 | if (selectRowIndexs.includes(orderNum + 1)) { | ||
| 493 | //下一行也是选中的,则不做转换。 | ||
| 494 | return; | ||
| 495 | } | ||
| 496 | let bottomNum = orderNum + 1; | ||
| 497 | row.orderNum = bottomNum; | ||
| 498 | if (i === 0) { | ||
| 499 | maxNum = bottomNum; | ||
| 500 | } | ||
| 501 | let changeRow = data[bottomNum - 1]; | ||
| 502 | changeRow.orderNum = orderNum; | ||
| 503 | selectRowIndexs.push(bottomNum); | ||
| 504 | data[orderNum - 1] = changeRow; | ||
| 505 | data[bottomNum - 1] = row; | ||
| 506 | }); | ||
| 507 | nextTick(() => { | ||
| 508 | let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body'); | ||
| 509 | let domScroll = bodyWrapper.parentElement.parentElement; | ||
| 510 | let rect = domScroll.getBoundingClientRect(); | ||
| 511 | if (maxNum * 36 > rect.height + domScroll.scrollTop) { | ||
| 512 | fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2) | ||
| 513 | } | ||
| 514 | }) | ||
| 515 | } | ||
| 516 | |||
| 517 | /** 批量删除字段标准 */ | ||
| 518 | const delFeilds = () => { | ||
| 519 | if (selectTableFieldRows.value.length == 0) { | ||
| 520 | ElMessage({ | ||
| 521 | type: "info", | ||
| 522 | message: "请选择需要删除的字段", | ||
| 523 | }); | ||
| 524 | return; | ||
| 525 | } | ||
| 526 | if (tableCreateInfo.value.isCreate) { | ||
| 527 | if (selectTableFieldRows.value.find((row: any) => row.isPrimary === 'Y')) { | ||
| 528 | ElMessage.error('已建表不能删除主键字段'); | ||
| 529 | return; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | let hasCreateField = selectTableFieldRows.value.some((row: any) => row.isCreate === 'Y'); | ||
| 533 | ElMessageBox.confirm(hasCreateField && hasSubjectData.value ? '已选择的字段中含有已创建的表字段且有数据,此操作将永久删除,是否继续?' : "此操作将永久删除,是否继续?", "提示", { | ||
| 534 | confirmButtonText: "确定", | ||
| 535 | cancelButtonText: "取消", | ||
| 536 | type: "warning", | ||
| 537 | }) | ||
| 538 | .then(() => { | ||
| 539 | //此删除是直接从库里删除,还是点击保存后再删除呢??如果是入库删除,后,调用接口获取数据。 | ||
| 540 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 541 | selectTableFieldRows.value.forEach((r: any) => { | ||
| 542 | let index = tableFields.findIndex((t: any) => t.orderNum === r.orderNum); | ||
| 543 | if (index !== -1) { | ||
| 544 | tableFields.splice(index, 1); | ||
| 545 | } | ||
| 546 | }); | ||
| 547 | fieldStandardTableRef.value?.clearSelection(); | ||
| 548 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 549 | field.orderNum = i + 1; | ||
| 550 | }); | ||
| 551 | ElMessage({ | ||
| 552 | type: "success", | ||
| 553 | message: "删除成功", | ||
| 554 | }); | ||
| 555 | }) | ||
| 556 | .catch(() => { | ||
| 557 | ElMessage({ | ||
| 558 | type: "info", | ||
| 559 | message: "已取消删除", | ||
| 560 | }); | ||
| 561 | }); | ||
| 562 | }; | ||
| 563 | |||
| 564 | //点击编辑按钮 | ||
| 565 | const handleFieldClickEdit = (scope) => { | ||
| 566 | scope.row['isEdit'] = true; | ||
| 567 | }; | ||
| 568 | |||
| 569 | //点击保存按钮 | ||
| 570 | const handleFieldClickSave = (scope) => { | ||
| 571 | if (!scope.row.enName) { | ||
| 572 | ElMessage({ | ||
| 573 | type: "error", | ||
| 574 | message: "字段英文名不能为空!", | ||
| 575 | }); | ||
| 576 | return; | ||
| 577 | } | ||
| 578 | if (checkDefault[scope.row.dataType]) { | ||
| 579 | if (!scope.row.fieldLength) { } | ||
| 580 | if (!checkDefault[scope.row.dataType](scope)) { | ||
| 581 | return | ||
| 582 | } | ||
| 583 | } | ||
| 584 | scope.row['isEdit'] = false; | ||
| 585 | }; | ||
| 586 | |||
| 587 | const handleFieldDelete = (scope) => { | ||
| 588 | ElMessageBox.confirm(scope.row['isCreate'] === 'Y' && hasSubjectData.value ? '该字段已被创建且表中有数据,此操作将永久删除,是否继续?' : "此操作将永久删除,是否继续?", "提示", { | ||
| 589 | confirmButtonText: "确定", | ||
| 590 | cancelButtonText: "取消", | ||
| 591 | type: "warning", | ||
| 592 | }) | ||
| 593 | .then(() => { | ||
| 594 | //此删除是直接从库里删除,还是点击保存后再删除呢??如果是入库删除,后,调用接口获取数据。 | ||
| 595 | let tableFields = tableCreateInfo.value.tableFields; | ||
| 596 | tableFields.splice(scope.$index, 1); | ||
| 597 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 598 | field.orderNum = i + 1; | ||
| 599 | }); | ||
| 600 | tableCreateInfo.value.tableFields.forEach((field, i) => { | ||
| 601 | field.orderNum = i + 1; | ||
| 602 | }); | ||
| 603 | ElMessage({ | ||
| 604 | type: "success", | ||
| 605 | message: "删除成功", | ||
| 606 | }); | ||
| 607 | }) | ||
| 608 | .catch(() => { | ||
| 609 | ElMessage({ | ||
| 610 | type: "info", | ||
| 611 | message: "已取消删除", | ||
| 612 | }); | ||
| 613 | }); | ||
| 614 | } | ||
| 615 | |||
| 616 | const dataTypeChange = (val, scope) => { | ||
| 617 | scope.row['defaultValue'] = '' | ||
| 618 | scope.row['fieldLength'] = undefined | ||
| 619 | scope.row['fieldPrecision'] = undefined | ||
| 620 | |||
| 621 | } | ||
| 622 | |||
| 623 | /*** 以下是处理数据字典或维表的树形选择框。 */ | ||
| 624 | |||
| 625 | const dimOrDictList: any = ref([{ | ||
| 626 | guid: '1', | ||
| 627 | chName: '数据字典', | ||
| 628 | children: dictionaryList.value, | ||
| 629 | isLeaf: false, | ||
| 630 | disabled: !dictionaryList.value.length, | ||
| 631 | }, { | ||
| 632 | guid: '2', | ||
| 633 | chName: '维度', | ||
| 634 | isLeaf: false, | ||
| 635 | disabled: !dimListData.value.length, | ||
| 636 | children: dimListData.value | ||
| 637 | }]); | ||
| 638 | |||
| 639 | const dimOrDictInputFilterMethod = (v, data) => { | ||
| 640 | return data.label?.includes(v) || data.chName?.includes(v); | ||
| 641 | }; | ||
| 642 | |||
| 643 | const dimOrDictSelectRef = ref(); | ||
| 644 | |||
| 645 | const dimOrDictSelectNode = ref(); | ||
| 646 | |||
| 647 | const handleDictSelectNodeChange = (node) => { | ||
| 648 | dimOrDictSelectNode.value = node; | ||
| 649 | } | ||
| 650 | |||
| 651 | const handleDictionaryChange = (val, scope) => { | ||
| 652 | if (!val) { | ||
| 653 | scope.row.dictionaryGuid = ''; | ||
| 654 | scope.row.dimGuid = ''; | ||
| 655 | scope.row.dictionaryChName = ''; | ||
| 656 | scope.row.dimChName = ''; | ||
| 657 | return; | ||
| 658 | } | ||
| 659 | let info = dimOrDictSelectNode.value; | ||
| 660 | if (!info) { | ||
| 661 | return; | ||
| 662 | } | ||
| 663 | if (info.parentGuid == '2') { | ||
| 664 | scope.row.dimGuid = val; | ||
| 665 | scope.row.dimChName = dimListData.value.find(d => d.guid === val)?.chName; | ||
| 666 | scope.row.dictionaryGuid = ''; | ||
| 667 | scope.row.dictionaryChName = ''; | ||
| 668 | } else { | ||
| 669 | scope.row.dictionaryGuid = val; | ||
| 670 | scope.row.dictionaryChName = dictionaryList.value.find(d => d.guid === val)?.chName; | ||
| 671 | scope.row.dimGuid = ''; | ||
| 672 | scope.row.dimChName = ''; | ||
| 673 | } | ||
| 674 | } | ||
| 675 | |||
| 676 | /** 扩展属性弹出对话框 */ | ||
| 677 | const expandPropertyDialogRef = ref(); | ||
| 678 | |||
| 679 | /** 扩展属性弹出对话框 */ | ||
| 680 | const handleClickExpand = () => { | ||
| 681 | expandPropertyDialogRef.value?.handleClickExpand(); | ||
| 682 | } | ||
| 683 | |||
| 684 | const expandDialogValueChange = (val) => { | ||
| 685 | tableCreateInfo.value.partitionAttribute = val; | ||
| 686 | expandProperties.value = val; | ||
| 687 | } | ||
| 688 | |||
| 689 | </script> | ||
| 690 | |||
| 691 | <template> | ||
| 692 | <div class="table_tool_wrap" v-loading="fullscreenLoading"> | ||
| 693 | <div class="tools_btns"> | ||
| 694 | <!-- <el-button type="primary" :disabled="isLook" @click="saveDraftTable" v-preReClick>保存为草稿</el-button> --> | ||
| 695 | <el-button type="primary" :disabled="isLook" @click="saveTable" v-preReClick>提交</el-button> | ||
| 696 | </div> | ||
| 697 | <el-table ref="tableRef" :data="tableCreateInfo.tableData" v-loading="tableCreateInfoLoading" | ||
| 698 | :highlight-current-row="true" stripe border height="100%" tooltip-effect="light" row-key="guid" :style="{ | ||
| 699 | width: '100%', | ||
| 700 | height: 'auto', | ||
| 701 | display: 'inline-block', | ||
| 702 | }"> | ||
| 703 | <el-table-column prop="dataSourceGuid" label="数据源" width="200px" align="left" show-overflow-tooltip> | ||
| 704 | <template #header> | ||
| 705 | <span>数据源</span> | ||
| 706 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 707 | </template> | ||
| 708 | <template #default="scope"> | ||
| 709 | <el-select v-if="!isLook" v-model="scope.row['dataSourceGuid']" placeholder="请选择" | ||
| 710 | :disabled="tableCreateInfo.isCreate" @change="(val) => selectDatabaseChange(val)" clearable filterable> | ||
| 711 | <el-option v-for="opt in databaseList" :key="opt['guid']" :label="opt['databaseNameZh']" | ||
| 712 | :value="opt['guid']" /> | ||
| 713 | </el-select> | ||
| 714 | <span v-else>{{ scope.row["dataServerChName"] }}</span> | ||
| 715 | </template> | ||
| 716 | </el-table-column> | ||
| 717 | <el-table-column prop="enName" label="数据库表" width="200px" align="left" show-overflow-tooltip> | ||
| 718 | <template #header> | ||
| 719 | <span>数据库表</span> | ||
| 720 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 721 | </template> | ||
| 722 | <template #default="scope"> | ||
| 723 | <template v-if="!isLook"> | ||
| 724 | <div class="prefix-or-suffix-cell"> | ||
| 725 | <el-input :disabled="tableCreateInfo.isCreate" v-model.trim="tableCreateInfo.inputNameValue" | ||
| 726 | :maxlength="50" placeholder="必填" /> | ||
| 727 | </div> | ||
| 728 | </template> | ||
| 729 | <span v-else>{{ scope.row["enName"] }}</span> | ||
| 730 | </template> | ||
| 731 | </el-table-column> | ||
| 732 | <el-table-column prop="chName" label="主题表名称" width="200px" align="left" show-overflow-tooltip> | ||
| 733 | <template #header> | ||
| 734 | <span>主题表名称</span> | ||
| 735 | <span v-if="!isLook" style="color:red;margin-left: 2px;">*</span> | ||
| 736 | </template> | ||
| 737 | <template #default="scope"> | ||
| 738 | <el-input v-if="!isLook" v-model.trim="scope.row['chName']" placeholder="必填" :maxlength="50" /> | ||
| 739 | <span v-else>{{ scope.row["chName"] }}</span> | ||
| 740 | </template> | ||
| 741 | </el-table-column> | ||
| 742 | <el-table-column prop="subjectDomain" label="主题域" width="180px" align="left" show-overflow-tooltip> | ||
| 743 | <template #default="scope"> | ||
| 744 | <el-input v-if="!isLook" disabled v-model="scope.row['subjectDomain']" /> | ||
| 745 | <span v-else>{{ scope.row["subjectDomain"] }}</span> | ||
| 746 | </template> | ||
| 747 | </el-table-column> | ||
| 748 | <el-table-column prop="tableModel" label="表模型" :width="isLook ? '100px' : '150px'" align="left" | ||
| 749 | show-overflow-tooltip> | ||
| 750 | <template #default="scope"> | ||
| 751 | <el-select v-if="dbType == 'doris' && !isLook" v-model="scope.row['tableModel']" placeholder="请选择" | ||
| 752 | :disabled="tableCreateInfo.isCreate"> | ||
| 753 | <el-option v-for="opt in tableModels" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 754 | </el-select> | ||
| 755 | <span v-else-if="dbType == 'doris'">{{tableModels.find(t => t.value === scope.row["tableModel"])?.label || | ||
| 756 | '-' | ||
| 757 | }}</span> | ||
| 758 | <span v-else>--</span> | ||
| 759 | </template> | ||
| 760 | </el-table-column> | ||
| 761 | <el-table-column prop="tableCategory" label="表分类" :width="isLook ? '100px' : '150px'" align="left" | ||
| 762 | show-overflow-tooltip> | ||
| 763 | <template #default="scope"> | ||
| 764 | <el-select v-if="!isLook" v-model="scope.row['tableCategory']" placeholder="请选择"> | ||
| 765 | <el-option v-for="opt in tableCategoryList" :key="opt['value']" :label="opt['label']" | ||
| 766 | :value="opt['value']" /> | ||
| 767 | </el-select> | ||
| 768 | <span v-else>{{tableCategoryList.find(t => t.value === scope.row["tableCategory"])?.label || '-'}}</span> | ||
| 769 | </template> | ||
| 770 | </el-table-column> | ||
| 771 | <el-table-column prop="syncPolicy" label="同步策略" :width="isLook ? '100px' : '150px'" align="left" | ||
| 772 | show-overflow-tooltip> | ||
| 773 | <template #default="scope"> | ||
| 774 | <el-select v-if="!isLook" v-model="scope.row['syncPolicy']" placeholder="请选择"> | ||
| 775 | <el-option v-for="opt in syncPolicys" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 776 | </el-select> | ||
| 777 | <span v-else>{{syncPolicys.find(s => s.value === scope.row["syncPolicy"])?.label || '-'}}</span> | ||
| 778 | </template> | ||
| 779 | </el-table-column> | ||
| 780 | <el-table-column prop="characterSet" label="字符集" :width="isLook ? '100px' : '150px'" align="left" | ||
| 781 | show-overflow-tooltip> | ||
| 782 | <template #default="scope"> | ||
| 783 | <el-select v-if="!isLook" v-model="scope.row['characterSet']" placeholder="请选择" | ||
| 784 | :disabled="tableCreateInfo.isCreate"> | ||
| 785 | <el-option v-for="opt in characterList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 786 | </el-select> | ||
| 787 | <span v-else>{{characterList.find(c => c.value === scope.row["characterSet"])?.label || '-'}}</span> | ||
| 788 | </template> | ||
| 789 | </el-table-column> | ||
| 790 | <el-table-column prop="description" label="描述" width="220px" align="left" show-overflow-tooltip> | ||
| 791 | <template #default="scope"> | ||
| 792 | <el-input v-if="!isLook" v-model.trim="scope.row['description']" /> | ||
| 793 | <span v-else>{{ scope.row["description"] || '-' }}</span> | ||
| 794 | </template> | ||
| 795 | </el-table-column> | ||
| 796 | <el-table-column label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip> | ||
| 797 | <template #default="scope"> | ||
| 798 | <span class="text_btn" @click="handleClickExpand()" v-preReClick>扩展属性</span> | ||
| 799 | </template> | ||
| 800 | </el-table-column> | ||
| 801 | </el-table> | ||
| 802 | <div class="tools_btns"> | ||
| 803 | <el-button type="primary" :disabled="isLook" @click="addField">新增</el-button> | ||
| 804 | <el-button @click="moveUp" :disabled="isLook">上移</el-button> | ||
| 805 | <el-button @click="moveDown" :disabled="isLook">下移</el-button> | ||
| 806 | <el-button @click="delFeilds" :disabled="isLook">批量删除</el-button> | ||
| 807 | </div> | ||
| 808 | <div class="table_panel"> | ||
| 809 | <el-table ref="fieldStandardTableRef" :data="tableCreateInfo.tableFields" v-loading="tableFieldsLoading" | ||
| 810 | :highlight-current-row="true" stripe border height="100%" row-key="guid" | ||
| 811 | @selection-change="selectionFieldsChange" tooltip-effect="light" :style="{ | ||
| 812 | width: '100%', | ||
| 813 | 'max-height': 'calc(100% - 16px)', | ||
| 814 | display: 'inline-block', | ||
| 815 | }"> | ||
| 816 | <el-table-column type="selection" v-if="!isLook" :width="32" align="center" /> | ||
| 817 | <el-table-column label="排序" type="index" width="56px" align="center" show-overflow-tooltip> | ||
| 818 | </el-table-column> | ||
| 819 | <el-table-column prop="chName" label="字段中文名称" width="150px" align="left" show-overflow-tooltip> | ||
| 820 | <template #default="scope"> | ||
| 821 | <el-input v-if="scope.row['isEdit']" :placeholder="'请输入'" v-model.trim="scope.row['chName']" /> | ||
| 822 | <span v-else>{{ scope.row["chName"] || '-' }}</span> | ||
| 823 | </template> | ||
| 824 | </el-table-column> | ||
| 825 | <el-table-column prop="enName" label="字段英文名" width="150px" align="left" show-overflow-tooltip> | ||
| 826 | <template #default="scope"> | ||
| 827 | <el-input v-if="scope.row['isEdit'] && !(scope.row['guid'] && tableCreateInfo.isCreate)" | ||
| 828 | v-model.trim="scope.row['enName']" placeholder="必填" | ||
| 829 | @input="inputLengthKeyUp(/[^a-zA-Z0-9_]/g, scope, 'enName')" /> | ||
| 830 | <span v-else>{{ scope.row["enName"] || '-' }}</span> | ||
| 831 | </template> | ||
| 832 | </el-table-column> | ||
| 833 | <el-table-column prop="dataType" label="字段类型" width="120px" align="left" show-overflow-tooltip> | ||
| 834 | <template #default="scope"> | ||
| 835 | <el-select v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y')" | ||
| 836 | v-model="scope.row['dataType']" placeholder="请选择" @change="(val) => dataTypeChange(val, scope)"> | ||
| 837 | <el-option v-for="opt in fieldTypes" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 838 | </el-select> | ||
| 839 | <span v-else>{{fieldTypes.find(f => f.value === scope.row["dataType"])?.label || '-'}}</span> | ||
| 840 | </template> | ||
| 841 | </el-table-column> | ||
| 842 | <el-table-column prop="fieldLength" label="长度" width="115px" align="left" show-overflow-tooltip> | ||
| 843 | <template #default="scope"> | ||
| 844 | <el-input | ||
| 845 | v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y') && (scope.row['dataType'] == 'varchar' || scope.row['dataType'] == 'decimal' || scope.row['dataType'] == 'char')" | ||
| 846 | v-model.trim="scope.row['fieldLength']" placeholder="必填" | ||
| 847 | @input="inputLengthKeyUp(/\D/g, scope, 'fieldLength', 2000, 1)" /> | ||
| 848 | <span v-else>{{ scope.row["fieldLength"] == null ? '-' : scope.row["fieldLength"] }}</span> | ||
| 849 | </template> | ||
| 850 | </el-table-column> | ||
| 851 | <el-table-column prop="fieldPrecision" label="精度" width="115px" align="left" show-overflow-tooltip> | ||
| 852 | <template #default="scope"> | ||
| 853 | <el-input | ||
| 854 | v-if="scope.row['isEdit'] && !(tableCreateInfo.isCreate && scope.row['isCreate'] === 'Y') && scope.row['dataType'] == 'decimal'" | ||
| 855 | v-model.trim="scope.row['fieldPrecision']" placeholder="必填" | ||
| 856 | @input="inputLengthKeyUp(/\D/g, scope, 'fieldPrecision', 30, 1)" /> | ||
| 857 | <span v-else>{{ scope.row["fieldPrecision"] == null ? '-' : scope.row["fieldPrecision"] }}</span> | ||
| 858 | </template> | ||
| 859 | </el-table-column> | ||
| 860 | <el-table-column prop="dimOrdictionaryGuid" label="关联维度/字典" width="130px" align="left" show-overflow-tooltip> | ||
| 861 | <template #default="scope"> | ||
| 862 | <el-tree-select ref="dimOrDictSelectRef" v-if="scope.row['isEdit']" filterable clearable | ||
| 863 | :data="dimOrDictList" v-model="scope.row['dimOrdictionaryGuid']" node-key="guid" | ||
| 864 | :default-expanded-keys="scope.row['dictionaryGuid'] ? ['1'] : (scope.row['dimGuid'] ? ['2'] : [])" | ||
| 865 | placeholder="请选择" :filter-node-method="dimOrDictInputFilterMethod" :props="{ | ||
| 866 | label: 'chName', | ||
| 867 | value: 'guid', | ||
| 868 | children: 'children', | ||
| 869 | isLeaf: 'isLeaf' | ||
| 870 | }" @change="(v) => handleDictionaryChange(v, scope)" @current-change="handleDictSelectNodeChange"> | ||
| 871 | <template #default="{ node, data }"> | ||
| 872 | <template v-if="node.level > 1 && data.parentGuid == '2'"> | ||
| 873 | <span>{{ data["chName"] + `(${data["subjectDomainName"]})` }}</span> | ||
| 874 | </template> | ||
| 875 | <span v-else>{{ data['chName'] }}</span> | ||
| 876 | </template> | ||
| 877 | </el-tree-select> | ||
| 878 | <span v-else>{{ (scope.row['dictionaryGuid'] ? scope.row["dictionaryChName"] : (scope.row['dimGuid'] ? | ||
| 879 | scope.row['dimChName'] : '-')) || '-' }}</span> | ||
| 880 | </template> | ||
| 881 | </el-table-column> | ||
| 882 | <el-table-column prop="isPrimary" label="是否主键" width="90px" align="left" show-overflow-tooltip> | ||
| 883 | <template #default="scope"> | ||
| 884 | <el-select v-if="scope.row['isEdit'] && !tableCreateInfo.isCreate" v-model="scope.row['isPrimary']" | ||
| 885 | placeholder="请选择"> | ||
| 886 | <el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 887 | </el-select> | ||
| 888 | <span v-else>{{ scope.row["isPrimary"] || '-' }}</span> | ||
| 889 | </template> | ||
| 890 | </el-table-column> | ||
| 891 | <el-table-column v-if="tableCreateInfo.tableData[0].tableModel == 2" prop="aggWay" label="聚合方式" width="120px" | ||
| 892 | align="left" show-overflow-tooltip> | ||
| 893 | <template #default="scope"> | ||
| 894 | <el-select v-if="scope.row['isEdit']" v-model="scope.row['aggWay']" placeholder="请选择"> | ||
| 895 | <el-option v-for="opt in aggMethodList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 896 | </el-select> | ||
| 897 | <span v-else>{{ scope.row["aggWay"] || '-' }}</span> | ||
| 898 | </template> | ||
| 899 | </el-table-column> | ||
| 900 | <el-table-column prop="notNull" label="是否必填" width="90px" align="left" show-overflow-tooltip> | ||
| 901 | <template #default="scope"> | ||
| 902 | <el-select v-if="scope.row['isEdit'] && !(scope.row.isCreate == 'Y' && scope.row['notNull'] == 'N')" | ||
| 903 | v-model="scope.row['notNull']" placeholder="请选择"> | ||
| 904 | <el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" /> | ||
| 905 | </el-select> | ||
| 906 | <span v-else>{{ scope.row["notNull"] || '-' }}</span> | ||
| 907 | </template> | ||
| 908 | </el-table-column> | ||
| 909 | <el-table-column prop="defaultValue" label="默认值" width="205px" align="left" show-overflow-tooltip> | ||
| 910 | <template #default="scope"> | ||
| 911 | <tableDefaultValue :scope="scope" :dbType="dbType" | ||
| 912 | :readonly="dbType == 'doris' && scope.row.isCreate == 'Y'"></tableDefaultValue> | ||
| 913 | </template> | ||
| 914 | </el-table-column> | ||
| 915 | <el-table-column v-if="!isLook" label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip> | ||
| 916 | <template #default="scope"> | ||
| 917 | <template v-if="!(tableCreateInfo.isCreate && scope.row['isPrimary'] === 'Y')"> | ||
| 918 | <span class="text_btn" v-if="!scope.row['isEdit']" @click="handleFieldClickEdit(scope)" | ||
| 919 | v-preReClick>编辑</span> | ||
| 920 | <span class="text_btn" v-else @click="handleFieldClickSave(scope)" v-preReClick>保存</span> | ||
| 921 | <el-divider direction="vertical" /> | ||
| 922 | <span class="text_btn" @click="handleFieldDelete(scope)">删除</span> | ||
| 923 | </template> | ||
| 924 | <span v-else>--</span> | ||
| 925 | </template> | ||
| 926 | </el-table-column> | ||
| 927 | </el-table> | ||
| 928 | </div> | ||
| 929 | <ContentWrap title="流程审批" description="" :isExpand="flowExpand" :expand-swicth="true" class="mb16" | ||
| 930 | @expand="(v) => flowExpand = v"> | ||
| 931 | <ApprovalProcess v-if="deploymentId" :deploymentId="deploymentId" :definitionId="''"> | ||
| 932 | </ApprovalProcess> | ||
| 933 | </ContentWrap> | ||
| 934 | <expandPropertyDialog ref="expandPropertyDialogRef" :is-look="isLook" :partitionAttribute="expandProperties" | ||
| 935 | :table-create-info="tableCreateInfo" @expandValueChange="expandDialogValueChange" /> | ||
| 936 | </div> | ||
| 937 | </template> | ||
| 938 | |||
| 939 | <style lang="scss" scoped> | ||
| 940 | .table_tool_wrap { | ||
| 941 | width: 100%; | ||
| 942 | height: 100%; | ||
| 943 | padding: 0 16px; | ||
| 944 | overflow: hidden auto; | ||
| 945 | |||
| 946 | .tools_btns { | ||
| 947 | padding: 8px 0; | ||
| 948 | } | ||
| 949 | |||
| 950 | :deep(.el-table) { | ||
| 951 | .cell { | ||
| 952 | |||
| 953 | .prefix-or-suffix-cell { | ||
| 954 | display: inline-flex; | ||
| 955 | align-items: center; | ||
| 956 | } | ||
| 957 | } | ||
| 958 | } | ||
| 959 | |||
| 960 | .table_panel { | ||
| 961 | height: 268px; | ||
| 962 | |||
| 963 | :deep(.el-table) { | ||
| 964 | & td.el-table__cell { | ||
| 965 | padding: 2px 0; | ||
| 966 | height: 36px; | ||
| 967 | } | ||
| 968 | } | ||
| 969 | } | ||
| 970 | } | ||
| 971 | |||
| 972 | :deep(.el-dialog) { | ||
| 973 | .dialog-form-inline { | ||
| 974 | .checkbox_input { | ||
| 975 | display: flex; | ||
| 976 | flex-direction: column; | ||
| 977 | |||
| 978 | .input_panel { | ||
| 979 | margin: 0; | ||
| 980 | } | ||
| 981 | } | ||
| 982 | |||
| 983 | .select_group { | ||
| 984 | .el-form-item__content>.el-input { | ||
| 985 | margin-top: 21px; | ||
| 986 | } | ||
| 987 | } | ||
| 988 | |||
| 989 | .radio_panel { | ||
| 990 | .panel_content { | ||
| 991 | display: none; | ||
| 992 | } | ||
| 993 | } | ||
| 994 | } | ||
| 995 | } | ||
| 996 | </style> |
src/views/data_pricing/calculateConfig.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: calculateConfig | ||
| 3 | </route> | ||
| 4 | <script lang="ts" setup name="calculateConfig"> | ||
| 5 | import { ref, onMounted } from "vue"; | ||
| 6 | import { useRouter, useRoute } from "vue-router"; | ||
| 7 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 8 | import useUserStore from "@/store/modules/user"; | ||
| 9 | import useDataAssetStore from "@/store/modules/dataAsset"; | ||
| 10 | import { getAllFlowData } from '@/api/modules/queryService'; | ||
| 11 | import { getDamCatalogList } from "@/api/modules/dataPricing"; | ||
| 12 | import { getRegisterCatalogDetail, getRegisterCatalogTableDetail } from "@/api/modules/dataAsset"; | ||
| 13 | import { download } from '@/utils/common' | ||
| 14 | import { | ||
| 15 | getConfigureList, | ||
| 16 | getConfigureDetail, | ||
| 17 | getDiseaseAll, | ||
| 18 | getPriceDetail, | ||
| 19 | getDemandList, | ||
| 20 | getModelScore, | ||
| 21 | savePrice, | ||
| 22 | getModelDemand, | ||
| 23 | getPriceResult, | ||
| 24 | exportModelScore | ||
| 25 | } from '@/api/modules/dataPricing'; | ||
| 26 | import { changeNum } from "@/utils/common"; | ||
| 27 | |||
| 28 | const { proxy } = getCurrentInstance() as any; | ||
| 29 | const router = useRouter(); | ||
| 30 | const route = useRoute(); | ||
| 31 | const userStore = useUserStore(); | ||
| 32 | const assetStore = useDataAssetStore(); | ||
| 33 | const fullPath = route.fullPath; | ||
| 34 | const userData = JSON.parse(localStorage.userData); | ||
| 35 | const guid = route.query.guid; | ||
| 36 | const priceName = route.query.name; | ||
| 37 | const loading = ref(false); | ||
| 38 | const flowDetail: any = ref({}); | ||
| 39 | const typeMap: any = ref({}); | ||
| 40 | const expand1 = ref(true) | ||
| 41 | const expand2 = ref(true) | ||
| 42 | const expand3 = ref(true) | ||
| 43 | const demandTableList: any = ref([]); | ||
| 44 | const pricingTargetList: any = ref([]); | ||
| 45 | const demandTableFieldAllNum = ref(0); | ||
| 46 | const resourceTableAllNum = ref(0); | ||
| 47 | const resourceTableFieldAllNum = ref(0); | ||
| 48 | const modelData: any = ref({}); | ||
| 49 | const pricingDimensionalityData: any = ref([]); | ||
| 50 | const dictionaryData: any = ref([]); | ||
| 51 | const diseaseData: any = ref([]); | ||
| 52 | const qualityScoreData: any = ref({}); | ||
| 53 | const disScore: any = ref([]); | ||
| 54 | const exportData: any = ref([]); | ||
| 55 | const dataUsage = ref(''); | ||
| 56 | // 基础设置 | ||
| 57 | const baseConfigFormRef = ref(); | ||
| 58 | const baseConfigFormItems: any = ref([ | ||
| 59 | { | ||
| 60 | label: '模型名称', | ||
| 61 | type: 'select', | ||
| 62 | placeholder: '请选择', | ||
| 63 | field: 'modelGuid', | ||
| 64 | default: '', | ||
| 65 | options: [], | ||
| 66 | props: { | ||
| 67 | label: "modelName", | ||
| 68 | value: "guid", | ||
| 69 | }, | ||
| 70 | clearable: true, | ||
| 71 | filterable: true, | ||
| 72 | required: true | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | label: '数据资源', | ||
| 76 | type: 'select', | ||
| 77 | placeholder: '请选择', | ||
| 78 | field: 'dataResourceGuid', | ||
| 79 | default: '', | ||
| 80 | options: [], | ||
| 81 | props: { | ||
| 82 | label: "damName", | ||
| 83 | value: "guid", | ||
| 84 | }, | ||
| 85 | clearable: true, | ||
| 86 | filterable: true, | ||
| 87 | required: true, | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | label: '所属主体', | ||
| 91 | type: 'input', | ||
| 92 | placeholder: '', | ||
| 93 | field: 'belongingEntityGuid', | ||
| 94 | default: '', | ||
| 95 | options: [], | ||
| 96 | clearable: true, | ||
| 97 | disabled: true | ||
| 98 | }, | ||
| 99 | { | ||
| 100 | label: '所属主题', | ||
| 101 | type: 'tree-select', | ||
| 102 | placeholder: '请选择', | ||
| 103 | field: 'belongingTheme', | ||
| 104 | default: '', | ||
| 105 | options: [], | ||
| 106 | showAllLevels: false, | ||
| 107 | checkStrictly: false,//只能选择叶子节点。 | ||
| 108 | lazy: false, | ||
| 109 | props: { | ||
| 110 | label: "label", | ||
| 111 | value: "value", | ||
| 112 | children: 'childDictList' | ||
| 113 | }, | ||
| 114 | filterable: true, | ||
| 115 | clearable: true, | ||
| 116 | disabled: true | ||
| 117 | }, | ||
| 118 | ]) | ||
| 119 | const baseConfigFormRules: any = ref({ | ||
| 120 | modelGuid: [ | ||
| 121 | { required: true, trigger: 'change', message: "请选择模型名称" } | ||
| 122 | ], | ||
| 123 | dataResourceGuid: [ | ||
| 124 | { required: true, trigger: 'change', message: "请选择数据资源" } | ||
| 125 | ], | ||
| 126 | }); | ||
| 127 | const baseConfigForm = ref({ | ||
| 128 | items: baseConfigFormItems.value, | ||
| 129 | rules: baseConfigFormRules.value, | ||
| 130 | }) | ||
| 131 | const tableFields: any = ref([ | ||
| 132 | { label: '需求表', field: 'demandTableName', type: 'input', width: 200, disabled: true }, | ||
| 133 | { label: '数据资源表', field: 'dataTableGuid', type: 'select', width: 200 }, | ||
| 134 | { label: '表描述', field: 'tableDescription', type: 'input', width: 200, disabled: true }, | ||
| 135 | { label: '需求表权重(%)', field: 'weightDemandTable', type: 'input', width: 140, disabled: true }, | ||
| 136 | ]) | ||
| 137 | const expendTableRef = ref(); | ||
| 138 | const tableData: any = ref([]); | ||
| 139 | const tableLoading = ref(false); | ||
| 140 | const dataTransactionPrice: any = ref(''); | ||
| 141 | const setFormItems = (info = null) => { | ||
| 142 | let datas: any = info || flowDetail.value || {}; | ||
| 143 | const dData = datas.dictionaryJson ? JSON.parse(datas.dictionaryJson) : {}; | ||
| 144 | datas = { ...datas, ...dData }; | ||
| 145 | baseConfigFormItems.value.map(item => { | ||
| 146 | item.default = datas[item.field] || ''; | ||
| 147 | }) | ||
| 148 | nextTick(() => { | ||
| 149 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); | ||
| 150 | }) | ||
| 151 | } | ||
| 152 | /** | ||
| 153 | * 传入多个promise对象,当全部结束时取消Loading | ||
| 154 | * @param promises 传入多个promise对象,当全部结束时取消Loading | ||
| 155 | */ | ||
| 156 | const promiseList = (...promises: Promise<void>[]) => { | ||
| 157 | // loading方法全局封装成一个组件 | ||
| 158 | !guid && (loading.value = true); | ||
| 159 | try { | ||
| 160 | Promise.all(promises).then(res => { | ||
| 161 | loading.value = false; | ||
| 162 | }); | ||
| 163 | } catch (e) { | ||
| 164 | loading.value = false; | ||
| 165 | } finally { | ||
| 166 | !guid && (loading.value = false); | ||
| 167 | } | ||
| 168 | }; | ||
| 169 | // 获取模型 | ||
| 170 | const getModel = () => { | ||
| 171 | getConfigureList({ pageSize: -1, pageIndex: 1, bizState: 'Y' }).then((res: any) => { | ||
| 172 | if (res.code == proxy.$passCode) { | ||
| 173 | const data = res.data.records || []; | ||
| 174 | typeMap.value.modelGuid = JSON.parse(JSON.stringify(data)); | ||
| 175 | let item = baseConfigFormItems.value.find(item => item.field == 'modelGuid'); | ||
| 176 | item && (item.options = data); | ||
| 177 | } | ||
| 178 | }) | ||
| 179 | } | ||
| 180 | // 获取所有疾病数据 | ||
| 181 | const getDiseaseData = () => { | ||
| 182 | getDiseaseAll().then((res: any) => { | ||
| 183 | if (res.code == proxy.$passCode) { | ||
| 184 | const data = res.data || []; | ||
| 185 | typeMap.value.diseaseGuid = JSON.parse(JSON.stringify(data)); | ||
| 186 | let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid'); | ||
| 187 | if (item) { | ||
| 188 | item.options = typeMap.value['diseaseGuid']; | ||
| 189 | if (guid) { | ||
| 190 | const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid); | ||
| 191 | if (!diseaseData) { | ||
| 192 | item.options.unshift({ | ||
| 193 | guid: flowDetail.value.diseaseGuid, | ||
| 194 | diseaseName: flowDetail.value.diseaseName | ||
| 195 | }); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | }) | ||
| 201 | } | ||
| 202 | // 获取数据资源 | ||
| 203 | const getDataCatalog = () => { | ||
| 204 | return getDamCatalogList({ dataType: userData.superTubeFlag == 'Y' ? "P" : "D", sceneType: "D" }).then((res: any) => { | ||
| 205 | if (res.code == proxy.$passCode) { | ||
| 206 | let data = res.data || []; | ||
| 207 | data.map(item => item.damGuid = item.guid); | ||
| 208 | typeMap.value.dataResourceGuid = JSON.parse(JSON.stringify(data)); | ||
| 209 | let item = baseConfigFormItems.value.find(item => item.field == 'dataResourceGuid'); | ||
| 210 | if (item) { | ||
| 211 | item.options = data; | ||
| 212 | if (guid) { | ||
| 213 | const rItem = typeMap.value.dataResourceGuid.find(m => m.damGuid == flowDetail.value.dataResourceGuid); | ||
| 214 | if (!rItem) { | ||
| 215 | const rtem = { damGuid: flowDetail.value.dataResourceGuid, damName: flowDetail.value.dataResourceName }; | ||
| 216 | item.options.unshift(rtem); | ||
| 217 | typeMap.value.dataResourceGuid.unshift(rtem); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | } | ||
| 221 | } | ||
| 222 | }) | ||
| 223 | } | ||
| 224 | // 获取数据资源主题 | ||
| 225 | const getSourceThem = (dictType, fieldName) => { | ||
| 226 | return getAllFlowData({ dictType }).then((res: any) => { | ||
| 227 | if (res.code == proxy.$passCode) { | ||
| 228 | const data = res.data || []; | ||
| 229 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 230 | let item = baseConfigFormItems.value.find(item => item.field == fieldName); | ||
| 231 | item && (item.options = data); | ||
| 232 | } else { | ||
| 233 | proxy.$ElMessage.error(res.msg); | ||
| 234 | } | ||
| 235 | }) | ||
| 236 | } | ||
| 237 | // 获取数据字典 | ||
| 238 | const getDataType = (dictType, fieldName) => { | ||
| 239 | getAllFlowData({ dictType }).then((res: any) => { | ||
| 240 | if (res.code == proxy.$passCode) { | ||
| 241 | const data = res.data || []; | ||
| 242 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 243 | let item = baseConfigFormItems.value.find(item => item.field == fieldName); | ||
| 244 | item && (item.options = data); | ||
| 245 | } else { | ||
| 246 | proxy.$ElMessage.error(res.msg); | ||
| 247 | } | ||
| 248 | }) | ||
| 249 | } | ||
| 250 | // 获取详情 | ||
| 251 | const getDetail = () => { | ||
| 252 | loading.value = true; | ||
| 253 | getPriceDetail({ guid }).then((res: any) => { | ||
| 254 | if (res.code == proxy.$passCode) { | ||
| 255 | const data = res.data || {}; | ||
| 256 | flowDetail.value = data; | ||
| 257 | dataTransactionPrice.value = flowDetail.value.dataTransactionPrice; | ||
| 258 | dataUsage.value = data.dataUsage || ''; | ||
| 259 | const mItem = typeMap.value.modelGuid.find(m => m.guid == flowDetail.value.modelGuid); | ||
| 260 | if (!mItem) { | ||
| 261 | const mtem = { guid: flowDetail.value.modelGuid, modelName: flowDetail.value.modelName }; | ||
| 262 | typeMap.value.modelGuid.unshift(mtem); | ||
| 263 | baseConfigFormItems.value[0].options.unshift(mtem); | ||
| 264 | }; | ||
| 265 | getModelInfo(flowDetail.value.modelGuid); | ||
| 266 | getDataTypeList() | ||
| 267 | } | ||
| 268 | }).catch(() => { | ||
| 269 | loading.value = false; | ||
| 270 | }) | ||
| 271 | } | ||
| 272 | const getDataTypeList = () => { | ||
| 273 | if (guid) { | ||
| 274 | promiseList( | ||
| 275 | getDataCatalog(), | ||
| 276 | getSourceThem('数据资产目录主题名称', 'belongingTheme'), | ||
| 277 | getQuilityModelScore(flowDetail.value.dataResourceGuid) | ||
| 278 | ) | ||
| 279 | } else { | ||
| 280 | promiseList( | ||
| 281 | getDataCatalog(), | ||
| 282 | getSourceThem('数据资产目录主题名称', 'belongingTheme'), | ||
| 283 | ) | ||
| 284 | } | ||
| 285 | } | ||
| 286 | const setFormItemData = () => { | ||
| 287 | let dictionaryList: any = [], diseaseList: any = []; | ||
| 288 | pricingTargetList.value.map(item => { | ||
| 289 | switch (item.targetType) { | ||
| 290 | case '2': | ||
| 291 | item.functionName == '2' && diseaseList.push(item); | ||
| 292 | break; | ||
| 293 | case '3': | ||
| 294 | dictionaryList.push(item); | ||
| 295 | break; | ||
| 296 | default: | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | }) | ||
| 300 | dictionaryData.value = dictionaryList; | ||
| 301 | diseaseData.value = diseaseList; | ||
| 302 | if (diseaseList.length) { | ||
| 303 | const diseaseName = flowDetail.value.diseaseName || ''; | ||
| 304 | const modelGuid = flowDetail.value.modelGuid || ''; | ||
| 305 | // 获取疾病得分 | ||
| 306 | if (diseaseName && modelGuid) { | ||
| 307 | getTargetNum({ diseaseName, guid: modelGuid }); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | baseConfigFormItems.value.splice(4); | ||
| 311 | for (var r in baseConfigFormRules.value) { | ||
| 312 | if (r != 'modelGuid' && r != 'dataResourceGuid') { | ||
| 313 | delete baseConfigFormRules.value[r]; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | // 添加所属疾病 | ||
| 317 | if (diseaseList.length > 0) { | ||
| 318 | baseConfigFormItems.value.push({ | ||
| 319 | label: '所属疾病', | ||
| 320 | type: 'cascader', | ||
| 321 | placeholder: '请选择', | ||
| 322 | field: 'diseaseGuid', | ||
| 323 | default: '', | ||
| 324 | options: [], | ||
| 325 | showAllLevels: false, | ||
| 326 | props: { | ||
| 327 | checkStrictly: true, | ||
| 328 | label: "diseaseName", | ||
| 329 | value: "guid", | ||
| 330 | children: 'childList', | ||
| 331 | emitPath: false | ||
| 332 | }, | ||
| 333 | filterable: true, | ||
| 334 | clearable: true, | ||
| 335 | required: true, | ||
| 336 | }); | ||
| 337 | baseConfigFormRules.value.diseaseGuid = { required: true, trigger: 'change', message: "请选择所属疾病" }; | ||
| 338 | if (typeMap.value['diseaseGuid'] == undefined) { | ||
| 339 | getDiseaseData(); | ||
| 340 | } else { | ||
| 341 | let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid'); | ||
| 342 | if (item) { | ||
| 343 | item.options = typeMap.value['diseaseGuid']; | ||
| 344 | const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid); | ||
| 345 | if (!diseaseData) { | ||
| 346 | item.options.unshift({ | ||
| 347 | guid: flowDetail.value.diseaseGuid, | ||
| 348 | diseaseName: flowDetail.value.diseaseName | ||
| 349 | }); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | } | ||
| 353 | } | ||
| 354 | // 添加数据字典 | ||
| 355 | dictionaryList.map(d => { | ||
| 356 | const dictName = d.dictionaryName; | ||
| 357 | const dictField = `dict_${d.guid}`; | ||
| 358 | baseConfigFormItems.value.push({ | ||
| 359 | label: dictName, | ||
| 360 | type: 'select', | ||
| 361 | placeholder: '请输入', | ||
| 362 | field: dictField, | ||
| 363 | default: '', | ||
| 364 | options: [], | ||
| 365 | clearable: true, | ||
| 366 | filterable: true, | ||
| 367 | required: true, | ||
| 368 | }); | ||
| 369 | baseConfigFormRules.value[dictField] = { required: true, trigger: 'change', message: `请选择${dictName}` }; | ||
| 370 | (() => { | ||
| 371 | if (typeMap.value[dictField] == undefined) { | ||
| 372 | getDataType(dictName, dictField) | ||
| 373 | } else { | ||
| 374 | let item = baseConfigFormItems.value.find(item => item.field == dictField); | ||
| 375 | item && (item.options = typeMap.value[dictField]); | ||
| 376 | } | ||
| 377 | })() | ||
| 378 | }) | ||
| 379 | setTimeout(() => { | ||
| 380 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); | ||
| 381 | }, 100) | ||
| 382 | } | ||
| 383 | |||
| 384 | const setdemandTableData = (mGuid = '') => { | ||
| 385 | const tList = flowDetail.value.dataPricingDemandmatchingRQVOS || demandTableList.value || []; | ||
| 386 | let tDatas: any = []; | ||
| 387 | if (guid) { | ||
| 388 | if (mGuid) { | ||
| 389 | tDatas = mGuid == flowDetail.value.modelGuid ? tList : demandTableList.value || []; | ||
| 390 | } else { | ||
| 391 | tDatas = tList; | ||
| 392 | } | ||
| 393 | } else { | ||
| 394 | tDatas = tList; | ||
| 395 | } | ||
| 396 | setTableData(JSON.parse(JSON.stringify(tDatas))) | ||
| 397 | } | ||
| 398 | |||
| 399 | const setTableData = (dataArr) => { | ||
| 400 | tableData.value.splice(0); | ||
| 401 | dataArr.map((item, i) => { | ||
| 402 | const demInfo = pricingTargetList.value.find(t => t.demandTableGuid == (item.demandTableGuid || item.guid)); | ||
| 403 | const demWeight = demInfo?.weight || ''; | ||
| 404 | tableData.value.push({ | ||
| 405 | ...item, | ||
| 406 | demandTableName: item.demandTableName || item.menuName, | ||
| 407 | dataTableGuid: item.dataTableGuid || '', | ||
| 408 | tableDescription: item.tableDescription || '', | ||
| 409 | weightDemandTable: item.weightDemandTable ? parseFloat(item.weightDemandTable).toFixed(2) : (demWeight ? parseFloat(demWeight).toFixed(2) : ''), | ||
| 410 | dataFields: item.pricingDemandFieldRQVOS || [], | ||
| 411 | dataFieldsNum: item.dataFieldsNum || 0, | ||
| 412 | }) | ||
| 413 | if ((item.demandTableGuid || item.guid)) { | ||
| 414 | const rGuid = item.demandTableGuid || item.guid; | ||
| 415 | const rIndex = i; | ||
| 416 | if (!guid || (guid && rGuid != (demInfo?.demandTableGuid || ''))) { | ||
| 417 | (() => { | ||
| 418 | getDemandField(rGuid, rIndex); | ||
| 419 | })() | ||
| 420 | } | ||
| 421 | } | ||
| 422 | }) | ||
| 423 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | ||
| 424 | return accumulator + Number(currentValue.dataFieldsNum); | ||
| 425 | }, 0); | ||
| 426 | setTimeout(() => { | ||
| 427 | tableData.value.map(t => { | ||
| 428 | expendTableRef.value.toggleRowExpansion(t); | ||
| 429 | }) | ||
| 430 | }, 200) | ||
| 431 | } | ||
| 432 | // 获取模型配置信息 | ||
| 433 | const getModelConfig = (mGuid) => { | ||
| 434 | return getModelDemand({ guid: mGuid }).then((res: any) => { | ||
| 435 | if (res.code == proxy.$passCode) { | ||
| 436 | const data = res.data || []; | ||
| 437 | demandTableList.value = data.pricingDemandMenuRSVOS || []; | ||
| 438 | pricingTargetList.value = data.pricingTargetRSVOS || []; | ||
| 439 | demandTableFieldAllNum.value = data.fieldCount || 0; | ||
| 440 | } | ||
| 441 | }) | ||
| 442 | } | ||
| 443 | // 获取模型详情 | ||
| 444 | const getModelDetail = (mGuid) => { | ||
| 445 | return getConfigureDetail({ guid: mGuid }).then((res: any) => { | ||
| 446 | if (res.code == proxy.$passCode) { | ||
| 447 | const data = res.data || []; | ||
| 448 | modelData.value = data; | ||
| 449 | const pricingDimensionality = data.pricingDimensionalityRSVOS || []; | ||
| 450 | let tData: any = []; | ||
| 451 | pricingDimensionality.map(p => { | ||
| 452 | p.pricingTargetRSVOS.map(t => { | ||
| 453 | tData.push({ ...p, ...t }) | ||
| 454 | }) | ||
| 455 | }) | ||
| 456 | pricingDimensionalityData.value = tData; | ||
| 457 | } | ||
| 458 | }) | ||
| 459 | } | ||
| 460 | // 获取资源详情 | ||
| 461 | const getResourceDetail = (sGuid, toPromise = true) => { | ||
| 462 | const detailData = getRegisterCatalogDetail({ guid: sGuid }).then((res: any) => { | ||
| 463 | if (res.code == proxy.$passCode) { | ||
| 464 | const data = res.data || {}; | ||
| 465 | baseConfigFormItems.value.map(item => { | ||
| 466 | if (item.field == 'belongingEntityGuid') { | ||
| 467 | item.default = data.rightMainName || ''; | ||
| 468 | } else if (item.field == 'belongingTheme') { | ||
| 469 | item.default = data.subjectDomain || ''; | ||
| 470 | } | ||
| 471 | }) | ||
| 472 | const damCatalogTableInfo = data.damCatalogTableInfo || []; | ||
| 473 | const damOptions = damCatalogTableInfo.map(item => { | ||
| 474 | return { | ||
| 475 | ...item, | ||
| 476 | label: item.tableName, | ||
| 477 | value: item.guid | ||
| 478 | } | ||
| 479 | }) | ||
| 480 | tableData.value.map((item, i) => { | ||
| 481 | item.damDataTable = JSON.parse(JSON.stringify(damOptions)); | ||
| 482 | if (guid && sGuid == flowDetail.value.dataResourceGuid) { | ||
| 483 | const sData = flowDetail.value.dataPricingDemandmatchingRQVOS?.find(s => s.demandTableGuid == item.demandTableGuid); | ||
| 484 | if (sData) { | ||
| 485 | item.dataTableGuid = sData.dataTableGuid; | ||
| 486 | item.dataFields.map(f => { | ||
| 487 | const fData = sData.pricingDemandFieldRQVOS.find(t => t.guid == f.guid); | ||
| 488 | f.enName = fData?.enName || ''; | ||
| 489 | f.chName = fData?.chName || ''; | ||
| 490 | }); | ||
| 491 | item.tableDescription = sData.tableDescription || damOptions.find(t => t.guid == sData.dataTableGuid)?.tableDescription || ''; | ||
| 492 | item.dataFieldsNum = item.dataFields.filter(item => item.chName != '' && item.chName != null).length; | ||
| 493 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | ||
| 494 | return accumulator + Number(currentValue.dataFieldsNum); | ||
| 495 | }, 0); | ||
| 496 | } | ||
| 497 | } else { | ||
| 498 | item.dataTableGuid = ''; | ||
| 499 | item.dataFields.map(f => { f.enName = ''; f.chName = '' }); | ||
| 500 | item.dataFieldsNum = 0; | ||
| 501 | item.tableDescription = ''; | ||
| 502 | resourceTableFieldAllNum.value = 0; | ||
| 503 | } | ||
| 504 | const dGuid = item.dataTableGuid; | ||
| 505 | const rIndex = i; | ||
| 506 | (() => { | ||
| 507 | !toPromise && dGuid && setTableRowData(dGuid, rIndex) | ||
| 508 | })() | ||
| 509 | }) | ||
| 510 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; | ||
| 511 | } | ||
| 512 | }); | ||
| 513 | if (toPromise) { | ||
| 514 | return detailData; | ||
| 515 | } else { | ||
| 516 | (() => detailData)() | ||
| 517 | } | ||
| 518 | } | ||
| 519 | // 获取质量模型评分 | ||
| 520 | const getQuilityModelScore = (sGuid) => { | ||
| 521 | return getModelScore({ damGuid: sGuid }).then((res: any) => { | ||
| 522 | if (res.code === proxy.$passCode) { | ||
| 523 | const data = res.data || {}; | ||
| 524 | qualityScoreData.value = data; | ||
| 525 | } else { | ||
| 526 | proxy.$ElMessage.error(res.msg); | ||
| 527 | } | ||
| 528 | }) | ||
| 529 | } | ||
| 530 | // 獲取模型相关信息 | ||
| 531 | const getModelInfo = (mGuid) => { | ||
| 532 | const promises: any = [ | ||
| 533 | getModelConfig(mGuid), | ||
| 534 | getModelDetail(mGuid) | ||
| 535 | ]; | ||
| 536 | try { | ||
| 537 | loading.value = true; | ||
| 538 | Promise.all(promises).then(res => { | ||
| 539 | loading.value = false; | ||
| 540 | setFormItemData(); | ||
| 541 | if (guid && mGuid == flowDetail.value.modelGuid) { | ||
| 542 | dataTransactionPrice.value = flowDetail.value.dataTransactionPrice; | ||
| 543 | setTimeout(() => { | ||
| 544 | getResourceDetail(flowDetail.value.dataResourceGuid, false); | ||
| 545 | setFormItems(); | ||
| 546 | setdemandTableData(mGuid); | ||
| 547 | }, 200); | ||
| 548 | } else { | ||
| 549 | setdemandTableData(mGuid); | ||
| 550 | } | ||
| 551 | }); | ||
| 552 | } catch (e) { | ||
| 553 | loading.value = false; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | // 获取数据资源管理信息 | ||
| 557 | const getResourceInfo = (sGuid) => { | ||
| 558 | const promises: any = [getResourceDetail(sGuid), getQuilityModelScore(sGuid)]; | ||
| 559 | try { | ||
| 560 | loading.value = true; | ||
| 561 | Promise.all(promises).then(res => { | ||
| 562 | loading.value = false; | ||
| 563 | }); | ||
| 564 | } catch (e) { | ||
| 565 | loading.value = false; | ||
| 566 | } | ||
| 567 | } | ||
| 568 | const setTableRowData = (dGuid, rIndex) => { | ||
| 569 | let rowData = tableData.value[rIndex]; | ||
| 570 | if (guid && dGuid == rowData.dataTableGuid) { | ||
| 571 | const sourceTableField = flowDetail.value.dataPricingDemandmatchingRQVOS?.find(s => dGuid == s.dataTableGuid); | ||
| 572 | const pricingDemandField = sourceTableField?.pricingDemandFieldRQVOS || []; | ||
| 573 | rowData.dataFields.map(f => { | ||
| 574 | f.chName = pricingDemandField.find(s => f.guid == s.guid)?.chName || '' | ||
| 575 | }) | ||
| 576 | } else { | ||
| 577 | rowData.dataFields.map(f => f.chName = '') | ||
| 578 | } | ||
| 579 | const damData = rowData.damDataTable.find(item => item.guid == dGuid); | ||
| 580 | rowData.tableDescription = damData?.tableDescription || ''; | ||
| 581 | rowData.dataFieldsNum = rowData.dataFields.filter(item => item.chName != '' && item.chName != null).length; | ||
| 582 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | ||
| 583 | return accumulator + Number(currentValue.dataFieldsNum); | ||
| 584 | }, 0); | ||
| 585 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; | ||
| 586 | if (dGuid) { | ||
| 587 | tableLoading.value = true; | ||
| 588 | getRegisterCatalogTableDetail(dGuid).then((res: any) => { | ||
| 589 | tableLoading.value = false; | ||
| 590 | if (res.code == proxy.$passCode) { | ||
| 591 | const data = res.data || {}; | ||
| 592 | const damTableField = data.damCatalogTableField || []; | ||
| 593 | const damFieldOptions = damTableField.map(d => { | ||
| 594 | return { | ||
| 595 | ...d, | ||
| 596 | label: d.chName || '', | ||
| 597 | value: d.chName || '' | ||
| 598 | } | ||
| 599 | }) | ||
| 600 | rowData.dataFields.map(t => { | ||
| 601 | t.damFieldTable = JSON.parse(JSON.stringify(damFieldOptions)); | ||
| 602 | }) | ||
| 603 | // console.log('rowData', rowData) | ||
| 604 | } else { | ||
| 605 | proxy.$ElMessage.error(res.msg); | ||
| 606 | } | ||
| 607 | }).catch(() => { | ||
| 608 | tableLoading.value = false; | ||
| 609 | }) | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | const changeDatasource = () => { | ||
| 614 | baseConfigFormItems.value.map(item => { | ||
| 615 | if (item.field == 'belongingEntityGuid') { | ||
| 616 | item.default = ''; | ||
| 617 | } else if (item.field == 'belongingTheme') { | ||
| 618 | item.default = ''; | ||
| 619 | } | ||
| 620 | }) | ||
| 621 | } | ||
| 622 | const cascaderChange = (val) => { | ||
| 623 | disScore.value = []; | ||
| 624 | if (val) { | ||
| 625 | const baseConfigFormObj = baseConfigFormRef.value; | ||
| 626 | const baseConfigFormInfo = baseConfigFormObj.formInline; | ||
| 627 | const parentsData = baseConfigFormObj.getCascaderCheckedData(); | ||
| 628 | const diseaseName = parentsData[0]?.label || ''; | ||
| 629 | const modelGuid = baseConfigFormInfo.modelGuid; | ||
| 630 | // 获取疾病得分 | ||
| 631 | getTargetNum({ diseaseName, guid: modelGuid }); | ||
| 632 | } | ||
| 633 | } | ||
| 634 | const selectChange = async (val, row, info) => { | ||
| 635 | dataTransactionPrice.value = ''; | ||
| 636 | if (row.field == 'modelGuid') { | ||
| 637 | tableData.value = []; | ||
| 638 | demandTableFieldAllNum.value = 0; | ||
| 639 | resourceTableAllNum.value = 0; | ||
| 640 | resourceTableFieldAllNum.value = 0; | ||
| 641 | await setFormItems(info); | ||
| 642 | val && getModelInfo(val); | ||
| 643 | qualityScoreData.value = {}; | ||
| 644 | baseConfigFormItems.value[1].default = ''; | ||
| 645 | changeDatasource(); | ||
| 646 | } else if (row.field == 'dataResourceGuid') { | ||
| 647 | await setFormItems(info); | ||
| 648 | qualityScoreData.value = {}; | ||
| 649 | resourceTableAllNum.value = 0; | ||
| 650 | resourceTableFieldAllNum.value = 0; | ||
| 651 | if (val) { | ||
| 652 | getResourceInfo(val); | ||
| 653 | } else { | ||
| 654 | changeDatasource(); | ||
| 655 | } | ||
| 656 | } else if (row.field == 'dataTableGuid') { | ||
| 657 | setTableRowData(val, info.$index) | ||
| 658 | } else if (row.field == 'chName') { | ||
| 659 | let tData = info.row; | ||
| 660 | if (val) { | ||
| 661 | const damData = tData.dataFields[row.index].damFieldTable.find(item => item.chName == val); | ||
| 662 | tData.dataFields[row.index].enName = damData?.enName || ''; | ||
| 663 | } else { | ||
| 664 | tData.dataFields[row.index].enName = ''; | ||
| 665 | } | ||
| 666 | tData.dataFieldsNum = tData.dataFields.filter(item => item.chName != '' && item.chName != null).length; | ||
| 667 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | ||
| 668 | return accumulator + Number(currentValue.dataFieldsNum); | ||
| 669 | }, 0); | ||
| 670 | } else { | ||
| 671 | setFormItems(info); | ||
| 672 | } | ||
| 673 | } | ||
| 674 | // 获取需求表字段 | ||
| 675 | const getDemandField = (rGuid, rIndex) => { | ||
| 676 | getDemandList({ | ||
| 677 | pageSize: -1, | ||
| 678 | pageIndex: 1, | ||
| 679 | relationMenuGuid: rGuid, | ||
| 680 | bizState: 'Y' | ||
| 681 | }).then((res: any) => { | ||
| 682 | tableLoading.value = false; | ||
| 683 | if (res.code == proxy.$passCode) { | ||
| 684 | const data = res.data || {}; | ||
| 685 | const fData = data.records || []; | ||
| 686 | const tFields = tableData.value[rIndex].dataFields; | ||
| 687 | const tData = fData.map(item => { | ||
| 688 | const iData = tFields.find(t => t.demandFieldGuid == item.guid) || {}; | ||
| 689 | return { | ||
| 690 | ...item, | ||
| 691 | fieldName: item.fieldName, | ||
| 692 | isRequired: item.isRequired, | ||
| 693 | chName: item.chName || '', | ||
| 694 | enName: item.enName || '', | ||
| 695 | ...iData | ||
| 696 | } | ||
| 697 | }); | ||
| 698 | tableData.value[rIndex].dataFields = tData; | ||
| 699 | |||
| 700 | } else { | ||
| 701 | proxy.$ElMessage.error(res.msg); | ||
| 702 | } | ||
| 703 | }).catch(() => { | ||
| 704 | tableLoading.value = false; | ||
| 705 | }) | ||
| 706 | } | ||
| 707 | const toPath = () => { | ||
| 708 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 709 | assetStore.set(true); | ||
| 710 | router.push({ | ||
| 711 | name: 'priceCalculate', | ||
| 712 | }) | ||
| 713 | } | ||
| 714 | // 获取维度公式计算结果 | ||
| 715 | const getSignatory = (row) => { | ||
| 716 | let formulaVal = 0; | ||
| 717 | const pricingTargetData = row.pricingTargetRSVOS || []; | ||
| 718 | if (!row.computationalFormula || row.computationalFormula == 'custom') { | ||
| 719 | let formula = row.customize; | ||
| 720 | // 遍历数组,检查 customize 是否包含对应的 targetName,若包含则替换为 tNum | ||
| 721 | pricingTargetData.forEach((item) => { | ||
| 722 | if (formula.includes(item.targetName)) { | ||
| 723 | formula = formula.replace(new RegExp(item.targetName, 'g'), item.tNum); | ||
| 724 | } | ||
| 725 | }); | ||
| 726 | // 使用 eval 计算公式结果(注意:eval 存在安全风险,仅适用于受控环境) | ||
| 727 | try { | ||
| 728 | formulaVal = eval(formula); | ||
| 729 | } catch (error) { | ||
| 730 | console.error('公式计算错误:', error); | ||
| 731 | } | ||
| 732 | } else { | ||
| 733 | const formula = pricingTargetData.map(item => item.tNum); | ||
| 734 | if (row.computationalFormula == '3') { | ||
| 735 | formulaVal = formula.reduce((accumulator, currentValue) => parseFloat(accumulator) * parseFloat(currentValue), 1); // 初始值为1 | ||
| 736 | } else { | ||
| 737 | formulaVal = formula.reduce((accumulator, currentValue) => parseFloat(accumulator) + parseFloat(currentValue), 0); // 初始值为0 | ||
| 738 | } | ||
| 739 | } | ||
| 740 | return (Math.round(formulaVal * 100) / 100).toFixed(2); | ||
| 741 | }; | ||
| 742 | const getTargetNum = (params) => { | ||
| 743 | // loading.value = true; | ||
| 744 | getPriceResult(params).then((res: any) => { | ||
| 745 | // loading.value = false; | ||
| 746 | if (res.code === proxy.$passCode) { | ||
| 747 | const data = res.data || []; | ||
| 748 | disScore.value = data; | ||
| 749 | } else { | ||
| 750 | proxy.$ElMessage.error(res.msg); | ||
| 751 | } | ||
| 752 | }).catch(() => { | ||
| 753 | // loading.value = false; | ||
| 754 | }); | ||
| 755 | } | ||
| 756 | |||
| 757 | // 生成报告内容 | ||
| 758 | const reporting = (formInfo) => { | ||
| 759 | let resultInfo: any = []; | ||
| 760 | const signatoryData = JSON.parse(JSON.stringify(modelData.value.pricingDimensionalityRSVOS || '[]')); | ||
| 761 | signatoryData.map((sign, s) => { | ||
| 762 | resultInfo.push({ | ||
| 763 | dimensionalityName: sign.dimensionalityName, | ||
| 764 | computationalFormula: sign.computationalFormula, | ||
| 765 | customize: sign.customize, | ||
| 766 | pricingTargetRSVOS: [] | ||
| 767 | }); | ||
| 768 | const targets = sign.pricingTargetRSVOS || []; | ||
| 769 | const signTargets = targets.map(t => { | ||
| 770 | let tNum: any = 0, tCustomize = ''; | ||
| 771 | if (t.targetType == '3') { // 指标类型-数据字典 | ||
| 772 | const tName = dictionaryData.value.find(d => d.guid == t.guid) ? `dict_${t.guid}` : ''; | ||
| 773 | if (tName) { | ||
| 774 | const pVal = typeMap.value[tName].find(t => t.value == formInfo[tName]); | ||
| 775 | const dictionary = t.dictionaryJson.find(d => d.name == pVal.label); | ||
| 776 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 777 | tNum = parseFloat(t.weight) / 100 * parseFloat(dictionary?.value || t.defaultValue || 0); | ||
| 778 | tCustomize = `权重${parseFloat(t.weight) / 100} * 因子/默认值${parseFloat(dictionary?.value || t.defaultValue || 0)}`; | ||
| 779 | } else { // 其他 | ||
| 780 | tNum = parseFloat(dictionary?.value || t.defaultValue || 0); | ||
| 781 | tCustomize = `默认值${parseFloat(dictionary?.value || t.defaultValue || 0)}`; | ||
| 782 | } | ||
| 783 | t.dictionaryName == '数据用途' && (dataUsage.value = pVal.value || ''); | ||
| 784 | } | ||
| 785 | } else if (t.targetType == '2') {// 指标类型-系统功能 | ||
| 786 | if (t.functionName == '1') { // 功能名称-质量评价模型 | ||
| 787 | const score = parseFloat(qualityScoreData.value.qualityScore || 0); | ||
| 788 | tNum = parseFloat(t.weight || 1) / 100 * score; | ||
| 789 | tCustomize = `权重${parseFloat(t.weight) / 100} * 模型评分${score}`; | ||
| 790 | } else if (t.functionName == '2') { // 功能名称-疾病管理 | ||
| 791 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 792 | const score = parseFloat(disScore.value.find(d => d.guid == t.guid)?.factor || 0); | ||
| 793 | tNum = parseFloat(t.weight) / 100 * score; | ||
| 794 | tCustomize = `权重${parseFloat(t.weight) / 100} * 疾病得分${score}`; | ||
| 795 | } else { //其他 | ||
| 796 | tNum = parseFloat(disScore.value.find(d => d.guid == t.guid)?.factor || 0); | ||
| 797 | tCustomize = `疾病得分${tNum}`; | ||
| 798 | } | ||
| 799 | } else if (t.functionName == '3') {// 功能名称-需求表管理 | ||
| 800 | const tData = tableData.value.find(f => f.demandTableGuid == t.demandTableGuid || f.guid == t.demandTableGuid); | ||
| 801 | if (tData) { | ||
| 802 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 803 | tNum = parseFloat(t.weight) / 100 * (parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)); | ||
| 804 | tCustomize = `权重${parseFloat(t.weight) / 100} * 匹配率/默认值${parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)}`; | ||
| 805 | } else { //其他 | ||
| 806 | tNum = parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0); | ||
| 807 | tCustomize = `匹配率/默认值${parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)}`; | ||
| 808 | } | ||
| 809 | } | ||
| 810 | } | ||
| 811 | } else { // 指标类型-系统内置 | ||
| 812 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 813 | tNum = parseFloat(t.weight) / 100 * parseFloat(t.defaultValue || 0); | ||
| 814 | tCustomize = `权重${parseFloat(t.weight) / 100} * 默认值${parseFloat(t.defaultValue || 0)}`; | ||
| 815 | } else { //其他 | ||
| 816 | tNum = parseFloat(t.defaultValue || 0); | ||
| 817 | tCustomize = `默认值${parseFloat(t.defaultValue || 0)}`; | ||
| 818 | } | ||
| 819 | } | ||
| 820 | t.tNum = (Math.round(parseFloat(tNum) * 100) / 100).toFixed(2); | ||
| 821 | resultInfo[s].pricingTargetRSVOS.push({ | ||
| 822 | targetName: t.targetName, | ||
| 823 | targetType: t.targetType, | ||
| 824 | functionName: t.functionName, | ||
| 825 | customize: tCustomize, | ||
| 826 | tNum: t.tNum, | ||
| 827 | }) | ||
| 828 | return t; | ||
| 829 | }) | ||
| 830 | sign.pricingTargetRSVOS = signTargets; | ||
| 831 | sign.sNum = getSignatory(sign); | ||
| 832 | resultInfo[s].sNum = sign.sNum; | ||
| 833 | }) | ||
| 834 | // exportData.value = resultInfo; | ||
| 835 | return { signatoryData, resultInfo }; | ||
| 836 | } | ||
| 837 | |||
| 838 | // 计算价格 | ||
| 839 | const calculatePrice = (pData) => { | ||
| 840 | let modelFormula = modelData.value.modelFormula; | ||
| 841 | // 1. 移除所有干扰的引号(确保是数学表达式) | ||
| 842 | modelFormula = modelFormula.replace(/["']/g, ""); | ||
| 843 | |||
| 844 | // 1. 提取变量名(中文、英文、数字、下划线) | ||
| 845 | const variableRegex = /[\u4e00-\u9fa5a-zA-Z_][\u4e00-\u9fa5a-zA-Z0-9_]*/g; | ||
| 846 | const variableNames = modelFormula.match(variableRegex) || []; | ||
| 847 | |||
| 848 | // 2. 去重 | ||
| 849 | const uniqueVariables = [...new Set(variableNames)]; | ||
| 850 | |||
| 851 | // 3. 构建变量映射 { 销售额: 2000, 成本: 500.5, ... } | ||
| 852 | const variables = {}; | ||
| 853 | uniqueVariables.forEach(name => { | ||
| 854 | const dim = pData.find(d => d.dimensionalityName === name); | ||
| 855 | variables[name] = dim ? parseFloat(dim.sNum) : 0; // 找不到则默认为 0 | ||
| 856 | }); | ||
| 857 | |||
| 858 | // 4. 替换变量为数值(不加引号,确保是数字运算) | ||
| 859 | let expression = modelFormula; | ||
| 860 | uniqueVariables.forEach(name => { | ||
| 861 | expression = expression.replace(new RegExp(name, 'g'), variables[name]); | ||
| 862 | }); | ||
| 863 | |||
| 864 | // 5. 安全计算(推荐 math.js,或 new Function) | ||
| 865 | try { | ||
| 866 | //如果用 eval,确保表达式格式正确 | ||
| 867 | const resultNum = eval(expression); | ||
| 868 | |||
| 869 | dataTransactionPrice.value = (Math.round(parseFloat(resultNum) * 100) / 100).toFixed(2); | ||
| 870 | } catch (error) { | ||
| 871 | console.error('公式计算错误:', error); | ||
| 872 | return NaN; | ||
| 873 | } | ||
| 874 | }; | ||
| 875 | |||
| 876 | // 计算结果和提交 | ||
| 877 | const checkForm = (type) => { | ||
| 878 | const baseConfigFormObj = baseConfigFormRef.value; | ||
| 879 | const baseConfigFormEl = baseConfigFormObj.ruleFormRef; | ||
| 880 | const baseConfigFormInfo = baseConfigFormObj.formInline; | ||
| 881 | baseConfigFormEl.validate((valid, errorItem) => { | ||
| 882 | if (valid) { | ||
| 883 | if (type == 'calculate') { | ||
| 884 | const { signatoryData, resultInfo } = reporting(baseConfigFormInfo); | ||
| 885 | exportData.value = resultInfo; | ||
| 886 | calculatePrice(signatoryData); | ||
| 887 | } else if (type == 'export') { | ||
| 888 | const { signatoryData, resultInfo } = reporting(baseConfigFormInfo); | ||
| 889 | exportData.value = resultInfo; | ||
| 890 | !dataTransactionPrice.value && calculatePrice(signatoryData); | ||
| 891 | loading.value = true; | ||
| 892 | let exportOut: any = {}; | ||
| 893 | // 估值对象信息 | ||
| 894 | const damName = typeMap.value.dataResourceGuid.find(f => f.damGuid == baseConfigFormInfo.dataResourceGuid)?.damName || ''; | ||
| 895 | exportOut.one = `因${baseConfigFormInfo.belongingEntityGuid}拟了解其所持有的\"${damName}\"相关数据资源的价格,为此需对该行为涉及的数据资源在不同应用场景下,基于数据资源持有单位的性质、信息化程度、数据稀缺性、需求匹配等情况下,为上述经济行为提供定价参考依据。`; | ||
| 896 | exportOut.two = `估值对象:${baseConfigFormInfo.belongingEntityGuid}持有的\"${damName}\"`; | ||
| 897 | // 估值范围信息 | ||
| 898 | const damNames = demandTableList.value.map(item => item.menuName) | ||
| 899 | let rangStr = `包含${damNames.join('、')}等${damNames.length}张表单,${damNames.length}张表共计${demandTableFieldAllNum.value}个字段`; | ||
| 900 | const dataTimeliness = pricingTargetList.value.find(p => p.dictionaryName == '时效性'); | ||
| 901 | const dataTimelinessStr = dataTimeliness ? typeMap.value[`dict_${dataTimeliness.guid}`].find(f => f.value == baseConfigFormInfo[`dict_${dataTimeliness.guid}`])?.label || '' : ''; | ||
| 902 | rangStr += dataTimelinessStr ? `,时间跨度为${dataTimelinessStr}的数据` : `的数据`; | ||
| 903 | damNames.length && (exportOut.two = `${exportOut.two}\n估值范围:${rangStr}`); | ||
| 904 | // 字典 | ||
| 905 | let dictList: any = [], hasModelScore = false; | ||
| 906 | const dictStr = exportData.value.map(e => { | ||
| 907 | // 检查是否有质量模型评分 | ||
| 908 | hasModelScore = hasModelScore || e.pricingTargetRSVOS.some( | ||
| 909 | t => t.targetType === '2' && t.functionName === '1' | ||
| 910 | ); | ||
| 911 | |||
| 912 | // 只有当维度指标数大于1时才处理明细 | ||
| 913 | if (e.pricingTargetRSVOS.length > 1) { | ||
| 914 | const targetStr = e.pricingTargetRSVOS | ||
| 915 | .map(t => `${t.targetName}为${changeNum(t.tNum, 2)}`) | ||
| 916 | .join('、'); | ||
| 917 | |||
| 918 | dictList.push(`${e.dimensionalityName}为${changeNum(e.sNum, 2)},其中${targetStr}`); | ||
| 919 | } | ||
| 920 | |||
| 921 | return `${e.dimensionalityName}为${changeNum(e.sNum, 2)}`; | ||
| 922 | }) | ||
| 923 | let dictListStr = `${dictStr.join(',')}。\n${dictList.join(';\n')}` | ||
| 924 | // 质量模型 | ||
| 925 | if (hasModelScore) { | ||
| 926 | const { largeCategoryScoreList = [], qualityScore = 0 } = qualityScoreData.value; | ||
| 927 | const qualityParts = [ | ||
| 928 | `数据的总体质量得分为${changeNum(qualityScore, 2)}` | ||
| 929 | ]; | ||
| 930 | |||
| 931 | if (largeCategoryScoreList.length) { | ||
| 932 | const categoryScores = largeCategoryScoreList.map( | ||
| 933 | q => `${q.largeCategoryName}方面得分为${changeNum(q.largeCategoryScore || 0, 2)}` | ||
| 934 | ); | ||
| 935 | qualityParts.push(`其中${categoryScores.join(',')}`); | ||
| 936 | } | ||
| 937 | |||
| 938 | dictListStr += `;\n${qualityParts.join('。')}`; | ||
| 939 | } | ||
| 940 | exportOut.three = `${baseConfigFormInfo.belongingEntityGuid}持有的"${damName}"的数据(患者人次)单价为${changeNum(dataTransactionPrice.value, 2)}元${dictListStr ? `;其中${dictListStr}` : '。'}`; | ||
| 941 | |||
| 942 | exportModelScore(exportOut).then((res: any) => { | ||
| 943 | loading.value = false; | ||
| 944 | if (res && !res.msg) { | ||
| 945 | ElMessage({ | ||
| 946 | type: "success", | ||
| 947 | message: '下载报告成功', | ||
| 948 | }); | ||
| 949 | download(res, `数据定价报告.doc`, 'word'); | ||
| 950 | } else { | ||
| 951 | res?.msg && ElMessage.error(res?.msg); | ||
| 952 | } | ||
| 953 | }).catch(() => { | ||
| 954 | loading.value = false; | ||
| 955 | ElMessage({ | ||
| 956 | type: "error", | ||
| 957 | message: '下载报告请求失败', | ||
| 958 | }); | ||
| 959 | }) | ||
| 960 | } else { | ||
| 961 | const { signatoryData, resultInfo } = reporting(baseConfigFormInfo); | ||
| 962 | exportData.value = resultInfo; | ||
| 963 | !dataTransactionPrice.value && calculatePrice(signatoryData); | ||
| 964 | const modelName = typeMap.value.modelGuid.find(d => d.guid == baseConfigFormInfo.modelGuid)?.modelName || ''; | ||
| 965 | const dataResourceName = typeMap.value.dataResourceGuid.find(d => d.damGuid == baseConfigFormInfo.dataResourceGuid)?.damName || ''; | ||
| 966 | const diseaseGuid = baseConfigFormInfo.diseaseGuid || ''; | ||
| 967 | let params: any = { | ||
| 968 | tenantGuid: userData.tenantGuid, | ||
| 969 | dataTransactionPrice: dataTransactionPrice.value, | ||
| 970 | modelGuid: baseConfigFormInfo.modelGuid, | ||
| 971 | modelName, | ||
| 972 | dataResourceGuid: baseConfigFormInfo.dataResourceGuid, | ||
| 973 | dataResourceName, | ||
| 974 | belongingEntityGuid: baseConfigFormInfo.belongingEntityGuid, | ||
| 975 | belongingTheme: baseConfigFormInfo.belongingTheme, | ||
| 976 | diseaseGuid, | ||
| 977 | diseaseName: '', | ||
| 978 | dataUsage: dataUsage.value | ||
| 979 | }; | ||
| 980 | if (diseaseGuid) { | ||
| 981 | const parentsData = baseConfigFormObj.getCascaderCheckedData(); | ||
| 982 | params.diseaseName = parentsData[0]?.label || ''; | ||
| 983 | } | ||
| 984 | let dictionaryJson = {}; | ||
| 985 | for (var b in baseConfigFormInfo) { | ||
| 986 | if (b.indexOf('dict_') > -1) { | ||
| 987 | dictionaryJson[b] = baseConfigFormInfo[b]; | ||
| 988 | } | ||
| 989 | } | ||
| 990 | params.dictionaryJson = Object.keys(dictionaryJson).length ? JSON.stringify(dictionaryJson) : ''; | ||
| 991 | let demandMatchingData: any = []; | ||
| 992 | tableData.value.map(item => { | ||
| 993 | demandMatchingData.push({ | ||
| 994 | demandTableName: item.demandTableName, | ||
| 995 | demandTableGuid: item.demandTableGuid || item.guid, // 需求表guid | ||
| 996 | dataTableGuid: item.dataTableGuid, // 数据资源表guid | ||
| 997 | weightDemandTable: item.weightDemandTable, | ||
| 998 | dataFieldsNum: item.dataFieldsNum, | ||
| 999 | pricingDemandFieldRQVOS: item.dataFields.map(d => { | ||
| 1000 | return { | ||
| 1001 | demandFieldGuid: d.demandFieldGuid || d.guid, // 资源表字段guid | ||
| 1002 | fieldName: d.fieldName, | ||
| 1003 | enName: d.enName, | ||
| 1004 | chName: d.chName, | ||
| 1005 | isRequired: d.isRequired | ||
| 1006 | } | ||
| 1007 | }) | ||
| 1008 | }) | ||
| 1009 | }); | ||
| 1010 | params.dataPricingDemandmatchingRQVOS = demandMatchingData; | ||
| 1011 | guid && (params.guid = guid); | ||
| 1012 | loading.value = true; | ||
| 1013 | savePrice(params).then((res: any) => { | ||
| 1014 | loading.value = false; | ||
| 1015 | if (res.code == proxy.$passCode) { | ||
| 1016 | ElMessage({ | ||
| 1017 | type: "success", | ||
| 1018 | message: guid ? '编辑数据定价成功' : '新增数据定价成功', | ||
| 1019 | }); | ||
| 1020 | toPath() | ||
| 1021 | } else { | ||
| 1022 | proxy.$ElMessage.error(res.msg); | ||
| 1023 | } | ||
| 1024 | }).catch(() => { | ||
| 1025 | loading.value = false; | ||
| 1026 | }); | ||
| 1027 | } | ||
| 1028 | } else { | ||
| 1029 | expand1.value = true; | ||
| 1030 | var obj = Object.keys(errorItem); | ||
| 1031 | baseConfigFormEl.scrollToField(obj[0]); | ||
| 1032 | } | ||
| 1033 | }) | ||
| 1034 | } | ||
| 1035 | const btnClick = async (btn, row: any = null) => { | ||
| 1036 | const type = btn.value; | ||
| 1037 | if (type == 'dim') { | ||
| 1038 | baseConfigFormItems.value.at(-1).default += btn.name; | ||
| 1039 | } else if (type == 'del-signatory') { | ||
| 1040 | open('确定要删除该条维度数据吗?', 'warning'); | ||
| 1041 | } else if (type == 'expend') { | ||
| 1042 | expendTableRef.value.toggleRowExpansion(row); | ||
| 1043 | } else if (type == 'calculate' || type == 'submit') { | ||
| 1044 | if (type == 'submit') { | ||
| 1045 | ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并提交' : '请确认当前数据交易价格是否为最新计算结果', '提示', { | ||
| 1046 | confirmButtonText: '确定', | ||
| 1047 | cancelButtonText: '取消', | ||
| 1048 | type: 'warning', | ||
| 1049 | }).then(() => { | ||
| 1050 | checkForm(type); | ||
| 1051 | }).catch(() => { | ||
| 1052 | ElMessage.info('已取消提交操作'); | ||
| 1053 | }); | ||
| 1054 | } else { | ||
| 1055 | checkForm(type); | ||
| 1056 | } | ||
| 1057 | } else if (type == 'export') { | ||
| 1058 | ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并下载' : '请确认当前数据交易价格是否为最新计算结果', '提示', { | ||
| 1059 | confirmButtonText: '确定', | ||
| 1060 | cancelButtonText: '取消', | ||
| 1061 | type: 'warning', | ||
| 1062 | }).then(() => { | ||
| 1063 | checkForm(type); | ||
| 1064 | }).catch(() => { | ||
| 1065 | ElMessage.info('已取消下载操作'); | ||
| 1066 | }); | ||
| 1067 | } else if (type == 'cancel') { | ||
| 1068 | ElMessageBox.confirm( | ||
| 1069 | "当前页面尚未保存,确定关闭吗?", | ||
| 1070 | "提示", | ||
| 1071 | { | ||
| 1072 | confirmButtonText: "确定", | ||
| 1073 | cancelButtonText: "取消", | ||
| 1074 | type: "warning", | ||
| 1075 | } | ||
| 1076 | ).then(() => { | ||
| 1077 | toPath() | ||
| 1078 | }).catch(() => { | ||
| 1079 | ElMessage({ | ||
| 1080 | type: "info", | ||
| 1081 | message: "已取消", | ||
| 1082 | }); | ||
| 1083 | }); | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | onActivated(() => { | ||
| 1087 | let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath); | ||
| 1088 | if (tab) { | ||
| 1089 | switch (route.query.type) { | ||
| 1090 | case 'create': | ||
| 1091 | tab.meta.title = `新增数据定价`; | ||
| 1092 | break; | ||
| 1093 | case 'edit': | ||
| 1094 | tab.meta.title = `编辑-${priceName}`; | ||
| 1095 | break; | ||
| 1096 | case 'detail': | ||
| 1097 | tab.meta.title = `详情-${priceName}`; | ||
| 1098 | break; | ||
| 1099 | } | ||
| 1100 | } | ||
| 1101 | getModel() | ||
| 1102 | }) | ||
| 1103 | onBeforeMount(() => { | ||
| 1104 | if (guid) { | ||
| 1105 | getDetail(); | ||
| 1106 | } else { | ||
| 1107 | getDataTypeList(); | ||
| 1108 | getModel() | ||
| 1109 | } | ||
| 1110 | }) | ||
| 1111 | onMounted(() => { | ||
| 1112 | }) | ||
| 1113 | </script> | ||
| 1114 | <template> | ||
| 1115 | <div class="container_wrap full" v-loading="loading"> | ||
| 1116 | <div class="content_main panel"> | ||
| 1117 | <ContentWrap id="contract-content-wrap" title="输入参数" expandSwicth style="margin-top: 15px" :isExpand="expand1" | ||
| 1118 | @expand="(v) => expand1 = v"> | ||
| 1119 | <Form ref="baseConfigFormRef" formId="contract-content-form" :itemList="baseConfigForm.items" | ||
| 1120 | :rules="baseConfigForm.rules" col="col3" @selectChange="selectChange" @cascaderChange="cascaderChange" /> | ||
| 1121 | </ContentWrap> | ||
| 1122 | <ContentWrap id="contract-signatory-wrap" title="需求匹配" expandSwicth style="margin-top: 15px" :isExpand="expand2" | ||
| 1123 | @expand="(v) => expand2 = v"> | ||
| 1124 | <div class="table_panel_wrap"> | ||
| 1125 | <div class="table_tool"> | ||
| 1126 | <div class="tool_title"> | ||
| 1127 | <div class="title_desc"> | ||
| 1128 | <span>需求表数量:</span> | ||
| 1129 | <span class="text-num">{{ demandTableList.length }}</span> | ||
| 1130 | <span>张,字段数:</span> | ||
| 1131 | <span class="text-num">{{ demandTableFieldAllNum }}</span> | ||
| 1132 | <span>匹配表数量:</span> | ||
| 1133 | <span class="text-num">{{ resourceTableAllNum }}</span> | ||
| 1134 | <span>张,字段数:</span> | ||
| 1135 | <span class="text-num">{{ resourceTableFieldAllNum }}</span> | ||
| 1136 | </div> | ||
| 1137 | </div> | ||
| 1138 | </div> | ||
| 1139 | <div class="table_panel" v-loading="tableLoading"> | ||
| 1140 | <el-table ref="expendTableRef" border :data="tableData" row-key="demandTableName" tooltip-effect="light" | ||
| 1141 | style="height: 100%;"> | ||
| 1142 | <el-table-column type="expand"> | ||
| 1143 | <template #default="props"> | ||
| 1144 | <div class="expand_panel"> | ||
| 1145 | <div class="table_tool"> | ||
| 1146 | <div class="tool_title"> | ||
| 1147 | <div class="title_desc"> | ||
| 1148 | <span>需求字段数:</span> | ||
| 1149 | <span class="text-num">{{ props.row.dataFields.length }}</span> | ||
| 1150 | <span>个,匹配字段数:</span> | ||
| 1151 | <span class="text-num">{{ props.row.dataFieldsNum }}</span> | ||
| 1152 | </div> | ||
| 1153 | </div> | ||
| 1154 | </div> | ||
| 1155 | <el-table :data="props.row.dataFields" border> | ||
| 1156 | <el-table-column label="序号" type="index" width="56" align="center" /> | ||
| 1157 | <el-table-column label="需求字段中文" prop="fieldName" class-name="edit-col"> | ||
| 1158 | <template #default="scope"> | ||
| 1159 | <el-input v-model.trim="scope.row.fieldName" placeholder="请输入" disabled /> | ||
| 1160 | </template> | ||
| 1161 | </el-table-column> | ||
| 1162 | <el-table-column label="匹配字段中文" prop="chName" class-name="edit-col"> | ||
| 1163 | <template #default="scope"> | ||
| 1164 | <el-select v-model="scope.row.chName" clearable filterable | ||
| 1165 | @change="val => selectChange(val, { field: 'chName', index: scope.$index }, props)"> | ||
| 1166 | <el-option v-for="(opt, o) in scope.row.damFieldTable" :label="opt.label" :value="opt.value" | ||
| 1167 | :key="o" /> | ||
| 1168 | </el-select> | ||
| 1169 | </template> | ||
| 1170 | </el-table-column> | ||
| 1171 | <el-table-column label="匹配字段英文" prop="enName" class-name="edit-col"> | ||
| 1172 | <template #default="scope"> | ||
| 1173 | <el-input v-model.trim="scope.row.enName" placeholder="请输入" disabled /> | ||
| 1174 | </template> | ||
| 1175 | </el-table-column> | ||
| 1176 | <el-table-column label="是否必需字段" prop="isRequired" class-name="edit-col"> | ||
| 1177 | <template #default="scope"> | ||
| 1178 | <el-select v-model="scope.row.isRequired" disabled> | ||
| 1179 | <el-option label="是" value="Y" /> | ||
| 1180 | <el-option label="否" value="N" /> | ||
| 1181 | </el-select> | ||
| 1182 | </template> | ||
| 1183 | </el-table-column> | ||
| 1184 | </el-table> | ||
| 1185 | </div> | ||
| 1186 | </template> | ||
| 1187 | </el-table-column> | ||
| 1188 | <el-table-column label="序号" type="index" width="56" align="center" /> | ||
| 1189 | <el-table-column v-for="item in tableFields" :key="item.field" :label="item.label" :prop="item.field" | ||
| 1190 | :width="item.width" :align="item.align" class-name="edit-col"> | ||
| 1191 | <template #default="scope"> | ||
| 1192 | <el-select v-if="item.type == 'select'" v-model="scope.row[item.field]" clearable filterable | ||
| 1193 | @change="val => selectChange(val, item, scope)"> | ||
| 1194 | <el-option v-for="(opt, o) in scope.row.damDataTable" :label="opt.label" :value="opt.value" | ||
| 1195 | :key="o" /> | ||
| 1196 | </el-select> | ||
| 1197 | <el-input v-else v-model.trim="scope.row[item.field]" :disabled="item.disabled" placeholder="请输入" | ||
| 1198 | clearable /> | ||
| 1199 | </template> | ||
| 1200 | </el-table-column> | ||
| 1201 | <el-table-column label="操作" fixed="right" width="100"> | ||
| 1202 | <template #default="scope"> | ||
| 1203 | <el-button type="primary" link @click="btnClick({ value: 'expend' }, scope.row)">字段映射</el-button> | ||
| 1204 | </template> | ||
| 1205 | </el-table-column> | ||
| 1206 | </el-table> | ||
| 1207 | </div> | ||
| 1208 | </div> | ||
| 1209 | </ContentWrap> | ||
| 1210 | <ContentWrap id="contract-content-wrap" title="输出结构" expandSwicth style="margin-top: 15px" :isExpand="expand3" | ||
| 1211 | @expand="(v) => expand3 = v"> | ||
| 1212 | <el-form class="result-form"> | ||
| 1213 | <el-form-item class="flex-column" label="数据交易价格(元)"> | ||
| 1214 | <el-input v-model="dataTransactionPrice" placeholder="" disabled style="display: none;" /> | ||
| 1215 | <div class="result-price">{{ changeNum(dataTransactionPrice, 2) }}</div> | ||
| 1216 | </el-form-item> | ||
| 1217 | <el-form-item class="align-end" style="margin-bottom: 14px;"> | ||
| 1218 | <el-button type="primary" @click="btnClick({ value: 'calculate' })">开始计算</el-button> | ||
| 1219 | <el-button @click="btnClick({ value: 'export' })">下载报告</el-button> | ||
| 1220 | <span style="margin-left: 8px">输出结果报告查看</span> | ||
| 1221 | </el-form-item> | ||
| 1222 | </el-form> | ||
| 1223 | </ContentWrap> | ||
| 1224 | </div> | ||
| 1225 | <div class="tool_btns"> | ||
| 1226 | <div class="btns"> | ||
| 1227 | <el-button @click="btnClick({ value: 'cancel' })">取消</el-button> | ||
| 1228 | <el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button> | ||
| 1229 | </div> | ||
| 1230 | </div> | ||
| 1231 | </div> | ||
| 1232 | </template> | ||
| 1233 | <style scoped lang="scss"> | ||
| 1234 | .container_wrap { | ||
| 1235 | overflow: hidden; | ||
| 1236 | |||
| 1237 | .content_main { | ||
| 1238 | height: calc(100% - 45px); | ||
| 1239 | overflow: hidden auto; | ||
| 1240 | |||
| 1241 | &.panel { | ||
| 1242 | padding: 0 16px 16px; | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | :deep(.el-card) { | ||
| 1246 | &#contract-signatory-wrap { | ||
| 1247 | .card-body-content { | ||
| 1248 | padding: 8px 16px; | ||
| 1249 | } | ||
| 1250 | } | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | .signatory-tags { | ||
| 1254 | margin-bottom: 11px; | ||
| 1255 | } | ||
| 1256 | |||
| 1257 | .table_panel_wrap { | ||
| 1258 | margin-bottom: 4px; | ||
| 1259 | |||
| 1260 | .table_tool { | ||
| 1261 | height: 36px; | ||
| 1262 | display: flex; | ||
| 1263 | justify-content: space-between; | ||
| 1264 | align-items: center; | ||
| 1265 | |||
| 1266 | .tool_title { | ||
| 1267 | width: 100%; | ||
| 1268 | display: flex; | ||
| 1269 | justify-content: start; | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | .title_desc { | ||
| 1273 | overflow: hidden; | ||
| 1274 | white-space: nowrap; | ||
| 1275 | text-overflow: ellipsis; | ||
| 1276 | |||
| 1277 | .text-num { | ||
| 1278 | color: var(--el-color-primary); | ||
| 1279 | margin: 0 8px; | ||
| 1280 | } | ||
| 1281 | } | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | .table_panel { | ||
| 1285 | margin-bottom: 4px; | ||
| 1286 | height: 392px; | ||
| 1287 | |||
| 1288 | :deep(.el-table) { | ||
| 1289 | .el-table__cell { | ||
| 1290 | &.edit-col { | ||
| 1291 | padding: 4px 0; | ||
| 1292 | |||
| 1293 | .cell { | ||
| 1294 | padding: 0 4px; | ||
| 1295 | |||
| 1296 | .el-cascader { | ||
| 1297 | width: 100%; | ||
| 1298 | height: 28px; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | .el-input { | ||
| 1302 | height: 28px; | ||
| 1303 | } | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | .expand-icon { | ||
| 1308 | color: #888; | ||
| 1309 | margin-right: 8px; | ||
| 1310 | vertical-align: text-bottom; | ||
| 1311 | cursor: pointer; | ||
| 1312 | } | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | .el-input.is-disabled .el-input__wrapper { | ||
| 1316 | background-color: var(--el-disabled-bg-color); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | .el-select__wrapper.is-disabled { | ||
| 1320 | background-color: var(--el-disabled-bg-color); | ||
| 1321 | } | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | .expand_panel { | ||
| 1325 | padding: 6px; | ||
| 1326 | margin: -6px 0; | ||
| 1327 | background: #fff; | ||
| 1328 | } | ||
| 1329 | } | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | .btn-block { | ||
| 1334 | width: 100%; | ||
| 1335 | margin: 16px 0 8px; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | .tool_btns { | ||
| 1339 | height: 44px; | ||
| 1340 | margin: 0 -8px; | ||
| 1341 | display: flex; | ||
| 1342 | justify-content: center; | ||
| 1343 | align-items: center; | ||
| 1344 | border-top: 1px solid #d9d9d9; | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | :deep(.el-form) { | ||
| 1349 | &.result-form { | ||
| 1350 | display: flex; | ||
| 1351 | |||
| 1352 | .el-form-item { | ||
| 1353 | &.flex-column { | ||
| 1354 | width: calc(33.33% - 6px); | ||
| 1355 | margin-right: 8px; | ||
| 1356 | display: flex; | ||
| 1357 | flex-direction: column; | ||
| 1358 | align-items: self-start; | ||
| 1359 | |||
| 1360 | .el-form-item__content { | ||
| 1361 | width: 100%; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | .result-price { | ||
| 1365 | width: 100%; | ||
| 1366 | height: 32px; | ||
| 1367 | line-height: 32px; | ||
| 1368 | padding: 1px 11px; | ||
| 1369 | border-radius: 4px; | ||
| 1370 | cursor: not-allowed; | ||
| 1371 | color: var(--el-disabled-text-color); | ||
| 1372 | background-color: var(--el-disabled-bg-color); | ||
| 1373 | box-shadow: 0 0 0 1px var(--el-disabled-border-color) inset; | ||
| 1374 | } | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | &.align-end { | ||
| 1378 | align-self: flex-end; | ||
| 1379 | } | ||
| 1380 | } | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | .el-select__wrapper.is-disabled { | ||
| 1384 | background-color: var(--el-disabled-bg-color); | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | </style> |
src/views/data_pricing/demandManage.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: demandManage | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="demandManage"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import { TableColumnWidth, commonPageConfig } from '@/utils/enum'; | ||
| 8 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 9 | import { CirclePlus, Search } from "@element-plus/icons-vue"; | ||
| 10 | import { useRouter, useRoute } from "vue-router"; | ||
| 11 | import { changeNum, getCurrentTime } from '@/utils/common'; | ||
| 12 | import useUserStore from "@/store/modules/user"; | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { | ||
| 15 | getDemandAll, | ||
| 16 | saveDemandTree, | ||
| 17 | updateDemandTree, | ||
| 18 | deleteDemandTree, | ||
| 19 | getDemandList, | ||
| 20 | saveDemand, | ||
| 21 | updateDemand, | ||
| 22 | deleteDemand, | ||
| 23 | } from '@/api/modules/dataPricing'; | ||
| 24 | |||
| 25 | const router = useRouter(); | ||
| 26 | const userStore = useUserStore() | ||
| 27 | const userData = JSON.parse(userStore.userData) | ||
| 28 | const { proxy } = getCurrentInstance() as any; | ||
| 29 | const cacheStore = useCatchStore() | ||
| 30 | |||
| 31 | /** 左侧标签列表管理 */ | ||
| 32 | const treeInfoRef = ref(); | ||
| 33 | const treeData = ref([]); | ||
| 34 | const treeInfo = ref({ | ||
| 35 | id: "demand-tree", | ||
| 36 | filter: true, | ||
| 37 | editTreeItem: true, | ||
| 38 | queryValue: "", | ||
| 39 | loading: false, | ||
| 40 | className: 'tree-list-manage', | ||
| 41 | queryPlaceholder: "输入关键字搜索", | ||
| 42 | props: { | ||
| 43 | label: "menuName", | ||
| 44 | value: "guid", | ||
| 45 | children: 'childList', | ||
| 46 | }, | ||
| 47 | prefix: { | ||
| 48 | type: 'prefixIcon' | ||
| 49 | }, | ||
| 50 | lazy: false, | ||
| 51 | nodeKey: 'guid', | ||
| 52 | expendAll: true, | ||
| 53 | currentNodeKey: '', | ||
| 54 | expandOnNodeClick: false, | ||
| 55 | data: [], | ||
| 56 | }); | ||
| 57 | |||
| 58 | const catalogData = ref([]); | ||
| 59 | const searchItemList = ref([ | ||
| 60 | { | ||
| 61 | type: "select", | ||
| 62 | label: "", | ||
| 63 | field: "isRequired", | ||
| 64 | placeholder: "是否必选", | ||
| 65 | default: "", | ||
| 66 | options: [ | ||
| 67 | { label: '是', value: 'Y' }, | ||
| 68 | { label: '否', value: 'N' } | ||
| 69 | ], | ||
| 70 | clearable: true, | ||
| 71 | style: { | ||
| 72 | width: '140px' | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | { | ||
| 76 | type: "input", | ||
| 77 | label: "", | ||
| 78 | field: "fieldName", | ||
| 79 | default: "", | ||
| 80 | placeholder: "字段名称", | ||
| 81 | clearable: true, | ||
| 82 | style: { | ||
| 83 | width: '230px' | ||
| 84 | } | ||
| 85 | }, | ||
| 86 | ]); | ||
| 87 | |||
| 88 | const lastClickNode: any = ref({}); | ||
| 89 | const showTable = ref(false) | ||
| 90 | /** 记录正在提交审批流程的api,防止重复提交 */ | ||
| 91 | const addDataPromise: any = ref(); | ||
| 92 | const tableRef = ref(); | ||
| 93 | const tableData: any = ref([]); | ||
| 94 | const selectRowData: any = ref([]) | ||
| 95 | const currTableData: any = ref({}); | ||
| 96 | const page: any = ref({ | ||
| 97 | ...commonPageConfig, | ||
| 98 | fieldName: '', | ||
| 99 | isRequired: '', | ||
| 100 | }); | ||
| 101 | const tableFields: any = [ | ||
| 102 | { label: "字段名称", field: "fieldName" }, | ||
| 103 | { label: "是否必选", field: "isRequired", type: 'select' }, | ||
| 104 | { label: "排序", field: "orderNum", type: 'defaultValue' }, | ||
| 105 | { label: '启用状态', field: 'bizState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N' }, | ||
| 106 | { label: "创建时间", field: "createTime", type: 'defaultValue' }, | ||
| 107 | ] | ||
| 108 | const tableInfo: any = ref({ | ||
| 109 | id: 'api-data-table', | ||
| 110 | rowKey: 'guid', | ||
| 111 | loading: false, | ||
| 112 | multiple: true, | ||
| 113 | fields: [ | ||
| 114 | { label: "字段名称", field: "fieldName", width: 200, align: "left", type: 'edit' }, | ||
| 115 | { | ||
| 116 | label: "是否必选", field: "isRequired", width: 140, type: 'edit', getName: (scope) => { | ||
| 117 | return scope.row.isRequired == 'Y' ? '是' : '否' | ||
| 118 | } | ||
| 119 | }, | ||
| 120 | { label: "排序", field: "orderNum", width: 120, type: 'edit', dataTypeName: 'fieldType' }, | ||
| 121 | { | ||
| 122 | label: '启用状态', field: 'bizState', type: 'edit', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N', switchWidth: 56, width: 96, align: 'center', | ||
| 123 | }, | ||
| 124 | { label: "创建时间", field: "createTime", width: TableColumnWidth.DATETIME, type: 'edit', dataTypeName: 'dateType' }, | ||
| 125 | ], | ||
| 126 | data: tableData.value, | ||
| 127 | editInfo: [], | ||
| 128 | page: { | ||
| 129 | type: "normal", | ||
| 130 | rows: 0, | ||
| 131 | ...page.value, | ||
| 132 | }, | ||
| 133 | actionInfo: { | ||
| 134 | label: "操作", | ||
| 135 | type: "btn", | ||
| 136 | isMore: false, | ||
| 137 | width: 120, | ||
| 138 | btns: (scope) => { | ||
| 139 | let btns: any[] = []; | ||
| 140 | if (scope.row.STATUS == 'edit') { | ||
| 141 | btns.push({ | ||
| 142 | value: 'save', label: '保存', click: (scope) => { | ||
| 143 | if (addDataPromise.value) { | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | // 调用新增数据的接口。 | ||
| 147 | let params = { ...scope.row, tenantGuid: userData.tenantGuid }; | ||
| 148 | params.relationMenuGuid = lastClickNode.value.guid; | ||
| 149 | delete params['ROWID']; | ||
| 150 | delete params['STATUS']; | ||
| 151 | delete params['STATE']; | ||
| 152 | delete params.dateType; | ||
| 153 | delete params.fieldType; | ||
| 154 | if (params.guid) { | ||
| 155 | addDataPromise.value = updateDemand(params).then((res: any) => { | ||
| 156 | addDataPromise.value = null; | ||
| 157 | if (res.code == proxy.$passCode) { | ||
| 158 | page.value.curr = 1; | ||
| 159 | getTableData(); | ||
| 160 | proxy.$ElMessage.success('编辑数据保存成功'); | ||
| 161 | } else { | ||
| 162 | proxy.$ElMessage.error(res.msg); | ||
| 163 | } | ||
| 164 | }); | ||
| 165 | } else { | ||
| 166 | addDataPromise.value = saveDemand(params).then((res: any) => { | ||
| 167 | addDataPromise.value = null; | ||
| 168 | if (res.code == proxy.$passCode) { | ||
| 169 | page.value.curr = 1; | ||
| 170 | getTableData(); | ||
| 171 | proxy.$ElMessage.success('新增数据保存成功'); | ||
| 172 | } else { | ||
| 173 | proxy.$ElMessage.error(res.msg); | ||
| 174 | } | ||
| 175 | }); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | }); | ||
| 179 | btns.push({ | ||
| 180 | value: 'del', label: '删除', click: (scope) => { | ||
| 181 | proxy.$openMessageBox('确定要删除该条数据吗?', () => { | ||
| 182 | tableData.value.splice(0, 1); | ||
| 183 | proxy.$ElMessage.success("删除成功"); | ||
| 184 | }, () => { | ||
| 185 | proxy.$ElMessage.info("已取消删除"); | ||
| 186 | }) | ||
| 187 | } | ||
| 188 | }); | ||
| 189 | return btns; | ||
| 190 | } | ||
| 191 | btns.push({ value: 'edit', label: '编辑' }); | ||
| 192 | btns.push({ value: 'del', label: '删除' }); | ||
| 193 | return btns; | ||
| 194 | } | ||
| 195 | } | ||
| 196 | }); | ||
| 197 | |||
| 198 | /** ---- 新增修改标签对话框配置------------- */ | ||
| 199 | const formItems: any = ref([ | ||
| 200 | { | ||
| 201 | label: '需求表名称', | ||
| 202 | type: 'input', | ||
| 203 | placeholder: '请输入', | ||
| 204 | field: 'menuName', | ||
| 205 | default: '', | ||
| 206 | maxlength: 20, | ||
| 207 | clearable: true, | ||
| 208 | required: true, | ||
| 209 | }, | ||
| 210 | { | ||
| 211 | label: '是否为目录', | ||
| 212 | type: 'select', | ||
| 213 | field: 'isCatalog', | ||
| 214 | default: 'N', | ||
| 215 | options: [ | ||
| 216 | { label: '是', value: 'Y' }, | ||
| 217 | { label: '否', value: 'N' } | ||
| 218 | ], | ||
| 219 | required: true, | ||
| 220 | }, | ||
| 221 | { | ||
| 222 | label: '所属上级', | ||
| 223 | type: 'cascader', | ||
| 224 | placeholder: '请选择', | ||
| 225 | field: "parentGuid", | ||
| 226 | default: [], | ||
| 227 | options: [], | ||
| 228 | showAllLevels: false, | ||
| 229 | props: { | ||
| 230 | checkStrictly: true, | ||
| 231 | label: "menuName", | ||
| 232 | value: "guid", | ||
| 233 | children: 'childList', | ||
| 234 | emitPath: false | ||
| 235 | }, | ||
| 236 | clearable: true, | ||
| 237 | filterable: true, | ||
| 238 | block: true | ||
| 239 | }, | ||
| 240 | { | ||
| 241 | label: '排序', | ||
| 242 | type: 'input', | ||
| 243 | placeholder: '请输入', | ||
| 244 | field: 'orderNum', | ||
| 245 | default: '', | ||
| 246 | inputType: 'integerNumber', | ||
| 247 | maxlength: 6, | ||
| 248 | clearable: true, | ||
| 249 | }, | ||
| 250 | ]) | ||
| 251 | |||
| 252 | const formRules = ref({ | ||
| 253 | menuName: [ | ||
| 254 | { required: true, message: '请填写需求表名称', trigger: 'blur' } | ||
| 255 | ], | ||
| 256 | isCatalog: [ | ||
| 257 | { required: true, message: '请选择是否为目录', trigger: 'change' } | ||
| 258 | ] | ||
| 259 | }); | ||
| 260 | |||
| 261 | /** 新建api标签对话框 */ | ||
| 262 | const demScheduleLabelDialogInfo = ref({ | ||
| 263 | visible: false, | ||
| 264 | size: 480, | ||
| 265 | direction: "column", | ||
| 266 | header: { | ||
| 267 | title: "", | ||
| 268 | }, | ||
| 269 | type: '', | ||
| 270 | contents: [ | ||
| 271 | { | ||
| 272 | type: 'form', | ||
| 273 | title: '', | ||
| 274 | formInfo: { | ||
| 275 | id: 'add-staff-form', | ||
| 276 | items: formItems.value, | ||
| 277 | rules: formRules.value | ||
| 278 | } | ||
| 279 | } | ||
| 280 | ], | ||
| 281 | footer: { | ||
| 282 | btns: [ | ||
| 283 | { type: "default", label: "取消", value: "cancel" }, | ||
| 284 | { type: "primary", label: "确定", value: "submit" }, | ||
| 285 | ], | ||
| 286 | }, | ||
| 287 | }); | ||
| 288 | |||
| 289 | // 获取需求表树形数据 | ||
| 290 | const getTreeData = () => { | ||
| 291 | getDemandAll({ isCatalog: '' }).then((res: any) => { | ||
| 292 | if (res.code == proxy.$passCode) { | ||
| 293 | const data = res.data || []; | ||
| 294 | treeData.value = JSON.parse(JSON.stringify(data)); | ||
| 295 | treeInfo.value.data = JSON.parse(JSON.stringify(data)); | ||
| 296 | treeInfo.value.currentNodeKey = data[0]?.guid || ""; | ||
| 297 | lastClickNode.value = data[0] || {}; | ||
| 298 | nextTick(() => { | ||
| 299 | treeInfoRef.value?.setCurrentKey(treeInfo.value.currentNodeKey); | ||
| 300 | if (lastClickNode.value.isCatalog != 'Y') { | ||
| 301 | showTable.value = true; | ||
| 302 | page.value.curr = 1; | ||
| 303 | getTableData(); | ||
| 304 | } else { | ||
| 305 | showTable.value = false; | ||
| 306 | } | ||
| 307 | }) | ||
| 308 | } else { | ||
| 309 | proxy.$ElMessage.error(res.msg); | ||
| 310 | } | ||
| 311 | }) | ||
| 312 | getCatalog(); | ||
| 313 | } | ||
| 314 | |||
| 315 | const getCatalog = () => { | ||
| 316 | getDemandAll({ isCatalog: 'Y' }).then((res: any) => { | ||
| 317 | if (res.code == proxy.$passCode) { | ||
| 318 | const data = res.data || []; | ||
| 319 | catalogData.value = JSON.parse(JSON.stringify(data)); | ||
| 320 | } | ||
| 321 | }) | ||
| 322 | } | ||
| 323 | |||
| 324 | /** 点击左侧节点 */ | ||
| 325 | const nodeClick = (data) => { | ||
| 326 | lastClickNode.value = data || {}; | ||
| 327 | if (data.isCatalog != 'Y') { | ||
| 328 | showTable.value = true; | ||
| 329 | page.value.curr = 1; | ||
| 330 | getTableData(); | ||
| 331 | } else { | ||
| 332 | showTable.value = false; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | const setRowData = (info: any = null) => { | ||
| 337 | const rowData: any = { | ||
| 338 | STATUS: 'edit', | ||
| 339 | STATE: "Running", | ||
| 340 | ROWID: '1', | ||
| 341 | dateType: 'datetime', | ||
| 342 | fieldType: 'int', | ||
| 343 | fieldName: info?.fieldName || '', | ||
| 344 | isRequired: info?.isRequired || 'N', | ||
| 345 | bizState: info?.bizState || 'Y', | ||
| 346 | createTime: info?.createTime || getCurrentTime(), | ||
| 347 | orderNum: info?.orderNum !== undefined ? info?.orderNum : tableData.value.length + 1 | ||
| 348 | } | ||
| 349 | info && (rowData.guid = info.guid || ''); | ||
| 350 | return rowData; | ||
| 351 | } | ||
| 352 | |||
| 353 | // 新增字段 | ||
| 354 | const addField = () => { | ||
| 355 | if (tableData.value[0]?.STATUS == 'edit') { | ||
| 356 | proxy.$ElMessage.warning('请先保存正在编辑的行数据'); | ||
| 357 | return; | ||
| 358 | } | ||
| 359 | // 支持新增数据,直接添加一行进行编辑。 | ||
| 360 | const rowData = setRowData(); | ||
| 361 | tableData.value.unshift(rowData); | ||
| 362 | nextTick(() => { | ||
| 363 | tableRef?.value?.tableRef?.setScrollTop(0); | ||
| 364 | }) | ||
| 365 | } | ||
| 366 | |||
| 367 | // 批量删除 | ||
| 368 | const batching = (type) => { | ||
| 369 | if (type == 'delete') { | ||
| 370 | if (selectRowData.value.length == 0) { | ||
| 371 | ElMessage({ | ||
| 372 | type: 'error', | ||
| 373 | message: '请选择需要删除的数据', | ||
| 374 | }) | ||
| 375 | return | ||
| 376 | } | ||
| 377 | open("此操作将永久删除, 是否继续?", "warning", true); | ||
| 378 | } else if (type == 'import') { | ||
| 379 | const info = { | ||
| 380 | dictionaryGuid: '' | ||
| 381 | } | ||
| 382 | cacheStore.setCatch('uploadSetting', info) | ||
| 383 | router.push( | ||
| 384 | { | ||
| 385 | name: 'importFileDemandManage', | ||
| 386 | query: { | ||
| 387 | isfileImport: '7' | ||
| 388 | } | ||
| 389 | } | ||
| 390 | ); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | const setFormItems = (info = null, type = '') => { | ||
| 395 | const datas: any = info || {}; | ||
| 396 | formItems.value.map(item => { | ||
| 397 | if (item.field == 'isCatalog') { | ||
| 398 | item.default = datas[item.field] || 'N'; | ||
| 399 | } else { | ||
| 400 | item.default = datas[item.field] || ''; | ||
| 401 | } | ||
| 402 | }) | ||
| 403 | } | ||
| 404 | |||
| 405 | const setCataLog = (dataArr, id, parentDisabled = false) => { | ||
| 406 | return dataArr.map(item => { | ||
| 407 | // 当前节点是否被禁选(自身匹配或父节点已禁选) | ||
| 408 | const isDisabled = parentDisabled || item.guid === id; | ||
| 409 | // 新节点基础属性 | ||
| 410 | const newItem = { | ||
| 411 | ...item, | ||
| 412 | disabled: isDisabled | ||
| 413 | }; | ||
| 414 | |||
| 415 | // 递归处理子节点,并传递当前节点的禁选状态 | ||
| 416 | if (item.childList && item.childList.length > 0) { | ||
| 417 | newItem.childList = setCataLog(item.childList, id, isDisabled); | ||
| 418 | } | ||
| 419 | return newItem; | ||
| 420 | }) | ||
| 421 | } | ||
| 422 | |||
| 423 | /** 处理标签的操作按钮,编辑,删除 */ | ||
| 424 | const handleTreeItemMenuClick = async (node, type) => { | ||
| 425 | let data = node.data; | ||
| 426 | lastClickNode.value = data; | ||
| 427 | if (type == "edit") { | ||
| 428 | await setFormItems(data); | ||
| 429 | if (data.isCatalog == 'Y') { | ||
| 430 | formItems.value[1].disabled = data.childList && data.childList.length > 0; | ||
| 431 | } else { | ||
| 432 | formItems.value[1].disabled = tableData.value && tableData.value.length > 0; | ||
| 433 | } | ||
| 434 | let cata = setCataLog(catalogData.value, data.guid); | ||
| 435 | formItems.value.at(-2).options = cata; | ||
| 436 | demScheduleLabelDialogInfo.value.contents[0].formInfo.items = formItems.value; | ||
| 437 | demScheduleLabelDialogInfo.value.header.title = "编辑需求表"; | ||
| 438 | demScheduleLabelDialogInfo.value.type = 'edit'; | ||
| 439 | demScheduleLabelDialogInfo.value.visible = true; | ||
| 440 | } else if (type == "delete") { | ||
| 441 | proxy.$openMessageBox('确定要删除该需求表吗?', () => { | ||
| 442 | deleteDemandTree([lastClickNode.value.guid]).then((res: any) => { | ||
| 443 | if (res.code == proxy.$passCode) { | ||
| 444 | getTreeData(); | ||
| 445 | proxy.$ElMessage.success("删除该需求表成功"); | ||
| 446 | } else { | ||
| 447 | proxy.$ElMessage.error(res.msg); | ||
| 448 | } | ||
| 449 | }); | ||
| 450 | }, () => { | ||
| 451 | proxy.$ElMessage.info("已取消"); | ||
| 452 | }) | ||
| 453 | } | ||
| 454 | } | ||
| 455 | /** 新建分组对话框确定。 */ | ||
| 456 | const demScheduleLabelDialogBtnClick = (btn, info) => { | ||
| 457 | if (btn.value == 'submit') { | ||
| 458 | let params = { ...info, parentGuid: info.parentGuid || '', tenantGuid: userData.tenantGuid }; | ||
| 459 | if (demScheduleLabelDialogInfo.value.type == 'add') { | ||
| 460 | saveDemandTree(params).then((res: any) => { | ||
| 461 | if (res.code == proxy.$passCode) { | ||
| 462 | getTreeData(); | ||
| 463 | proxy.$ElMessage({ | ||
| 464 | type: 'success', | ||
| 465 | message: '新增需求表成功' | ||
| 466 | }) | ||
| 467 | demScheduleLabelDialogInfo.value.visible = false; | ||
| 468 | } else { | ||
| 469 | proxy.$ElMessage({ | ||
| 470 | type: 'error', | ||
| 471 | message: res.msg, | ||
| 472 | }) | ||
| 473 | } | ||
| 474 | }) | ||
| 475 | } else { | ||
| 476 | params.guid = lastClickNode.value.guid; | ||
| 477 | updateDemandTree(params).then((res: any) => { | ||
| 478 | if (res.code == proxy.$passCode) { | ||
| 479 | getTreeData(); | ||
| 480 | proxy.$ElMessage({ | ||
| 481 | type: 'success', | ||
| 482 | message: '编辑需求表成功' | ||
| 483 | }) | ||
| 484 | demScheduleLabelDialogInfo.value.visible = false; | ||
| 485 | } else { | ||
| 486 | proxy.$ElMessage({ | ||
| 487 | type: 'error', | ||
| 488 | message: res.msg, | ||
| 489 | }) | ||
| 490 | } | ||
| 491 | }) | ||
| 492 | } | ||
| 493 | } else if (btn.value == 'cancel') { | ||
| 494 | demScheduleLabelDialogInfo.value.visible = false; | ||
| 495 | } | ||
| 496 | }; | ||
| 497 | |||
| 498 | const addTreeNode = async () => { | ||
| 499 | await setFormItems(); | ||
| 500 | demScheduleLabelDialogInfo.value.header.title = '新建需求表'; | ||
| 501 | formItems.value[1].disabled = false; | ||
| 502 | formItems.value.at(-2).options = catalogData.value; | ||
| 503 | demScheduleLabelDialogInfo.value.contents[0].formInfo.items = formItems.value; | ||
| 504 | demScheduleLabelDialogInfo.value.type = 'add'; | ||
| 505 | demScheduleLabelDialogInfo.value.visible = true; | ||
| 506 | } | ||
| 507 | |||
| 508 | // 设置需求表表头 | ||
| 509 | const setTableField = () => { | ||
| 510 | const editInfo = {}; | ||
| 511 | tableFields.forEach(f => { | ||
| 512 | if (f.type == 'switch') { | ||
| 513 | editInfo[f.field] = { | ||
| 514 | label: f.label, | ||
| 515 | type: f.type, | ||
| 516 | field: f.field, | ||
| 517 | default: false, | ||
| 518 | activeText: '启用', | ||
| 519 | inactiveText: '停用', | ||
| 520 | activeValue: 'Y', | ||
| 521 | inactiveValue: 'N', | ||
| 522 | }; | ||
| 523 | } else if (f.type == 'select') { | ||
| 524 | editInfo[f.field] = { | ||
| 525 | label: f.label, | ||
| 526 | type: f.type, | ||
| 527 | field: f.field, | ||
| 528 | default: '', | ||
| 529 | options: [ | ||
| 530 | { label: '是', value: 'Y' }, | ||
| 531 | { label: '否', value: 'N' } | ||
| 532 | ], | ||
| 533 | clearable: true | ||
| 534 | } | ||
| 535 | } else if (f.type == 'defaultValue') { | ||
| 536 | editInfo[f.field] = { | ||
| 537 | label: f.label, | ||
| 538 | type: f.type, | ||
| 539 | field: f.field, | ||
| 540 | default: '', | ||
| 541 | clearable: true, | ||
| 542 | disabled: true, | ||
| 543 | } | ||
| 544 | } else { | ||
| 545 | editInfo[f.field] = { | ||
| 546 | label: f.label, | ||
| 547 | type: 'input', | ||
| 548 | field: f.field, | ||
| 549 | placeholder: f.isPrimary == 'Y' ? '主键自动生成' : '请输入', | ||
| 550 | default: '', | ||
| 551 | clearable: true | ||
| 552 | } | ||
| 553 | } | ||
| 554 | }) | ||
| 555 | tableInfo.value.editInfo = editInfo; | ||
| 556 | } | ||
| 557 | |||
| 558 | const toSearch = (val: any = null, clear: boolean = false) => { | ||
| 559 | page.value.curr = 1; | ||
| 560 | if (clear) { | ||
| 561 | searchItemList.value.map((item) => (item.default = "")); | ||
| 562 | page.value.fieldName = ''; | ||
| 563 | page.value.isRequired = ''; | ||
| 564 | } else { | ||
| 565 | let info = val ? { ...val } : {}; | ||
| 566 | searchItemList.value.map(item => { | ||
| 567 | info[item.field] = item.default; | ||
| 568 | }) | ||
| 569 | page.value.fieldName = info.fieldName || ''; | ||
| 570 | page.value.isRequired = info.isRequired || ''; | ||
| 571 | } | ||
| 572 | getTableData(); | ||
| 573 | }; | ||
| 574 | |||
| 575 | // 获取表格数据 | ||
| 576 | const getTableData = () => { | ||
| 577 | if (!lastClickNode.value?.guid) { | ||
| 578 | return; | ||
| 579 | } | ||
| 580 | tableInfo.value.loading = true; | ||
| 581 | getDemandList({ | ||
| 582 | pageSize: page.value.limit, | ||
| 583 | pageIndex: page.value.curr, | ||
| 584 | relationMenuGuid: lastClickNode.value.guid, | ||
| 585 | fieldName: page.value.fieldName, | ||
| 586 | isRequired: page.value.isRequired, | ||
| 587 | }).then((res: any) => { | ||
| 588 | tableInfo.value.loading = false; | ||
| 589 | if (res.code == proxy.$passCode) { | ||
| 590 | const data = res.data || {}; | ||
| 591 | tableData.value = data.records || []; | ||
| 592 | tableInfo.value.data = tableData.value; | ||
| 593 | tableInfo.value.page.limit = data.pageSize | ||
| 594 | tableInfo.value.page.curr = data.pageIndex | ||
| 595 | tableInfo.value.page.rows = data.totalRows | ||
| 596 | } else { | ||
| 597 | proxy.$ElMessage.error(res.msg); | ||
| 598 | } | ||
| 599 | }) | ||
| 600 | } | ||
| 601 | |||
| 602 | const tablePageChange = (info) => { | ||
| 603 | page.value.curr = Number(info.curr); | ||
| 604 | page.value.limit = Number(info.limit); | ||
| 605 | getTableData(); | ||
| 606 | }; | ||
| 607 | |||
| 608 | const tableSelectionChange = (val) => { | ||
| 609 | selectRowData.value = val; | ||
| 610 | }; | ||
| 611 | |||
| 612 | const tableSwitchBeforeChange = (scope, field, callBack) => { | ||
| 613 | if (scope.row.STATUS == 'edit') { | ||
| 614 | callBack(true); | ||
| 615 | } else { | ||
| 616 | // proxy.$openMessageBox(`确定要更新该字段值吗?`, () => { | ||
| 617 | // const state = scope.row[field] == 'Y' ? 'N' : 'Y'; | ||
| 618 | // let mdmModelData: any = {}; | ||
| 619 | // mdmModelData[field] = state; | ||
| 620 | // let pkValue = scope.row[mergeFormItems.value[0].field]; | ||
| 621 | // mdmModelData[mergeFormItems.value[0].field] = pkValue; | ||
| 622 | // updateMdmModelData({ | ||
| 623 | // mdmModelTableGuid: props.modelConfigInfo.guid, | ||
| 624 | // mdmModelData: mdmModelData, | ||
| 625 | // pkValues: [pkValue] | ||
| 626 | // }).then((res: any) => { | ||
| 627 | // if (res.code == proxy.$passCode) { | ||
| 628 | // proxy.$ElMessage.success('该字段值更新成功'); | ||
| 629 | // let firstData = tableData.value[0]; | ||
| 630 | // getMainModelData().then((res: any) => { | ||
| 631 | // if (firstData && firstData.STATUS == 'edit') { | ||
| 632 | // tableData.value.unshift(firstData); | ||
| 633 | // } | ||
| 634 | // }); | ||
| 635 | // callBack(true) | ||
| 636 | // } else { | ||
| 637 | // proxy.$ElMessage.error(res.msg); | ||
| 638 | // callBack(false) | ||
| 639 | // } | ||
| 640 | // }); | ||
| 641 | // }, () => { | ||
| 642 | // callBack(false); | ||
| 643 | // }) | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | const tableSwitchChange = (val, scope, field) => { | ||
| 648 | if (scope.row.STATUS == 'edit') { | ||
| 649 | tableData.value[scope.$index][field] = val; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | const tableBtnClick = (scope, btn) => { | ||
| 654 | const type = btn.value; | ||
| 655 | const row = scope.row; | ||
| 656 | currTableData.value = row; | ||
| 657 | if (type === 'edit') { // 编辑 | ||
| 658 | if (tableData.value.find(t => t.STATUS == 'edit')) { | ||
| 659 | proxy.$ElMessage.warning('请先保存正在编辑的行数据'); | ||
| 660 | return; | ||
| 661 | } | ||
| 662 | const rowData = setRowData(row); | ||
| 663 | tableData.value[scope.$index] = rowData; | ||
| 664 | } else if (type === 'del') { // 删除 | ||
| 665 | open('确定要删除该条数据吗?', 'warning'); | ||
| 666 | } | ||
| 667 | }; | ||
| 668 | |||
| 669 | const open = (msg, type, isBatch = false) => { | ||
| 670 | ElMessageBox.confirm(msg, "提示", { | ||
| 671 | confirmButtonText: "确定", | ||
| 672 | cancelButtonText: "取消", | ||
| 673 | type: type, | ||
| 674 | }).then(() => { | ||
| 675 | let guids = [currTableData.value.guid] | ||
| 676 | if (isBatch) { | ||
| 677 | guids = selectRowData.value.map(item => item.guid); | ||
| 678 | } | ||
| 679 | deleteDemand(guids).then((res: any) => { | ||
| 680 | if (res.code == proxy.$passCode) { | ||
| 681 | getTableData(); | ||
| 682 | ElMessage({ | ||
| 683 | type: "success", | ||
| 684 | message: "删除成功", | ||
| 685 | }); | ||
| 686 | } else { | ||
| 687 | ElMessage({ | ||
| 688 | type: "error", | ||
| 689 | message: res.msg, | ||
| 690 | }); | ||
| 691 | } | ||
| 692 | }); | ||
| 693 | }); | ||
| 694 | }; | ||
| 695 | |||
| 696 | onBeforeMount(() => { | ||
| 697 | getTreeData(); | ||
| 698 | setTableField(); | ||
| 699 | }); | ||
| 700 | |||
| 701 | onActivated(() => { | ||
| 702 | |||
| 703 | }) | ||
| 704 | |||
| 705 | </script> | ||
| 706 | |||
| 707 | <template> | ||
| 708 | <div class="container_wrap full flex"> | ||
| 709 | <div class="aside_wrap"> | ||
| 710 | <div class="aside_title">需求表列表</div> | ||
| 711 | <el-icon class="icon-add" color="#4fa1a4" @click="addTreeNode()"> | ||
| 712 | <CirclePlus /> | ||
| 713 | </el-icon> | ||
| 714 | <Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="handleTreeItemMenuClick" /> | ||
| 715 | </div> | ||
| 716 | <div class="main_wrap"> | ||
| 717 | <template v-if="showTable"> | ||
| 718 | <div class="table_tool_wrap"> | ||
| 719 | <div class="tools_btns"> | ||
| 720 | <el-button type="primary" @click="addField" v-preReClick>添加</el-button> | ||
| 721 | <el-button @click="batching('import')" v-preReClick>批量导入</el-button> | ||
| 722 | <el-button @click="batching('delete')" v-preReClick>批量删除</el-button> | ||
| 723 | </div> | ||
| 724 | <div class="tools_serach"> | ||
| 725 | <template v-for="(item, i) in searchItemList" :key="'s_' + i"> | ||
| 726 | <el-select v-if="item.type == 'select'" v-model="item.default" :placeholder="item.placeholder" | ||
| 727 | :clearable="item.clearable" :style="item.style" @change="val => toSearch()"> | ||
| 728 | <el-option v-for="(opt, o) in item.options" :label="opt.label" :value="opt.value" :key="o" /> | ||
| 729 | </el-select> | ||
| 730 | <el-input v-else v-model.trim="item.default" :placeholder="item.placeholder" :suffix-icon="Search" | ||
| 731 | :clearable="item.clearable" :style="item.style" @change="val => toSearch()" /> | ||
| 732 | </template> | ||
| 733 | </div> | ||
| 734 | </div> | ||
| 735 | <div class="table_panel_wrap"> | ||
| 736 | <Table ref="tableRef" :tableInfo="tableInfo" @tableSelectionChange="tableSelectionChange" | ||
| 737 | @tablePageChange="tablePageChange" @tableBtnClick="tableBtnClick" /> | ||
| 738 | </div> | ||
| 739 | </template> | ||
| 740 | <div class="card-noData" v-else> | ||
| 741 | <img src="@/assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" /> | ||
| 742 | <p>请选择需求表</p> | ||
| 743 | </div> | ||
| 744 | </div> | ||
| 745 | <!-- 添加编辑需求表的对话框 --> | ||
| 746 | <Dialog :dialogInfo="demScheduleLabelDialogInfo" @btnClick="demScheduleLabelDialogBtnClick" /> | ||
| 747 | </div> | ||
| 748 | </template> | ||
| 749 | |||
| 750 | <style lang="scss" scoped> | ||
| 751 | .container_wrap { | ||
| 752 | padding: 0; | ||
| 753 | display: flex; | ||
| 754 | justify-content: space-between; | ||
| 755 | |||
| 756 | .aside_wrap { | ||
| 757 | width: 199px; | ||
| 758 | border-right: 1px solid #d9d9d9; | ||
| 759 | box-shadow: none; | ||
| 760 | |||
| 761 | .aside_title { | ||
| 762 | width: calc(100% - 32px); | ||
| 763 | display: inline-block; | ||
| 764 | } | ||
| 765 | |||
| 766 | .icon-add.el-icon { | ||
| 767 | width: 24px; | ||
| 768 | height: 24px; | ||
| 769 | vertical-align: middle; | ||
| 770 | cursor: pointer; | ||
| 771 | |||
| 772 | svg { | ||
| 773 | width: 24px; | ||
| 774 | height: 24px; | ||
| 775 | } | ||
| 776 | } | ||
| 777 | |||
| 778 | :deep(.tree_panel) { | ||
| 779 | height: 100%; | ||
| 780 | padding-top: 0; | ||
| 781 | |||
| 782 | .el-tree { | ||
| 783 | margin: 0; | ||
| 784 | height: calc(100% - 68px); | ||
| 785 | overflow: hidden auto; | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | } | ||
| 790 | |||
| 791 | .main_wrap { | ||
| 792 | padding: 0 8px; | ||
| 793 | height: auto; | ||
| 794 | flex: 1; | ||
| 795 | |||
| 796 | .table_tool_wrap { | ||
| 797 | width: 100%; | ||
| 798 | padding: 0 8px; | ||
| 799 | display: flex; | ||
| 800 | justify-content: space-between; | ||
| 801 | align-items: center; | ||
| 802 | |||
| 803 | .tools_btns { | ||
| 804 | padding: 0px 0 0; | ||
| 805 | } | ||
| 806 | |||
| 807 | .tools_serach { | ||
| 808 | width: 378px; | ||
| 809 | display: flex; | ||
| 810 | justify-content: space-between; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | |||
| 814 | .table_panel_wrap { | ||
| 815 | width: 100%; | ||
| 816 | height: calc(100% - 44px); | ||
| 817 | padding: 0px 8px 0; | ||
| 818 | } | ||
| 819 | |||
| 820 | .card-noData { | ||
| 821 | position: absolute; | ||
| 822 | top: 50%; | ||
| 823 | left: 50%; | ||
| 824 | transform: translate(-50%, -50%); | ||
| 825 | display: flex; | ||
| 826 | flex-direction: column; | ||
| 827 | align-items: center; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | } | ||
| 831 | |||
| 832 | .row-dialog-content { | ||
| 833 | height: 300px; | ||
| 834 | |||
| 835 | .tools_btns { | ||
| 836 | margin-bottom: 8px; | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 840 | :deep(.el-form) { | ||
| 841 | .select-input-long { | ||
| 842 | .el-form-item:first-child { | ||
| 843 | width: 67%; | ||
| 844 | margin-right: 0px; | ||
| 845 | } | ||
| 846 | |||
| 847 | .el-form-item:last-child { | ||
| 848 | width: 33%; | ||
| 849 | margin-right: 0px; | ||
| 850 | |||
| 851 | .item-label { | ||
| 852 | white-space: pre; | ||
| 853 | |||
| 854 | .required_mark::after { | ||
| 855 | content: ''; | ||
| 856 | } | ||
| 857 | } | ||
| 858 | } | ||
| 859 | } | ||
| 860 | |||
| 861 | .select-input-long-reverse { | ||
| 862 | .el-form-item:first-child { | ||
| 863 | width: 100px; | ||
| 864 | margin-right: 0px; | ||
| 865 | } | ||
| 866 | |||
| 867 | .el-form-item:last-child { | ||
| 868 | width: calc(100% - 100px); | ||
| 869 | margin-right: 0px; | ||
| 870 | |||
| 871 | .item-label { | ||
| 872 | white-space: pre; | ||
| 873 | |||
| 874 | .required_mark::after { | ||
| 875 | content: ''; | ||
| 876 | } | ||
| 877 | } | ||
| 878 | } | ||
| 879 | } | ||
| 880 | } | ||
| 881 | </style> |
src/views/data_pricing/diseaseManage.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: diseaseManage | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="diseaseManage"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import TableTools from '@/components/Tools/table_tools.vue'; | ||
| 8 | import { TableColumnWidth, commonPageConfig } from '@/utils/enum'; | ||
| 9 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 10 | import { CirclePlus } from "@element-plus/icons-vue"; | ||
| 11 | import { useRouter, useRoute } from "vue-router"; | ||
| 12 | import useUserStore from "@/store/modules/user"; | ||
| 13 | import useCatchStore from "@/store/modules/catch"; | ||
| 14 | import { | ||
| 15 | getDiseaseAll, | ||
| 16 | getDiseaseList, | ||
| 17 | saveDisease, | ||
| 18 | updateDisease, | ||
| 19 | deleteDisease, | ||
| 20 | } from '@/api/modules/dataPricing'; | ||
| 21 | import { changeNum } from '@/utils/common'; | ||
| 22 | |||
| 23 | const router = useRouter(); | ||
| 24 | const userStore = useUserStore() | ||
| 25 | const userData = JSON.parse(userStore.userData) | ||
| 26 | const { proxy } = getCurrentInstance() as any; | ||
| 27 | const cacheStore = useCatchStore() | ||
| 28 | |||
| 29 | const searchItemList = ref([ | ||
| 30 | { | ||
| 31 | type: "input", | ||
| 32 | label: "", | ||
| 33 | field: "diseaseName", | ||
| 34 | default: "", | ||
| 35 | placeholder: "疾病名称", | ||
| 36 | clearable: true, | ||
| 37 | }, | ||
| 38 | { | ||
| 39 | type: "select", | ||
| 40 | label: "", | ||
| 41 | field: "isChildrenDisease", | ||
| 42 | placeholder: "是否儿童", | ||
| 43 | default: "", | ||
| 44 | options: [ | ||
| 45 | { label: '是', value: 'Y' }, | ||
| 46 | { label: '否', value: 'N' } | ||
| 47 | ], | ||
| 48 | clearable: true, | ||
| 49 | } | ||
| 50 | ]); | ||
| 51 | |||
| 52 | const tableData: any = ref([]); | ||
| 53 | const selectRowData: any = ref([]) | ||
| 54 | const currTableData: any = ref({}); | ||
| 55 | const selectionTreeTableRef = ref(); | ||
| 56 | const page: any = ref({ | ||
| 57 | ...commonPageConfig, | ||
| 58 | diseaseName: '', | ||
| 59 | isChildrenDisease: '' | ||
| 60 | }); | ||
| 61 | const tableInfo = ref({ | ||
| 62 | id: 'api-data-table', | ||
| 63 | rowKey: 'guid', | ||
| 64 | loading: false, | ||
| 65 | multiple: true, | ||
| 66 | fields: [ | ||
| 67 | { label: "疾病名称", field: "diseaseName", width: 200 }, | ||
| 68 | { | ||
| 69 | label: "是否儿童疾病", field: "isChildrenDisease", width: 120, getName: (scope) => { | ||
| 70 | return scope.row.isChildrenDisease == 'Y' ? '是' : '否'; | ||
| 71 | } | ||
| 72 | }, | ||
| 73 | { label: "发病率/患病率", field: "incidenceRate", width: 120 }, | ||
| 74 | { | ||
| 75 | label: "因子", field: "factor", width: 100, align: 'right', getName: (scope) => { | ||
| 76 | return (scope.row.factor !== '' && scope.row.factor !== null) ? changeNum(scope.row.factor, 2) : '-'; | ||
| 77 | } | ||
| 78 | }, | ||
| 79 | { | ||
| 80 | label: "启用状态", field: "bizState", type: 'tag', width: 120, align: 'center', getName: (scope) => { | ||
| 81 | return scope.row.bizState == 'Y' ? '启用' : '停用'; | ||
| 82 | }, tagType: (scope) => { | ||
| 83 | return scope.row.bizState == 'Y' ? 'success' : 'info'; | ||
| 84 | } | ||
| 85 | }, | ||
| 86 | { label: "排序", field: "orderNum", width: 100, align: 'right', type: 'chnum' }, | ||
| 87 | { label: "创建时间", field: "createTime", width: TableColumnWidth.DATETIME }, | ||
| 88 | ], | ||
| 89 | data: tableData.value, | ||
| 90 | treeProps: { | ||
| 91 | children: 'childList', | ||
| 92 | hasChildren: 'hasChildren', | ||
| 93 | checkStrictly: false, | ||
| 94 | }, | ||
| 95 | page: { | ||
| 96 | type: "normal", | ||
| 97 | rows: 0, | ||
| 98 | ...page.value, | ||
| 99 | }, | ||
| 100 | actionInfo: { | ||
| 101 | label: "操作", | ||
| 102 | type: "btn", | ||
| 103 | isMore: false, | ||
| 104 | width: 120, | ||
| 105 | btns: [ | ||
| 106 | { label: "编辑", value: "edit" }, | ||
| 107 | { label: "删除", value: "del" } | ||
| 108 | ] | ||
| 109 | } | ||
| 110 | }); | ||
| 111 | |||
| 112 | /** ---- 新增修改标签对话框配置------------- */ | ||
| 113 | const catalogData = ref([]); | ||
| 114 | const formItems: any = ref([ | ||
| 115 | { | ||
| 116 | label: '疾病名称', | ||
| 117 | type: 'input', | ||
| 118 | placeholder: '请输入', | ||
| 119 | field: 'diseaseName', | ||
| 120 | default: '', | ||
| 121 | maxlength: 50, | ||
| 122 | required: true, | ||
| 123 | clearable: true, | ||
| 124 | }, | ||
| 125 | { | ||
| 126 | label: '所属上级', | ||
| 127 | type: 'cascader', | ||
| 128 | placeholder: '请选择', | ||
| 129 | field: "parentGuid", | ||
| 130 | default: [], | ||
| 131 | options: [], | ||
| 132 | showAllLevels: false, | ||
| 133 | props: { | ||
| 134 | checkStrictly: true, | ||
| 135 | label: "diseaseName", | ||
| 136 | children: 'childList', | ||
| 137 | value: "guid", | ||
| 138 | emitPath: false | ||
| 139 | }, | ||
| 140 | clearable: true, | ||
| 141 | filterable: true, | ||
| 142 | }, | ||
| 143 | { | ||
| 144 | label: '是否儿童疾病', | ||
| 145 | type: 'select', | ||
| 146 | placeholder: '请选择', | ||
| 147 | field: 'isChildrenDisease', | ||
| 148 | default: '', | ||
| 149 | options: [ | ||
| 150 | { label: '是', value: 'Y' }, | ||
| 151 | { label: '否', value: 'N' } | ||
| 152 | ], | ||
| 153 | required: true, | ||
| 154 | clearable: true, | ||
| 155 | }, | ||
| 156 | { | ||
| 157 | label: '启用状态', | ||
| 158 | type: 'switch', | ||
| 159 | field: 'bizState', | ||
| 160 | default: 'Y', | ||
| 161 | placeholder: '请选择', | ||
| 162 | activeValue: 'Y', | ||
| 163 | inactiveValue: 'N', | ||
| 164 | switchWidth: 32, | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | label: '发病率/患病率', | ||
| 168 | type: 'input', | ||
| 169 | placeholder: '请输入', | ||
| 170 | field: 'incidenceRate', | ||
| 171 | default: '', | ||
| 172 | maxlength: 20, | ||
| 173 | clearable: true, | ||
| 174 | required: true, | ||
| 175 | }, | ||
| 176 | { | ||
| 177 | label: '因子', | ||
| 178 | type: 'input-group', | ||
| 179 | placeholder: '请输入', | ||
| 180 | field: 'in', | ||
| 181 | default: '', | ||
| 182 | children: [ | ||
| 183 | { | ||
| 184 | label: '', | ||
| 185 | type: 'input', | ||
| 186 | placeholder: '请输入', | ||
| 187 | field: 'factor', | ||
| 188 | default: '', | ||
| 189 | inputType: 'factorNumber', | ||
| 190 | maxlength: 10, | ||
| 191 | clearable: true, | ||
| 192 | }, | ||
| 193 | { | ||
| 194 | label: '', | ||
| 195 | type: 'checkbox', | ||
| 196 | placeholder: '下级同时修改', | ||
| 197 | desc: '', | ||
| 198 | field: 'juniorTogetherModify', | ||
| 199 | default: "N", | ||
| 200 | trueValue: 'Y', | ||
| 201 | falseValue: 'N', | ||
| 202 | } | ||
| 203 | ], | ||
| 204 | }, | ||
| 205 | { | ||
| 206 | label: '排序', | ||
| 207 | type: 'input', | ||
| 208 | placeholder: '由数字组成', | ||
| 209 | field: 'orderNum', | ||
| 210 | inputType: 'integerNumber', | ||
| 211 | default: '', | ||
| 212 | maxlength: 6, | ||
| 213 | clearable: true, | ||
| 214 | }, | ||
| 215 | ]) | ||
| 216 | const formRules = ref({ | ||
| 217 | diseaseName: [ | ||
| 218 | { required: true, message: '请填写疾病名称', trigger: 'blur' } | ||
| 219 | ], | ||
| 220 | isChildrenDisease: [ | ||
| 221 | { required: true, message: '请选择是否儿童疾病', trigger: 'change' } | ||
| 222 | ], | ||
| 223 | bizState: [ | ||
| 224 | { required: true, message: '请选择启用状态', trigger: 'change' } | ||
| 225 | ], | ||
| 226 | incidenceRate: [ | ||
| 227 | { requires: true, message: '请填写发病率/患病率', trigger: 'blur' }, | ||
| 228 | { | ||
| 229 | validator: (rule: any, value: any, callback: any) => { | ||
| 230 | if (!value) { | ||
| 231 | callback(new Error("请填写发病率/患病率")); | ||
| 232 | } else { | ||
| 233 | if (drawerInfo.value.type.indexOf('edit') > -1 && currTableData.value.incidenceRate == value) { | ||
| 234 | callback(); | ||
| 235 | return | ||
| 236 | } | ||
| 237 | let eMsg = ''; | ||
| 238 | // 验证格式:数字、小数或分数 | ||
| 239 | if (!/^[0-9]*\.?[0-9]*(\/[0-9]+\.?[0-9]*)?$/.test(value)) { | ||
| 240 | eMsg = '请输入有效的数字、小数或分数(如0.5或1/2)'; | ||
| 241 | } | ||
| 242 | |||
| 243 | let numericValue; | ||
| 244 | |||
| 245 | // 处理分数 | ||
| 246 | if (value.includes('/')) { | ||
| 247 | const parts = value.split('/'); | ||
| 248 | if (parts.length !== 2) { | ||
| 249 | eMsg = '请输入有效的分数格式(如1/2)'; | ||
| 250 | } | ||
| 251 | |||
| 252 | const numerator = parseFloat(parts[0]); | ||
| 253 | const denominator = parseFloat(parts[1]); | ||
| 254 | |||
| 255 | if (isNaN(numerator) || isNaN(denominator)) { | ||
| 256 | eMsg = '请输入有效的分数格式(如1/2)'; | ||
| 257 | } | ||
| 258 | |||
| 259 | if (denominator === 0) { | ||
| 260 | eMsg = '请输入有效的分数格式(如1/2)'; | ||
| 261 | } | ||
| 262 | |||
| 263 | numericValue = numerator / denominator; | ||
| 264 | } else {// 处理普通数字 | ||
| 265 | numericValue = parseFloat(value); | ||
| 266 | if (isNaN(numericValue)) { | ||
| 267 | eMsg = '请输入有效的数字'; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | if (numericValue < 0) { | ||
| 272 | eMsg = '发病率必须大于等于0'; | ||
| 273 | } | ||
| 274 | |||
| 275 | if (numericValue > 1) { | ||
| 276 | eMsg = '发病率必须小于或等于1'; | ||
| 277 | } | ||
| 278 | if (eMsg) { | ||
| 279 | callback(new Error(eMsg)); | ||
| 280 | } else { | ||
| 281 | callback(); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | }, | ||
| 285 | trigger: "blur", | ||
| 286 | }, | ||
| 287 | ] | ||
| 288 | }); | ||
| 289 | const formInfo = ref({ | ||
| 290 | type: "form", | ||
| 291 | title: "", | ||
| 292 | col: "span", | ||
| 293 | formInfo: { | ||
| 294 | id: "add-disease-form", | ||
| 295 | readonly: false, | ||
| 296 | items: formItems.value, | ||
| 297 | rules: formRules.value, | ||
| 298 | }, | ||
| 299 | }); | ||
| 300 | |||
| 301 | const drawerInfo = ref({ | ||
| 302 | visible: false, | ||
| 303 | direction: "rtl", | ||
| 304 | size: 480, | ||
| 305 | header: { | ||
| 306 | title: "新增", | ||
| 307 | }, | ||
| 308 | type: "", | ||
| 309 | container: { | ||
| 310 | contents: [ | ||
| 311 | formInfo.value | ||
| 312 | ], | ||
| 313 | }, | ||
| 314 | footer: { | ||
| 315 | visible: true, | ||
| 316 | btns: [ | ||
| 317 | { type: "default", label: "取消", value: "cancel" }, | ||
| 318 | { type: "primary", label: "保存", value: "submit" }, | ||
| 319 | ], | ||
| 320 | }, | ||
| 321 | }); | ||
| 322 | |||
| 323 | // 获取所有疾病数据 | ||
| 324 | const getDiseaseData = () => { | ||
| 325 | getDiseaseAll().then((res: any) => { | ||
| 326 | if (res.code == proxy.$passCode) { | ||
| 327 | const data = res.data || []; | ||
| 328 | catalogData.value = JSON.parse(JSON.stringify(data)); | ||
| 329 | } | ||
| 330 | }) | ||
| 331 | } | ||
| 332 | |||
| 333 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 334 | page.value.curr = 1; | ||
| 335 | if (clear) { | ||
| 336 | searchItemList.value.map((item) => (item.default = "")); | ||
| 337 | page.value.diseaseName = ''; | ||
| 338 | page.value.isChildrenDisease = ''; | ||
| 339 | } else { | ||
| 340 | page.value.diseaseName = val.diseaseName || ''; | ||
| 341 | page.value.isChildrenDisease = val.isChildrenDisease || ''; | ||
| 342 | } | ||
| 343 | getTableData(); | ||
| 344 | }; | ||
| 345 | |||
| 346 | const getTableData = () => { | ||
| 347 | tableInfo.value.loading = true; | ||
| 348 | getDiseaseList({ | ||
| 349 | tenantGuid: userData.tenantGuid, | ||
| 350 | pageSize: page.value.limit, | ||
| 351 | pageIndex: page.value.curr, | ||
| 352 | diseaseName: page.value.diseaseName, | ||
| 353 | isChildrenDisease: page.value.isChildrenDisease, | ||
| 354 | }).then((res: any) => { | ||
| 355 | tableInfo.value.loading = false; | ||
| 356 | if (res.code == proxy.$passCode) { | ||
| 357 | const data = res.data || {}; | ||
| 358 | tableData.value = data.records || []; | ||
| 359 | tableInfo.value.data = data.records || [] | ||
| 360 | tableInfo.value.page.limit = data.pageSize | ||
| 361 | tableInfo.value.page.curr = data.pageIndex | ||
| 362 | tableInfo.value.page.rows = data.totalRows | ||
| 363 | // formItems.value[1].options = data.records || []; | ||
| 364 | } else { | ||
| 365 | proxy.$ElMessage.error(res.msg); | ||
| 366 | } | ||
| 367 | }) | ||
| 368 | } | ||
| 369 | |||
| 370 | const tablePageChange = (info) => { | ||
| 371 | page.value.curr = Number(info.curr); | ||
| 372 | page.value.limit = Number(info.limit); | ||
| 373 | tableInfo.value.page.limit = page.value.limit; | ||
| 374 | tableInfo.value.page.curr = page.value.curr; | ||
| 375 | getTableData(); | ||
| 376 | }; | ||
| 377 | |||
| 378 | // 处理表格数据选中 | ||
| 379 | const setSelect = (data, flag) => { | ||
| 380 | data.forEach((row: any) => { | ||
| 381 | selectionTreeTableRef.value.tableRef.toggleRowSelection(row, flag); | ||
| 382 | row.childList && setSelect(row.childList, flag); | ||
| 383 | }); | ||
| 384 | } | ||
| 385 | |||
| 386 | const setCataLog = (dataArr, id, parentDisabled = false) => { | ||
| 387 | return dataArr.map(item => { | ||
| 388 | // 当前节点是否被禁选(自身匹配或父节点已禁选) | ||
| 389 | const isDisabled = parentDisabled || item.guid === id; | ||
| 390 | // 新节点基础属性 | ||
| 391 | const newItem = { | ||
| 392 | ...item, | ||
| 393 | disabled: isDisabled | ||
| 394 | }; | ||
| 395 | |||
| 396 | // 递归处理子节点,并传递当前节点的禁选状态 | ||
| 397 | if (item.childList && item.childList.length > 0) { | ||
| 398 | newItem.childList = setCataLog(item.childList, id, isDisabled); | ||
| 399 | } | ||
| 400 | return newItem; | ||
| 401 | }) | ||
| 402 | } | ||
| 403 | |||
| 404 | const tableCheckboxSelectChange = (selectRows, row) => { | ||
| 405 | const check = selectRows.find(item => item.guid === row.guid); | ||
| 406 | row.childList && setSelect(row.childList, check ? true : false); | ||
| 407 | } | ||
| 408 | |||
| 409 | const checkAll = ref(false) | ||
| 410 | const tableCheckboxAllSelectChange = (selectRows) => { | ||
| 411 | checkAll.value = !checkAll.value; | ||
| 412 | setSelect(tableData.value, checkAll.value); | ||
| 413 | } | ||
| 414 | |||
| 415 | const tableSelectionChange = (val) => { | ||
| 416 | selectRowData.value = val; | ||
| 417 | }; | ||
| 418 | |||
| 419 | const tableBtnClick = (scope, btn) => { | ||
| 420 | const type = btn.value; | ||
| 421 | const row = scope.row; | ||
| 422 | currTableData.value = row; | ||
| 423 | if (type === 'edit') { // 编辑 | ||
| 424 | drawerInfo.value.visible = true; | ||
| 425 | drawerInfo.value.header.title = '编辑疾病'; | ||
| 426 | let cata = setCataLog(catalogData.value, row.guid); | ||
| 427 | formItems.value.map(item => { | ||
| 428 | if (item.field == 'parentGuid') { | ||
| 429 | item.options = cata; | ||
| 430 | } | ||
| 431 | item.default = row[item.field] || ''; | ||
| 432 | if (item.children) { | ||
| 433 | item.children.map(child => { | ||
| 434 | child.default = row[child.field] || ''; | ||
| 435 | if (child.field == 'factor') { | ||
| 436 | child.default = (row[child.field] !== '' && row[child.field] !== null) ? changeNum(row[child.field], 2) : ''; | ||
| 437 | } | ||
| 438 | }) | ||
| 439 | } | ||
| 440 | if (item.inputType == 'integerNumber') { | ||
| 441 | item.default = typeof row[item.field] == 'number' ? row[item.field] : ''; | ||
| 442 | } | ||
| 443 | }); | ||
| 444 | drawerInfo.value.type = type; | ||
| 445 | } else if (type === 'del') { // 删除 | ||
| 446 | open('确定要删除该条数据吗?', 'warning'); | ||
| 447 | } | ||
| 448 | }; | ||
| 449 | |||
| 450 | const open = (msg, type, isBatch = false) => { | ||
| 451 | ElMessageBox.confirm(msg, "提示", { | ||
| 452 | confirmButtonText: "确定", | ||
| 453 | cancelButtonText: "取消", | ||
| 454 | type: type, | ||
| 455 | }).then(() => { | ||
| 456 | let guids = [currTableData.value.guid] | ||
| 457 | if (isBatch) { | ||
| 458 | guids = []; | ||
| 459 | // 处理表格数据选中 | ||
| 460 | const setGuids = (data) => { | ||
| 461 | data.forEach((row: any) => { | ||
| 462 | guids.push(row.guid); | ||
| 463 | row.childList && setGuids(row.childList); | ||
| 464 | }); | ||
| 465 | } | ||
| 466 | setGuids(selectRowData.value); | ||
| 467 | } | ||
| 468 | deleteDisease(guids).then((res: any) => { | ||
| 469 | if (res.code == proxy.$passCode) { | ||
| 470 | getTableData(); | ||
| 471 | getDiseaseData(); | ||
| 472 | ElMessage({ | ||
| 473 | type: "success", | ||
| 474 | message: "删除成功", | ||
| 475 | }); | ||
| 476 | } else { | ||
| 477 | proxy.$ElMessage.error(res.msg); | ||
| 478 | } | ||
| 479 | }); | ||
| 480 | }); | ||
| 481 | }; | ||
| 482 | |||
| 483 | const addDisease = () => { | ||
| 484 | formItems.value.map(item => { | ||
| 485 | if (item.field == 'bizState') { | ||
| 486 | item.default = 'Y'; | ||
| 487 | } else { | ||
| 488 | if (item.field == 'parentGuid') { | ||
| 489 | item.options = catalogData.value; | ||
| 490 | } | ||
| 491 | item.default = ''; | ||
| 492 | if (item.children) { | ||
| 493 | item.children.map(child => { | ||
| 494 | child.default = ''; | ||
| 495 | }) | ||
| 496 | } | ||
| 497 | } | ||
| 498 | }); | ||
| 499 | drawerInfo.value.header.title = '新增疾病'; | ||
| 500 | drawerInfo.value.type = 'add'; | ||
| 501 | drawerInfo.value.visible = true; | ||
| 502 | |||
| 503 | } | ||
| 504 | // 批量删除 | ||
| 505 | const batching = (type) => { | ||
| 506 | if (type == 'delete') { | ||
| 507 | if (selectRowData.value.length == 0) { | ||
| 508 | ElMessage({ | ||
| 509 | type: 'error', | ||
| 510 | message: '请选择需要删除的数据', | ||
| 511 | }) | ||
| 512 | return | ||
| 513 | } | ||
| 514 | open("此操作将永久删除, 是否继续?", "warning", true); | ||
| 515 | } else if (type == 'import') { | ||
| 516 | const info = { | ||
| 517 | dictionaryGuid: '' | ||
| 518 | } | ||
| 519 | cacheStore.setCatch('uploadSetting', info) | ||
| 520 | router.push( | ||
| 521 | { | ||
| 522 | name: 'importFileDisease', | ||
| 523 | query: { | ||
| 524 | isfileImport: '8' | ||
| 525 | } | ||
| 526 | } | ||
| 527 | ); | ||
| 528 | } | ||
| 529 | } | ||
| 530 | |||
| 531 | |||
| 532 | const drawerBtnClick = async (btn, info) => { | ||
| 533 | if (btn.value == "submit") { | ||
| 534 | drawerInfo.value.footer.btns.map((item: any) => (item.disabled = true)); | ||
| 535 | let params = { ...info, tenantGuid: userData.tenantGuid }; | ||
| 536 | delete params.in; | ||
| 537 | if (drawerInfo.value.type == "add") { | ||
| 538 | saveDisease(params) | ||
| 539 | .then((res: any) => { | ||
| 540 | if (res.code == proxy.$passCode) { | ||
| 541 | getTableData(); | ||
| 542 | getDiseaseData(); | ||
| 543 | ElMessage({ | ||
| 544 | type: "success", | ||
| 545 | message: "新增疾病成功", | ||
| 546 | }); | ||
| 547 | drawerInfo.value.visible = false; | ||
| 548 | } else { | ||
| 549 | proxy.$ElMessage.error(res.msg); | ||
| 550 | drawerInfo.value.footer.btns.map( | ||
| 551 | (item: any) => delete item.disabled | ||
| 552 | ); | ||
| 553 | } | ||
| 554 | }) | ||
| 555 | .catch(() => { | ||
| 556 | drawerInfo.value.footer.btns.map((item: any) => delete item.disabled); | ||
| 557 | }); | ||
| 558 | } else { | ||
| 559 | params.guid = currTableData.value.guid; | ||
| 560 | updateDisease(params) | ||
| 561 | .then((res: any) => { | ||
| 562 | if (res.code == proxy.$passCode) { | ||
| 563 | getTableData(); | ||
| 564 | getDiseaseData(); | ||
| 565 | ElMessage({ | ||
| 566 | type: "success", | ||
| 567 | message: "编辑疾病成功", | ||
| 568 | }); | ||
| 569 | drawerInfo.value.visible = false; | ||
| 570 | } else { | ||
| 571 | proxy.$ElMessage.error(res.msg); | ||
| 572 | drawerInfo.value.footer.btns.map( | ||
| 573 | (item: any) => delete item.disabled | ||
| 574 | ); | ||
| 575 | } | ||
| 576 | }) | ||
| 577 | .catch(() => { | ||
| 578 | drawerInfo.value.footer.btns.map((item: any) => delete item.disabled); | ||
| 579 | }); | ||
| 580 | } | ||
| 581 | } else { | ||
| 582 | drawerInfo.value.footer.btns.map((item: any) => delete item.disabled); | ||
| 583 | nextTick(() => { | ||
| 584 | drawerInfo.value.visible = false; | ||
| 585 | }); | ||
| 586 | } | ||
| 587 | }; | ||
| 588 | |||
| 589 | onBeforeMount(() => { | ||
| 590 | getDiseaseData(); | ||
| 591 | }); | ||
| 592 | |||
| 593 | onActivated(() => { | ||
| 594 | |||
| 595 | }) | ||
| 596 | |||
| 597 | </script> | ||
| 598 | |||
| 599 | <template> | ||
| 600 | <div class="container_wrap"> | ||
| 601 | <div class="table_tool_wrap"> | ||
| 602 | <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" /> | ||
| 603 | <div class="tools_btns"> | ||
| 604 | <el-button type="primary" @click="addDisease" v-preReClick>新增</el-button> | ||
| 605 | <el-button @click="batching('import')" v-preReClick>批量导入</el-button> | ||
| 606 | <el-button @click="batching('delete')" v-preReClick>批量删除</el-button> | ||
| 607 | </div> | ||
| 608 | </div> | ||
| 609 | <div class="table_panel_wrap"> | ||
| 610 | <Table ref="selectionTreeTableRef" :tableInfo="tableInfo" @tableCheckboxSelectChange="tableCheckboxSelectChange" | ||
| 611 | @tableCheckboxAllSelectChange="tableCheckboxAllSelectChange" @tableSelectionChange="tableSelectionChange" | ||
| 612 | @tablePageChange="tablePageChange" @tableBtnClick="tableBtnClick" /> | ||
| 613 | </div> | ||
| 614 | <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" /> | ||
| 615 | </div> | ||
| 616 | </template> | ||
| 617 | |||
| 618 | <style lang="scss" scoped> | ||
| 619 | .table_tool_wrap { | ||
| 620 | width: 100%; | ||
| 621 | height: 84px !important; | ||
| 622 | padding: 0 8px; | ||
| 623 | |||
| 624 | .tools_btns { | ||
| 625 | padding: 0px 0 0; | ||
| 626 | } | ||
| 627 | } | ||
| 628 | |||
| 629 | .table_panel_wrap { | ||
| 630 | width: 100%; | ||
| 631 | height: calc(100% - 84px); | ||
| 632 | padding: 0px 8px 0; | ||
| 633 | } | ||
| 634 | </style> |
src/views/data_pricing/priceCalculate.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: priceCalculate | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="priceCalculate"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import TableTools from '@/components/Tools/table_tools.vue'; | ||
| 8 | import { TableColumnWidth, commonPageConfig } from '@/utils/enum'; | ||
| 9 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 10 | import { CirclePlus } from "@element-plus/icons-vue"; | ||
| 11 | import { useRouter, useRoute } from "vue-router"; | ||
| 12 | import useUserStore from "@/store/modules/user"; | ||
| 13 | import useDataAssetStore from "@/store/modules/dataAsset"; | ||
| 14 | import { getAllFlowData } from '@/api/modules/queryService'; | ||
| 15 | import { changeNum } from "@/utils/common"; | ||
| 16 | import { | ||
| 17 | getDiseaseAll, | ||
| 18 | getPriceList, | ||
| 19 | deletePrice, | ||
| 20 | } from '@/api/modules/dataPricing'; | ||
| 21 | |||
| 22 | const router = useRouter(); | ||
| 23 | const userStore = useUserStore() | ||
| 24 | const assetStore = useDataAssetStore(); | ||
| 25 | const userData = JSON.parse(userStore.userData) | ||
| 26 | const { proxy } = getCurrentInstance() as any; | ||
| 27 | |||
| 28 | const searchItemList = ref([ | ||
| 29 | { | ||
| 30 | type: "input", | ||
| 31 | label: "", | ||
| 32 | field: "dataResourceName", | ||
| 33 | default: "", | ||
| 34 | placeholder: "数据资源名称", | ||
| 35 | clearable: true, | ||
| 36 | }, | ||
| 37 | { | ||
| 38 | type: "cascader", | ||
| 39 | label: "", | ||
| 40 | field: "diseaseName", | ||
| 41 | placeholder: "疾病名称", | ||
| 42 | default: "", | ||
| 43 | options: [], | ||
| 44 | showAllLevels: false, | ||
| 45 | props: { | ||
| 46 | checkStrictly: true, | ||
| 47 | label: "diseaseName", | ||
| 48 | value: "guid", | ||
| 49 | children: 'childList', | ||
| 50 | emitPath: false | ||
| 51 | }, | ||
| 52 | filterable: true, | ||
| 53 | clearable: true, | ||
| 54 | } | ||
| 55 | ]); | ||
| 56 | |||
| 57 | const typeMap: any = ref({}); | ||
| 58 | const selectRowData: any = ref([]) | ||
| 59 | const currTableData: any = ref({}); | ||
| 60 | const page: any = ref({ | ||
| 61 | ...commonPageConfig, | ||
| 62 | dataResourceName: '', | ||
| 63 | diseaseName: '' | ||
| 64 | }); | ||
| 65 | const tableField: any = ref([ | ||
| 66 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 67 | { label: "定价模型名称", field: "modelName", width: 200 }, | ||
| 68 | { label: "数据资源名称", field: "dataResourceName", width: 200 }, | ||
| 69 | { label: "疾病名称", field: "diseaseName", width: 200 }, | ||
| 70 | { | ||
| 71 | label: "交易价格(元)", field: "dataTransactionPrice", width: 120, align: 'right', getName: (scope) => { | ||
| 72 | return scope.row.dataTransactionPrice ? changeNum(parseFloat(scope.row.dataTransactionPrice), 2) : '-'; | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | { label: "创建人", field: "createUserName", width: 120 }, | ||
| 76 | { label: "创建时间", field: "createTime", width: TableColumnWidth.DATETIME }, | ||
| 77 | ]); | ||
| 78 | const tableInfo = ref({ | ||
| 79 | id: 'api-data-table', | ||
| 80 | rowKey: 'guid', | ||
| 81 | loading: false, | ||
| 82 | fields: tableField.value, | ||
| 83 | data: [], | ||
| 84 | page: { | ||
| 85 | type: "normal", | ||
| 86 | rows: 0, | ||
| 87 | ...page.value, | ||
| 88 | }, | ||
| 89 | actionInfo: { | ||
| 90 | label: "操作", | ||
| 91 | type: "btn", | ||
| 92 | isMore: false, | ||
| 93 | width: 120, | ||
| 94 | btns: [ | ||
| 95 | { label: "编辑", value: "edit" }, | ||
| 96 | { label: "删除", value: "del" } | ||
| 97 | ] | ||
| 98 | } | ||
| 99 | }); | ||
| 100 | |||
| 101 | const setTableField = () => { | ||
| 102 | tableField.value.splice(4, 0, { | ||
| 103 | label: "交易用途", field: "dataUsage", width: 120, getName: (scope) => { | ||
| 104 | return typeMap.value['dataUsage'].find((item) => item.value == scope.row['dataUsage'])?.label || '-'; | ||
| 105 | } | ||
| 106 | }); | ||
| 107 | tableInfo.value.fields = tableField.value; | ||
| 108 | } | ||
| 109 | |||
| 110 | // 获取所有疾病数据 | ||
| 111 | const getDiseaseData = () => { | ||
| 112 | getDiseaseAll().then((res: any) => { | ||
| 113 | if (res.code == proxy.$passCode) { | ||
| 114 | const data = res.data || []; | ||
| 115 | searchItemList.value[1].options = data; | ||
| 116 | } | ||
| 117 | }) | ||
| 118 | } | ||
| 119 | |||
| 120 | // 获取数据字典 | ||
| 121 | const getDataType = (dictType, fieldName) => { | ||
| 122 | getAllFlowData({ dictType }).then((res: any) => { | ||
| 123 | if (res.code == proxy.$passCode) { | ||
| 124 | const data = res.data || []; | ||
| 125 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 126 | setTableField() | ||
| 127 | } else { | ||
| 128 | proxy.$ElMessage.error(res.msg); | ||
| 129 | } | ||
| 130 | }) | ||
| 131 | } | ||
| 132 | |||
| 133 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 134 | page.value.curr = 1; | ||
| 135 | if (clear) { | ||
| 136 | searchItemList.value.map((item) => (item.default = "")); | ||
| 137 | page.value.dataResourceName = '' | ||
| 138 | page.value.diseaseName = ''; | ||
| 139 | } else { | ||
| 140 | page.value.dataResourceName = val.dataResourceName || ''; | ||
| 141 | page.value.diseaseName = val.diseaseName || ''; | ||
| 142 | } | ||
| 143 | getTableData(); | ||
| 144 | }; | ||
| 145 | |||
| 146 | const getTableData = () => { | ||
| 147 | tableInfo.value.loading = true; | ||
| 148 | getPriceList({ | ||
| 149 | pageSize: page.value.limit, | ||
| 150 | pageIndex: page.value.curr, | ||
| 151 | dataResourceName: page.value.dataResourceName, | ||
| 152 | diseaseName: page.value.diseaseName, | ||
| 153 | }).then((res: any) => { | ||
| 154 | tableInfo.value.loading = false; | ||
| 155 | if (res.code == proxy.$passCode) { | ||
| 156 | const data = res.data || {}; | ||
| 157 | tableInfo.value.data = data.records || []; | ||
| 158 | tableInfo.value.page.limit = data.pageSize | ||
| 159 | tableInfo.value.page.curr = data.pageIndex | ||
| 160 | tableInfo.value.page.rows = data.totalRows | ||
| 161 | } else { | ||
| 162 | proxy.$ElMessage.error(res.msg); | ||
| 163 | } | ||
| 164 | }) | ||
| 165 | } | ||
| 166 | |||
| 167 | const tablePageChange = (info) => { | ||
| 168 | page.value.curr = Number(info.curr); | ||
| 169 | page.value.limit = Number(info.limit); | ||
| 170 | tableInfo.value.page.limit = page.value.limit; | ||
| 171 | tableInfo.value.page.curr = page.value.curr; | ||
| 172 | getTableData(); | ||
| 173 | }; | ||
| 174 | |||
| 175 | const tableBtnClick = (scope, btn) => { | ||
| 176 | const type = btn.value; | ||
| 177 | const row = scope.row; | ||
| 178 | currTableData.value = row; | ||
| 179 | if (type === 'edit') { // 编辑 | ||
| 180 | router.push( | ||
| 181 | { | ||
| 182 | name: 'calculateConfig', | ||
| 183 | query: { | ||
| 184 | guid: row.guid, | ||
| 185 | name: row.modelName, | ||
| 186 | type: 'edit' | ||
| 187 | } | ||
| 188 | } | ||
| 189 | ); | ||
| 190 | } else if (type === 'del') { // 删除 | ||
| 191 | open('确定要删除该条数据吗?', 'warning'); | ||
| 192 | } | ||
| 193 | }; | ||
| 194 | |||
| 195 | const open = (msg, type, isBatch = false) => { | ||
| 196 | ElMessageBox.confirm(msg, "提示", { | ||
| 197 | confirmButtonText: "确定", | ||
| 198 | cancelButtonText: "取消", | ||
| 199 | type: type, | ||
| 200 | }).then(() => { | ||
| 201 | let guids = [currTableData.value.guid] | ||
| 202 | if (isBatch) { | ||
| 203 | guids = selectRowData.value | ||
| 204 | } | ||
| 205 | deletePrice(guids).then((res: any) => { | ||
| 206 | if (res.code == proxy.$passCode) { | ||
| 207 | getTableData(); | ||
| 208 | ElMessage({ | ||
| 209 | type: "success", | ||
| 210 | message: "删除成功", | ||
| 211 | }); | ||
| 212 | } else { | ||
| 213 | proxy.$ElMessage.error(res.msg); | ||
| 214 | } | ||
| 215 | }); | ||
| 216 | }); | ||
| 217 | }; | ||
| 218 | |||
| 219 | const addDisease = () => { | ||
| 220 | router.push( | ||
| 221 | { | ||
| 222 | name: 'calculateConfig', | ||
| 223 | query: { | ||
| 224 | type: 'create' | ||
| 225 | } | ||
| 226 | } | ||
| 227 | ); | ||
| 228 | } | ||
| 229 | |||
| 230 | onBeforeMount(() => { | ||
| 231 | getDiseaseData(); | ||
| 232 | getDataType('数据用途', 'dataUsage') | ||
| 233 | }); | ||
| 234 | |||
| 235 | onActivated(() => { | ||
| 236 | if (assetStore.isRefresh) {//如果是首次加载,则不需要调用 | ||
| 237 | toSearch(null, true); | ||
| 238 | assetStore.set(false); | ||
| 239 | } | ||
| 240 | }) | ||
| 241 | |||
| 242 | </script> | ||
| 243 | |||
| 244 | <template> | ||
| 245 | <div class="container_wrap"> | ||
| 246 | <div class="table_tool_wrap"> | ||
| 247 | <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" /> | ||
| 248 | <div class="tools_btns"> | ||
| 249 | <el-button type="primary" @click="addDisease" v-preReClick>新增</el-button> | ||
| 250 | </div> | ||
| 251 | </div> | ||
| 252 | <div class="table_panel_wrap"> | ||
| 253 | <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" @tableBtnClick="tableBtnClick" /> | ||
| 254 | </div> | ||
| 255 | </div> | ||
| 256 | </template> | ||
| 257 | |||
| 258 | <style lang="scss" scoped> | ||
| 259 | .table_tool_wrap { | ||
| 260 | width: 100%; | ||
| 261 | height: 84px !important; | ||
| 262 | padding: 0 8px; | ||
| 263 | |||
| 264 | .tools_btns { | ||
| 265 | padding: 0px 0 0; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | .table_panel_wrap { | ||
| 270 | width: 100%; | ||
| 271 | height: calc(100% - 84px); | ||
| 272 | padding: 0px 8px 0; | ||
| 273 | } | ||
| 274 | </style> |
src/views/data_pricing/priceConfig.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: priceConfig | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="priceConfig"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import TableTools from '@/components/Tools/table_tools.vue'; | ||
| 8 | import { TableColumnWidth, commonPageConfig } from '@/utils/enum'; | ||
| 9 | import { ElMessage, ElMessageBox } from "element-plus"; | ||
| 10 | import { CirclePlus } from "@element-plus/icons-vue"; | ||
| 11 | import { useRouter, useRoute } from "vue-router"; | ||
| 12 | import useUserStore from "@/store/modules/user"; | ||
| 13 | import useDataAssetStore from "@/store/modules/dataAsset"; | ||
| 14 | import { getAllFlowData } from '@/api/modules/queryService'; | ||
| 15 | import { | ||
| 16 | getConfigureList, | ||
| 17 | deleteConfigure, | ||
| 18 | getConfigureDetail, | ||
| 19 | addCopyConfigure | ||
| 20 | } from '@/api/modules/dataPricing'; | ||
| 21 | |||
| 22 | const router = useRouter(); | ||
| 23 | const userStore = useUserStore() | ||
| 24 | const assetStore = useDataAssetStore(); | ||
| 25 | const userData = JSON.parse(userStore.userData) | ||
| 26 | const { proxy } = getCurrentInstance() as any; | ||
| 27 | |||
| 28 | const searchItemList = ref([ | ||
| 29 | { | ||
| 30 | type: "input", | ||
| 31 | label: "", | ||
| 32 | field: "modelName", | ||
| 33 | default: "", | ||
| 34 | placeholder: "定价模型名称", | ||
| 35 | clearable: true, | ||
| 36 | }, | ||
| 37 | { | ||
| 38 | type: "select", | ||
| 39 | label: "", | ||
| 40 | field: "institutionType", | ||
| 41 | placeholder: "机构类型", | ||
| 42 | default: "", | ||
| 43 | options: [], | ||
| 44 | clearable: true, | ||
| 45 | } | ||
| 46 | ]); | ||
| 47 | |||
| 48 | const typeMap = ref({}); | ||
| 49 | const tableData: any = ref([]); | ||
| 50 | const selectRowData: any = ref([]) | ||
| 51 | const currTableData: any = ref({}); | ||
| 52 | const page: any = ref({ | ||
| 53 | ...commonPageConfig, | ||
| 54 | modelName: '', | ||
| 55 | institutionType: '' | ||
| 56 | }); | ||
| 57 | const tableInfo = ref({ | ||
| 58 | id: 'api-data-table', | ||
| 59 | rowKey: 'guid', | ||
| 60 | loading: false, | ||
| 61 | fields: [ | ||
| 62 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 63 | { label: "定价模型名称", field: "modelName", width: 200 }, | ||
| 64 | { | ||
| 65 | label: "机构类型", field: "institutionType", width: 120, getName: (scope) => { | ||
| 66 | return filterVal(scope.row.institutionType, 'institutionType') | ||
| 67 | } | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | label: "启用状态", field: "bizState", type: 'tag', width: 120, align: 'center', getName: (scope) => { | ||
| 71 | return scope.row.bizState == 'Y' ? '启用' : '停用'; | ||
| 72 | }, tagType: (scope) => { | ||
| 73 | return scope.row.bizState == 'Y' ? 'success' : 'info'; | ||
| 74 | } | ||
| 75 | }, | ||
| 76 | { label: "创建人", field: "createUserName", width: 120 }, | ||
| 77 | { label: "创建时间", field: "createTime", width: TableColumnWidth.DATETIME }, | ||
| 78 | ], | ||
| 79 | data: tableData.value, | ||
| 80 | page: { | ||
| 81 | type: "normal", | ||
| 82 | rows: 0, | ||
| 83 | ...page.value, | ||
| 84 | }, | ||
| 85 | actionInfo: { | ||
| 86 | label: "操作", | ||
| 87 | type: "btn", | ||
| 88 | isMore: false, | ||
| 89 | width: 160, | ||
| 90 | btns: [ | ||
| 91 | { label: "编辑", value: "edit" }, | ||
| 92 | { label: "复制", value: "copy" }, | ||
| 93 | { label: "删除", value: "del" } | ||
| 94 | ] | ||
| 95 | } | ||
| 96 | }); | ||
| 97 | |||
| 98 | // 过滤 | ||
| 99 | const filterVal = (val, name) => { | ||
| 100 | if (typeMap.value[name]) { | ||
| 101 | const data = typeMap.value[name].find(item => item.value == val); | ||
| 102 | return data?.label || '--'; | ||
| 103 | } | ||
| 104 | }; | ||
| 105 | |||
| 106 | // 获取需求类型 | ||
| 107 | const getDataType = (dictType, fieldName) => { | ||
| 108 | getAllFlowData({ dictType }).then((res: any) => { | ||
| 109 | if (res.code == proxy.$passCode) { | ||
| 110 | const data = res.data || []; | ||
| 111 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 112 | let item = searchItemList.value.find(item => item.field == fieldName); | ||
| 113 | item && (item.options = data); | ||
| 114 | } else { | ||
| 115 | proxy.$ElMessage.error(res.msg); | ||
| 116 | } | ||
| 117 | }) | ||
| 118 | } | ||
| 119 | |||
| 120 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 121 | page.value.curr = 1; | ||
| 122 | if (clear) { | ||
| 123 | searchItemList.value.map((item) => (item.default = "")); | ||
| 124 | page.value.modelName = ''; | ||
| 125 | page.value.institutionType = ''; | ||
| 126 | } else { | ||
| 127 | page.value.modelName = val.modelName || ''; | ||
| 128 | page.value.institutionType = val.institutionType || ''; | ||
| 129 | } | ||
| 130 | getTableData(); | ||
| 131 | }; | ||
| 132 | |||
| 133 | const getTableData = () => { | ||
| 134 | tableInfo.value.loading = true; | ||
| 135 | getConfigureList({ | ||
| 136 | pageSize: page.value.limit, | ||
| 137 | pageIndex: page.value.curr, | ||
| 138 | modelName: page.value.modelName, | ||
| 139 | institutionType: page.value.institutionType, | ||
| 140 | }).then((res: any) => { | ||
| 141 | tableInfo.value.loading = false; | ||
| 142 | if (res.code == proxy.$passCode) { | ||
| 143 | const data = res.data || {}; | ||
| 144 | tableInfo.value.data = data.records || [] | ||
| 145 | tableInfo.value.page.limit = data.pageSize | ||
| 146 | tableInfo.value.page.curr = data.pageIndex | ||
| 147 | tableInfo.value.page.rows = data.totalRows | ||
| 148 | } else { | ||
| 149 | proxy.$ElMessage.error(res.msg); | ||
| 150 | } | ||
| 151 | }) | ||
| 152 | } | ||
| 153 | |||
| 154 | const tablePageChange = (info) => { | ||
| 155 | page.value.curr = Number(info.curr); | ||
| 156 | page.value.limit = Number(info.limit); | ||
| 157 | tableInfo.value.page.limit = page.value.limit; | ||
| 158 | tableInfo.value.page.curr = page.value.curr; | ||
| 159 | getTableData(); | ||
| 160 | }; | ||
| 161 | |||
| 162 | const tableBtnClick = (scope, btn) => { | ||
| 163 | const type = btn.value; | ||
| 164 | const row = scope.row; | ||
| 165 | currTableData.value = row; | ||
| 166 | if (type === 'edit') { // 编辑 | ||
| 167 | router.push( | ||
| 168 | { | ||
| 169 | name: 'priceModel', | ||
| 170 | query: { | ||
| 171 | guid: row.guid, | ||
| 172 | name: row.modelName, | ||
| 173 | type | ||
| 174 | } | ||
| 175 | } | ||
| 176 | ); | ||
| 177 | } else if (type == 'copy') { //复制 | ||
| 178 | ElMessageBox.confirm('是否确定复制该模型?', "提示", { | ||
| 179 | confirmButtonText: "确定", | ||
| 180 | cancelButtonText: "取消", | ||
| 181 | type: 'warning', | ||
| 182 | }).then(() => { | ||
| 183 | getConfigureDetail({ guid: row.guid }).then((res: any) => { | ||
| 184 | if (res.code == proxy.$passCode) { | ||
| 185 | const data = res.data || {}; | ||
| 186 | let params = { ...data }; | ||
| 187 | delete params.createTime; | ||
| 188 | delete params.createUserName; | ||
| 189 | delete params.pricingDimensionalityRSVOS; | ||
| 190 | const pricingDimensionalityRSVOS = data.pricingDimensionalityRSVOS || []; | ||
| 191 | pricingDimensionalityRSVOS.map(p => { | ||
| 192 | p.pricingTargetRQVOS = p.pricingTargetRSVOS || []; | ||
| 193 | delete p.pricingTargetRSVOS; | ||
| 194 | }); | ||
| 195 | params.pricingDimensionalityRQVOS = pricingDimensionalityRSVOS; | ||
| 196 | addCopyConfigure(params).then((res: any) => { | ||
| 197 | if (res.code == proxy.$passCode) { | ||
| 198 | ElMessage({ | ||
| 199 | type: "success", | ||
| 200 | message: "复制定价配置成功", | ||
| 201 | }); | ||
| 202 | getTableData(); | ||
| 203 | } else { | ||
| 204 | proxy.$ElMessage.error(res.msg); | ||
| 205 | } | ||
| 206 | }).catch(() => { | ||
| 207 | |||
| 208 | }); | ||
| 209 | } | ||
| 210 | }).catch(() => { | ||
| 211 | |||
| 212 | }) | ||
| 213 | }); | ||
| 214 | } else if (type === 'del') { // 删除 | ||
| 215 | open('确定要删除该条数据吗?', 'warning'); | ||
| 216 | } | ||
| 217 | }; | ||
| 218 | |||
| 219 | const open = (msg, type, isBatch = false) => { | ||
| 220 | ElMessageBox.confirm(msg, "提示", { | ||
| 221 | confirmButtonText: "确定", | ||
| 222 | cancelButtonText: "取消", | ||
| 223 | type: type, | ||
| 224 | }).then(() => { | ||
| 225 | let guids = [currTableData.value.guid] | ||
| 226 | if (isBatch) { | ||
| 227 | guids = selectRowData.value | ||
| 228 | } | ||
| 229 | deleteConfigure(guids).then((res: any) => { | ||
| 230 | if (res.code == proxy.$passCode) { | ||
| 231 | getTableData(); | ||
| 232 | ElMessage({ | ||
| 233 | type: "success", | ||
| 234 | message: "删除成功", | ||
| 235 | }); | ||
| 236 | } else { | ||
| 237 | proxy.$ElMessage.error(res.msg); | ||
| 238 | } | ||
| 239 | }); | ||
| 240 | }); | ||
| 241 | }; | ||
| 242 | |||
| 243 | const addDisease = () => { | ||
| 244 | router.push( | ||
| 245 | { | ||
| 246 | name: 'priceModel', | ||
| 247 | query: { | ||
| 248 | type: 'create' | ||
| 249 | } | ||
| 250 | } | ||
| 251 | ); | ||
| 252 | } | ||
| 253 | |||
| 254 | onBeforeMount(() => { | ||
| 255 | getDataType('机构类型', 'institutionType') | ||
| 256 | }); | ||
| 257 | |||
| 258 | onActivated(() => { | ||
| 259 | if (assetStore.isRefresh) {//如果是首次加载,则不需要调用 | ||
| 260 | toSearch(null, true); | ||
| 261 | assetStore.set(false); | ||
| 262 | } | ||
| 263 | }) | ||
| 264 | |||
| 265 | </script> | ||
| 266 | |||
| 267 | <template> | ||
| 268 | <div class="container_wrap"> | ||
| 269 | <div class="table_tool_wrap"> | ||
| 270 | <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" /> | ||
| 271 | <div class="tools_btns"> | ||
| 272 | <el-button type="primary" @click="addDisease" v-preReClick>新增</el-button> | ||
| 273 | </div> | ||
| 274 | </div> | ||
| 275 | <div class="table_panel_wrap"> | ||
| 276 | <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" @tableBtnClick="tableBtnClick" /> | ||
| 277 | </div> | ||
| 278 | </div> | ||
| 279 | </template> | ||
| 280 | |||
| 281 | <style lang="scss" scoped> | ||
| 282 | .table_tool_wrap { | ||
| 283 | width: 100%; | ||
| 284 | height: 84px !important; | ||
| 285 | padding: 0 8px; | ||
| 286 | |||
| 287 | .tools_btns { | ||
| 288 | padding: 0px 0 0; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | .table_panel_wrap { | ||
| 293 | width: 100%; | ||
| 294 | height: calc(100% - 84px); | ||
| 295 | padding: 0px 8px 0; | ||
| 296 | } | ||
| 297 | </style> |
src/views/data_pricing/priceModel.vue
0 → 100644
| 1 | <route lang="yaml"> | ||
| 2 | name: priceModel | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="priceModel"> | ||
| 6 | import { ref, onMounted } from "vue"; | ||
| 7 | import { useRouter, useRoute } from "vue-router"; | ||
| 8 | import { ElMessage, ElMessageBox, rowProps } from "element-plus"; | ||
| 9 | import { Plus, CirclePlus, Guide } from "@element-plus/icons-vue"; | ||
| 10 | import useUserStore from "@/store/modules/user"; | ||
| 11 | import useDataAssetStore from "@/store/modules/dataAsset"; | ||
| 12 | import { getAllFlowData } from '@/api/modules/queryService'; | ||
| 13 | import { changeNum } from "@/utils/common"; | ||
| 14 | import { | ||
| 15 | getDemandTreeList, | ||
| 16 | getConfigureDetail, | ||
| 17 | saveConfigure, | ||
| 18 | updateConfigure | ||
| 19 | } from '@/api/modules/dataPricing'; | ||
| 20 | |||
| 21 | const { proxy } = getCurrentInstance() as any; | ||
| 22 | const router = useRouter(); | ||
| 23 | const route = useRoute(); | ||
| 24 | const userStore = useUserStore(); | ||
| 25 | const assetStore = useDataAssetStore(); | ||
| 26 | const fullPath = route.fullPath; | ||
| 27 | const userData = JSON.parse(localStorage.userData); | ||
| 28 | const guid = route.query.guid; | ||
| 29 | const modelName = route.query.name; | ||
| 30 | |||
| 31 | const loading = ref(false); | ||
| 32 | const flowDetail: any = ref({}); | ||
| 33 | const typeMap: any = ref({}); | ||
| 34 | const expand1 = ref(true) | ||
| 35 | const expand2 = ref(true) | ||
| 36 | |||
| 37 | // 基础设置 | ||
| 38 | const baseConfigFormRef = ref(); | ||
| 39 | const baseConfigFormItems: any = ref([ | ||
| 40 | { | ||
| 41 | label: '模型名称', | ||
| 42 | type: 'input', | ||
| 43 | placeholder: '请输入', | ||
| 44 | field: 'modelName', | ||
| 45 | default: '', | ||
| 46 | clearable: true, | ||
| 47 | required: true | ||
| 48 | }, | ||
| 49 | { | ||
| 50 | label: '机构类型', | ||
| 51 | type: 'select', | ||
| 52 | placeholder: '请选择', | ||
| 53 | field: 'institutionType', | ||
| 54 | default: '', | ||
| 55 | options: [], | ||
| 56 | clearable: true, | ||
| 57 | required: true, | ||
| 58 | }, | ||
| 59 | { | ||
| 60 | label: '启用状态', | ||
| 61 | type: 'switch', | ||
| 62 | field: 'bizState', | ||
| 63 | default: 'Y', | ||
| 64 | placeholder: '请选择', | ||
| 65 | activeValue: 'Y', | ||
| 66 | inactiveValue: 'N', | ||
| 67 | switchWidth: 32, | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | label: '模型公式', | ||
| 71 | type: 'input', | ||
| 72 | placeholder: '请输入', | ||
| 73 | field: 'modelFormula', | ||
| 74 | default: '', | ||
| 75 | maxlength: 500, | ||
| 76 | clearable: true, | ||
| 77 | required: true, | ||
| 78 | block: true, | ||
| 79 | }, | ||
| 80 | ]) | ||
| 81 | const baseConfigFormRules = ref({ | ||
| 82 | modelName: [ | ||
| 83 | { required: true, trigger: 'blur', message: "请填写模型名称" } | ||
| 84 | ], | ||
| 85 | institutionType: [ | ||
| 86 | { required: true, trigger: 'change', message: "请选择机构类型" } | ||
| 87 | ], | ||
| 88 | modelFormula: [ | ||
| 89 | { required: true, trigger: 'change', message: "请填写模型公式" }, | ||
| 90 | { | ||
| 91 | validator: (rule, value, callback) => { | ||
| 92 | validateFormula(value, callback); | ||
| 93 | }, | ||
| 94 | trigger: 'blur' | ||
| 95 | } | ||
| 96 | ], | ||
| 97 | }); | ||
| 98 | const baseConfigForm = ref({ | ||
| 99 | items: baseConfigFormItems.value, | ||
| 100 | rules: baseConfigFormRules.value, | ||
| 101 | }) | ||
| 102 | |||
| 103 | |||
| 104 | // 校验模型公式 | ||
| 105 | const validateFormula = (value, callback) => { | ||
| 106 | const baseConfigFormObj = baseConfigFormRef.value; | ||
| 107 | const baseConfigFormInfo = baseConfigFormObj.formInline; | ||
| 108 | const formula = value || baseConfigFormInfo.modelFormula; | ||
| 109 | |||
| 110 | if (!formula.trim()) { | ||
| 111 | callback(new Error('请输入模型公式')); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | const dimensions = signatoryTableList.value.map(s => s.dimensionalityName); | ||
| 116 | |||
| 117 | /* 第一步:检查维度是否存在 */ | ||
| 118 | const dimMatches = [...formula.matchAll(/"([^"]+)"/g)]; | ||
| 119 | for (const match of dimMatches) { | ||
| 120 | const dim = match[1]; // 获取引号内的内容 | ||
| 121 | if (!dimensions.includes(dim)) { | ||
| 122 | callback(new Error(`维度"${dim}"不存在`)); | ||
| 123 | return; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | /* 第二步:检查维度间是否有运算符 */ | ||
| 128 | if (/"([^"]+)"\s*"([^"]+)"/.test(formula)) { | ||
| 129 | callback(new Error('维度之间必须使用运算符连接')); | ||
| 130 | return; | ||
| 131 | } | ||
| 132 | |||
| 133 | /* 第三步:检查运算符使用是否合法 */ | ||
| 134 | // 检查连续运算符 | ||
| 135 | if (/([+\-*\/^]\s*){2,}/.test(formula.replace(/\s+/g, ''))) { | ||
| 136 | callback(new Error('不允许连续使用运算符')); | ||
| 137 | return; | ||
| 138 | } | ||
| 139 | // 检查运算符后无参数 | ||
| 140 | if (/[+\-*\/^]\s*["(]*(\)|$)/.test(formula.replace(/\s+/g, ''))) { | ||
| 141 | callback(new Error('公式不完整')); | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | |||
| 145 | /* 第四步:替换变量并校验公式结构 */ | ||
| 146 | const dimMap = new Map(); | ||
| 147 | dimMatches.forEach((match, i) => { | ||
| 148 | dimMap.set(match[0], `a${i + 1}`); // 创建维度到变量的映射 | ||
| 149 | }); | ||
| 150 | |||
| 151 | let formulaWithVars = formula; | ||
| 152 | dimMap.forEach((varName, dim) => { | ||
| 153 | formulaWithVars = formulaWithVars.split(dim).join(varName); | ||
| 154 | }); | ||
| 155 | |||
| 156 | // 基础字符检查 | ||
| 157 | const validChars = /^[\sa\d+\-*\/^().]+$/; | ||
| 158 | if (!validChars.test(formulaWithVars)) { | ||
| 159 | callback(new Error('公式包含非法字符')); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* 增强的括号匹配检查(支持多种括号类型)*/ | ||
| 164 | const bracketPairs = { | ||
| 165 | '(': ')', | ||
| 166 | '[': ']', | ||
| 167 | '{': '}', | ||
| 168 | '<': '>' | ||
| 169 | }; | ||
| 170 | const stack = []; | ||
| 171 | |||
| 172 | for (const char of formulaWithVars) { | ||
| 173 | if (bracketPairs[char]) { | ||
| 174 | stack.push(char); | ||
| 175 | } else if (Object.values(bracketPairs).includes(char)) { | ||
| 176 | if (stack.length === 0 || bracketPairs[stack.pop()] !== char) { | ||
| 177 | callback(new Error('括号使用不匹配或未正确闭合')); | ||
| 178 | return; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | if (stack.length > 0) { | ||
| 184 | callback(new Error('括号使用不匹配或未正确闭合')); | ||
| 185 | return; | ||
| 186 | } | ||
| 187 | |||
| 188 | callback(); // 所有检查通过 | ||
| 189 | }; | ||
| 190 | |||
| 191 | // 维度设置 | ||
| 192 | const currTableData: any = ref({}); | ||
| 193 | const currSignatoryData: any = ref({}); | ||
| 194 | const signatoryTableList: any = ref([]); | ||
| 195 | const pricingDimensionality: any = ref([]); | ||
| 196 | |||
| 197 | // 维度表单 | ||
| 198 | const signatoryFormItems: any = ref([ | ||
| 199 | { | ||
| 200 | label: '维度名称', | ||
| 201 | type: 'input', | ||
| 202 | placeholder: '请输入', | ||
| 203 | field: 'dimensionalityName', | ||
| 204 | default: '', | ||
| 205 | maxlength: 50, | ||
| 206 | clearable: true, | ||
| 207 | required: true, | ||
| 208 | }, | ||
| 209 | { | ||
| 210 | label: '计算公式', | ||
| 211 | type: 'select', | ||
| 212 | placeholder: '请选择', | ||
| 213 | field: 'computationalFormula', | ||
| 214 | default: '', | ||
| 215 | options: [], | ||
| 216 | clearable: true, | ||
| 217 | required: true, | ||
| 218 | }, | ||
| 219 | { | ||
| 220 | label: '权重(%)', | ||
| 221 | type: 'input', | ||
| 222 | placeholder: '请输入', | ||
| 223 | field: 'weight', | ||
| 224 | default: '', | ||
| 225 | inputType: 'factorNumber', | ||
| 226 | maxlength: 10, | ||
| 227 | clearable: true, | ||
| 228 | }, | ||
| 229 | { | ||
| 230 | label: '启用状态', | ||
| 231 | type: 'switch', | ||
| 232 | field: 'invocationStatus', | ||
| 233 | default: 'Y', | ||
| 234 | placeholder: '请选择', | ||
| 235 | activeValue: 'Y', | ||
| 236 | inactiveValue: 'N', | ||
| 237 | switchWidth: 32, | ||
| 238 | }, | ||
| 239 | { | ||
| 240 | label: '维度说明', | ||
| 241 | type: 'textarea', | ||
| 242 | placeholder: '请输入', | ||
| 243 | field: 'remark', | ||
| 244 | default: '', | ||
| 245 | maxlength: 500, | ||
| 246 | clearable: true, | ||
| 247 | block: true, | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | label: '自定义公式', | ||
| 251 | type: 'textarea', | ||
| 252 | placeholder: '请输入', | ||
| 253 | field: 'customize', | ||
| 254 | default: '', | ||
| 255 | maxlength: 500, | ||
| 256 | clearable: true, | ||
| 257 | block: true, | ||
| 258 | visible: false, | ||
| 259 | }, | ||
| 260 | ]) | ||
| 261 | const signatoryFormRules = ref({ | ||
| 262 | dimensionalityName: [ | ||
| 263 | { | ||
| 264 | validator: (rule: any, value: any, callback: any) => { | ||
| 265 | if (!value) { | ||
| 266 | callback(new Error("请填写维度名称")); | ||
| 267 | } else { | ||
| 268 | if (drawerInfo.value.type.indexOf('edit') > -1 && currSignatoryData.value.dimensionalityName == value) { | ||
| 269 | callback(); | ||
| 270 | return | ||
| 271 | } | ||
| 272 | const dimName = signatoryTableList.value.map(item => item.dimensionalityName); | ||
| 273 | if (dimName.indexOf(value) != -1) { | ||
| 274 | callback(new Error("该名称已存在")); | ||
| 275 | } else { | ||
| 276 | callback(); | ||
| 277 | } | ||
| 278 | } | ||
| 279 | }, | ||
| 280 | trigger: "blur", | ||
| 281 | }, | ||
| 282 | ], | ||
| 283 | computationalFormula: [ | ||
| 284 | { required: true, message: '请选择计算公式', trigger: 'change' } | ||
| 285 | ], | ||
| 286 | }); | ||
| 287 | |||
| 288 | // 指标表单 | ||
| 289 | const treeData = ref([]); | ||
| 290 | const targetFormItems: any = ref([ | ||
| 291 | { | ||
| 292 | label: '指标名称', | ||
| 293 | type: 'input', | ||
| 294 | placeholder: '请输入', | ||
| 295 | field: 'targetName', | ||
| 296 | default: '', | ||
| 297 | maxlength: 50, | ||
| 298 | clearable: true, | ||
| 299 | required: true, | ||
| 300 | }, | ||
| 301 | { | ||
| 302 | label: '指标类型', | ||
| 303 | type: 'select', | ||
| 304 | placeholder: '请选择', | ||
| 305 | field: 'targetType', | ||
| 306 | default: '', | ||
| 307 | options: [], | ||
| 308 | clearable: true, | ||
| 309 | required: true, | ||
| 310 | }, | ||
| 311 | { | ||
| 312 | label: '权重(%)', | ||
| 313 | type: 'input', | ||
| 314 | placeholder: '请输入', | ||
| 315 | field: 'weight', | ||
| 316 | default: '', | ||
| 317 | inputType: 'factorNumber', | ||
| 318 | maxlength: 10, | ||
| 319 | clearable: true, | ||
| 320 | required: true, | ||
| 321 | visible: false, | ||
| 322 | }, | ||
| 323 | { | ||
| 324 | label: '是否展示', | ||
| 325 | type: 'switch', | ||
| 326 | field: 'isShow', | ||
| 327 | default: 'Y', | ||
| 328 | placeholder: '请选择', | ||
| 329 | activeValue: 'Y', | ||
| 330 | inactiveValue: 'N', | ||
| 331 | switchWidth: 32, | ||
| 332 | disabled: false, | ||
| 333 | style: { | ||
| 334 | width: 'calc(25% - 4px)', | ||
| 335 | 'margin-left': '8px' | ||
| 336 | } | ||
| 337 | }, | ||
| 338 | { | ||
| 339 | label: '是否输入参数', | ||
| 340 | type: 'switch', | ||
| 341 | field: 'isInputParameter', | ||
| 342 | default: 'Y', | ||
| 343 | placeholder: '请选择', | ||
| 344 | activeValue: 'Y', | ||
| 345 | inactiveValue: 'N', | ||
| 346 | switchWidth: 32, | ||
| 347 | style: { | ||
| 348 | width: 'calc(25% - 4px)' | ||
| 349 | } | ||
| 350 | }, | ||
| 351 | { | ||
| 352 | label: '默认值', | ||
| 353 | type: 'input', | ||
| 354 | placeholder: '请输入', | ||
| 355 | field: 'defaultValue', | ||
| 356 | default: '', | ||
| 357 | inputType: 'factorNumber', | ||
| 358 | maxlength: 18, | ||
| 359 | clearable: true, | ||
| 360 | required: false | ||
| 361 | }, | ||
| 362 | { | ||
| 363 | label: '选择字典', | ||
| 364 | type: 'select', | ||
| 365 | placeholder: '请选择', | ||
| 366 | field: 'dictionaryType', | ||
| 367 | default: '', | ||
| 368 | options: [], | ||
| 369 | clearable: true, | ||
| 370 | required: true, | ||
| 371 | visible: false, | ||
| 372 | }, | ||
| 373 | { | ||
| 374 | label: '功能名称', | ||
| 375 | type: 'select', | ||
| 376 | placeholder: '请选择', | ||
| 377 | field: 'functionName', | ||
| 378 | default: '', | ||
| 379 | options: [], | ||
| 380 | clearable: true, | ||
| 381 | required: true, | ||
| 382 | visible: false, | ||
| 383 | }, | ||
| 384 | { | ||
| 385 | label: '选择需求表', | ||
| 386 | type: 'select', | ||
| 387 | placeholder: '请选择', | ||
| 388 | field: 'demandTableGuid', | ||
| 389 | default: '', | ||
| 390 | options: [], | ||
| 391 | props: { | ||
| 392 | label: "menuName", | ||
| 393 | value: "guid", | ||
| 394 | }, | ||
| 395 | filterable: true, | ||
| 396 | clearable: true, | ||
| 397 | required: true, | ||
| 398 | visible: false, | ||
| 399 | }, | ||
| 400 | { | ||
| 401 | label: '公式设置', | ||
| 402 | type: 'textarea', | ||
| 403 | placeholder: '请输入', | ||
| 404 | field: 'formulaSetting', | ||
| 405 | default: '', | ||
| 406 | resize: 'vertical', | ||
| 407 | maxlength: 500, | ||
| 408 | clearable: true, | ||
| 409 | block: true, | ||
| 410 | required: true, | ||
| 411 | }, | ||
| 412 | ]) | ||
| 413 | const targetFormRules = ref({ | ||
| 414 | targetName: [ | ||
| 415 | { | ||
| 416 | validator: (rule: any, value: any, callback: any) => { | ||
| 417 | if (!value) { | ||
| 418 | callback(new Error("请填写指标名称")); | ||
| 419 | } else { | ||
| 420 | if (drawerInfo.value.type.indexOf('edit') > -1 && currTableData.value.targetName == value) { | ||
| 421 | callback(); | ||
| 422 | return | ||
| 423 | } | ||
| 424 | const dimName = currSignatoryData.value.tableInfo.data.map(item => item.targetName); | ||
| 425 | if (dimName.indexOf(value) != -1) { | ||
| 426 | callback(new Error("该名称已存在")); | ||
| 427 | } else { | ||
| 428 | callback(); | ||
| 429 | } | ||
| 430 | } | ||
| 431 | }, | ||
| 432 | trigger: "blur", | ||
| 433 | }, | ||
| 434 | ], | ||
| 435 | targetType: [ | ||
| 436 | { required: true, message: '请选择指标类型', trigger: 'change' } | ||
| 437 | ], | ||
| 438 | dictionaryType: [ | ||
| 439 | { required: true, message: '请选择数据字典', trigger: 'change' } | ||
| 440 | ], | ||
| 441 | functionName: [ | ||
| 442 | { required: true, message: '请选择功能名称', trigger: 'change' } | ||
| 443 | ], | ||
| 444 | formulaSetting: [ | ||
| 445 | { required: true, message: '请填写公式设置', trigger: 'blur' } | ||
| 446 | ], | ||
| 447 | demandTableGuid: [ | ||
| 448 | { required: true, message: '请选择需求表', trigger: 'change' } | ||
| 449 | ], | ||
| 450 | weight: [ | ||
| 451 | { required: true, message: '请填写权重', trigger: 'change' }, | ||
| 452 | { | ||
| 453 | validator: (rule: any, value: any, callback: any) => { | ||
| 454 | if (!value) { | ||
| 455 | callback(new Error("请填写权重")); | ||
| 456 | } else { | ||
| 457 | if (drawerInfo.value.type.indexOf('edit') > -1 && currTableData.value.weight == value) { | ||
| 458 | callback(); | ||
| 459 | return | ||
| 460 | } | ||
| 461 | setTimeout(() => { | ||
| 462 | let formula: any = []; | ||
| 463 | if (drawerInfo.value.type.indexOf('edit') > -1) { | ||
| 464 | formula = currSignatoryData.value.tableInfo.data.map(p => p.targetName == currTableData.value.targetName ? value : p.weight || 0); | ||
| 465 | } else { | ||
| 466 | formula = currSignatoryData.value.tableInfo.data.map(p => p.weight || 0); | ||
| 467 | formula.push(value); | ||
| 468 | } | ||
| 469 | const isOver = formula.reduce((accumulator, currentValue) => parseFloat(accumulator) + parseFloat(currentValue), 0); // 初始值为0 | ||
| 470 | if (isOver > 100) { | ||
| 471 | callback(new Error("该维度权重和已超过100%,请重新填写")); | ||
| 472 | } else { | ||
| 473 | callback(); | ||
| 474 | } | ||
| 475 | }, 200); | ||
| 476 | } | ||
| 477 | }, | ||
| 478 | trigger: "blur", | ||
| 479 | }, | ||
| 480 | ], | ||
| 481 | defaultValue: [ | ||
| 482 | { required: true, message: '请填写默认值', trigger: 'blur' } | ||
| 483 | ], | ||
| 484 | }); | ||
| 485 | |||
| 486 | const dictionaryType = ref(''); | ||
| 487 | const showFactorTable = ref(false); | ||
| 488 | const mergeRowCount: any = ref({}); | ||
| 489 | const rowCount = { | ||
| 490 | level: { index: 0, rowspan: [] }, | ||
| 491 | }; | ||
| 492 | const mergeTableData = [ | ||
| 493 | { id: '1-1', level: '一级', grade: '甲等', factor: '' }, | ||
| 494 | { id: '1-2', level: '一级', grade: '乙等', factor: '' }, | ||
| 495 | { id: '1-3', level: '一级', grade: '丙等', factor: '' }, | ||
| 496 | { id: '2-1', level: '二级', grade: '甲等', factor: '' }, | ||
| 497 | { id: '2-2', level: '二级', grade: '乙等', factor: '' }, | ||
| 498 | { id: '2-3', level: '二级', grade: '丙等', factor: '' }, | ||
| 499 | { id: '3-1', level: '三级', grade: '甲等', factor: '' }, | ||
| 500 | { id: '3-2', level: '三级', grade: '乙等', factor: '' }, | ||
| 501 | { id: '3-3', level: '三级', grade: '丙等', factor: '' }, | ||
| 502 | ]; | ||
| 503 | const tableData: any = ref([]); | ||
| 504 | |||
| 505 | // 抽屉内容 | ||
| 506 | const contents = ref({ | ||
| 507 | target: { | ||
| 508 | type: "form", | ||
| 509 | title: "", | ||
| 510 | col: "span", | ||
| 511 | formInfo: { | ||
| 512 | id: "add-dict-form", | ||
| 513 | readonly: false, | ||
| 514 | items: targetFormItems.value, | ||
| 515 | rules: targetFormRules.value, | ||
| 516 | }, | ||
| 517 | }, | ||
| 518 | signatory: { | ||
| 519 | type: "form", | ||
| 520 | title: "", | ||
| 521 | col: "span", | ||
| 522 | formInfo: { | ||
| 523 | id: "add-dict-form", | ||
| 524 | readonly: false, | ||
| 525 | items: signatoryFormItems.value, | ||
| 526 | rules: signatoryFormRules.value, | ||
| 527 | }, | ||
| 528 | } | ||
| 529 | }) | ||
| 530 | const drawerInfo: any = ref({ | ||
| 531 | visible: false, | ||
| 532 | direction: "rtl", | ||
| 533 | size: 480, | ||
| 534 | header: { | ||
| 535 | title: "新增", | ||
| 536 | }, | ||
| 537 | type: "", | ||
| 538 | container: { | ||
| 539 | contents: [], | ||
| 540 | }, | ||
| 541 | footer: { | ||
| 542 | visible: true, | ||
| 543 | btns: [ | ||
| 544 | { type: "default", label: "取消", value: "cancel" }, | ||
| 545 | { type: "primary", label: "保存", value: "submit" }, | ||
| 546 | ], | ||
| 547 | }, | ||
| 548 | }); | ||
| 549 | |||
| 550 | const setTableField = (data) => { | ||
| 551 | tableData.value = []; | ||
| 552 | const dictionaryName = typeMap.value['dictionaryType'].find(item => item.value == dictionaryType.value)?.label || ''; | ||
| 553 | const dictionaryJson = dictionaryName && dictionaryName == currTableData.value.dictionaryName ? (currTableData.value.dictionaryJson || []) : []; | ||
| 554 | if (dictionaryType.value == '1') { | ||
| 555 | const tData = JSON.parse(JSON.stringify(mergeTableData)); | ||
| 556 | if (dictionaryJson.length) { | ||
| 557 | tData.map((item, i) => { | ||
| 558 | item.factor = dictionaryJson[i]?.value || ''; | ||
| 559 | }) | ||
| 560 | } | ||
| 561 | tableData.value = tData; | ||
| 562 | getMergeRow(); | ||
| 563 | } else { | ||
| 564 | if (dictionaryJson.length) { | ||
| 565 | dictionaryJson.map(item => { | ||
| 566 | tableData.value.push({ | ||
| 567 | label: item.name, | ||
| 568 | factor: item.value || '', | ||
| 569 | }) | ||
| 570 | }) | ||
| 571 | } else { | ||
| 572 | data.map((item: any) => { | ||
| 573 | tableData.value.push({ | ||
| 574 | label: item.label, | ||
| 575 | factor: '', | ||
| 576 | }) | ||
| 577 | }) | ||
| 578 | } | ||
| 579 | } | ||
| 580 | } | ||
| 581 | |||
| 582 | const getDictionaryRuleData = () => { | ||
| 583 | const dictType: any = typeMap.value['dictionaryType'].find(item => item.value == dictionaryType.value)?.label || ''; | ||
| 584 | getAllFlowData({ dictType }).then((res: any) => { | ||
| 585 | if (res.code == proxy.$passCode) { | ||
| 586 | const data = res.data || []; | ||
| 587 | setTableField(data); | ||
| 588 | } else { | ||
| 589 | proxy.$ElMessage.error(res.msg); | ||
| 590 | } | ||
| 591 | }) | ||
| 592 | } | ||
| 593 | |||
| 594 | // 设置表单信息 | ||
| 595 | const setFormItems = (info = null, type = '') => { | ||
| 596 | const datas: any = info || flowDetail.value || {}; | ||
| 597 | if (type == 'target') { | ||
| 598 | targetFormItems.value.map(item => { | ||
| 599 | item.default = datas[item.field] || ''; | ||
| 600 | if (item.field == 'functionName') { | ||
| 601 | item.visible = datas.targetType == '2' | ||
| 602 | } else if (item.field == 'dictionaryType') { | ||
| 603 | dictionaryType.value = datas[item.field] || ''; | ||
| 604 | item.visible = datas.targetType == '3' | ||
| 605 | showFactorTable.value = datas.targetType == '3' && datas[item.field] | ||
| 606 | showFactorTable.value && getDictionaryRuleData(); | ||
| 607 | } else if (item.field == 'formulaSetting') { | ||
| 608 | item.visible = datas.targetType == '2' && datas.functionName == '2' | ||
| 609 | } else if (item.field == 'demandTableGuid') { | ||
| 610 | item.visible = datas.targetType == '2' && datas.functionName == '3' | ||
| 611 | } else if (item.field == 'isShow' || item.field == 'isInputParameter') { | ||
| 612 | item.default = datas[item.field] || 'Y'; | ||
| 613 | } else if (item.field == 'isShow') { | ||
| 614 | item.disabled = datas.targetType == '1' | ||
| 615 | } else if (item.field == 'defaultValue') { | ||
| 616 | item.required = datas.targetType == '1'; | ||
| 617 | targetFormRules.value.defaultValue[0].required = datas.targetType == '1'; | ||
| 618 | } | ||
| 619 | }) | ||
| 620 | } else if (type == 'signatory') { | ||
| 621 | signatoryFormItems.value.map(item => { | ||
| 622 | if (item.field == 'invocationStatus') { | ||
| 623 | item.default = datas[item.field] || 'Y'; | ||
| 624 | } else if (item.field == 'customize') { | ||
| 625 | item.default = datas[item.field] || ''; | ||
| 626 | item.visible = datas.computationalFormula == 'custom' | ||
| 627 | } else { | ||
| 628 | item.default = datas[item.field] || ''; | ||
| 629 | } | ||
| 630 | }) | ||
| 631 | } else { | ||
| 632 | baseConfigFormItems.value.map(item => { | ||
| 633 | if (item.field == 'modelFormula') { | ||
| 634 | item.default = datas[item.field] || ''; | ||
| 635 | } else { | ||
| 636 | item.default = datas[item.field] || ''; | ||
| 637 | } | ||
| 638 | }) | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | // 过滤 | ||
| 643 | const setVal = (type, row) => { | ||
| 644 | let formulaText = ''; | ||
| 645 | if (!row[type] || row[type] == 'custom') { | ||
| 646 | formulaText = row.customize; | ||
| 647 | } else { | ||
| 648 | const pricingTargetData = row.pricingTargetRSVOS || row.tableInfo?.data || []; | ||
| 649 | let formula: any = []; | ||
| 650 | if (pricingTargetData.length) { | ||
| 651 | pricingTargetData.map(item => { | ||
| 652 | if (row[type] == '1') { | ||
| 653 | formula.push(`${item.targetName}*${item.weight}%`) | ||
| 654 | } else { | ||
| 655 | formula.push(`${item.targetName}`) | ||
| 656 | } | ||
| 657 | }) | ||
| 658 | if (row[type] == '3') { | ||
| 659 | formulaText = `公式=${formula.join('*')}`; | ||
| 660 | } else { | ||
| 661 | formulaText = `公式=${formula.join('+')}`; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | } | ||
| 665 | row.customize = formulaText; | ||
| 666 | pricingDimensionality.value.find(item => { | ||
| 667 | if (item.dimensionalityName == row.dimensionalityName) { | ||
| 668 | item.customize = formulaText; | ||
| 669 | } | ||
| 670 | }) | ||
| 671 | return formulaText; | ||
| 672 | }; | ||
| 673 | |||
| 674 | /** | ||
| 675 | * 传入多个promise对象,当全部结束时取消Loading | ||
| 676 | * @param promises 传入多个promise对象,当全部结束时取消Loading | ||
| 677 | */ | ||
| 678 | const promiseList = (...promises: Promise<void>[]) => { | ||
| 679 | // loading方法全局封装成一个组件 | ||
| 680 | loading.value = true; | ||
| 681 | try { | ||
| 682 | Promise.all(promises).then(res => { | ||
| 683 | if (guid) { | ||
| 684 | setFormItems(); | ||
| 685 | setSignatoryData(); | ||
| 686 | } | ||
| 687 | }); | ||
| 688 | } catch (e) { | ||
| 689 | loading.value = false; | ||
| 690 | } finally { | ||
| 691 | loading.value = false; | ||
| 692 | } | ||
| 693 | }; | ||
| 694 | |||
| 695 | // 获取数据字典 | ||
| 696 | const getDataType = (dictType, fieldName) => { | ||
| 697 | return getAllFlowData({ dictType }).then((res: any) => { | ||
| 698 | if (res.code == proxy.$passCode) { | ||
| 699 | const data = res.data || []; | ||
| 700 | if (fieldName == 'computationalFormula') { | ||
| 701 | data.push({ label: '自定义', value: 'custom' }) | ||
| 702 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 703 | let item = signatoryFormItems.value.find(item => item.field == fieldName); | ||
| 704 | item && (item.options = data); | ||
| 705 | } else { | ||
| 706 | typeMap.value[fieldName] = JSON.parse(JSON.stringify(data)); | ||
| 707 | if (fieldName == 'institutionType') { | ||
| 708 | let item = baseConfigFormItems.value.find(item => item.field == fieldName); | ||
| 709 | item && (item.options = data); | ||
| 710 | } else { | ||
| 711 | let item = targetFormItems.value.find(item => item.field == fieldName); | ||
| 712 | item && (item.options = data); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | } else { | ||
| 716 | proxy.$ElMessage.error(res.msg); | ||
| 717 | } | ||
| 718 | }) | ||
| 719 | } | ||
| 720 | |||
| 721 | // 初始化维度表格信息 | ||
| 722 | const setSignatoryTableInfo = (row, isEdit = false) => { | ||
| 723 | const pricingTarget = row.pricingTargetRSVOS || []; | ||
| 724 | const fieldList: any = [ | ||
| 725 | { label: "指标名称", field: "targetName", width: 200 }, | ||
| 726 | { | ||
| 727 | label: "指标类型", field: "targetType", width: 120, getName: (scope) => { | ||
| 728 | return typeMap.value['targetType'].find(item => item.value == scope.row.targetType)?.label || '--'; | ||
| 729 | } | ||
| 730 | }, | ||
| 731 | { | ||
| 732 | label: "默认值", field: "defaultValue", width: 180, align: 'right', getName: (scope) => { | ||
| 733 | return changeNum(scope.row.defaultValue, 2) || '-' | ||
| 734 | } | ||
| 735 | }, | ||
| 736 | { | ||
| 737 | label: "是否展示", field: "isShow", width: 100, getName: (scope) => { | ||
| 738 | return scope.row.isShow == 'Y' ? '是' : '否'; | ||
| 739 | } | ||
| 740 | }, | ||
| 741 | { | ||
| 742 | label: "是否输入参数", field: "isInputParameter", width: 140, getName: (scope) => { | ||
| 743 | return scope.row.isInputParameter == 'Y' ? '是' : '否'; | ||
| 744 | } | ||
| 745 | } | ||
| 746 | ]; | ||
| 747 | row.computationalFormula == '1' && fieldList.splice(2, 0, { label: "权重(%)", field: "weight", width: 100 }); | ||
| 748 | if (isEdit) { | ||
| 749 | const rIndex = signatoryTableList.value.findIndex(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 750 | rIndex != -1 && signatoryTableList.value.splice(rIndex, 1, { ...currSignatoryData.value, ...row, tableInfo: { ...currSignatoryData.value.tableInfo, fields: fieldList } }); | ||
| 751 | const sIndex = pricingDimensionality.value.findIndex(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 752 | sIndex != -1 && pricingDimensionality.value.splice(sIndex, 1, { ...currSignatoryData.value, ...row, tableInfo: { ...currSignatoryData.value.tableInfo, fields: fieldList } }); | ||
| 753 | } else { | ||
| 754 | const tData = { | ||
| 755 | id: `signatory-${signatoryTableList.value.length}`, | ||
| 756 | rowKey: '', | ||
| 757 | fields: fieldList, | ||
| 758 | data: pricingTarget, | ||
| 759 | showPage: false, | ||
| 760 | actionInfo: { | ||
| 761 | label: "操作", | ||
| 762 | type: "btn", | ||
| 763 | width: 120, | ||
| 764 | btns: [ | ||
| 765 | { label: "编辑", value: "edit" }, | ||
| 766 | { label: "删除", value: "del" } | ||
| 767 | ] | ||
| 768 | } | ||
| 769 | }; | ||
| 770 | signatoryTableList.value.push({ | ||
| 771 | ...row, | ||
| 772 | tableInfo: tData | ||
| 773 | }); | ||
| 774 | } | ||
| 775 | } | ||
| 776 | |||
| 777 | // 设置维度指标数据 | ||
| 778 | const setSignatoryData = () => { | ||
| 779 | const pricingData = flowDetail.value.pricingDimensionalityRSVOS || []; | ||
| 780 | pricingDimensionality.value = pricingData; | ||
| 781 | pricingData.map(item => { | ||
| 782 | const rows = item; | ||
| 783 | (() => { | ||
| 784 | setSignatoryTableInfo(rows); | ||
| 785 | })() | ||
| 786 | }) | ||
| 787 | } | ||
| 788 | |||
| 789 | // 获取详情 | ||
| 790 | const getModelDetail = () => { | ||
| 791 | loading.value = true; | ||
| 792 | getConfigureDetail({ guid }).then((res: any) => { | ||
| 793 | if (res.code == proxy.$passCode) { | ||
| 794 | const data = res.data || {}; | ||
| 795 | flowDetail.value = data; | ||
| 796 | getDataTypeList() | ||
| 797 | } | ||
| 798 | }).catch(() => { | ||
| 799 | loading.value = false; | ||
| 800 | }) | ||
| 801 | } | ||
| 802 | |||
| 803 | const getDataTypeList = () => { | ||
| 804 | promiseList( | ||
| 805 | getTreeData(), | ||
| 806 | getDataType('机构类型', 'institutionType'), | ||
| 807 | getDataType('维度计算公式', 'computationalFormula'), | ||
| 808 | getDataType('维度指标类型', 'targetType'), | ||
| 809 | getDataType('系统功能', 'functionName'), | ||
| 810 | getDataType('选择字典', 'dictionaryType'), | ||
| 811 | ) | ||
| 812 | } | ||
| 813 | |||
| 814 | // 获取需求表树形数据 | ||
| 815 | const getTreeData = () => { | ||
| 816 | return getDemandTreeList({ pageIndex: 1, pageSize: 100000, isCatalog: 'N' }).then((res: any) => { | ||
| 817 | if (res.code == proxy.$passCode) { | ||
| 818 | const data = res.data?.records || []; | ||
| 819 | treeData.value = JSON.parse(JSON.stringify(data)); | ||
| 820 | const item = targetFormItems.value.find(item => item.field == 'demandTableGuid'); | ||
| 821 | item && (item.options = data); | ||
| 822 | } else { | ||
| 823 | proxy.$ElMessage.error(res.msg); | ||
| 824 | } | ||
| 825 | }) | ||
| 826 | } | ||
| 827 | |||
| 828 | const selectChange = async (val, row, info) => { | ||
| 829 | if (row.field == 'computationalFormula') { | ||
| 830 | setFormItems(info, 'signatory'); | ||
| 831 | } else if (row.field == 'targetType' || row.field == 'dictionaryType' || row.field == 'functionName') { | ||
| 832 | const tInfo = { ...currTableData.value, ...info }; | ||
| 833 | await setFormItems(tInfo, 'target'); | ||
| 834 | if (row.field == 'targetType') { | ||
| 835 | targetFormItems.value[3].default = val == '1' ? 'N' : 'Y'; | ||
| 836 | } | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 840 | const inputChange = (val, scope, field) => { | ||
| 841 | let row = scope.row; | ||
| 842 | let strArr = val.split("."); | ||
| 843 | if (strArr.length > 1) { | ||
| 844 | let right = strArr[1]; | ||
| 845 | if (right === "" || right.length < 3) { | ||
| 846 | row[field] = val = parseFloat(val || 0).toFixed(3); | ||
| 847 | } | ||
| 848 | } else { | ||
| 849 | row[field] = val = parseFloat(val || 0).toFixed(3); | ||
| 850 | } | ||
| 851 | } | ||
| 852 | |||
| 853 | /** 输入框输入触发事件 */ | ||
| 854 | const inputEventChange = (val, scope, field) => { | ||
| 855 | let row = scope.row; | ||
| 856 | row[field] = row[field].toString().replace(/[^\d.]/g, "") | ||
| 857 | row[field] = row[field].toString().replace(/\.{2,}/g, ".") | ||
| 858 | row[field] = row[field].toString().replace(".", "$#$").replace(/\./g, "").replace("$#$", ".") | ||
| 859 | row[field] = row[field].toString().replace(/^(\-)*(\d+)\.(\d\d\d\d\d\d).*$/, "$1$2.$3") | ||
| 860 | row[field] = row[field].toString().replace(/^\D*(\d{0,12}(?:\.\d{0,3})?).*$/g, "$1") | ||
| 861 | } | ||
| 862 | |||
| 863 | // 设置表格合并下标 | ||
| 864 | const getMergeRow = () => { | ||
| 865 | mergeRowCount.value = JSON.parse(JSON.stringify(rowCount)); | ||
| 866 | let list = tableData.value; | ||
| 867 | for (var i = 0; i < list.length; i++) { | ||
| 868 | if (i === 0) { | ||
| 869 | //第一个数据 默认合并1行,开始位置下标默认为0 | ||
| 870 | for (var m in mergeRowCount.value) { | ||
| 871 | mergeRowCount.value[m].rowspan.push(1); | ||
| 872 | mergeRowCount.value[m].index = 0; | ||
| 873 | } | ||
| 874 | } else { | ||
| 875 | // 根据拥有子级数量进行合并1 | ||
| 876 | for (var m in mergeRowCount.value) { | ||
| 877 | let mergeRow = mergeRowCount.value[m]; | ||
| 878 | if (list[i][m] && list[i][m] === list[i - 1][m]) { | ||
| 879 | mergeRow.rowspan[mergeRow.index] += 1; | ||
| 880 | mergeRow.rowspan.push(0); | ||
| 881 | } else { | ||
| 882 | mergeRow.rowspan.push(1); | ||
| 883 | mergeRow.index = i; | ||
| 884 | } | ||
| 885 | } | ||
| 886 | } | ||
| 887 | } | ||
| 888 | } | ||
| 889 | // 表格行合并 | ||
| 890 | const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => { | ||
| 891 | if (columnIndex === 0) { | ||
| 892 | const mergeInfo = mergeRowCount.value.level; | ||
| 893 | const rowspan = mergeInfo.rowspan[rowIndex]; | ||
| 894 | if (rowspan > 0) { | ||
| 895 | return { | ||
| 896 | rowspan, | ||
| 897 | colspan: 1, | ||
| 898 | }; | ||
| 899 | } else { | ||
| 900 | return { | ||
| 901 | rowspan: 0, | ||
| 902 | colspan: 0, | ||
| 903 | }; | ||
| 904 | } | ||
| 905 | } | ||
| 906 | } | ||
| 907 | |||
| 908 | const toPath = () => { | ||
| 909 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 910 | assetStore.set(true); | ||
| 911 | router.push({ | ||
| 912 | name: 'priceConfig', | ||
| 913 | }) | ||
| 914 | } | ||
| 915 | |||
| 916 | const switchChange = (val, index) => { | ||
| 917 | pricingDimensionality.value[index].invocationStatus = val; | ||
| 918 | } | ||
| 919 | |||
| 920 | const btnClick = async (btn, row: any = null) => { | ||
| 921 | const type = btn.value; | ||
| 922 | if (type == 'dim') { | ||
| 923 | const baseConfigFormObj = baseConfigFormRef.value; | ||
| 924 | const baseConfigFormEl = baseConfigFormObj.ruleFormRef; | ||
| 925 | const baseConfigFormInfo = baseConfigFormObj.formInline; | ||
| 926 | await setFormItems(baseConfigFormInfo); | ||
| 927 | baseConfigFormItems.value.at(-1).default = baseConfigFormInfo.modelFormula ? `${baseConfigFormInfo.modelFormula}"${row.dimensionalityName}"` : `"${row.dimensionalityName}"`; | ||
| 928 | // 触发校验 | ||
| 929 | setTimeout(() => { | ||
| 930 | baseConfigFormEl.validateField('modelFormula'); | ||
| 931 | }, 200); | ||
| 932 | } else if (type == 'add-target') { | ||
| 933 | currSignatoryData.value = row; | ||
| 934 | currTableData.value = {}; | ||
| 935 | const tData = currSignatoryData.value.tableInfo.data; | ||
| 936 | await setFormItems(null, 'target'); | ||
| 937 | drawerInfo.value.type = type; | ||
| 938 | drawerInfo.value.header.title = '新增指标'; | ||
| 939 | targetFormItems.value[2].visible = row.computationalFormula == '1'; | ||
| 940 | targetFormItems.value.at(-2).options.map(o => { | ||
| 941 | const fData = tData.filter(t => t.targetType == '2' && t.functionName == '3'); | ||
| 942 | o.disabled = fData.find(f => f.demandTableGuid == o.guid) ? true : false; | ||
| 943 | }); | ||
| 944 | drawerInfo.value.container.contents[0] = contents.value.target; | ||
| 945 | tableData.value = []; | ||
| 946 | drawerInfo.value.visible = true; | ||
| 947 | } else if (type == 'add-signatory') { | ||
| 948 | currSignatoryData.value = {}; | ||
| 949 | currTableData.value = {}; | ||
| 950 | showFactorTable.value = false; | ||
| 951 | await setFormItems(null, 'signatory'); | ||
| 952 | drawerInfo.value.type = type; | ||
| 953 | drawerInfo.value.header.title = '新增维度'; | ||
| 954 | drawerInfo.value.container.contents[0] = contents.value.signatory; | ||
| 955 | drawerInfo.value.visible = true; | ||
| 956 | } else if (type == 'edit-signatory') { | ||
| 957 | currSignatoryData.value = row; | ||
| 958 | currTableData.value = {}; | ||
| 959 | showFactorTable.value = false; | ||
| 960 | await setFormItems(row, 'signatory'); | ||
| 961 | drawerInfo.value.type = type; | ||
| 962 | drawerInfo.value.header.title = '编辑维度'; | ||
| 963 | drawerInfo.value.container.contents[0] = contents.value.signatory; | ||
| 964 | drawerInfo.value.visible = true; | ||
| 965 | } else if (type == 'del-signatory') { | ||
| 966 | currSignatoryData.value = row; | ||
| 967 | open('确定要删除该条维度数据吗?', 'warning', 'signatory'); | ||
| 968 | } else if (type == 'submit') { | ||
| 969 | const baseConfigFormObj = baseConfigFormRef.value; | ||
| 970 | const baseConfigFormEl = baseConfigFormObj.ruleFormRef; | ||
| 971 | const baseConfigFormInfo = baseConfigFormObj.formInline; | ||
| 972 | baseConfigFormEl.validate((valid, errorItem) => { | ||
| 973 | if (valid) { | ||
| 974 | const pricingDimensionalityData = pricingDimensionality.value.map((item, i) => { | ||
| 975 | item.orderNum = i + 1; | ||
| 976 | const pricingTargetData = item.pricingTargetRSVOS || item.pricingTargetRQVOS || []; | ||
| 977 | item.pricingTargetRQVOS = pricingTargetData.map((targetItem, t) => { | ||
| 978 | targetItem.orderNum = t + 1; | ||
| 979 | delete targetItem.tableInfo; | ||
| 980 | return targetItem; | ||
| 981 | }) | ||
| 982 | delete item.pricingTargetRSVOS; | ||
| 983 | return item; | ||
| 984 | }) | ||
| 985 | loading.value = true; | ||
| 986 | let params = { | ||
| 987 | ...baseConfigFormInfo, | ||
| 988 | tenantGuid: userData.tenantGuid, | ||
| 989 | pricingDimensionalityRQVOS: pricingDimensionalityData, | ||
| 990 | }; | ||
| 991 | if (guid) { | ||
| 992 | params.guid = guid | ||
| 993 | updateConfigure(params).then((res: any) => { | ||
| 994 | loading.value = false; | ||
| 995 | if (res.code == proxy.$passCode) { | ||
| 996 | ElMessage({ | ||
| 997 | type: "success", | ||
| 998 | message: guid ? "编辑定价配置成功" : "新增定价配置成功", | ||
| 999 | }); | ||
| 1000 | toPath() | ||
| 1001 | } else { | ||
| 1002 | proxy.$ElMessage.error(res.msg); | ||
| 1003 | } | ||
| 1004 | }).catch(() => { | ||
| 1005 | loading.value = false; | ||
| 1006 | }); | ||
| 1007 | } else { | ||
| 1008 | saveConfigure(params).then((res: any) => { | ||
| 1009 | loading.value = false; | ||
| 1010 | if (res.code == proxy.$passCode) { | ||
| 1011 | ElMessage({ | ||
| 1012 | type: "success", | ||
| 1013 | message: guid ? "编辑定价配置成功" : "新增定价配置成功", | ||
| 1014 | }); | ||
| 1015 | toPath() | ||
| 1016 | } else { | ||
| 1017 | proxy.$ElMessage.error(res.msg); | ||
| 1018 | } | ||
| 1019 | }).catch(() => { | ||
| 1020 | loading.value = false; | ||
| 1021 | }); | ||
| 1022 | } | ||
| 1023 | } else { | ||
| 1024 | expand1.value = true; | ||
| 1025 | var obj = Object.keys(errorItem); | ||
| 1026 | baseConfigFormEl.scrollToField(obj[0]); | ||
| 1027 | } | ||
| 1028 | }); | ||
| 1029 | } else if (type == 'cancel') { | ||
| 1030 | ElMessageBox.confirm( | ||
| 1031 | "当前页面尚未保存,确定关闭吗?", | ||
| 1032 | "提示", | ||
| 1033 | { | ||
| 1034 | confirmButtonText: "确定", | ||
| 1035 | cancelButtonText: "取消", | ||
| 1036 | type: "warning", | ||
| 1037 | } | ||
| 1038 | ).then(() => { | ||
| 1039 | toPath() | ||
| 1040 | }).catch(() => { | ||
| 1041 | ElMessage({ | ||
| 1042 | type: "info", | ||
| 1043 | message: "已取消", | ||
| 1044 | }); | ||
| 1045 | }); | ||
| 1046 | } | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | const tableBtnClick = async (scope, btn, lData: any = null) => { | ||
| 1050 | const type = btn.value; | ||
| 1051 | const row = scope.row; | ||
| 1052 | currTableData.value = row; | ||
| 1053 | if (type === 'edit') { // 编辑 | ||
| 1054 | currSignatoryData.value = lData; | ||
| 1055 | const tData = currSignatoryData.value.tableInfo.data; | ||
| 1056 | await setFormItems(row, 'target'); | ||
| 1057 | drawerInfo.value.type = 'edit-target'; | ||
| 1058 | drawerInfo.value.header.title = '编辑指标'; | ||
| 1059 | targetFormItems.value[2].visible = lData.computationalFormula == '1'; | ||
| 1060 | targetFormItems.value.at(-2).options.map(o => { | ||
| 1061 | const fData = tData.filter(t => t.targetType == '2' && t.functionName == '3'); | ||
| 1062 | o.disabled = fData.find(f => f.demandTableGuid == o.guid) ? true : false; | ||
| 1063 | }); | ||
| 1064 | drawerInfo.value.container.contents[0] = contents.value.target; | ||
| 1065 | drawerInfo.value.visible = true; | ||
| 1066 | } else if (type === 'del') { // 删除 | ||
| 1067 | currSignatoryData.value = lData; | ||
| 1068 | open('确定要删除该条数据吗?', 'warning', 'target'); | ||
| 1069 | } | ||
| 1070 | }; | ||
| 1071 | |||
| 1072 | |||
| 1073 | const open = (msg, type, target) => { | ||
| 1074 | ElMessageBox.confirm(msg, "提示", { | ||
| 1075 | confirmButtonText: "确定", | ||
| 1076 | cancelButtonText: "取消", | ||
| 1077 | type: type, | ||
| 1078 | }).then(() => { | ||
| 1079 | if (target == 'signatory') { | ||
| 1080 | const tIndex = signatoryTableList.value.findIndex(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1081 | tIndex != -1 && signatoryTableList.value.splice(tIndex, 1); | ||
| 1082 | const sIndex = pricingDimensionality.value.findIndex(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1083 | sIndex != -1 && pricingDimensionality.value.splice(sIndex, 1); | ||
| 1084 | } else if (target == 'target') { | ||
| 1085 | const signatoryRow = signatoryTableList.value.find(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1086 | if (signatoryRow) { | ||
| 1087 | const tIndex = signatoryRow.tableInfo.data.findIndex(t => t.targetName == currTableData.value.targetName); | ||
| 1088 | tIndex != -1 && signatoryRow.tableInfo.data.splice(tIndex, 1); | ||
| 1089 | } | ||
| 1090 | const signatoryParams = pricingDimensionality.value.find(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1091 | if (signatoryParams) { | ||
| 1092 | const sIndex = signatoryParams.pricingTargetRSVOS.findIndex(s => s.targetName == currTableData.value.targetName); | ||
| 1093 | sIndex != -1 && signatoryParams.pricingTargetRSVOS.splice(sIndex, 1); | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | }); | ||
| 1097 | }; | ||
| 1098 | const drawerBtnClick = async (btn, info) => { | ||
| 1099 | if (btn.value == "submit") { | ||
| 1100 | let params = { ...info }; | ||
| 1101 | if (drawerInfo.value.type == 'add-signatory') {// 新增维度 | ||
| 1102 | setSignatoryTableInfo(params); | ||
| 1103 | pricingDimensionality.value.push({ | ||
| 1104 | ...params, | ||
| 1105 | pricingTargetRSVOS: [] | ||
| 1106 | }) | ||
| 1107 | } else if (drawerInfo.value.type == 'edit-signatory') {// 编辑维度 | ||
| 1108 | setSignatoryTableInfo(params, true); | ||
| 1109 | } else if (drawerInfo.value.type == 'add-target') {// 新增指标 | ||
| 1110 | let factorFull = true; | ||
| 1111 | const dictionaryData = tableData.value.map((d: any) => { | ||
| 1112 | if (dictionaryType.value && !d.factor) { | ||
| 1113 | factorFull = false; | ||
| 1114 | } | ||
| 1115 | if (dictionaryType.value == '1') { | ||
| 1116 | return { name: `${d.level}${d.grade}`, value: d.factor || '' } | ||
| 1117 | } else { | ||
| 1118 | return { name: `${d.label}`, value: d.factor || '' } | ||
| 1119 | } | ||
| 1120 | }) | ||
| 1121 | if (dictionaryType.value && !factorFull) { | ||
| 1122 | ElMessage({ | ||
| 1123 | type: "error", | ||
| 1124 | message: '请完善字典因子', | ||
| 1125 | }); | ||
| 1126 | return; | ||
| 1127 | } | ||
| 1128 | const dictionaryName = typeMap.value['dictionaryType'].find(item => item.value == params.dictionaryType)?.label || ''; | ||
| 1129 | const sArr = signatoryTableList.value.map(item => { | ||
| 1130 | if (item.dimensionalityName == currSignatoryData.value.dimensionalityName) { | ||
| 1131 | item.tableInfo.data.push({ ...params, dictionaryJson: dictionaryData, dictionaryName }); | ||
| 1132 | } | ||
| 1133 | return item; | ||
| 1134 | }) | ||
| 1135 | signatoryTableList.value = sArr; | ||
| 1136 | let signatoryParams = pricingDimensionality.value.find(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1137 | if (signatoryParams) { | ||
| 1138 | const sData = signatoryParams.pricingTargetRSVOS.find(s => s.targetName == params.targetName) | ||
| 1139 | !sData && signatoryParams.pricingTargetRSVOS.push({ ...params, dictionaryJson: dictionaryData, dictionaryName }) | ||
| 1140 | } | ||
| 1141 | } else if (drawerInfo.value.type == 'edit-target') {// 编辑指标 | ||
| 1142 | let factorFull = true; | ||
| 1143 | const dictionaryData = tableData.value.map((d: any) => { | ||
| 1144 | if (dictionaryType.value && !d.factor) { | ||
| 1145 | factorFull = false; | ||
| 1146 | } | ||
| 1147 | if (dictionaryType.value == '1') { | ||
| 1148 | return { name: `${d.level}${d.grade}`, value: d.factor || '' } | ||
| 1149 | } else { | ||
| 1150 | return { name: `${d.label}`, value: d.factor || '' } | ||
| 1151 | } | ||
| 1152 | }) | ||
| 1153 | if (dictionaryType.value && !factorFull) { | ||
| 1154 | ElMessage({ | ||
| 1155 | type: "error", | ||
| 1156 | message: '请完善字典因子', | ||
| 1157 | }); | ||
| 1158 | return; | ||
| 1159 | } | ||
| 1160 | const dictionaryName = typeMap.value['dictionaryType'].find(item => item.value == params.dictionaryType)?.label || ''; | ||
| 1161 | const sArr = signatoryTableList.value.map(item => { | ||
| 1162 | if (item.dimensionalityName == currSignatoryData.value.dimensionalityName) { | ||
| 1163 | const tIndex = item.tableInfo.data.findIndex(t => t.targetName == currTableData.value.targetName) | ||
| 1164 | tIndex != -1 && item.tableInfo.data.splice(tIndex, 1, { ...params, dictionaryJson: dictionaryData, dictionaryName }) | ||
| 1165 | } | ||
| 1166 | return item; | ||
| 1167 | }) | ||
| 1168 | signatoryTableList.value = sArr; | ||
| 1169 | let signatoryParams = pricingDimensionality.value.find(item => item.dimensionalityName == currSignatoryData.value.dimensionalityName); | ||
| 1170 | if (signatoryParams) { | ||
| 1171 | const sIndex = signatoryParams.pricingTargetRSVOS.findIndex(s => s.targetName == currTableData.value.targetName) | ||
| 1172 | sIndex != -1 && signatoryParams.pricingTargetRSVOS.splice(sIndex, 1, { ...params, dictionaryJson: dictionaryData, dictionaryName }) | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | drawerInfo.value.visible = false; | ||
| 1176 | } else { | ||
| 1177 | nextTick(() => { | ||
| 1178 | drawerInfo.value.visible = false; | ||
| 1179 | }); | ||
| 1180 | } | ||
| 1181 | }; | ||
| 1182 | |||
| 1183 | onActivated(() => { | ||
| 1184 | let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath); | ||
| 1185 | if (tab) { | ||
| 1186 | switch (route.query.type) { | ||
| 1187 | case 'create': | ||
| 1188 | tab.meta.title = `新增定价配置`; | ||
| 1189 | break; | ||
| 1190 | case 'edit': | ||
| 1191 | tab.meta.title = `编辑-${modelName}`; | ||
| 1192 | break; | ||
| 1193 | case 'detail': | ||
| 1194 | tab.meta.title = `详情-${modelName}`; | ||
| 1195 | break; | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | }) | ||
| 1199 | |||
| 1200 | onBeforeMount(() => { | ||
| 1201 | if (guid) { | ||
| 1202 | getModelDetail(); | ||
| 1203 | } else { | ||
| 1204 | getDataTypeList(); | ||
| 1205 | } | ||
| 1206 | }) | ||
| 1207 | |||
| 1208 | onMounted(() => { | ||
| 1209 | }) | ||
| 1210 | </script> | ||
| 1211 | |||
| 1212 | <template> | ||
| 1213 | <div class="container_wrap full" v-loading="loading"> | ||
| 1214 | <div class="content_main panel"> | ||
| 1215 | <ContentWrap id="contract-content-wrap" title="基础设置" expandSwicth style="margin-top: 15px" :isExpand="expand1" | ||
| 1216 | @expand="(v) => expand1 = v"> | ||
| 1217 | <Form ref="baseConfigFormRef" formId="contract-content-form" :itemList="baseConfigForm.items" | ||
| 1218 | :rules="baseConfigForm.rules" col="col3" /> | ||
| 1219 | <div class="signatory-tags" v-if="signatoryTableList.length"> | ||
| 1220 | <template v-for="(item, index) in signatoryTableList" :key="'tag_' + index"> | ||
| 1221 | <el-button v-if="item.invocationStatus == 'Y'" type="primary" @click="btnClick({ value: 'dim' }, item)">{{ | ||
| 1222 | item.dimensionalityName }}</el-button> | ||
| 1223 | </template> | ||
| 1224 | </div> | ||
| 1225 | <div class="tips-text" style="color: #666; margin-bottom: 4px; font-size: 12px;"> | ||
| 1226 | 备注:模型公式是维度名称与运算符组合,如("维度1"+"维度2")/("维度3"+"维度4")*10,维度名称要用英文引号(")包裹。维度名称在添加维度后才会在公式下展示! | ||
| 1227 | </div> | ||
| 1228 | </ContentWrap> | ||
| 1229 | <ContentWrap id="contract-signatory-wrap" title="维度设置" expandSwicth style="margin-top: 15px" :isExpand="expand2" | ||
| 1230 | @expand="(v) => expand2 = v"> | ||
| 1231 | <div class="table_panel_wrap" v-for="(item, index) in signatoryTableList" :key="'wrap_' + index"> | ||
| 1232 | <div class="table_tool"> | ||
| 1233 | <div class="tool_title"> | ||
| 1234 | <div class="title_text">{{ item.dimensionalityName }}</div> | ||
| 1235 | <div class="title_desc"><ellipsis-tooltip :content="setVal('computationalFormula', item)" | ||
| 1236 | refName="tooltipOver"></ellipsis-tooltip></div> | ||
| 1237 | </div> | ||
| 1238 | <div class="tool_btns"> | ||
| 1239 | <el-switch v-model="item.invocationStatus" inline-prompt active-value="Y" inactive-value="N" | ||
| 1240 | active-text="启用" inactive-text="停用" @change="val => switchChange(val, index)" | ||
| 1241 | style="margin-right: 8px;" /> | ||
| 1242 | <el-button type="primary" @click="btnClick({ value: 'edit-signatory' }, item)">编辑</el-button> | ||
| 1243 | <el-button @click="btnClick({ value: 'del-signatory' }, item)">删除</el-button> | ||
| 1244 | </div> | ||
| 1245 | </div> | ||
| 1246 | <div class="table_panel"> | ||
| 1247 | <Table :tableInfo="item.tableInfo" @tableBtnClick="(scope, btn) => tableBtnClick(scope, btn, item)" /> | ||
| 1248 | </div> | ||
| 1249 | <el-button type="primary" :icon="CirclePlus" link | ||
| 1250 | @click="btnClick({ value: 'add-target' }, item)">新增指标</el-button> | ||
| 1251 | </div> | ||
| 1252 | <el-button class="btn-block" plain size="large" @click="btnClick({ value: 'add-signatory' })">新增维度</el-button> | ||
| 1253 | </ContentWrap> | ||
| 1254 | </div> | ||
| 1255 | <div class="tool_btns"> | ||
| 1256 | <div class="btns"> | ||
| 1257 | <el-button @click="btnClick({ value: 'cancel' })">取消</el-button> | ||
| 1258 | <el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button> | ||
| 1259 | </div> | ||
| 1260 | </div> | ||
| 1261 | <Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" @drawerSelectChange="selectChange"> | ||
| 1262 | <template v-if="showFactorTable"> | ||
| 1263 | <span class="required_mark" style="line-height: 21px;">字典值对应因子</span> | ||
| 1264 | <div class="table_panel"> | ||
| 1265 | <el-table border :data="tableData" :span-method="tableSpanMethod" tooltip-effect="light" style="height: 100%;" | ||
| 1266 | v-if="dictionaryType == '1'"> | ||
| 1267 | <el-table-column label="医院等级"> | ||
| 1268 | <el-table-column prop="level" label="级别" width="100" /> | ||
| 1269 | <el-table-column prop="grade" label="等次" width="100" /> | ||
| 1270 | </el-table-column> | ||
| 1271 | <el-table-column prop="factor" label="因子" class-name="edit-col"> | ||
| 1272 | <template #default="scope"> | ||
| 1273 | <el-input v-model="scope.row.factor" placeholder="请输入" | ||
| 1274 | @change="(val) => inputChange(val, scope, 'factor')" | ||
| 1275 | @input="(val) => inputEventChange(val, scope, 'factor')" /> | ||
| 1276 | </template> | ||
| 1277 | </el-table-column> | ||
| 1278 | </el-table> | ||
| 1279 | <el-table border :data="tableData" tooltip-effect="light" style="height: 100%;" v-else> | ||
| 1280 | <el-table-column label="字典名称" prop="label" width="140" /> | ||
| 1281 | <el-table-column prop="factor" label="因子" class-name="edit-col"> | ||
| 1282 | <template #default="scope"> | ||
| 1283 | <el-input v-model="scope.row.factor" placeholder="请输入" | ||
| 1284 | @change="(val) => inputChange(val, scope, 'factor')" | ||
| 1285 | @input="(val) => inputEventChange(val, scope, 'factor')" /> | ||
| 1286 | </template> | ||
| 1287 | </el-table-column> | ||
| 1288 | </el-table> | ||
| 1289 | </div> | ||
| 1290 | </template> | ||
| 1291 | </Drawer> | ||
| 1292 | </div> | ||
| 1293 | </template> | ||
| 1294 | |||
| 1295 | <style scoped lang="scss"> | ||
| 1296 | .container_wrap { | ||
| 1297 | overflow: hidden; | ||
| 1298 | |||
| 1299 | .content_main { | ||
| 1300 | height: calc(100% - 45px); | ||
| 1301 | overflow: hidden auto; | ||
| 1302 | |||
| 1303 | &.panel { | ||
| 1304 | padding: 0 16px 16px; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | :deep(.el-card) { | ||
| 1308 | &#contract-signatory-wrap { | ||
| 1309 | .card-body-content { | ||
| 1310 | padding: 8px 16px; | ||
| 1311 | } | ||
| 1312 | } | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | .signatory-tags { | ||
| 1316 | margin-top: 2px; | ||
| 1317 | margin-bottom: 11px; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | .table_panel_wrap { | ||
| 1321 | margin-bottom: 4px; | ||
| 1322 | |||
| 1323 | .table_tool { | ||
| 1324 | height: 36px; | ||
| 1325 | display: flex; | ||
| 1326 | justify-content: space-between; | ||
| 1327 | align-items: center; | ||
| 1328 | |||
| 1329 | .tool_title { | ||
| 1330 | display: flex; | ||
| 1331 | justify-content: start; | ||
| 1332 | flex: 1; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | .title_text { | ||
| 1336 | font-weight: 600; | ||
| 1337 | margin-right: 8px; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | .title_desc { | ||
| 1341 | color: #b2b2b2; | ||
| 1342 | flex: 1; | ||
| 1343 | overflow: hidden; | ||
| 1344 | white-space: nowrap; | ||
| 1345 | text-overflow: ellipsis; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | .tool_btns { | ||
| 1349 | margin: 0; | ||
| 1350 | border: none; | ||
| 1351 | } | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | .table_panel { | ||
| 1355 | margin-bottom: 4px; | ||
| 1356 | height: 212px; | ||
| 1357 | } | ||
| 1358 | } | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | .btn-block { | ||
| 1362 | width: 100%; | ||
| 1363 | margin: 16px 0 8px; | ||
| 1364 | |||
| 1365 | } | ||
| 1366 | |||
| 1367 | .tool_btns { | ||
| 1368 | height: 44px; | ||
| 1369 | margin: 0 -8px; | ||
| 1370 | display: flex; | ||
| 1371 | justify-content: center; | ||
| 1372 | align-items: center; | ||
| 1373 | border-top: 1px solid #d9d9d9; | ||
| 1374 | } | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | :deep(.el-drawer) { | ||
| 1378 | .table_panel { | ||
| 1379 | th { | ||
| 1380 | text-align: center; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | .el-table__cell { | ||
| 1384 | &.edit-col { | ||
| 1385 | padding: 4px 0; | ||
| 1386 | |||
| 1387 | .cell { | ||
| 1388 | padding: 0 4px; | ||
| 1389 | |||
| 1390 | .el-input { | ||
| 1391 | height: 28px; | ||
| 1392 | } | ||
| 1393 | } | ||
| 1394 | } | ||
| 1395 | } | ||
| 1396 | } | ||
| 1397 | } | ||
| 1398 | </style> |
| ... | @@ -25,12 +25,13 @@ import { | ... | @@ -25,12 +25,13 @@ import { |
| 25 | getDatabase, | 25 | getDatabase, |
| 26 | getRuleTypeList | 26 | getRuleTypeList |
| 27 | } from '@/api/modules/dataQuality'; | 27 | } from '@/api/modules/dataQuality'; |
| 28 | import { getDamCatalogList } from '@/api/modules/dataPricing'; | ||
| 28 | import useDataQualityStore from "@/store/modules/dataQuality"; | 29 | import useDataQualityStore from "@/store/modules/dataQuality"; |
| 29 | import { useValidator } from '@/hooks/useValidator'; | 30 | import { useValidator } from '@/hooks/useValidator'; |
| 30 | import { TableColumnWidth } from '@/utils/enum'; | 31 | import { TableColumnWidth } from '@/utils/enum'; |
| 31 | 32 | ||
| 32 | const dataQualityStore = useDataQualityStore(); | 33 | const dataQualityStore = useDataQualityStore(); |
| 33 | 34 | const userData = JSON.parse(localStorage.userData); | |
| 34 | const { proxy } = getCurrentInstance() as any; | 35 | const { proxy } = getCurrentInstance() as any; |
| 35 | const { orderNum, description } = useValidator(); | 36 | const { orderNum, description } = useValidator(); |
| 36 | 37 | ||
| ... | @@ -39,6 +40,8 @@ const cacheStore = useCatchStore(); | ... | @@ -39,6 +40,8 @@ const cacheStore = useCatchStore(); |
| 39 | /** 可选择的质量规则列表。 */ | 40 | /** 可选择的质量规则列表。 */ |
| 40 | const ruleTypeList: any = ref([]); | 41 | const ruleTypeList: any = ref([]); |
| 41 | 42 | ||
| 43 | const productList: any = ref([]); | ||
| 44 | |||
| 42 | /** 质量规则集表对象。 */ | 45 | /** 质量规则集表对象。 */ |
| 43 | const qualityModelTreeRef = ref(); | 46 | const qualityModelTreeRef = ref(); |
| 44 | /** 树选中不同层级的,代表的类型, model, group, table */ | 47 | /** 树选中不同层级的,代表的类型, model, group, table */ |
| ... | @@ -281,7 +284,22 @@ const formItems: any = ref([ | ... | @@ -281,7 +284,22 @@ const formItems: any = ref([ |
| 281 | default: '', | 284 | default: '', |
| 282 | maxlength: 6, | 285 | maxlength: 6, |
| 283 | required: true | 286 | required: true |
| 284 | }, { | 287 | }, |
| 288 | { | ||
| 289 | label: '数据产品', | ||
| 290 | type: 'select', | ||
| 291 | field: 'damGuid', | ||
| 292 | default: '', | ||
| 293 | placeholder: '请选择', | ||
| 294 | options: productList.value, | ||
| 295 | props: { | ||
| 296 | value: 'guid', | ||
| 297 | label: 'damName' | ||
| 298 | }, | ||
| 299 | clearable: true, | ||
| 300 | filterable: true | ||
| 301 | }, | ||
| 302 | { | ||
| 285 | label: '描述', | 303 | label: '描述', |
| 286 | type: 'textarea', | 304 | type: 'textarea', |
| 287 | placeholder: '请输入', | 305 | placeholder: '请输入', |
| ... | @@ -929,6 +947,17 @@ onActivated(async () => { | ... | @@ -929,6 +947,17 @@ onActivated(async () => { |
| 929 | } | 947 | } |
| 930 | }) | 948 | }) |
| 931 | 949 | ||
| 950 | // 获取数据产品列表 | ||
| 951 | const getProducts = () => { | ||
| 952 | getDamCatalogList({ dataType: userData.superTubeFlag == 'Y' ? "P" : "D", sceneType: "Z" }).then((res: any) => { | ||
| 953 | if (res.code == proxy.$passCode) { | ||
| 954 | const data = res.data || []; | ||
| 955 | productList.value = data; | ||
| 956 | formItems.value.at(-2).options = data; | ||
| 957 | } | ||
| 958 | }) | ||
| 959 | } | ||
| 960 | |||
| 932 | onBeforeMount(() => { | 961 | onBeforeMount(() => { |
| 933 | getQualityGroupTreeData(); | 962 | getQualityGroupTreeData(); |
| 934 | getGroupTableData(); | 963 | getGroupTableData(); |
| ... | @@ -945,6 +974,7 @@ onBeforeMount(() => { | ... | @@ -945,6 +974,7 @@ onBeforeMount(() => { |
| 945 | ElMessage.error(res.msg); | 974 | ElMessage.error(res.msg); |
| 946 | } | 975 | } |
| 947 | }) | 976 | }) |
| 977 | getProducts(); | ||
| 948 | }) | 978 | }) |
| 949 | 979 | ||
| 950 | </script> | 980 | </script> | ... | ... |
| ... | @@ -18,7 +18,7 @@ import { | ... | @@ -18,7 +18,7 @@ import { |
| 18 | getImportData, | 18 | getImportData, |
| 19 | exportDictionary, | 19 | exportDictionary, |
| 20 | exportCollectTask, | 20 | exportCollectTask, |
| 21 | // getImageContent | 21 | exportTemplate |
| 22 | } from '@/api/modules/queryService'; | 22 | } from '@/api/modules/queryService'; |
| 23 | import { | 23 | import { |
| 24 | parseAndDecodeUrl, | 24 | parseAndDecodeUrl, |
| ... | @@ -29,6 +29,7 @@ import { | ... | @@ -29,6 +29,7 @@ import { |
| 29 | getDictionaryTree | 29 | getDictionaryTree |
| 30 | } from '@/api/modules/dataInventory'; | 30 | } from '@/api/modules/dataInventory'; |
| 31 | import { commonPageConfig } from '@/utils/enum'; | 31 | import { commonPageConfig } from '@/utils/enum'; |
| 32 | import { getDemandTreeList, getDiseaseAll } from '@/api/modules/dataPricing'; | ||
| 32 | 33 | ||
| 33 | const { proxy } = getCurrentInstance() as any; | 34 | const { proxy } = getCurrentInstance() as any; |
| 34 | 35 | ||
| ... | @@ -156,6 +157,29 @@ const getDictList = () => { | ... | @@ -156,6 +157,29 @@ const getDictList = () => { |
| 156 | }) | 157 | }) |
| 157 | } | 158 | } |
| 158 | 159 | ||
| 160 | // 获取需求表树形数据 | ||
| 161 | const getTreeData = () => { | ||
| 162 | if (isfileImport == '7') { | ||
| 163 | getDemandTreeList({ pageIndex: 1, pageSize: 100000, isCatalog: 'N' }).then((res: any) => { | ||
| 164 | if (res.code == proxy.$passCode) { | ||
| 165 | const data = res.data?.records || []; | ||
| 166 | dictionaryList.value = data; | ||
| 167 | } else { | ||
| 168 | proxy.$ElMessage.error(res.msg); | ||
| 169 | } | ||
| 170 | }) | ||
| 171 | } else { | ||
| 172 | getDiseaseAll().then((res: any) => { | ||
| 173 | if (res.code == proxy.$passCode) { | ||
| 174 | const data = res.data || []; | ||
| 175 | dictionaryList.value = data; | ||
| 176 | } else { | ||
| 177 | proxy.$ElMessage.error(res.msg); | ||
| 178 | } | ||
| 179 | }) | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 159 | const tabsChange = (name) => { | 183 | const tabsChange = (name) => { |
| 160 | tabsActiveName.value = name | 184 | tabsActiveName.value = name |
| 161 | let info: any = { | 185 | let info: any = { |
| ... | @@ -283,11 +307,16 @@ const batching = (type) => { | ... | @@ -283,11 +307,16 @@ const batching = (type) => { |
| 283 | } | 307 | } |
| 284 | open("此操作将永久删除, 是否继续?", "warning", true); | 308 | open("此操作将永久删除, 是否继续?", "warning", true); |
| 285 | } else if (type === 'importFile') { | 309 | } else if (type === 'importFile') { |
| 286 | if (isfileImport == '2' || isfileImport == '4') { | 310 | if (isfileImport == '2' || isfileImport == '4' || isfileImport == '7' || isfileImport == '8') { |
| 287 | dialogInfo.value.header.title = '导入数据' | 311 | dialogInfo.value.header.title = '导入数据' |
| 288 | dialogInfo.value.type = 'upload' | 312 | dialogInfo.value.type = 'upload' |
| 289 | dialogInfo.value.size = isfileImport == '4' ? 600 : 500; | 313 | dialogInfo.value.size = isfileImport == '4' ? 600 : 500; |
| 290 | uploadFiles.value = [] | 314 | uploadFiles.value = [] |
| 315 | if (isfileImport == '7') { | ||
| 316 | uploadSteps.value[0].selectInfo.options = dictionaryList.value; | ||
| 317 | } else if (isfileImport == '8') { | ||
| 318 | uploadSteps.value[0].cascaderInfo.options = dictionaryList.value; | ||
| 319 | } | ||
| 291 | uploadInfo.value.uploadInfo.steps = uploadSteps.value | 320 | uploadInfo.value.uploadInfo.steps = uploadSteps.value |
| 292 | const content: any = [uploadInfo.value] | 321 | const content: any = [uploadInfo.value] |
| 293 | dialogInfo.value.contents = content | 322 | dialogInfo.value.contents = content |
| ... | @@ -377,6 +406,20 @@ const exportData = (ids: any = null) => { | ... | @@ -377,6 +406,20 @@ const exportData = (ids: any = null) => { |
| 377 | res?.msg && ElMessage.error(res?.msg); | 406 | res?.msg && ElMessage.error(res?.msg); |
| 378 | } | 407 | } |
| 379 | }); | 408 | }); |
| 409 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '7') { | ||
| 410 | exportTemplate({ | ||
| 411 | bizGuid: '', | ||
| 412 | importType: "0046" | ||
| 413 | }).then((res: any) => { | ||
| 414 | download(res, '需求表管理导入模板.xlsx', 'excel') | ||
| 415 | }); | ||
| 416 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '8') { | ||
| 417 | exportTemplate({ | ||
| 418 | bizGuid: '', | ||
| 419 | importType: "0047" | ||
| 420 | }).then((res: any) => { | ||
| 421 | download(res, '疾病管理导入模板.xlsx', 'excel') | ||
| 422 | }); | ||
| 380 | } | 423 | } |
| 381 | } | 424 | } |
| 382 | 425 | ||
| ... | @@ -390,11 +433,11 @@ const importData = (info) => { | ... | @@ -390,11 +433,11 @@ const importData = (info) => { |
| 390 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) | 433 | // dialogInfo.value.footer.btns.map((item: any) => delete item.disabled) |
| 391 | return | 434 | return |
| 392 | } | 435 | } |
| 393 | let paramUrl = ''; | ||
| 394 | if (isfileImport == '2') { | ||
| 395 | uploadFiles.value.forEach((item: any, index: number) => { | 436 | uploadFiles.value.forEach((item: any, index: number) => { |
| 396 | params.append("file", item.raw); | 437 | params.append("file", item.raw); |
| 397 | }); | 438 | }); |
| 439 | let paramUrl = ''; | ||
| 440 | if (isfileImport == '2') { | ||
| 398 | paramUrl = `ms-daop-zcgl-asset-dam-service/dam-catalog-table/excel-by-subject-guid?staffGuid=${userData.staffGuid}&subjectGuid=${route.query.bizGuid}` | 441 | paramUrl = `ms-daop-zcgl-asset-dam-service/dam-catalog-table/excel-by-subject-guid?staffGuid=${userData.staffGuid}&subjectGuid=${route.query.bizGuid}` |
| 399 | } else if (isfileImport == '4') { | 442 | } else if (isfileImport == '4') { |
| 400 | if (!info.databaseNameZh) { | 443 | if (!info.databaseNameZh) { |
| ... | @@ -411,14 +454,17 @@ const importData = (info) => { | ... | @@ -411,14 +454,17 @@ const importData = (info) => { |
| 411 | }) | 454 | }) |
| 412 | return; | 455 | return; |
| 413 | } | 456 | } |
| 414 | uploadFiles.value.forEach((item: any, index: number) => { | 457 | |
| 415 | params.append("uploadFile", item.raw); | ||
| 416 | }); | ||
| 417 | paramUrl = `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/meta-collect-import?staffGuid=${userData.staffGuid}&databaseNameZh=${info.databaseNameZh}&databaseNameEn=${info.databaseNameEn}&isCover=${info.isCover}` | 458 | paramUrl = `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/meta-collect-import?staffGuid=${userData.staffGuid}&databaseNameZh=${info.databaseNameZh}&databaseNameEn=${info.databaseNameEn}&isCover=${info.isCover}` |
| 459 | } else if (isfileImport == '7') { | ||
| 460 | info.bizGuid = '0046'; | ||
| 461 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}` | ||
| 462 | paramUrl += `&extendFields=${encodeURIComponent(JSON.stringify(info))}` | ||
| 463 | } else if (isfileImport == '8') { | ||
| 464 | info.bizGuid = '0047'; | ||
| 465 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}` | ||
| 466 | paramUrl += `&extendFields=${encodeURIComponent(JSON.stringify(info))}` | ||
| 418 | } else { | 467 | } else { |
| 419 | uploadFiles.value.forEach((item: any, index: number) => { | ||
| 420 | params.append("file", item.raw); | ||
| 421 | }); | ||
| 422 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}&dataType=2` | 468 | paramUrl = `${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}&dataType=2` |
| 423 | if (info && Object.keys(info).length) { | 469 | if (info && Object.keys(info).length) { |
| 424 | paramUrl += `&extendFields=${encodeURIComponent(JSON.stringify(info))}` | 470 | paramUrl += `&extendFields=${encodeURIComponent(JSON.stringify(info))}` |
| ... | @@ -452,6 +498,10 @@ const dialogBtnClick = (btn, info) => { | ... | @@ -452,6 +498,10 @@ const dialogBtnClick = (btn, info) => { |
| 452 | if (dialogInfo.value.type == 'upload') { | 498 | if (dialogInfo.value.type == 'upload') { |
| 453 | if (tabsActiveName.value == 'dictionary') { | 499 | if (tabsActiveName.value == 'dictionary') { |
| 454 | importData({ bizGuid: dictionaryGuid.value }) | 500 | importData({ bizGuid: dictionaryGuid.value }) |
| 501 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '7') { | ||
| 502 | importData(info) | ||
| 503 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '8') { | ||
| 504 | importData(info) | ||
| 455 | } else { | 505 | } else { |
| 456 | importData(info) | 506 | importData(info) |
| 457 | } | 507 | } |
| ... | @@ -478,6 +528,10 @@ const setUploadInfo = () => { | ... | @@ -478,6 +528,10 @@ const setUploadInfo = () => { |
| 478 | importType.value = '0034'; | 528 | importType.value = '0034'; |
| 479 | } else if (isfileImport == '4') { | 529 | } else if (isfileImport == '4') { |
| 480 | importType.value = '0042'; | 530 | importType.value = '0042'; |
| 531 | } else if (isfileImport == '7') { | ||
| 532 | importType.value = '0046'; | ||
| 533 | } else if (isfileImport == '8') { | ||
| 534 | importType.value = '0047'; | ||
| 481 | } else { | 535 | } else { |
| 482 | importType.value = '0033'; | 536 | importType.value = '0033'; |
| 483 | } | 537 | } |
| ... | @@ -641,6 +695,94 @@ const setUploadInfo = () => { | ... | @@ -641,6 +695,94 @@ const setUploadInfo = () => { |
| 641 | } | 695 | } |
| 642 | ] | 696 | ] |
| 643 | uploadInfo.value.uploadInfo.extraParams = { isCover: 'Y' } | 697 | uploadInfo.value.uploadInfo.extraParams = { isCover: 'Y' } |
| 698 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '7') { | ||
| 699 | uploadSteps.value = [ | ||
| 700 | { | ||
| 701 | title: '1、导入前请先录入以下内容', | ||
| 702 | type: 'select', | ||
| 703 | selectInfo: { | ||
| 704 | label: '需求表名称', | ||
| 705 | placeholder: '请选择', | ||
| 706 | field: 'menuGuid', | ||
| 707 | default: '', | ||
| 708 | options: [], | ||
| 709 | props: { | ||
| 710 | label: "menuName", | ||
| 711 | value: "guid", | ||
| 712 | }, | ||
| 713 | filterable: true, | ||
| 714 | clearable: true, | ||
| 715 | required: true, | ||
| 716 | style: { | ||
| 717 | width: '191px', | ||
| 718 | } | ||
| 719 | } | ||
| 720 | }, | ||
| 721 | { | ||
| 722 | title: '2、请下载最新的模板,并按照模板格式准备需要导入的数据', | ||
| 723 | type: 'btn_down' | ||
| 724 | }, | ||
| 725 | { | ||
| 726 | title: '3、选择准备好的文件导入', | ||
| 727 | type: 'btn_upload', | ||
| 728 | uploadInfo: { | ||
| 729 | action: '', | ||
| 730 | auto: false, | ||
| 731 | cover: true, | ||
| 732 | fileList: [], | ||
| 733 | accept: '.xlsx, .xls', | ||
| 734 | tips: '当前支持xls、xlsx文件,默认使用第一个sheet' | ||
| 735 | } | ||
| 736 | } | ||
| 737 | ] | ||
| 738 | dictionaryGuid.value = uploadSetting.value?.dictionaryGuid || '' | ||
| 739 | uploadInfo.value.uploadInfo.extraParams = { | ||
| 740 | menuGuid: dictionaryGuid.value | ||
| 741 | } | ||
| 742 | } else if (tabsActiveName.value == 'importFile' && isfileImport == '8') { | ||
| 743 | uploadSteps.value = [ | ||
| 744 | { | ||
| 745 | title: '1、导入前请先录入以下内容', | ||
| 746 | type: 'cascader', | ||
| 747 | cascaderInfo: { | ||
| 748 | label: '疾病名称', | ||
| 749 | placeholder: '', | ||
| 750 | field: 'parentGuid', | ||
| 751 | options: [], | ||
| 752 | default: '', | ||
| 753 | showAllLevels: false, | ||
| 754 | props: { | ||
| 755 | checkStrictly: true, | ||
| 756 | label: "diseaseName", | ||
| 757 | value: "guid", | ||
| 758 | children: 'childList', | ||
| 759 | emitPath: false | ||
| 760 | }, | ||
| 761 | filterable: true, | ||
| 762 | clearable: true, | ||
| 763 | } | ||
| 764 | }, | ||
| 765 | { | ||
| 766 | title: '2、请下载最新的模板,并按照模板格式准备需要导入的数据', | ||
| 767 | type: 'btn_down' | ||
| 768 | }, | ||
| 769 | { | ||
| 770 | title: '3、选择准备好的文件导入', | ||
| 771 | type: 'btn_upload', | ||
| 772 | uploadInfo: { | ||
| 773 | action: '', | ||
| 774 | auto: false, | ||
| 775 | cover: true, | ||
| 776 | fileList: [], | ||
| 777 | accept: '.xlsx, .xls', | ||
| 778 | tips: '当前支持xls、xlsx文件,默认使用第一个sheet' | ||
| 779 | } | ||
| 780 | } | ||
| 781 | ] | ||
| 782 | dictionaryGuid.value = uploadSetting.value?.dictionaryGuid || '' | ||
| 783 | uploadInfo.value.uploadInfo.extraParams = { | ||
| 784 | parentGuid: dictionaryGuid.value | ||
| 785 | } | ||
| 644 | } else { | 786 | } else { |
| 645 | uploadSteps.value = [ | 787 | uploadSteps.value = [ |
| 646 | { | 788 | { |
| ... | @@ -674,7 +816,8 @@ onActivated(() => { | ... | @@ -674,7 +816,8 @@ onActivated(() => { |
| 674 | if (tabsActiveName.value == 'dictionary') { | 816 | if (tabsActiveName.value == 'dictionary') { |
| 675 | getDictList(); | 817 | getDictList(); |
| 676 | } | 818 | } |
| 677 | setUploadInfo() | 819 | setUploadInfo(); |
| 820 | (isfileImport == '7' || isfileImport == '8') && getTreeData(); | ||
| 678 | }) | 821 | }) |
| 679 | 822 | ||
| 680 | </script> | 823 | </script> | ... | ... |
-
Please register or sign in to post a comment