You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fu-hsi-web/src/views/caseDetails/index.vue

661 lines
21 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
* @description: 案件详情
* @fileName: index
* @author: 17076
* @date: 2024/6/19-下午2:54
* @version: V1.0.0
-->
<template>
<div class="details-content">
<div class="details-header">
<div v-if="expand" class="flex-row expand-info">
<div class="left-score">
<vue-chart autoresize :option="scoreOption" :style="{ width: '100%', height: '260px' }" />
<div
v-if="caseData['totalScore'] != null"
class="flex-column circle-info"
:style="circleStyle"
>
<span>综合得分</span>
<span :style="commonStyle">{{ caseData['totalScore'] }}</span>
<span :style="commonStyle">{{ caseData['identifyResultName'] }}</span>
<!-- <span>最新时间:<span>{{ caseData['caseAnalysisSuccessTime']||'' }}</span></span> -->
<span v-if="caseData['caseAnalysisSuccessTime']">{{ `最新时间:${caseData['caseAnalysisSuccessTime']}` }}</span>
</div>
<div
v-else
class="flex-column circle-info empty-score"
>
<span>待分析</span>
<span>暂无结果</span>
</div>
<div v-if="isEdit" class="model" @click="handleAnalysis">模型分析</div>
</div>
<div class="base-info">
<div class="flex-row" style="align-items: center; justify-content: space-between">
<h4>基本信息</h4>
<div style="display: flex;">
<!-- <el-button type="info" plain icon="el-icon-download" @click="handleDownload">下载</el-button> -->
<div v-if="isEdit" class="btn-icon" @click="handleEdit">
<img src="@/assets/caseManagement/edit.png" alt="">
<span>编辑</span>
</div>
<!-- <el-button v-if="isEdit" type="primary" plain icon="el-icon-edit" @click="handleEdit">编辑</el-button> -->
<div v-if="caseData['totalScore'] != null" class="btn-icon" @click="openDeatil">
<img src="@/assets/caseManagement/analysis.png" alt="">
<span>案件分析结果</span>
</div>
<!-- <el-button v-if="caseData['totalScore'] != null" type="primary" plain ></el-button> -->
<el-button type="text" icon="el-icon-arrow-up" style="color: #666666" @click="expand = false">收起</el-button>
</div>
</div>
<el-descriptions :column="4">
<el-descriptions-item label="案件编号">{{ caseData['caseNo'] }}</el-descriptions-item>
<el-descriptions-item label="案件名称">{{ caseData['caseName'] }}</el-descriptions-item>
<el-descriptions-item label="案件类型" span="2">{{ caseData.caseTypeName }}</el-descriptions-item>
<el-descriptions-item label="案件状态">{{ caseData.caseStatusName }}</el-descriptions-item>
<el-descriptions-item label="到案方式">{{ caseData.crimeModeName }}</el-descriptions-item>
<!-- <el-descriptions-item label="立案时间">{{ caseData.registerTime || '暂未添加,上传笔录后自动生成' }}</el-descriptions-item>
<el-descriptions-item label="受理时间">{{ caseData.acceptTime || '暂未添加,上传笔录后自动生成' }}</el-descriptions-item> -->
<el-descriptions-item label="行为人">{{ caseData.caseActorName || '暂未添加,上传笔录后自动生成' }}</el-descriptions-item>
<el-descriptions-item label="当事人">
<div slot="default" :title="caseData.lawParty || '暂未添加,上传笔录后自动生成'" class="case-lawParty">
{{ caseData.lawParty || '暂未添加,上传笔录后自动生成' }}
</div>
</el-descriptions-item>
<el-descriptions-item label="案件概述" span="24">
<div slot="default" class="case-summarize">
{{ caseData.caseDetail }}
</div>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
<div v-else class="flex-row pick-up-info">
<div class="flex-row left-title" style="align-items: center">
<span>综合得分</span>
<span :style="commonStyle" style="font-size: 30px;">{{ caseData.totalScore }}</span>
<div v-if="isEdit" class="model" @click="handleAnalysis">模型分析</div>
</div>
<div class="base-info flex-row" style="align-items: center; justify-content: space-between">
<div class="flex-row">
<span>案件编号:</span>
<span>{{ caseData.caseNo }}</span>
<span style="margin-left: 30px">案件名称:</span>
<span>{{ caseData.caseName }}</span>
<span style="margin-left: 30px">案件状态:</span>
<span>{{ caseData.caseStatusName }}</span>
<div class="btn-list">
<div v-if="isEdit" class="btns" @click="handleEdit">
<img src="@/assets/caseManagement/edit.png" alt="">
<span>编辑</span>
</div>
<!-- <el-button v-if="isEdit" type="primary" plain icon="el-icon-edit" @click="handleEdit">编辑</el-button> -->
<div v-if="caseData['totalScore'] != null" class="btns" @click="openDeatil">
<img src="@/assets/caseManagement/analysis.png" alt="">
<span>案件分析结果</span>
</div>
</div>
</div>
<el-button type="text" icon="el-icon-arrow-down" style="color: #666666" @click="expand = true">展开</el-button>
</div>
</div>
</div>
<div class="flex-row details-info" :style="{ height: expand ? 'calc(100% - 270px)' : 'calc(100% - 80px)' }">
<div class="info-left">
<el-tree
v-if="currentKey"
:data="leftTabs"
node-key="value"
highlight-current
:current-node-key="currentKey"
default-expand-all
@node-click="handleNodeClick"
/>
</div>
<div v-loading="!showFlag" class="info-right">
<h4 style="margin: 0">
<span>{{ selectTitle }}</span>
<span v-if="score!==''">{{ ` ${score}分` }}</span>
</h4>
<component :is="selectCom" v-if="showFlag" :is-edit="isEdit" :is-expand="expand" @reloadData="fetchData" />
</div>
</div>
<!--编辑/新增弹窗-->
<edit-case-info ref="edit" @reloadData="fetchData" />
<!--模型分析-->
<model-analysis ref="analysis" @confirm="handleConfirmAnalysis" />
<!--案件分析详情-->
<case-analysis ref="caseAnalysis" />
</div>
</template>
<script>
import VueChart from '@/plugins/echarts'
import scoreConfig from './js/scoreConfig'
import EditCaseInfo from '@/views/caseManagement/components/EditCaseInfo.vue'
import CaseRecord from './components/CaseRecord.vue'
import CaseEvidence from './components/CaseEvidence.vue'
import CommonIndex from './components/CommonIndex.vue'
import InnocentIndex from './components/InnocentIndex.vue'
import IncriminateIndex from './components/IncriminateIndex.vue'
import CaseAtlas from './components/CaseAtlas.vue'
import ModelAnalysis from '@/views/caseManagement/components/ModelAnalysis.vue'
import CaseAnalysis from './components/CaseAnalysis.vue'
import ManuallyDefined from './components/ManuallyDefined.vue'
import { executeModelAnalyse, queryCaseList, getCaseScore } from '@/api/caseManagement'
import merge from 'webpack-merge'
export default {
name: 'Index',
components: {
ModelAnalysis,
EditCaseInfo,
VueChart,
CaseRecord,
CaseEvidence,
CommonIndex,
InnocentIndex,
IncriminateIndex,
CaseAtlas,
CaseAnalysis,
ManuallyDefined
},
data() {
return {
// 是否展开
expand: true,
caseData: {},
// 得分配置
scoreOption: scoreConfig,
// 得分/结果样式
commonStyle: {
color: '#FFBB69'
},
// 圆圈样式
circleStyle: {
alignItems: 'center',
boxShadow: '0px 1px 30px 0px rgba(255,169,66,0.2)'
},
showFlag: true,
score: '',
// 左侧分类树
leftTabs: [
{ label: '案件证据', value: '1', children: [
{ label: '笔录', value: '1-1', component: 'CaseRecord' },
{ label: '证据', value: '1-2', component: 'CaseEvidence' }
] },
{ label: '指标判断', value: '4', children: [
{ label: '人工定义', value: '4-1', component: 'ManuallyDefined' }
] },
{ label: '指标结果', value: '2', children: [
{ label: '共性指标', value: '2-1', component: 'CommonIndex' },
{ label: '入罪指标', value: '2-2', component: 'IncriminateIndex' },
{ label: '出罪指标', value: '2-3', component: 'InnocentIndex' }
] },
{ label: '知识图谱', value: '3', children: [
{ label: '案件图谱', value: '3-1', component: 'CaseAtlas' }
] }
],
currentKey: '',
// 当前选中的标题
selectTitle: '案件证据-笔录',
// 当前选中的组件
selectCom: 'CaseRecord',
// 得分详情
scoreInfo: {},
// 是否编辑
isEdit: false,
timer: undefined
}
},
mounted() {
// 是否是编辑
this.isEdit = this.$route.query.isEdit === '1'
this.fetchData()
this.queryCaseScore()
},
methods: {
// 获取当前选中的node
getSelectNode(val) {
for (const item of this.leftTabs) {
for (const items of item.children) {
if (items.value === val) {
return {
component: items.component,
selectTitle: `${item['label']}-${items['label']}`,
label: `${items['label']}`
}
}
}
}
},
// 获取案件得分详情
queryCaseScore() {
getCaseScore({ caseId: this.$route.params['id'] }).then(res => {
if (res.code === 200) {
this.scoreInfo = res.data
if (this.$route.query.currentKey) {
this.currentKey = this.$route.query.currentKey
const node = this.getSelectNode(this.$route.query.currentKey)
this.selectTitle = node.selectTitle
if (node.label === '共性指标') {
this.score = this.scoreInfo.commonScore
} else if (node.label === '入罪指标') {
this.score = this.scoreInfo.crimeScore
} else if (node.label === '出罪指标') {
this.score = this.scoreInfo.crimeOutScore
} else {
this.score = ''
}
this.selectCom = node.component
} else {
this.currentKey = '1-1'
}
}
})
},
// 动态更新指针值,触发动画
updateGauge(value) {
this.scoreOption.series[0].data = [{ value }]
this.caseData.totalScore = this.getRandomNumber(20, 80)
},
getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
},
// 获取案件数据
fetchData() {
queryCaseList({ id: this.$route.params['id'] }, 1, 1).then(res => {
if (res.code === 200) {
this.caseData = res.data.records[0]
if (this.caseData.lawPartyList) {
const list = []
this.caseData.lawPartyList.forEach(e => {
list.push(e.name)
})
this.caseData.lawParty = list.join(',')
}
// 设置分数
this.scoreOption.series[0].data = [{ value: this.caseData.totalScore }]
clearInterval(this.timer)
this.timer = undefined
// 判断分数设置不通颜色
if (this.caseData.identifyResult === '3') {
this.scoreOption.series[0].progress.itemStyle.color.colorStops = [{
offset: 0, color: '#00975E'
}, {
offset: 1, color: '#3EE5A6'
}]
this.scoreOption.series[0].pointer.itemStyle.color = '#3EE5A6'
this.commonStyle.color = '#00975E'
this.circleStyle.boxShadow = '0px 1px 30px 0px rgba(0,151,94,0.2)'
} else if (this.caseData.identifyResult === '2') {
this.scoreOption.series[0].progress.itemStyle.color.colorStops = [{
offset: 0, color: '#F68600'
}, {
offset: 1, color: '#FFA942'
}]
this.scoreOption.series[0].pointer.itemStyle.color = '#FFA942'
this.commonStyle.color = '#FFBB69'
this.circleStyle.boxShadow = '0px 1px 30px 0px rgba(255,169,66,0.2)'
} else {
this.scoreOption.series[0].progress.itemStyle.color.colorStops = [{
offset: 0, color: '#FF3429'
}, {
offset: 1, color: '#FF3429'
}]
this.scoreOption.series[0].pointer.itemStyle.color = '#FF3429'
this.commonStyle.color = '#FF3429'
this.circleStyle.boxShadow = '0px 1px 30px 0px rgba(255,169,66,0.2)'
}
}
})
},
// 下载
handleDownload() {
},
openDeatil() {
this.$refs.caseAnalysis.show()
},
// 编辑
handleEdit() {
this.$refs.edit.show(this.caseData, true)
},
// 模型分析
handleAnalysis() {
this.showFlag = false
this.handleConfirmAnalysis()
let value = 80
if (this.timer) return
this.timer = setInterval(() => {
this.updateGauge(value)
value = value === 20 ? 80 : 20
}, 500)
setTimeout(() => {
this.showFlag = true
this.fetchData()
}, 5000)
// this.$refs.analysis.show(this.caseData)
},
handleConfirmAnalysis(data) {
this.$set(this.caseData, 'isAnalysing', true)
const params = {
caseId: this.$route.params['id'],
lawActorName: this.caseData.lawActorName,
lawParty: this.caseData.lawParty
}
executeModelAnalyse(params).then(res => {
const { code, msg } = res
this.$set(this.caseData, 'isAnalysing', false)
if (code === 200) {
this.$baseMessage.success(msg || '模型分析成功!')
}
this.fetchData()
}).catch(() => {
clearInterval(this.timer)
this.timer = undefined
this.showFlag = true
})
},
// 节点点击回调
handleNodeClick(node, data) {
const currentQuery = this.$route.query
currentQuery.currentKey = node.value
// this.$set(this.$route.query, 'currentKey', node.value)
this.$router.push({
query: merge(this.$route.query, currentQuery)
})
// this.$route.query.currentKey = node.value
// console.log(data, 666)
if (data.level === 1) return
this.selectTitle = `${data.parent.data['label']}-${data.data['label']}`
if (data.data['label'] === '共性指标') {
this.score = this.scoreInfo.commonScore
} else if (data.data['label'] === '入罪指标') {
this.score = this.scoreInfo.crimeScore
} else if (data.data['label'] === '出罪指标') {
this.score = this.scoreInfo.crimeOutScore
} else {
this.score = ''
}
this.selectCom = node.component
}
}
}
</script>
<style scoped lang="scss">
.details-content {
height: 100%;
color: #333333;
box-sizing: border-box;
.btn-icon {
padding: 8px 20px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
display: flex;
font-size: 16px;
color: #3763FF;
justify-content: center;
align-items: center;
margin-right: 24px;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
}
.info-left {
::v-deep {
.el-descriptions__body {
background: none;
}
.el-tree-node__content {
background: linear-gradient( 90deg, rgba(69, 105, 255, .1) 0%, #FFFFFF 100%);
border-radius: 5px;
height: 35px;
line-height: 35px;
margin-bottom: 10px;
.el-tree-node__expand-icon {
padding: 6px;
}
}
.el-tree-node__children{
margin-left: 10px;
border-left: 1px solid rgba(51, 51, 51, 0.20);
}
.el-tree-node__children .el-tree-node__content {
background: #FFFFFF;
padding-left: 0 !important;
margin-left: 8px;
}
.el-tree-node__children .el-tree-node__content .el-tree-node__expand-icon {
padding: 0;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background: #3763FF;
color: white;
}
.el-descriptions-item__label {
font-weight: 400;
font-size: 16px;
color: #666666;
}
.el-descriptions-item__content {
font-weight: 400;
font-size: 16px;
color: #333333;
}
.el-descriptions--small:not(.is-bordered) .el-descriptions-item__cell {
padding-bottom: 16px !important;
}
}
}
.details-header {
padding: 10px;
box-sizing: border-box;
border-radius: 8px;
background: #FFFFFF;
.expand-info {
height: 260px;
align-items: center;
.left-score {
position: relative;
width: 340px;
.model {
width: 200px;
height: 52px;
background: #3763FF;
border-radius: 26px 26px 26px 26px;
text-align: center;
font-size: 18px !important;
color: #FFFFFF;
line-height: 52px;
cursor: pointer;
position: absolute;
top: 180px;
left: 70px;
}
.circle-info {
position: absolute;
width: 220px;
height: 220px;
top: 30px;
left: 60px;
box-shadow: 0 1px 30px 0 rgba(255,169,66,0.2);
border-radius: 50%;
font-size: 12px;
color: #999999;
span {
margin-top: 10px;
}
span:nth-child(2) {
font-size: 35px;
font-weight: 700;
}
span:nth-child(3) {
font-size: 13px;
font-weight: bold;
}
span:nth-last-child(1) {
font-size: 12px;
}
}
.empty-score {
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 16px;
// position: relative;
span:nth-child(1) {
margin-top: 0;
}
span:nth-last-child(1) {
font-size: 17px;
}
}
}
}
.pick-up-info {
height: 50px;
color: #333333;
line-height: 50px;
.model {
width: 112px;
height: 42px;
background: #3763FF;
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 42px;font-size: 16px;
color: #FFFFFF;
margin: 0 24px;
cursor: pointer;
}
.left-title {
font-weight: 500;
margin-right: 10px;
span:nth-last-child(1) {
font-weight: 700;
font-size: 20px;
color: #FF9311;
}
}
}
.base-info {
flex: 1;
background: #F5F9FF;
padding: 10px;
box-sizing: border-box;
border-radius: 8px;
position: relative;
// height: 240px;
h4 {
font-weight: bold;
font-size: 18px;
color: #333333;
}
.btn-list {
display: flex;
position: absolute;
right: 48px;
top: 4px;
}
.btns {
padding: 0 20px;
// height: 42px;
// line-height: 42px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
display: flex;
font-size: 16px;
color: #3763FF;
justify-content: center;
align-items: center;
margin-right: 24px;
height: 38px;
line-height: 38px;
cursor: pointer;
span {
line-height: unset !important;
}
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
}
}
.case-summarize {
max-height: 55px;
overflow-y: auto;
overflow-x: hidden;
text-wrap: wrap;
}
.case-lawParty {
width: 250px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.details-info {
margin-top: 10px;
box-sizing: border-box;
>div {
height: 100%;
background: #FFFFFF;
padding: 20px;
box-sizing: border-box;
border-radius: 8px;
}
.info-left {
min-width: 245px;
// overflow-y: auto;
// overflow-x: hidden;
}
.info-right {
flex: 1;
margin-left: 10px;
>div {
margin-top: 10px;
height: calc(100% - 10px - 20px);
}
}
}
}
::v-deep {
.el-descriptions__body {
background: none;
}
.el-descriptions-item__label {
font-weight: 400;
font-size: 16px;
color: #666666;
}
.el-descriptions-item__content {
font-weight: 400;
font-size: 16px;
color: #333333;
}
.el-descriptions--small:not(.is-bordered) .el-descriptions-item__cell {
padding-bottom: 16px !important;
}
}
</style>