Compare commits
11 Commits
86543f644c
...
dc329a652c
| Author | SHA1 | Date |
|---|---|---|
|
|
dc329a652c | 1 day ago |
|
|
6465dd7ce3 | 1 day ago |
|
|
a9e3bb93d3 | 1 day ago |
|
|
488727dc03 | 1 day ago |
|
|
d1a917cd16 | 2 days ago |
|
|
d757ae3041 | 2 days ago |
|
|
f669ec07b6 | 2 days ago |
|
|
b523311246 | 2 days ago |
|
|
f948ece266 | 2 days ago |
|
|
0f1bd6f3a6 | 2 days ago |
|
|
d8edd7c89e | 2 days ago |
19 changed files with 13153 additions and 19 deletions
@ -0,0 +1,21 @@
|
||||
<script setup lang="ts"> |
||||
import { onMounted } from "vue" |
||||
import { useRoute, useRouter } from "vue-router" |
||||
|
||||
const route = useRoute() |
||||
const router = useRouter() |
||||
|
||||
onMounted(() => { |
||||
const url = route.meta.url as string | undefined |
||||
const newPage = !!route.meta.openNewPage |
||||
|
||||
if (url) window.open(url, newPage ? "_blank" : "_self") |
||||
|
||||
// 新开页:当前页别停在空白占位页,回首页/上一页 |
||||
if (newPage) router.replace("/") |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<div style="padding:16px;">正在打开外部页面...</div> |
||||
</template> |
||||
@ -0,0 +1,458 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="114"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="问题来源"> |
||||
<el-select |
||||
v-model="query.sourceTableSubOneList" |
||||
clearable |
||||
filterable |
||||
multiple |
||||
collapse-tags |
||||
placeholder="请选择来源" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in dict.ts12389SourceTableSubOneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
:label="item.label" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input |
||||
placeholder="请输入编号" |
||||
v-model="query.originId" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="登记/受理时间"> |
||||
<date-time-range-picker-ext |
||||
v-model="query.discoveryTimeList" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件人"> |
||||
<el-input |
||||
placeholder="来件人姓名、身份证号码、联系电话" |
||||
v-model="query.personInfo" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="涉及二级机构" prop="secondDepartName"> |
||||
<depart-tree-select |
||||
v-model="query.secondDepartId" |
||||
:check-strictly="true" |
||||
@node-click="(row) => (query.secondDepartName = row.shortName)" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理方式"> |
||||
<el-select |
||||
v-model="query.handleMethod" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="自办"/> |
||||
<el-option value="1" label="下发"/> |
||||
</el-select> |
||||
|
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理状态"> |
||||
<el-select |
||||
v-model="query.status" |
||||
clearable |
||||
placeholder="办理状态" |
||||
> |
||||
<el-option value="0" label="未办理"/> |
||||
<el-option value="1" label="已办理"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="标签"> |
||||
<el-select |
||||
placeholder="全部" |
||||
clearable |
||||
v-model="query.tags" |
||||
multiple |
||||
collapse-tags |
||||
> |
||||
<el-option |
||||
v-for="item in dict.sfssTags" |
||||
:key="item.id" |
||||
:value="item.dictValue" |
||||
:label="item.dictLabel" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件内容"> |
||||
<el-input |
||||
placeholder="请输入来件内容" |
||||
v-model="query.thingDesc" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="是否重复件"> |
||||
<el-select |
||||
v-model="query.repeatt" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="否"/> |
||||
<el-option value="1" label="是"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="核查结论" > |
||||
<el-select v-model="query.checkStatusList" clearable multiple |
||||
style="width: 280px"> |
||||
<el-option v-for="item in dict.checkStatus" :value="item.dictValue" :label="item.dictLabel"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="初核材料"> |
||||
<el-select |
||||
v-model="query.initialReviewFileList" |
||||
placeholder="全部" |
||||
clearable |
||||
multiple |
||||
> |
||||
<el-option value="0" label="未上传"/> |
||||
<el-option value="1" label="已上传"/> |
||||
<el-option value="2" label="超时上传"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
</el-form> |
||||
<div class="mb-25 flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleExport">数据导出</el-button> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList"> |
||||
<template #icon> |
||||
<icon name="el-icon-Search"/> |
||||
</template> |
||||
查询 |
||||
</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div class="table-container" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column label="信件编号" width="130" prop="originId" show-overflow-tooltip/> |
||||
<el-table-column label="来源" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceTablePath }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="登记/受理时间" |
||||
width="170" |
||||
prop="discoveryTime" |
||||
:formatter="(_, __, v) => v ? timeFormat(v, 'yyyy-mm-dd hh:MM:ss') : '/'" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="来件人姓名" width="100" prop="responderName" |
||||
:formatter="row => row.responderName ? row.responderName : '匿名'"/> |
||||
<el-table-column label="身份证号" width="100" prop="responderIdCode" |
||||
:formatter="row => row.responderIdCode ? row.responderIdCode : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="联系电话" width="100" prop="responderPhone" |
||||
:formatter="row => row.responderPhone ? row.responderPhone : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="被投诉机构" width="130" prop="secondDepartName"/> |
||||
<el-table-column label="来信内容" width="100" prop="thingDesc" show-overflow-tooltip/> |
||||
<el-table-column label="涉嫌问题" width="100" prop="involveProblemStr" show-overflow-tooltip/> |
||||
<el-table-column label="是否重复件" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.yesNo, row.repeatt) }} |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="初核限时" width="150" align="center"> |
||||
<template #default="{ row }"> |
||||
<!-- 有状态:显示状态文案 --> |
||||
<el-tag v-if="row.gwf3>=1" :type="row.gwf3 === '2' ? 'danger' : 'success'"> |
||||
{{ row.gwf3 === '2' ? '超时完成初核' : '按时完成初核' }} |
||||
</el-tag> |
||||
|
||||
<!-- 无状态:显示倒计时 --> |
||||
<countdown v-else :time="Number(row.remainingDuration || 0)"/> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="标签" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.sfssTags, row.tag) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办结情况" width="100" prop="completionStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.completionStatus === '1' ? '程序办结' : |
||||
row.completionStatus === '2' ? '已解决合理诉求' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="群众认可" width="100" prop="publicRecognition"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.publicRecognition === '1' ? '认可' : |
||||
row.publicRecognition === '2' ? '不认可' : |
||||
row.publicRecognition === '3' ? '不接电话' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办理方式" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.handleMethodType, row.handleMethod) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="业务类别" width="100" prop="businessTypeName"/> |
||||
<el-table-column label="核查结论" width="140" prop="checkStatus" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.checkStatus, row.checkStatus) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="状态" prop="status" width="100"> |
||||
<template #default="{ row }"> |
||||
<span :style="row.status === '0' ? 'color: red' : ''"> |
||||
{{ |
||||
row.status === '0' ? '未办理' : |
||||
row.status === '1' ? '已办理' : |
||||
'-' |
||||
}} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="100" fixed="right"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleWatchDetail(row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="flex end mt-8"> |
||||
<el-pagination |
||||
@size-change="getList" |
||||
@current-change="getList" |
||||
:page-sizes="[10, 20, 50]" |
||||
v-model:page-size="query.size" |
||||
v-model:current-page="query.current" |
||||
layout="total, sizes, prev, pager, next" |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 查看详情 --> |
||||
<complaint_detail |
||||
v-model="detailShow" |
||||
:id="activeId" |
||||
:dict="dict"/> |
||||
|
||||
</template> |
||||
|
||||
|
||||
<script setup> |
||||
import { ref, watch, computed, onMounted } from 'vue'; |
||||
import {timeFormat} from "@/utils/util"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import { |
||||
exportData, |
||||
getComplaintCollectionPage |
||||
} from "@/api/data/complaintCollection.ts"; |
||||
import Complaint_detail from "@/components/data/complaint_detail.vue"; |
||||
|
||||
|
||||
const catchStore = useCatchStore(); |
||||
|
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['17'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}); |
||||
|
||||
|
||||
|
||||
const list = ref([]); |
||||
const total = ref(0); |
||||
const loading = ref(false) |
||||
const getList = async () => { |
||||
loading.value = true; |
||||
|
||||
// 确保始终包含默认来源 |
||||
if (!query.value.sourceTableList.includes('17')) { |
||||
query.value.sourceTableList = ['17', ...query.value.sourceTableList]; |
||||
} |
||||
|
||||
const params = { |
||||
...query.value, |
||||
} |
||||
|
||||
let res = await getComplaintCollectionPage(params); |
||||
list.value = res.complaintCollectionPageDTOS; |
||||
total.value = res.total; |
||||
loading.value = false; |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['17'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getList() |
||||
}) |
||||
|
||||
const storeDict = computed(() => |
||||
catchStore.getDicts([ |
||||
"businessType", |
||||
"suspectProblem", |
||||
"policeType", |
||||
"hostLevel", |
||||
"timeLimit", |
||||
"approvalFlow", |
||||
"specialSupervision", |
||||
"checkStatus", |
||||
"sfssSourceTable", |
||||
"sfssTags", |
||||
"accountabilityTarget" |
||||
]) || {} |
||||
); |
||||
|
||||
const ts12389SourceTableSubOneList = computed(() => { |
||||
const list = storeDict.value.sfssSourceTable || [] |
||||
|
||||
// 二级:remark 等于12389投诉的dictValue |
||||
const children = list |
||||
.filter(d => d.remark === '17') |
||||
.sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0)) |
||||
|
||||
return children.map(c => ({ |
||||
label: c.dictLabel, |
||||
value: String(c.dictValue), |
||||
})) |
||||
}) |
||||
|
||||
const localDict = { |
||||
yesNo: [ |
||||
{id: 1, dictLabel: "是", dictValue: "1"}, |
||||
{id: 2, dictLabel: "否", dictValue: "0"}, |
||||
], |
||||
handleMethodType: [ |
||||
{id: 1, dictLabel: "自办", dictValue: "0"}, |
||||
{id: 2, dictLabel: "下发", dictValue: "1"}, |
||||
], |
||||
}; |
||||
|
||||
const dict = computed(() => ({ |
||||
...storeDict.value, |
||||
...localDict, |
||||
ts12389SourceTableSubOneList: ts12389SourceTableSubOneList.value, |
||||
})); |
||||
|
||||
function getDictLabel(list, value) { |
||||
if (!Array.isArray(list)) return '/' |
||||
|
||||
if (value === null || value === undefined || value === '') return '/' |
||||
|
||||
let values = [] |
||||
|
||||
if (Array.isArray(value)) { |
||||
values = value |
||||
} |
||||
else if (typeof value === 'string' && value.includes(',')) { |
||||
values = value.split(',').map(v => v.trim()) |
||||
} |
||||
else { |
||||
values = [value] |
||||
} |
||||
|
||||
const labels = values |
||||
.map(v => { |
||||
const item = list.find(d => d.dictValue == v) |
||||
return item?.dictLabel |
||||
}) |
||||
.filter(Boolean) |
||||
|
||||
return labels.length ? labels.join(',') : '/' |
||||
} |
||||
|
||||
const detailShow = ref(false) |
||||
const activeId = ref("") |
||||
const handleWatchDetail = async (row) => { |
||||
activeId.value = row.id |
||||
detailShow.value = true |
||||
} |
||||
|
||||
const handleExport = async () => { |
||||
let body = { |
||||
...query.value |
||||
} |
||||
await exportData(body); |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-form-item .el-form-item { |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
:deep() { |
||||
.el-form-item--label-right .el-form-item__label { |
||||
text-align: right; |
||||
line-height: 32px; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
padding: 0 24px 16px; |
||||
} |
||||
</style> |
||||
// 这是ai写的页面 |
||||
@ -0,0 +1,459 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="114"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="问题来源"> |
||||
<el-select |
||||
v-model="query.sourceTableSubOneList" |
||||
clearable |
||||
filterable |
||||
multiple |
||||
collapse-tags |
||||
placeholder="请选择来源" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in dict.gabxfSourceTableSubOneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
:label="item.label" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input |
||||
placeholder="请输入编号" |
||||
v-model="query.originId" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="登记/受理时间"> |
||||
<date-time-range-picker-ext |
||||
v-model="query.discoveryTimeList" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件人"> |
||||
<el-input |
||||
placeholder="来件人姓名、身份证号码、联系电话" |
||||
v-model="query.personInfo" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="涉及二级机构" prop="secondDepartName"> |
||||
<depart-tree-select |
||||
v-model="query.secondDepartId" |
||||
:check-strictly="true" |
||||
@node-click="(row) => (query.secondDepartName = row.shortName)" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理方式"> |
||||
<el-select |
||||
v-model="query.handleMethod" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="自办"/> |
||||
<el-option value="1" label="下发"/> |
||||
</el-select> |
||||
|
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理状态"> |
||||
<el-select |
||||
v-model="query.status" |
||||
clearable |
||||
placeholder="办理状态" |
||||
> |
||||
<el-option value="0" label="未办理"/> |
||||
<el-option value="1" label="已办理"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="标签"> |
||||
<el-select |
||||
placeholder="全部" |
||||
clearable |
||||
v-model="query.tags" |
||||
multiple |
||||
collapse-tags |
||||
> |
||||
<el-option |
||||
v-for="item in dict.sfssTags" |
||||
:key="item.id" |
||||
:value="item.dictValue" |
||||
:label="item.dictLabel" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件内容"> |
||||
<el-input |
||||
placeholder="请输入来件内容" |
||||
v-model="query.thingDesc" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="是否重复件"> |
||||
<el-select |
||||
v-model="query.repeatt" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="否"/> |
||||
<el-option value="1" label="是"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="核查结论" > |
||||
<el-select v-model="query.checkStatusList" clearable multiple |
||||
style="width: 280px"> |
||||
<el-option v-for="item in dict.checkStatus" :value="item.dictValue" :label="item.dictLabel"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="初核材料"> |
||||
<el-select |
||||
v-model="query.initialReviewFileList" |
||||
placeholder="全部" |
||||
clearable |
||||
multiple |
||||
> |
||||
<el-option value="0" label="未上传"/> |
||||
<el-option value="1" label="已上传"/> |
||||
<el-option value="2" label="超时上传"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="mb-25 flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleExport">数据导出</el-button> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList"> |
||||
<template #icon> |
||||
<icon name="el-icon-Search"/> |
||||
</template> |
||||
查询 |
||||
</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div class="table-container" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column label="信件编号" width="130" prop="originId" show-overflow-tooltip/> |
||||
<el-table-column label="来源" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceTablePath }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="登记/受理时间" |
||||
width="170" |
||||
prop="discoveryTime" |
||||
:formatter="(_, __, v) => v ? timeFormat(v, 'yyyy-mm-dd hh:MM:ss') : '/'" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="来件人姓名" width="100" prop="responderName" |
||||
:formatter="row => row.responderName ? row.responderName : '匿名'"/> |
||||
<el-table-column label="身份证号" width="100" prop="responderIdCode" |
||||
:formatter="row => row.responderIdCode ? row.responderIdCode : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="联系电话" width="100" prop="responderPhone" |
||||
:formatter="row => row.responderPhone ? row.responderPhone : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="被投诉机构" width="130" prop="secondDepartName"/> |
||||
<el-table-column label="来信内容" width="100" prop="thingDesc" show-overflow-tooltip/> |
||||
<el-table-column label="涉嫌问题" width="100" prop="involveProblemStr" show-overflow-tooltip/> |
||||
<el-table-column label="是否重复件" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.yesNo, row.repeatt) }} |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="初核限时" width="150" align="center"> |
||||
<template #default="{ row }"> |
||||
<!-- 有状态:显示状态文案 --> |
||||
<el-tag v-if="row.gwf3>=1" :type="row.gwf3 === '2' ? 'danger' : 'success'"> |
||||
{{ row.gwf3 === '2' ? '超时完成初核' : '按时完成初核' }} |
||||
</el-tag> |
||||
|
||||
<!-- 无状态:显示倒计时 --> |
||||
<countdown v-else :time="Number(row.remainingDuration || 0)"/> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="标签" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.sfssTags, row.tag) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办结情况" width="100" prop="completionStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.completionStatus === '1' ? '程序办结' : |
||||
row.completionStatus === '2' ? '已解决合理诉求' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="群众认可" width="100" prop="publicRecognition"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.publicRecognition === '1' ? '认可' : |
||||
row.publicRecognition === '2' ? '不认可' : |
||||
row.publicRecognition === '3' ? '不接电话' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办理方式" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.handleMethodType, row.handleMethod) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="业务类别" width="100" prop="businessTypeName"/> |
||||
<el-table-column label="核查结论" width="140" prop="checkStatus" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.checkStatus, row.checkStatus) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="状态" prop="status" width="100"> |
||||
<template #default="{ row }"> |
||||
<span :style="row.status === '0' ? 'color: red' : ''"> |
||||
{{ |
||||
row.status === '0' ? '未办理' : |
||||
row.status === '1' ? '已办理' : |
||||
'-' |
||||
}} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="100" fixed="right"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleWatchDetail(row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="flex end mt-8"> |
||||
<el-pagination |
||||
@size-change="getList" |
||||
@current-change="getList" |
||||
:page-sizes="[10, 20, 50]" |
||||
v-model:page-size="query.size" |
||||
v-model:current-page="query.current" |
||||
layout="total, sizes, prev, pager, next" |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 查看详情 --> |
||||
<complaint_detail |
||||
v-model="detailShow" |
||||
:id="activeId" |
||||
:dict="dict"/> |
||||
|
||||
</template> |
||||
|
||||
|
||||
<script setup> |
||||
import { ref, watch, computed, onMounted } from 'vue'; |
||||
import {timeFormat} from "@/utils/util"; |
||||
import feedback from "@/utils/feedback"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import { |
||||
exportData, |
||||
getComplaintCollectionPage |
||||
} from "@/api/data/complaintCollection.ts"; |
||||
import Complaint_detail from "@/components/data/complaint_detail.vue"; |
||||
|
||||
|
||||
const catchStore = useCatchStore(); |
||||
|
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['22'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}); |
||||
|
||||
|
||||
|
||||
const list = ref([]); |
||||
const total = ref(0); |
||||
const loading = ref(false) |
||||
const getList = async () => { |
||||
loading.value = true; |
||||
|
||||
// 确保始终包含默认来源 |
||||
if (!query.value.sourceTableList.includes('22')) { |
||||
query.value.sourceTableList = ['22', ...query.value.sourceTableList]; |
||||
} |
||||
|
||||
const params = { |
||||
...query.value, |
||||
} |
||||
|
||||
let res = await getComplaintCollectionPage(params); |
||||
list.value = res.complaintCollectionPageDTOS; |
||||
total.value = res.total; |
||||
loading.value = false; |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['22'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getList() |
||||
}) |
||||
|
||||
const storeDict = computed(() => |
||||
catchStore.getDicts([ |
||||
"businessType", |
||||
"suspectProblem", |
||||
"policeType", |
||||
"hostLevel", |
||||
"timeLimit", |
||||
"approvalFlow", |
||||
"specialSupervision", |
||||
"checkStatus", |
||||
"sfssSourceTable", |
||||
"sfssTags", |
||||
"accountabilityTarget" |
||||
]) || {} |
||||
); |
||||
|
||||
const gabxfSourceTableSubOneList = computed(() => { |
||||
const list = storeDict.value.sfssSourceTable || [] |
||||
|
||||
// 二级:remark 等于公安部信访的dictValue |
||||
const children = list |
||||
.filter(d => d.remark === '22') |
||||
.sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0)) |
||||
|
||||
return children.map(c => ({ |
||||
label: c.dictLabel, |
||||
value: String(c.dictValue), |
||||
})) |
||||
}) |
||||
|
||||
const localDict = { |
||||
yesNo: [ |
||||
{id: 1, dictLabel: "是", dictValue: "1"}, |
||||
{id: 2, dictLabel: "否", dictValue: "0"}, |
||||
], |
||||
handleMethodType: [ |
||||
{id: 1, dictLabel: "自办", dictValue: "0"}, |
||||
{id: 2, dictLabel: "下发", dictValue: "1"}, |
||||
], |
||||
}; |
||||
|
||||
const dict = computed(() => ({ |
||||
...storeDict.value, |
||||
...localDict, |
||||
gabxfSourceTableSubOneList: gabxfSourceTableSubOneList.value, |
||||
})); |
||||
|
||||
function getDictLabel(list, value) { |
||||
if (!Array.isArray(list)) return '/' |
||||
|
||||
if (value === null || value === undefined || value === '') return '/' |
||||
|
||||
let values = [] |
||||
|
||||
if (Array.isArray(value)) { |
||||
values = value |
||||
} |
||||
else if (typeof value === 'string' && value.includes(',')) { |
||||
values = value.split(',').map(v => v.trim()) |
||||
} |
||||
else { |
||||
values = [value] |
||||
} |
||||
|
||||
const labels = values |
||||
.map(v => { |
||||
const item = list.find(d => d.dictValue == v) |
||||
return item?.dictLabel |
||||
}) |
||||
.filter(Boolean) |
||||
|
||||
return labels.length ? labels.join(',') : '/' |
||||
} |
||||
|
||||
const detailShow = ref(false) |
||||
const activeId = ref("") |
||||
const handleWatchDetail = async (row) => { |
||||
activeId.value = row.id |
||||
detailShow.value = true |
||||
} |
||||
|
||||
const handleExport = async () => { |
||||
let body = { |
||||
...query.value |
||||
} |
||||
await exportData(body); |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-form-item .el-form-item { |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
:deep() { |
||||
.el-form-item--label-right .el-form-item__label { |
||||
text-align: right; |
||||
line-height: 32px; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
padding: 0 24px 16px; |
||||
} |
||||
</style> |
||||
|
||||
// 这是ai写的页面 |
||||
@ -0,0 +1,453 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="114"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="问题来源"> |
||||
<el-select |
||||
v-model="query.sourceTableSubOneList" |
||||
clearable |
||||
filterable |
||||
multiple |
||||
collapse-tags |
||||
placeholder="请选择来源" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in dict.gjxfSourceTableSubOneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
:label="item.label" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input |
||||
placeholder="请输入编号" |
||||
v-model="query.originId" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="登记/受理时间"> |
||||
<date-time-range-picker-ext |
||||
v-model="query.discoveryTimeList" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件人"> |
||||
<el-input |
||||
placeholder="来件人姓名、身份证号码、联系电话" |
||||
v-model="query.personInfo" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="涉及二级机构" prop="secondDepartName"> |
||||
<depart-tree-select |
||||
v-model="query.secondDepartId" |
||||
:check-strictly="true" |
||||
@node-click="(row) => (query.secondDepartName = row.shortName)" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理方式"> |
||||
<el-select |
||||
v-model="query.handleMethod" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="自办"/> |
||||
<el-option value="1" label="下发"/> |
||||
</el-select> |
||||
|
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理状态"> |
||||
<el-select |
||||
v-model="query.status" |
||||
clearable |
||||
placeholder="办理状态" |
||||
> |
||||
<el-option value="0" label="未办理"/> |
||||
<el-option value="1" label="已办理"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="标签"> |
||||
<el-select |
||||
placeholder="全部" |
||||
clearable |
||||
v-model="query.tags" |
||||
multiple |
||||
collapse-tags |
||||
> |
||||
<el-option |
||||
v-for="item in dict.sfssTags" |
||||
:key="item.id" |
||||
:value="item.dictValue" |
||||
:label="item.dictLabel" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件内容"> |
||||
<el-input |
||||
placeholder="请输入来件内容" |
||||
v-model="query.thingDesc" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="是否重复件"> |
||||
<el-select |
||||
v-model="query.repeatt" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="否"/> |
||||
<el-option value="1" label="是"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="核查结论" > |
||||
<el-select v-model="query.checkStatusList" clearable multiple |
||||
style="width: 280px"> |
||||
<el-option v-for="item in dict.checkStatus" :value="item.dictValue" :label="item.dictLabel"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="初核材料"> |
||||
<el-select |
||||
v-model="query.initialReviewFileList" |
||||
placeholder="全部" |
||||
clearable |
||||
multiple |
||||
> |
||||
<el-option value="0" label="未上传"/> |
||||
<el-option value="1" label="已上传"/> |
||||
<el-option value="2" label="超时上传"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="mb-25 flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleExport">数据导出</el-button> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList"> |
||||
<template #icon> |
||||
<icon name="el-icon-Search"/> |
||||
</template> |
||||
查询 |
||||
</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div class="table-container" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column label="信件编号" width="130" prop="originId" show-overflow-tooltip/> |
||||
<el-table-column label="来源" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceTablePath }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="登记/受理时间" |
||||
width="170" |
||||
prop="discoveryTime" |
||||
:formatter="(_, __, v) => v ? timeFormat(v, 'yyyy-mm-dd hh:MM:ss') : '/'" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="来件人姓名" width="100" prop="responderName" |
||||
:formatter="row => row.responderName ? row.responderName : '匿名'"/> |
||||
<el-table-column label="身份证号" width="100" prop="responderIdCode" |
||||
:formatter="row => row.responderIdCode ? row.responderIdCode : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="联系电话" width="100" prop="responderPhone" |
||||
:formatter="row => row.responderPhone ? row.responderPhone : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="被投诉机构" width="130" prop="secondDepartName"/> |
||||
<el-table-column label="来信内容" width="100" prop="thingDesc" show-overflow-tooltip/> |
||||
<el-table-column label="涉嫌问题" width="100" prop="involveProblemStr" show-overflow-tooltip/> |
||||
<el-table-column label="是否重复件" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.yesNo, row.repeatt) }} |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="初核限时" width="150" align="center"> |
||||
<template #default="{ row }"> |
||||
<!-- 有状态:显示状态文案 --> |
||||
<el-tag v-if="row.gwf3>=1" :type="row.gwf3 === '2' ? 'danger' : 'success'"> |
||||
{{ row.gwf3 === '2' ? '超时完成初核' : '按时完成初核' }} |
||||
</el-tag> |
||||
|
||||
<!-- 无状态:显示倒计时 --> |
||||
<countdown v-else :time="Number(row.remainingDuration || 0)"/> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="标签" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.sfssTags, row.tag) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办结情况" width="100" prop="completionStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.completionStatus === '1' ? '程序办结' : |
||||
row.completionStatus === '2' ? '已解决合理诉求' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="群众认可" width="100" prop="publicRecognition"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.publicRecognition === '1' ? '认可' : |
||||
row.publicRecognition === '2' ? '不认可' : |
||||
row.publicRecognition === '3' ? '不接电话' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办理方式" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.handleMethodType, row.handleMethod) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="业务类别" width="100" prop="businessTypeName"/> |
||||
<el-table-column label="核查结论" width="140" prop="checkStatus" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.checkStatus, row.checkStatus) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="状态" prop="status" width="100"> |
||||
<template #default="{ row }"> |
||||
<span :style="row.status === '0' ? 'color: red' : ''"> |
||||
{{ |
||||
row.status === '0' ? '未办理' : |
||||
row.status === '1' ? '已办理' : |
||||
'-' |
||||
}} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="100" fixed="right"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleWatchDetail(row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="flex end mt-8"> |
||||
<el-pagination |
||||
@size-change="getList" |
||||
@current-change="getList" |
||||
:page-sizes="[10, 20, 50]" |
||||
v-model:page-size="query.size" |
||||
v-model:current-page="query.current" |
||||
layout="total, sizes, prev, pager, next" |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 查看详情 --> |
||||
<complaint_detail |
||||
v-model="detailShow" |
||||
:id="activeId" |
||||
:dict="dict"/> |
||||
|
||||
</template> |
||||
|
||||
|
||||
<script setup> |
||||
import {computed, onMounted, ref} from 'vue'; |
||||
import {timeFormat} from "@/utils/util"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import {exportData, getComplaintCollectionPage} from "@/api/data/complaintCollection.ts"; |
||||
import Complaint_detail from "@/components/data/complaint_detail.vue"; |
||||
|
||||
|
||||
const catchStore = useCatchStore(); |
||||
|
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['21'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}); |
||||
|
||||
|
||||
|
||||
const list = ref([]); |
||||
const total = ref(0); |
||||
const loading = ref(false) |
||||
const getList = async () => { |
||||
loading.value = true; |
||||
|
||||
// 确保始终包含默认来源 |
||||
if (!query.value.sourceTableList.includes('21')) { |
||||
query.value.sourceTableList = ['21', ...query.value.sourceTableList]; |
||||
} |
||||
|
||||
const params = { |
||||
...query.value, |
||||
} |
||||
|
||||
let res = await getComplaintCollectionPage(params); |
||||
list.value = res.complaintCollectionPageDTOS; |
||||
total.value = res.total; |
||||
loading.value = false; |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['21'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getList() |
||||
}) |
||||
|
||||
const storeDict = computed(() => |
||||
catchStore.getDicts([ |
||||
"businessType", |
||||
"suspectProblem", |
||||
"policeType", |
||||
"hostLevel", |
||||
"timeLimit", |
||||
"approvalFlow", |
||||
"specialSupervision", |
||||
"checkStatus", |
||||
"sfssSourceTable", |
||||
"sfssTags", |
||||
"accountabilityTarget" |
||||
]) || {} |
||||
); |
||||
|
||||
const localDict = { |
||||
yesNo: [ |
||||
{id: 1, dictLabel: "是", dictValue: "1"}, |
||||
{id: 2, dictLabel: "否", dictValue: "0"}, |
||||
], |
||||
handleMethodType: [ |
||||
{id: 1, dictLabel: "自办", dictValue: "0"}, |
||||
{id: 2, dictLabel: "下发", dictValue: "1"}, |
||||
], |
||||
}; |
||||
|
||||
const gjxfSourceTableSubOneList = computed(() => { |
||||
const list = storeDict.value.sfssSourceTable || [] |
||||
|
||||
// 二级:remark 等于国家信访的dictValue |
||||
const children = list |
||||
.filter(d => d.remark === '21') |
||||
.sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0)) |
||||
|
||||
return children.map(c => ({ |
||||
label: c.dictLabel, |
||||
value: String(c.dictValue), |
||||
})) |
||||
}) |
||||
|
||||
const dict = computed(() => ({ |
||||
...storeDict.value, |
||||
...localDict, |
||||
gjxfSourceTableSubOneList: gjxfSourceTableSubOneList.value, |
||||
})); |
||||
|
||||
function getDictLabel(list, value) { |
||||
if (!Array.isArray(list)) return '/' |
||||
|
||||
if (value === null || value === undefined || value === '') return '/' |
||||
|
||||
let values = [] |
||||
|
||||
if (Array.isArray(value)) { |
||||
values = value |
||||
} |
||||
else if (typeof value === 'string' && value.includes(',')) { |
||||
values = value.split(',').map(v => v.trim()) |
||||
} |
||||
else { |
||||
values = [value] |
||||
} |
||||
|
||||
const labels = values |
||||
.map(v => { |
||||
const item = list.find(d => d.dictValue == v) |
||||
return item?.dictLabel |
||||
}) |
||||
.filter(Boolean) |
||||
|
||||
return labels.length ? labels.join(',') : '/' |
||||
} |
||||
|
||||
const detailShow = ref(false) |
||||
const activeId = ref("") |
||||
const handleWatchDetail = async (row) => { |
||||
activeId.value = row.id |
||||
detailShow.value = true |
||||
} |
||||
|
||||
const handleExport = async () => { |
||||
let body = { |
||||
...query.value |
||||
} |
||||
await exportData(body); |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-form-item .el-form-item { |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
:deep() { |
||||
.el-form-item--label-right .el-form-item__label { |
||||
text-align: right; |
||||
line-height: 32px; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
padding: 0 24px 16px; |
||||
} |
||||
</style> |
||||
@ -0,0 +1,487 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="114"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="问题来源"> |
||||
<el-select |
||||
v-model="query.sourceTableSubOneList" |
||||
clearable |
||||
filterable |
||||
multiple |
||||
collapse-tags |
||||
placeholder="请选择来源" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in dict.jzxxSourceTableSubOneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
:label="item.label" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input |
||||
placeholder="请输入编号" |
||||
v-model="query.originId" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="登记/受理时间"> |
||||
<date-time-range-picker-ext |
||||
v-model="query.discoveryTimeList" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件人"> |
||||
<el-input |
||||
placeholder="来件人姓名、身份证号码、联系电话" |
||||
v-model="query.personInfo" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="涉及二级机构" prop="secondDepartName"> |
||||
<depart-tree-select |
||||
v-model="query.secondDepartId" |
||||
:check-strictly="true" |
||||
@node-click="(row) => (query.secondDepartName = row.shortName)" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理方式"> |
||||
<el-select |
||||
v-model="query.handleMethod" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="自办"/> |
||||
<el-option value="1" label="下发"/> |
||||
</el-select> |
||||
|
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理状态"> |
||||
<el-select |
||||
v-model="query.status" |
||||
clearable |
||||
placeholder="办理状态" |
||||
> |
||||
<el-option value="0" label="未办理"/> |
||||
<el-option value="1" label="已办理"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="标签"> |
||||
<el-select |
||||
placeholder="全部" |
||||
clearable |
||||
v-model="query.tags" |
||||
multiple |
||||
collapse-tags |
||||
> |
||||
<el-option |
||||
v-for="item in dict.sfssTags" |
||||
:key="item.id" |
||||
:value="item.dictValue" |
||||
:label="item.dictLabel" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件内容"> |
||||
<el-input |
||||
placeholder="请输入来件内容" |
||||
v-model="query.thingDesc" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="是否重复件"> |
||||
<el-select |
||||
v-model="query.repeatt" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="否"/> |
||||
<el-option value="1" label="是"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="核查结论" > |
||||
<el-select v-model="query.checkStatusList" clearable multiple |
||||
style="width: 280px"> |
||||
<el-option v-for="item in dict.checkStatus" :value="item.dictValue" :label="item.dictLabel"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="初核材料"> |
||||
<el-select |
||||
v-model="query.initialReviewFileList" |
||||
placeholder="全部" |
||||
clearable |
||||
multiple |
||||
> |
||||
<el-option value="0" label="未上传"/> |
||||
<el-option value="1" label="已上传"/> |
||||
<el-option value="2" label="超时上传"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件状态"> |
||||
<el-select |
||||
v-model="query.processingStatus" |
||||
placeholder="全部" |
||||
clearable |
||||
style="width: 100%" |
||||
> |
||||
<el-option value="processing" label="办理中"/> |
||||
<el-option value="completion" label="已办结"/> |
||||
<el-option value="delayed" label="已延期"/> |
||||
<el-option value="terminated" label="已终止"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
|
||||
</el-form> |
||||
<div class="mb-25 flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleExport">数据导出</el-button> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList"> |
||||
<template #icon> |
||||
<icon name="el-icon-Search"/> |
||||
</template> |
||||
查询 |
||||
</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div class="table-container" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column label="信件编号" width="130" prop="originId" show-overflow-tooltip/> |
||||
<el-table-column label="来源" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceTablePath }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="登记/受理时间" |
||||
width="170" |
||||
prop="discoveryTime" |
||||
:formatter="(_, __, v) => v ? timeFormat(v, 'yyyy-mm-dd hh:MM:ss') : '/'" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="来件人姓名" width="100" prop="responderName" |
||||
:formatter="row => row.responderName ? row.responderName : '匿名'"/> |
||||
<el-table-column label="身份证号" width="100" prop="responderIdCode" |
||||
:formatter="row => row.responderIdCode ? row.responderIdCode : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="联系电话" width="100" prop="responderPhone" |
||||
:formatter="row => row.responderPhone ? row.responderPhone : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="被投诉机构" width="130" prop="secondDepartName"/> |
||||
<el-table-column label="来信内容" width="100" prop="thingDesc" show-overflow-tooltip/> |
||||
<el-table-column label="涉嫌问题" width="100" prop="involveProblemStr" show-overflow-tooltip/> |
||||
<el-table-column label="是否重复件" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.yesNo, row.repeatt) }} |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="初核限时" width="150" align="center"> |
||||
<template #default="{ row }"> |
||||
<!-- 有状态:显示状态文案 --> |
||||
<el-tag v-if="row.gwf3>=1" :type="row.gwf3 === '2' ? 'danger' : 'success'"> |
||||
{{ row.gwf3 === '2' ? '超时完成初核' : '按时完成初核' }} |
||||
</el-tag> |
||||
|
||||
<!-- 无状态:显示倒计时 --> |
||||
<countdown v-else :time="Number(row.remainingDuration || 0)"/> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="标签" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.sfssTags, row.tag) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办结情况" width="100" prop="completionStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.completionStatus === '1' ? '程序办结' : |
||||
row.completionStatus === '2' ? '已解决合理诉求' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="群众认可" width="100" prop="publicRecognition"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.publicRecognition === '1' ? '认可' : |
||||
row.publicRecognition === '2' ? '不认可' : |
||||
row.publicRecognition === '3' ? '不接电话' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办理方式" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.handleMethodType, row.handleMethod) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="业务类别" width="100" prop="businessTypeName"/> |
||||
<el-table-column label="核查结论" width="140" prop="checkStatus" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.checkStatus, row.checkStatus) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="状态" prop="status" width="100"> |
||||
<template #default="{ row }"> |
||||
<span :style="row.status === '0' ? 'color: red' : ''"> |
||||
{{ |
||||
row.status === '0' ? '未办理' : |
||||
row.status === '1' ? '已办理' : |
||||
'-' |
||||
}} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="信件状态(局)" width="120" prop="processingStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.processingStatus === 'completion' ? '已办结' : |
||||
row.processingStatus === 'processing' ? '办理中' : |
||||
row.processingStatus === 'delayed' ? '已延期' : |
||||
row.processingStatus === 'terminated' ? '已终止' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="100" fixed="right"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleWatchDetail(row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="flex end mt-8"> |
||||
<el-pagination |
||||
@size-change="getList" |
||||
@current-change="getList" |
||||
:page-sizes="[10, 20, 50]" |
||||
v-model:page-size="query.size" |
||||
v-model:current-page="query.current" |
||||
layout="total, sizes, prev, pager, next" |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 查看详情 --> |
||||
<complaint_detail |
||||
v-model="detailShow" |
||||
:id="activeId" |
||||
:dict="dict"/> |
||||
|
||||
</template> |
||||
|
||||
|
||||
<script setup> |
||||
import { ref, watch, computed, onMounted } from 'vue'; |
||||
import {timeFormat} from "@/utils/util"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import { |
||||
exportData, |
||||
getComplaintCollectionPage |
||||
} from "@/api/data/complaintCollection.ts"; |
||||
import Complaint_detail from "@/components/data/complaint_detail.vue"; |
||||
|
||||
|
||||
const catchStore = useCatchStore(); |
||||
|
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['23'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
processingStatus: '', |
||||
}); |
||||
|
||||
|
||||
|
||||
const list = ref([]); |
||||
const total = ref(0); |
||||
const loading = ref(false) |
||||
const getList = async () => { |
||||
loading.value = true; |
||||
|
||||
// 确保始终包含默认来源 |
||||
if (!query.value.sourceTableList.includes('23')) { |
||||
query.value.sourceTableList = ['23', ...query.value.sourceTableList]; |
||||
} |
||||
|
||||
const params = { |
||||
...query.value, |
||||
} |
||||
|
||||
let res = await getComplaintCollectionPage(params); |
||||
list.value = res.complaintCollectionPageDTOS; |
||||
total.value = res.total; |
||||
loading.value = false; |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['23'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
processingStatus: '', |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getList() |
||||
}) |
||||
|
||||
const storeDict = computed(() => |
||||
catchStore.getDicts([ |
||||
"businessType", |
||||
"suspectProblem", |
||||
"policeType", |
||||
"hostLevel", |
||||
"timeLimit", |
||||
"approvalFlow", |
||||
"specialSupervision", |
||||
"checkStatus", |
||||
"sfssSourceTable", |
||||
"sfssTags", |
||||
"accountabilityTarget" |
||||
]) || {} |
||||
); |
||||
|
||||
const jzxxSourceTableSubOneList = computed(() => { |
||||
const list = storeDict.value.sfssSourceTable || [] |
||||
|
||||
// 二级:remark 等于局长信箱的dictValue |
||||
const children = list |
||||
.filter(d => d.remark === '23') |
||||
.sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0)) |
||||
|
||||
return children.map(c => ({ |
||||
label: c.dictLabel, |
||||
value: String(c.dictValue), |
||||
})) |
||||
}) |
||||
|
||||
const localDict = { |
||||
yesNo: [ |
||||
{id: 1, dictLabel: "是", dictValue: "1"}, |
||||
{id: 2, dictLabel: "否", dictValue: "0"}, |
||||
], |
||||
handleMethodType: [ |
||||
{id: 1, dictLabel: "自办", dictValue: "0"}, |
||||
{id: 2, dictLabel: "下发", dictValue: "1"}, |
||||
], |
||||
}; |
||||
|
||||
const dict = computed(() => ({ |
||||
...storeDict.value, |
||||
...localDict, |
||||
jzxxSourceTableSubOneList: jzxxSourceTableSubOneList.value, |
||||
})); |
||||
|
||||
function getDictLabel(list, value) { |
||||
if (!Array.isArray(list)) return '/' |
||||
|
||||
if (value === null || value === undefined || value === '') return '/' |
||||
|
||||
let values = [] |
||||
|
||||
if (Array.isArray(value)) { |
||||
values = value |
||||
} |
||||
else if (typeof value === 'string' && value.includes(',')) { |
||||
values = value.split(',').map(v => v.trim()) |
||||
} |
||||
else { |
||||
values = [value] |
||||
} |
||||
|
||||
const labels = values |
||||
.map(v => { |
||||
const item = list.find(d => d.dictValue == v) |
||||
return item?.dictLabel |
||||
}) |
||||
.filter(Boolean) |
||||
|
||||
return labels.length ? labels.join(',') : '/' |
||||
} |
||||
|
||||
const detailShow = ref(false) |
||||
const activeId = ref("") |
||||
const handleWatchDetail = async (row) => { |
||||
activeId.value = row.id |
||||
detailShow.value = true |
||||
} |
||||
|
||||
const handleExport = async () => { |
||||
let body = { |
||||
...query.value |
||||
} |
||||
await exportData(body); |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-form-item .el-form-item { |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
:deep() { |
||||
.el-form-item--label-right .el-form-item__label { |
||||
text-align: right; |
||||
line-height: 32px; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
padding: 0 24px 16px; |
||||
} |
||||
</style> |
||||
|
||||
// 这是ai写的页面 |
||||
@ -0,0 +1,458 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<header> |
||||
<el-form :label-width="114"> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="问题来源"> |
||||
<el-select |
||||
v-model="query.sourceTableSubOneList" |
||||
clearable |
||||
filterable |
||||
multiple |
||||
collapse-tags |
||||
placeholder="请选择来源" |
||||
style="width: 100%" |
||||
> |
||||
<el-option |
||||
v-for="item in dict.leaderSourceTableSubOneList" |
||||
:key="item.value" |
||||
:value="item.value" |
||||
:label="item.label" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="信件编号"> |
||||
<el-input |
||||
placeholder="请输入编号" |
||||
v-model="query.originId" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="登记/受理时间"> |
||||
<date-time-range-picker-ext |
||||
v-model="query.discoveryTimeList" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件人"> |
||||
<el-input |
||||
placeholder="来件人姓名、身份证号码、联系电话" |
||||
v-model="query.personInfo" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="涉及二级机构" prop="secondDepartName"> |
||||
<depart-tree-select |
||||
v-model="query.secondDepartId" |
||||
:check-strictly="true" |
||||
@node-click="(row) => (query.secondDepartName = row.shortName)" |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理方式"> |
||||
<el-select |
||||
v-model="query.handleMethod" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="自办"/> |
||||
<el-option value="1" label="下发"/> |
||||
</el-select> |
||||
|
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="办理状态"> |
||||
<el-select |
||||
v-model="query.status" |
||||
clearable |
||||
placeholder="办理状态" |
||||
> |
||||
<el-option value="0" label="未办理"/> |
||||
<el-option value="1" label="已办理"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="标签"> |
||||
<el-select |
||||
placeholder="全部" |
||||
clearable |
||||
v-model="query.tags" |
||||
multiple |
||||
collapse-tags |
||||
> |
||||
<el-option |
||||
v-for="item in dict.sfssTags" |
||||
:key="item.id" |
||||
:value="item.dictValue" |
||||
:label="item.dictLabel" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
<el-row> |
||||
<el-col :span="6"> |
||||
<el-form-item label="来件内容"> |
||||
<el-input |
||||
placeholder="请输入来件内容" |
||||
v-model="query.thingDesc" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="是否重复件"> |
||||
<el-select |
||||
v-model="query.repeatt" |
||||
placeholder="全部" |
||||
clearable |
||||
> |
||||
<el-option value="0" label="否"/> |
||||
<el-option value="1" label="是"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="核查结论" > |
||||
<el-select v-model="query.checkStatusList" clearable multiple |
||||
style="width: 280px"> |
||||
<el-option v-for="item in dict.checkStatus" :value="item.dictValue" :label="item.dictLabel"></el-option> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
<el-col :span="6"> |
||||
<el-form-item label="初核材料"> |
||||
<el-select |
||||
v-model="query.initialReviewFileList" |
||||
placeholder="全部" |
||||
clearable |
||||
multiple |
||||
> |
||||
<el-option value="0" label="未上传"/> |
||||
<el-option value="1" label="已上传"/> |
||||
<el-option value="2" label="超时上传"/> |
||||
</el-select> |
||||
</el-form-item> |
||||
</el-col> |
||||
</el-row> |
||||
</el-form> |
||||
<div class="mb-25 flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleExport">数据导出</el-button> |
||||
</div> |
||||
<div> |
||||
<el-button type="primary" @click="getList"> |
||||
<template #icon> |
||||
<icon name="el-icon-Search"/> |
||||
</template> |
||||
查询 |
||||
</el-button> |
||||
<el-button @click="reset">重置</el-button> |
||||
</div> |
||||
</div> |
||||
</header> |
||||
<div class="table-container" v-loading="loading"> |
||||
<el-table :data="list"> |
||||
<el-table-column label="信件编号" width="130" prop="originId" show-overflow-tooltip/> |
||||
<el-table-column label="来源" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ row.sourceTablePath }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="登记/受理时间" |
||||
width="170" |
||||
prop="discoveryTime" |
||||
:formatter="(_, __, v) => v ? timeFormat(v, 'yyyy-mm-dd hh:MM:ss') : '/'" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="来件人姓名" width="100" prop="responderName" |
||||
:formatter="row => row.responderName ? row.responderName : '匿名'"/> |
||||
<el-table-column label="身份证号" width="100" prop="responderIdCode" |
||||
:formatter="row => row.responderIdCode ? row.responderIdCode : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="联系电话" width="100" prop="responderPhone" |
||||
:formatter="row => row.responderPhone ? row.responderPhone : '无'" show-overflow-tooltip/> |
||||
<el-table-column label="被投诉机构" width="130" prop="secondDepartName"/> |
||||
<el-table-column label="来信内容" width="100" prop="thingDesc" show-overflow-tooltip/> |
||||
<el-table-column label="涉嫌问题" width="100" prop="involveProblemStr" show-overflow-tooltip/> |
||||
<el-table-column label="是否重复件" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.yesNo, row.repeatt) }} |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="初核限时" width="150" align="center"> |
||||
<template #default="{ row }"> |
||||
<!-- 有状态:显示状态文案 --> |
||||
<el-tag v-if="row.gwf3>=1" :type="row.gwf3 === '2' ? 'danger' : 'success'"> |
||||
{{ row.gwf3 === '2' ? '超时完成初核' : '按时完成初核' }} |
||||
</el-tag> |
||||
|
||||
<!-- 无状态:显示倒计时 --> |
||||
<countdown v-else :time="Number(row.remainingDuration || 0)"/> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column label="标签" width="100" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.sfssTags, row.tag) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办结情况" width="100" prop="completionStatus"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.completionStatus === '1' ? '程序办结' : |
||||
row.completionStatus === '2' ? '已解决合理诉求' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="群众认可" width="100" prop="publicRecognition"> |
||||
<template #default="{ row }"> |
||||
{{ |
||||
row.publicRecognition === '1' ? '认可' : |
||||
row.publicRecognition === '2' ? '不认可' : |
||||
row.publicRecognition === '3' ? '不接电话' : |
||||
'/' |
||||
}} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="办理方式" width="100"> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.handleMethodType, row.handleMethod) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="业务类别" width="100" prop="businessTypeName"/> |
||||
<el-table-column label="核查结论" width="140" prop="checkStatus" show-overflow-tooltip> |
||||
<template #default="{ row }"> |
||||
{{ getDictLabel(dict.checkStatus, row.checkStatus) }} |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="状态" prop="status" width="100"> |
||||
<template #default="{ row }"> |
||||
<span :style="row.status === '0' ? 'color: red' : ''"> |
||||
{{ |
||||
row.status === '0' ? '未办理' : |
||||
row.status === '1' ? '已办理' : |
||||
'-' |
||||
}} |
||||
</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="操作" width="100" fixed="right"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleWatchDetail(row)">查看详情</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="flex end mt-8"> |
||||
<el-pagination |
||||
@size-change="getList" |
||||
@current-change="getList" |
||||
:page-sizes="[10, 20, 50]" |
||||
v-model:page-size="query.size" |
||||
v-model:current-page="query.current" |
||||
layout="total, sizes, prev, pager, next" |
||||
:total="total" |
||||
> |
||||
</el-pagination> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- 查看详情 --> |
||||
<complaint_detail |
||||
v-model="detailShow" |
||||
:id="activeId" |
||||
:dict="dict"/> |
||||
|
||||
</template> |
||||
|
||||
|
||||
<script setup> |
||||
import { ref, watch, computed, onMounted } from 'vue'; |
||||
import {timeFormat} from "@/utils/util"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import { |
||||
exportData, |
||||
getComplaintCollectionPage |
||||
} from "@/api/data/complaintCollection.ts"; |
||||
import Complaint_detail from "@/components/data/complaint_detail.vue"; |
||||
|
||||
|
||||
const catchStore = useCatchStore(); |
||||
|
||||
const query = ref({ |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['leader_explain'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}); |
||||
|
||||
|
||||
|
||||
const list = ref([]); |
||||
const total = ref(0); |
||||
const loading = ref(false) |
||||
const getList = async () => { |
||||
loading.value = true; |
||||
|
||||
// 确保始终包含默认来源 |
||||
if (!query.value.sourceTableList.includes('leader_explain')) { |
||||
query.value.sourceTableList = ['leader_explain', ...query.value.sourceTableList]; |
||||
} |
||||
|
||||
const params = { |
||||
...query.value, |
||||
} |
||||
|
||||
let res = await getComplaintCollectionPage(params); |
||||
list.value = res.complaintCollectionPageDTOS; |
||||
total.value = res.total; |
||||
loading.value = false; |
||||
} |
||||
|
||||
function reset() { |
||||
query.value = { |
||||
size: 10, |
||||
current: 1, |
||||
sourceTableList: ['leader_explain'], |
||||
sourceTableSubOneList: [], |
||||
initialReviewFileList: [], |
||||
}; |
||||
getList(); |
||||
} |
||||
|
||||
onMounted(() => { |
||||
getList() |
||||
}) |
||||
|
||||
const storeDict = computed(() => |
||||
catchStore.getDicts([ |
||||
"businessType", |
||||
"suspectProblem", |
||||
"policeType", |
||||
"hostLevel", |
||||
"timeLimit", |
||||
"approvalFlow", |
||||
"specialSupervision", |
||||
"checkStatus", |
||||
"sfssSourceTable", |
||||
"sfssTags", |
||||
"accountabilityTarget" |
||||
]) || {} |
||||
); |
||||
|
||||
const leaderSourceTableSubOneList = computed(() => { |
||||
const list = storeDict.value.sfssSourceTable || [] |
||||
|
||||
// 二级:remark 等于领导交办的dictValue |
||||
const children = list |
||||
.filter(d => d.remark === 'leader_explain') |
||||
.sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0)) |
||||
|
||||
return children.map(c => ({ |
||||
label: c.dictLabel, |
||||
value: String(c.dictValue), |
||||
})) |
||||
}) |
||||
|
||||
const localDict = { |
||||
yesNo: [ |
||||
{id: 1, dictLabel: "是", dictValue: "1"}, |
||||
{id: 2, dictLabel: "否", dictValue: "0"}, |
||||
], |
||||
handleMethodType: [ |
||||
{id: 1, dictLabel: "自办", dictValue: "0"}, |
||||
{id: 2, dictLabel: "下发", dictValue: "1"}, |
||||
], |
||||
}; |
||||
|
||||
const dict = computed(() => ({ |
||||
...storeDict.value, |
||||
...localDict, |
||||
leaderSourceTableSubOneList: leaderSourceTableSubOneList.value, |
||||
})); |
||||
|
||||
function getDictLabel(list, value) { |
||||
if (!Array.isArray(list)) return '/' |
||||
|
||||
if (value === null || value === undefined || value === '') return '/' |
||||
|
||||
let values = [] |
||||
|
||||
if (Array.isArray(value)) { |
||||
values = value |
||||
} |
||||
else if (typeof value === 'string' && value.includes(',')) { |
||||
values = value.split(',').map(v => v.trim()) |
||||
} |
||||
else { |
||||
values = [value] |
||||
} |
||||
|
||||
const labels = values |
||||
.map(v => { |
||||
const item = list.find(d => d.dictValue == v) |
||||
return item?.dictLabel |
||||
}) |
||||
.filter(Boolean) |
||||
|
||||
return labels.length ? labels.join(',') : '/' |
||||
} |
||||
|
||||
const detailShow = ref(false) |
||||
const activeId = ref("") |
||||
const handleWatchDetail = async (row) => { |
||||
activeId.value = row.id |
||||
detailShow.value = true |
||||
} |
||||
|
||||
const handleExport = async () => { |
||||
let body = { |
||||
...query.value |
||||
} |
||||
await exportData(body); |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.el-form-item .el-form-item { |
||||
margin-bottom: 18px; |
||||
} |
||||
|
||||
:deep() { |
||||
.el-form-item--label-right .el-form-item__label { |
||||
text-align: right; |
||||
line-height: 32px; |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
p { |
||||
margin: 0; |
||||
line-height: 1.4; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: flex-end; |
||||
padding: 0 24px 16px; |
||||
} |
||||
</style> |
||||
|
||||
// 这是ai写的页面 |
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,675 @@
|
||||
<template> |
||||
<div class="container"> |
||||
<!-- 标签页组件 --> |
||||
<el-tabs v-model="activeTab" class="mb-20"> |
||||
<!-- 个人极端赋分标签 --> |
||||
<el-tab-pane label="个人极端赋分" name="riskScoreRule"> |
||||
<!-- 个人极端赋分内容 --> |
||||
<div class="tab-content" v-loading="riskScoreLoading"> |
||||
<header class="mb-20"> |
||||
<div class="flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleAddRiskScoreRule"> |
||||
<template #icon> |
||||
<icon name="el-icon-Plus" /> |
||||
</template> |
||||
新增 |
||||
</el-button> |
||||
</div> |
||||
<div style="width: 50%"> |
||||
<el-row> </el-row> |
||||
</div> |
||||
</div> |
||||
<div class="flex between mt-10 v-center"> |
||||
<div> |
||||
<div> |
||||
<span class="text-primary">个人极端暴力风险指数</span> = ((基础因素得分 × 权重)+(诱发因素得分 × 权重)+(行为因素得分 × 权重)+(管控因素得分 × 权重)) × 20 |
||||
</div> |
||||
</div> |
||||
<a |
||||
class="flex v-center gap file-link" |
||||
:href="`${BASE_PATH}/templates/【工作机制】个人极端暴力风险数字督察灵敏感知体系风险赋分及预警处置机制.doc`" |
||||
target="__blank" |
||||
> |
||||
<icon name="local-icon-pdf" :size="38" /> |
||||
<span>个人极端风险赋分规则.pdf</span> |
||||
</a> |
||||
</div> |
||||
</header> |
||||
<div class="table-container"> |
||||
<el-table |
||||
ref="riskScoreTableRef" |
||||
:default-expand-all="false" |
||||
:data="scoreRules" |
||||
:expand-row-keys="[]" |
||||
:tree-props="{ |
||||
children: 'children', |
||||
hasChildren: 'hasChildren', |
||||
}" |
||||
row-key="id" |
||||
> |
||||
<el-table-column |
||||
label="问题条目" |
||||
prop="riskName" |
||||
show-overflow-tooltip |
||||
width="180" |
||||
/> |
||||
<el-table-column |
||||
label="一级指标" |
||||
prop="riskIndex" |
||||
show-overflow-tooltip |
||||
width="180" |
||||
/> |
||||
<el-table-column |
||||
label="因素分值" |
||||
prop="score" |
||||
width="200" |
||||
align="center" |
||||
> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="赋分规则" |
||||
prop="ruleDesc" |
||||
show-overflow-tooltip |
||||
> |
||||
</el-table-column> |
||||
<el-table-column label="因素权重" width="100" align="center"> |
||||
<template #default="{ row }"> |
||||
<span v-if="row.level === 1">{{ getChildWeightSum(row) }}</span> |
||||
<span v-if="row.level === 2">{{ row.weight }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column label="开启状态" width="100"> |
||||
<template #default="{ row }"> |
||||
<el-tag type="success" v-if="row.status === true">开启</el-tag> |
||||
<el-tag type="danger" v-if="row.status === false">关闭</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="最后更新时间" |
||||
prop="updateTime" |
||||
width="180" |
||||
/> |
||||
<el-table-column label="操作" width="160"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleEditRiskScoreRule(row)">编辑</el-button> |
||||
<el-button type="danger" link @click="handleDeleteRiskScoreRule(row)">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
</div> |
||||
</el-tab-pane> |
||||
|
||||
<!-- 问题赋分标签 --> |
||||
<el-tab-pane label="问题赋分" name="dictContent"> |
||||
<!-- 问题赋分内容 --> |
||||
<div class="tab-content" v-loading="dictContentLoading"> |
||||
<header class="mb-20"> |
||||
<div class="flex between"> |
||||
<div> |
||||
<el-button type="primary" @click="handleAddDictContent"> |
||||
<template #icon> |
||||
<icon name="el-icon-Plus" /> |
||||
</template> |
||||
新增 |
||||
</el-button> |
||||
</div> |
||||
<div style="width: 50%"> |
||||
<el-row> |
||||
<el-col :span="12"></el-col> |
||||
<el-col :span="12"> |
||||
<div class="flex end"> |
||||
<el-button type="primary" @click="handleCalculateDictContent">重新计算分值</el-button> |
||||
</div> |
||||
</el-col> |
||||
</el-row> |
||||
</div> |
||||
</div> |
||||
<div class="flex between mt-10"> |
||||
<div> |
||||
<div class="text-primary mt-10 mb-10">赋分分公式如下</div> |
||||
<div>问题风险值 = 基础风险值+(基础风险值×问题严重等级系数)+(基础风险值×问题发生频次系数)</div> |
||||
</div> |
||||
<a |
||||
class="flex v-center gap file-link" |
||||
:href="`${BASE_PATH}/templates/长沙公安数字督察灵敏感知体系问题赋分及风险预警机制.pdf`" |
||||
target="__blank" |
||||
> |
||||
<icon name="local-icon-pdf" :size="38" /> |
||||
<span>问题赋分机制.pdf</span> |
||||
</a> |
||||
</div> |
||||
</header> |
||||
<div class="table-container"> |
||||
<el-table :data="dictContents" row-key="id" :default-expand-all="false"> |
||||
<el-table-column |
||||
label="问题条目" |
||||
prop="name" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column label="基础分值" prop="score" width="200" align="center"> |
||||
<template #default="{ row }"> |
||||
<span v-if="row.level === 1">{{ getScoreRange(row) }}</span> |
||||
<span v-else>{{ row.score }}</span> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="问题严重等级" |
||||
prop="isActiveLevel" |
||||
align="center" |
||||
> |
||||
<template #default="{ row }"> |
||||
<el-tag type="success" v-if="row.isActiveLevel === true">开启</el-tag> |
||||
<el-tag type="danger" v-if="row.isActiveLevel === false">关闭</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
<el-table-column |
||||
label="序号" |
||||
prop="sort" |
||||
width="100" |
||||
align="center" |
||||
/> |
||||
<el-table-column label="最后更新时间" prop="updTime" /> |
||||
<el-table-column label="操作"> |
||||
<template #default="{ row }"> |
||||
<el-button type="primary" link @click="handleEditDictContent(row)">编辑</el-button> |
||||
<el-button type="danger" link @click="handleDeleteDictContent(row)">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</div> |
||||
<div class="mt-40"> |
||||
<div>基础分值设定规则:</div> |
||||
<p>1、二级问题条目设定的基础分值,作为其下属三级问题条目的默认基础分值。</p> |
||||
<p>2、若三级问题条目已单独设置基础分值,则赋分时以该三级条目的基础分值为准。</p> |
||||
<p>3、如三级问题条目未设置基础分值,则采用其所属二级问题条目的基础分值进行赋分。</p> |
||||
</div> |
||||
</div> |
||||
</el-tab-pane> |
||||
</el-tabs> |
||||
|
||||
<!-- 个人极端赋分编辑对话框 --> |
||||
<el-dialog |
||||
v-model="riskScoreShow" |
||||
:title="riskScoreMode === 'add' ? '新增赋分规则' : '编辑赋分规则'" |
||||
width="600" |
||||
> |
||||
<el-form label-width="120" ref="riskScoreFormRef" :model="riskScoreFormData"> |
||||
<el-form-item |
||||
label="父级节点" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请选择父级节点', |
||||
}" |
||||
prop="pid" |
||||
> |
||||
<el-tree-select |
||||
class="flex-1" |
||||
v-model="riskScoreFormData.pid" |
||||
:data="treeOptions" |
||||
clearable |
||||
node-key="id" |
||||
:props="{ |
||||
label: 'riskName', |
||||
}" |
||||
:default-expanded-keys="[MENU_ROOT_ID]" |
||||
placeholder="请选择父级节点" |
||||
check-strictly |
||||
filterable |
||||
@node-click="(node) => riskScoreFormData.pLevel = node.level" |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item |
||||
label="一级指标" |
||||
prop="riskIndex" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请选择一级值班', |
||||
}" |
||||
v-if="riskScoreFormData.pLevel === 1" |
||||
> |
||||
<el-select clearable v-model="riskScoreFormData.riskIndex"> |
||||
<el-option |
||||
v-for="item in dict.riskIndex" |
||||
:key="item.id" |
||||
:label="item.dictLabel" |
||||
:value="item.dictValue" |
||||
/> |
||||
</el-select> |
||||
</el-form-item> |
||||
<el-form-item |
||||
label="风险因素" |
||||
prop="riskName" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请输入风险因素', |
||||
}" |
||||
> |
||||
<el-input |
||||
v-model="riskScoreFormData.riskName" |
||||
placeholder="请输入" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="因素分值" prop="score"> |
||||
<el-input |
||||
v-model="riskScoreFormData.score" |
||||
placeholder="请输入序号" |
||||
type="number" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="赋分规则" prop="ruleDesc"> |
||||
<el-input |
||||
v-model="riskScoreFormData.ruleDesc" |
||||
placeholder="请输入序号" |
||||
type="textarea" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="因素权重" prop="weight"> |
||||
<el-input |
||||
v-model="riskScoreFormData.weight" |
||||
placeholder="请输入权重" |
||||
type="number" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
</el-form> |
||||
<footer class="flex end"> |
||||
<el-button @click="riskScoreShow = false">取消</el-button> |
||||
<el-button type="primary" @click="submitRiskScoreRule">确定</el-button> |
||||
</footer> |
||||
</el-dialog> |
||||
|
||||
<!-- 问题赋分编辑对话框 --> |
||||
<el-dialog |
||||
v-model="dictContentShow" |
||||
:title="dictContentMode === 'add' ? '新增问题类型' : '编辑问题类型'" |
||||
width="600" |
||||
> |
||||
<el-form label-width="120" ref="dictContentFormRef" :model="dictContentFormData"> |
||||
<el-form-item |
||||
label="父级节点" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请选择父级节点', |
||||
}" |
||||
prop="parentCode" |
||||
> |
||||
<el-tree-select |
||||
class="flex-1" |
||||
v-model="dictContentFormData.parentCode" |
||||
:data="dictContentOptions" |
||||
clearable |
||||
node-key="id" |
||||
:props="{ |
||||
label: 'name', |
||||
}" |
||||
:default-expanded-keys="[DICT_CONTENT_ROOT_ID]" |
||||
placeholder="请选择父级节点" |
||||
check-strictly |
||||
filterable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item |
||||
label="问题条目" |
||||
prop="name" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请输入问题条目', |
||||
}" |
||||
> |
||||
<el-input |
||||
v-model="dictContentFormData.name" |
||||
placeholder="请输入问题条目" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="基础分值" prop="score" v-if="dictContentFormData.parentCode != DICT_CONTENT_ROOT_ID"> |
||||
<el-input |
||||
v-model="dictContentFormData.score" |
||||
placeholder="请输入序号" |
||||
type="number" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item label="序号" prop="sort"> |
||||
<el-input |
||||
v-model="dictContentFormData.sort" |
||||
placeholder="请输入序号" |
||||
type="number" |
||||
clearable |
||||
/> |
||||
</el-form-item> |
||||
<el-form-item |
||||
label="问题严重等级" |
||||
prop="isActiveLevel" |
||||
:rules="{ |
||||
required: true, |
||||
message: '请选择问题严重等级', |
||||
trigger: ['blur'], |
||||
}" |
||||
> |
||||
<el-switch |
||||
v-model="dictContentFormData.isActiveLevel" |
||||
inline-prompt |
||||
active-text="开启" |
||||
inactive-text="关闭" |
||||
:active-value="true" |
||||
:inactive-value="false" |
||||
/> |
||||
</el-form-item> |
||||
</el-form> |
||||
<footer class="flex end"> |
||||
<el-button @click="dictContentShow = false">取消</el-button> |
||||
<el-button type="primary" @click="submitDictContent">确定</el-button> |
||||
</footer> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { ref, watch, onMounted } from 'vue'; |
||||
import { BASE_PATH } from "@/api/request"; |
||||
import feedback from "@/utils/feedback"; |
||||
import useCatchStore from "@/stores/modules/catch"; |
||||
import { MENU_ROOT_ID } from "@/enums/appEnums"; |
||||
import { DICT_CONTENT_ROOT_ID } from "@/enums/appEnums"; |
||||
import { calculateScore } from "@/api/work/negative"; |
||||
|
||||
// 导入个人极端赋分相关接口 |
||||
import { |
||||
listRiskScoreRuleTreeOld, |
||||
addRiskScoreRule, |
||||
updateRiskScoreRule, |
||||
delRiskScoreRule, |
||||
} from "@/api/sensitivePerception/riskScoreRule"; |
||||
|
||||
// 导入问题赋分相关接口 |
||||
import { |
||||
listDictContentTree, |
||||
addDictContent, |
||||
updateDictContent, |
||||
delDictContent, |
||||
} from "@/api/system/dictContent"; |
||||
|
||||
// 标签页状态 |
||||
const activeTab = ref('riskScoreRule'); |
||||
|
||||
// 个人极端赋分相关状态 |
||||
const riskScoreLoading = ref(false); |
||||
const scoreRules = ref([]); |
||||
const treeOptions = ref([ |
||||
{ |
||||
id: MENU_ROOT_ID, |
||||
riskName: "顶级", |
||||
children: [], |
||||
}, |
||||
]); |
||||
const riskScoreShow = ref(false); |
||||
const riskScoreFormData = ref({}); |
||||
const riskScoreFormRef = ref(); |
||||
const riskScoreMode = ref<string>("add"); |
||||
|
||||
// 问题赋分相关状态 |
||||
const dictContentLoading = ref(false); |
||||
const dictContents = ref([]); |
||||
const dictContentOptions = ref([ |
||||
{ |
||||
id: DICT_CONTENT_ROOT_ID, |
||||
name: "顶级", |
||||
children: [], |
||||
}, |
||||
]); |
||||
const dictContentShow = ref(false); |
||||
const dictContentFormData = ref({}); |
||||
const dictContentFormRef = ref(); |
||||
const dictContentMode = ref<string>("add"); |
||||
|
||||
// 获取字典数据 |
||||
const catchStore = useCatchStore(); |
||||
const dict = catchStore.getDicts(["riskIndex"]); |
||||
|
||||
// 个人极端赋分相关方法 |
||||
// 获取个人极端赋分列表 |
||||
function getRiskScoreList() { |
||||
riskScoreLoading.value = true; |
||||
listRiskScoreRuleTreeOld().then((data) => { |
||||
scoreRules.value = data; |
||||
treeOptions.value[0].children = data.map((item) => { |
||||
return { |
||||
id: item.id, |
||||
riskName: item.riskName, |
||||
level: item.level |
||||
}; |
||||
}); |
||||
riskScoreLoading.value = false; |
||||
}); |
||||
} |
||||
|
||||
// 监听个人极端赋分模式变化 |
||||
watch(riskScoreMode, (val) => { |
||||
if (val === "add") { |
||||
riskScoreFormData.value = {}; |
||||
if (riskScoreFormRef.value) { |
||||
riskScoreFormRef.value.resetFields(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// 提交个人极端赋分表单 |
||||
async function submitRiskScoreRule() { |
||||
await riskScoreFormRef.value.validate(); |
||||
if (riskScoreMode.value === "add") { |
||||
await addRiskScoreRule(riskScoreFormData.value); |
||||
const parentCode = riskScoreFormData.value.parentCode; |
||||
riskScoreFormData.value = {}; |
||||
riskScoreFormRef.value.resetFields(); |
||||
riskScoreFormData.value.parentCode = parentCode; |
||||
} else { |
||||
await updateRiskScoreRule(riskScoreFormData.value); |
||||
} |
||||
riskScoreShow.value = false; |
||||
getRiskScoreList(); |
||||
} |
||||
|
||||
// 新增个人极端赋分 |
||||
function handleAddRiskScoreRule() { |
||||
riskScoreShow.value = true; |
||||
riskScoreMode.value = "add"; |
||||
} |
||||
|
||||
// 编辑个人极端赋分 |
||||
function handleEditRiskScoreRule(row) { |
||||
riskScoreShow.value = true; |
||||
riskScoreMode.value = "edit"; |
||||
riskScoreFormData.value = { ...row }; |
||||
} |
||||
|
||||
// 删除个人极端赋分 |
||||
const handleDeleteRiskScoreRule = async (row) => { |
||||
await feedback.confirm(`确定要删除 "${row.name}"?`); |
||||
await delRiskScoreRule(row.id); |
||||
getRiskScoreList(); |
||||
feedback.msgSuccess("删除成功"); |
||||
}; |
||||
|
||||
// 计算子节点权重和 |
||||
function getChildWeightSum(row) { |
||||
const arr = row.children |
||||
.filter((item) => item.status) |
||||
.map((item) => item.weight || 0); |
||||
if (arr.length === 0) { |
||||
return 0; |
||||
} |
||||
return arr.reduce((a, b) => a + b).toFixed(2); |
||||
} |
||||
|
||||
// 问题赋分相关方法 |
||||
// 获取问题赋分列表 |
||||
function getDictContentList() { |
||||
dictContentLoading.value = true; |
||||
listDictContentTree().then((data) => { |
||||
dictContents.value = data; |
||||
dictContentOptions.value[0].children = data; |
||||
dictContentLoading.value = false; |
||||
}); |
||||
} |
||||
|
||||
// 监听问题赋分模式变化 |
||||
watch(dictContentMode, (val) => { |
||||
if (val === "add") { |
||||
dictContentFormData.value = {}; |
||||
if (dictContentFormRef.value) { |
||||
dictContentFormRef.value.resetFields(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// 提交问题赋分表单 |
||||
async function submitDictContent() { |
||||
await dictContentFormRef.value.validate(); |
||||
if (dictContentMode.value === "add") { |
||||
await addDictContent(dictContentFormData.value); |
||||
const parentCode = dictContentFormData.value.parentCode; |
||||
dictContentFormData.value = {}; |
||||
dictContentFormRef.value.resetFields(); |
||||
dictContentFormData.value.parentCode = parentCode; |
||||
} else { |
||||
await updateDictContent(dictContentFormData.value); |
||||
} |
||||
dictContentShow.value = false; |
||||
getDictContentList(); |
||||
} |
||||
|
||||
// 新增问题赋分 |
||||
function handleAddDictContent() { |
||||
dictContentShow.value = true; |
||||
dictContentMode.value = "add"; |
||||
} |
||||
|
||||
// 编辑问题赋分 |
||||
function handleEditDictContent(row) { |
||||
dictContentShow.value = true; |
||||
dictContentMode.value = "edit"; |
||||
dictContentFormData.value = { ...row }; |
||||
} |
||||
|
||||
// 删除问题赋分 |
||||
const handleDeleteDictContent = async (row) => { |
||||
await feedback.confirm(`确定要删除 "${row.name}"?`); |
||||
await delDictContent(row.id); |
||||
getDictContentList(); |
||||
feedback.msgSuccess("删除成功"); |
||||
}; |
||||
|
||||
// 计算分值范围 |
||||
function getScoreRange(row) { |
||||
const sorceSet = new Set(); |
||||
row.children.forEach((item) => { |
||||
if (item.score) { |
||||
sorceSet.add(item.score); |
||||
} |
||||
item.children.forEach((j) => { |
||||
if (j.score) { |
||||
sorceSet.add(j.score); |
||||
} |
||||
}); |
||||
}); |
||||
if (sorceSet.size === 0) { |
||||
return '' |
||||
} |
||||
if (sorceSet.size === 1) { |
||||
return sorceSet.values().next().value |
||||
} |
||||
const min = Math.min(...sorceSet); |
||||
const max = Math.max(...sorceSet); |
||||
return `${min}-${max}` |
||||
} |
||||
|
||||
// 重新计算风险指数 |
||||
async function handleCalculateDictContent() { |
||||
await feedback.confirm("确定要重新计算风险指数?"); |
||||
dictContentLoading.value = true |
||||
await calculateScore() |
||||
feedback.msgSuccess("风险指数计算完成"); |
||||
dictContentLoading.value = false |
||||
} |
||||
|
||||
// 页面挂载时加载数据 |
||||
onMounted(() => { |
||||
getRiskScoreList(); |
||||
getDictContentList(); |
||||
}); |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.file-link { |
||||
font-size: 16px; |
||||
text-decoration: none; |
||||
color: #19257d; |
||||
padding: 0 8px; |
||||
border-radius: 8px; |
||||
&:hover { |
||||
background-color: #eee; |
||||
} |
||||
} |
||||
|
||||
.tab-content { |
||||
background: #fff; |
||||
padding: 20px; |
||||
border-radius: 8px; |
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
||||
} |
||||
|
||||
header { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.table-container { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.flex { |
||||
display: flex; |
||||
} |
||||
|
||||
.between { |
||||
justify-content: space-between; |
||||
} |
||||
|
||||
.v-center { |
||||
align-items: center; |
||||
} |
||||
|
||||
.mt-10 { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.mb-10 { |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
.mb-20 { |
||||
margin-bottom: 20px; |
||||
} |
||||
|
||||
.mt-40 { |
||||
margin-top: 40px; |
||||
} |
||||
|
||||
.gap { |
||||
gap: 8px; |
||||
} |
||||
|
||||
.text-primary { |
||||
color: #1989fa; |
||||
} |
||||
|
||||
.end { |
||||
justify-content: flex-end; |
||||
} |
||||
</style> |
||||
<!-- 这是ai生成的页面 --> |
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue