| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- <template>
- <div class="app-container gzcb-page">
- <!-- 搜索区(若依风格) -->
- <div class="filter-panel">
- <el-form :inline="true" :model="searchForm" class="filter-form" label-width="80px">
- <el-form-item label="事件状态">
- <el-select v-model="searchForm.status" placeholder="请选择事件状态" clearable style="width:140px">
- <el-option v-for="d in urgeStatusOptions" :key="d.value" :label="d.label" :value="d.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="处置人">
- <el-input v-model="searchForm.handler" placeholder="请输入处置人" clearable style="width:140px" @keyup.enter="handleSearch" />
- </el-form-item>
- <el-form-item label="事件编号">
- <el-input v-model="searchForm.eventNo" placeholder="请输入事件编号" clearable style="width:160px" @keyup.enter="handleSearch" />
- </el-form-item>
- <el-form-item label="接报时间">
- <el-date-picker
- v-model="searchForm.dateRange"
- type="daterange"
- range-separator="至"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- style="width:240px"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
- <el-button :icon="Refresh" @click="handleReset">重置</el-button>
- </el-form-item>
- </el-form>
- </div>
- <!-- 数据表格 -->
- <div class="table-panel">
- <el-table :data="tableData" border stripe style="width:100%" v-loading="loading">
- <el-table-column prop="eventNo" label="事件编号" width="150" />
- <el-table-column prop="eventType" label="管网类型" width="100">
- <template #default="{ row }">{{ dictLabel(dis_event_type, row.eventType) }}</template>
- </el-table-column>
- <el-table-column prop="summary" label="事件摘要" min-width="160" show-overflow-tooltip />
- <el-table-column prop="department" label="责任单位" width="110">
- <template #default="{ row }">{{ row.department || '-' }}</template>
- </el-table-column>
- <el-table-column prop="receiver" label="目标接收人" width="100">
- <template #default="{ row }">{{ row.receiver || row.handler || '-' }}</template>
- </el-table-column>
- <el-table-column prop="receiverDept" label="接收部门" width="110">
- <template #default="{ row }">{{ row.receiverDept || row.department || '-' }}</template>
- </el-table-column>
- <el-table-column prop="elapsed" label="接报后已过" width="110">
- <template #default="{ row }">{{ row.elapsed || '-' }}</template>
- </el-table-column>
- <el-table-column prop="urgeCount" label="催办次数" width="90" align="center" />
- <el-table-column prop="lastUrgeTime" label="最近催办时间" width="150">
- <template #default="{ row }">{{ row.lastUrgeTime || '-' }}</template>
- </el-table-column>
- <el-table-column prop="createTime" label="创建时间" width="150" />
- <el-table-column prop="statusName" label="状态" width="90">
- <template #default="{ row }">
- <el-tag :type="statusTagType(row.status)" size="small">{{ row.statusName }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="操作" width="160" fixed="right">
- <template #default="{ row }">
- <el-button v-if="canUrge(row)" type="primary" plain size="small" @click="handleUrge(row)" v-hasPermi="['dispatch:event:urge']">催办</el-button>
- <el-button type="info" plain size="small" @click="handleViewRecords(row)">查看记录</el-button>
- </template>
- </el-table-column>
- </el-table>
- <div class="pagination-wrap">
- <el-pagination
- v-model:current-page="pagination.page"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 50]"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </div>
- <!-- 催办弹窗 -->
- <el-dialog v-model="urgeVisible" title="工作催办" width="600px" :close-on-click-modal="false">
- <el-form :model="urgeForm" :rules="urgeRules" ref="urgeFormRef" label-width="100px">
- <div class="section-title">事件信息</div>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="事件编号">{{ urgeForm.eventNo }}</el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="管网类型">{{ dictLabel(dis_event_type, urgeForm.eventType) }}</el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="当前状态">
- <el-tag :type="statusTagType(urgeForm.status)" size="small">{{ urgeForm.statusName || '-' }}</el-tag>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="接报后已过">{{ urgeForm.elapsed || '-' }}</el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="事件摘要">
- <div class="desc-text">{{ urgeForm.summary || '-' }}</div>
- </el-form-item>
- <div class="section-title">接收人信息</div>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="姓名">{{ urgeForm.receiver || '-' }}</el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="部门">{{ urgeForm.receiverDept || '-' }}</el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="处置人电话">
- <span v-if="urgeForm.receiverPhone" style="color:#2f6fe4;font-weight:600;font-size:14px">{{ urgeForm.receiverPhone }}</span>
- <span v-else style="color:#c0c4cc;font-size:13px">处置人未维护联系电话,请改用电话/短信以外的催办方式</span>
- </el-form-item>
- <div class="section-title">催办内容</div>
- <el-form-item label="催办方式" prop="methods">
- <el-checkbox-group v-model="urgeForm.methods">
- <el-checkbox v-for="d in dis_event_urge_method" :key="d.value" :label="d.label" />
- </el-checkbox-group>
- </el-form-item>
- <el-form-item label="催办内容" prop="content">
- <el-input v-model="urgeForm.content" type="textarea" :rows="4" placeholder="请输入催办内容" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="urgeVisible = false">取消</el-button>
- <el-button type="primary" @click="confirmUrge">发送催办</el-button>
- </template>
- </el-dialog>
- <!-- 查看记录弹窗 -->
- <el-drawer v-model="recordsVisible" title="催办记录" size="700px" :close-on-click-modal="false" class="detail-drawer" direction="rtl">
- <div v-if="currentRow">
- <el-form label-width="100px" size="default" style="margin-bottom:12px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="事件编号">{{ currentRow.eventNo }}</el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="责任单位">{{ currentRow.department || '-' }}</el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="事件摘要">
- <div class="desc-text">{{ currentRow.summary || '-' }}</div>
- </el-form-item>
- </el-form>
- <el-table :data="currentRow.records" border stripe style="width:100%">
- <el-table-column prop="urgeTime" label="催办时间" width="150" />
- <el-table-column prop="method" label="催办方式" width="100" />
- <el-table-column prop="receiver" label="目标接收人" width="90">
- <template #default="{ row }">{{ row.receiver || '-' }}</template>
- </el-table-column>
- <el-table-column prop="content" label="催办内容" show-overflow-tooltip />
- <el-table-column prop="result" label="结果" width="90">
- <template #default="{ row }">
- <el-tag :type="row.result === '已反馈' ? 'success' : 'info'" size="small">{{ row.result }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <template #footer>
- <el-button @click="recordsVisible = false">关闭</el-button>
- </template>
- </el-drawer>
- </div>
- </template>
- <script setup name="Gzcb">
- import { ref, nextTick, onMounted } from 'vue'
- import { ElMessage } from 'element-plus'
- import { useDict } from '@/utils/dict'
- import { getEventUrgePage, urgeEvent, getEventLogs, getEventStatusOptions } from '@/api/dispatch'
- import { Search, Refresh } from '@element-plus/icons-vue'
- // ==================== 字典 ====================
- const { dis_event_urge_method, dis_event_urge_result, dis_event_type } = useDict('dis_event_urge_method', 'dis_event_urge_result', 'dis_event_type')
- function dictLabel(list, value) {
- if (value === null || value === undefined || value === '') return '-'
- const hit = (list || []).find(item => String(item.value) === String(value) || item.label === value)
- return hit ? hit.label : value
- }
- // 多选方式以「、」连接存储,回显时逐个翻译
- function methodLabel(value) {
- if (!value) return '-'
- return String(value).split('、').map(item => dictLabel(dis_event_urge_method.value, item)).join('、')
- }
- // 工作催办只面向已核实、处置中事件。
- const urgeStatusOptions = ref([])
- async function loadStatusOptions() {
- try {
- const res = await getEventStatusOptions()
- urgeStatusOptions.value = (res.data || []).filter(item => [1, 2].includes(item.value))
- } catch {
- urgeStatusOptions.value = []
- }
- }
- // 状态码 -> 标签样式(0 待核实 1 已核实 2 处置中 3 已解除 4 不实事件)
- const STATUS_TAG = { 0: 'warning', 1: 'success', 2: 'primary', 3: 'warning', 4: 'info' }
- function statusTagType(status) {
- return STATUS_TAG[status] || 'info'
- }
- function canUrge(row) {
- return [1, 2].includes(row.status)
- }
- // ==================== 数据状态 ====================
- const tableData = ref([])
- const total = ref(0)
- const loading = ref(false)
- const searchForm = ref({ status: '', handler: '', eventNo: '', dateRange: null })
- const pagination = ref({ page: 1, pageSize: 10 })
- // ==================== 加载数据 ====================
- async function loadData() {
- loading.value = true
- try {
- const params = {}
- if (searchForm.value.status !== '' && searchForm.value.status !== null) params.status = searchForm.value.status
- if (searchForm.value.handler) params.handler = searchForm.value.handler
- if (searchForm.value.eventNo) params.eventNo = searchForm.value.eventNo
- if (searchForm.value.dateRange && searchForm.value.dateRange.length === 2) {
- params.startTime = searchForm.value.dateRange[0]
- params.endTime = searchForm.value.dateRange[1]
- }
- const res = await getEventUrgePage(pagination.value.page, pagination.value.pageSize, params)
- tableData.value = res.data?.rows || res.data?.records || res.data || []
- total.value = res.data?.total || 0
- } catch (error) {
- ElMessage.error('加载数据失败:' + (error.message || '未知错误'))
- } finally {
- loading.value = false
- }
- }
- onMounted(() => {
- loadStatusOptions()
- loadData()
- })
- // ==================== 搜索筛选 ====================
- function handleSearch() {
- pagination.value.page = 1
- loadData()
- }
- function handleReset() {
- searchForm.value = { status: '', handler: '', eventNo: '', dateRange: null }
- pagination.value.page = 1
- loadData()
- }
- // ==================== 分页 ====================
- function handleSizeChange(val) {
- pagination.value.pageSize = val
- pagination.value.page = 1
- loadData()
- }
- function handleCurrentChange(val) {
- pagination.value.page = val
- loadData()
- }
- // ==================== 催办 ====================
- const urgeVisible = ref(false)
- const urgeFormRef = ref(null)
- const currentUrgeId = ref(null)
- const urgeForm = ref({ eventNo: '', eventType: '', status: null, statusName: '', elapsed: '', summary: '', receiver: '', receiverDept: '', receiverPhone: '', methods: [], content: '' })
- const urgeRules = {
- methods: [{ required: true, message: '请选择催办方式', trigger: 'change', type: 'array' }],
- content: [{ required: true, message: '请输入催办内容', trigger: 'blur' }]
- }
- function handleUrge(row) {
- currentUrgeId.value = row.eventId
- urgeForm.value = {
- eventNo: row.eventNo,
- eventType: row.eventType,
- status: row.status,
- statusName: row.statusName || '',
- elapsed: row.elapsed || '',
- summary: row.summary || '',
- receiver: row.receiver || row.handler || '',
- receiverDept: row.receiverDept || row.department || '',
- // 电话取事件责任处置人的电话(初判核实录入),无则回退最近催办记录里的号码
- receiverPhone: row.handlerPhone || row.receiverPhone || '',
- // 默认勾选「系统消息」:发送后给处置人推一条站内催办消息
- methods: ['系统消息'],
- content: '关于【' + (row.summary || '') + '】的处置进度,请尽快反馈处理情况。'
- }
- urgeVisible.value = true
- nextTick(() => urgeFormRef.value?.clearValidate())
- }
- async function confirmUrge() {
- try {
- await urgeFormRef.value.validate()
- } catch {
- return
- }
- try {
- await urgeEvent({
- eventId: currentUrgeId.value,
- receiver: urgeForm.value.receiver,
- receiverDept: urgeForm.value.receiverDept,
- receiverPhone: urgeForm.value.receiverPhone,
- method: urgeForm.value.methods.join('、'),
- operDesc: urgeForm.value.content
- })
- ElMessage.success('催办已发送')
- urgeVisible.value = false
- loadData()
- } catch (error) {
- ElMessage.error('催办失败:' + (error.message || '未知错误'))
- }
- }
- // ==================== 查看记录 ====================
- const recordsVisible = ref(false)
- const currentRow = ref(null)
- async function handleViewRecords(row) {
- currentRow.value = { ...row, records: [] }
- recordsVisible.value = true
- // 催办记录就是该事件 operType=8 的操作日志
- try {
- const res = await getEventLogs(row.eventId, 8)
- currentRow.value = {
- ...row,
- records: (res.data || []).map(log => ({
- urgeTime: log.operTime,
- method: methodLabel(log.method),
- receiver: log.receiver || '',
- content: log.operDesc,
- result: dictLabel(dis_event_urge_result.value, log.urgeResult)
- }))
- }
- } catch {
- // 加载失败时保留空记录列表
- }
- }
- </script>
- <style scoped>
- .gzcb-page {
- padding: 16px;
- background: #f5f5f5;
- min-height: calc(100vh - 84px);
- }
- .filter-panel {
- background: #fff;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- padding: 12px 16px;
- margin-bottom: 12px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- flex-wrap: wrap;
- gap: 12px;
- }
- .filter-form {
- display: flex;
- align-items: center;
- gap: 0 12px;
- flex-wrap: wrap;
- }
- /* 若依风格查询栏:内联表单项去默认外边距,间距统一交给 gap */
- .filter-form :deep(.el-form-item) {
- margin-right: 0;
- margin-bottom: 0;
- }
- .table-panel {
- background: #fff;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- padding: 16px;
- }
- .pagination-wrap {
- margin-top: 16px;
- display: flex;
- justify-content: flex-end;
- }
- .section-title {
- font-size: 14px;
- font-weight: 600;
- color: #303133;
- margin-bottom: 12px;
- padding-left: 8px;
- border-left: 3px solid #409EFF;
- }
- :deep(.el-form-item__label) {
- color: #909399;
- }
- :deep(.el-form-item__content) {
- color: #303133;
- }
- </style>
|