2d0b4959 by lihua

添加新的计算定价页面

1 parent 71fa1604
......@@ -121,6 +121,36 @@ const routes: RouteRecordRaw[] = [
}
}
},
{
path: 'price-calculate-new',
name: 'priceCalculateNew',
component: () => import('@/views/data_pricing/priceCalculateNew.vue'),
meta: {
title: '数据定价(新)',
breadcrumb: false,
cache: true
}
},
{
path: 'calculate-config-new',
name: 'calculateConfigNew',
component: () => import('@/views/data_pricing/calculateConfigNew.vue'),
meta: {
title: '新增数据定价',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true,
activeMenu: '/data-pricing/pricing-manage/price-calculate-new'
},
beforeEnter: (to, from) => {
if (to.query.guid) {
to.meta.title = `编辑-${to.query.name}`;
} else {
to.meta.title = `新增数据定价`;
}
}
},
],
},
]
......
......@@ -313,7 +313,7 @@ const setDictFormItems = (dictList) => {
required: true,
});
baseConfigFormRules.value[dictField] = [{ required: true, trigger: 'change', message: `请选择${dictName}` }];
dictName == '数据用途' && (dataUsage.value.field = dictField);
d.dictionaryName == '数据用途' && (dataUsage.value.field = dictField);
(() => {
if (typeMap.value[dictField] == undefined) {
getDataType(d.dictionaryName, dictField)
......
<route lang="yaml">
name: calculateConfig
</route>
<script lang="ts" setup name="calculateConfig">
import { ref, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import useUserStore from "@/store/modules/user";
import useDataAssetStore from "@/store/modules/dataAsset";
import { getAllFlowData } from '@/api/modules/queryService';
import { download } from '@/utils/common'
import {
getConfigureList,
getConfigureDetail,
getDiseaseAll,
getPriceDetail,
getDemandList,
getModelScore,
savePrice,
getModelDemand,
getPriceResult,
exportModelScore,
calculatPrice
} from '@/api/modules/dataPricing';
import { changeNum } from "@/utils/common";
import { useValidator } from '@/hooks/useValidator';
const { required } = useValidator();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
const assetStore = useDataAssetStore();
const fullPath = route.fullPath;
const userData = JSON.parse(localStorage.userData);
const guid = route.query.guid;
const priceName = route.query.name;
const loading = ref(false);
const flowDetail: any = ref({});
const typeMap: any = ref({});
const expandProduct = ref(true);
const expand1 = ref(true)
const expand3 = ref(true)
const demandTableList: any = ref([]);
const pricingTargetList: any = ref([]);
const demandTableFieldAllNum = ref(0);
const resourceTableAllNum = ref(0);
const resourceTableFieldAllNum = ref(0);
const modelData: any = ref({});
const pricingDimensionalityData: any = ref([]);
const dictionaryData: any = ref([]);
const diseaseData: any = ref([]);
const qualityScoreData: any = ref({});
const disScore: any = ref([]);
const buildInData: any = ref([]);
const dataUsage = ref({
field: '',
dictValue: ''
});
const currModelGuid = ref('');
const productConfigFormRef = ref();
/** 产品信息配置表单信息 */
const productConfigFormItems = ref([{
label: '企业名称',
type: 'input',
placeholder: '请输入',
field: 'companyName',
default: '',
required: true,
maxlength: 100,
visible: true
}, {
label: '联系人',
type: 'input',
placeholder: '请输入',
field: 'contactPerson',
default: '',
required: true,
maxlength: 50,
visible: true
}, {
label: '联系方式',
type: 'input',
placeholder: '请输入',
field: 'contactInformation',
default: '',
required: true,
maxlength: 50,
visible: true
}, {
label: '数据产品名称',
type: 'input',
placeholder: '请输入',
field: 'damName',
default: '',
required: true,
maxlength: 50,
visible: true
}, {
label: '产品简介',
placeholder: '该输入',
field: 'productDesc',
type: 'textarea',
default: '',
maxlength: 250,
block: true,
clearable: true,
required: true,
}]);
const productConfigFormRules = ref({
companyName: [required('请填写企业名称')],
contactPerson: [required('请填写联系人')],
contactInformation: [required('请填写联系方式')],
damName: [required('请填写产品名称')],
productDesc: [required('请填写产品简介')],
});
// 基础设置
const baseConfigFormRef = ref();
const baseConfigFormItems: any = ref([
{
label: '模型名称',
type: 'select',
placeholder: '请选择',
field: 'modelGuid',
default: '',
options: [],
props: {
label: "modelName",
value: "guid",
},
clearable: true,
filterable: true,
required: true
},
{
label: '数据资源名称',
type: 'input',
placeholder: '请输入',
field: 'dataResourceGuid',
maxlength: 50,
default: '',
clearable: true,
required: true
},
// {
// label: '数据资源',
// type: 'select',
// placeholder: '请选择',
// field: 'dataResourceGuid',
// default: '',
// options: [],
// props: {
// label: "damName",
// value: "guid",
// },
// clearable: true,
// filterable: true,
// required: true,
// },
// {
// label: '所属主体',
// type: 'input',
// placeholder: '',
// field: 'belongingEntityGuid',
// default: '',
// clearable: true,
// disabled: true
// },
// {
// label: '所属主题',
// type: 'tree-select',
// placeholder: '请选择',
// field: 'belongingTheme',
// default: '',
// options: [],
// showAllLevels: false,
// checkStrictly: false,//只能选择叶子节点。
// lazy: false,
// props: {
// label: "label",
// value: "value",
// children: 'childDictList'
// },
// filterable: true,
// clearable: true,
// disabled: true
// },
])
const baseConfigFormRules: any = ref({
modelGuid: [
{ required: true, trigger: 'change', message: "请选择模型名称" }
],
dataResourceGuid: [
{ required: true, trigger: 'blur', message: "请填写数据资源" }
],
});
const baseConfigForm = ref({
items: baseConfigFormItems.value,
rules: baseConfigFormRules.value,
})
const tableFields: any = ref([
{ label: '需求表', field: 'demandTableName', type: 'input', width: 200, disabled: true },
{ label: '数据资源表', field: 'dataTableGuid', type: 'select', width: 200 },
{ label: '表描述', field: 'tableDescription', type: 'input', width: 200, disabled: true },
{ label: '需求表权重(%)', field: 'weightDemandTable', type: 'input', width: 140, disabled: true },
])
const expendTableRef = ref();
const tableData: any = ref([]);
const tableLoading = ref(false);
const dataTransactionPrice: any = ref('');
const setFormItems = (info = null) => {
let datas: any = info || flowDetail.value || {};
const dictData = datas.dictionaryJson ? JSON.parse(datas.dictionaryJson) : {};
const builtIndicators = datas.builtIndicators || buildInData.value || [];
let buildData = {};
builtIndicators.map(item => {
buildData[`build_${item.guid}`] = item.isInputParameter != 'Y' ? changeNum(item.targetValue, 2) : item.targetValue != '' && item.targetValue != null ? parseFloat(item.targetValue).toFixed(2) : '';
});
datas = { ...datas, ...dictData, ...buildData };
baseConfigFormItems.value.map(item => {
item.default = datas[item.field] || '';
item.label == '数据用途' && (dataUsage.value.dictValue = datas[item.field] || '');
})
nextTick(() => {
baseConfigFormRef.value.ruleFormRef?.clearValidate();
})
}
/**
* 传入多个promise对象,当全部结束时取消Loading
* @param promises 传入多个promise对象,当全部结束时取消Loading
*/
const promiseList = (...promises: Promise<void>[]) => {
// loading方法全局封装成一个组件
!guid && (loading.value = true);
try {
Promise.all(promises).then(res => {
loading.value = false;
});
} catch (e) {
loading.value = false;
} finally {
!guid && (loading.value = false);
}
};
// 获取模型
const getModel = () => {
getConfigureList({ pageSize: -1, pageIndex: 1, bizState: 'Y' }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data.records || [];
typeMap.value.modelGuid = JSON.parse(JSON.stringify(data));
let item = baseConfigFormItems.value.find(item => item.field == 'modelGuid');
item && (item.options = data);
}
})
}
// 获取所有疾病数据
const getDiseaseData = () => {
getDiseaseAll().then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
typeMap.value.diseaseGuid = JSON.parse(JSON.stringify(data));
let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid');
if (item) {
item.options = typeMap.value['diseaseGuid'];
if (guid) {
const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid);
if (!diseaseData) {
item.options.unshift({
guid: flowDetail.value.diseaseGuid,
diseaseName: flowDetail.value.diseaseName
});
}
}
}
}
})
}
// 获取数据资源
// const getDataCatalog = () => {
// return getDamCatalogList({ dataType: userData.superTubeFlag == 'Y' ? "P" : "D", sceneType: "D" }).then((res: any) => {
// if (res.code == proxy.$passCode) {
// let data = res.data || [];
// data.map(item => item.damGuid = item.guid);
// typeMap.value.dataResourceGuid = JSON.parse(JSON.stringify(data));
// let item = baseConfigFormItems.value.find(item => item.field == 'dataResourceGuid');
// if (item) {
// item.options = data;
// if (guid) {
// const rItem = typeMap.value.dataResourceGuid.find(m => m.damGuid == flowDetail.value.dataResourceGuid);
// if (!rItem) {
// const rtem = { damGuid: flowDetail.value.dataResourceGuid, damName: flowDetail.value.dataResourceName };
// item.options.unshift(rtem);
// typeMap.value.dataResourceGuid.unshift(rtem);
// }
// }
// }
// }
// })
// }
// 获取数据资源主题
const getSourceThem = (dictType, fieldName) => {
return getAllFlowData({ dictType }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
let item = baseConfigFormItems.value.find(item => item.field == fieldName);
item && (item.options = data);
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
// 获取数据字典
const getDataType = (dictType, fieldName) => {
getAllFlowData({ dictType }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
let item = baseConfigFormItems.value.find(item => item.field == fieldName);
item && (item.options = data);
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
// 获取详情
const getDetail = () => {
loading.value = true;
getPriceDetail({ guid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {};
flowDetail.value = data;
dataTransactionPrice.value = flowDetail.value.dataTransactionPrice;
dataUsage.value.dictValue = data.dataUsage || '';
currModelGuid.value = flowDetail.value.modelGuid;
const mItem = typeMap.value.modelGuid.find(m => m.guid == flowDetail.value.modelGuid);
if (!mItem) {
const mtem = { guid: flowDetail.value.modelGuid, modelName: flowDetail.value.modelName };
typeMap.value.modelGuid.unshift(mtem);
baseConfigFormItems.value[0].options.unshift(mtem);
};
productConfigFormItems.value.forEach(item => {
item.default = flowDetail.value[item.field] || '';
})
getModelInfo(flowDetail.value.modelGuid);
// getDataTypeList()
}
}).catch(() => {
loading.value = false;
})
}
// const getDataTypeList = () => {
// if (guid) {
// promiseList(
// // getDataCatalog(),
// // getSourceThem('数据资产目录主题名称', 'belongingTheme'),
// getQuilityModelScore(flowDetail.value.dataResourceGuid)
// )
// }
// }
// 设置数据字典选项
const setDictFormItems = (dictList) => {
dictList.map(d => {
const dictName = d.targetName;
const dictField = `dict_${d.guid}`;
baseConfigFormItems.value.push({
label: dictName,
type: 'select',
placeholder: '请选择',
field: dictField,
default: '',
options: [],
clearable: true,
filterable: true,
required: true,
});
baseConfigFormRules.value[dictField] = [{ required: true, trigger: 'change', message: `请选择${dictName}` }];
d.dictionaryName == '数据用途' && (dataUsage.value.field = dictField);
(() => {
if (typeMap.value[dictField] == undefined) {
getDataType(d.dictionaryName, dictField)
} else {
let item = baseConfigFormItems.value.find(item => item.field == dictField);
item && (item.options = typeMap.value[dictField]);
}
})()
})
}
// 设置疾病选项
const setDiseaseFormItems = () => {
baseConfigFormItems.value.push({
label: '所属疾病',
type: 'cascader',
placeholder: '请选择',
field: 'diseaseGuid',
default: '',
options: [],
showAllLevels: false,
props: {
checkStrictly: true,
label: "diseaseName",
value: "guid",
children: 'childList',
emitPath: false
},
filterable: true,
clearable: true,
required: true,
});
baseConfigFormRules.value.diseaseGuid = [{ required: true, trigger: 'change', message: "请选择所属疾病" }];
if (typeMap.value['diseaseGuid'] == undefined) {
getDiseaseData();
} else {
let item = baseConfigFormItems.value.find(item => item.field == 'diseaseGuid');
if (item) {
item.options = typeMap.value['diseaseGuid'];
const diseaseData = typeMap.value.diseaseGuid.find(m => m.guid == flowDetail.value.diseaseGuid);
if (!diseaseData) {
item.options.unshift({
guid: flowDetail.value.diseaseGuid,
diseaseName: flowDetail.value.diseaseName
});
}
}
}
}
// 设置内置指标选项
const setBuildInFormItems = (buildList) => {
buildList.map(b => {
const buildName = b.targetName;
const buildField = `build_${b.guid}`;
buildInData.value.push({
guid: b.guid,
targetName: buildName,
targetValue: b.defaultValue || '',
isInputParameter: b.isInputParameter,
})
baseConfigFormItems.value.push({
label: buildName,
type: 'input',
placeholder: '',
field: buildField,
default: b.isInputParameter != 'Y' ? changeNum(b.defaultValue, 2) : b.defaultValue != '' && b.defaultValue != null ? parseFloat(b.defaultValue).toFixed(2) : '',
inputType: 'moneyNumber',
maxlength: 18,
clearable: true,
disabled: b.isInputParameter != 'Y',
required: true
});
baseConfigFormRules.value[buildField] = [
{ required: true, message: `请填写${buildName}`, trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (value === '') {
callback(new Error(`请填写${buildName}`));
return;
}
const num = parseFloat(value);
if (isNaN(num)) {
callback(new Error('请输入有效的数字'));
return;
}
// 已自动保留两位小数,不需再验证小数位数
if (num < 0 || num > b.defaultValue) {
callback(new Error(`输入值必须在0到${b.defaultValue}之间`));
} else {
callback();
}
}, trigger: "blur",
},
]
})
};
// 添加表单选项数据
const setFormItemData = async () => {
let dictionaryList: any = [], diseaseList: any = [], buildInList: any = [];
pricingTargetList.value.map(item => {
switch (item.targetType) {
case '2':
item.functionName == '2' && diseaseList.push(item);
break;
case '3':
dictionaryList.push(item);
break;
case '1':
buildInList.push(item);
break;
default:
break;
}
})
dictionaryData.value = dictionaryList;
diseaseData.value = diseaseList;
if (diseaseList.length) {
const diseaseName = flowDetail.value.diseaseName || '';
const modelGuid = flowDetail.value.modelGuid || '';
// 获取疾病得分
if (diseaseName && modelGuid) {
getTargetNum({ diseaseName, guid: modelGuid });
}
}
baseConfigFormItems.value.splice(4);
for (var r in baseConfigFormRules.value) {
if (r != 'modelGuid' && r != 'dataResourceGuid') {
delete baseConfigFormRules.value[r];
}
}
// 添加所属疾病
diseaseList.length > 0 && await setDiseaseFormItems();
// 添加数据字典
dictionaryList.length > 0 && await setDictFormItems(dictionaryList);
// 添加内置指标
buildInList.length > 0 && await setBuildInFormItems(buildInList);
setTimeout(() => {
baseConfigFormRef.value.ruleFormRef?.clearValidate();
}, 100)
}
const setdemandTableData = (mGuid = '') => {
const tList = flowDetail.value.dataPricingDemandmatchingRQVOS || demandTableList.value || [];
let tDatas: any = [];
if (guid) {
if (mGuid) {
tDatas = mGuid == flowDetail.value.modelGuid ? tList : demandTableList.value || [];
} else {
tDatas = tList;
}
} else {
tDatas = tList;
}
setTableData(JSON.parse(JSON.stringify(tDatas)))
}
const setTableData = (dataArr) => {
tableData.value.splice(0);
dataArr.map((item, i) => {
const demInfo = pricingTargetList.value.find(t => t.demandTableGuid == (item.demandTableGuid || item.guid));
const demWeight = demInfo?.weight || '';
tableData.value.push({
...item,
demandTableName: item.demandTableName || item.menuName,
dataTableGuid: item.dataTableGuid || '',
tableDescription: item.tableDescription || '',
weightDemandTable: item.weightDemandTable ? parseFloat(item.weightDemandTable).toFixed(2) : (demWeight ? parseFloat(demWeight).toFixed(2) : ''),
dataFields: item.pricingDemandFieldRQVOS || [],
dataFieldsNum: item.dataFieldsNum || 0,
})
if ((item.demandTableGuid || item.guid)) {
const rGuid = item.demandTableGuid || item.guid;
const rIndex = i;
(() => {
getDemandField(rGuid, rIndex);
})()
}
})
resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => {
return accumulator + Number(currentValue.dataFieldsNum);
}, 0);
setTimeout(() => {
tableData.value.map(t => {
expendTableRef.value.toggleRowExpansion(t);
})
}, 200)
}
// 获取模型配置信息
const getModelConfig = (mGuid) => {
return getModelDemand({ guid: mGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
demandTableList.value = data.pricingDemandMenuRSVOS || [];
pricingTargetList.value = data.pricingTargetRSVOS || [];
demandTableFieldAllNum.value = data.fieldCount || 0;
buildInData.value = [];
}
})
}
// 获取模型详情
const getModelDetail = (mGuid) => {
return getConfigureDetail({ guid: mGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
modelData.value = data;
const pricingDimensionality = data.pricingDimensionalityRSVOS || [];
let tData: any = [];
pricingDimensionality.map(p => {
p.pricingTargetRSVOS.map(t => {
tData.push({ ...p, ...t })
})
})
pricingDimensionalityData.value = tData;
}
})
}
// 获取质量模型评分
const getQuilityModelScore = (sGuid) => {
return getModelScore({ damGuid: sGuid }).then((res: any) => {
if (res.code === proxy.$passCode) {
const data = res.data || {};
qualityScoreData.value = data;
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
// 獲取模型相关信息
const getModelInfo = (mGuid) => {
const promises: any = [
getModelConfig(mGuid),
getModelDetail(mGuid)
];
try {
loading.value = true;
Promise.all(promises).then(res => {
loading.value = false;
setFormItemData();
if (guid && mGuid == flowDetail.value.modelGuid) {
dataTransactionPrice.value = flowDetail.value.dataTransactionPrice;
setTimeout(() => {
// getResourceDetail(flowDetail.value.dataResourceGuid, false);
setFormItems();
setdemandTableData(mGuid);
}, 200);
} else {
setdemandTableData(mGuid);
}
});
} catch (e) {
loading.value = false;
}
}
// 获取数据资源管理信息
// const getResourceInfo = (sGuid) => {
// const promises: any = [/*getResourceDetail(sGuid),*/ getQuilityModelScore(sGuid)];
// try {
// loading.value = true;
// Promise.all(promises).then(res => {
// loading.value = false;
// });
// } catch (e) {
// loading.value = false;
// }
// }
// // 需求表字段匹配
// const matchTableFields = (rData, tData) => {
// rData.dataFields.map(t => {
// const match = tData.find(d => d.chName == t.fieldName);
// if (match) {
// t.chName = match.chName;
// t.enName = match.enName;
// }
// })
// rData.dataFieldsNum = rData.dataFields.filter(item => item.chName != '' && item.chName != null).length;
// resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => {
// return accumulator + Number(currentValue.dataFieldsNum);
// }, 0);
// }
// const setRowData = (rowData, dGuid, detailDataTable) => {
// if (guid && dGuid == rowData.dataTableGuid) {
// const pricingDemandField = detailDataTable?.pricingDemandFieldRQVOS || [];
// rowData.dataFields.map(f => {
// f.chName = pricingDemandField.find(s => f.guid == s.guid)?.chName || ''
// })
// } else {
// rowData.dataFields.map(f => f.chName = '')
// }
// const damData = rowData.damDataTable.find(item => item.guid == dGuid);
// rowData.tableDescription = damData?.tableDescription || '';
// rowData.dataFieldsNum = rowData.dataFields.filter(item => item.chName != '' && item.chName != null).length;
// resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => {
// return accumulator + Number(currentValue.dataFieldsNum);
// }, 0);
// resourceTableAllNum.value = tableData.value.filter(item => item.dataTableGuid != '' && item.dataTableGuid != null).length;
// }
// const setTableRowData = (dGuid, rIndex, setRow = true) => {
// let rowData = tableData.value[rIndex];
// const detailDataTable = (flowDetail.value.dataPricingDemandmatchingRQVOS || []).find(f => f.dataTableGuid == dGuid && f.demandTableGuid == rowData.demandTableGuid);
// setRow && setRowData(rowData, dGuid, detailDataTable);
// const currDataTableGuid = detailDataTable?.dataTableGuid || '';
// if (dGuid) {
// tableLoading.value = true;
// getRegisterCatalogTableDetail(dGuid).then((res: any) => {
// tableLoading.value = false;
// if (res.code == proxy.$passCode) {
// const data = res.data || {};
// const damTableField = data.damCatalogTableField || [];
// const damFieldOptions = damTableField.map(d => {
// return {
// ...d,
// label: d.chName || '',
// value: d.chName || ''
// }
// })
// rowData.dataFields.map(t => {
// t.damFieldTable = JSON.parse(JSON.stringify(damFieldOptions));
// })
// // 匹配
// if (!guid || (guid && (dGuid != currDataTableGuid || currModelGuid.value != flowDetail.value.modelGuid))) {
// matchTableFields(rowData, damTableField);
// }
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// }).catch(() => {
// tableLoading.value = false;
// })
// }
// }
// const changeDatasource = () => {
// baseConfigFormItems.value.map(item => {
// if (item.field == 'belongingEntityGuid') {
// item.default = '';
// } else if (item.field == 'belongingTheme') {
// item.default = '';
// }
// })
// }
const cascaderChange = (val) => {
disScore.value = [];
if (val) {
const baseConfigFormObj = baseConfigFormRef.value;
const baseConfigFormInfo = baseConfigFormObj.formInline;
const parentsData = baseConfigFormObj.getCascaderCheckedData();
const diseaseName = parentsData[0]?.label || '';
const modelGuid = baseConfigFormInfo.modelGuid;
// 获取疾病得分
getTargetNum({ diseaseName, guid: modelGuid });
}
}
const selectChange = async (val, row, info) => {
dataTransactionPrice.value = '';
if (row.field == 'modelGuid') {
tableData.value = [];
demandTableFieldAllNum.value = 0;
resourceTableAllNum.value = 0;
resourceTableFieldAllNum.value = 0;
await setFormItems(info);
val && getModelInfo(val);
currModelGuid.value = val || '';
qualityScoreData.value = {};
baseConfigFormItems.value[1].default = '';
// changeDatasource();
}
// else if (row.field == 'dataResourceGuid') {
// await setFormItems(info);
// qualityScoreData.value = {};
// resourceTableAllNum.value = 0;
// resourceTableFieldAllNum.value = 0;
// if (val) {
// getResourceInfo(val);
// } else {
// changeDatasource();
// }
// }
else if (row.field == dataUsage.value.field) {
dataUsage.value.dictValue = val || '';
setFormItems(info);
}
// else if (row.field == 'dataTableGuid') {
// setTableRowData(val, info.$index)
// } else if (row.field == 'chName') {
// let tData = info.row;
// if (val) {
// const damData = tData.dataFields[row.index].damFieldTable.find(item => item.chName == val);
// tData.dataFields[row.index].enName = damData?.enName || '';
// } else {
// tData.dataFields[row.index].enName = '';
// }
// tData.dataFieldsNum = tData.dataFields.filter(item => item.chName != '' && item.chName != null).length;
// resourceTableFieldAllNum.value = tableData.value.reduce((accumulator, currentValue) => {
// return accumulator + Number(currentValue.dataFieldsNum);
// }, 0);
// }
else {
setFormItems(info);
}
}
// 获取需求表字段
const getDemandField = (rGuid, rIndex) => {
getDemandList({
pageSize: -1,
pageIndex: 1,
relationMenuGuid: rGuid,
bizState: 'Y'
}).then((res: any) => {
tableLoading.value = false;
if (res.code == proxy.$passCode) {
const data = res.data || {};
const fData = data.records || [];
const tFields = tableData.value[rIndex].dataFields;
const tData = fData.map(item => {
const iData = tFields.find(t => t.demandFieldGuid == item.guid) || {};
return {
...item,
fieldName: item.fieldName,
isRequired: item.isRequired,
chName: item.chName || '',
enName: item.enName || '',
...iData
}
});
tableData.value[rIndex].dataFields = tData;
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
tableLoading.value = false;
})
}
const toPath = () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: 'priceCalculate',
})
}
// 获取疾病得分
const getTargetNum = (params) => {
// loading.value = true;
getPriceResult(params).then((res: any) => {
// loading.value = false;
if (res.code === proxy.$passCode) {
const data = res.data || [];
disScore.value = data;
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
// loading.value = false;
});
}
// 获取定价计算配置参数
const getCalculateParams = (baseConfigFormObj, baseConfigFormInfo) => {
let companyInfo = productConfigFormRef.value.formInline;
const modelName = typeMap.value.modelGuid.find(d => d.guid == baseConfigFormInfo.modelGuid)?.modelName || '';
// const dataResourceName = typeMap.value.dataResourceGuid.find(d => d.damGuid == baseConfigFormInfo.dataResourceGuid)?.damName || '';
const diseaseGuid = baseConfigFormInfo.diseaseGuid || '';
let params: any = {
tenantGuid: userData.tenantGuid,
dataTransactionPrice: dataTransactionPrice.value,
modelGuid: baseConfigFormInfo.modelGuid,
modelName,
dataResourceGuid: baseConfigFormInfo.dataResourceGuid,
dataResourceName: baseConfigFormInfo.dataResourceGuid,
belongingEntityGuid: companyInfo.companyName,
belongingTheme: baseConfigFormInfo.belongingTheme,
diseaseGuid,
diseaseName: '',
dataUsage: dataUsage.value.dictValue
};
Object.assign(params, companyInfo);
if (diseaseGuid) {
const parentsData = baseConfigFormObj.getCascaderCheckedData();
params.diseaseName = parentsData[0]?.label || '';
}
let dictionaryJson = {}, builtInTarget: any = [];
for (var b in baseConfigFormInfo) {
if (b.indexOf('dict_') > -1) {
dictionaryJson[b] = baseConfigFormInfo[b];
}
}
buildInData.value.map(item => {
let targetValue = baseConfigFormInfo[`build_${item.guid}`];
if (typeof targetValue === 'string') {
if (/^[+-]?\d{1,3}(,\d{3})*(\.\d{2})?$/.test(targetValue)) {
targetValue = parseFloat(targetValue.replace(/,/g, ''))
}
}
builtInTarget.push({
...item,
targetValue
})
})
params.dictionaryJson = Object.keys(dictionaryJson).length ? JSON.stringify(dictionaryJson) : '';
params.builtIndicators = builtInTarget;
let demandMatchingData: any = [];
tableData.value.map(item => {
demandMatchingData.push({
demandTableName: item.demandTableName,
demandTableGuid: item.demandTableGuid || item.guid, // 需求表guid
dataTableGuid: item.dataTableGuid || '', // 数据资源表guid
weightDemandTable: item.weightDemandTable,
dataFieldsNum: item.dataFieldsNum,
pricingDemandFieldRQVOS: item.dataFields.map(d => {
return {
demandFieldGuid: d.demandFieldGuid || d.guid, // 资源表字段guid
fieldName: d.fieldName,
enName: d.enName,
chName: d.chName,
isRequired: d.isRequired,
orderNum: d.orderNum
}
})
})
});
params.dataPricingDemandmatchingRQVOS = demandMatchingData;
guid && (params.guid = guid);
return params;
}
// 获取定价计算结构
const getCalculatPrice = async (params) => {
try {
const res: any = await calculatPrice(params);
loading.value = false;
if (res.code === proxy.$passCode) {
const data = res.data || {};
return data; // 返回计算结果以便后续使用
} else {
proxy.$ElMessage.error(res.msg);
throw new Error(res.msg); // 抛出错误以便 catch 捕获
}
} catch (error) {
console.error('计算价格失败:', error);
loading.value = false;
throw error; // 重新抛出错误
}
};
// 计算结果和提交
const checkForm = (type) => {
const baseConfigFormObj = baseConfigFormRef.value;
const baseConfigFormEl = baseConfigFormObj.ruleFormRef;
const baseConfigFormInfo = baseConfigFormObj.formInline;
productConfigFormRef.value.ruleFormRef.validate((valid1, errorItem) => {
if (valid1) {
baseConfigFormEl.validate(async (valid, errorItem) => {
if (valid) {
const paramsInfo = getCalculateParams(baseConfigFormObj, baseConfigFormInfo);
loading.value = true;
// 先获取计算结果
const priceData = await getCalculatPrice(paramsInfo);
// 显示结果
dataTransactionPrice.value = priceData.transactionPrice.toFixed(2);
if (type == 'export') {
loading.value = true;
const exportOut = {
one: priceData.one,
two: priceData.two,
three: priceData.three,
}
exportModelScore(exportOut).then((res: any) => {
loading.value = false;
if (res && !res.msg) {
ElMessage({
type: "success",
message: '下载报告成功',
});
download(res, `数据定价报告.doc`, 'word');
} else {
res?.msg && ElMessage.error(res?.msg);
}
}).catch(() => {
loading.value = false;
ElMessage({
type: "error",
message: '下载报告请求失败',
});
})
} else if (type == 'submit') {
let params = {
...paramsInfo,
dataTransactionPrice: dataTransactionPrice.value,
}
loading.value = true;
savePrice(params).then((res: any) => {
loading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: guid ? '编辑数据定价成功' : '新增数据定价成功',
});
toPath()
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
loading.value = false;
});
}
} else {
expand1.value = true;
var obj = Object.keys(errorItem);
baseConfigFormEl.scrollToField(obj[0]);
}
})
} else {
expandProduct.value = true;
var obj = Object.keys(errorItem);
productConfigFormRef.value.scrollToField(obj[0]);
baseConfigFormEl.validate((valid, errorItem1) => {
if (!valid) {
expand1.value = true;
}
})
}
})
}
const btnClick = async (btn, row: any = null) => {
const type = btn.value;
if (type == 'dim') {
baseConfigFormItems.value.at(-1).default += btn.name;
} else if (type == 'del-signatory') {
open('确定要删除该条维度数据吗?', 'warning');
} else if (type == 'expend') {
expendTableRef.value.toggleRowExpansion(row);
} else if (type == 'calculate' || type == 'submit') {
if (type == 'submit') {
const errorMsgText = document.querySelectorAll('.el-form-item__error');
if (errorMsgText.length) {
ElMessage.info('请修改错误提示项内容后,再操作');
return
}
ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并提交' : '请确认当前数据交易价格是否为最新计算结果', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
checkForm(type);
}).catch(() => {
ElMessage.info('已取消提交操作');
});
} else {
checkForm(type);
}
} else if (type == 'export') {
ElMessageBox.confirm(dataTransactionPrice.value === '' ? '是否直接计算价格并下载' : '请确认当前数据交易价格是否为最新计算结果', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
checkForm(type);
}).catch(() => {
ElMessage.info('已取消下载操作');
});
} else if (type == 'cancel') {
ElMessageBox.confirm(
"当前页面尚未保存,确定关闭吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
).then(() => {
toPath()
}).catch(() => {
ElMessage({
type: "info",
message: "已取消",
});
});
}
}
onActivated(() => {
let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath);
if (tab) {
switch (route.query.type) {
case 'create':
tab.meta.title = `新增数据定价`;
break;
case 'edit':
tab.meta.title = `编辑-${priceName}`;
break;
case 'detail':
tab.meta.title = `详情-${priceName}`;
break;
}
}
getModel()
})
onBeforeMount(() => {
if (guid) {
getDetail();
}
// else {
// getDataTypeList();
// }
})
onMounted(() => {
})
</script>
<template>
<div class="container_wrap full" v-loading="loading">
<div class="content_main panel">
<ContentWrap id="contract-content-wrap" title="产品信息" expandSwicth style="margin-top: 15px"
:isExpand="expandProduct" @expand="(v) => expandProduct = v">
<Form ref="productConfigFormRef" formId="product-content-form" :itemList="productConfigFormItems"
:rules="productConfigFormRules" col="col3" />
</ContentWrap>
<ContentWrap id="contract-content-wrap" title="输入参数" expandSwicth style="margin-top: 15px" :isExpand="expand1"
@expand="(v) => expand1 = v">
<Form ref="baseConfigFormRef" formId="contract-content-form" :itemList="baseConfigForm.items"
:rules="baseConfigForm.rules" col="col3" @selectChange="selectChange" @cascaderChange="cascaderChange" />
</ContentWrap>
<!-- <ContentWrap id="contract-signatory-wrap" title="需求匹配" expandSwicth style="margin-top: 15px" :isExpand="expand2"
@expand="(v) => expand2 = v">
<div class="table_panel_wrap">
<div class="table_tool">
<div class="tool_title">
<div class="title_desc">
<span>需求表数量:</span>
<span class="text-num">{{ demandTableList.length }}</span>
<span>张,字段数:</span>
<span class="text-num">{{ demandTableFieldAllNum }}</span>
<span>匹配表数量:</span>
<span class="text-num">{{ resourceTableAllNum }}</span>
<span>张,字段数:</span>
<span class="text-num">{{ resourceTableFieldAllNum }}</span>
</div>
</div>
</div>
<div class="table_panel" v-loading="tableLoading">
<el-table ref="expendTableRef" border :data="tableData" row-key="demandTableName" tooltip-effect="light"
style="height: 100%;">
<el-table-column type="expand">
<template #default="props">
<div class="expand_panel">
<div class="table_tool">
<div class="tool_title">
<div class="title_desc">
<span>需求字段数:</span>
<span class="text-num">{{ props.row.dataFields.length }}</span>
<span>个,匹配字段数:</span>
<span class="text-num">{{ props.row.dataFieldsNum }}</span>
</div>
</div>
</div>
<el-table :data="props.row.dataFields" border>
<el-table-column label="序号" type="index" width="56" align="center" />
<el-table-column label="需求字段中文" prop="fieldName" class-name="edit-col">
<template #default="scope">
<el-input v-model.trim="scope.row.fieldName" placeholder="请输入" disabled />
</template>
</el-table-column>
<el-table-column label="匹配字段中文" prop="chName" class-name="edit-col">
<template #default="scope">
<el-select v-model="scope.row.chName" clearable filterable
@change="val => selectChange(val, { field: 'chName', index: scope.$index }, props)">
<el-option v-for="(opt, o) in scope.row.damFieldTable" :label="opt.label" :value="opt.value"
:key="o" />
</el-select>
</template>
</el-table-column>
<el-table-column label="匹配字段英文" prop="enName" class-name="edit-col">
<template #default="scope">
<el-input v-model.trim="scope.row.enName" placeholder="请输入" disabled />
</template>
</el-table-column>
<el-table-column label="是否必需字段" prop="isRequired" class-name="edit-col">
<template #default="scope">
<el-select v-model="scope.row.isRequired" disabled>
<el-option label="是" value="Y" />
<el-option label="否" value="N" />
</el-select>
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column label="序号" type="index" width="56" align="center" />
<el-table-column v-for="item in tableFields" :key="item.field" :label="item.label" :prop="item.field"
:width="item.width" :align="item.align" class-name="edit-col">
<template #default="scope">
<el-select v-if="item.type == 'select'" v-model="scope.row[item.field]" clearable filterable
@change="val => selectChange(val, item, scope)">
<el-option v-for="(opt, o) in scope.row.damDataTable" :label="opt.label" :value="opt.value"
:key="o" />
</el-select>
<el-input v-else v-model.trim="scope.row[item.field]" :disabled="item.disabled" placeholder="请输入"
clearable />
</template>
</el-table-column>
</el-table>
</div>
</div>
</ContentWrap> -->
<ContentWrap id="contract-content-wrap" title="输出结果" expandSwicth style="margin-top: 15px" :isExpand="expand3"
@expand="(v) => expand3 = v">
<el-form class="result-form">
<el-form-item class="flex-column" label="数据交易价格(元)">
<el-input v-model="dataTransactionPrice" placeholder="" disabled style="display: none;" />
<div class="result-price">{{ changeNum(dataTransactionPrice, 2) }}</div>
</el-form-item>
<el-form-item class="align-end" style="margin-bottom: 14px;">
<el-button type="primary" @click="btnClick({ value: 'calculate' })">开始计算</el-button>
<!-- <el-button @click="btnClick({ value: 'export' })">下载报告</el-button> -->
<!-- <span style="margin-left: 8px">如需出具详细的定价报告,请联系后台管理员,谢谢!</span> -->
</el-form-item>
</el-form>
</ContentWrap>
</div>
<div class="tool_btns">
<div class="btns">
<el-button @click="btnClick({ value: 'cancel' })">取消</el-button>
<el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.container_wrap {
overflow: hidden;
.content_main {
height: calc(100% - 45px);
overflow: hidden auto;
&.panel {
padding: 0 16px 16px;
}
:deep(.el-card) {
&#contract-signatory-wrap {
.card-body-content {
padding: 8px 16px;
}
}
}
.signatory-tags {
margin-bottom: 11px;
}
.table_panel_wrap {
margin-bottom: 4px;
.table_tool {
height: 36px;
display: flex;
justify-content: space-between;
align-items: center;
.tool_title {
width: 100%;
display: flex;
justify-content: start;
}
.title_desc {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.text-num {
color: var(--el-color-primary);
margin: 0 8px;
}
}
}
.table_panel {
margin-bottom: 4px;
height: 392px;
:deep(.el-table) {
.el-table__cell {
&.edit-col {
padding: 4px 0;
.cell {
padding: 0 4px;
.el-cascader {
width: 100%;
height: 28px;
}
.el-input {
height: 28px;
}
}
}
.expand-icon {
color: #888;
margin-right: 8px;
vertical-align: text-bottom;
cursor: pointer;
}
}
.el-input.is-disabled .el-input__wrapper {
background-color: var(--el-disabled-bg-color);
}
.el-select__wrapper.is-disabled {
background-color: var(--el-disabled-bg-color);
}
}
.expand_panel {
padding: 6px;
margin: -6px 0;
background: #fff;
}
}
}
}
.btn-block {
width: 100%;
margin: 16px 0 8px;
}
.tool_btns {
height: 44px;
margin: 0 -8px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid #d9d9d9;
}
}
:deep(.el-form) {
&.result-form {
display: flex;
.el-form-item {
&.flex-column {
width: calc(33.33% - 6px);
margin-right: 8px;
display: flex;
flex-direction: column;
align-items: self-start;
.el-form-item__content {
width: 100%;
}
.result-price {
width: 100%;
height: 32px;
line-height: 32px;
padding: 1px 11px;
border-radius: 4px;
cursor: not-allowed;
color: var(--el-disabled-text-color);
background-color: var(--el-disabled-bg-color);
box-shadow: 0 0 0 1px var(--el-disabled-border-color) inset;
}
}
&.align-end {
align-self: flex-end;
}
}
}
.el-select__wrapper.is-disabled {
background-color: var(--el-disabled-bg-color);
}
}
</style>
<route lang="yaml">
name: priceCalculate
</route>
<script lang="ts" setup name="priceCalculate">
import { ref } from 'vue';
import TableTools from '@/components/Tools/table_tools.vue';
import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
import { ElMessage, ElMessageBox } from "element-plus";
import { CirclePlus } from "@element-plus/icons-vue";
import { useRouter, useRoute } from "vue-router";
import useUserStore from "@/store/modules/user";
import useDataAssetStore from "@/store/modules/dataAsset";
import { getAllFlowData } from '@/api/modules/queryService';
import { changeNum } from "@/utils/common";
import {
getDiseaseAll,
getPriceList,
deletePrice,
} from '@/api/modules/dataPricing';
const router = useRouter();
const userStore = useUserStore()
const assetStore = useDataAssetStore();
const userData = JSON.parse(userStore.userData)
const { proxy } = getCurrentInstance() as any;
const searchItemList = ref([
{
type: "input",
label: "",
field: "dataResourceName",
default: "",
placeholder: "数据资源名称",
clearable: true,
},
{
type: "cascader",
label: "",
field: "diseaseName",
placeholder: "疾病名称",
default: "",
options: [],
showAllLevels: false,
props: {
checkStrictly: true,
label: "diseaseName",
value: "guid",
children: 'childList',
emitPath: false
},
filterable: true,
clearable: true,
}
]);
const typeMap: any = ref({});
const selectRowData: any = ref([])
const currTableData: any = ref({});
const page: any = ref({
...commonPageConfig,
dataResourceName: '',
diseaseName: ''
});
const tableField: any = ref([
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" },
{ label: "定价模型名称", field: "modelName", width: 200 },
{ label: "数据资源名称", field: "dataResourceName", width: 200 },
{ label: "疾病名称", field: "diseaseName", width: 200 },
{
label: "交易价格(元)", field: "dataTransactionPrice", width: 120, align: 'right', getName: (scope) => {
return scope.row.dataTransactionPrice ? changeNum(parseFloat(scope.row.dataTransactionPrice), 2) : '-';
}
},
{ label: "创建人", field: "createUserName", width: 120 },
{ label: "创建时间", field: "createTime", width: TableColumnWidth.DATETIME },
]);
const tableInfo = ref({
id: 'api-data-table',
rowKey: 'guid',
loading: false,
fields: tableField.value,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
isMore: false,
width: 120,
btns: [
{ label: "编辑", value: "edit" },
{ label: "删除", value: "del" }
]
}
});
const setTableField = () => {
tableField.value.splice(4, 0, {
label: "交易用途", field: "dataUsage", width: 120, getName: (scope) => {
return typeMap.value['dataUsage'].find((item) => item.value == scope.row['dataUsage'])?.label || '-';
}
});
tableInfo.value.fields = tableField.value;
}
// 获取所有疾病数据
const getDiseaseData = () => {
getDiseaseAll().then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
searchItemList.value[1].options = data;
}
})
}
// 获取数据字典
const getDataType = (dictType, fieldName) => {
getAllFlowData({ dictType }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
typeMap.value[fieldName] = JSON.parse(JSON.stringify(data));
setTableField()
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
const toSearch = (val: any, clear: boolean = false) => {
page.value.curr = 1;
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.dataResourceName = ''
page.value.diseaseName = '';
} else {
page.value.dataResourceName = val.dataResourceName || '';
page.value.diseaseName = val.diseaseName || '';
}
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true;
getPriceList({
pageSize: page.value.limit,
pageIndex: page.value.curr,
dataResourceName: page.value.dataResourceName,
diseaseName: page.value.diseaseName,
}).then((res: any) => {
tableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
const data = res.data || {};
tableInfo.value.data = data.records || [];
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.limit = page.value.limit;
tableInfo.value.page.curr = page.value.curr;
getTableData();
};
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
currTableData.value = row;
if (type === 'edit') { // 编辑
if (row.belongingTheme) {
router.push(
{
name: 'calculateConfig',
query: {
guid: row.guid,
name: row.modelName,
type: 'edit'
}
}
);
} else {
router.push(
{
name: 'calculateConfigNew',
query: {
guid: row.guid,
name: row.modelName,
type: 'edit'
}
}
);
}
} else if (type === 'del') { // 删除
open('确定要删除该条数据吗?', 'warning');
}
};
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
let guids = [currTableData.value.guid]
if (isBatch) {
guids = selectRowData.value
}
deletePrice(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
getTableData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
proxy.$ElMessage.error(res.msg);
}
});
});
};
const addDisease = () => {
router.push(
{
name: 'calculateConfigNew',
query: {
type: 'create'
}
}
);
}
onBeforeMount(() => {
getDiseaseData();
getDataType('数据用途', 'dataUsage')
});
onActivated(() => {
if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
toSearch(null, true);
assetStore.set(false);
}
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
<div class="tools_btns">
<el-button type="primary" @click="addDisease" v-preReClick>新增</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" @tableBtnClick="tableBtnClick" />
</div>
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 0px 8px 0;
}
</style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!