feat(riskCheck): 新增风险筛查结果页面

- 添加历史风险筛查结果页面组件
- 实现风险筛查结果的展示和详情加载功能
- 优化页面样式和布局
This commit is contained in:
du.meimei
2025-07-28 10:37:22 +08:00
parent c2dbce956c
commit c838c966b8
8 changed files with 1382 additions and 215 deletions

View File

@@ -348,7 +348,7 @@
<!-- 注意:两个 div 写在同一行,避免 inline-block 空隙 -->
<div class="main" id="main">
<div class="left-nav">
<div class="left-nav" id="leftNav">
<div class="nav-header">历史风险筛查结果</div>
<div class="nav-body" id="navBody">
<div id="loadingNav" class="loading">
@@ -357,7 +357,7 @@
</div>
</div>
</div>
<div class="right-container">
<div class="right-container" id="right-container">
<div class="top-container">
<div class="custom-container">
<span id="custom">客户名称</span>
@@ -377,12 +377,19 @@
<script src="ajax.js"></script>
<script>
var noNav = getQueryParam('noNav')
var noPadding = getQueryParam('noPT')
if (noPadding) {
document.getElementById('main')
main.style.padding = '0'
}
if (noNav) {
var leftNav = document.getElementById('leftNav')
var rightContainer = document.getElementById('right-container')
leftNav.style.display = 'none'
rightContainer.style.width = '100%'
}
// 添加错误处理函数
function handleError(errorMsg, url, line) {
console.log('Error occurred: ' + errorMsg + ' at ' + url + ':' + line)

View File

@@ -278,10 +278,10 @@ export default {
this.submitLoading = true
// 根据是否为编辑模式调用不同接口
const request = this.isEdit ? updateRule : createRule
// 创建提交参数的副本
const params = Object.assign({}, this.ruleForm)
// 将ruleType的值转换为对应的中文typeName
const selectedRuleType = this.ruleTypeList.find(
item => item.typeCode === params.ruleType
@@ -289,7 +289,7 @@ export default {
if (selectedRuleType) {
params.ruleType = selectedRuleType.typeName
}
// 将ruleField的值转换为对应的中文fieldComment
const selectedFieldType = this.fieldTypeList.find(
item => item.fieldName === params.ruleField

View File

@@ -0,0 +1,49 @@
<template>
<div>
<h3>审批单录入</h3>
<!-- 审批单基本信息 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>审批单基本信息</span>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form ref="form" :model="formData" label-width="120px">
<el-form-item label="审批单号">
<el-input
v-model="formData.orderCode"
placeholder="请输入审批单号"
></el-input>
</el-form-item>
<el-form-item label="审批单出单时间">
<el-date-picker
v-model="formData.orderTime"
type="datetime"
placeholder="选择日期时间"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
></el-date-picker>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12">
<!-- 右侧留空保持对称 -->
</el-col>
</el-row>
</el-card>
</div>
</template>
<script>
export default {
name: 'ApprovalForm',
props: {
formData: {
type: Object,
default: () => ({})
}
}
}
</script>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,143 @@
<template>
<!-- 基本信息 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>基本信息</span>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form ref="form" :model="formData.data.baseInfo" label-width="120px">
<el-form-item label="客户名称">
<el-input
v-model="formData.data.baseInfo.customerName"
placeholder="请输入客户名称"
></el-input>
</el-form-item>
<el-form-item label="起保日期">
<el-date-picker
v-model="formData.data.baseInfo.insureStartDate"
type="date"
placeholder="选择起保日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="归属机构">
<el-input
type="text"
placeholder="输入归属机构"
v-model="formData.data.baseInfo.orgName"
></el-input>
</el-form-item>
<el-form-item label="是否续保">
<el-radio-group v-model="formData.data.baseInfo.isRenew">
<el-radio label="是"></el-radio>
<el-radio label="否"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="业务来源">
<el-input
type="text"
placeholder="输入业务来源"
v-model="formData.data.baseInfo.bizSource"
></el-input>
</el-form-item>
<el-form-item label="签报有效起期">
<el-date-picker
v-model="formData.data.baseInfo.signStartDate"
type="date"
placeholder="选择签报有效起期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="业务详细说明">
<el-input
type="textarea"
:rows="3"
placeholder="说明业务来源、背景及分公司初步风险判断"
v-model="formData.data.baseInfo.bizDescription"
></el-input>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12">
<el-form ref="form" :model="formData.data.baseInfo" label-width="120px">
<el-form-item label="终保日期">
<el-date-picker
v-model="formData.data.baseInfo.insureEndDate"
type="date"
placeholder="选择终保日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="共保标志">
<el-select
v-model="formData.data.baseInfo.isCoUnderwriting"
placeholder="请选择共保标志"
>
<el-option label="独家承保" value="独家承保"></el-option>
<el-option label="共保" value="共保"></el-option>
</el-select>
</el-form-item>
<el-form-item label="业务细分">
<el-input
type="text"
placeholder="输入业务细分"
v-model="formData.data.baseInfo.bizDetailSource"
></el-input>
</el-form-item>
<el-form-item label="签报有效止期">
<el-date-picker
v-model="formData.data.baseInfo.signEndDate"
type="date"
placeholder="选择签报有效止期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<!-- 补充的字段 -->
<el-form-item label="主险代码">
<el-input
v-model="formData.data.baseInfo.mainRiskCode"
placeholder="请输入主险代码"
></el-input>
</el-form-item>
<el-form-item label="总保额">
<el-input
v-model="formData.data.baseInfo.totalAmt"
placeholder="请输入总保额"
></el-input>
</el-form-item>
<el-form-item label="总保费">
<el-input
v-model="formData.data.baseInfo.totalPrem"
placeholder="请输入总保费"
></el-input>
</el-form-item>
<el-form-item label="币种">
<el-input
v-model="formData.data.baseInfo.currency"
placeholder="如CNY"
></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
</el-card>
</template>
<script>
export default {
name: 'BaseForm',
props: {
formData: {
type: Object,
default: () => ({})
}
}
}
</script>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,579 @@
<template>
<div class="main" id="main">
<div class="left-nav">
<div class="nav-header">历史风险筛查结果</div>
<div class="nav-body" id="navBody">
<div v-if="loadingNav" class="loading">
<span class="loading-spinner"></span>
数据加载中...
</div>
<div v-else-if="navList.length === 0" class="empty-message">
暂无历史记录
</div>
<a
v-else
v-for="(navItem, i) in navList"
:key="i"
href="javascript:void(0)"
:class="['link', { active: activeNavIndex === i }]"
@click="handleNavClick(i)"
>
<img
:src="navItem.hasRisk === 1 ? errorIcon : rightIcon"
class="png-icon"
/>
{{ navItem.taSubmitDate }}
<span>{{ navItem.hasRisk === 1 ? '【有风险】' : '【无风险】' }}</span>
</a>
</div>
</div>
<div class="right-container">
<div class="top-container">
<div class="custom-container">
<span id="custom">{{ navCheckRecord.orgName || '未知客户' }}</span>
<span id="time">{{ detailTimeInfo }}</span>
</div>
<h4 id="insured">
被保险人名称{{ navCheckRecord.insuredName || '未知' }}
</h4>
<div id="docs" v-html="currentCheckSummary"></div>
</div>
<div style="overflow: auto;">
<div id="detail-container">
<div v-if="detailLoading" class="loading">
<span class="loading-spinner"></span>
正在加载详情...
</div>
<div v-else-if="arrs.length === 0" class="empty-message">
<img
src="@/assets/images/empty.png"
alt=""
style="width:200px;margin: 0 auto"
/>
<p>暂无风险</p>
</div>
<template v-else>
<div v-for="(resultDetail, ind) in arrs" :key="ind">
<h4 v-if="resultDetail.tabName" class="section-title">
{{ resultDetail.tabName }}
</h4>
<div
:class="['tree-item-header', { expanded: expandedItems[ind] }]"
@click="toggleItem(ind)"
>
{{
resultDetail.typeName
? resultDetail.typeName
: resultDetail.dictLabel
}}
</div>
<div
:id="'result-container-' + ind"
class="result-container-item"
:style="{ display: expandedItems[ind] ? 'block' : 'none' }"
>
<ul class="result-container-item-child-ul">
<li
v-if="
!(
resultDetail.children &&
resultDetail.children.length > 0
)
"
class="result-container-item-child"
style="color: #95a5a6; font-style: italic;"
>
暂无数据
</li>
<li
v-for="(child, childIndex) in resultDetail.children"
:key="childIndex"
class="result-container-item-child"
@click="handleChildClick(child)"
>
<span class="index">{{ childIndex + 1 }}</span>
{{
(child.ruleName ? child.ruleName : child.fileName) ||
'未知项目'
}}
</li>
</ul>
</div>
</div>
</template>
</div>
</div>
</div>
<div style="clear: both"></div>
</div>
</template>
<script>
import { queryResult, queryResultDetail } from '@/api/riskCheck/record'
import errorIcon from '@/assets/images/error.png'
import rightIcon from '@/assets/images/right.png'
export default {
name: 'RiskHistory',
data() {
return {
errorIcon,
rightIcon,
loadingNav: true,
detailLoading: false,
navList: [],
navCheckRecord: {},
activeNavIndex: -1,
arrs: [],
expandedItems: {},
ipConfig: {
ip: this.$route.query.ip || 'http://39.104.123.256:7196'
},
serviceUrl: {
download: {
url: '/bpic/image/download'
}
}
}
},
computed: {
currentCheckSummary() {
if (this.activeNavIndex >= 0 && this.navList[this.activeNavIndex]) {
return (
this.navList[this.activeNavIndex].checkSummary ||
'<p>暂无风险摘要信息</p>'
)
}
return '<p>请选择左侧记录查看详细信息</p>'
},
detailTimeInfo() {
if (this.activeNavIndex >= 0 && this.navList[this.activeNavIndex]) {
return (
(this.navCheckRecord.taLatestSubmitDate || '未知时间') +
' 共【' +
(this.arrs ? this.arrs.length : 0) +
'】条风险提示'
)
}
return ''
}
},
mounted() {
// 处理noPT参数
if (this.$route.query.noPT) {
const main = document.getElementById('main')
if (main) {
main.style.padding = '0'
}
}
this.getNavList()
},
methods: {
getNavList() {
const taCode = this.$route.query.taCode || 'C123504032025600027'
queryResult({ taCode })
.then(response => {
this.loadingNav = false
if (response.code !== 200) {
this.$message.error(response.message || '请求失败')
throw new Error(response.message || '请求失败')
}
const data = response.content || response.data
this.navList = data.resultList || []
this.navCheckRecord = data.riskCheckRecord || {}
// 默认点击第一个导航项
if (this.navList.length > 0) {
this.$nextTick(() => {
this.handleNavClick(0)
})
}
})
.catch(error => {
this.loadingNav = false
this.$message.error('获取数据失败: ' + error.message)
this.navList = []
})
},
handleNavClick(index) {
// 更新活动索引
this.activeNavIndex = index
// 格式化checkSummary
if (
this.navList[index].checkSummary &&
typeof this.navList[index].checkSummary === 'string'
) {
let text = this.navList[index].checkSummary
text = text.replace(/\n\n/g, '</p><p>') // 段落
text = text.replace(/\n/g, '<br/>') // 剩余单换行
text = '<p>' + text + '</p>'
text = text.replace(/<p><\/p>/g, '<p>&nbsp;</p>') // 防止空段落出错
this.navList[index].checkSummary = text
} else {
this.navList[index].checkSummary = '<p>暂无风险摘要信息</p>'
}
// 获取详情
this.getDetail(this.navList[index])
},
getDetail(navItem) {
this.detailLoading = true
const taCode = this.$route.query.taCode || this.navCheckRecord.taCode
const params = {
resultId: navItem.id,
recordId: navItem.recordId,
taCode: taCode
}
queryResultDetail(params)
.then(response => {
this.detailLoading = false
if (response.code !== 200) {
this.$message.error(response.message || '请求失败')
throw new Error(response.message || '请求失败')
}
const data = response.content || response.data
const result = data.ruleTypeList || []
const fileStorageInfoList = data.fileBizTypeDictList || []
this.arrs = []
if (result && result.length > 0) {
result[0].tabName = '风险筛查结果'
for (let i = 0; i < result.length; i++) {
this.arrs.push(result[i])
}
}
if (fileStorageInfoList && fileStorageInfoList.length > 0) {
fileStorageInfoList[0].tabName = '影像件'
for (let i = 0; i < fileStorageInfoList.length; i++) {
this.arrs.push(fileStorageInfoList[i])
}
}
// 默认展开第一个项目
if (this.arrs.length > 0) {
this.$set(this.expandedItems, 0, true)
}
})
.catch(error => {
this.detailLoading = false
this.$message.error('获取详情失败: ' + error.message)
this.arrs = []
})
},
toggleItem(index) {
this.$set(this.expandedItems, index, !this.expandedItems[index])
},
handleChildClick(item) {
if (item.filePath) {
window.open(
this.ipConfig.ip + this.serviceUrl.download.url + '?fileId=' + item.id
)
}
}
}
}
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main {
width: 100%;
height: 100%;
padding: 1%;
font-size: 0; /* 消除 inline-block 间隙 */
}
.left-nav {
width: 20%;
float: left;
height: 100%;
display: inline-block;
vertical-align: top;
background: #fff;
border-radius: 10px;
font-size: 16px; /* 恢复字体 */
border: 1px solid #ddd;
/* IE8兼容的阴影效果 */
filter: progid:DXImageTransform.Microsoft.Shadow(color='#cccccc', Direction=135, Strength=3);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.nav-header {
font-size: 18px;
font-weight: bold;
text-align: center;
padding: 20px 0;
border-bottom: 1px solid #eee;
background: #f8f9fa;
color: #2c3e50;
border-radius: 10px 10px 0 0;
}
.link {
display: block;
margin: 15px auto;
text-align: center;
background: #fff;
text-decoration: none;
color: #000;
font-size: 14px;
border-radius: 4px;
padding: 12px 10px;
width: 85%;
transition: all 0.3s ease;
/* IE8兼容样式 */
border: 1px solid transparent;
}
.link:hover {
background: #f5f9ff;
border-color: #3498db;
color: #000;
}
.link.active {
background: #f0f4fa;
color: #3498db;
}
.right-container {
width: 79%;
height: 100%;
display: inline-block;
float: right;
background: #fff;
border-radius: 10px;
font-size: 16px;
overflow-y: auto;
overflow-x: hidden;
border: 1px solid #ddd;
/* IE8兼容的阴影效果 */
filter: progid:DXImageTransform.Microsoft.Shadow(color='#cccccc', Direction=135, Strength=3);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.top-container,
#detail-container {
width: 100%;
background: #fff;
margin-bottom: 10px;
border: 1px solid #eee;
}
.top-container {
border-bottom: 1px solid #eee;
padding: 20px;
background: #fafbfc;
}
#detail-container {
padding: 20px;
}
#custom {
display: inline-block;
font-size: 22px;
font-weight: bold;
margin-right: 15px;
color: #2c3e50;
}
#time {
font-size: 14px;
margin-top: 8px;
color: #7f8c8d;
}
.custom-container {
display: block;
margin: 10px 0 20px 0;
}
#docs {
padding: 15px 20px;
font-size: 14px;
line-height: 1.6;
background: #2c3e50;
color: #ecf0f1;
border-radius: 4px;
margin: 15px 0;
}
#insured {
padding: 10px 0;
font-weight: bold;
color: #2c3e50;
border-bottom: 1px solid #eee;
}
.tree-item-header {
padding: 15px 20px;
background: #f0f4fa;
margin: 15px 0;
cursor: pointer;
border-radius: 4px;
border: 1px solid #d6dde6;
font-weight: bold;
color: #2c3e50;
transition: background 0.3s;
/* IE8兼容样式 */
background: #e3e9f2;
}
.tree-item-header:hover {
background: #e3e9f2;
}
.tree-item-header::before {
content: '';
margin-right: 10px;
transition: transform 0.3s;
/* IE8不支持::before伪元素和transform */
}
.tree-item-header.expanded::before {
content: '';
/* IE8不支持 */
}
.result-container-item {
padding: 0 10px;
margin-bottom: 20px;
}
.result-container-item-child-ul {
list-style: none;
}
ul {
list-style: none;
}
li {
list-style: none;
}
.index {
margin: 0 10px;
display: inline-block;
width: 25px;
height: 25px;
line-height: 25px;
text-align: center;
border-radius: 50%;
color: #fff;
background-color: #9fa8da;
border: 1px solid #9fa8da;
}
.result-container-item-child-ul li {
font-size: 14px;
line-height: 1.8;
padding: 10px 15px;
margin: 8px 0;
background: #fff;
border: 1px solid #eee;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
/* IE8兼容样式 */
border: 1px solid #ddd;
}
.result-container-item-child-ul li:hover {
background: #f8f9ff;
border-color: #3498db;
}
/* 添加降级样式 */
.no-js-warning {
color: #e74c3c;
text-align: center;
padding: 30px;
font-weight: bold;
font-size: 16px;
background: #fadbd8;
border: 1px solid #f5b7b1;
border-radius: 4px;
margin: 20px;
}
/* 为不支持flex的浏览器提供备选方案 */
.custom-container > * {
display: inline-block;
vertical-align: top;
}
/* 添加加载状态提示 */
.loading {
text-align: center;
padding: 30px;
color: #7f8c8d;
}
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
/* IE8不支持动画 */
border: 3px solid #3498db;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.section-title {
font-size: 18px;
font-weight: bold;
margin: 25px 0 15px 0;
padding-bottom: 10px;
border-bottom: 2px solid #3498db;
color: #2c3e50;
}
.empty-message {
text-align: center;
padding: 40px 20px;
color: #95a5a6;
}
.png-icon {
vertical-align: middle;
margin: -2px 10px 0 10px;
outline: none;
border: none;
display: inline-block;
}
</style>

