|
|
|
@ -4,11 +4,11 @@ import { ElMessage } from 'element-plus'; |
|
|
|
import * as echarts from 'echarts'; |
|
|
|
import { getDicts } from '@/api/system/dict/data'; |
|
|
|
import { |
|
|
|
getOverview, getGroupList, getDetailList, |
|
|
|
getOverview, getGroupList, getDetailList, getComplaintDetail, |
|
|
|
getTypeStatList, getAreaStatList, getStreetStatList, |
|
|
|
exportGroupList, exportTypeStat, exportAreaStat, exportStreetStat |
|
|
|
} from '@/api/efcode/report/statistics-complaint'; |
|
|
|
import type { ComplaintQuery, ComplaintGroupVo, ComplaintDetailVo, ComplaintTypeStatVo } from '@/api/efcode/report/statistics-complaint'; |
|
|
|
import type { ComplaintQuery, ComplaintGroupVo, ComplaintDetailVo, ComplaintTypeStatVo, ComplaintHandleVo } from '@/api/efcode/report/statistics-complaint'; |
|
|
|
|
|
|
|
// 当前Tab |
|
|
|
const activeTab = ref('tab1'); |
|
|
|
@ -76,6 +76,13 @@ const detailPageNum = ref(1); |
|
|
|
const detailPageSize = ref(10); |
|
|
|
const currentDeptId = ref(''); |
|
|
|
|
|
|
|
// 投诉举报详情弹窗 |
|
|
|
const complaintDetailVisible = ref(false); |
|
|
|
const complaintDetailLoading = ref(false); |
|
|
|
const complaintDetailTab = ref('progress'); // progress / info |
|
|
|
const complaintDetailData = ref<ComplaintDetailVo | null>(null); |
|
|
|
const complaintHandleList = ref<ComplaintHandleVo[]>([]); |
|
|
|
|
|
|
|
// 字典 |
|
|
|
const caseTypeOptions = ref<any[]>([]); |
|
|
|
const addressTypeOptions = ref<any[]>([]); |
|
|
|
@ -216,6 +223,32 @@ const handleDetailPageChange = () => { |
|
|
|
loadDetailData(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** 点击详情按钮 → 弹出投诉举报详情 */ |
|
|
|
const handleShowComplaintDetail = async (row: ComplaintDetailVo) => { |
|
|
|
complaintDetailTab.value = 'progress'; |
|
|
|
complaintDetailVisible.value = true; |
|
|
|
complaintDetailLoading.value = true; |
|
|
|
try { |
|
|
|
const res = await getComplaintDetail(row.id); |
|
|
|
complaintDetailData.value = (res.data?.detail || res.data) as ComplaintDetailVo; |
|
|
|
complaintHandleList.value = (res.data?.handleList || res.data?.progress || []) as ComplaintHandleVo[]; |
|
|
|
} catch (e) { |
|
|
|
// 接口未连通,降级使用当前行数据 + mock 兜底 |
|
|
|
complaintDetailData.value = { ...row }; |
|
|
|
complaintHandleList.value = mockHandleList(row); |
|
|
|
} finally { |
|
|
|
complaintDetailLoading.value = false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** mock 处置进度兜底数据(接口未连通时使用) */ |
|
|
|
const mockHandleList = (row: ComplaintDetailVo): ComplaintHandleVo[] => [ |
|
|
|
{ handleDepartment: '系统自动评价', handleOpinion: '系统自动评价', handleTime: row.complaintTime }, |
|
|
|
{ handleDepartment: '市统一受理分拨平台', handleOpinion: '复核通过,办结工单。', handleTime: row.complaintTime }, |
|
|
|
{ handleDepartment: row.complaintDepartment, handleOpinion: '已受理,正在核实处理中。', handleTime: row.complaintTime }, |
|
|
|
{ handleDepartment: '市统一受理分拨平台', handleOpinion: '工单已派发至相关部门,请及时跟进处理。', handleTime: row.complaintTime } |
|
|
|
]; |
|
|
|
|
|
|
|
/** Tab1导出 */ |
|
|
|
const handleExportTab1 = async () => { |
|
|
|
try { |
|
|
|
@ -409,11 +442,79 @@ const downloadBlob = (res: any, filename: string) => { |
|
|
|
<el-table-column label="被投诉对象" prop="complaintDepartment" min-width="160" :show-overflow-tooltip="true" /> |
|
|
|
<el-table-column label="投诉类型" prop="enforceTypeText" width="140" align="center" /> |
|
|
|
<el-table-column label="投诉时间" prop="complaintTime" width="170" align="center" /> |
|
|
|
<el-table-column label="操作" width="100" align="center" fixed="right"> |
|
|
|
<template #default="{ row }"> |
|
|
|
<el-button type="primary" link :underline="false" @click="handleShowComplaintDetail(row)">详情</el-button> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
<pagination v-show="detailTotal > 0" |
|
|
|
v-model:page="detailPageNum" v-model:limit="detailPageSize" |
|
|
|
:total="detailTotal" @pagination="handleDetailPageChange" /> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<!-- 投诉举报详情弹窗 --> |
|
|
|
<el-dialog v-model="complaintDetailVisible" title="投诉举报详情" width="680px" destroy-on-close append-to-body> |
|
|
|
<div v-loading="complaintDetailLoading"> |
|
|
|
<el-tabs v-model="complaintDetailTab"> |
|
|
|
<!-- 处置进度 --> |
|
|
|
<el-tab-pane label="处置进度" name="progress"> |
|
|
|
<el-timeline v-if="complaintHandleList.length > 0" class="complaint-timeline"> |
|
|
|
<el-timeline-item |
|
|
|
v-for="(item, index) in complaintHandleList" |
|
|
|
:key="index" |
|
|
|
:type="index === 0 ? 'primary' : 'success'" |
|
|
|
:hollow="index === 0" |
|
|
|
> |
|
|
|
<div class="timeline-title">{{ item.handleDepartment }}</div> |
|
|
|
<div class="timeline-row"><span class="timeline-label">处理部门:</span>{{ item.handleDepartment }}</div> |
|
|
|
<div class="timeline-row"><span class="timeline-label">处理意见:</span>{{ item.handleOpinion }}</div> |
|
|
|
<div class="timeline-row"><span class="timeline-label">处理时间:</span>{{ item.handleTime }}</div> |
|
|
|
</el-timeline-item> |
|
|
|
</el-timeline> |
|
|
|
<el-empty v-else description="暂无处置进度" /> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<!-- 投诉详情 --> |
|
|
|
<el-tab-pane label="投诉详情" name="info"> |
|
|
|
<el-descriptions |
|
|
|
v-if="complaintDetailData" |
|
|
|
:column="1" |
|
|
|
border |
|
|
|
:label-style="{ width: '120px', textAlign: 'right', backgroundColor: '#f5f7fa' }" |
|
|
|
> |
|
|
|
<el-descriptions-item label="投诉部门">{{ complaintDetailData.complaintDepartment || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="投诉时间">{{ complaintDetailData.complaintTime || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="投诉类型">{{ complaintDetailData.enforceTypeText || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="投诉内容">{{ complaintDetailData.complaintContent || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="涉事地址">{{ complaintDetailData.enterpriseAddress || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="附件"> |
|
|
|
<span v-if="complaintDetailData.attachment"> |
|
|
|
<el-link type="primary" :underline="false">{{ complaintDetailData.attachment }}</el-link> |
|
|
|
</span> |
|
|
|
<span v-else>-</span> |
|
|
|
</el-descriptions-item> |
|
|
|
<el-descriptions-item label="授权状态"> |
|
|
|
<el-checkbox |
|
|
|
:model-value="complaintDetailData.authStatus == 1" |
|
|
|
disabled |
|
|
|
>同意</el-checkbox> |
|
|
|
<el-checkbox |
|
|
|
:model-value="complaintDetailData.authStatus != 1" |
|
|
|
disabled |
|
|
|
>不同意</el-checkbox> |
|
|
|
</el-descriptions-item> |
|
|
|
<el-descriptions-item label="联系人">{{ complaintDetailData.contactPerson || '-' }}</el-descriptions-item> |
|
|
|
<el-descriptions-item label="联系电话">{{ complaintDetailData.contactPhone || '-' }}</el-descriptions-item> |
|
|
|
</el-descriptions> |
|
|
|
<el-empty v-else description="暂无详情数据" /> |
|
|
|
</el-tab-pane> |
|
|
|
</el-tabs> |
|
|
|
</div> |
|
|
|
<template #footer> |
|
|
|
<el-button @click="complaintDetailVisible = false">关闭</el-button> |
|
|
|
</template> |
|
|
|
</el-dialog> |
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
<!-- ==================== Tab2: 投诉类型统计 ==================== --> |
|
|
|
@ -494,4 +595,25 @@ const downloadBlob = (res: any, filename: string) => { |
|
|
|
</template> |
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
.complaint-timeline { |
|
|
|
padding: 16px 12px; |
|
|
|
|
|
|
|
.timeline-title { |
|
|
|
font-weight: 600; |
|
|
|
font-size: 15px; |
|
|
|
margin-bottom: 8px; |
|
|
|
color: #303133; |
|
|
|
} |
|
|
|
|
|
|
|
.timeline-row { |
|
|
|
font-size: 13px; |
|
|
|
color: #606266; |
|
|
|
line-height: 1.8; |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
|
|
|
|
.timeline-label { |
|
|
|
color: #909399; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|
|