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.

1747 lines
73 KiB

<template>
<w-dialog
ref="dialogRef"
:title="state.dialogTitle"
width="80%"
height="80%"
body-padding="0px 0px 0px 0px"
:maximized="true"
:buttons="dialogButtonsComputed"
@hide="dialogHide"
@maximized="maximized"
>
<q-stepper ref="stepperRef" v-model="state.step" header-nav color="primary" animated active-color="amber" keep-alive @update:model-value="stepClick">
<q-step :name="RatingStep.KHXX" title="客户信息" icon="account_circle" :done="state.custInfoDone" :style="stepMinHeightComputed">
<q-card flat bordered>
<q-card-section>
<span class="text-3xl text-amber-600">{{ state.custInfoObj['custName'] }}<q-badge color="red" align="top">上市</q-badge></span>
<div class="flex pt-2">
<div class="flex-1 text-center">
<div>客户号</div>
<div class="text-blue-500">
{{ state.custInfoObj['custNo'] }}
</div>
</div>
<div class="flex-1 text-center">
<div>企业规模</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictCustomerSize)(state.custInfoObj['customerSize']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>企业类型</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictRegisteredType)(state.custInfoObj['registeredType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>融资平台标志</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictGoverFinanceSign)(state.custInfoObj['goverFinanceSign']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>融资平台类型</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictGoverFinanceType)(state.custInfoObj['goverFinanceType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>所在国家地区</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictNationCd)(state.custInfoObj['nation']) }}
</div>
</div>
</div>
<div class="pt-3"></div>
<div class="flex">
<div class="flex-1 text-center">
<div>注册所在地</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictRegistrationCd)(state.custInfoObj['registration']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>是否集团客户</div>
<div class="text-blue-500">
{{ state.custInfoObj['groupCustInd'] === '1' ? '是' : '否' }}
</div>
</div>
<div class="flex-1 text-center">
<div>成员类别</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictMemberTypeCd)(state.custInfoObj['memberType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>行业类型国标</div>
<div class="text-blue-500">
{{ state.custInfoObj['industryTypeName'] }}
</div>
</div>
<div class="flex-1 text-center">
<div>成立日期</div>
<div class="text-blue-500">
{{ state.custInfoObj['buildDate'] }}
</div>
</div>
<div class="flex-1 text-center"></div>
</div>
</q-card-section>
</q-card>
<div class="pt-[10px]">
<w-grid
ref="financeReportGridRef"
title="财务报表"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReport/getReport')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'endDate', label: '财报日期', format: Formater.dateOnly() },
{ name: 'type', label: '报表类型', format: Formater.dictionary(dictFinanceTypeCd) },
{ name: 'sort', label: '报表类别', format: Formater.dictionary(dictFinanceSortTypeCd) },
{ name: 'auditedInd', label: '是否审计', format: Formater.dictionary(dictFinanceStatusCd) },
{ name: 'caliber', label: '报表口径', format: Formater.dictionary(dictCaliberCd) },
{ name: 'currency', label: '报表币种', format: Formater.dictionary(dictCurrencyTypeCd) },
{ name: 'userNo', label: '经办人' },
{ name: 'remarks', label: '备注' },
{
name: 'op',
label: '操作',
format: opFormat,
},
]"
></w-grid>
</div>
<div class="pt-[10px]">
<w-grid
ref="creditReportGridRef"
title="征信报告"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('api/irbs/creditReport')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'id', label: '报告号' },
{ name: 'custNo', label: '客户号' },
{ name: 'entName', label: '客户名称' },
{ name: 'reportDate', label: '报告日期', format: Formater.dateOnly() },
{ name: 'expiryDate', label: '征信有效期', format: Formater.dateOnly() },
{ name: 'blankInd', label: '是否白户', slot: 'isValid' },
]"
:query-criteria="{
fieldName: 'custNo',
operator: 'equals',
value: '',
}"
></w-grid>
<w-dialog ref="financeReportDetailDialogRef" title="财报详情" width="70%" height="70%" @maximized="finReportDetailDialogMaximized">
<q-splitter v-model="state.finReportDetailSplitterModel" disable style="height: 100%">
<template #before>
<q-tabs v-model="state.finReportDetailTab" vertical indicator-color="amber" active-color="amber">
<q-tab name="fz" icon="message" label="报表基本信息" />
<q-tab v-if="state.finReportType === FinanceReportType.QYL" name="qylzcfz" icon="currency_yen" label="企业类资产负债表" />
<q-tab v-if="state.finReportType === FinanceReportType.QYL" name="qylxjl" icon="money" label="企业类现金流量表" />
<q-tab v-if="state.finReportType === FinanceReportType.QYL" name="qylsy" icon="remove_circle_outline" label="企业类损益表" />
<q-tab v-if="state.finReportType === FinanceReportType.SYL" name="sylzcfz" icon="currency_yen" label="事业类资产负债表" />
<q-tab v-if="state.finReportType === FinanceReportType.SYL" name="sylsyzc" icon="price_change" label="事业类收入支出表" />
</q-tabs>
</template>
<template #after>
<q-tab-panels
v-model="state.finReportDetailTab"
:keep-alive="true"
animated
swipeable
vertical
transition-prev="jump-up"
transition-next="jump-up"
>
<q-tab-panel name="fz">
<w-info-panel :info="state.finReportFz" :column-num="1"></w-info-panel>
</q-tab-panel>
<q-tab-panel name="qylzcfz">
<!--企业类资产负债表-->
<w-grid
:dense-body="true"
:height="state.finReportDetailDialogContentHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReportDetail')"
:checkbox-selection="false"
:sort-no="true"
:config-button="false"
:columns="[
{ name: 'projectCode', label: '科目编码' },
{ name: 'projectName', label: '科目名称' },
{ name: 'projectValue', label: '科目值' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'reportId',
operator: 'equals',
value: state.finReportSelectedId,
},
{
fieldName: 'projectType',
operator: 'equals',
value: FinanceReportProjectType.QYLZCFZ,
},
],
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="qylxjl">
<!--企业类现金流表-->
<w-grid
:dense-body="true"
:height="state.finReportDetailDialogContentHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReportDetail')"
:checkbox-selection="false"
:sort-no="true"
:config-button="false"
:columns="[
{ name: 'projectCode', label: '科目编码' },
{ name: 'projectName', label: '科目名称' },
{ name: 'projectValue', label: '科目值' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'reportId',
operator: 'equals',
value: state.finReportSelectedId,
},
{
fieldName: 'projectType',
operator: 'equals',
value: FinanceReportProjectType.QYLXJL,
},
],
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="qylsy">
<!--企业类损益表-->
<w-grid
:dense-body="true"
:height="state.finReportDetailDialogContentHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReportDetail')"
:checkbox-selection="false"
:sort-no="true"
:config-button="false"
:columns="[
{ name: 'projectCode', label: '科目编码' },
{ name: 'projectName', label: '科目名称' },
{ name: 'projectValue', label: '科目值' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'reportId',
operator: 'equals',
value: state.finReportSelectedId,
},
{
fieldName: 'projectType',
operator: 'equals',
value: FinanceReportProjectType.QYLSY,
},
],
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="sylzcfz">
<!--事业类资产负债表-->
<w-grid
:dense-body="true"
:height="state.finReportDetailDialogContentHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReportDetail')"
:checkbox-selection="false"
:sort-no="true"
:config-button="false"
:columns="[
{ name: 'projectCode', label: '科目编码' },
{ name: 'projectName', label: '科目名称' },
{ name: 'projectValue', label: '科目值' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'reportId',
operator: 'equals',
value: state.finReportSelectedId,
},
{
fieldName: 'projectType',
operator: 'equals',
value: FinanceReportProjectType.SYLZCFZ,
},
],
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="sylsyzc">
<!--事业类事业类收入支出表-->
<w-grid
:dense-body="true"
:height="state.finReportDetailDialogContentHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/financeReportDetail')"
:checkbox-selection="false"
:sort-no="true"
:config-button="false"
:columns="[
{ name: 'projectCode', label: '科目编码' },
{ name: 'projectName', label: '科目名称' },
{ name: 'projectValue', label: '科目值' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'reportId',
operator: 'equals',
value: state.finReportSelectedId,
},
{
fieldName: 'projectType',
operator: 'equals',
value: FinanceReportProjectType.SYLSRZC,
},
],
}"
></w-grid>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</w-dialog>
</div>
<q-stepper-navigation v-if="showNextBtnComputed" class="pt-[10px] flex justify-end">
<q-btn color="primary" label="下一步" @click="custInfoNext(true)" />
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.DLFX" title="定量分析" icon="assessment" :done="state.quantitativeDone" :style="stepMinHeightComputed">
<div class="flex">
<div class="flex-1">
<w-info-panel :info="state.quantitativeInfo"></w-info-panel>
</div>
<div class="flex-1"></div>
<div class="flex-1"></div>
</div>
<q-stepper-navigation v-if="showNextBtnComputed" class="pt-[10px] flex justify-end">
<q-btn color="primary" label="下一步" @click="quantitativeNext" />
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.DXFX" title="定性分析" icon="article" :done="state.qualitativeEditDone" :style="stepMinHeightComputed">
<w-form ref="qualitativeFormRef" :fields="state.qualitativeEditInfo" :cols-num="1" :cols-y-gap="16"></w-form>
<q-stepper-navigation v-if="showNextBtnComputed" class="pt-[10px] flex justify-end">
<q-btn color="primary" label="下一步" @click="qualitativeEditNext" />
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.CPJG" title="初评结果" icon="note_alt" :done="state.qualitativeShowDone" :style="stepMinHeightComputed">
<div class="flex">
<div class="flex-1">
<w-info-panel :info="state.qualitativeShowInfo" :column-num="2"></w-info-panel>
</div>
<div class="flex-1"></div>
</div>
<q-stepper-navigation v-if="showNextBtnComputed" class="pt-[10px] flex justify-end">
<q-btn color="primary" label="下一步" @click="qualitativeShowNext" />
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.PJTZX" title="评级调整项" icon="build_circle" :done="state.adjustItemDone" :style="stepMinHeightComputed">
<w-form ref="adjustItemFormRef" :fields="state.adjustItemInfo" :cols-num="1" :cols-y-gap="16"></w-form>
<q-stepper-navigation v-if="showNextBtnComputed" class="pt-[10px] flex justify-end">
<q-btn color="primary" label="下一步" @click="adjustItemNext" />
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.QSYJ" title="签署意见" icon="comment" :done="state.otherDone" :style="stepMinHeightComputed">
<w-grid
ref="opinionGridRef"
title="审批历史"
:dense="state.dense"
:height="200"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/ratingOverturn')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'orgName', label: '所属机构' },
{ name: 'roleName', label: '岗位名称' },
{ name: 'userCode', label: '操作人工号' },
{ name: 'userName', label: '操作人名称' },
{ name: 'operationOpinion', label: '操作意见', format: Formater.dictionary({ items: RatingProcessOperationStatus }) },
{ name: 'isOverturn', label: '是否推翻', format: Formater.yesNo() },
{ name: 'overturnType', label: '推翻类型', format: Formater.dictionary(dictOverturnType) },
{ name: 'suggestLevel', label: '建议等级' },
{ name: 'adjReason', label: '意见说明' },
{ name: 'lastModifyDate', label: '操作时间' },
{ name: 'fileCount', label: '附件列表' },
]"
:query-criteria="{
fieldName: 'ratingId',
operator: 'equals',
value: state.rating['id'],
}"
:sort-by="['-lastModifyDate']"
></w-grid>
<div class="pt-[10px]">
<q-card flat bordered>
<q-item>
<q-item-section>
<q-item-label>评级推翻</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section>
<div class="flex flex-row gap-4">
<div class="basis-1/4">
<w-info-panel :info="state.otherInfo" :column-num="1"></w-info-panel>
</div>
<div class="basis-2/3">
<w-form
ref="overturnFormRef"
:fields="[
{ label: '附件', name: 'file', type: 'file' },
{ label: '是否推翻', name: 'isOverturn', type: 'checkbox' },
{
label: '推翻类型',
name: 'overturnType',
type: 'select',
options: optionsOverturnType,
required: true,
showIf: (args) => {
if (args?.form && args.form.getFieldValue('isOverturn')) {
return true;
}
return false;
},
},
{
label: '建议等级',
name: 'suggestLevel',
type: 'select',
options: RatingLevelOptionsComputed,
required: true,
showIf: (args) => {
if (args?.form && args.form.getFieldValue('isOverturn')) {
return true;
}
return false;
},
},
{
label: '意见说明',
name: 'adjReason',
type: 'textarea',
required: true,
showIf: (args) => {
if (args?.form && args.form.getFieldValue('isOverturn')) {
return true;
}
return false;
},
},
]"
:cols-num="1"
></w-form>
</div>
</div>
</q-card-section>
</q-card>
</div>
<q-stepper-navigation class="pt-[10px] flex justify-end">
<w-workflow-action
ref="workflowActionRef"
:task-id="state.rating['taskId']"
:data="state.opinionData"
:default-submit-button="false"
:action-url="Environment.apiContextPath('/api/irbs/companyRatingProcess/submit')"
@before-submit="
async (action, callback) => {
state.opinionData = {
transientVariables: {
opaVal: action.transientVariables.goback,
desc: '客户名称:' + state.rating['custName'],
},
data: overturnFormRef.getData(),
};
const validateResult = await overturnFormRef.validate();
if (validateResult) {
callback(true);
} else {
callback(false);
}
}
"
@after-submit="
() => {
state.otherDone = true;
state.step = RatingStep.PJBG;
stepClick(RatingStep.PJBG);
}
"
>
</w-workflow-action>
</q-stepper-navigation>
</q-step>
<q-step :name="RatingStep.PJBG" title="评级报告" icon="summarize" :done="state.reportInfoDone" :style="stepMinHeightComputed">
<div class="pt-[10px]">
<!-- <q-card flat bordered>
<q-item dense class="pl-[8px]">
<q-item-section>
<q-item-label>客户基本信息</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section class="p-[10px]">
<span class="text-3xl text-amber-600">{{ state.custInfoObj['custName'] }}<q-badge color="red" align="top">上市</q-badge></span>
<div class="grid grid-cols-6">
<span>客户号{{ state.custInfoObj['custNo'] }}</span>
<span>企业规模{{ state.custInfoObj['customerSize'] }}</span>
<span>企业类型{{ state.custInfoObj['registeredType'] }}</span>
<span>融资平台标志{{ state.custInfoObj['goverFinanceSign'] }}</span>
<span>融资平台类型{{ state.custInfoObj['goverFinanceType'] }}</span>
<span>所在国家地区{{ state.custInfoObj['nation'] }}</span>
<span>注册所在地{{ state.custInfoObj['registration'] }}</span>
<span>是否集团客户{{ state.custInfoObj['groupCustInd'] }}</span>
<span>成员类别{{ state.custInfoObj['memberType'] }}</span>
<span>行业类型国标{{ state.custInfoObj['industryType'] }}</span>
<span>成立日期{{ state.custInfoObj['buildDate'] }}</span>
<span>经办人编号{{ state.custInfoObj['customerManagerNo'] }}</span>
<span>经办人名称{{ state.custInfoObj['customerManagerName'] }}</span>
<span>经办机构{{ state.custInfoObj['handleOrgId'] }}</span>
<span>登记日期{{ state.custInfoObj['handleTime'] }}</span>
</div>
</q-card-section>
</q-card> -->
<q-card flat bordered>
<q-card-section>
<span class="text-3xl text-amber-600">{{ state.custInfoObj['custName'] }}<q-badge color="red" align="top">上市</q-badge></span>
<div class="flex pt-2">
<div class="flex-1 text-center">
<div>客户号</div>
<div class="text-blue-500">
{{ state.custInfoObj['custNo'] }}
</div>
</div>
<div class="flex-1 text-center">
<div>企业规模</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictCustomerSize)(state.custInfoObj['customerSize']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>企业类型</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictRegisteredType)(state.custInfoObj['registeredType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>融资平台标志</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictGoverFinanceSign)(state.custInfoObj['goverFinanceSign']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>融资平台类型</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictGoverFinanceType)(state.custInfoObj['goverFinanceType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>所在国家地区</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictNationCd)(state.custInfoObj['nation']) }}
</div>
</div>
</div>
<div class="pt-3"></div>
<div class="flex">
<div class="flex-1 text-center">
<div>注册所在地</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictRegistrationCd)(state.custInfoObj['registration']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>是否集团客户</div>
<div class="text-blue-500">
{{ state.custInfoObj['groupCustInd'] === '1' ? '是' : '否' }}
</div>
</div>
<div class="flex-1 text-center">
<div>成员类别</div>
<div class="text-blue-500">
{{ Formater.dictionary(dictMemberTypeCd)(state.custInfoObj['memberType']) }}
</div>
</div>
<div class="flex-1 text-center">
<div>行业类型国标</div>
<div class="text-blue-500">
{{ state.custInfoObj['industryTypeName'] }}
</div>
</div>
<div class="flex-1 text-center">
<div>成立日期</div>
<div class="text-blue-500">
{{ state.custInfoObj['buildDate'] }}
</div>
</div>
<div class="flex-1 text-center"></div>
</div>
</q-card-section>
</q-card>
</div>
<div class="pt-[20px]">
<q-card flat bordered>
<q-item dense class="pl-[8px]">
<q-item-section>
<q-item-label>评级结果</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section class="p-[10px]">
<div>
<div>
<span class="pl-[8px]">客户评级</span>
<div class="pt-[8px]">
<w-info-panel :dense="state.dense" :info="state.reportCustRatingInfo" :column-num="4"></w-info-panel>
</div>
<div v-if="state.reportShowScoreDtl" class="pt-[8px]">
<q-list bordered class="rounded-borders">
<q-expansion-item default-opened expand-separator icon="bubble_chart" label="得分详情">
<q-separator />
<q-splitter v-model="state.splitterModel">
<template #before>
<div>
<div class="text-center">
<q-chip outline color="orange" text-color="white" :clickable="false" :ripple="false"> 定量得分详情 </q-chip>
</div>
<q-list v-if="state.reportQuantitativeScoreDtl" padding>
<template v-for="(values, key, a) in state.reportQuantitativeScoreDtl" :key="a">
<q-item-label header>{{ key }}</q-item-label>
<template v-for="(dtl, index) in values" :key="index">
<q-item>
<q-item-section>
<q-item-label>{{ dtl['INDEX_NAME'] }}</q-item-label>
<q-item-label caption> {{ dtl['INDEX_VALUE'] }} </q-item-label>
</q-item-section>
<q-item-section v-if="!Tools.isEmpty(dtl['INDEX_SCORE'])" side>
<q-chip :clickable="false" :ripple="false" color="green" text-color="white">
{{ Round(dtl['INDEX_SCORE'], 2) }}
</q-chip>
</q-item-section>
</q-item>
</template>
<q-separator />
</template>
</q-list>
</div>
</template>
<template #after>
<q-splitter v-model="state.afterSplitterModel">
<template #before>
<div>
<div class="text-center">
<q-chip outline color="light-blue" text-color="white" :clickable="false" :ripple="false"> 定性得分详情 </q-chip>
</div>
<q-list v-if="state.reportQualitativeScoreDtl" padding>
<template v-for="(values, key, a) in state.reportQualitativeScoreDtl" :key="a">
<q-item-label header>{{ key }}</q-item-label>
<template v-for="(dtl, index) in values" :key="index">
<q-item>
<q-item-section>
<q-item-label>{{ dtl['INDEX_NAME'] }}</q-item-label>
<q-item-label caption> {{ dtl['TEXT'] }} </q-item-label>
</q-item-section>
<q-item-section v-if="!Tools.isEmpty(dtl['INDEX_SCORE'])" side>
<q-chip :clickable="false" :ripple="false" color="green" text-color="white">
{{ Round(dtl['INDEX_SCORE'], 2) }}
</q-chip>
</q-item-section>
</q-item>
</template>
<q-separator />
</template>
</q-list>
</div>
</template>
<template #after>
<div>
<div class="text-center">
<q-chip outline color="lime" text-color="white" :clickable="false" :ripple="false"> 评级调整项详情 </q-chip>
</div>
<q-list v-if="state.reportAdjustScoreDtl" padding>
<template v-for="(values, key, a) in state.reportAdjustScoreDtl" :key="a">
<q-item-label header>{{ key }}</q-item-label>
<template v-for="(dtl, index) in values" :key="index">
<q-item>
<q-item-section>
<q-item-label>{{ dtl['INDEX_NAME'] }}</q-item-label>
<q-item-label caption> {{ dtl['TEXT'] }} </q-item-label>
</q-item-section>
</q-item>
</template>
<q-separator />
</template>
</q-list>
</div>
</template>
</q-splitter>
</template>
</q-splitter>
</q-expansion-item>
</q-list>
</div>
</div>
<div>
<w-grid
ref="debtGradeGridRef"
title="(二)债项评级"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/debtGrade')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'custNo', label: '客户号' },
{ name: 'custName', label: '客户名称' },
{ name: 'contNo', label: '合同编号' },
{ name: 'prodCd', label: '业务品种', slot: 'LMT_PROD_CD' },
{ name: 'ccyCd', label: '币种', slot: 'CurrencyTypeCd' },
{ name: 'irsEad', label: '风险暴露' },
{ name: 'contrAmt', label: '合同金额' },
{ name: 'contStartDt', label: '起始日期', format: Formater.dateOnly() },
{ name: 'contEndtDt', label: '到期日期', format: Formater.dateOnly() },
{ name: 'irsLgdNumber', label: '违约损失率' },
{ name: 'lgdLv', label: '预测LGD等级' },
{ name: 'irsEad', label: '风险暴露' },
{ name: 'expenseFeeLgd', label: '合同层实际LGD' },
]"
:query-criteria="{
fieldName: 'custNo',
operator: 'equals',
value: state.rating['custNo'],
}"
></w-grid>
</div>
</div>
</q-card-section>
</q-card>
</div>
<div class="pt-[20px]">
<q-card flat bordered>
<q-item dense class="pl-[8px]">
<q-item-section>
<q-item-label>信用记录分析</q-item-label>
</q-item-section>
</q-item>
<q-separator />
<q-card-section class="p-[10px]">
<div>
<w-grid
ref="custHistRatingGridRef"
title="(一)客户过往评级记录"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/companyRating')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'id', label: '申请编号' },
{ name: 'custNo', label: '客户号' },
{ name: 'custName', label: '客户名称' },
{ name: 'modelScore', label: '得分' },
{ name: 'modelLevel', label: '系统评级等级' },
{ name: 'adjLevel', label: '调整等级' },
{ name: 'initLevel', label: '初评等级' },
{ name: 'finalLevel', label: '最终等级' },
{ name: 'effectiveTime', label: '生效日期', format: Formater.dateOnly() },
{ name: 'matureTime', label: '到期日期', format: Formater.dateOnly() },
{ name: 'ratingStatus', label: '评级状态', format: Formater.enum(RatingStatusEnum) },
{ name: 'launchUser', label: '发起人' },
{ name: 'processStatus', label: '状态', format: Formater.enum(RatingProcessStatusEnum) },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'custNo',
operator: 'equals',
value: state.rating['custNo'],
},
{
fieldName: 'processStatus',
operator: 'equals',
value: RatingProcessStatus.PASS,
},
],
}"
></w-grid>
</div>
<div>
<w-grid
ref="defaultCognizanceGridRef"
title="(二)违约认定情况"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/defaultCognizance')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'custNo', label: '客户号' },
{ name: 'custName', label: '客户名称' },
{ name: 'levelHis', label: '违约时评级' },
{ name: 'effectiveDate', label: '违约发起时间' },
{ name: 'creator', label: '违约发起人' },
{ name: 'defaultProcessStatus', label: '违约流程状态' },
{ name: 'defalutType', label: '违约认定类型' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'custNo',
operator: 'equals',
value: state.rating['custNo'],
},
{
fieldName: 'status',
operator: 'equals',
value: DefaultProcessStatus.PASS,
},
],
}"
10 months ago
:sort-by="['-effectiveDate']"
></w-grid>
<w-grid
ref="defaultRebirthGridRef"
title="(三)违约重生情况"
:dense="state.dense"
:height="state.tableHeight"
:pageable="false"
:hide-bottom="true"
:auto-fetch-data="true"
:fetch-data-url="Environment.apiContextPath('api/irbs/defaultRebirth')"
:checkbox-selection="false"
:config-button="false"
:columns="[
{ name: 'custNo', label: '客户号' },
{ name: 'custName', label: '客户名称' },
{ name: 'rebirthEffectiveDate', label: '重生生效时间' },
{ name: 'creator', label: '重生发起人' },
{ name: 'rebirthProcessStatus', label: '重生流程状态' },
{ name: 'defalutRebornType', label: '违约重生类型' },
]"
:query-criteria="{
operator: 'and',
criteria: [
{
fieldName: 'custNo',
operator: 'equals',
value: state.rating['custNo'],
},
{
fieldName: 'rebirthProcessStatus',
operator: 'equals',
value: DefaultProcessStatus.PASS,
},
],
}"
10 months ago
:sort-by="['-rebirthEffectiveDate']"
></w-grid>
</div>
</q-card-section>
</q-card>
</div>
</q-step>
</q-stepper>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, toRaw, reactive, nextTick, computed } from 'vue';
import { useQuasar, getCssVar } from 'quasar';
import { axios, Environment, NotifyManager, Tools, EnumTools, DictionaryTools, Options, Formater } from 'platform-core';
import {
RatingProcessStatus,
DefaultProcessStatus,
RatingProcessOperationStatus,
RatingStep,
RatingLevelOptions,
FinanceReportType,
FinanceReportProjectType,
Round,
} from './CustRating.ts';
import RatingLevel from './RatingLevel.vue';
const $q = useQuasar();
const gc = Environment.getConfigure();
const darkBgColor = getCssVar('dark');
const stickyBgColor = gc.theme.dark ? darkBgColor : gc.theme?.grid?.stickyBgColor || '#ffffff';
const dialogRef = ref();
const stepperRef = ref();
const financeReportGridRef = ref();
const creditReportGridRef = ref();
const financeReportDetailDialogRef = ref();
const qualitativeFormRef = ref();
const adjustItemFormRef = ref();
const opinionGridRef = ref();
const debtGradeGridRef = ref();
const custHistRatingGridRef = ref();
const defaultCognizanceGridRef = ref();
const defaultRebirthGridRef = ref();
const overturnFormRef = ref();
const workflowActionRef = ref();
const props = defineProps({
dictionary: {
type: Object,
default: () => {
return {};
},
},
});
const emit = defineEmits(['refresh']);
const state = reactive({
splitterModel: 30,
afterSplitterModel: 50,
rating: {},
opinionData: {},
viewFlag: false,
ratingProcessStatus: null,
dialogTitle: '公司客户评级',
dense: false,
tableHeight: 200,
dialogContentHeight: 300,
step: RatingStep.KHXX,
custInfoDone: false,
quantitativeDone: false,
qualitativeEditDone: false,
qualitativeShowDone: false,
adjustItemDone: false,
otherDone: false,
reportInfoDone: false,
custInfoObj: {},
custInfo: <any>[],
quantitativeInfo: <any>[],
qualitativeEditInfo: <any>[],
qualitativeEditObj: {},
qualitativeShowInfo: <any>[],
adjustItemInfo: <any>[],
adjustItemObj: {},
otherInfo: <any>[],
otherInfoAdjLevel: <any>null,
overturnLevelNum: <any>null,
finReportDetailSplitterModel: 16,
finReportDetailTab: 'fz',
finReportType: FinanceReportType.QYL,
finReportFz: <any>[], // 财报附注信息
finReportSelectedId: '',
finReportDetailDialogContentHeight: <undefined | number>undefined,
reportShowScoreDtl: false,
reportCustRatingInfo: <any>[],
reportQuantitativeScoreDtl: <any>null,
reportQualitativeScoreDtl: <any>null,
reportAdjustScoreDtl: <any>null,
});
const dialogHide = () => {
state.reportShowScoreDtl = false;
state.step = RatingStep.KHXX;
state.custInfoDone = false;
state.quantitativeDone = false;
state.qualitativeEditDone = false;
state.qualitativeShowDone = false;
state.adjustItemDone = false;
state.otherDone = false;
state.reportInfoDone = false;
emit('refresh');
};
const stepClick = (value) => {
if (value === RatingStep.DLFX) {
custInfoNext();
} else if (value === RatingStep.DXFX) {
quantitativeNext();
} else if (value === RatingStep.CPJG) {
loadFirstResult();
} else if (value === RatingStep.PJTZX) {
qualitativeShowNext();
} else if (value === RatingStep.QSYJ) {
loadRatingOverturn();
} else if (value === RatingStep.PJBG) {
loadRatingReport();
}
};
const opFormat = (value, row) => {
if (row && row['sort']) {
return {
componentType: 'q-chip',
attrs: {
dense: true,
color: 'primary',
icon: 'visibility',
textColor: 'white',
square: true,
size: state.dense ? 'xs' : 'md',
label: '查 看',
onclick: () => {
state.finReportType = row['sort'];
state.finReportSelectedId = row['id'];
financeReportDetailDialogRef.value.show();
state.finReportFz = [];
state.finReportFz.push({ label: '财务报表截至日期', value: row['endDate'] });
state.finReportFz.push({ label: '是否经过审计', value: row['auditedInd'], format: Formater.dictionary(dictFinanceStatusCd) });
state.finReportFz.push({ label: '财务报表类别', value: row['sort'], format: Formater.dictionary(dictFinanceTypeCd) });
state.finReportFz.push({ label: '财务报表口径', value: row['caliber'], format: Formater.dictionary(dictCaliberCd) });
state.finReportFz.push({ label: '财务报表币种', value: row['currency'], format: Formater.dictionary(dictCurrencyTypeCd) });
nextTick(() => {
state.finReportDetailDialogContentHeight = financeReportDetailDialogRef.value.getContent().offsetHeight - 33;
});
},
},
};
} else {
return '';
}
};
const RatingLevelOptionsComputed = computed(() => {
if (state.overturnLevelNum) {
const adjLevel = RatingLevelOptions.filter((item) => {
return item['value'] === state.otherInfoAdjLevel;
});
const filterResult = RatingLevelOptions.filter((item) => {
return item['numberValue'] <= adjLevel[0]['numberValue'] + state.overturnLevelNum;
});
return filterResult;
}
return [];
});
// 加载客户信息
const loadCustInfo = async () => {
// 加载客户基本信息
let customerType = '';
await axios.get(Environment.apiContextPath('api/irbs/ratingCompanyCustomer/' + state.rating['custId'])).then((resp) => {
if (resp && resp.data) {
customerType = resp.data['customerType'];
state.custInfo = [];
state.custInfo.push({ label: '客户号', name: 'custNo', value: resp.data['custNo'] });
state.custInfo.push({ label: '客户名称', name: 'custName', value: resp.data['custName'] });
state.custInfo.push({ label: '证件类型', name: 'certificateType', value: resp.data['certificateType'] });
state.custInfo.push({ label: '证件号码', name: 'certificateNum', value: resp.data['certificateNum'] });
state.custInfo.push({ label: '客户类型', name: 'customerType', value: resp.data['customerType'] });
state.custInfo.push({ label: '企业规模', name: 'customerSize', value: resp.data['customerSize'] });
state.custInfo.push({ label: '企业类型', name: 'registeredType', value: resp.data['registeredType'] });
state.custInfo.push({ label: '融资平台标志', name: 'goverFinanceSign', value: resp.data['goverFinanceSign'] });
state.custInfo.push({ label: '融资平台类型', name: 'goverFinanceType', value: resp.data['goverFinanceType'] });
state.custInfo.push({ label: '注册所在地', name: 'registration', value: resp.data['registration'] });
state.custInfo.push({ label: '所在国家地区', name: 'nation', value: resp.data['nation'] });
state.custInfo.push({ label: '成员类别', name: 'memberType', value: resp.data['memberType'] });
state.custInfo.push({ label: '是否集团客户', name: 'groupCustInd', value: resp.data['groupCustInd'] });
state.custInfo.push({ label: '是否上市企业', name: 'marketEnterprisesInd', value: resp.data['marketEnterprisesInd'] });
state.custInfo.push({ label: '行业类型(国标)', name: 'industryType', value: resp.data['industryType'] });
state.custInfo.push({ label: '成立日期', name: 'buildDate', value: resp.data['buildDate'] });
state.custInfo.push({ label: '经办人编号', name: 'customerManagerNo', value: resp.data['customerManagerNo'] });
state.custInfo.push({ label: '经办人名称', name: 'customerManagerName', value: resp.data['customerManagerName'] });
state.custInfo.push({ label: '经办机构', name: 'handleOrgId', value: resp.data['handleOrgId'] });
state.custInfo.push({ label: '登记日期', name: 'handleTime', value: resp.data['handleTime'] });
state.custInfoObj = {};
state.custInfoObj['custNo'] = resp.data['custNo'];
state.custInfoObj['custName'] = resp.data['custName'];
state.custInfoObj['certificateType'] = resp.data['certificateType'];
state.custInfoObj['certificateNum'] = resp.data['certificateNum'];
state.custInfoObj['customerType'] = resp.data['customerType'];
state.custInfoObj['customerSize'] = resp.data['customerSize'];
state.custInfoObj['registeredType'] = resp.data['registeredType'];
state.custInfoObj['goverFinanceSign'] = resp.data['goverFinanceSign'];
state.custInfoObj['goverFinanceType'] = resp.data['goverFinanceType'];
state.custInfoObj['registration'] = resp.data['registration'];
state.custInfoObj['nation'] = resp.data['nation'];
state.custInfoObj['memberType'] = resp.data['memberType'];
state.custInfoObj['groupCustInd'] = resp.data['groupCustInd'];
state.custInfoObj['marketEnterprisesInd'] = resp.data['marketEnterprisesInd'];
state.custInfoObj['industryType'] = resp.data['industryType'];
state.custInfoObj['industryTypeName'] = resp.data['industryTypeName'];
state.custInfoObj['buildDate'] = resp.data['buildDate'];
state.custInfoObj['customerManagerNo'] = resp.data['customerManagerNo'];
state.custInfoObj['customerManagerName'] = resp.data['customerManagerName'];
state.custInfoObj['handleOrgId'] = resp.data['handleOrgId'];
state.custInfoObj['handleTime'] = resp.data['handleTime'];
}
});
// 加载财报信息
financeReportGridRef.value.setFetchDataUrl(
Environment.apiContextPath('api/irbs/financeReport/getReport?custId=' + state.rating['custId'] + '&sort=' + customerType),
);
financeReportGridRef.value.refresh();
// 加载征信报告
creditReportGridRef.value.setQueryCriteriaFieldValue('custNo', state.rating['custNo']);
creditReportGridRef.value.refresh();
};
// 客户信息下一步,进入定量分析
const custInfoNext = (loading = false) => {
if (loading) {
showLoading('正在获取定量得分,请稍等...');
}
state.custInfoDone = true;
state.step = RatingStep.DLFX;
axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepQuan'), { params: { ratingId: state.rating['id'], page: 'apply' } })
.then((resp) => {
hideLoading();
if (resp && resp.data && resp.data.quanScore) {
state.quantitativeInfo = [];
state.quantitativeInfo.push({ label: '定量得分', value: Round(resp.data.quanScore, 2) });
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
};
// 定量分析下一步,进入定性分析
const quantitativeNext = () => {
state.quantitativeDone = true;
state.step = RatingStep.DXFX;
axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepQual'), { params: { ratingId: state.rating['id'], page: 'apply' } })
.then((resp) => {
hideLoading();
if (resp && resp.data && resp.data.indices) {
state.qualitativeEditInfo = [];
for (let i = 0; i < resp.data.indices.length; i++) {
let index = resp.data.indices[i];
let indexOptions = <any>[];
if (index.options && index.options.length > 0) {
index.options.forEach((item) => {
indexOptions.push({ label: item.text, value: item.disVal });
});
}
if (!Tools.isEmpty(index.indexValue)) {
state.qualitativeEditInfo.push({
label: i + 1 + '、' + index.indexName,
name: index.indexCode,
type: 'option-group',
options: indexOptions,
defaultValue: index.indexValue,
});
} else {
state.qualitativeEditInfo.push({ label: i + 1 + '、' + index.indexName, name: index.indexCode, type: 'option-group', options: indexOptions });
}
state.qualitativeEditObj[index.indexCode] = [i + 1 + '、' + index.indexName, index];
}
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
};
// 定性分析下一步,进入初评结果
const qualitativeEditNext = () => {
// 判断是否存在未选择的选项
const formData = qualitativeFormRef.value.getData();
const submitData = <any>[];
let flag = true;
const errorRows = <any>[];
const keys = Object.keys(formData);
for (let i = 0; i < keys.length; i++) {
if (Tools.isEmpty(formData[keys[i]])) {
flag = false;
errorRows.push({
label: state.qualitativeEditObj[keys[i]][0],
value: keys[i],
checkedIcon: 'cancel',
uncheckedIcon: 'cancel',
color: 'red',
keepColor: true,
disable: true,
dense: true,
});
} else {
state.qualitativeEditObj[keys[i]][1].indexValue = formData[keys[i]];
submitData.push(state.qualitativeEditObj[keys[i]][1]);
}
}
if (!flag) {
$q.dialog({
title: '提示',
message: '以下定性选项为空,请选择后执行该操作!',
persistent: true,
options: {
type: 'checkbox',
model: [],
items: errorRows,
},
});
return;
}
$q.dialog({
title: '询问',
message: '请检查所选数据的正确性,提交并计算结果后无法再次修改,确定要提交吗?',
cancel: true,
persistent: true,
}).onOk(async () => {
showLoading('正在计算定性得分,请稍等...');
const resp = await axios.post(Environment.apiContextPath('api/irbs/companyRating/qualSaveIndices'), submitData).catch((error) => {
hideLoading();
NotifyManager.error('计算出错,请联系管理员');
console.info('error====', error);
});
if (resp && resp.data) {
loadFirstResult();
}
});
};
const loadFirstResult = () => {
state.qualitativeShowInfo = [];
axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepInitRating'), { params: { ratingId: state.rating['id'], page: 'apply' } })
.then((res) => {
hideLoading();
if (res && res.data) {
state.qualitativeEditDone = true;
state.step = RatingStep.CPJG;
state.qualitativeShowInfo.push({ label: '定量得分', value: Round(res.data.quanScore, 2) });
state.qualitativeShowInfo.push({ label: '定性得分', value: Round(res.data.qualScore, 2) });
state.qualitativeShowInfo.push({ label: '得分', value: Round(res.data.modelScore, 2) });
state.qualitativeShowInfo.push({
label: '等级',
value: res.data.modelLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: res.data.modelLevel,
dense: true,
},
};
},
});
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
};
// 初评结果下一步,进入评级调整项
const qualitativeShowNext = () => {
state.qualitativeShowDone = true;
state.step = RatingStep.PJTZX;
axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepAdj'), { params: { ratingId: state.rating['id'], page: 'apply' } })
.then((resp) => {
if (resp && resp.data && resp.data.indices) {
state.adjustItemInfo = [];
for (let i = 0; i < resp.data.indices.length; i++) {
let index = resp.data.indices[i];
let indexOptions = <any>[];
if (index.options && index.options.length > 0) {
index.options.forEach((item) => {
indexOptions.push({ label: item.text, value: item.disVal });
});
}
if (!Tools.isEmpty(index.indexValue)) {
state.adjustItemInfo.push({
label: i + 1 + '、' + index.indexName,
name: index.indexCode,
type: 'option-group',
options: indexOptions,
defaultValue: index.indexValue,
});
} else {
state.adjustItemInfo.push({ label: i + 1 + '、' + index.indexName, name: index.indexCode, type: 'option-group', options: indexOptions });
}
state.adjustItemObj[index.indexCode] = [i + 1 + '、' + index.indexName, index];
}
}
})
.catch((error) => {
console.info('error====', error);
});
};
// 评级调整项下一步,进入签署意见
const adjustItemNext = () => {
// 判断是否存在未选择的选项
const formData = adjustItemFormRef.value.getData();
const submitData = <any>[];
let flag = true;
const errorRows = <any>[];
const keys = Object.keys(formData);
for (let i = 0; i < keys.length; i++) {
if (Tools.isEmpty(formData[keys[i]])) {
flag = false;
errorRows.push({
label: state.adjustItemObj[keys[i]][0],
value: keys[i],
checkedIcon: 'cancel',
uncheckedIcon: 'cancel',
color: 'red',
keepColor: true,
disable: true,
dense: true,
});
} else {
state.adjustItemObj[keys[i]][1].indexValue = formData[keys[i]];
submitData.push(state.adjustItemObj[keys[i]][1]);
}
}
if (!flag) {
$q.dialog({
title: '提示',
message: '以下调整项选项为空,请选择后执行该操作!',
persistent: true,
options: {
type: 'checkbox',
model: [],
items: errorRows,
},
});
return;
}
$q.dialog({
title: '询问',
message: '请检查所选数据的正确性,提交并计算结果后无法再次修改,确定要提交吗?',
cancel: true,
persistent: true,
}).onOk(async () => {
showLoading('正在重新计算得分,请稍等...');
const resp = await axios.post(Environment.apiContextPath('api/irbs/companyRating/saveIndices'), submitData).catch((error) => {
hideLoading();
NotifyManager.error('计算出错,请联系管理员');
console.info('error====', error);
});
if (resp) {
loadRatingOverturn();
} else {
hideLoading();
}
});
};
const loadRatingOverturn = () => {
axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepRatingOverturn'), { params: { ratingId: state.rating['id'], page: 'apply' } })
.then((res) => {
hideLoading();
if (res && res.data) {
state.adjustItemDone = true;
state.step = RatingStep.QSYJ;
state.otherInfo = [];
state.otherInfo.push({ label: '定量得分', value: Round(res.data.quanScore, 2) });
state.otherInfo.push({ label: '定性得分', value: Round(res.data.qualScore, 2) });
state.otherInfo.push({ label: '模型得分', value: Round(res.data.modelScore, 2) });
state.otherInfo.push({
label: '模型等级',
value: res.data.modelLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: res.data.modelLevel,
dense: true,
},
};
},
});
state.otherInfo.push({
label: '调整后等级',
value: res.data.adjLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: res.data.adjLevel,
dense: true,
},
};
},
});
state.otherInfo.push({
label: '准入建议',
value: res.data.accessLevel,
});
state.otherInfoAdjLevel = res.data.adjLevel;
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
// 获取当前参数配置中设置的向上推翻等级限制
axios
.get(Environment.apiContextPath('api/irbs/companyRating/getSystemParameter'), { params: { code: 'parameter.irbs.params.overturnLevel' } })
.then((res) => {
if (res && res.data) {
state.overturnLevelNum = parseInt(res.data);
}
})
.catch((error) => {
console.info('error====', error);
});
};
const groupByProperties = (list, propName) => {
const map = {};
list.forEach((item, index, arr) => {
if (!map[item[propName]]) {
map[item[propName]] = arr.filter((a) => a[propName] == item[propName]);
}
});
return map;
};
const loadRatingReport = async () => {
// 加载评级信息
state.reportCustRatingInfo = [];
await axios
.get(Environment.apiContextPath('api/irbs/companyRating/stepRatingReport'), { params: { ratingId: state.rating['id'] } })
.then((resp) => {
if (resp && resp.data) {
state.rating = resp.data;
state.reportCustRatingInfo.push({ label: '模型名称', value: resp.data.modelName });
state.reportCustRatingInfo.push({ label: '定量得分', value: Round(resp.data.quanScore, 2) });
state.reportCustRatingInfo.push({ label: '定性得分', value: Round(resp.data.qualScore, 2) });
state.reportCustRatingInfo.push({ label: '模型得分', value: Round(resp.data.modelScore, 2) });
state.reportCustRatingInfo.push({
label: '模型级别',
value: resp.data.modelLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: resp.data.modelLevel,
dense: true,
},
};
},
});
state.reportCustRatingInfo.push({
label: '调整项级别',
value: resp.data.adjLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: resp.data.adjLevel,
dense: true,
},
};
},
});
state.reportCustRatingInfo.push({
label: '初始级别',
value: resp.data.initLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: resp.data.initLevel,
dense: true,
},
};
},
});
state.reportCustRatingInfo.push({ label: '上一次建议级别', value: resp.data.spLevel });
state.reportCustRatingInfo.push({
label: '最终认定级别',
value: resp.data.finalLevel,
format: () => {
return {
componentType: RatingLevel,
attrs: {
level: resp.data.finalLevel,
dense: true,
},
};
},
});
state.reportCustRatingInfo.push({ label: '违约概率', value: resp.data.pd ? resp.data.pd + '%' : '' });
state.reportCustRatingInfo.push({ label: '客户经理', value: resp.data.managerName });
state.reportCustRatingInfo.push({ label: '评级发起日期', value: resp.data.startTime });
state.reportCustRatingInfo.push({ label: '评级生效日期', value: resp.data.effectiveTime });
state.reportCustRatingInfo.push({ label: '评级到期日期', value: resp.data.matureTime });
state.reportCustRatingInfo.push({ label: '评级状态', value: resp.data.ratingStatus, format: Formater.enum(RatingStatusEnum) });
state.reportCustRatingInfo.push({ label: '流程状态', value: resp.data.processStatus, format: Formater.enum(RatingProcessStatusEnum) });
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
// 判断当前用户是否能看到得分详情
const authResult = await axios.get(Environment.apiContextPath('api/irbs/rating/report/showScoreRole/findShowScoreAuth')).catch((error) => {
console.info('error====', error);
});
if (authResult && authResult['code'] === 200 && typeof authResult['data'] === 'boolean' && authResult['data']) {
state.reportShowScoreDtl = true;
// 加载得分详情
const urlSearchParams = new URLSearchParams({ sortBy: ['INDEX_TYPE', 'INDEX_CATEGORY'] });
urlSearchParams.append('pageable', 'false');
const criteria = {
fieldName: 'RATING_ID',
operator: 'equals',
value: state.rating['id'],
};
urlSearchParams.append('criteria', JSON.stringify(criteria));
await axios
.get(Environment.apiContextPath('api/irbs/ratingIndex/getScoreDetail'), { params: urlSearchParams })
.then((resp) => {
if (resp?.data?.content) {
const groupMap = groupByProperties(resp.data.content, 'INDEX_TYPE');
state.reportQuantitativeScoreDtl = groupByProperties(groupMap[RatingStep.DLFX], 'INDEX_CATEGORY');
state.reportQualitativeScoreDtl = groupByProperties(groupMap[RatingStep.DXFX], 'INDEX_CATEGORY');
state.reportAdjustScoreDtl = groupByProperties(groupMap[RatingStep.PJTZX], 'INDEX_CATEGORY');
}
})
.catch((error) => {
hideLoading();
console.info('error====', error);
});
}
};
const dialogButtons = [
{
label: '设置默认值',
click: () => {
if (state.step === RatingStep.PJTZX) {
const formData = adjustItemFormRef.value.getData();
const testObj = {};
Object.keys(formData).forEach((item) => {
testObj[item] = '0';
});
adjustItemFormRef.value.setData(testObj);
} else if (state.step === RatingStep.DXFX) {
const formData = qualitativeFormRef.value.getData();
const testObj = {};
Object.keys(formData).forEach((item) => {
testObj[item] = '1';
});
qualitativeFormRef.value.setData(testObj);
}
},
},
];
const showNextBtnComputed = computed(() => {
if (
state.ratingProcessStatus === RatingProcessStatus.AWAIT_RATING ||
state.ratingProcessStatus === RatingProcessStatus.AWAIT_SUBMIT ||
(state.ratingProcessStatus === RatingProcessStatus.BACK && !state.viewFlag)
) {
return true;
} else {
return false;
}
});
const dialogButtonsComputed = computed(() => {
if (state.viewFlag) {
return [];
} else if (
state.ratingProcessStatus === RatingProcessStatus.AWAIT_RATING ||
state.ratingProcessStatus === RatingProcessStatus.AWAIT_SUBMIT ||
state.ratingProcessStatus === RatingProcessStatus.BACK
) {
return dialogButtons;
}
return [];
});
const stepMinHeightComputed = computed(() => {
let style = '';
if (dialogRef?.value && dialogRef.value.getContent() && state.dialogContentHeight) {
style = 'min-height: calc(' + dialogRef.value.getContent().offsetHeight + 'px - ' + '73px)';
} else {
style = 'min-height: calc(' + state.dialogContentHeight + 'px - ' + '73px)';
}
return style;
});
const maximized = (flag) => {
nextTick(() => {
state.dense = !flag;
state.dialogContentHeight = dialogRef.value.getContent().offsetHeight;
if (flag) {
state.tableHeight = 150;
} else {
state.tableHeight = 100;
}
});
};
const finReportDetailDialogMaximized = () => {
nextTick(() => {
state.finReportDetailDialogContentHeight = financeReportDetailDialogRef.value.getContent().offsetHeight - 33;
});
};
const show = (data: any, viewFlag = false) => {
dialogRef.value.show();
state.rating = data;
state.viewFlag = viewFlag;
state.dialogTitle = `公司客户评级 客户:` + data['custName'] + ` 评级模型:` + (data['modelName'] || '');
// if (data.currentStep === 'WAIT_INIT' || data.currentStep === 'CHECK_FINISH') {
// axios.post(Environment.apiContextPath('api/irbs/companyRating/startRating/' + data['id'])).catch((error) => {
// console.info('error====', error);
// });
// }
state.ratingProcessStatus = data['processStatus'];
nextTick(async () => {
stepperRef.value.$el.getElementsByClassName('q-stepper__header')[0].style.setProperty('--stickyBgColor', stickyBgColor);
loadCustInfo();
if (state.rating['currentStep'] === RatingStep.DLFX) {
custInfoNext();
} else if (state.rating['currentStep'] === RatingStep.DXFX) {
state.custInfoDone = true;
quantitativeNext();
} else if (state.rating['currentStep'] === RatingStep.CPJG) {
state.custInfoDone = true;
state.quantitativeDone = true;
loadFirstResult();
} else if (state.rating['currentStep'] === RatingStep.PJTZX) {
state.custInfoDone = true;
state.quantitativeDone = true;
state.qualitativeEditDone = true;
qualitativeShowNext();
} else if (state.rating['currentStep'] === RatingStep.QSYJ) {
state.custInfoDone = true;
state.quantitativeDone = true;
state.qualitativeEditDone = true;
state.qualitativeShowDone = true;
loadRatingOverturn();
}
if (viewFlag || state.rating['currentStep'] === RatingStep.PJBG) {
state.custInfoDone = true;
state.quantitativeDone = true;
state.qualitativeEditDone = true;
state.qualitativeShowDone = true;
state.adjustItemDone = true;
await loadRatingReport();
if (viewFlag) {
state.rating['currentStep'] = RatingStep.PJBG;
state.step = RatingStep.PJBG;
}
}
});
};
const hide = () => {
dialogRef.value.hide();
};
const showLoading = (msg: string = '正在获取数据,请稍等...') => {
$q.loading.show({
message: msg,
boxClass: 'bg-grey-2 text-grey-9',
spinnerColor: 'primary',
});
};
const hideLoading = () => {
$q.loading.hide();
};
defineExpose({
show,
hide,
});
const dictionaryArr = await DictionaryTools.fetch([
'OVERTURN_TYPE',
'CustomerSizeCd',
'REGISTERED_TYPE',
'GOVER_FINANCE_TYPE',
'GOVER_FINANCE_SIGN',
'REGISTRATION_CD',
'NATION_CD',
'MEMBER_TYPE_CD',
'FinanceTypeCd',
'FinanceSortTypeCd',
'FinanceStatusCd',
'CaliberCd',
'CurrencyTypeCd',
]);
const dictOverturnType = dictionaryArr['OVERTURN_TYPE'];
const optionsOverturnType = Options.dictionary(dictOverturnType);
const dictCustomerSize = dictionaryArr['CustomerSizeCd'];
const dictRegisteredType = dictionaryArr['REGISTERED_TYPE'];
const dictGoverFinanceType = dictionaryArr['GOVER_FINANCE_TYPE'];
const dictGoverFinanceSign = dictionaryArr['GOVER_FINANCE_SIGN'];
const dictRegistrationCd = dictionaryArr['REGISTRATION_CD'];
const dictNationCd = dictionaryArr['NATION_CD'];
const dictMemberTypeCd = dictionaryArr['MEMBER_TYPE_CD'];
const dictFinanceTypeCd = dictionaryArr['FinanceTypeCd'];
const dictFinanceSortTypeCd = dictionaryArr['FinanceSortTypeCd'];
const dictFinanceStatusCd = dictionaryArr['FinanceStatusCd'];
const dictCaliberCd = dictionaryArr['CaliberCd'];
const dictCurrencyTypeCd = dictionaryArr['CurrencyTypeCd'];
const enumArr = await EnumTools.fetch(['irbs.cust.rating.enums.RatingStatus', 'irbs.cust.rating.enums.RatingProcessStatus']);
const RatingStatusEnum = enumArr['irbs.cust.rating.enums.RatingStatus'];
const RatingProcessStatusEnum = enumArr['irbs.cust.rating.enums.RatingProcessStatus'];
</script>
<style scoped lang="css">
:deep(.q-stepper__header) {
position: sticky;
top: 0;
z-index: 100;
background-color: var(--stickyBgColor);
}
.q-stepper--horizontal :deep(.q-stepper__step-inner) {
padding: 10px;
}
</style>