数字督察一体化平台-前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

459 lines
14 KiB

<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