Ver Fonte

fix:应急bug修改

null há 3 semanas atrás
pai
commit
90f13e5db2

+ 79 - 0
src/api/dispatch.js

@@ -172,6 +172,43 @@ export function deleteEventPlan(id) {
   return request({ url: '/api/dispatch/plan/deleteById', method: 'delete', params: { id } })
 }
 
+// ============ 应急事件数据查询与统计 ============
+export function getEventRecordPage(pageNum, pageSize, params) {
+  return request({ url: '/api/dispatch/event-record/findByPage', method: 'get', params: { pageNum, pageSize, ...params } })
+}
+export function getEventRecordStats(params) {
+  return request({ url: '/api/dispatch/event-record/stats', method: 'get', params })
+}
+export function getEventRecordById(id) {
+  return request({ url: '/api/dispatch/event-record/getById/' + id, method: 'get' })
+}
+export function addEventRecord(data) {
+  return request({ url: '/api/dispatch/event-record/save', method: 'post', data })
+}
+export function updateEventRecord(data) {
+  return request({ url: '/api/dispatch/event-record/updateById', method: 'put', data })
+}
+export function deleteEventRecord(id) {
+  return request({ url: '/api/dispatch/event-record/deleteById', method: 'delete', params: { id } })
+}
+
+// ============ 数字预案库匹配(应急预案选择) ============
+export function getPlanLibraryList() {
+  return request({ url: '/api/dispatch/plan-library/list', method: 'get' })
+}
+export function matchPlan(data) {
+  return request({ url: '/api/dispatch/plan-library/match', method: 'post', data })
+}
+export function matchPlanByTopic(data) {
+  return request({ url: '/api/dispatch/plan-library/matchByTopic', method: 'post', data })
+}
+export function getPlanMatchHistory(limit = 10) {
+  return request({ url: '/api/dispatch/plan-library/history', method: 'get', params: { limit } })
+}
+export function applyPlan(data) {
+  return request({ url: '/api/dispatch/plan-library/apply', method: 'post', data })
+}
+
 // ============ 应急预案审批 ============
 export function getPlanApprovalPage(pageNum, pageSize, params) {
   return request({ url: '/api/dispatch/plan-approval/findByPage', method: 'get', params: { pageNum, pageSize, ...params } })
@@ -197,3 +234,45 @@ export function publishPlan(id) {
 export function getApprovalSteps(approvalId) {
   return request({ url: '/api/dispatch/plan-approval-step/listByApprovalId', method: 'get', params: { approvalId } })
 }
+
+// ============ 应急事件统一档案(全生命周期闭环) ============
+// 接报 -> 受理 -> 核实 -> 转接/报送 -> 跟踪/催办 -> 解除 -> 关闭
+export function getEventPage(pageNum, pageSize, params) {
+  return request({ url: '/api/dispatch/event/findByPage', method: 'get', params: { pageNum, pageSize, ...params } })
+}
+export function getEventDetail(id) {
+  return request({ url: '/api/dispatch/event/getDetail/' + id, method: 'get' })
+}
+export function getEventStats(params) {
+  return request({ url: '/api/dispatch/event/stats', method: 'get', params })
+}
+export function saveEventReport(data) {
+  return request({ url: '/api/dispatch/event/saveReport', method: 'post', data })
+}
+export function acceptEvent(id) {
+  return request({ url: '/api/dispatch/event/accept', method: 'post', data: { id } })
+}
+export function verifyEventInfo(data) {
+  return request({ url: '/api/dispatch/event/verify', method: 'post', data })
+}
+export function transferEvent(data) {
+  return request({ url: '/api/dispatch/event/transfer', method: 'post', data })
+}
+export function reportEvent(data) {
+  return request({ url: '/api/dispatch/event/report', method: 'post', data })
+}
+export function trackEvent(data) {
+  return request({ url: '/api/dispatch/event/track', method: 'post', data })
+}
+export function releaseEventInfo(id) {
+  return request({ url: '/api/dispatch/event/release', method: 'post', data: { id } })
+}
+export function closeEventInfo(data) {
+  return request({ url: '/api/dispatch/event/close', method: 'post', data })
+}
+export function updateEventInfo(data) {
+  return request({ url: '/api/dispatch/event/updateById', method: 'put', data })
+}
+export function deleteEventInfo(id) {
+  return request({ url: '/api/dispatch/event/deleteById', method: 'delete', params: { id } })
+}

+ 217 - 81
src/views/subSystem/dispatch/disAssess/DisInquiry.vue

@@ -57,11 +57,11 @@
             <div class="stat-label">事件总数</div>
           </div>
           <div class="stat-card stat-card-warning">
-            <div class="stat-value">{{ stats.totalLoss }}</div>
+            <div class="stat-value">{{ formatLoss(stats.totalLoss) }}</div>
             <div class="stat-label">直接经济损失(万元)</div>
           </div>
           <div class="stat-card stat-card-info">
-            <div class="stat-value">{{ stats.avgLoss }}</div>
+            <div class="stat-value">{{ formatLoss(stats.avgLoss) }}</div>
             <div class="stat-label">平均损失(万元)</div>
           </div>
           <div class="stat-card stat-card-danger">
@@ -73,43 +73,103 @@
         <!-- 事件列表表格 -->
         <el-card shadow="hover">
           <template #header>
-            <div class="panel-title">事件列表 <span class="total-count">共{{ filteredData.length }}条数据</span></div>
+            <div class="panel-title">事件列表 <span class="total-count">共{{ total }}条数据</span>
+              <el-button type="primary" size="small" style="margin-left:auto" @click="openAdd">新增事件</el-button>
+            </div>
           </template>
-          <el-table :data="pagedData" border stripe style="width: 100%" size="default">
-            <el-table-column prop="name" label="事件名称" min-width="180" show-overflow-tooltip />
-            <el-table-column prop="type" label="类型" width="120" />
-            <el-table-column prop="time" label="时间" width="140" />
+          <el-table :data="tableData" border stripe style="width: 100%" size="default">
+            <el-table-column prop="eventName" label="事件名称" min-width="180" show-overflow-tooltip />
+            <el-table-column prop="eventType" label="类型" width="100" />
+            <el-table-column prop="happenTime" label="发生时间" width="160" />
             <el-table-column prop="level" label="等级" width="100">
               <template #default="{ row }">
                 <el-tag :type="levelTagType(row.level)" size="small" effect="dark">{{ row.level }}</el-tag>
               </template>
             </el-table-column>
-            <el-table-column prop="region" label="地域" width="110" />
-            <el-table-column prop="department" label="责任部门" width="130" />
-            <el-table-column prop="loss" label="损失(万元)" width="110" align="right" />
+            <el-table-column prop="region" label="地域" width="90" />
+            <el-table-column prop="department" label="责任部门" width="110" />
+            <el-table-column prop="status" label="状态" width="90">
+              <template #default="{ row }">
+                <el-tag :type="statusTagType(row.status)" size="small">{{ row.status }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="损失(万元)" width="110" align="right">
+              <template #default="{ row }">
+                {{ formatLoss(row.lossAmount) }}
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="140" align="center">
+              <template #default="{ row }">
+                <el-button link type="primary" @click="openEdit(row)">编辑</el-button>
+                <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
+              </template>
+            </el-table-column>
           </el-table>
           <el-pagination
             v-model:current-page="pageNum"
             v-model:page-size="pageSize"
-            :total="filteredData.length"
+            :total="total"
             layout="total, prev, pager, next, sizes"
             :page-sizes="[10, 20, 50]"
             style="margin-top: 16px; justify-content: flex-end"
+            @current-change="loadData"
+            @size-change="handleSizeChange"
           />
         </el-card>
       </div>
     </div>
+
+    <!-- 新增/编辑弹窗 -->
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px" destroy-on-close>
+      <el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
+        <el-form-item label="事件名称" prop="eventName">
+          <el-input v-model="form.eventName" placeholder="请输入事件名称" />
+        </el-form-item>
+        <el-form-item label="事件类型" prop="eventType">
+          <el-select v-model="form.eventType" placeholder="请选择" style="width:100%">
+            <el-option v-for="item in eventTypeOptions.filter(o => o !== '全部')" :key="item" :label="item" :value="item" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="发生时间" prop="eventTime">
+          <el-date-picker v-model="form.eventTime" type="date" value-format="YYYY-MM-DD" style="width:100%" />
+        </el-form-item>
+        <el-form-item label="事件等级" prop="eventLevel">
+          <el-select v-model="form.eventLevel" placeholder="请选择" style="width:100%">
+            <el-option v-for="item in eventLevelOptions.filter(o => o !== '全部')" :key="item" :label="item" :value="item" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="地域" prop="region">
+          <el-select v-model="form.region" placeholder="请选择" style="width:100%">
+            <el-option v-for="item in regionOptions.filter(o => o !== '全部')" :key="item" :label="item" :value="item" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="责任部门" prop="department">
+          <el-select v-model="form.department" placeholder="请选择" style="width:100%">
+            <el-option v-for="item in departmentOptions.filter(o => o !== '全部')" :key="item" :label="item" :value="item" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="损失(万元)" prop="lossAmount">
+          <el-input-number v-model="form.lossAmount" :min="0" :precision="2" style="width:100%" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitForm">确定</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, computed } from 'vue'
+import { ref, reactive } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getEventPage, getEventStats, saveEventReport, updateEventInfo, deleteEventInfo } from '@/api/dispatch'
 
-// 查询条件选项
-const eventTypeOptions = ['全部', '自然灾害', '事故灾难', '公共卫生', '社会安全', '管网泄漏', '管道堵塞']
+// 查询条件选项(与应急预案选择/统一事件口径一致)
+const eventTypeOptions = ['全部', '排水', '供水', '燃气', '其他']
 const eventLevelOptions = ['全部', '一般', '较大', '重大', '特别重大']
-const regionOptions = ['全部', '太常片区', '城东片区', '城南片区', '城北片区']
-const departmentOptions = ['全部', '应急管理局', '消防救援局', '市政管理局', '水务局']
+const regionOptions = ['全部', '城南', '城北', '太常']
+const departmentOptions = ['全部', '供水局', '燃气公司', '排水公司']
 const lossRangeOptions = ['全部', '100万以下', '100-500万', '500-1000万', '1000万以上']
 
 // 查询表单
@@ -122,77 +182,136 @@ const queryForm = reactive({
   lossRange: ''
 })
 
-// Mock 数据
-const allData = ref([
-  { id: 1, name: '太常片区暴雨内涝事件', type: '自然灾害', time: '2025-06-15', level: '重大', region: '太常片区', department: '应急管理局', loss: 860 },
-  { id: 2, name: '城东主管道泄漏事故', type: '管网泄漏', time: '2025-05-22', level: '较大', region: '城东片区', department: '水务局', loss: 320 },
-  { id: 3, name: '城南化工厂氯气泄漏', type: '事故灾难', time: '2025-04-10', level: '特别重大', region: '城南片区', department: '消防救援局', loss: 1580 },
-  { id: 4, name: '城北管道堵塞溢流', type: '管道堵塞', time: '2025-07-03', level: '一般', region: '城北片区', department: '市政管理局', loss: 45 },
-  { id: 5, name: '太常片区燃气管道破裂', type: '管网泄漏', time: '2025-03-18', level: '重大', region: '太常片区', department: '应急管理局', loss: 720 },
-  { id: 6, name: '城东餐饮食物中毒', type: '公共卫生', time: '2025-08-01', level: '较大', region: '城东片区', department: '应急管理局', loss: 180 },
-  { id: 7, name: '城南地铁施工坍塌', type: '事故灾难', time: '2025-02-14', level: '重大', region: '城南片区', department: '消防救援局', loss: 950 },
-  { id: 8, name: '城北片区群体性事件', type: '社会安全', time: '2025-09-20', level: '一般', region: '城北片区', department: '应急管理局', loss: 60 },
-  { id: 9, name: '太常片区排水管网堵塞', type: '管道堵塞', time: '2025-05-08', level: '较大', region: '太常片区', department: '市政管理局', loss: 260 },
-  { id: 10, name: '城东供水主管爆裂', type: '管网泄漏', time: '2025-01-25', level: '特别重大', region: '城东片区', department: '水务局', loss: 2100 },
-  { id: 11, name: '城南片区暴雨内涝', type: '自然灾害', time: '2025-07-18', level: '较大', region: '城南片区', department: '应急管理局', loss: 480 },
-  { id: 12, name: '城北燃气泄漏事故', type: '管网泄漏', time: '2025-04-28', level: '一般', region: '城北片区', department: '消防救援局', loss: 88 },
-  { id: 13, name: '太常片区路面塌陷', type: '事故灾难', time: '2025-06-30', level: '重大', region: '太常片区', department: '市政管理局', loss: 680 },
-  { id: 14, name: '城东排水管道堵塞', type: '管道堵塞', time: '2025-03-05', level: '一般', region: '城东片区', department: '水务局', loss: 35 },
-  { id: 15, name: '城南供水管网破裂', type: '管网泄漏', time: '2025-08-12', level: '重大', region: '城南片区', department: '水务局', loss: 780 },
-  { id: 16, name: '城北片区洪涝灾害', type: '自然灾害', time: '2025-09-05', level: '特别重大', region: '城北片区', department: '应急管理局', loss: 1850 }
-])
-
-// 分页
+// 列表数据(接口分页)
+const tableData = ref([])
+const total = ref(0)
 const pageNum = ref(1)
 const pageSize = ref(10)
 
-// 根据条件筛选
-const filteredData = computed(() => {
-  let data = [...allData.value]
-  if (queryForm.eventType && queryForm.eventType !== '全部') {
-    data = data.filter(d => d.type === queryForm.eventType)
-  }
-  if (queryForm.eventTime) {
-    data = data.filter(d => d.time === queryForm.eventTime)
-  }
-  if (queryForm.eventLevel && queryForm.eventLevel !== '全部') {
-    data = data.filter(d => d.level === queryForm.eventLevel)
-  }
-  if (queryForm.region && queryForm.region !== '全部') {
-    data = data.filter(d => d.region === queryForm.region)
-  }
-  if (queryForm.department && queryForm.department !== '全部') {
-    data = data.filter(d => d.department === queryForm.department)
-  }
-  if (queryForm.lossRange && queryForm.lossRange !== '全部') {
-    data = data.filter(d => {
-      switch (queryForm.lossRange) {
-        case '100万以下': return d.loss < 100
-        case '100-500万': return d.loss >= 100 && d.loss < 500
-        case '500-1000万': return d.loss >= 500 && d.loss < 1000
-        case '1000万以上': return d.loss >= 1000
-        default: return true
+// 统计数据(接口计算)
+const stats = ref({ totalEvents: 0, totalLoss: 0, avgLoss: 0, majorEvents: 0 })
+
+// 新增/编辑弹窗状态
+const dialogVisible = ref(false)
+const dialogTitle = ref('')
+const formRef = ref(null)
+const form = reactive({ id: null, eventName: '', eventType: '', eventTime: '', eventLevel: '', region: '', department: '', lossAmount: undefined })
+
+const formRules = {
+  eventName: [{ required: true, message: '请输入事件名称', trigger: 'blur' }],
+  eventType: [{ required: true, message: '请选择事件类型', trigger: 'change' }],
+  eventTime: [{ required: true, message: '请选择发生时间', trigger: 'change' }],
+  eventLevel: [{ required: true, message: '请选择事件等级', trigger: 'change' }],
+  region: [{ required: true, message: '请选择地域', trigger: 'change' }],
+  department: [{ required: true, message: '请选择责任部门', trigger: 'change' }],
+  lossAmount: [{ required: true, message: '请输入损失金额', trigger: 'blur' }]
+}
+
+// 损失金额格式化(保留2位小数)
+const formatLoss = (val) => {
+  const num = Number(val)
+  return isNaN(num) ? '-' : num.toFixed(2)
+}
+
+// 打开新增
+const openAdd = () => {
+  Object.assign(form, { id: null, eventName: '', eventType: '', eventTime: '', eventLevel: '', region: '', department: '', lossAmount: undefined })
+  dialogTitle.value = '新增事件记录'
+  dialogVisible.value = true
+}
+
+// 打开编辑
+const openEdit = (row) => {
+  Object.assign(form, {
+    id: row.id,
+    eventName: row.eventName,
+    eventType: row.eventType,
+    eventTime: row.happenTime ? String(row.happenTime).slice(0, 10) : '',
+    eventLevel: row.level,
+    region: row.region,
+    department: row.department,
+    lossAmount: Number(row.lossAmount)
+  })
+  dialogTitle.value = '编辑事件记录'
+  dialogVisible.value = true
+}
+
+// 提交新增/修改(统一事件:新增即入主表参与闭环流转)
+const submitForm = () => {
+  formRef.value.validate(async (valid) => {
+    if (!valid) return
+    const payload = {
+      eventName: form.eventName,
+      eventType: form.eventType,
+      happenTime: form.eventTime ? form.eventTime + ' 00:00:00' : null,
+      level: form.eventLevel,
+      region: form.region,
+      department: form.department,
+      lossAmount: form.lossAmount
+    }
+    try {
+      if (form.id) {
+        await updateEventInfo({ id: form.id, ...payload })
+        ElMessage.success('修改成功')
+      } else {
+        await saveEventReport(payload)
+        ElMessage.success('新增成功')
       }
-    })
-  }
-  return data
-})
+      dialogVisible.value = false
+      loadData()
+    } catch (e) {
+      ElMessage.error(form.id ? '修改失败' : '新增失败')
+    }
+  })
+}
 
-// 分页后数据
-const pagedData = computed(() => {
-  const start = (pageNum.value - 1) * pageSize.value
-  return filteredData.value.slice(start, start + pageSize.value)
-})
+// 删除
+const handleDelete = (row) => {
+  ElMessageBox.confirm(`确定删除事件「${row.eventName}」吗?`, '删除确认', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    try {
+      await deleteEventInfo(row.id)
+      ElMessage.success('删除成功')
+      loadData()
+    } catch (e) {
+      ElMessage.error('删除失败')
+    }
+  }).catch(() => {})
+}
 
-// 统计数据
-const stats = computed(() => {
-  const data = filteredData.value
-  const totalEvents = data.length
-  const totalLoss = data.reduce((sum, d) => sum + d.loss, 0)
-  const avgLoss = totalEvents > 0 ? (totalLoss / totalEvents).toFixed(1) : 0
-  const majorEvents = data.filter(d => d.level === '重大' || d.level === '特别重大').length
-  return { totalEvents, totalLoss, avgLoss, majorEvents }
-})
+// 构建查询参数(空值与'全部'不传)
+const buildParams = () => {
+  const params = {}
+  if (queryForm.eventType && queryForm.eventType !== '全部') params.eventType = queryForm.eventType
+  if (queryForm.eventTime) {
+    params.startDate = queryForm.eventTime
+    params.endDate = queryForm.eventTime
+  }
+  if (queryForm.eventLevel && queryForm.eventLevel !== '全部') params.level = queryForm.eventLevel
+  if (queryForm.region && queryForm.region !== '全部') params.region = queryForm.region
+  if (queryForm.department && queryForm.department !== '全部') params.department = queryForm.department
+  if (queryForm.lossRange && queryForm.lossRange !== '全部') params.lossRange = queryForm.lossRange
+  return params
+}
+
+// 加载列表与统计(并行请求)
+const loadData = async () => {
+  try {
+    const params = buildParams()
+    const [pageRes, statsRes] = await Promise.all([
+      getEventPage(pageNum.value, pageSize.value, params),
+      getEventStats(params)
+    ])
+    tableData.value = pageRes.data?.records || []
+    total.value = pageRes.data?.total || 0
+    stats.value = statsRes.data || { totalEvents: 0, totalLoss: 0, avgLoss: 0, majorEvents: 0 }
+  } catch (e) {
+    ElMessage.error('查询失败')
+  }
+}
 
 // 等级tag颜色
 const levelTagType = (level) => {
@@ -200,9 +319,22 @@ const levelTagType = (level) => {
   return map[level] || 'info'
 }
 
+// 状态tag颜色
+const statusTagType = (status) => {
+  const map = { '待受理': 'warning', '待核实': 'warning', '已核实': 'primary', '处置中': 'primary', '已解除': 'warning', '已关闭': 'success', '不实事件': 'info' }
+  return map[status] || 'info'
+}
+
 // 查询
 const handleQuery = () => {
   pageNum.value = 1
+  loadData()
+}
+
+// 每页条数变化
+const handleSizeChange = () => {
+  pageNum.value = 1
+  loadData()
 }
 
 // 重置
@@ -211,7 +343,11 @@ const handleReset = () => {
     eventType: '', eventTime: '', eventLevel: '', region: '', department: '', lossRange: ''
   })
   pageNum.value = 1
+  loadData()
 }
+
+// 初始化查询
+loadData()
 </script>
 
 <style scoped lang="scss">

+ 80 - 73
src/views/subSystem/dispatch/disDecisionDep/DisPlanSelection.vue

@@ -213,55 +213,36 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed } from 'vue'
+import { ref, reactive } from 'vue'
 import { ElMessage } from 'element-plus'
 import { Setting, InfoFilled, Clock, Promotion, Document, Checked, Search } from '@element-plus/icons-vue'