View File

@@ -50,7 +50,9 @@
<span :style="{ backgroundColor: item.color }">{{
index + 1
}}</span>
{{ item.warning }}
{{
item.warning
}}
</ul>
</ul>
</details>

View File

@@ -1,99 +1,579 @@
<template>
<div class="risk-check-result" v-if="content">
<!-- 背景为白色 -->
<div class="header">
<h2>风险筛查结果</h2>
<div class="check-info">
<span>
筛查检查结果ID: {{ content.riskCheckResultId }} 筛查时间:
{{ formatTime(content.riskCheckTime) }}
{{
this.content.detailList ? content.detailList.length : 0
}}条风险提示
</span>
<div class="main" id="main">
<div class="left-nav">
<div class="nav-header">历史风险筛查结果</div>
<div class="nav-body" id="navBody">
<div v-if="loadingNav" class="loading">
<span class="loading-spinner"></span>
数据加载中...
</div>
<div v-else-if="navList.length === 0" class="empty-message">
暂无历史记录
</div>
<a
v-else
v-for="(navItem, i) in navList"
:key="i"
href="javascript:void(0)"
:class="['link', { active: activeNavIndex === i }]"
@click="handleNavClick(i)"
>
<!-- <img-->
<!-- :src="navItem.hasRisk === 1 ? errorIcon : rightIcon"-->
<!-- class="png-icon"-->
<!-- />-->
{{ navItem.taSubmitDate }}
<span>{{ navItem.hasRisk === 1 ? '【有风险】' : '【无风险】' }}</span>
</a>
</div>
</div>
<div class="right-container">
<div class="top-container">
<div class="custom-container">
<span id="custom">{{ navCheckRecord.orgName || '未知客户' }}</span>
<span id="time">{{ detailTimeInfo }}</span>
</div>
<h4 id="insured">
被保险人名称{{ navCheckRecord.insuredName || '未知' }}
</h4>
<div id="docs" v-html="currentCheckSummary"></div>
</div>
<div style="overflow: auto;">
<div id="detail-container">
<div v-if="detailLoading" class="loading">
<span class="loading-spinner"></span>
正在加载详情...
</div>
<div v-else-if="arrs.length === 0" class="empty-message">
<!-- <img-->
<!-- src="@/assets/images/empty.png"-->
<!-- alt=""-->
<!-- style="width:200px;margin: 0 auto"-->
<!-- />-->
<p>暂无风险</p>
</div>
<template v-else>
<div v-for="(resultDetail, ind) in arrs" :key="ind">
<h4 v-if="resultDetail.tabName" class="section-title">
{{ resultDetail.tabName }}
</h4>
<el-card>
<!-- 这里显示content.summary 的内容 -->
{{ content.summary }}
</el-card>
<div
:class="['tree-item-header', { expanded: expandedItems[ind] }]"
@click="toggleItem(ind)"
>
{{
resultDetail.typeName
? resultDetail.typeName
: resultDetail.dictLabel
}}
</div>
<!-- 只有当有风险时才显示风险列表 -->
<ul v-if="content.hasRisk === 1 && content.detailList.length > 0">
<li v-for="(detail, index) in content.detailList" :key="detail.id">
<!-- 风险的序号然后 detailList[index].warning -->
{{ index + 1 }}. {{ detail.warning }}
</li>
</ul>
<div
:id="'result-container-' + ind"
class="result-container-item"
:style="{ display: expandedItems[ind] ? 'block' : 'none' }"
>
<ul class="result-container-item-child-ul">
<li
v-if="
!(
resultDetail.children &&
resultDetail.children.length > 0
)
"
class="result-container-item-child"
style="color: #95a5a6; font-style: italic;"
>
暂无数据
</li>
<li
v-for="(child, childIndex) in resultDetail.children"
:key="childIndex"
class="result-container-item-child"
@click="handleChildClick(child)"
>
<span class="index">{{ childIndex + 1 }}</span>
{{
(child.ruleName ? child.ruleName : child.fileName) ||
'未知项目'
}}
</li>
</ul>
</div>
</div>
</template>
</div>
</div>
</div>
<div style="clear: both"></div>
</div>
</template>
<script>
import { queryResult, queryResultDetail } from '@/api/riskCheck/record'
// import errorIcon from '@/assets/images/error.png'
// import rightIcon from '@/assets/images/right.png'
export default {
name: 'RiskResult',
name: 'RiskHistory',
data() {
return {
content: {}
// errorIcon,
// rightIcon,
loadingNav: true,
detailLoading: false,
navList: [],
navCheckRecord: {},
activeNavIndex: -1,
arrs: [],
expandedItems: {},
ipConfig: {
ip: this.$route.query.ip || 'http://39.104.123.256:7196'
},
serviceUrl: {
download: {
url: '/bpic/image/download'
}
}
}
},
created() {
this.content = JSON.parse(localStorage.getItem('riskResult'))
computed: {
currentCheckSummary() {
if (this.activeNavIndex >= 0 && this.navList[this.activeNavIndex]) {
return (
this.navList[this.activeNavIndex].checkSummary ||
'<p>暂无风险摘要信息</p>'
)
}
return '<p>请选择左侧记录查看详细信息</p>'
},
detailTimeInfo() {
if (this.activeNavIndex >= 0 && this.navList[this.activeNavIndex]) {
const navItem = this.navList[this.activeNavIndex]
return (
(this.navCheckRecord.taLatestSubmitDate || '未知时间') +
' 共【' +
(this.arrs ? this.arrs.length : 0) +
'】条风险提示'
)
}
return ''
}
},
mounted() {
// 处理noPT参数
if (this.$route.query.noPT) {
const main = document.getElementById('main')
if (main) {
main.style.padding = '0'
}
}
this.getNavList()
},
methods: {
// 格式化时间显示
formatTime(timeString) {
if (!timeString) return ''
const date = new Date(timeString)
return date.toLocaleString('zh-CN')
getNavList() {
const taCode = this.$route.query.taCode || 'C123504032025600027'
queryResult({ taCode })
.then(response => {
this.loadingNav = false
if (response.code !== 200) {
throw new Error(response.message || '请求失败')
}
const data = response.content || response.data
this.navList = data.resultList || []
this.navCheckRecord = data.riskCheckRecord || {}
// 默认点击第一个导航项
if (this.navList.length > 0) {
this.$nextTick(() => {
this.handleNavClick(0)
})
}
})
.catch(error => {
this.loadingNav = false
this.$message.error('获取数据失败: ' + error.message)
this.navList = []
})
},
handleNavClick(index) {
// 更新活动索引
this.activeNavIndex = index
// 格式化checkSummary
if (
this.navList[index].checkSummary &&
typeof this.navList[index].checkSummary === 'string'
) {
let text = this.navList[index].checkSummary
text = text.replace(/\n\n/g, '</p><p>') // 段落
text = text.replace(/\n/g, '<br/>') // 剩余单换行
text = '<p>' + text + '</p>'
text = text.replace(/<p><\/p>/g, '<p>&nbsp;</p>') // 防止空段落出错
this.navList[index].checkSummary = text
} else {
this.navList[index].checkSummary = '<p>暂无风险摘要信息</p>'
}
// 获取详情
this.getDetail(this.navList[index])
},
getDetail(navItem) {
this.detailLoading = true
const taCode = this.$route.query.taCode || this.navCheckRecord.taCode
const params = {
resultId: navItem.id,
recordId: navItem.recordId,
taCode: taCode
}
queryResultDetail(params)
.then(response => {
this.detailLoading = false
if (response.code !== 200) {
throw new Error(response.message || '请求失败')
}
const data = response.content || response.data
const result = data.ruleTypeList || []
const fileStorageInfoList = data.fileBizTypeDictList || []
this.arrs = []
if (result && result.length > 0) {
result[0].tabName = '风险筛查结果'
for (let i = 0; i < result.length; i++) {
this.arrs.push(result[i])
}
}
if (fileStorageInfoList && fileStorageInfoList.length > 0) {
fileStorageInfoList[0].tabName = '影像件'
for (let i = 0; i < fileStorageInfoList.length; i++) {
this.arrs.push(fileStorageInfoList[i])
}
}
// 默认展开第一个项目
if (this.arrs.length > 0) {
this.$set(this.expandedItems, 0, true)
}
})
.catch(error => {
this.detailLoading = false
this.$message.error('获取详情失败: ' + error.message)
this.arrs = []
})
},
toggleItem(index) {
this.$set(this.expandedItems, index, !this.expandedItems[index])
},
handleChildClick(item) {
if (item.filePath) {
window.open(
this.ipConfig.ip + this.serviceUrl.download.url + '?fileId=' + item.id
)
}
}
},
destroyed() {
localStorage.removeItem('riskResult')
}
}
</script>
<style scoped>
.risk-check-result {
background-color: white;
padding: 20px;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
margin: 0 50px;
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.header {
border-bottom: 1px solid #ebeef5;
padding-bottom: 20px;
margin-bottom: 20px;
.main {
width: 100%;
height: 100%;
padding: 1%;
font-size: 0; /* 消除 inline-block 间隙 */
}
.header h2 {
color: #303133;
margin-bottom: 15px;
font-size: 24px;
.left-nav {
width: 20%;
float: left;
height: 100%;
display: inline-block;
vertical-align: top;
background: #fff;
border-radius: 10px;
font-size: 16px; /* 恢复字体 */
border: 1px solid #ddd;
/* IE8兼容的阴影效果 */
filter: progid:DXImageTransform.Microsoft.Shadow(color='#cccccc', Direction=135, Strength=3);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.check-info {
display: flex;
flex-direction: column;
gap: 8px;
color: #606266;
.nav-header {
font-size: 18px;
font-weight: bold;
text-align: center;
padding: 20px 0;
border-bottom: 1px solid #eee;
background: #f8f9fa;
color: #2c3e50;
border-radius: 10px 10px 0 0;
}
.link {
display: block;
margin: 15px auto;
text-align: center;
background: #fff;
text-decoration: none;
color: #000;
font-size: 14px;
border-radius: 4px;
padding: 12px 10px;
width: 85%;
transition: all 0.3s ease;
/* IE8兼容样式 */
border: 1px solid transparent;
}
.el-card {
.link:hover {
background: #f5f9ff;
border-color: #3498db;
color: #000;
}
.link.active {
background: #f0f4fa;
color: #3498db;
}
.right-container {
width: 79%;
height: 100%;
display: inline-block;
float: right;
background: #fff;
border-radius: 10px;
font-size: 16px;
overflow-y: auto;
overflow-x: hidden;
border: 1px solid #ddd;
/* IE8兼容的阴影效果 */
filter: progid:DXImageTransform.Microsoft.Shadow(color='#cccccc', Direction=135, Strength=3);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.top-container,
#detail-container {
width: 100%;
background: #fff;
margin-bottom: 10px;
border: 1px solid #eee;
}
.top-container {
border-bottom: 1px solid #eee;
padding: 20px;
background: #fafbfc;
}
#detail-container {
padding: 20px;
}
#custom {
display: inline-block;
font-size: 22px;
font-weight: bold;
margin-right: 15px;
color: #2c3e50;
}
#time {
font-size: 14px;
margin-top: 8px;
color: #7f8c8d;
}
.custom-container {
display: block;
margin: 10px 0 20px 0;
}
#docs {
padding: 15px 20px;
font-size: 14px;
line-height: 1.6;
background: #2c3e50;
color: #ecf0f1;
border-radius: 4px;
margin: 15px 0;
}
#insured {
padding: 10px 0;
font-weight: bold;
color: #2c3e50;
border-bottom: 1px solid #eee;
}
.tree-item-header {
padding: 15px 20px;
background: #f0f4fa;
margin: 15px 0;
cursor: pointer;
border-radius: 4px;
border: 1px solid #d6dde6;
font-weight: bold;
color: #2c3e50;
transition: background 0.3s;
/* IE8兼容样式 */
background: #e3e9f2;
}
.tree-item-header:hover {
background: #e3e9f2;
}
.tree-item-header::before {
content: '';
margin-right: 10px;
transition: transform 0.3s;
/* IE8不支持::before伪元素和transform */
}
.tree-item-header.expanded::before {
content: '';
/* IE8不支持 */
}
.result-container-item {
padding: 0 10px;
margin-bottom: 20px;
}
.result-container-item-child-ul {
list-style: none;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
list-style: none;
}
li {
padding: 10px 0;
border-bottom: 1px solid #ebeef5;
font-weight: 500;
list-style: none;
}
.index {
margin: 0 10px;
display: inline-block;
width: 25px;
height: 25px;
line-height: 25px;
text-align: center;
border-radius: 50%;
color: #fff;
//background-image: url('~@/assets/images/round.png');
background-repeat: no-repeat;
background-size: cover;
}
.result-container-item-child-ul li {
font-size: 14px;
line-height: 1.8;
padding: 10px 15px;
margin: 8px 0;
background: #fff;
border: 1px solid #eee;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
/* IE8兼容样式 */
border: 1px solid #ddd;
}
.result-container-item-child-ul li:hover {
background: #f8f9ff;
border-color: #3498db;
}
/* 添加降级样式 */
.no-js-warning {
color: #e74c3c;
text-align: center;
padding: 30px;
font-weight: bold;
font-size: 16px;
background: #fadbd8;
border: 1px solid #f5b7b1;
border-radius: 4px;
margin: 20px;
}
/* 为不支持flex的浏览器提供备选方案 */
.custom-container > * {
display: inline-block;
vertical-align: top;
}
/* 添加加载状态提示 */
.loading {
text-align: center;
padding: 30px;
color: #7f8c8d;
}
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
/* IE8不支持动画 */
border: 3px solid #3498db;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.section-title {
font-size: 18px;
font-weight: bold;
margin: 25px 0 15px 0;
padding-bottom: 10px;
border-bottom: 2px solid #3498db;
color: #2c3e50;
}
.empty-message {
text-align: center;
padding: 40px 20px;
color: #95a5a6;
}
.png-icon {
vertical-align: middle;
margin: -2px 10px 0 10px;
outline: none;
border: none;
display: inline-block;
}
</style>

View File

@@ -31,144 +31,11 @@
</el-col>
</el-row>
</el-card>
<!-- <approval-form :formData="formData"></approval-form>-->
<!-- &lt;!&ndash; 基本信息 &ndash;&gt;-->
<!-- <base-form :formData="formData"></base-form>-->
<!-- 基本信息 -->
<!-- 基本信息 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>基本信息</span>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-form
ref="form"
:model="formData.data.baseInfo"
label-width="120px"
>
<el-form-item label="客户名称">
<el-input
v-model="formData.data.baseInfo.customerName"
placeholder="请输入客户名称"
></el-input>
</el-form-item>
<el-form-item label="起保日期">
<el-date-picker
v-model="formData.data.baseInfo.insureStartDate"
type="date"
placeholder="选择起保日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="归属机构">
<el-input
type="text"
placeholder="输入归属机构"
v-model="formData.data.baseInfo.orgName"
></el-input>
</el-form-item>
<el-form-item label="是否续保">
<el-radio-group v-model="formData.data.baseInfo.isRenew">
<el-radio label="是"></el-radio>
<el-radio label="否"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="业务来源">
<el-input
type="text"
placeholder="输入业务来源"
v-model="formData.data.baseInfo.bizSource"
></el-input>
</el-form-item>
<el-form-item label="签报有效起期">
<el-date-picker
v-model="formData.data.baseInfo.signStartDate"
type="date"
placeholder="选择签报有效起期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="业务详细说明">
<el-input
type="textarea"
:rows="3"
placeholder="说明业务来源、背景及分公司初步风险判断"
v-model="formData.data.baseInfo.bizDescription"
></el-input>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12">
<el-form
ref="form"
:model="formData.data.baseInfo"
label-width="120px"
>
<el-form-item label="终保日期">
<el-date-picker
v-model="formData.data.baseInfo.insureEndDate"
type="date"
placeholder="选择终保日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="共保标志">
<el-select
v-model="formData.data.baseInfo.isCoUnderwriting"
placeholder="请选择共保标志"
>
<el-option label="独家承保" value="独家承保"></el-option>
<el-option label="共保" value="共保"></el-option>
</el-select>
</el-form-item>
<el-form-item label="业务细分">
<el-input
type="text"
placeholder="输入业务细分"
v-model="formData.data.baseInfo.bizDetailSource"
></el-input>
</el-form-item>
<el-form-item label="签报有效止期">
<el-date-picker
v-model="formData.data.baseInfo.signEndDate"
type="date"
placeholder="选择签报有效止期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<!-- 补充的字段 -->
<el-form-item label="主险代码">
<el-input
v-model="formData.data.baseInfo.mainRiskCode"
placeholder="请输入主险代码"
></el-input>
</el-form-item>
<el-form-item label="总保额">
<el-input
v-model="formData.data.baseInfo.totalAmt"
placeholder="请输入总保额"
></el-input>
</el-form-item>
<el-form-item label="总保费">
<el-input
v-model="formData.data.baseInfo.totalPrem"
placeholder="请输入总保费"
></el-input>
</el-form-item>
<el-form-item label="币种">
<el-input
v-model="formData.data.baseInfo.currency"
placeholder="如CNY"
></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
</el-card>
<base-form :formData="formData"></base-form>
<!-- 标的基本信息 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
@@ -999,17 +866,52 @@
<!-- <h4>当前表单数据JSON 预览</h4>-->
<!-- <pre>{{ JSON.stringify(formData, null, 4) }}</pre>-->
<!-- </div>-->
<el-drawer
title="我是标题"
:visible.sync="drawer"
:before-close="handleClose"
>
<div class="iframe-container">
<!-- 使用iframe展示详情内容 -->
<iframe
v-if="drawer"
:src="detailUrl"
frameborder="0"
width="100%"
height="800px"
>
</iframe>
<!-- 加载提示 -->
<div v-if="loading" class="loading">
<i class="el-icon-loading"></i>
<p>正在加载详情内容...</p>
</div>
<!-- 无数据提示 -->
<div v-if="!detailUrl && !loading" class="no-data">
<p>暂无详情内容</p>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import { taDataSubmit } from '@/api/riskCheck'
import uloadPng from '@/assets/images/konwledge/upload.png'
import ApprovalForm from '@/views/riskCheck/components/taData/ApprovalForm.vue'
import BaseForm from '@/views/riskCheck/components/taData/BaseForm.vue'
export default {
name: 'TaDataSubmit',
components: { BaseForm, ApprovalForm },
data() {
return {
drawer: false,
detailUrl: '',
loading: false,
isDragOver: false,
fileList: [], //列表 文件
uloadPng,
@@ -1097,17 +999,20 @@ export default {
taDataSubmit(formData).then(res => {
if (res.success) {
this.handleReset()
localStorage.setItem(
'riskResult',
JSON.stringify(res.content.content)
)
this.goToRiskResultView()
// localStorage.setItem(
// 'riskResult',
// JSON.stringify(res.content.content)
// )
this.goToRiskResultView(res.content.content.taCode)
}
})
},
handleReset() {
this.formData = ''
},
handleClose(done) {
done()
},
// 新增特别约定
addSpecAgreement() {
this.formData.data.specAgreement.push({
@@ -1251,8 +1156,13 @@ export default {
formatFileSize(size) {
return (size / 1024 / 1024).toFixed(2) + 'MB'
},
goToRiskResultView() {
this.$router.push(`/applicationManagement/riskResult`)
goToRiskResultView(taCode) {
this.drawer = true
this.detailUrl = `${
window.location.origin
}/bpic_eli/risk_history.html?taCode=${taCode}&ip=${
process.env.VUE_APP_ADMIN
}&noPT=true&noNav=true`
}
},
computed: {
@@ -1311,13 +1221,10 @@ export default {
<style scoped>
.ta-data-form {
max-width: 1200px;
margin: 20px auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.box-card {
margin-bottom: 20px;
margin: 20px 0;
}
.form-actions {
text-align: center;