金融产品设计及数字化营销沙盘
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

310 lines
10 KiB

<template>
<!-- 企业利率模型 -->
<el-form label-width="100px"
class="form"
status-icon>
<el-form-item label="利率模型">
<el-table class="c-table"
:data="form.corporateInterestRateModelIndicators"
:span-method="span"
border>
<el-table-column prop="indexName"
label="指标名称"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="indexName"
label="计算公式"
min-width="100"
align="center">
<template #default="{ row }">
<el-select v-if="row?.recordChildren?.length < 3"
class="w-full"
v-model="row.computationalFormula">
<el-option v-for="item in row.recordChildren[0]?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="standard"
label="标准"
min-width="150"
align="center"></el-table-column>
<el-table-column label="浮动系数"
min-width="150">
<template #default="{ row }">
<el-select class="w-full"
v-model="row.floatingCoefficient">
<el-option v-for="item in row?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item :label="formProcess[0]?.name">
<div class="flex-1">
<p class="mb-1">{{ formProcess[0]?.recordChildren[0]?.name }}</p>
<el-select v-model="form.finalFloatingRatioEqual"
clearable>
<el-option v-for="item in formProcess[0]?.recordChildren[0]?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
<p class="mt-3 mb-1">{{ formProcess[0]?.recordChildren[1]?.name }}</p>
<el-select v-model="form.finalFloatingRatioLess"
clearable>
<el-option v-for="item in formProcess[0]?.recordChildren[1]?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
<p class="mt-3 mb-1">{{ formProcess[0]?.recordChildren[2]?.name }}</p>
<el-select v-model="form.finalFloatingRatioGreater"
clearable>
<el-option v-for="item in formProcess[0]?.recordChildren[2]?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
</div>
</el-form-item>
<el-form-item :label="formProcess[1]?.name">
<div class="flex-1">
<p class="mb-1">{{ formProcess[1]?.recordChildren[0]?.name }}</p>
<el-select v-model="form.finalInterestRateEqual">
<el-option v-for="item in formProcess[1]?.recordChildren[0]?.subject?.itemList"
:key="item"
:value="item.options" />
</el-select>
</div>
</el-form-item>
</el-form>
<div class="flex justify-end">
<div class="submit"
@click="submit">确认完成配置</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage, ElLoading } from 'element-plus';
import { businessInterestRateDetails, businessInterestRateSaveOrUpdate } from '@/api/model';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import type { TableColumnCtx } from 'element-plus';
import { useRouter, useRoute } from 'vue-router';
import { handleId } from '@/utils/common';
import Cookies from 'js-cookie';
const router = useRouter();
const route = useRoute();
const projectId = +Cookies.get('sand-projectId');
const levelId = +Cookies.get('sand-level');
let loading = null;
const form = ref<Record<string, any>>({
projectId,
checkpointId: levelId,
finalFloatingRatioEqual: '',
finalFloatingRatioGreater: '',
finalFloatingRatioLess: '',
finalInterestRateEqual: '',
type: 2,
corporateInterestRateModelIndicators: [],
});
const formProcess = ref<Record<string, any>[]>([]);
const info = ref<Record<string, any>[]>([]);
// 配置项
const getConfig = async () => {
const { process } = await getProcessInformationBasedOnRoles(936);
formProcess.value = process.slice(1);
const list = process[0]?.recordChildren;
const result = [];
list?.forEach((e, i) => {
const children = e.recordChildren.length > 2 ? e.recordChildren : e.recordChildren[1]?.recordChildren;
let cur = info.value.length ? info.value[i] : {};
let temp = {
indexId: cur?.indexId || '',
modelId: cur?.modelId || '',
computationalFormula: cur?.computationalFormula || '',
indexName: e.name,
recordChildren: e.recordChildren || [],
stRecordId: e.id,
ruleId: children[0]?.id,
standard: children[0]?.name,
subject: children[0]?.subject,
floatingCoefficient: cur?.corporateInterestRateModels ? (cur?.corporateInterestRateModels[0].floatingCoefficient ?? '') + '' : '',
id: cur?.corporateInterestRateModels ? cur?.corporateInterestRateModels[0].id : '',
};
result.push(temp);
children.forEach((n, j) => {
if (j) {
cur = info.value.length ? info.value[i].corporateInterestRateModels[j] : {};
temp = JSON.parse(JSON.stringify(temp));
temp.standard = n.name;
temp.subject = n.subject;
temp.ruleId = n.id;
temp.floatingCoefficient = (cur?.floatingCoefficient ?? '') + '';
temp.id = cur?.id ?? '';
temp.rule = 1;
result.push(temp);
}
});
});
form.value.corporateInterestRateModelIndicators = result;
loading.close();
};
// 详情
const getDetail = async (load?: number) => {
if (load) loading = ElLoading.service();
try {
const { data } = await businessInterestRateDetails(levelId, projectId);
if (data) {
form.value = data;
info.value = data.corporateInterestRateModelIndicators;
}
getConfig();
} finally {
}
};
onMounted(() => {
getDetail(1);
});
interface SpanMethodProps {
row: Record<string, any>;
column: TableColumnCtx<Record<string, any>>;
rowIndex: number;
columnIndex: number;
}
const rowMerge1 = [0, 16];
const rowMerge2 = [11, 20, 25, 30, 35, 40];
// 表格合并
const span = ({ row, column, rowIndex, columnIndex }: SpanMethodProps) => {
if (!columnIndex || columnIndex === 1) {
if (rowMerge1.includes(rowIndex)) {
return {
rowspan: 4,
colspan: 1,
};
} else if (rowMerge2.includes(rowIndex)) {
return {
rowspan: 5,
colspan: 1,
};
} else if (rowIndex === 4) {
return {
rowspan: 7,
colspan: 1,
};
} else if (rowIndex === 45) {
return {
rowspan: 6,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
};
const getItemId = (name: string): number | string => {
if (!name) return '';
return formProcess.value[0]?.recordChildren[0]?.subject?.itemList.find((e) => e.options === name)?.itemId;
};
// 新增判分记录
const addRecord = async (data: Record<string, any>) => {
const preIds = `1,${Cookies.get('sand-level')},42,68,757,936`; // 1,关卡id,角色(这个页面是风控经理策略),其他看判分点接口
const rule: Array<Record<string, any>> = [];
const listIds = preIds + ',938';
form.value.corporateInterestRateModelIndicators.forEach((e, i) => {
// 浮动系数
e.floatingCoefficient &&
rule.push(
handleId(
e.ruleId,
e.subject.subjectId,
e?.subject?.itemList?.find((n) => n.options === e.floatingCoefficient)?.itemId,
`${listIds},${e.stRecordId}${e.recordChildren.length > 2 ? '' : ',' + e.recordChildren[1].id},${e.ruleId}`,
1,
),
);
// 计算公式
e.computationalFormula &&
!e.rule &&
rule.push(
handleId(
e.recordChildren[0].id,
e.recordChildren[0].subjectId,
e.recordChildren[0]?.subject?.itemList?.find((n) => n.options === e.computationalFormula)?.itemId,
`${listIds},${e.stRecordId},${e.recordChildren[0].id}`,
1,
),
);
});
data.finalFloatingRatioEqual && rule.push(handleId(1024, 279, getItemId(data.finalFloatingRatioEqual), preIds + ',1023,1024', 1));
data.finalFloatingRatioLess && rule.push(handleId(1025, 279, getItemId(data.finalFloatingRatioLess), preIds + ',1023,1025', 1));
data.finalFloatingRatioGreater && rule.push(handleId(1026, 279, getItemId(data.finalFloatingRatioGreater), preIds + ',1023,1026', 1));
data.finalInterestRateEqual &&
rule.push(
handleId(1028, 280, formProcess.value[1]?.recordChildren[0]?.subject?.itemList.find((e) => e.options === data.finalInterestRateEqual)?.itemId, preIds + ',1027,1028', 1),
);
await addOperation({
checkpointId: levelId,
parentId: preIds,
lcJudgmentRuleReq: rule,
projectId,
});
};
// 提交
const submit = async () => {
loading = ElLoading.service();
const param = JSON.parse(JSON.stringify(form.value));
const list = [];
param.corporateInterestRateModelIndicators.forEach((e, i) => {
const temp = {
floatingCoefficient: e.floatingCoefficient,
standard: e.standard,
id: e.id,
indexId: e.indexId,
};
if (e.rule) {
list.find((n) => n.indexName === e.indexName).corporateInterestRateModels.push(temp);
} else {
list.push({
indexId: e.indexId,
modelId: e.modelId,
computationalFormula: e.computationalFormula,
indexName: e.indexName,
corporateInterestRateModels: [temp],
});
}
});
param.corporateInterestRateModelIndicators = list;
param.type = 2;
await businessInterestRateSaveOrUpdate(param);
addRecord(param);
getDetail();
ElMessage.success('提交成功!');
};
</script>
<style lang="scss" scoped>
@import url(../../../styles/form.scss);
.c-table {
:deep(.el-input__inner) {
@apply px-2;
}
}
</style>