Pārlūkot izejas kodu

开发事件管理列表界面,完善知识库界面

愿你天天开心 9 mēneši atpakaļ
vecāks
revīzija
1136a5f3cf

+ 379 - 0
src/views/duty/eventing/index.vue

@@ -0,0 +1,379 @@
+<template>
+  <div class="p-2">
+    <transition name="fade">
+      <div v-show="showSearch" class="mb-[20px]">
+        <el-form ref="queryFormRef" :model="queryParams">
+          <el-row :gutter="10">
+            <!-- 第一行 -->
+            <el-col :span="6">
+              <el-form-item label="事件类型" prop="eventType">
+                <el-select v-model="queryParams.eventType" placeholder="全部" clearable>
+                  <el-option label="全部" value=""></el-option>
+                  <el-option
+                    v-for="item in data.eventTypeSelection"
+                    :key="item.dictValue"
+                    :label="item.dictLabel"
+                    :value="item.dictValue"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="事件等级" prop="eventLevel">
+                <el-select v-model="queryParams.eventLevel" placeholder="全部" clearable>
+                  <el-option label="全部" value=""></el-option>
+                  <el-option
+                    v-for="item in data.eventLevelSelection"
+                    :key="item.dictValue"
+                    :label="item.dictLabel"
+                    :value="item.dictValue"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="事件状态" prop="eventStatus">
+                <el-select v-model="queryParams.eventStatus" placeholder="全部" clearable>
+                  <el-option label="全部" value=""></el-option>
+                  <el-option
+                    v-for="item in data.eventStatusSelection"
+                    :key="item.dictValue"
+                    :label="item.dictLabel"
+                    :value="item.dictValue"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="行政区划" prop="regionCode">
+                <el-select v-model="queryParams.regionCode" placeholder="全部" clearable>
+                  <el-option label="全部" value=""></el-option>
+                  <el-option
+                    v-for="item in data.regionSelection"
+                    :key="item.dictValue"
+                    :label="item.dictLabel"
+                    :value="item.dictValue"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="10" class="mt-[10px]">
+            <el-col :span="6">
+              <el-form-item label="事发时间" prop="eventTime">
+                <el-date-picker
+                  v-model="queryParams.eventTime"
+                  type="datetime"
+                  placeholder="选择事发时间"
+                  value-format="yyyy-MM-dd HH:mm:ss"
+                ></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item>
+                <el-input v-model="queryParams.keyword" placeholder="请输入事件标题/事件地点" clearable
+                          @keyup.enter="handleQuery"/>
+              </el-form-item>
+            </el-col>
+              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+          </el-row>
+        </el-form>
+      </div>
+    </transition>
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="Plus" @click="handleAdd">新增事件</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete(selectedRow)">删除事件
+        </el-button>
+      </el-col>
+    </el-row>
+
+    <!-- 表格组件 -->
+    <el-table v-loading="loading" :data="eventList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="事件编号" align="center" prop="eventId"/>
+      <el-table-column label="事件标题" align="center" prop="eventTitle"/>
+      <el-table-column label="事件类型" align="center" prop="eventType"/>
+      <el-table-column label="事件等级" align="center" prop="eventLevel"/>
+      <el-table-column label="事件状态" align="center" prop="eventStatus"/>
+      <el-table-column label="事件地点" align="center" prop="address"/>
+      <el-table-column label="事件时间" align="center" prop="eventTime"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-tooltip content="查看" placement="top">
+            <el-button link type="primary" icon="View" @click="handleView(scope.row)"></el-button>
+          </el-tooltip>
+          <el-tooltip content="编辑" placement="top">
+            <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
+          </el-tooltip>
+          <el-tooltip content="关闭事件" placement="top">
+            <el-button link type="primary" icon="Close" @click="handleClose(scope.row)"></el-button>
+          </el-tooltip>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
+                :total="total" @pagination="getList"/>
+
+    <!-- 新增/修改弹窗 -->
+    <el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body>
+      <el-form ref="eventFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="事件标题" prop="eventTitle">
+          <el-input v-model="form.eventTitle" placeholder="请输入事件标题"/>
+        </el-form-item>
+        <el-form-item label="事件类型" prop="eventType">
+          <el-select v-model="form.eventType" placeholder="请选择事件类型" clearable>
+            <el-option
+              v-for="item in data.eventTypeSelection"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="事件等级" prop="eventLevel">
+          <el-select v-model="form.eventLevel" placeholder="请选择事件等级" clearable>
+            <el-option
+              v-for="item in data.eventLevelSelection"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="事件状态" prop="eventStatus">
+          <el-select v-model="form.eventStatus" placeholder="请选择事件状态" clearable>
+            <el-option
+              v-for="item in data.eventStatusSelection"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="事件地点" prop="address">
+          <el-input v-model="form.address" placeholder="请输入事件地点"/>
+        </el-form-item>
+        <el-form-item label="事发时间" prop="eventTime">
+          <el-date-picker
+            v-model="form.eventTime"
+            type="datetimerange"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+            value-format="yyyy-MM-dd HH:mm:ss"
+          ></el-date-picker>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确定</el-button>
+          <el-button @click="cancel">取消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, toRefs, onMounted } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getDicts } from "@/api/system/dict/data";
+
+const eventList = ref([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const selectedRow = ref(null);
+
+const queryFormRef = ref();
+const eventFormRef = ref();
+
+const dialog = reactive({
+  visible: false,
+  title: ''
+});
+
+const initFormData = {
+  eventId: '',
+  eventTitle: '',
+  eventType: '',
+  eventLevel: '',
+  eventStatus: '',
+  address: '',
+  eventTime: ''
+};
+
+const data = reactive({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    eventType: '',
+    eventLevel: '',
+    eventStatus: '',
+    eventTime: '',
+    regionCode: '',
+    keyword: ''
+  },
+  rules: {
+    eventTitle: [{ required: true, message: '事件标题不能为空', trigger: 'blur' }],
+    eventType: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],
+    eventLevel: [{ required: true, message: '事件等级不能为空', trigger: 'blur' }],
+    eventStatus: [{ required: true, message: '事件状态不能为空', trigger: 'blur' }],
+    address: [{ required: true, message: '事件地点不能为空', trigger: 'blur' }],
+    eventTime: [{ required: true, message: '事发时间不能为空', trigger: 'blur' }]
+  },
+  eventTypeSelection: [],
+  eventLevelSelection: [],
+  eventStatusSelection: [],
+  regionSelection: []
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const getList = async () => {
+  loading.value = true;
+  try {
+    const response = await fetchEvents(queryParams.value);
+    const { data, total } = response;
+    eventList.value = data;
+    total.value = total;
+  } catch (error) {
+    ElMessage.error('获取数据失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+const fetchEvents = async (params) => {
+  // 假设后端接口为 /api/events
+  const response = await fetch('/api/events', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    body: JSON.stringify(params)
+  });
+  const result = await response.json();
+  if (response.ok) {
+    return result;
+  } else {
+    throw new Error(result.message || '获取事件列表失败');
+  }
+};
+
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+};
+
+const reset = () => {
+  form.value = { ...initFormData };
+  eventFormRef.value?.resetFields();
+};
+
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
+
+const resetQuery = () => {
+  queryParams.value = { pageNum: 1, pageSize: 10, eventType: '', eventLevel: '', eventStatus: '', eventTime: '', regionCode: '', keyword: '' };
+  handleQuery();
+};
+
+const handleSelectionChange = (selection) => {
+  ids.value = selection.map((item) => item.eventId);
+  selectedRow.value = selection.length === 1 ? selection[0] : null;
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
+
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = '新增事件';
+};
+
+// 修改事件
+const handleUpdate = (row) => {
+  if (row) {
+    reset();
+    Object.assign(form.value, row);
+    dialog.visible = true;
+    dialog.title = '修改事件';
+  }
+};
+
+// 提交表单
+const submitForm = () => {
+  eventFormRef.value?.validate((valid) => {
+    if (valid) {
+      buttonLoading.value = true;
+      setTimeout(() => {
+        if (form.value.eventId) {
+          // 更新逻辑
+        } else {
+          // 添加逻辑
+        }
+        buttonLoading.value = false;
+        dialog.visible = false;
+        getList();
+      }, 500);
+    }
+  });
+};
+
+const handleDelete = (row) => {
+  if (row) {
+    // 删除逻辑
+    setTimeout(() => {
+      eventList.value = eventList.value.filter((item) => item.eventId !== row.eventId);
+      getList();
+    }, 500);
+  }
+};
+
+// 关闭事件
+const handleClose = (row) => {
+  if (row) {
+    // 关闭逻辑
+    setTimeout(() => {
+      row.eventStatus = '3'; // 已关闭
+      getList();
+    }, 500);
+  }
+};
+
+// 查看事件详情
+const handleView = (row) => {
+  if (row) {
+    // 查看事件详情逻辑
+    console.log('查看事件详情', row);
+  }
+};
+
+onMounted(() => {
+  getList();
+  Promise.all([
+    getDicts("mm_event_type"),
+    getDicts("mm_event_level"),
+    getDicts("mm_event_state"),
+    getDicts("region")
+  ]).then(([eventTypeRes, eventLevelRes, eventStatusRes, regionRes]) => {
+    data.eventTypeSelection = eventTypeRes.data;
+    data.eventLevelSelection = eventLevelRes.data;
+    data.eventStatusSelection = eventStatusRes.data;
+    data.regionSelection = regionRes.data;
+  });
+});
+</script>

+ 137 - 0
src/views/knowledge/knowledge-management/detail.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="report-details">
+    <el-button type="text" @click="goBack">返回上一级</el-button>
+    <el-row>
+      <el-col :span="20">
+        <h2>{{ report.title }}</h2>
+      </el-col>
+      <el-col :span="4" class="text-right">
+        <el-button type="primary" @click="handleEdit">编辑</el-button>
+        <el-button type="danger" @click="handleDelete">删除</el-button>
+      </el-col>
+    </el-row>
+    <el-divider></el-divider>
+    <div class="basic-info">
+      <strong>基本信息</strong>
+      <el-row>
+        <el-col :span="8">报告编号:{{ report.reportId }}</el-col>
+        <el-col :span="8">主题词:{{ report.keyword }}</el-col>
+        <el-col :span="8">事件类型:{{ report.eventType }}</el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">发布日期:{{ report.publishDate }}</el-col>
+        <el-col :span="8">来源单位:{{ report.sourceUnit }}</el-col>
+        <el-col :span="8">通知类型:{{ report.notificationType }}</el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">摘要:{{ report.summary }}</el-col>
+      </el-row>
+    </div>
+    <div class="attachments">
+      <strong>报告附件:</strong>
+    </div>
+    <el-link :href="report.attachmentUrl" target="_blank">{{ report.attachmentName }}</el-link>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import { ElMessageBox, ElMessage } from 'element-plus';
+
+const report = ref({
+  reportId: '',
+  title: '',
+  keyword: '',
+  eventType: '',
+  publishDate: '',
+  sourceUnit: '',
+  notificationType: '',
+  summary: '',
+  attachmentName: '',
+  attachmentUrl: ''
+});
+
+const route = useRoute();
+const router = useRouter();
+
+const goBack = () => {
+  router.go(-1);
+};
+
+const handleEdit = () => {
+  // 编辑逻辑
+  ElMessageBox.prompt('编辑报告', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    inputValue: report.value.title
+  }).then(({ value }) => {
+    report.value.title = value;
+    ElMessage({
+      type: 'success',
+      message: '报告已更新'
+    });
+  }).catch(() => {
+    ElMessage({
+      type: 'info',
+      message: '已取消编辑'
+    });
+  });
+};
+
+const handleDelete = () => {
+  // 删除逻辑
+  ElMessageBox.confirm('此操作将永久删除该报告, 是否继续?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    ElMessage({
+      type: 'success',
+      message: '报告已删除'
+    });
+    router.push('/');
+  }).catch(() => {
+    ElMessage({
+      type: 'info',
+      message: '已取消删除'
+    });
+  });
+};
+
+onMounted(() => {
+  const reportId = route.params.reportId;
+
+  // 模拟数据对象
+  const mockData = {
+    reportId: 'YJYA0000000001',
+    title: '广东省城市轨道交通运营突发事件总结报告',
+    keyword: '轨道交通',
+    eventType: '自然灾害',
+    publishDate: '2024-07-11 16:09:09',
+    sourceUnit: '茂名市应急管理局',
+    notificationType: '总结报告',
+    summary: '广东省城市轨道交通运营突发事件总结报告。',
+    attachmentName: '关于X市公交XXX公交车司机出现状况的调查报告.pdf',
+    attachmentUrl: '/path/to/attachment.pdf'
+  };
+
+  // 直接赋值给 report
+  report.value = mockData;
+});
+</script>
+
+<style scoped>
+.report-details {
+  padding: 20px;
+  background-color: #fff;
+}
+
+.basic-info {
+  margin-bottom: 20px;
+}
+
+.attachments {
+  margin-bottom: 20px;
+}
+</style>