+import { matchPlan, matchPlanByTopic, getPlanMatchHistory, applyPlan as applyPlanApi } from '@/api/dispatch'
 
-// 下拉选项
-const eventTypeOptions = ['管道泄漏', '管网爆管', '第三方破坏', '路面塌陷', '火灾']
+// 下拉选项(排水/供水/燃气 三类规划)
+const eventTypeOptions = ['排水', '供水', '燃气']
 const eventLevelOptions = ['一般(IV级)', '较大(III级)', '重大(II级)', '特别重大(I级)']
-const eventRegionOptions = ['城东管网区', '城南管网区', '城北管网区', '城西管网区']
-const unitOptions = ['县供水集团', '市燃气集团', '区排水公司']
+const eventRegionOptions = ['城南', '城北', '太常']
+const unitOptions = ['供水局', '燃气公司', '排水公司']
 
 // 表单
 const form = reactive({
-  eventType: '管道泄漏',
+  eventType: '排水',
   eventLevel: '较大(III级)',
-  eventRegion: '城东管网区',
-  responsibleUnit: '市燃气集团'
+  eventRegion: '城',
+  responsibleUnit: '排水公司'
 })
 
-// 数字预案库
-const digitalPlanLibrary = ref([
-  { id: 'P001', name: '城东燃气管网泄漏应急预案', type: '管道泄漏', level: '较大(III级)', region: '城东管网区', unit: '市燃气集团', score: 95, content: '立即关闭上下游阀门,启动应急疏散,调集抢修车组,联动消防。专题:燃气泄漏专题', summary: '针对城东燃气管网泄漏的应急处置方案,涵盖阀门控制、疏散、消防联动等步骤。' },
-  { id: 'P002', name: '城南供水管网爆管抢修预案', type: '管网爆管', level: '重大(II级)', region: '城南管网区', unit: '县供水集团', score: 92, content: '隔离爆管区域,启用备用水源,组织抢修班组,发布停水公告。专题:供水爆管专题', summary: '城南区域供水管网爆管处置流程,包括区域隔离、备用水源调度和抢修组织。' },
-  { id: 'P003', name: '第三方破坏应急联动预案', type: '第三方破坏', level: '一般(IV级)', region: '城西管网区', unit: '区排水公司', score: 88, content: '制止施工,评估破坏程度,快速修复,责任认定。专题:第三方施工破坏', summary: '针对第三方施工破坏管网的应急处置,涵盖制止施工、评估修复及责任认定。' },
-  { id: 'P004', name: '城北燃气重大泄漏预案', type: '管道泄漏', level: '特别重大(I级)', region: '城北管网区', unit: '市燃气集团', score: 96, content: '区域交通管制,全方面稀释,紧急疏散周边居民。专题:燃气泄漏专题', summary: '城北枢纽区特别重大燃气泄漏处置方案,含交通管制、疏散及稀释措施。' },
-  { id: 'P005', name: '中心城区防汛排涝应急预案', type: '路面塌陷', level: '较大(III级)', region: '城南管网区', unit: '区排水公司', score: 85, content: '启动排涝泵站,布防沙袋,应急抽水组待命。专题:防汛排涝专题', summary: '中心城区防汛排涝预案,涉及排涝泵站、沙袋布防和应急抽水调度。' },
-  { id: 'P006', name: '供热管道故障处置预案', type: '管道泄漏', level: '一般(IV级)', region: '城西管网区', unit: '县供水集团', score: 82, content: '隔离故障段,启动备用热源,入户安抚。专题:供热故障专题', summary: '供热管道泄漏故障的处置方案,含故障隔离、备用热源启动及入户安抚。' },
-  { id: 'P007', name: '电力管廊事故紧急处置预案', type: '第三方破坏', level: '重大(II级)', region: '城南管网区', unit: '区排水公司', score: 87, content: '切断电源,组织电缆抢修,应急供电车保障。专题:电力管廊事故', summary: '电力管廊事故应急处置,涵盖断电、电缆抢修和应急供电车调度。' },
-  { id: 'P008', name: '通信光缆中断抢修预案', type: '路面塌陷', level: '一般(IV级)', region: '城东管网区', unit: '区排水公司', score: 80, content: '启用备用路由,光缆熔接抢修,协调运营商。专题:通信光缆中断', summary: '通信光缆中断抢修方案,涉及备用路由启用、光缆熔接及运营商协调。' },
-  { id: 'P009', name: '火灾应急处置预案', type: '火灾', level: '重大(II级)', region: '城北管网区', unit: '市燃气集团', score: 91, content: '启动消防联动,现场灭火,疏散周边人员,设置警戒区。专题:火灾专题', summary: '火灾事故应急处置方案,包含消防联动、人员疏散和警戒区设置。' },
-  { id: 'P010', name: '城南火灾联动应急方案', type: '火灾', level: '较大(III级)', region: '城南管网区', unit: '区排水公司', score: 84, content: '调集消防力量,控制火势蔓延,保护周边管网设施。专题:火灾专题', summary: '城南区域火灾联动方案,侧重火势控制与管网设施保护。' }
-])
+// 数字预案库由后端接口维护(dis_plan_library 表)
 
