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/caseManagement/index.vue

356 lines
12 KiB
Vue

<!--
* @description: 案件管理
* @fileName: Index
* @author: 17076
* @date: 2024/6/6-下午4:04
* @version: V1.0.0
-->
<template>
<div class="content">
<cs-search title="案件检索" :data="searchData" :span="8" @onSearch="onSearch" @getData="onSearch" />
<div class="case-content">
<div class="flex-row header">
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="handleAdd"></el-button>
<div>
<el-button icon="el-icon-upload2" title="导入案件" circle @click="handleImport" />
<el-button icon="el-icon-download" title="模板下载" circle @click="handleDownload" />
</div>
<input ref="file" type="file" style="display: none" @change="uploadFile">
</div>
<el-row :gutter="20" type="flex" class="list-content">
<vuedraggable v-model="caseList" animation="400" handle=".mover" style="width: 100%">
<transition-group class="list-span">
<el-col v-for="item in caseList" :key="item.id" :span="6">
<div class="list-item" @click="handleClick(item)">
<div class="flex-row item-header">
<div class="flex-row" style="align-items: center;flex: 1">
<el-tag
v-if="item.caseStatus"
:type="item.caseStatus === '1' ? 'success' : 'warning'"
style="margin-right: 5px"
>
{{ item.identifyResultName }}
</el-tag>
<span class="main-title">{{ item.caseName }}</span>
</div>
<div>
<img src="~@/assets/caseManagement/duihua@2x.png" class="tag-icon" @click.stop="handleContact(item)">
<img src="~@/assets/caseManagement/tuola@2x.png" class="tag-icon mover">
</div>
</div>
<div class="item-body">
<el-row :gutter="10" style="padding: 10px;">
<el-col :span="8">
<span class="item-body-top etc">{{ `行为人:${item['lawActorName'] ? item['lawActorName'] : '-'}` }}</span>
</el-col>
<el-col :span="8">
<span class="item-body-top etc">{{ `案件编号:${item.caseNo}` }}</span>
</el-col>
<!-- <el-col :span="8">-->
<!-- <span class="item-body-top etc">{{ `证据数量:${item.evidenceNum}` }}</span>-->
<!-- </el-col>-->
<el-col :span="24" style="margin-top: 10px">
<span class="item-body-top etc">{{ `当事人:${item.lawParty}` }}</span>
</el-col>
</el-row>
<div class="item-body-bottom">
<div class="flex-row" style="align-items: center; justify-content: space-between;padding: 10px;min-height: 40px">
<div class="flex-column">
<div class="flex-row" style="align-items: center;margin-bottom: 5px">
<i v-if="item.isAnalysing" class="el-icon-loading" style="margin-right: 5px" />
<span class="status-title">{{ formatterStatusName(item) }}</span>
</div>
<span class="subtitle">{{ item.updateTime }}</span>
</div>
<div v-show="item['totalScore']" class="flex-column" style="align-items: center">
<span :class="['score', item.totalScore >= 70 ? 'success' : 'warning']">{{ item.totalScore }}</span>
<span class="subtitle">综合得分</span>
</div>
</div>
<div class="flex-row bottom-buttons">
<div @click.stop="handleDel(item)">删除</div>
<div @click.stop="handleEdit(item)">编辑</div>
<div :class="[item['isAnalysing'] ? 'disabled' : '']" @click.stop="handleAnalysis(item)">模型分析</div>
</div>
</div>
</div>
</div>
</el-col>
</transition-group>
</vuedraggable>
</el-row>
<div style="text-align: center">
<cs-page
:page.sync="queryForm.page"
:limit.sync="queryForm.size"
:total="queryForm.total"
@pagination="fetchData"
/>
</div>
</div>
<!--编辑/新增弹窗-->
<edit-case-info ref="edit" @reloadData="fetchData" />
<!--对话弹窗-->
<conversation-dialog ref="conversation" />
<!--模型分析弹窗-->
<model-analysis ref="analysis" @confirm="handleConfirmAnalysis" />
</div>
</template>
<script>
import mixin from '@/views/mixin'
import * as vuedraggable from 'vuedraggable'
import EditCaseInfo from '@/views/caseManagement/components/EditCaseInfo.vue'
import ModelAnalysis from '@/views/caseManagement/components/ModelAnalysis.vue'
import { queryCaseList, delCaseInfo, uploadCase, executeModelAnalyse } from '@/api/caseManagement'
export default {
name: 'Index',
components: { ModelAnalysis, EditCaseInfo, vuedraggable },
mixins: [mixin],
data() {
return {
searchData: [
{ label: '案件编号', model: 'caseNo', type: 'input' },
{ label: '案件名称', model: 'caseName', type: 'input' },
{ label: '认定结果', model: 'identifyResult', type: 'select', option: JSON.parse(sessionStorage.getItem('identify_result')) },
{ label: '行为人', model: 'lawActorName', type: 'input' },
{ label: '当事人', model: 'lawParty', type: 'input' },
{ label: '最新时间', model: 'updateTime', type: 'datetimerange' }
],
// 案件数据
caseList: []
}
},
mounted() {
// this.fetchData()
},
methods: {
// 获取数据
fetchData() {
// 处理时间范围选择器
const params = JSON.parse(JSON.stringify(this.searchFormData))
if (params['updateTime']) {
this.$set(params, 'updateTimeStart', this.searchFormData['updateTime'][0])
this.$set(params, 'updateTimeEnd', this.searchFormData['updateTime'][1])
}
delete params['updateTime']
queryCaseList(params, this.queryForm.page, this.queryForm.size).then(res => {
this.caseList = res.data.records
this.caseList.forEach(e => {
const list = []
for (const item of e.lawPartyList) {
list.push(item.name)
}
e.lawParty = list.join(',')
})
this.queryForm.total = res.data.total
})
},
// 案件点击
handleClick(item) {
this.$router.push({ path: `/case-details/${item.id}/${item.caseName}`, query: { isEdit: 0 }})
},
// 新增
handleAdd() {
this.$refs.edit.show()
},
// 案件导入
handleImport() {
this.$refs['file'].value = null
this.$refs['file'].click()
},
uploadFile(e) {
const files = e.target.files
const rawFile = files[0]
if (!rawFile) return
const formData = new FormData()
formData.append('file', rawFile)
const loading = this.$baseLoading(0, '案件信息上传中,请勿刷新界面..')
uploadCase(formData).then(res => {
loading.close()
const { code, msg } = res
code === 200 ? this.$baseMessage.success(msg || '上传成功') : this.$baseMessage.error(msg || '上传失败')
this.fetchData()
}).catch(() => {
loading.close()
})
},
// 模板下载
handleDownload() {
const fileName = '案件导入模板.xlsx'
const fileUrl = './static/caseImport.xlsx' // 文件的URL地址
const link = document.createElement('a')
link.href = fileUrl
link.setAttribute('download', fileName)
link.click()
},
// 删除
handleDel(item) {
this.$baseConfirm('确定要删除吗?', null, async() => {
const { code, msg } = await delCaseInfo(item['id'])
code === 200 ? this.$baseMessage.success(msg, '删除成功!') : this.$baseMessage.error(msg, '删除失败!')
this.fetchData()
})
},
// 编辑
handleEdit(item) {
this.$router.push({ path: `/case-details/${item.id}/${item.caseName}`, query: { isEdit: 1 }})
},
// 模型分析
handleAnalysis(item) {
this.$refs.analysis.show(item)
},
// 执行模型分析
handleConfirmAnalysis(item) {
this.$set(item, 'isAnalysing', true)
const params = {
caseId: item.id,
lawActorName: item.lawActorName,
lawParty: item.lawParty
}
executeModelAnalyse(params).then(res => {
this.$set(item, 'isAnalysing', false)
this.fetchData()
})
},
// 对话
handleContact() {
this.$refs.conversation.show()
},
// 格式化状态名称
formatterStatusName(item) {
const score = item['totalScore']
let statusName = ''
if (score) {
statusName = '已处理'
} else {
if (item['isAnalysing']) {
statusName = '正在分析'
} else {
statusName = '待处理'
}
}
return statusName
},
// 筛选
onSearch(data, callback) {
this.searchFormData = Object.assign({}, data)
this.queryForm.page = 1
this.fetchData()
if (callback) callback(true)
}
}
}
</script>
<style scoped lang="scss">
.content {
height: 100%;
.case-content {
border-radius: 8px;
background: white;
padding: 20px;
box-sizing: border-box;
margin-top: 10px;
height: calc(100% - 170px);
.header {
align-items: center;
justify-content: space-between;
}
.list-content {
margin-top: 10px;
overflow-y: auto;
height: calc(100% - 32px - 32px - 20px);
flex-wrap: wrap;
.list-span {
display: flex;
flex-wrap: wrap;
}
.list-item {
background: #F2F5F9;
border: 1px solid #CADFFF;
border-radius: 8px;
margin-bottom: 20px;
cursor: pointer;
.item-header {
align-items: center;
justify-content: space-between;
padding: 10px;
font-size: 13px;
border-bottom: 1px solid #CADFFF;
.main-title {
color: $base-color-default;
font-weight: 500;
}
.tag-icon {
width: 15px;
height: 15px;
cursor: pointer;
&:nth-child(2) {
margin-left: 10px;
cursor: move;
}
}
}
.item-body {
.item-body-top {
display: inline-block;
font-size: 12px;
color: #999999;
width: 100%;
}
.item-body-bottom {
background: #ffffff;
border-top: 3px solid $base-color-default;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
margin: 0 10px;
.score {
font-weight: 500;
font-size: 22px;
}
.success {
color: #00975E;
}
.warning {
color: #FF9311;
}
.bottom-buttons {
min-height: 45px;
line-height: 45px;
align-items: center;
color: $base-color-default;
font-size: 14px;
font-weight: 500;
>div {
flex: 1;
text-align: center;
cursor: pointer;
border-top: 1px solid #EAEAEA;
border-right: 1px solid #EAEAEA;
}
>div:nth-child(3) {
border-right: none;
}
.disabled {
color: #999999;
}
}
.status-title {
color: #333333;
font-weight: 500;
}
}
}
}
}
.subtitle {
font-size: 12px;
color: #999999;
}
}
}
</style>