+ 10 - 5
src/views/knowledge/knowledge-management/index.vue

@@ -67,6 +67,9 @@
         <el-table-column label="发布日期" align="center" prop="publishDate"/>
         <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
+            <el-tooltip content="查看" placement="top">
+              <el-button link type="primary" icon="View" @click="handleView(scope.row)"></el-button>
+            </el-tooltip>
             <el-tooltip content="修改" placement="top">
               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
             </el-tooltip>
@@ -204,6 +207,7 @@ const getList = async () => {
   }
 };
 
+// 获取报告列表
 const fetchReports = async (params) => {
   // 假设后端接口为 /api/reports
   const response = await fetch('/api/reports', {
@@ -254,6 +258,12 @@ const handleAdd = () => {
   dialog.title = '添加报告';
 };
 
+// 查看报告
+const handleView = (row) => {
+  // 跳转到总结报告详情页
+  window.location.href = `/report/details/${row.reportId}`;
+};
+
 // 修改报告
 const handleUpdate = (row) => {
   if (row) {
@@ -298,11 +308,6 @@ const handleExport = () => {
 };
 
 // 处理文件上传数量限制
-const handleExceed = () => {
-  ElMessage.warning('最多上传5个文件');
-};
-
-
 onMounted(() => {
   getList();
   getDicts("mm_event_type").then(res => {