-// 专题列表
+// 专题列表(对应三大类)
 const topics = ref([
-  { label: '燃气泄漏专题', value: '燃气泄漏专题' },
-  { label: '供水爆管专题', value: '供水爆管专题' },
-  { label: '防汛排涝专题', value: '防汛排涝专题' },
-  { label: '供热故障专题', value: '供热故障专题' },
-  { label: '电力管廊事故', value: '电力管廊事故' },
-  { label: '通信光缆中断', value: '通信光缆中断' }
+  { label: '排水专题', value: '排水专题' },
+  { label: '供水专题', value: '供水专题' },
+  { label: '燃气专题', value: '燃气专题' }
 ])
 
-// 最近匹配记录
-const matchHistory = ref([
-  { id: 1, date: '2025-06-18', desc: '城东泄漏', planName: '城东燃气管网泄漏应急预案' },
-  { id: 2, date: '2025-06-15', desc: '城南爆管', planName: '供水管网爆管抢修预案' },
-  { id: 3, date: '2025-06-10', desc: '第三方破坏', planName: '第三方施工破坏应急方案' },
-  { id: 4, date: '2025-06-05', desc: '城北火灾', planName: '火灾应急处置预案' }
-])
+// 最近匹配记录(接口加载)
+const matchHistory = ref([])
 
 // 状态
 const matchResults = ref([])
