7d41b35c by lxs Committed by lihua

数据定价更新

1 parent 9eb1c020
...@@ -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="数据交易价格(元)">
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!