数据定价更新
Showing
1 changed file
with
214 additions
and
277 deletions
| ... | @@ -52,8 +52,13 @@ const dictionaryData: any = ref([]); | ... | @@ -52,8 +52,13 @@ const dictionaryData: any = ref([]); |
| 52 | const diseaseData: any = ref([]); | 52 | const diseaseData: any = ref([]); |
| 53 | const qualityScoreData: any = ref({}); | 53 | const qualityScoreData: any = ref({}); |
| 54 | const disScore: any = ref([]); | 54 | const disScore: any = ref([]); |
| 55 | const exportData: any = ref([]); | 55 | const buildInData: any = ref([]); |
| 56 | const dataUsage = ref(''); | 56 | const dataUsage = ref({ |
| 57 | field: '', | ||
| 58 | dictValue: '' | ||
| 59 | }); | ||
| 60 | const currModelGuid = ref(''); | ||
| 61 | |||
| 57 | // 基础设置 | 62 | // 基础设置 |
| 58 | const baseConfigFormRef = ref(); | 63 | const baseConfigFormRef = ref(); |
| 59 | const baseConfigFormItems: any = ref([ | 64 | const baseConfigFormItems: any = ref([ |
| ... | @@ -93,7 +98,6 @@ const baseConfigFormItems: any = ref([ | ... | @@ -93,7 +98,6 @@ const baseConfigFormItems: any = ref([ |
| 93 | placeholder: '', | 98 | placeholder: '', |
| 94 | field: 'belongingEntityGuid', | 99 | field: 'belongingEntityGuid', |
| 95 | default: '', | 100 | default: '', |
| 96 | options: [], | ||
| 97 | clearable: true, | 101 | clearable: true, |
| 98 | disabled: true | 102 | disabled: true |
| 99 | }, | 103 | }, |
| ... | @@ -141,10 +145,16 @@ const tableLoading = ref(false); | ... | @@ -141,10 +145,16 @@ const tableLoading = ref(false); |
| 141 | const dataTransactionPrice: any = ref(''); | 145 | const dataTransactionPrice: any = ref(''); |
| 142 | const setFormItems = (info = null) => { | 146 | const setFormItems = (info = null) => { |
| 143 | let datas: any = info || flowDetail.value || {}; | 147 | let datas: any = info || flowDetail.value || {}; |
| 144 | const dData = datas.dictionaryJson ? JSON.parse(datas.dictionaryJson) : {}; | 148 | const dictData = datas.dictionaryJson ? JSON.parse(datas.dictionaryJson) : {}; |
| 145 | datas = { ...datas, ...dData }; | 149 | const builtIndicators = datas.builtIndicators || buildInData.value || []; |
| 150 | let buildData = {}; | ||
| 151 | builtIndicators.map(item => { | ||
| 152 | buildData[`build_${item.guid}`] = item.isInputParameter != 'Y' ? changeNum(item.targetValue, 2) : item.targetValue != '' && item.targetValue != null ? parseFloat(item.targetValue).toFixed(2) : ''; | ||
| 153 | }); | ||
| 154 | datas = { ...datas, ...dictData, ...buildData }; | ||
| 146 | baseConfigFormItems.value.map(item => { | 155 | baseConfigFormItems.value.map(item => { |
| 147 | item.default = datas[item.field] || ''; | 156 | item.default = datas[item.field] || ''; |
| 157 | item.label == '数据用途' && (dataUsage.value.dictValue = datas[item.field] || ''); | ||
| 148 | }) | 158 | }) |
| 149 | nextTick(() => { | 159 | nextTick(() => { |
| 150 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); | 160 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); |
| ... | @@ -256,7 +266,8 @@ const getDetail = () => { | ... | @@ -256,7 +266,8 @@ const getDetail = () => { |
| 256 | const data = res.data || {}; | 266 | const data = res.data || {}; |
| 257 | flowDetail.value = data; | 267 | flowDetail.value = data; |
| 258 | dataTransactionPrice.value = flowDetail.value.dataTransactionPrice; | 268 | dataTransactionPrice.value = flowDetail.value.dataTransactionPrice; |
| 259 | dataUsage.value = data.dataUsage || ''; | 269 | dataUsage.value.dictValue = data.dataUsage || ''; |
| 270 | currModelGuid.value = flowDetail.value.modelGuid; | ||
| 260 | const mItem = typeMap.value.modelGuid.find(m => m.guid == flowDetail.value.modelGuid); | 271 | const mItem = typeMap.value.modelGuid.find(m => m.guid == flowDetail.value.modelGuid); |
| 261 | if (!mItem) { | 272 | if (!mItem) { |
| 262 | const mtem = { guid: flowDetail.value.modelGuid, modelName: flowDetail.value.modelName }; | 273 | const mtem = { guid: flowDetail.value.modelGuid, modelName: flowDetail.value.modelName }; |
| ... | @@ -284,8 +295,127 @@ const getDataTypeList = () => { | ... | @@ -284,8 +295,127 @@ const getDataTypeList = () => { |
| 284 | ) | 295 | ) |
| 285 | } | 296 | } |
| 286 | } | 297 | } |
| 287 | const setFormItemData = () => { | 298 | |
| 288 | let dictionaryList: any = [], diseaseList: any = []; | 299 | // 设置数据字典选项 |
| 300 | const setDictFormItems = (dictList) => { | ||
| 301 | dictList.map(d => { | ||
| 302 | const dictName = d.dictionaryName; | ||
| 303 | const dictField = `dict_${d.guid}`; | ||
| 304 | baseConfigFormItems.value.push({ | ||
| 305 | label: dictName, | ||
| 306 | type: 'select', | ||
| 307 | placeholder: '请输入', | ||
| 308 | field: dictField, | ||
| 309 | default: '', | ||
| 310 | options: [], | ||
| 311 | clearable: true, | ||
| 312 | filterable: true, | ||
| 313 | required: true, | ||
| 314 | }); | ||
| 315 | baseConfigFormRules.value[dictField] = [{ required: true, trigger: 'change', message: `请选择${dictName}` }]; | ||
| 316 | dictName == '数据用途' && (dataUsage.value.field = dictField); | ||
| 317 | (() => { | ||
| 318 | if (typeMap.value[dictField] == undefined) { | ||
| 319 | getDataType(dictName, dictField) | ||
| 320 | } else { | ||
| 321 | let item = baseConfigFormItems.value.find(item => item.field == dictField); | ||
| 322 | item && (item.options = typeMap.value[dictField]); | ||
| 323 | } | ||
| 324 | })() | ||
| 325 | }) | ||
| 326 | } | ||
| 327 | |||
| 328 | // 设置疾病选项 | ||
| 329 | const setDiseaseFormItems = () => { | ||
| 330 | baseConfigFormItems.value.push({ | ||
| 331 | label: '所属疾病', | ||
| 332 | type: 'cascader', | ||
| 333 | placeholder: '请选择', | ||
| 334 | field: 'diseaseGuid', | ||
| 335 | default: '', | ||
| 336 | options: [], | ||
| 337 | showAllLevels: false, | ||
| 338 | props: { | ||
| 339 | checkStrictly: true, | ||
| 340 | label: "diseaseName", | ||
| 341 | value: "guid", | ||
| 342 | children: 'childList', | ||
| 343 | emitPath: false | ||
| 344 | }, | ||
| 345 | filterable: true, | ||
| 346 | clearable: true, | ||
| 347 | required: true, | ||
| 348 | }); | ||
| 349 | baseConfigFormRules.value.diseaseGuid = [{ required: true, trigger: 'change', message: "请选择所属疾病" }]; | ||
| 350 | if (typeMap.value['diseaseGuid'] == undefined) { | ||
| 351 | getDiseaseData(); | ||
| 352 | } else { | ||
| 353 | let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid'); | ||
| 354 | if (item) { | ||
| 355 | item.options = typeMap.value['diseaseGuid']; | ||
| 356 | const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid); | ||
| 357 | if (!diseaseData) { | ||
| 358 | item.options.unshift({ | ||
| 359 | guid: flowDetail.value.diseaseGuid, | ||
| 360 | diseaseName: flowDetail.value.diseaseName | ||
| 361 | }); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | // 设置内置指标选项 | ||
| 368 | const setBuildInFormItems = (buildList) => { | ||
| 369 | buildList.map(b => { | ||
| 370 | const buildName = b.targetName; | ||
| 371 | const buildField = `build_${b.guid}`; | ||
| 372 | buildInData.value.push({ | ||
| 373 | guid: b.guid, | ||
| 374 | targetName: buildName, | ||
| 375 | targetValue: b.defaultValue || '', | ||
| 376 | isInputParameter: b.isInputParameter, | ||
| 377 | }) | ||
| 378 | baseConfigFormItems.value.push({ | ||
| 379 | label: buildName, | ||
| 380 | type: 'input', | ||
| 381 | placeholder: '', | ||
| 382 | field: buildField, | ||
| 383 | default: b.isInputParameter != 'Y' ? changeNum(b.defaultValue, 2) : b.defaultValue != '' && b.defaultValue != null ? parseFloat(b.defaultValue).toFixed(2) : '', | ||
| 384 | inputType: 'moneyNumber', | ||
| 385 | maxlength: 18, | ||
| 386 | clearable: true, | ||
| 387 | disabled: b.isInputParameter != 'Y', | ||
| 388 | required: true | ||
| 389 | }); | ||
| 390 | baseConfigFormRules.value[buildField] = [ | ||
| 391 | { required: true, message: `请填写${buildName}`, trigger: 'blur' }, | ||
| 392 | { | ||
| 393 | validator: (rule, value, callback) => { | ||
| 394 | if (value === '') { | ||
| 395 | callback(new Error(`请填写${buildName}`)); | ||
| 396 | return; | ||
| 397 | } | ||
| 398 | const num = parseFloat(value); | ||
| 399 | if (isNaN(num)) { | ||
| 400 | callback(new Error('请输入有效的数字')); | ||
| 401 | return; | ||
| 402 | } | ||
| 403 | |||
| 404 | // 已自动保留两位小数,不需再验证小数位数 | ||
| 405 | if (num < 0 || num > b.defaultValue) { | ||
| 406 | callback(new Error(`输入值必须在0到${b.defaultValue}之间`)); | ||
| 407 | } else { | ||
| 408 | callback(); | ||
| 409 | } | ||
| 410 | }, trigger: "blur", | ||
| 411 | }, | ||
| 412 | ] | ||
| 413 | }) | ||
| 414 | }; | ||
| 415 | |||
| 416 | // 添加表单选项数据 | ||
| 417 | const setFormItemData = async () => { | ||
| 418 | let dictionaryList: any = [], diseaseList: any = [], buildInList: any = []; | ||
| 289 | pricingTargetList.value.map(item => { | 419 | pricingTargetList.value.map(item => { |
| 290 | switch (item.targetType) { | 420 | switch (item.targetType) { |
| 291 | case '2': | 421 | case '2': |
| ... | @@ -294,6 +424,9 @@ const setFormItemData = () => { | ... | @@ -294,6 +424,9 @@ const setFormItemData = () => { |
| 294 | case '3': | 424 | case '3': |
| 295 | dictionaryList.push(item); | 425 | dictionaryList.push(item); |
| 296 | break; | 426 | break; |
| 427 | case '1': | ||
| 428 | buildInList.push(item); | ||
| 429 | break; | ||
| 297 | default: | 430 | default: |
| 298 | break; | 431 | break; |
| 299 | } | 432 | } |
| ... | @@ -315,68 +448,12 @@ const setFormItemData = () => { | ... | @@ -315,68 +448,12 @@ const setFormItemData = () => { |
| 315 | } | 448 | } |
| 316 | } | 449 | } |
| 317 | // 添加所属疾病 | 450 | // 添加所属疾病 |
| 318 | if (diseaseList.length > 0) { | 451 | diseaseList.length > 0 && await setDiseaseFormItems(); |
| 319 | baseConfigFormItems.value.push({ | ||
| 320 | label: '所属疾病', | ||
| 321 | type: 'cascader', | ||
| 322 | placeholder: '请选择', | ||
| 323 | field: 'diseaseGuid', | ||
| 324 | default: '', | ||
| 325 | options: [], | ||
| 326 | showAllLevels: false, | ||
| 327 | props: { | ||
| 328 | checkStrictly: true, | ||
| 329 | label: "diseaseName", | ||
| 330 | value: "guid", | ||
| 331 | children: 'childList', | ||
| 332 | emitPath: false | ||
| 333 | }, | ||
| 334 | filterable: true, | ||
| 335 | clearable: true, | ||
| 336 | required: true, | ||
| 337 | }); | ||
| 338 | baseConfigFormRules.value.diseaseGuid = { required: true, trigger: 'change', message: "请选择所属疾病" }; | ||
| 339 | if (typeMap.value['diseaseGuid'] == undefined) { | ||
| 340 | getDiseaseData(); | ||
| 341 | } else { | ||
| 342 | let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid'); | ||
| 343 | if (item) { | ||
| 344 | item.options = typeMap.value['diseaseGuid']; | ||
| 345 | const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid); | ||
| 346 | if (!diseaseData) { | ||
| 347 | item.options.unshift({ | ||
| 348 | guid: flowDetail.value.diseaseGuid, | ||
| 349 | diseaseName: flowDetail.value.diseaseName | ||
| 350 | }); | ||
| 351 | } | ||
| 352 | } | ||
| 353 | } | ||
| 354 | } | ||
| 355 | // 添加数据字典 | 452 | // 添加数据字典 |
| 356 | dictionaryList.map(d => { | 453 | dictionaryList.length > 0 && await setDictFormItems(dictionaryList); |
| 357 | const dictName = d.dictionaryName; | 454 | // 添加内置指标 |
| 358 | const dictField = `dict_${d.guid}`; | 455 | buildInList.length > 0 && await setBuildInFormItems(buildInList); |
| 359 | baseConfigFormItems.value.push({ | 456 | |
| 360 | label: dictName, | ||
| 361 | type: 'select', | ||
| 362 | placeholder: '请输入', | ||
| 363 | field: dictField, | ||
| 364 | default: '', | ||
| 365 | options: [], | ||
| 366 | clearable: true, | ||
| 367 | filterable: true, | ||
| 368 | required: true, | ||
| 369 | }); | ||
| 370 | baseConfigFormRules.value[dictField] = { required: true, trigger: 'change', message: `请选择${dictName}` }; | ||
| 371 | (() => { | ||
| 372 | if (typeMap.value[dictField] == undefined) { | ||
| 373 | getDataType(dictName, dictField) | ||
| 374 | } else { | ||
| 375 | let item = baseConfigFormItems.value.find(item => item.field == dictField); | ||
| 376 | item && (item.options = typeMap.value[dictField]); | ||
| 377 | } | ||
| 378 | })() | ||
| 379 | }) | ||
| 380 | setTimeout(() => { | 457 | setTimeout(() => { |
| 381 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); | 458 | baseConfigFormRef.value.ruleFormRef?.clearValidate(); |
| 382 | }, 100) | 459 | }, 100) |
| ... | @@ -414,11 +491,9 @@ const setTableData = (dataArr) => { | ... | @@ -414,11 +491,9 @@ const setTableData = (dataArr) => { |
| 414 | if ((item.demandTableGuid || item.guid)) { | 491 | if ((item.demandTableGuid || item.guid)) { |
| 415 | const rGuid = item.demandTableGuid || item.guid; | 492 | const rGuid = item.demandTableGuid || item.guid; |
| 416 | const rIndex = i; | 493 | const rIndex = i; |
| 417 | if (!guid || (guid && rGuid != (demInfo?.demandTableGuid || ''))) { | 494 | (() => { |
| 418 | (() => { | 495 | getDemandField(rGuid, rIndex); |
| 419 | getDemandField(rGuid, rIndex); | 496 | })() |
| 420 | })() | ||
| 421 | } | ||
| 422 | } | 497 | } |
| 423 | }) | 498 | }) |
| 424 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | 499 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { |
| ... | @@ -438,6 +513,7 @@ const getModelConfig = (mGuid) => { | ... | @@ -438,6 +513,7 @@ const getModelConfig = (mGuid) => { |
| 438 | demandTableList.value = data.pricingDemandMenuRSVOS || []; | 513 | demandTableList.value = data.pricingDemandMenuRSVOS || []; |
| 439 | pricingTargetList.value = data.pricingTargetRSVOS || []; | 514 | pricingTargetList.value = data.pricingTargetRSVOS || []; |
| 440 | demandTableFieldAllNum.value = data.fieldCount || 0; | 515 | demandTableFieldAllNum.value = data.fieldCount || 0; |
| 516 | buildInData.value = []; | ||
| 441 | } | 517 | } |
| 442 | }) | 518 | }) |
| 443 | } | 519 | } |
| ... | @@ -505,7 +581,7 @@ const getResourceDetail = (sGuid, toPromise = true) => { | ... | @@ -505,7 +581,7 @@ const getResourceDetail = (sGuid, toPromise = true) => { |
| 505 | const dGuid = item.dataTableGuid; | 581 | const dGuid = item.dataTableGuid; |
| 506 | const rIndex = i; | 582 | const rIndex = i; |
| 507 | (() => { | 583 | (() => { |
| 508 | !toPromise && dGuid && setTableRowData(dGuid, rIndex) | 584 | !toPromise && dGuid && setTableRowData(dGuid, rIndex, false) |
| 509 | })() | 585 | })() |
| 510 | }) | 586 | }) |
| 511 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; | 587 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; |
| ... | @@ -566,11 +642,25 @@ const getResourceInfo = (sGuid) => { | ... | @@ -566,11 +642,25 @@ const getResourceInfo = (sGuid) => { |
| 566 | loading.value = false; | 642 | loading.value = false; |
| 567 | } | 643 | } |
| 568 | } | 644 | } |
| 569 | const setTableRowData = (dGuid, rIndex) => { | 645 | |
| 570 | let rowData = tableData.value[rIndex]; | 646 | // 需求表字段匹配 |
| 647 | const matchTableFields = (rData, tData) => { | ||
| 648 | rData.dataFields.map(t => { | ||
| 649 | const match = tData.find(d => d.chName == t.fieldName); | ||
| 650 | if (match) { | ||
| 651 | t.chName = match.chName; | ||
| 652 | t.enName = match.enName; | ||
| 653 | } | ||
| 654 | }) | ||
| 655 | rData.dataFieldsNum = rData.dataFields.filter(item => item.chName != '' && item.chName != null).length; | ||
| 656 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | ||
| 657 | return accumulator + Number(currentValue.dataFieldsNum); | ||
| 658 | }, 0); | ||
| 659 | } | ||
| 660 | |||
| 661 | const setRowData = (rowData, dGuid, detailDataTable) => { | ||
| 571 | if (guid && dGuid == rowData.dataTableGuid) { | 662 | if (guid && dGuid == rowData.dataTableGuid) { |
| 572 | const sourceTableField = flowDetail.value.dataPricingDemandmatchingRQVOS?.find(s => dGuid == s.dataTableGuid); | 663 | const pricingDemandField = detailDataTable?.pricingDemandFieldRQVOS || []; |
| 573 | const pricingDemandField = sourceTableField?.pricingDemandFieldRQVOS || []; | ||
| 574 | rowData.dataFields.map(f => { | 664 | rowData.dataFields.map(f => { |
| 575 | f.chName = pricingDemandField.find(s => f.guid == s.guid)?.chName || '' | 665 | f.chName = pricingDemandField.find(s => f.guid == s.guid)?.chName || '' |
| 576 | }) | 666 | }) |
| ... | @@ -584,6 +674,13 @@ const setTableRowData = (dGuid, rIndex) => { | ... | @@ -584,6 +674,13 @@ const setTableRowData = (dGuid, rIndex) => { |
| 584 | return accumulator + Number(currentValue.dataFieldsNum); | 674 | return accumulator + Number(currentValue.dataFieldsNum); |
| 585 | }, 0); | 675 | }, 0); |
| 586 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; | 676 | resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length; |
| 677 | } | ||
| 678 | |||
| 679 | const setTableRowData = (dGuid, rIndex, setRow = true) => { | ||
| 680 | let rowData = tableData.value[rIndex]; | ||
| 681 | const detailDataTable = (flowDetail.value.dataPricingDemandmatchingRQVOS || []).find(f => f.dataTableGuid == dGuid && f.demandTableGuid == rowData.demandTableGuid); | ||
| 682 | setRow && setRowData(rowData, dGuid, detailDataTable); | ||
| 683 | const currDataTableGuid = detailDataTable?.dataTableGuid || ''; | ||
| 587 | if (dGuid) { | 684 | if (dGuid) { |
| 588 | tableLoading.value = true; | 685 | tableLoading.value = true; |
| 589 | getRegisterCatalogTableDetail(dGuid).then((res: any) => { | 686 | getRegisterCatalogTableDetail(dGuid).then((res: any) => { |
| ... | @@ -600,17 +697,11 @@ const setTableRowData = (dGuid, rIndex) => { | ... | @@ -600,17 +697,11 @@ const setTableRowData = (dGuid, rIndex) => { |
| 600 | }) | 697 | }) |
| 601 | rowData.dataFields.map(t => { | 698 | rowData.dataFields.map(t => { |
| 602 | t.damFieldTable = JSON.parse(JSON.stringify(damFieldOptions)); | 699 | t.damFieldTable = JSON.parse(JSON.stringify(damFieldOptions)); |
| 603 | const match = damFieldOptions.find(d => d.chName == t.fieldName); | ||
| 604 | if (match) { | ||
| 605 | t.chName = match.chName; | ||
| 606 | t.enName = match.enName; | ||
| 607 | } | ||
| 608 | }) | 700 | }) |
| 609 | rowData.dataFieldsNum = rowData.dataFields.filter(item => item.chName != '' && item.chName != null).length; | 701 | // 匹配 |
| 610 | resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => { | 702 | if (!guid || (guid && (dGuid != currDataTableGuid || currModelGuid.value != flowDetail.value.modelGuid))) { |
| 611 | return accumulator + Number(currentValue.dataFieldsNum); | 703 | matchTableFields(rowData, damTableField); |
| 612 | }, 0); | 704 | } |
| 613 | // console.log('rowData', rowData) | ||
| 614 | } else { | 705 | } else { |
| 615 | proxy.$ElMessage.error(res.msg); | 706 | proxy.$ElMessage.error(res.msg); |
| 616 | } | 707 | } |
| ... | @@ -629,6 +720,7 @@ const changeDatasource = () => { | ... | @@ -629,6 +720,7 @@ const changeDatasource = () => { |
| 629 | } | 720 | } |
| 630 | }) | 721 | }) |
| 631 | } | 722 | } |
| 723 | |||
| 632 | const cascaderChange = (val) => { | 724 | const cascaderChange = (val) => { |
| 633 | disScore.value = []; | 725 | disScore.value = []; |
| 634 | if (val) { | 726 | if (val) { |
| ... | @@ -650,6 +742,7 @@ const selectChange = async (val, row, info) => { | ... | @@ -650,6 +742,7 @@ const selectChange = async (val, row, info) => { |
| 650 | resourceTableFieldAllNum.value = 0; | 742 | resourceTableFieldAllNum.value = 0; |
| 651 | await setFormItems(info); | 743 | await setFormItems(info); |
| 652 | val && getModelInfo(val); | 744 | val && getModelInfo(val); |
| 745 | currModelGuid.value = val || ''; | ||
| 653 | qualityScoreData.value = {}; | 746 | qualityScoreData.value = {}; |
| 654 | baseConfigFormItems.value[1].default = ''; | 747 | baseConfigFormItems.value[1].default = ''; |
| 655 | changeDatasource(); | 748 | changeDatasource(); |
| ... | @@ -663,6 +756,9 @@ const selectChange = async (val, row, info) => { | ... | @@ -663,6 +756,9 @@ const selectChange = async (val, row, info) => { |
| 663 | } else { | 756 | } else { |
| 664 | changeDatasource(); | 757 | changeDatasource(); |
| 665 | } | 758 | } |
| 759 | } else if (row.field == dataUsage.value.field) { | ||
| 760 | dataUsage.value.dictValue = val || ''; | ||
| 761 | setFormItems(info); | ||
| 666 | } else if (row.field == 'dataTableGuid') { | 762 | } else if (row.field == 'dataTableGuid') { |
| 667 | setTableRowData(val, info.$index) | 763 | setTableRowData(val, info.$index) |
| 668 | } else if (row.field == 'chName') { | 764 | } else if (row.field == 'chName') { |
| ... | @@ -721,34 +817,8 @@ const toPath = () => { | ... | @@ -721,34 +817,8 @@ const toPath = () => { |
| 721 | name: 'priceCalculate', | 817 | name: 'priceCalculate', |
| 722 | }) | 818 | }) |
| 723 | } | 819 | } |
| 724 | // 获取维度公式计算结果 | 820 | |
| 725 | const getSignatory = (row) => { | 821 | // 获取疾病得分 |
| 726 | let formulaVal = 0; | ||
| 727 | const pricingTargetData = row.pricingTargetRSVOS || []; | ||
| 728 | if (!row.computationalFormula || row.computationalFormula == 'custom') { | ||
| 729 | let formula = row.customize; | ||
| 730 | // 遍历数组,检查 customize 是否包含对应的 targetName,若包含则替换为 tNum | ||
| 731 | pricingTargetData.forEach((item) => { | ||
| 732 | if (formula.includes(item.targetName)) { | ||
| 733 | formula = formula.replace(new RegExp(item.targetName, 'g'), item.tNum); | ||
| 734 | } | ||
| 735 | }); | ||
| 736 | // 使用 eval 计算公式结果(注意:eval 存在安全风险,仅适用于受控环境) | ||
| 737 | try { | ||
| 738 | formulaVal = eval(formula); | ||
| 739 | } catch (error) { | ||
| 740 | console.error('公式计算错误:', error); | ||
| 741 | } | ||
| 742 | } else { | ||
| 743 | const formula = pricingTargetData.map(item => item.tNum); | ||
| 744 | if (row.computationalFormula == '3') { | ||
| 745 | formulaVal = formula.reduce((accumulator, currentValue) => parseFloat(accumulator) * parseFloat(currentValue), 1); // 初始值为1 | ||
| 746 | } else { | ||
| 747 | formulaVal = formula.reduce((accumulator, currentValue) => parseFloat(accumulator) + parseFloat(currentValue), 0); // 初始值为0 | ||
| 748 | } | ||
| 749 | } | ||
| 750 | return (Math.round(formulaVal * 100) / 100).toFixed(2); | ||
| 751 | }; | ||
| 752 | const getTargetNum = (params) => { | 822 | const getTargetNum = (params) => { |
| 753 | // loading.value = true; | 823 | // loading.value = true; |
| 754 | getPriceResult(params).then((res: any) => { | 824 | getPriceResult(params).then((res: any) => { |
| ... | @@ -764,151 +834,6 @@ const getTargetNum = (params) => { | ... | @@ -764,151 +834,6 @@ const getTargetNum = (params) => { |
| 764 | }); | 834 | }); |
| 765 | } | 835 | } |
| 766 | 836 | ||
| 767 | // 生成报告内容 | ||
| 768 | const reporting = (formInfo) => { | ||
| 769 | let resultInfo: any = []; | ||
| 770 | const signatoryData = JSON.parse(JSON.stringify(modelData.value.pricingDimensionalityRSVOS || '[]')); | ||
| 771 | signatoryData.map((sign, s) => { | ||
| 772 | resultInfo.push({ | ||
| 773 | dimensionalityName: sign.dimensionalityName, | ||
| 774 | computationalFormula: sign.computationalFormula, | ||
| 775 | customize: sign.customize, | ||
| 776 | pricingTargetRSVOS: [] | ||
| 777 | }); | ||
| 778 | const targets = sign.pricingTargetRSVOS || []; | ||
| 779 | const signTargets = targets.map(t => { | ||
| 780 | let tNum: any = 0, tCustomize = ''; | ||
| 781 | if (t.targetType == '3') { // 指标类型-数据字典 | ||
| 782 | const tName = dictionaryData.value.find(d => d.guid == t.guid) ? `dict_${t.guid}` : ''; | ||
| 783 | if (tName) { | ||
| 784 | const pVal = typeMap.value[tName].find(t => t.value == formInfo[tName]); | ||
| 785 | const dictionary = t.dictionaryJson.find(d => d.name == pVal.label); | ||
| 786 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 787 | tNum = parseFloat(t.weight) / 100 * parseFloat(dictionary?.value || t.defaultValue || 0); | ||
| 788 | tCustomize = `权重${parseFloat(t.weight) / 100} * 因子/默认值${parseFloat(dictionary?.value || t.defaultValue || 0)}`; | ||
| 789 | } else { // 其他 | ||
| 790 | tNum = parseFloat(dictionary?.value || t.defaultValue || 0); | ||
| 791 | tCustomize = `默认值${parseFloat(dictionary?.value || t.defaultValue || 0)}`; | ||
| 792 | } | ||
| 793 | t.dictionaryName == '数据用途' && (dataUsage.value = pVal.value || ''); | ||
| 794 | } | ||
| 795 | } else if (t.targetType == '2') {// 指标类型-系统功能 | ||
| 796 | if (t.functionName == '1') { // 功能名称-质量评价模型 | ||
| 797 | const score = parseFloat(qualityScoreData.value.qualityScore || 0); | ||
| 798 | tNum = parseFloat(t.weight || 1) / 100 * score / 100; | ||
| 799 | tCustomize = `权重${parseFloat(t.weight || 1) / 100} * 模型评分${score}/100`; | ||
| 800 | } else if (t.functionName == '2') { // 功能名称-疾病管理 | ||
| 801 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 802 | const score = parseFloat(disScore.value.find(d => d.guid == t.guid)?.factor || 0); | ||
| 803 | tNum = parseFloat(t.weight) / 100 * score; | ||
| 804 | tCustomize = `权重${parseFloat(t.weight) / 100} * 疾病得分${score}`; | ||
| 805 | } else { //其他 | ||
| 806 | tNum = parseFloat(disScore.value.find(d => d.guid == t.guid)?.factor || 0); | ||
| 807 | tCustomize = `疾病得分${tNum}`; | ||
| 808 | } | ||
| 809 | } else if (t.functionName == '3') {// 功能名称-需求表管理 | ||
| 810 | const tData = tableData.value.find(f => f.demandTableGuid == t.demandTableGuid || f.guid == t.demandTableGuid); | ||
| 811 | if (tData) { | ||
| 812 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 813 | tNum = parseFloat(t.weight) / 100 * (parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)); | ||
| 814 | tCustomize = `权重${parseFloat(t.weight) / 100} * 匹配率/默认值${parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)}`; | ||
| 815 | } else { //其他 | ||
| 816 | tNum = parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0); | ||
| 817 | tCustomize = `匹配率/默认值${parseFloat(tData.dataFieldsNum) / tData.dataFields.length || parseFloat(t.defaultValue || 0)}`; | ||
| 818 | } | ||
| 819 | } | ||
| 820 | } | ||
| 821 | } else { // 指标类型-系统内置 | ||
| 822 | if (sign.computationalFormula == '1') {// 加权平均 | ||
| 823 | tNum = parseFloat(t.weight) / 100 * parseFloat(t.defaultValue || 0); | ||
| 824 | tCustomize = `权重${parseFloat(t.weight) / 100} * 默认值${parseFloat(t.defaultValue || 0)}`; | ||
| 825 | } else { //其他 | ||
| 826 | tNum = parseFloat(t.defaultValue || 0); | ||
| 827 | tCustomize = `默认值${parseFloat(t.defaultValue || 0)}`; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | t.tNum = (Math.round(parseFloat(tNum) * 100) / 100).toFixed(2); | ||
| 831 | resultInfo[s].pricingTargetRSVOS.push({ | ||
| 832 | targetName: t.targetName, | ||
| 833 | targetType: t.targetType, | ||
| 834 | functionName: t.functionName, | ||
| 835 | customize: tCustomize, | ||
| 836 | tNum: t.tNum, | ||
| 837 | }) | ||
| 838 | return t; | ||
| 839 | }) | ||
| 840 | sign.pricingTargetRSVOS = signTargets; | ||
| 841 | sign.sNum = getSignatory(sign); | ||
| 842 | resultInfo[s].sNum = sign.sNum; | ||
| 843 | }) | ||
| 844 | // exportData.value = resultInfo; | ||
| 845 | return { signatoryData, resultInfo }; | ||
| 846 | } | ||
| 847 | |||
| 848 | // 计算价格 | ||
| 849 | const calculatePrice = (pData) => { | ||
| 850 | let modelFormula = modelData.value.modelFormula; | ||
| 851 | // 1. 移除所有干扰的引号(确保是数学表达式) | ||
| 852 | modelFormula = modelFormula.replace(/["']/g, "").trim(); | ||
| 853 | |||
| 854 | // 2. 定义允许的数学运算符和函数 | ||
| 855 | const allowedOperators = /[+\-*/%^() .\d]/; | ||
| 856 | const mathFunctions = ['sin', 'cos', 'tan', 'log', 'sqrt', 'abs', 'pow']; | ||
| 857 | |||
| 858 | // 3. 提取变量名 | ||
| 859 | const variableRegex = /[\u4e00-\u9fa5a-zA-Z_][\u4e00-\u9fa5a-zA-Z0-9_]*/g; | ||
| 860 | const variableNames = [...new Set(modelFormula.match(variableRegex) || [])]; | ||
| 861 | |||
| 862 | // 4. 构建变量映射 | ||
| 863 | const variables = {}; | ||
| 864 | variableNames.forEach(name => { | ||
| 865 | const dim = pData.find(d => d.dimensionalityName === name); | ||
| 866 | variables[name] = dim ? parseFloat(dim.sNum) || 0 : 0; | ||
| 867 | }); | ||
| 868 | |||
| 869 | // 5. 替换变量为数值(考虑边界情况) | ||
| 870 | let expression = modelFormula; | ||
| 871 | Object.keys(variables).forEach(name => { | ||
| 872 | expression = expression.replace(new RegExp(name, 'g'), variables[name]); | ||
| 873 | }); | ||
| 874 | |||
| 875 | // 6. 表达式规范化(不丢失括号) | ||
| 876 | expression = expression | ||
| 877 | .replace(/\s+/g, '') // 去空格 | ||
| 878 | .replace(/\^/g, '**') // 幂运算转换 | ||
| 879 | .replace(/"|'/g, '') // 去引号(不破坏括号) | ||
| 880 | .replace(/(\d)\(/g, '$1*(') // 处理隐式乘法 | ||
| 881 | .replace(/\)\(/g, ')*('); // 括号间乘法 | ||
| 882 | |||
| 883 | // 7. 验证括号配对 | ||
| 884 | const balance = expression.split('').reduce((acc, char) => { | ||
| 885 | if (char === '(') acc++; | ||
| 886 | if (char === ')') acc--; | ||
| 887 | return acc; | ||
| 888 | }, 0); | ||
| 889 | |||
| 890 | if (balance !== 0) { | ||
| 891 | console.error('括号不匹配'); | ||
| 892 | return NaN; | ||
| 893 | } | ||
| 894 | |||
| 895 | // 8. 安全计算 | ||
| 896 | try { | ||
| 897 | const result = new Function('return ' + expression)(); | ||
| 898 | const roundedResult = Math.round(parseFloat(result) * 100) / 100; | ||
| 899 | |||
| 900 | dataTransactionPrice.value = roundedResult.toFixed(2); | ||
| 901 | return roundedResult; | ||
| 902 | } catch (error) { | ||
| 903 | console.error('计算错误:', { | ||
| 904 | error, | ||
| 905 | original: modelFormula, | ||
| 906 | processed: expression | ||
| 907 | }); | ||
| 908 | return NaN; | ||
| 909 | } | ||
| 910 | }; | ||
| 911 | |||
| 912 | // 获取定价计算配置参数 | 837 | // 获取定价计算配置参数 |
| 913 | const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { | 838 | const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { |
| 914 | const modelName = typeMap.value.modelGuid.find(d => d.guid == baseConfigFormInfo.modelGuid)?.modelName || ''; | 839 | const modelName = typeMap.value.modelGuid.find(d => d.guid == baseConfigFormInfo.modelGuid)?.modelName || ''; |
| ... | @@ -925,19 +850,32 @@ const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { | ... | @@ -925,19 +850,32 @@ const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { |
| 925 | belongingTheme: baseConfigFormInfo.belongingTheme, | 850 | belongingTheme: baseConfigFormInfo.belongingTheme, |
| 926 | diseaseGuid, | 851 | diseaseGuid, |
| 927 | diseaseName: '', | 852 | diseaseName: '', |
| 928 | dataUsage: dataUsage.value | 853 | dataUsage: dataUsage.value.dictValue |
| 929 | }; | 854 | }; |
| 930 | if (diseaseGuid) { | 855 | if (diseaseGuid) { |
| 931 | const parentsData = baseConfigFormObj.getCascaderCheckedData(); | 856 | const parentsData = baseConfigFormObj.getCascaderCheckedData(); |
| 932 | params.diseaseName = parentsData[0]?.label || ''; | 857 | params.diseaseName = parentsData[0]?.label || ''; |
| 933 | } | 858 | } |
| 934 | let dictionaryJson = {}; | 859 | let dictionaryJson = {}, builtInTarget: any = []; |
| 935 | for (var b in baseConfigFormInfo) { | 860 | for (var b in baseConfigFormInfo) { |
| 936 | if (b.indexOf('dict_') > -1) { | 861 | if (b.indexOf('dict_') > -1) { |
| 937 | dictionaryJson[b] = baseConfigFormInfo[b]; | 862 | dictionaryJson[b] = baseConfigFormInfo[b]; |
| 938 | } | 863 | } |
| 939 | } | 864 | } |
| 865 | buildInData.value.map(item => { | ||
| 866 | let targetValue = baseConfigFormInfo[`build_${item.guid}`]; | ||
| 867 | if (typeof targetValue === 'string') { | ||
| 868 | if (/^[+-]?\d{1,3}(,\d{3})*(\.\d{2})?$/.test(targetValue)) { | ||
| 869 | targetValue = parseFloat(targetValue.replace(/,/g, '')) | ||
| 870 | } | ||
| 871 | } | ||
| 872 | builtInTarget.push({ | ||
| 873 | ...item, | ||
| 874 | targetValue | ||
| 875 | }) | ||
| 876 | }) | ||
| 940 | params.dictionaryJson = Object.keys(dictionaryJson).length ? JSON.stringify(dictionaryJson) : ''; | 877 | params.dictionaryJson = Object.keys(dictionaryJson).length ? JSON.stringify(dictionaryJson) : ''; |
| 878 | params.builtIndicators = builtInTarget; | ||
| 941 | let demandMatchingData: any = []; | 879 | let demandMatchingData: any = []; |
| 942 | tableData.value.map(item => { | 880 | tableData.value.map(item => { |
| 943 | demandMatchingData.push({ | 881 | demandMatchingData.push({ |
| ... | @@ -967,15 +905,16 @@ const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { | ... | @@ -967,15 +905,16 @@ const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => { |
| 967 | const getCalculatPrice = async (params) => { | 905 | const getCalculatPrice = async (params) => { |
| 968 | try { | 906 | try { |
| 969 | const res: any = await calculatPrice(params); | 907 | const res: any = await calculatPrice(params); |
| 908 | loading.value = false; | ||
| 970 | if (res.code === proxy.$passCode) { | 909 | if (res.code === proxy.$passCode) { |
| 971 | const data = res.data || {}; | 910 | const data = res.data || {}; |
| 972 | return data; // 返回计算结果以便后续使用 | 911 | return data; // 返回计算结果以便后续使用 |
| 973 | } else { | 912 | } else { |
| 974 | proxy.$ElMessage.error(res.msg); | 913 | proxy.$ElMessage.error(res.msg); |
| 975 | loading.value = false; | ||
| 976 | throw new Error(res.msg); // 抛出错误以便 catch 捕获 | 914 | throw new Error(res.msg); // 抛出错误以便 catch 捕获 |
| 977 | } | 915 | } |
| 978 | } catch (error) { | 916 | } catch (error) { |
| 917 | console.error('计算价格失败:', error); | ||
| 979 | loading.value = false; | 918 | loading.value = false; |
| 980 | throw error; // 重新抛出错误 | 919 | throw error; // 重新抛出错误 |
| 981 | } | 920 | } |
| ... | @@ -994,10 +933,8 @@ const checkForm = (type) => { | ... | @@ -994,10 +933,8 @@ const checkForm = (type) => { |
| 994 | const priceData = await getCalculatPrice(paramsInfo); | 933 | const priceData = await getCalculatPrice(paramsInfo); |
| 995 | // 显示结果 | 934 | // 显示结果 |
| 996 | dataTransactionPrice.value = priceData.transactionPrice.toFixed(2); | 935 | dataTransactionPrice.value = priceData.transactionPrice.toFixed(2); |
| 997 | 936 | if (type == 'export') { | |
| 998 | if (type == 'calculate') { | 937 | loading.value = true; |
| 999 | loading.value = false; | ||
| 1000 | } else if (type == 'export') { | ||
| 1001 | const exportOut = { | 938 | const exportOut = { |
| 1002 | one: priceData.one, | 939 | one: priceData.one, |
| 1003 | two: priceData.two, | 940 | two: priceData.two, |
| ... | @@ -1021,11 +958,12 @@ const checkForm = (type) => { | ... | @@ -1021,11 +958,12 @@ const checkForm = (type) => { |
| 1021 | message: '下载报告请求失败', | 958 | message: '下载报告请求失败', |
| 1022 | }); | 959 | }); |
| 1023 | }) | 960 | }) |
| 1024 | } else { | 961 | } else if (type == 'submit') { |
| 1025 | let params = { | 962 | let params = { |
| 1026 | ...paramsInfo, | 963 | ...paramsInfo, |
| 1027 | dataTransactionPrice: dataTransactionPrice.value, | 964 | dataTransactionPrice: dataTransactionPrice.value, |
| 1028 | } | 965 | } |
| 966 | loading.value = true; | ||
| 1029 | savePrice(params).then((res: any) => { | 967 | savePrice(params).then((res: any) => { |
| 1030 | loading.value = false; | 968 | loading.value = false; |
| 1031 | if (res.code == proxy.$passCode) { | 969 | if (res.code == proxy.$passCode) { |
| ... | @@ -1058,6 +996,11 @@ const btnClick = async (btn, row: any = null) => { | ... | @@ -1058,6 +996,11 @@ const btnClick = async (btn, row: any = null) => { |
| 1058 | expendTableRef.value.toggleRowExpansion(row); | 996 | expendTableRef.value.toggleRowExpansion(row); |
| 1059 | } else if (type == 'calculate' || type == 'submit') { | 997 | } else if (type == 'calculate' || type == 'submit') { |
| 1060 | if (type == 'submit') { | 998 | if (type == 'submit') { |
| 999 | const errorMsgText = document.querySelectorAll('.el-form-item__error'); | ||
| 1000 | if (errorMsgText.length) { | ||
| 1001 | ElMessage.info('请修改错误提示项内容后,再操作'); | ||
| 1002 | return | ||
| 1003 | } | ||
| 1061 | ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并提交' : '请确认当前数据交易价格是否为最新计算结果', '提示', { | 1004 | ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并提交' : '请确认当前数据交易价格是否为最新计算结果', '提示', { |
| 1062 | confirmButtonText: '确定', | 1005 | confirmButtonText: '确定', |
| 1063 | cancelButtonText: '取消', | 1006 | cancelButtonText: '取消', |
| ... | @@ -1121,7 +1064,6 @@ onBeforeMount(() => { | ... | @@ -1121,7 +1064,6 @@ onBeforeMount(() => { |
| 1121 | getDetail(); | 1064 | getDetail(); |
| 1122 | } else { | 1065 | } else { |
| 1123 | getDataTypeList(); | 1066 | getDataTypeList(); |
| 1124 | getModel() | ||
| 1125 | } | 1067 | } |
| 1126 | }) | 1068 | }) |
| 1127 | onMounted(() => { | 1069 | onMounted(() => { |
| ... | @@ -1214,16 +1156,11 @@ onMounted(() => { | ... | @@ -1214,16 +1156,11 @@ onMounted(() => { |
| 1214 | clearable /> | 1156 | clearable /> |
| 1215 | </template> | 1157 | </template> |
| 1216 | </el-table-column> | 1158 | </el-table-column> |
| 1217 | <el-table-column label="操作" fixed="right" width="100"> | ||
| 1218 | <template #default="scope"> | ||
| 1219 | <el-button type="primary" link @click="btnClick({ value: 'expend' }, scope.row)">字段映射</el-button> | ||
| 1220 | </template> | ||
| 1221 | </el-table-column> | ||
| 1222 | </el-table> | 1159 | </el-table> |
| 1223 | </div> | 1160 | </div> |
| 1224 | </div> | 1161 | </div> |
| 1225 | </ContentWrap> | 1162 | </ContentWrap> |
| 1226 | <ContentWrap id="contract-content-wrap" title="输出结构" expandSwicth style="margin-top: 15px" :isExpand="expand3" | 1163 | <ContentWrap id="contract-content-wrap" title="输出结果" expandSwicth style="margin-top: 15px" :isExpand="expand3" |
| 1227 | @expand="(v) => expand3 = v"> | 1164 | @expand="(v) => expand3 = v"> |
| 1228 | <el-form class="result-form"> | 1165 | <el-form class="result-form"> |
| 1229 | <el-form-item class="flex-column" label="数据交易价格(元)"> | 1166 | <el-form-item class="flex-column" label="数据交易价格(元)"> | ... | ... |
-
Please register or sign in to post a comment