@@ -269,42 +250,61 @@ const selectedPlan = ref(null)
 const activeTopic = ref('')
 const applyDialogVisible = ref(false)
 
-// 匹配算法
-const matchPreplan = (eventType, eventLevel, eventRegion, responsibleUnit) => {
-  const scored = digitalPlanLibrary.value.map(plan => {
-    let score = 0
-    if (plan.type === eventType) score += 40
-    if (plan.level === eventLevel) score += 25
-    if (plan.region === eventRegion) score += 20
-    if (plan.unit === responsibleUnit) score += 15
-    return { ...plan, matchScore: score }
-  })
-  return scored.filter(p => p.matchScore > 0).sort((a, b) => b.matchScore - a.matchScore)
+// 后端匹配结果 → 页面展示字段映射
+const toDisplayPlan = (vo) => ({
+  id: vo.id,
+  name: vo.planName,
+  type: vo.eventType,
+  level: vo.eventLevel,
+  region: vo.eventRegion,
+  unit: vo.responsibleUnit,
+  topic: vo.topic,
+  summary: vo.planSummary,
+  content: vo.planContent,
+  matchScore: vo.matchScore
+})
+
+// 加载最近匹配记录
+const loadHistory = async () => {
+  try {
+    const res = await getPlanMatchHistory(10)
+    matchHistory.value = (res.data || []).map(r => ({
+      id: r.id,
+      date: (r.createTime || '').substring(0, 10),
+      desc: r.recordDesc,
+      planName: r.planName
+    }))
+  } catch (e) {
+    ElMessage.error('加载最近匹配记录失败')
+  }
 }
 
 // 专题匹配
-const matchByTopic = (topicName) => {
+const matchByTopic = async (topicName) => {
   activeTopic.value = topicName
-  const keywordMap = {
-    '燃气泄漏专题': p => p.name.includes('燃气') || p.content.includes('燃气'),
-    '供水爆管专题': p => p.name.includes('供水') || p.type === '管网爆管',
-    '防汛排涝专题': p => p.name.includes('防汛') || p.content.includes('防汛'),
-    '供热故障专题': p => p.name.includes('供热') || p.content.includes('供热'),
-    '电力管廊事故': p => p.name.includes('电力') || p.content.includes('电力'),
-    '通信光缆中断': p => p.name.includes('通信') || p.content.includes('光缆')
+  try {
+    const res = await matchPlanByTopic({ topic: topicName })
+    const matched = (res.data || []).map(toDisplayPlan)
+    matchResults.value = matched
+    selectedPlan.value = matched.length > 0 ? matched[0] : null
+    loadHistory()
+  } catch (e) {
+    ElMessage.error('专题匹配失败')
   }
-  const filterFn = keywordMap[topicName] || (() => false)
-  const matched = digitalPlanLibrary.value.filter(filterFn)
-  matchResults.value = matched.map(m => ({ ...m, matchScore: 85 + Math.floor(Math.random() * 12) }))
-  selectedPlan.value = matchResults.value.length > 0 ? matchResults.value[0] : null
 }
 
 // 手动匹配
-const manualMatch = () => {
+const manualMatch = async () => {
   activeTopic.value = ''
-  const matched = matchPreplan(form.eventType, form.eventLevel, form.eventRegion, form.responsibleUnit)
-  matchResults.value = matched
-  selectedPlan.value = matched.length > 0 ? matched[0] : null
+  try {
+    const res = await matchPlan({ ...form })
+    const matched = (res.data || []).map(toDisplayPlan)
+    matchResults.value = matched
+    selectedPlan.value = matched.length > 0 ? matched[0] : null
+    loadHistory()
+  } catch (e) {
+    ElMessage.error('预案匹配失败')
+  }
 }
 
 // 选择预案
@@ -312,7 +312,7 @@ const selectPlan = (plan) => {
   selectedPlan.value = plan
 }
 
-// 应用预案
+// 应用预案(打开确认弹窗)
 const applyPlan = () => {
   if (!selectedPlan.value) {
     ElMessage.warning('请先选择一个预案')
@@ -321,20 +321,27 @@ const applyPlan = () => {
   applyDialogVisible.value = true
 }
 
-const confirmApply = () => {
+const confirmApply = async () => {
   applyDialogVisible.value = false
-  ElMessage.success(`已启动预案: ${selectedPlan.value.name},预案内容将分发至应急指挥中心及相应处置单位。`)
+  try {
+    await applyPlanApi({
+      ...form,
+      planId: selectedPlan.value.id,
+      planName: selectedPlan.value.name,
+      matchScore: selectedPlan.value.matchScore
+    })
+    ElMessage.success(`已启动预案: ${selectedPlan.value.name},预案内容将分发至应急指挥中心及相应处置单位。`)
+    loadHistory()
+  } catch (e) {
+    ElMessage.error('预案应用失败')
+  }
 }
 
-// 初始化默认匹配
-const initDefaultMatch = () => {
-  const matched = matchPreplan(form.eventType, form.eventLevel, form.eventRegion, form.responsibleUnit)
-  if (matched.length) {
-    matchResults.value = matched
-    selectedPlan.value = matched[0]
-  }
+// 初始化:仅加载最近匹配记录,不自动匹配(只有点击「立即匹配预案」才生成记录)
+const init = async () => {
+  await loadHistory()
 }
-initDefaultMatch()
+init()
 </script>
 
 <style scoped>

+ 14 - 11
src/views/subSystem/dispatch/disOnDuty/cphs.vue

@@ -29,10 +29,13 @@
     <div class="table-panel">
       <el-table :data="tableData" border stripe style="width:100%" v-loading="loading">
         <el-table-column prop="eventNo" label="事件编号" width="140" />
-        <el-table-column prop="category" label="事件类别" width="110" />
+        <el-table-column prop="category" label="事件类别" width="110">
+          <template #default="{ row }">{{ row.category || '-' }}</template>
+        </el-table-column>
         <el-table-column prop="level" label="事件等级" width="100">
           <template #default="{ row }">
-            <el-tag :type="levelTagType(row.level)" size="small">{{ row.level }}</el-tag>
+            <el-tag v-if="row.level" :type="levelTagType(row.level)" size="small">{{ row.level }}</el-tag>
+            <span v-else>-</span>
           </template>
         </el-table-column>
         <el-table-column prop="location" label="发生地点" show-overflow-tooltip />
@@ -126,10 +129,10 @@
               <el-form-item label="接报编号">{{ currentRow.eventNo }}</el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="事件标识">{{ currentRow.eventId || '待生成' }}</el-form-item>
+              <el-form-item label="事件标识">{{ currentRow.eventNo }}</el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="关联接报ID">{{ currentRow.reportId }}</el-form-item>
+              <el-form-item label="事件来源">{{ currentRow.source || '-' }}</el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
@@ -160,7 +163,7 @@
             </el-col>
           </el-row>
           <el-form-item label="核实意见">
-            <div class="desc-text">{{ currentRow.opinion || '-' }}</div>
+            <div class="desc-text">{{ currentRow.verifyOpinion || '-' }}</div>
           </el-form-item>
           <el-form-item label="状态">
             <el-tag :type="statusTagType(currentRow.status)" size="small">{{ currentRow.status }}</el-tag>
@@ -177,7 +180,7 @@
 <script setup name="Cphs">
 import { ref, onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { getEventVerifyPage, deleteEventVerify, verifyEvent } from '@/api/dispatch'
+import { getEventPage, deleteEventInfo, verifyEventInfo } from '@/api/dispatch'
 
 // ==================== 数据状态 ====================
 const tableData = ref([])
@@ -190,11 +193,11 @@ const pagination = ref({ page: 1, pageSize: 10 })
 async function loadData() {
   loading.value = true
   try {
-    const params = {}
+    const params = { status: '待核实' }
     if (searchForm.value.category) params.category = searchForm.value.category
     if (searchForm.value.level) params.level = searchForm.value.level
     if (searchForm.value.verifyStatus) params.status = searchForm.value.verifyStatus
-    const res = await getEventVerifyPage(pagination.value.page, pagination.value.pageSize, params)
+    const res = await getEventPage(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) {
@@ -267,7 +270,7 @@ function handleVerify(row) {
     description: row.description,
     category: row.category,
     level: row.level,
-    opinion: '',
+    opinion: row.verifyOpinion || '',
     isReal: '真实'
   }
   verifyVisible.value = true
@@ -280,7 +283,7 @@ async function confirmVerify() {
     return
   }
   try {
-    await verifyEvent({
+    await verifyEventInfo({
       id: currentVerifyId.value,
       category: verifyForm.value.category,
       level: verifyForm.value.level,
@@ -299,7 +302,7 @@ async function confirmVerify() {
 async function handleDelete(row) {
   try {
     await ElMessageBox.confirm('确定要删除该核实记录吗?', '删除确认', { type: 'warning' })
-    await deleteEventVerify(row.id)
+    await deleteEventInfo(row.id)
     ElMessage.success('删除成功')
     loadData()
   } catch (error) {

+ 40 - 29
src/views/subSystem/dispatch/disOnDuty/gzjc.vue

@@ -4,7 +4,7 @@
     <div class="filter-panel">
       <div class="filter-form">
         <el-select v-model="searchForm.eventStatus" placeholder="事件状态" clearable style="width:140px">
-          <el-option label="处理中" value="处理中" />
+          <el-option label="处置中" value="处置中" />
           <el-option label="已解除" value="已解除" />
           <el-option label="已关闭" value="已关闭" />
         </el-select>
@@ -48,8 +48,8 @@
         <el-table-column prop="handler" label="负责人" min-width="100" />
         <el-table-column label="操作" width="260" fixed="right">
           <template #default="{ row }">
-            <el-button v-if="row.status === '处中'" type="primary" link size="small" @click="handleTrack(row)">跟踪</el-button>
-            <el-button v-if="row.status === '处中'" type="primary" link size="small" @click="handleClose(row)">解除</el-button>
+            <el-button v-if="row.status === '处中'" type="primary" link size="small" @click="handleTrack(row)">跟踪</el-button>
+            <el-button v-if="row.status === '处中'" type="primary" link size="small" @click="handleClose(row)">解除</el-button>
             <el-button v-if="row.status === '已解除'" type="primary" link size="small" @click="handleClose(row)">关闭</el-button>
             <el-button type="primary" link size="small" @click="handleDetail(row)">详情</el-button>
             <el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
@@ -129,6 +129,9 @@
         <el-form-item label="解除说明" prop="remark">
           <el-input v-model="closeForm.remark" type="textarea" :rows="4" placeholder="请输入解除说明" />
         </el-form-item>
+        <el-form-item label="损失(万元)">
+          <el-input-number v-model="closeForm.lossAmount" :min="0" :precision="2" style="width:100%" />
+        </el-form-item>
       </el-form>
       <template #footer>
         <el-button @click="closeVisible = false">取消</el-button>
@@ -201,7 +204,7 @@
 <script setup name="Gzjc">
 import { ref, onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { getEventTrackPage, deleteEventTrack, addTrackLog, releaseEvent, closeEvent, getTrackLogs } from '@/api/dispatch'
+import { getEventPage, deleteEventInfo, trackEvent, releaseEventInfo, closeEventInfo, getTrackLogs } from '@/api/dispatch'
 
 // ==================== 数据状态 ====================
 const tableData = ref([])
@@ -214,14 +217,14 @@ const pagination = ref({ page: 1, pageSize: 10 })
 async function loadData() {
   loading.value = true
   try {
-    const params = {}
-    if (searchForm.value.eventStatus) params.status = searchForm.value.eventStatus
+    const params = { statusList: ['处置中', '已解除', '已关闭'] }
+    if (searchForm.value.eventStatus) params.statusList = [searchForm.value.eventStatus]
     if (searchForm.value.category) params.category = searchForm.value.category
     if (searchForm.value.dateRange && searchForm.value.dateRange.length === 2) {
       params.startDate = searchForm.value.dateRange[0]
       params.endDate = searchForm.value.dateRange[1]
     }
-    const res = await getEventTrackPage(pagination.value.page, pagination.value.pageSize, params)
+    const res = await getEventPage(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) {
@@ -261,7 +264,7 @@ function handleCurrentChange(val) {
 
 // ==================== 标签样式 ====================
 function statusTagType(status) {
-  if (status === '处中') return 'primary'
+  if (status === '处中') return 'primary'
   if (status === '已解除') return 'warning'
   if (status === '已关闭') return 'success'
   return 'info'
@@ -290,8 +293,10 @@ function handleTrack(row) {
   currentRow.value = row
   currentTrackId.value = row.id
   trackForm.value = { eventNo: row.eventNo, content: '', assessment: '趋于平稳', needUpgrade: '否', nextVisitTime: '' }
-  // 尝试加载跟踪日志
-  loadTrackLogs(row.id)
+  // 加载跟踪日志(按最近跟踪记录ID)
+  if (row.trackId) {
+    loadTrackLogs(row.trackId)
+  }
   trackVisible.value = true
 }
 
@@ -313,13 +318,12 @@ async function confirmTrack() {
     return
   }
   try {
-    await addTrackLog({
-      trackId: currentTrackId.value,
-      title: '跟踪记录',
-      content: trackForm.value.content,
+    await trackEvent({
+      relEventId: currentTrackId.value,
+      description: trackForm.value.content,
       assessment: trackForm.value.assessment,
       needUpgrade: trackForm.value.needUpgrade,
-      type: 'primary'
+      nextVisitTime: trackForm.value.nextVisitTime
     })
     ElMessage.success('跟踪记录保存成功')
     trackVisible.value = false
@@ -333,7 +337,7 @@ async function confirmTrack() {
 const closeVisible = ref(false)
 const closeFormRef = ref(null)
 const currentCloseRow = ref(null)
-const closeForm = ref({ eventNo: '', summary: '', reason: '', remark: '' })
+const closeForm = ref({ eventNo: '', summary: '', reason: '', remark: '', lossAmount: undefined })
 const closeRules = {
   reason: [{ required: true, message: '请选择解除原因', trigger: 'change' }],
   remark: [{ required: true, message: '请输入解除说明', trigger: 'blur' }]
@@ -342,8 +346,8 @@ const closeTitle = ref('事件解除')
 
 function handleClose(row) {
   currentCloseRow.value = row
-  closeTitle.value = row.status === '处中' ? '事件解除' : '事件关闭'
-  closeForm.value = { eventNo: row.eventNo, summary: row.description || '', reason: '', remark: '' }
+  closeTitle.value = row.status === '处中' ? '事件解除' : '事件关闭'
+  closeForm.value = { eventNo: row.eventNo, summary: row.description || '', reason: '', remark: '', lossAmount: row.lossAmount ? Number(row.lossAmount) : undefined }
   closeVisible.value = true
 }
 
@@ -354,11 +358,16 @@ async function confirmClose() {
     return
   }
   try {
-    if (currentCloseRow.value.status === '处中') {
-      await releaseEvent(currentCloseRow.value.id)
+    if (currentCloseRow.value.status === '处中') {
+      await releaseEventInfo(currentCloseRow.value.id)
       ElMessage.success('事件已解除')
     } else if (currentCloseRow.value.status === '已解除') {
-      await closeEvent(currentCloseRow.value.id)
+      await closeEventInfo({
+        id: currentCloseRow.value.id,
+        closeReason: closeForm.value.reason,
+        closeRemark: closeForm.value.remark,
+        lossAmount: closeForm.value.lossAmount
+      })
       ElMessage.success('事件已关闭')
     }
     closeVisible.value = false
@@ -372,7 +381,7 @@ async function confirmClose() {
 async function handleDelete(row) {
   try {
     await ElMessageBox.confirm('确定要删除该跟踪记录吗?', '删除确认', { type: 'warning' })
-    await deleteEventTrack(row.id)
+    await deleteEventInfo(row.id)
     ElMessage.success('删除成功')
     loadData()
   } catch (error) {
@@ -389,14 +398,16 @@ const currentRow = ref(null)
 async function handleDetail(row) {
   currentRow.value = row
   detailVisible.value = true
-  // 尝试加载最新的跟踪日志
-  try {
-    const res = await getTrackLogs(row.id)
-    if (res.data && res.data.length) {
-      currentRow.value = { ...row, timeline: res.data }
+  // 加载最新的跟踪日志(按最近跟踪记录ID)
+  if (row.trackId) {
+    try {
+      const res = await getTrackLogs(row.trackId)
+      if (res.data && res.data.length) {
+        currentRow.value = { ...row, timeline: res.data }
+      }
+    } catch {
+      // 使用行内已有数据
     }
-  } catch {
-    // 使用行内已有数据
   }
 }
 </script>

+ 18 - 10
src/views/subSystem/dispatch/disOnDuty/jbgl.vue

@@ -20,8 +20,12 @@
         />
         <el-select v-model="searchForm.status" placeholder="事件状态" clearable style="width:140px">
           <el-option label="待受理" value="待受理" />
-          <el-option label="已受理" value="已受理" />
-          <el-option label="已驳回" value="已驳回" />
+          <el-option label="待核实" value="待核实" />
+          <el-option label="已核实" value="已核实" />
+          <el-option label="处置中" value="处置中" />
+          <el-option label="已解除" value="已解除" />
+          <el-option label="已关闭" value="已关闭" />
+          <el-option label="不实事件" value="不实事件" />
         </el-select>
         <el-button type="primary" @click="handleSearch">搜索</el-button>
         <el-button @click="handleReset">重置</el-button>
@@ -170,7 +174,7 @@
 <script setup name="Jbgl">
 import { ref, onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { getEventReportPage, addEventReport, updateEventReport, deleteEventReport, acceptEventReport } from '@/api/dispatch'
+import { getEventPage, saveEventReport, updateEventInfo, deleteEventInfo, acceptEvent } from '@/api/dispatch'
 
 // ==================== 数据状态 ====================
 const tableData = ref([])
@@ -190,7 +194,7 @@ async function loadData() {
       params.startDate = searchForm.value.dateRange[0]
       params.endDate = searchForm.value.dateRange[1]
     }
-    const res = await getEventReportPage(pagination.value.page, pagination.value.pageSize, params)
+    const res = await getEventPage(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) {
@@ -231,8 +235,12 @@ function handleCurrentChange(val) {
 // ==================== 状态标签样式 ====================
 function statusTagType(status) {
   if (status === '待受理') return 'warning'
-  if (status === '已受理') return 'success'
-  if (status === '已驳回') return 'danger'
+  if (status === '待核实') return 'warning'
+  if (status === '已核实') return 'success'
+  if (status === '处置中') return 'primary'
+  if (status === '已解除') return 'warning'
+  if (status === '已关闭') return 'success'
+  if (status === '不实事件') return 'info'
   return 'info'
 }
 
@@ -248,7 +256,7 @@ function handleAccept(row) {
 async function confirmAccept() {
   if (!currentRow.value) return
   try {
-    await acceptEventReport(currentRow.value.id)
+    await acceptEvent(currentRow.value.id)
     ElMessage.success('受理成功')
     acceptVisible.value = false
     loadData()
@@ -305,10 +313,10 @@ function handleSubmit() {
     if (!valid) return
     try {
       if (editingId.value) {
-        await updateEventReport({ id: editingId.value, ...addForm.value })
+        await updateEventInfo({ id: editingId.value, ...addForm.value })
         ElMessage.success('编辑成功')
       } else {
-        await addEventReport(addForm.value)
+        await saveEventReport(addForm.value)
         ElMessage.success('新增成功')
       }
       addVisible.value = false
@@ -323,7 +331,7 @@ function handleSubmit() {
 async function handleDelete(row) {
   try {
     await ElMessageBox.confirm('确定要删除该接报记录吗?', '删除确认', { type: 'warning' })
-    await deleteEventReport(row.id)
+    await deleteEventInfo(row.id)
     ElMessage.success('删除成功')
     loadData()
   } catch (error) {

+ 24 - 26
src/views/subSystem/dispatch/disOnDuty/zjbs.vue

@@ -5,9 +5,8 @@
       <div class="filter-form">
         <el-input v-model="searchForm.eventNo" placeholder="事件编号" clearable style="width:160px" />
         <el-select v-model="searchForm.transferStatus" placeholder="转接状态" clearable style="width:140px">
-          <el-option label="待转接" value="待转接" />
-          <el-option label="已转接" value="已转接" />
-          <el-option label="已报送" value="已报送" />
+          <el-option label="已核实" value="已核实" />
+          <el-option label="处置中" value="处置中" />
         </el-select>
         <el-select v-model="searchForm.receiveDept" placeholder="接收部门" clearable style="width:160px">
           <el-option label="市政部门" value="市政部门" />
@@ -25,8 +24,7 @@
     <!-- 数据表格 -->
     <div class="table-panel">
       <el-table :data="tableData" border stripe style="width:100%" v-loading="loading">
-        <el-table-column prop="reportEventNo" label="接报编号" width="140" show-overflow-tooltip />
-        <el-table-column prop="eventNo" label="事件编号" width="140" />
+        <el-table-column prop="eventNo" label="事件编号" width="150" />
         <el-table-column prop="category" label="事件类别" width="110" />
         <el-table-column prop="level" label="事件等级" width="100">
           <template #default="{ row }">
@@ -43,8 +41,8 @@
         </el-table-column>
         <el-table-column label="操作" width="240" fixed="right">
           <template #default="{ row }">
-            <el-button v-if="row.status === '待转接'" type="primary" link size="small" @click="handleTransfer(row)">转接</el-button>
-            <el-button v-if="row.status === '待转接' || row.status === '已转接'" type="primary" link size="small" @click="handleReport(row)">报送</el-button>
+            <el-button v-if="row.status === '已核实'" type="primary" link size="small" @click="handleTransfer(row)">转接</el-button>
+            <el-button v-if="row.status === '处置中' && row.transferId" type="primary" link size="small" @click="handleReport(row)">报送</el-button>
             <el-button type="primary" link size="small" @click="handleDetail(row)">详情</el-button>
             <el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
           </template>
@@ -136,9 +134,6 @@
       <div v-if="currentRow" class="detail-content">
         <el-form label-width="100px" size="default">
           <el-row :gutter="20">
-            <el-col :span="6">
-              <el-form-item label="接报编号">{{ currentRow.reportEventNo || '-' }}</el-form-item>
-            </el-col>
             <el-col :span="6">
               <el-form-item label="事件编号">{{ currentRow.eventNo }}</el-form-item>
             </el-col>
@@ -146,7 +141,10 @@
               <el-form-item label="事件类别">{{ currentRow.category }}</el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="关联核实ID">{{ currentRow.verifyId }}</el-form-item>
+              <el-form-item label="事件等级">{{ currentRow.level }}</el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="事件来源">{{ currentRow.source || '-' }}</el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
@@ -170,8 +168,8 @@
               <el-form-item label="报送层级">{{ currentRow.reportTargets || '-' }}</el-form-item>
             </el-col>
           </el-row>
-          <el-form-item label="事件摘要">
-            <div class="desc-text">{{ currentRow.summary || '-' }}</div>
+          <el-form-item label="事件描述">
+            <div class="desc-text">{{ currentRow.description || '-' }}</div>
           </el-form-item>
         </el-form>
         <div class="section-title">流转历史</div>
@@ -197,7 +195,7 @@
 import { ref, onMounted } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { getToken } from '@/utils/auth'
-import { getEventTransferPage, deleteEventTransfer, doTransfer, doEventReport } from '@/api/dispatch'
+import { getEventPage, deleteEventInfo, transferEvent, reportEvent } from '@/api/dispatch'
 
 // ==================== 推荐部门映射 ====================
 const recommendMap = {
@@ -218,11 +216,11 @@ const pagination = ref({ page: 1, pageSize: 10 })
 async function loadData() {
   loading.value = true
   try {
-    const params = {}
+    const params = { statusList: ['已核实', '处置中'] }
     if (searchForm.value.eventNo) params.eventNo = searchForm.value.eventNo
-    if (searchForm.value.transferStatus) params.status = searchForm.value.transferStatus
-    if (searchForm.value.receiveDept) params.transferDept = searchForm.value.receiveDept
-    const res = await getEventTransferPage(pagination.value.page, pagination.value.pageSize, params)
+    if (searchForm.value.transferStatus) params.statusList = [searchForm.value.transferStatus]
+    if (searchForm.value.receiveDept) params.department = searchForm.value.receiveDept
+    const res = await getEventPage(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) {
@@ -262,8 +260,8 @@ function handleCurrentChange(val) {
 
 // ==================== 标签样式 ====================
 function statusTagType(status) {
-  if (status === '待转接') return 'warning'
-  if (status === '已转接') return 'primary'
+  if (status === '已核实') return 'primary'
+  if (status === '处置中') return 'warning'
   if (status === '已报送') return 'success'
   return 'info'
 }
@@ -303,10 +301,10 @@ async function confirmTransfer() {
     return
   }
   try {
-    await doTransfer({
-      id: currentTransferId.value,
+    await transferEvent({
+      relEventId: currentTransferId.value,
       transferDept: transferForm.value.depts.join('、'),
-      remark: transferForm.value.remark
+      transferRemark: transferForm.value.remark
     })
     ElMessage.success('转接成功')
     transferVisible.value = false
@@ -377,10 +375,10 @@ async function confirmReport() {
   }
   submitting.value = true
   try {
-    await doEventReport({
+    await reportEvent({
       id: currentReportId.value,
       reportTargets: reportForm.value.reportTargets,
-      attachments: reportForm.value.attachments
+      attachPaths: reportForm.value.attachments.map(a => a.url).join(',')
     })
     ElMessage.success('报送成功')
     reportVisible.value = false
@@ -398,7 +396,7 @@ async function confirmReport() {
 async function handleDelete(row) {
   try {
     await ElMessageBox.confirm('确定要删除该转接记录吗?', '删除确认', { type: 'warning' })
-    await deleteEventTransfer(row.id)
+    await deleteEventInfo(row.id)
     ElMessage.success('删除成功')
     loadData()
   } catch (error) {