فهرست منبع

Merge branch 'dev' of https://gogs.tjp.com.cn/maoming/yjhtgl-web into dev

Hwf 1 سال پیش
والد
کامیت
6243a7702a

+ 50 - 4
src/api/duty/eventing.ts

@@ -3,7 +3,7 @@ import request from '@/utils/request';
 // 获取事件列表
 export function getEvent(params) {
   return request({
-    url: '/api/event/list',
+    url: '/api/event_management/event/list',
     method: 'get',
     params: params
   });
@@ -12,24 +12,70 @@ export function getEvent(params) {
 // 新建事件
 export function addEvent(data) {
   return request({
-    url: '/api/event/create',
+    url: '/api/event_management/event/create',
     method: 'post',
     data: data
   });
 }
 
+// 事件详情
 export function getEventDetail(params) {
   return request({
-    url: '/api/event/detail',
+    url: '/api/event_management/event/detail',
     method: 'get',
     params: params
   });
 }
 
+// 编辑事件
+export function editEvent(params) {
+  return request({
+    url: '/api/event_management/event/edit',
+    method: 'get',
+    params: params
+  });
+}
+
+export function postEditEvent(data) {
+  return request({
+    url: '/api/event_management/event/edit',
+    method: 'post',
+    data
+  });
+}
+
+// 关闭事件
 export function closeEvent(data) {
   return request({
-    url: '/api/event/close',
+    url: '/api/event_management/event/close',
+    method: 'post',
+    data: data
+  });
+}
+
+// 开始指挥事件
+export function startEvent(data) {
+  return request({
+    url: '/api/event_management/event/start',
+    method: 'post',
+    data: data
+  });
+}
+
+// 删除事件
+export function deleteEvent(data) {
+  return request({
+    url: '/api/event_management/event/delete',
     method: 'post',
     data: data
   });
 }
+
+// 上报伤亡情况
+export function uploadEventCasualties(data) {
+  return request({
+    url: '/api/event_management/event/uploadEventCasualties',
+    method: 'post',
+    data: data
+  });
+}

+ 1 - 1
src/components/FileUpload/index.vue

@@ -59,7 +59,7 @@ const props = defineProps({
   // 大小限制(MB)
   fileSize: propTypes.number.def(5),
   // 文件类型, 例如['png', 'jpg', 'jpeg']
-  fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']),
+  fileType: propTypes.array.def(['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']),
   // 是否显示提示
   isShowTip: propTypes.bool.def(true)
 });

+ 0 - 17
src/types/components.d.ts

@@ -16,21 +16,15 @@ declare module 'vue' {
     CompanyMap: typeof import('./../components/Map/company-map.vue')['default']
     DictTag: typeof import('./../components/DictTag/index.vue')['default']
     Editor: typeof import('./../components/Editor/index.vue')['default']
-    ElAnchor: typeof import('element-plus/es')['ElAnchor']
-    ElAnchorLink: typeof import('element-plus/es')['ElAnchorLink']
     ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
     ElBadge: typeof import('element-plus/es')['ElBadge']
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
-    ElCard: typeof import('element-plus/es')['ElCard']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
-    ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
-    ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
     ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDivider: typeof import('element-plus/es')['ElDivider']
     ElDrawer: typeof import('element-plus/es')['ElDrawer']
@@ -43,16 +37,12 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElProgress: typeof import('element-plus/es')['ElProgress']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
@@ -60,21 +50,14 @@ declare module 'vue' {
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTabPane: typeof import('element-plus/es')['ElTabPane']
-    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
-    ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
-    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     Hamburger: typeof import('./../components/Hamburger/index.vue')['default']
     HeaderSearch: typeof import('./../components/HeaderSearch/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
-    IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
-    IEpCaretTop: typeof import('~icons/ep/caret-top')['default']
-    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']

+ 342 - 0
src/views/agent/one_network_shared_proxy/agent.vue

@@ -0,0 +1,342 @@
+<template>
+  <div class="p-2">
+    <transition name="fade">
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+          <el-form-item style="width: 200px" 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-form-item label="发布日期" prop="publishDate">
+            <el-date-picker
+              v-model="queryParams.publishDate"
+              type="daterange"
+              range-separator="-"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              value-format="yyyy-MM-dd"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="queryParams.passtoken" placeholder="请输入接口名称" clearable
+                      @keyup.enter="handleQuery"/>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </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="success" plain icon="Edit" :disabled="single" @click="handleUpdate(selectedRow)">修改
+        </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-col :span="1.5">
+        <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @query-table="getList"></right-toolbar>
+    </el-row>
+
+    <!--      表格组件-->
+    <el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange"> <!--      handleSelectionChange-->
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="接口名称" align="center" prop="servername"/>
+      <el-table-column label="接口ID" align="center" prop="passid"/>
+      <el-table-column label="令牌" align="center" prop="passtoken"/>
+      <el-table-column label="接口类型" align="center" prop="eventType"/>
+      <el-table-column label="默认参数" align="center" prop="params_default"/>
+      <el-table-column label="默认请求体" align="center" prop="body_default"/>
+      <el-table-column label="默认请求头" align="center" prop="header_default"/>
+      <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>
+          <el-tooltip content="删除" placement="top">
+            <el-button link type="primary" icon="Delete" @click="handleDelete(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="demoFormRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="接口名称" prop="servername">  <!--  reportNumber -->
+          <el-input v-model="form.servername" placeholder="请输入接口名称"/>
+        </el-form-item>
+        <el-form-item label="接口参数" prop="passid">  <!--  reportName -->
+          <el-input v-model="form.passid" placeholder="请输入接口参数"/>
+        </el-form-item>
+        <el-form-item label="接口令牌" prop="passtoken"> <!--  keyword -->
+          <el-input v-model="form.passtoken" placeholder="请输入接口令牌"/>
+        </el-form-item>
+        <el-form-item label="接口编码" prop="servercode">   <!--  新增的一个 -->
+          <el-input v-model="form.servercode" 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="params_default"> <!--  新增的一个 -->
+          <el-input v-model="form.params_default" placeholder="请输入默认参数"/>
+        </el-form-item>
+        <el-form-item label="默认请求体" prop="body_default" >  <!--  新增的一个 -->
+          <el-input v-model="form.body_default" placeholder="请输入默认请求体"/>
+        </el-form-item>
+        <el-form-item label="默认请求头" prop="header_default"> <!--  新增的一个 -->
+          <el-input v-model="form.header_default" placeholder="请输入默认请求头"/>
+        </el-form-item>
+        <!-- <el-form-item label="发布日期" prop="publishDate">
+          <el-date-picker
+            v-model="form.publishDate"
+            type="date"
+            placeholder="选择发布日期"
+            value-format="yyyy-MM-dd"
+          ></el-date-picker>
+        </el-form-item> -->
+        <!-- <el-col :span="1.5"> -->
+        <!-- 使用分片上传组件,每个分片-->
+        <!-- <chunk-upload :max-file-size="50 * 1024 * 1024" :max-files="5" />
+      </el-col> -->
+      </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 {getDicts} from "@/api/system/dict/data";
+import {ElMessage} from 'element-plus';
+import ChunkUpload from '@/components/ChunkUpload/index.vue';
+// import { DictDataForm, DictDataQuery, DictDataVO } from './type';
+import request from '@/utils/request';
+
+const demoList = 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 demoFormRef = ref();
+
+// const fileList = ref([]);
+
+const dialog = reactive({
+  visible: false,
+  title: ''
+});
+
+const initFormData = {
+  servername: '',
+  passid: '',
+  passtoken: '',
+  servercode: '',
+  eventType: '',
+  params_default: '',
+  body_default: '',
+  header_default: '',
+  publishDate: ''
+};
+
+const data = reactive({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    eventType: '',
+    publishDate: ['', ''],
+    passtoken: '',
+    servercode: ''
+  },
+  rules: {
+    servername: [{required: true, message: '接口名称不能为空', trigger: 'blur'}],
+    passid: [{required: true, message: '接口参数不能为空', trigger: 'blur'}],
+    passtoken: [{required: true, message: '令牌不能为空', trigger: 'blur'}],
+    servercode: [{required: true, message: '接口编码不能为空', trigger: 'blur'}],
+    eventType: [{required: true, message: '事件类型不能为空', trigger: 'blur'}],
+    params_default: [{required: true, message: '默认参数不能为空', trigger: 'blur'}],
+    body_default: [{required: true, message: '请求体不能为空', trigger: 'blur'}],
+    header_default: [{required: true, message: '请求头不能为空', trigger: 'blur'}]
+    //   publishDate: [{required: true, message: '发布日期不能为空', trigger: 'blur'}]
+  },
+  eventTypeSelection: []
+});
+
+const {queryParams, form, rules} = toRefs(data);
+
+const getList = async () => {
+  loading.value = true;
+  try {
+    const response = await fetchReports(queryParams.value);
+    const {data, total} = response;
+    demoList.value = data;
+    total.value = total;
+  } catch (error) {
+    ElMessage.error('获取数据失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 获取报告列表
+const fetchReports = async (params) => {
+  // 假设后端接口为 /api/reports
+  const response = await fetch('/api/oneShare/list', {
+    method: 'GET',
+    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};
+  demoFormRef.value?.resetFields();
+};
+
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
+// 重置查询
+const resetQuery = () => {
+  queryParams.value = {pageNum: 1, pageSize: 10, eventType: '', publishDate: ['', ''], passtoken: '',servercode: ''};
+  handleQuery();
+};
+
+// 获取列表
+const handleSelectionChange = (selection) => {
+  ids.value = selection.map((item) => item.servername);
+  selectedRow.value = selection.length === 1 ? selection[0] : null;
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
+// // 获取列表2
+// export function addData(data: DictDataForm) {
+//   return request({
+//     url: '/api/oneShare/list',
+//     method: 'post',
+//     data: data
+//   });
+// };
+
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = '添加接口';
+};
+
+// 查看报告
+const handleView = (row) => {
+  // 跳转到总结报告详情页
+  window.location.href = `/report/details/${row.reportId}`;
+};
+
+// 修改报告
+const handleUpdate = (row) => {
+  if (row) {
+    reset();
+    Object.assign(form.value, row);
+    dialog.visible = true;
+    dialog.title = '修改报告';
+  }
+};
+// 提交表单
+const submitForm = () => {
+  demoFormRef.value?.validate((valid) => {
+    if (valid) {
+      buttonLoading.value = true;
+      setTimeout(() => {
+        if (form.value.servername) {
+          // 更新逻辑
+        } else {
+          // 添加逻辑
+        }
+        buttonLoading.value = false;
+        dialog.visible = false;
+        getList();
+      }, 500);
+    }
+  });
+};
+
+const handleDelete = (row) => {
+  if (row) {
+    // 删除逻辑
+    setTimeout(() => {
+      demoList.value = demoList.value.filter((item) => item.servername !== row.servername);
+      getList();
+    }, 500);
+  }
+};
+
+const handleExport = () => {
+  // 导出逻辑
+  console.log('导出数据');
+};
+
+// 处理文件上传数量限制
+onMounted(() => {
+  getList();
+  // 取字典值"mm_event_type"
+  getDicts("proxy_handler_one_share_api_type").then(res => {
+    data.eventTypeSelection = res.data;
+  });
+});
+</script>
+

+ 21 - 13
src/views/duty/eventing/CloseEventDialog.vue

@@ -1,6 +1,6 @@
 <template>
-  <el-dialog ref="formDialogRef" :model-value="visible" title="关闭事件" width="750px" append-to-body @close="closeDialog">
-    <el-form ref="userFormRef" :model="form" :rules="rules" label-width="80px">
+  <el-dialog ref="formDialogRef" :model-value="visible" title="关闭事件" width="750px" append-to-body>
+    <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
       <el-row>
         <el-col :span="24">
           <el-form-item label="伤亡情况">
@@ -46,7 +46,7 @@
 </template>
 
 <script lang="ts" setup>
-import { closeEvent, getEventDetail } from '@/api/duty/eventing';
+import { closeEvent } from '@/api/duty/eventing';
 
 interface Form {
   eventId: string;
@@ -58,6 +58,7 @@ interface Form {
 interface Props {
   modelValue: boolean;
   eventId: string;
+  data: Form;
 }
 const props = withDefaults(defineProps<Props>(), {
   modelValue: false
@@ -68,26 +69,33 @@ watch(
   () => props.modelValue,
   () => {
     if (props.modelValue) {
-      getEventDetail({ eventId: props.eventId }).then((res) => {
-        form.value = res.data;
-        debugger;
-      });
+      form.value = props.data;
     }
     visible.value = props.modelValue;
   }
 );
-const router = useRouter();
+
 const visible = ref(false);
 const form = ref<Form>({
+  eventId: '',
   deaths: '',
   injuries: '',
   missing: '',
   fileNames: []
 });
+
+const validateFileCount = (rule, value, callback) => {
+  if (!value || value.length== 0) {
+    return callback(new Error('总结报告不能为空'));
+  }
+  callback();
+};
+
 const rules = reactive({
   deaths: [{ required: true, message: '死亡人数不能为空', trigger: 'blur' }],
   injuries: [{ required: true, message: '受伤人数不能为空', trigger: 'blur' }],
-  missing: [{ required: true, message: '失踪人数不能为空', trigger: 'blur' }]
+  missing: [{ required: true, message: '失踪人数不能为空', trigger: 'blur' }],
+  fileNames: [{ validator: validateFileCount, message: '总结报告不能为空', trigger: 'blur' }]
 });
 const formRef = ref();
 const buttonLoading = ref(false);
@@ -97,16 +105,16 @@ const submitForm = () => {
   formRef.value?.validate(async (valid: boolean) => {
     if (valid) {
       buttonLoading.value = true;
-      closeEvent({ eventId: props.eventId, ...form.value }).then(() => {
-        proxy?.$modal.msgSuccess('关闭事件成功');
-        router.go(-1);
+      closeEvent({ eventId: props.eventId, ...form.value }).then((res) => {
+        proxy?.$modal.msgSuccess(res.msg);
+        closeDialog();
       });
     };
   });
 };
 
 const closeDialog = () => {
-  emits('update:modelValue', false);
+  emits('update:modelValue');
 };
 </script>
 

+ 108 - 0
src/views/duty/eventing/EditCasualtiesDialog.vue

@@ -0,0 +1,108 @@
+<template>
+    <el-dialog ref="formDialogRef" :model-value="visible" title="上报伤亡情况" width="750px" append-to-body>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="伤亡情况">
+              <el-row>
+                <el-col :span="8">
+                  <el-form-item label="死亡" prop="deaths">
+                    <el-input v-model="form.deaths">
+                      <template #append>人</template>
+                    </el-input>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item label="受伤" prop="injuries">
+                    <el-input v-model="form.injuries">
+                      <template #append>人</template>
+                    </el-input>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item label="失联" prop="missing">
+                    <el-input v-model="form.missing">
+                      <template #append>人</template>
+                    </el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确定</el-button>
+          <el-button @click="closeDialog">取消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </template>
+  
+<script lang="ts" setup>
+import { uploadEventCasualties } from '@/api/duty/eventing';
+
+interface Form {
+  eventId: string;
+  deaths: string;
+  injuries: string;
+  missing: string;
+}
+interface Props {
+  modelValue: boolean;
+  eventId: string;
+  data: Form;
+}
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false
+});
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const emits = defineEmits(['update:modelValue']);
+watch(
+  () => props.modelValue,
+  () => {
+    if (props.modelValue) {
+      form.value = props.data;
+    }
+    visible.value = props.modelValue;
+  }
+);
+
+const visible = ref(false);
+const form = ref<Form>({
+  eventId: '',
+  deaths: '',
+  injuries: '',
+  missing: ''
+});
+
+
+const rules = reactive({
+  deaths: [{ required: true, message: '死亡人数不能为空', trigger: 'blur' }],
+  injuries: [{ required: true, message: '受伤人数不能为空', trigger: 'blur' }],
+  missing: [{ required: true, message: '失踪人数不能为空', trigger: 'blur' }]
+});
+const formRef = ref();
+const buttonLoading = ref(false);
+
+// 关闭事件
+const submitForm = () => {
+  formRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      uploadEventCasualties({ eventId: props.eventId, ...form.value }).then((res) => {
+        proxy?.$modal.msgSuccess(res.msg);
+        closeDialog();
+      });
+    };
+  });
+};
+
+const closeDialog = () => {
+  emits('update:modelValue');
+};
+</script>
+
+<style lang="scss" scoped></style>
+  

+ 236 - 0
src/views/duty/eventing/EventEditDialog.vue

@@ -0,0 +1,236 @@
+<template>
+    <el-dialog ref="formDialogRef" :model-value="visible" :title="props.title" width="650px" append-to-body @close="closeDialog">
+        <el-form ref="eventFormRef" :model="form" :rules="rules" label-width="80px">
+            <el-form-item label="事件标题" prop="event_title">
+                <el-input v-model="form.event_title" placeholder="请输入事件标题" />
+            </el-form-item>
+            
+            <el-form-item label="事件类型" prop="event_type">
+                <el-select v-model="form.event_type" placeholder="请选择事件类型" clearable>
+                    <el-option v-for="item in mm_event_type" :key="item.value" :label="item.label" :value="item.value"></el-option>
+                </el-select>
+            </el-form-item>
+            
+            <el-form-item label="事件等级" prop="event_level">
+                <el-select v-model="form.event_level" placeholder="请选择事件等级" clearable style="width:calc(100% - 30px)">
+                    <el-option v-for="item in mm_event_level" :key="item.value" :label="item.label" :value="item.value"></el-option>
+                </el-select>
+                <el-icon @click="eventLevelInfoDialogVisible = true" size="large" style="margin-left:8px"><WarningFilled /></el-icon>
+            </el-form-item>
+            
+            <el-form-item label="事件状态" prop="event_status">
+                <el-select v-model="form.event_status" placeholder="请选择事件状态" clearable :readonly="true">
+                    <el-option v-for="item in mm_event_state" :key="item.value" :label="item.label" :value="item.value"></el-option>
+                </el-select>
+            </el-form-item>
+            
+            <el-form-item label="事发时间" prop="event_time">
+                <el-date-picker v-model="form.event_time" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择事发时间"></el-date-picker>
+            </el-form-item>
+            
+            <el-form-item label="上报时间" prop="report_time">
+                <el-date-picker v-model="form.report_time" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择上报时间"></el-date-picker>
+            </el-form-item>
+            
+            <el-form-item label="伤亡情况">
+                <el-row :gutter="10">
+                    <el-col :span="6">
+                        <el-switch
+                            size="large"
+                            v-model="form.casualties"
+                            inline-prompt
+                            active-text="已上报"
+                            inactive-text="未上报"
+                            active-value="1"
+                            inactive-value="0"
+                        />
+                    </el-col>
+                    <el-col :span="4" v-show="form.casualties === '1'">
+                        <el-input v-model="form.deaths" placeholder="死亡">
+                            <template #suffix>人</template>
+                        </el-input>
+                    </el-col>
+                    <el-col :span="4" v-show="form.casualties === '1'">
+                        <el-input v-model="form.injuries" placeholder="受伤">
+                            <template #suffix>人</template>
+                        </el-input>
+                    </el-col>
+                    <el-col :span="4" v-show="form.casualties === '1'">
+                        <el-input v-model="form.missing" placeholder="失踪">
+                            <template #suffix>人</template>
+                        </el-input>
+                    </el-col>
+                </el-row>
+            </el-form-item>
+            
+            <el-form-item label="联系方式" prop="contact">
+                <el-input v-model="form.contact" placeholder="请输入联系方式" />
+            </el-form-item>
+            
+            <el-form-item label="事件来源" prop="event_source">
+                <el-input v-model="form.event_source" placeholder="请输入事件来源" />
+            </el-form-item>
+            
+            <el-form-item label="事件地点" prop="address">
+                <el-input v-model="form.address" placeholder="请输入事件地点" readonly >
+                    <template #append>
+                        <el-button @click="openMapDialog" type="primary">地图定位</el-button>
+                    </template>
+                </el-input> 
+            </el-form-item>
+
+            <el-form-item label="事件描述" prop="event_description">
+                <el-input type="textarea" v-model="form.event_description" placeholder="请输入事件描述" />
+            </el-form-item>
+        </el-form>
+        <template #footer>
+            <div class="dialog-footer">
+                <el-button :loading="buttonLoading" type="primary" @click="submitForm">确定</el-button>
+                <el-button @click="closeDialog">取消</el-button>
+            </div>
+        </template>
+    </el-dialog>
+
+    <!-- 事故等级弹窗 -->
+    <EventLevelInfoDialog v-model="eventLevelInfoDialogVisible" @closeDialog="closeEventLevelInfoDialog" />
+
+    <!-- 地图弹窗 -->
+    <company-map v-model:visible="mapDialogVisible" :address="form.address" @confirm="handleMapChange"></company-map>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, toRefs } from 'vue';
+import { addEvent, editEvent, postEditEvent } from '@/api/duty/eventing';
+import EventLevelInfoDialog from './EventLevelInfoDialog.vue';
+
+const proxy = getCurrentInstance()?.proxy;
+const { mm_event_type, mm_event_level, mm_event_state, region } = toRefs<any>(proxy?.useDict('mm_event_type', 'mm_event_level', 'mm_event_state', 'region'));
+
+const buttonLoading = ref(false);
+const eventFormRef = ref();
+const visible = ref(false);
+
+interface Props {
+  modelValue: boolean;
+  eventId: string;
+  title: string;
+}
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false
+});
+
+const emits = defineEmits(['update:modelValue']);
+watch(
+  () => props.modelValue,
+  () => {
+    // 界面显示初始化
+    if (props.modelValue) {
+        if(props.eventId != "") {
+            editEvent({ event_id: props.eventId }).then((res) => {
+                form.value = res.data
+            });
+        }
+        else {
+            form.value = { ...initFormData };
+            eventFormRef.value?.resetFields();
+        }
+    }
+    visible.value = props.modelValue;
+  }
+);
+
+// 表单初始数据
+const initFormData = {
+    event_title: '', // 事件标题
+    event_type: '', // 事件类型
+    event_level: '', // 事件等级
+    event_status: '0', // 事件状态
+    address: '', // 事件地点
+    longitude: '', // 经度
+    latitude: '', // 纬度
+    event_time: '',// 事发时间
+    report_time: '',// 上报时间
+    casualties: '0', // 伤亡情况
+    deaths: '',
+    injuries: '',
+    missing: '',
+    event_source: '', // 事件来源
+    event_description: '', // 事件描述
+    contact: '' // 联系方式
+};
+
+// 表单数据
+const data = reactive({
+  form: { ...initFormData },
+  rules: {
+    event_title: [{ required: true, message: '事件标题不能为空', trigger: 'blur' }],
+    event_type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],
+    event_level: [{ required: true, message: '事件等级不能为空', trigger: 'blur' }],
+    event_status: [{ required: true, message: '事件状态不能为空', trigger: 'blur' }],
+    address: [{ required: true, message: '事件地点不能为空', trigger: 'blur' }],
+    event_time: [{ required: true, message: '事发时间不能为空', trigger: 'blur' }],
+    report_time: [{ required: true, message: '上报时间不能为空', trigger: 'blur' }],
+    event_source: [{ required: true, message: '事件来源不能为空', trigger: 'blur' }],
+    event_description: [{ required: true, message: '事件描述不能为空', trigger: 'blur' }],
+    contact: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }]
+  }
+});
+
+const { form, rules } = toRefs(data);
+
+// 提交表单
+const submitForm = () => {
+    eventFormRef.value?.validate((valid) => {
+    if (valid) {
+      buttonLoading.value = true;
+      // 打印表单数据
+      console.log('表单数据', form.value);
+      if(props.eventId === "") {
+        addEvent(form.value)
+            .then((res) => {
+                proxy?.$modal.msgSuccess(res.msg);
+                closeDialog()
+            })
+            .finally(() => {
+            buttonLoading.value = false;
+            });
+      }
+      else {
+        postEditEvent(form.value)
+            .then((res) => {
+                proxy?.$modal.msgSuccess(res.msg);
+                closeDialog()
+            })
+            .finally(() => {
+            buttonLoading.value = false;
+            });
+        }
+    }
+  });
+}
+
+const closeDialog = () => {
+  emits('update:modelValue', false);
+};
+
+
+// 地图定位
+const mapDialogVisible = ref(false);
+const openMapDialog = () => {
+  mapDialogVisible.value = true;
+};
+
+const handleMapChange = (data) => {
+  form.value.address = data.address;
+  form.value.longitude = data.lnglat[0];
+  form.value.latitude = data.lnglat[1];
+  mapDialogVisible.value = false;
+};
+
+// 事故等级弹窗
+const eventLevelInfoDialogVisible = ref(false);
+
+const closeEventLevelInfoDialog = () => {
+  eventLevelInfoDialogVisible.value = false;
+};
+</script>

+ 23 - 0
src/views/duty/eventing/EventLevelInfoDialog.vue

@@ -0,0 +1,23 @@
+<template>
+    <el-dialog title="突发事故分级标准" width="450px" append-to-body @close="closeDialog">
+      <p><strong>一般突发事故:</strong>是指造成3人以下死亡(含失踪),或者10人以下重伤,或者1000万元以下直接经济损失,或产生一定社会影响的。</p>
+      <p><strong>较大突发事故:</strong>是指造成3人以上10人以下死亡(含失踪),或者10人以上50人以下重伤,或者1000万元以上5000万元以下直接经济损失,或产生较大社会影响的。</p>
+      <p><strong>重大突发事故:</strong>是指造成10人以上30人以下死亡(含失踪),或者50人以上100人以下重伤,或者5000万元以上1亿元以下直接经济损失,或产生重大社会影响的。</p>
+      <p><strong>特别重大突发事故:</strong>是指造成30人以上死亡(含失踪),或者100人以上重伤(包括急性工业中毒),或者1亿元以上直接经济损失,或产生特别重大社会影响的。</p>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="closeDialog">关闭</el-button>
+        </div>
+      </template>
+    </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { defineEmits } from 'vue';
+const emits = defineEmits([
+    'closeDialog'
+])
+const closeDialog = () => {
+  emits('closeDialog');
+};
+</script>

+ 132 - 0
src/views/duty/eventing/StartEventDialog.vue

@@ -0,0 +1,132 @@
+<template>
+  <el-dialog ref="formDialogRef" :model-value="visible" title="开始指挥" width="550px" append-to-body @close="closeDialog">
+    <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="事件等级" prop="event_level">
+            <el-select v-model="form.event_level" placeholder="请选择事件等级" clearable style="width:calc(100% - 30px)">
+              <el-option v-for="item in mm_event_level" :key="item.value" :label="item.label" :value="item.value"></el-option>
+            </el-select>
+            <el-icon @click="eventLevelInfoDialogVisible = true" size="large" style="margin-left:8px"><WarningFilled /></el-icon>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24" v-show="false">
+          <el-form-item label="伤亡情况">
+            <el-row>
+              <el-col :span="8">
+                <el-form-item label="死亡" prop="deaths">
+                  <el-input v-model="form.deaths">
+                    <template #append>人</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="受伤" prop="injuries">
+                  <el-input v-model="form.injuries">
+                    <template #append>人</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="失联" prop="missing">
+                  <el-input v-model="form.missing">
+                    <template #append>人</template>
+                  </el-input>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="closeDialog">取 消</el-button>
+      </div>
+    </template>
+  </el-dialog>
+
+  <EventLevelInfoDialog v-model="eventLevelInfoDialogVisible" @closeDialog="closeEventLevelInfoDialog" />
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, toRefs } from 'vue';
+import { startEvent } from '@/api/duty/eventing';
+import EventLevelInfoDialog from './EventLevelInfoDialog.vue';
+
+const proxy = getCurrentInstance()?.proxy;
+const { mm_event_level } = toRefs<any>(proxy?.useDict('mm_event_level'));
+
+interface Form {
+  eventId: string;
+  event_level: string;
+  deaths: string;
+  injuries: string;
+  missing: string;
+}
+interface Props {
+  modelValue: boolean;
+  eventId: string;
+  data: Form;
+}
+const props = withDefaults(defineProps<Props>(), {
+  modelValue: false
+});
+
+const emits = defineEmits(['update:modelValue']);
+watch(
+  () => props.modelValue,
+  () => {
+    if (props.modelValue) {
+      form.value = props.data;
+    }
+    visible.value = props.modelValue;
+  }
+);
+const router = useRouter();
+const visible = ref(false);
+const form = ref<Form>({
+  eventId: '',
+  event_level: '',
+  deaths: '',
+  injuries: '',
+  missing: ''
+});
+const rules = reactive({
+  event_level: [{ required: true, message: '事件等级不能为空', trigger: 'blur' }],
+  deaths: [{ required: true, message: '死亡人数不能为空', trigger: 'blur' }],
+  injuries: [{ required: true, message: '受伤人数不能为空', trigger: 'blur' }],
+  missing: [{ required: true, message: '失踪人数不能为空', trigger: 'blur' }]
+});
+const formRef = ref();
+const buttonLoading = ref(false);
+
+// 关闭事件
+const submitForm = () => {
+  console.log('submitForm');
+  formRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      startEvent({ eventId: props.eventId, ...form.value }).then(() => {
+        proxy?.$modal.msgSuccess('开始指挥');
+        closeDialog()
+      });
+    }
+    else {
+    }
+  });
+};
+
+const closeDialog = () => {
+  emits('update:modelValue', false);
+};
+
+const eventLevelInfoDialogVisible = ref(false);
+
+const closeEventLevelInfoDialog = () => {
+  eventLevelInfoDialogVisible.value = false;
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 183 - 56
src/views/duty/eventing/eventDetails.vue

@@ -5,37 +5,37 @@
       返回上一级
     </div>
     <div class="line">
-      <div class="title">{{ detailData.eventTitle }}</div>
+      <div class="title">{{ detailData.event_title }}</div>
       <div class="flex">
-        <el-button type="primary">编辑</el-button>
-        <el-button type="primary">开始指挥</el-button>
-        <el-button type="danger" @click="handleCloseEvent">关闭事件</el-button>
-        <el-button type="danger">删除事件</el-button>
+        <el-button type="primary" :disabled="detailData.del_flag == '2'" @click="handleUpdate">编辑</el-button>
+        <el-button type="primary" :disabled="detailData.event_status != '0'" @click="handleStartEvent">开始指挥</el-button>
+        <el-button type="danger" :disabled="detailData.event_status != '2'" @click="handleCloseEvent">关闭事件</el-button>
+        <el-button type="danger" :disabled="(detailData.del_flag != '0')" @click="handleDeleteEvent">删除事件</el-button>
       </div>
     </div>
     <div class="sub-title">基础信息</div>
     <div class="line2">
       <div class="line-item">
         <div class="item-label">事件编号:</div>
-        <div class="item-value">{{ detailData.eventId }}</div>
+        <div class="item-value">{{ detailData.event_id }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">事件类型:</div>
         <div class="item-value">
-          <dict-tag :options="mm_event_type" :value="detailData.eventType" />
+          <dict-tag :options="mm_event_type" :value="detailData.event_type" />
         </div>
       </div>
       <div class="line-item">
         <div class="item-label">事件等级:</div>
         <div class="item-value" style="display: flex; align-items: center">
-          <dict-tag :options="mm_event_level" :value="detailData.eventLevel" />
-          <el-icon style="cursor: pointer" @click="handleEventLevelOpen"><Fold /></el-icon>
+          <dict-tag :options="mm_event_level" :value="detailData.event_level" />
+          <el-icon style="margin-left: 20px;cursor: pointer" @click="handleEventLevelOpen"><Fold /></el-icon>
         </div>
       </div>
       <div class="line-item">
         <div class="item-label">事件状态:</div>
         <div class="item-value">
-          <dict-tag :options="mm_event_state" :value="detailData.eventStatus" />
+          <dict-tag :options="mm_event_state" :value="detailData.event_status" />
         </div>
       </div>
     </div>
@@ -46,44 +46,50 @@
       </div>
       <div class="line-item">
         <div class="item-label">事发时间:</div>
-        <div class="item-value">{{ detailData.eventTime }}</div>
+        <div class="item-value">{{ detailData.event_time }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">上报时间:</div>
-        <div class="item-value">{{ detailData.reportTime }}</div>
+        <div class="item-value">{{ detailData.report_time }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">伤亡情况:</div>
-        <div class="flex">
+        <div class="flex" v-if="detailData.casualties == '0'">
           <span>未上报</span>
-          <span class="link" style="margin-left: 20px">去上报</span>
+          <span class="link" style="margin-left: 20px" @click="uploadeCasualties">去上报</span>
+        </div>
+        <div class="flex" v-if="detailData.casualties == '1'">
+          <span>已上报</span>
         </div>
       </div>
     </div>
     <div class="line2">
       <div class="line-item">
         <div class="item-label">登记人:</div>
-        <div class="item-value">{{ detailData.reportedBy }}</div>
+        <div class="item-value">{{ detailData.reported_by }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">登记时间:</div>
-        <div class="item-value">{{ detailData.reportTime }}</div>
+        <div class="item-value">{{ detailData.report_time }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">联系方式:</div>
-        <div class="item-value">18688888888</div>
+        <div class="item-value">{{ detailData.contact }}</div>
       </div>
       <div class="line-item">
         <div class="item-label">事件来源:</div>
-        <div class="item-value">{{detailData.eventSource}}</div>
+        <div class="item-value">{{detailData.event_source}}</div>
       </div>
     </div>
     <div class="sub-title">事件概要</div>
-    <div class="textarea">2024年7月29日14时52分,接xxx报,7月29日12时02分,茂名市xxx公交站西侧出现积水倒灌情况。</div>
+    <div class="textarea">{{detailData.event_description}}</div>
+    
     <div class="sub-title">事件跟踪</div>
+    
     <el-steps :active="eventTrackState.active" :align-center="true" style="width: 100%">
-      <el-step v-for="(item, index) in eventTrackState.listData" :key="index" :title="item.title" :description="item.description"></el-step>
+      <el-step v-for="(item, index) in eventTrackState.items" :key="index" :title="item.title" :description="item.description"></el-step>
     </el-steps>
+    
     <div class="sub-title">指挥记录</div>
     <div class="list">
       <div class="list-item">
@@ -97,12 +103,12 @@
     </div>
     <div class="sub-title">匹配预案</div>
     <div class="list">
-      <div class="list-item2">预案名称11111111</div>
+      <div class="list-item2">{{detailData.plan_name}}</div>
     </div>
     <div class="sub-title">事件总结报告</div>
     <div class="list2">
-      <div class="list-item">
-        <div class="link">关于X市X镇XXX公交站西侧出现积水倒灌事故报告.pdf</div>
+      <div class="list-item" v-for="(item, index) in summaryFiles" :key="index" @click="downloadSummaryFile(item.url)">
+        <div class="link">{{item.file_name}}</div>
         <el-icon class="icon"><Download /></el-icon>
       </div>
     </div>
@@ -115,68 +121,87 @@
           placement="top"
         >
           <div class="dict-item">
-            <dict-tag :options="mm_event_level" :value="item.levelStatus" />
+            <dict-tag :options="mm_event_level" :value="item.level" />
           </div>
         </el-timeline-item>
       </el-timeline>
     </el-dialog>
-    <CloseEventDialog v-model="closeDialogState.show" :eventId="eventId" />
+
+    <CloseEventDialog v-model="closeDialogState.show" :data="closeDialogState.form" :eventId="eventId" @update:model-value="fetchEventDetail" />
+    
+    <StartEventDialog v-model="startDialogState.show" :data="startDialogState.form" :eventId="eventId" @update:model-value="fetchEventDetail" />
+
+    <EventEditDialog v-model="eventEditDialogState.show" :title="eventEditDialogState.title" :eventId="eventId" @update:model-value="fetchEventDetail"/>
+
+    <EditCasualtiesDialog v-model="editCasualtiesDialogState.show" :data="editCasualtiesDialogState.form" :eventId="eventId" @update:model-value="fetchEventDetail"/>
+
   </div>
 </template>
 
 <script lang="ts" setup>
-import { getEventDetail } from '@/api/duty/eventing';
+import { getEventDetail, deleteEvent } from '@/api/duty/eventing';
+import StartEventDialog from './StartEventDialog.vue';
 import CloseEventDialog from './CloseEventDialog.vue';
+import EventEditDialog from './EventEditDialog.vue';
+import EditCasualtiesDialog from './EditCasualtiesDialog.vue';
 
 const route = useRoute();
 const router = useRouter();
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { mm_event_type, mm_event_level, mm_event_state, region } = toRefs<any>(proxy?.useDict('mm_event_type', 'mm_event_level', 'mm_event_state', 'region'));
+
 // 事件等级数据
-const eventLevelState = reactive({
+let eventLevelState = reactive({
   show: false,
-  data: []
-});
-const handleEventLevelOpen = () => {
-  eventLevelState.show = true;
-  eventLevelState.data = [
+  data: [
     {
       timestamp: '2024/7/1 09:00:09',
       name: '张佳佳',
-      levelStatus: '4'
+      level: '4'
     },
     {
       timestamp: '2024/7/1 09:00:09',
       name: '张佳佳',
-      levelStatus: '3'
+      level: '3'
     },
     {
       timestamp: '2024/7/1 09:00:09',
       name: '张佳佳',
-      levelStatus: '2'
+      level: '2'
     },
     {
       timestamp: '2024/7/1 09:00:09',
       name: '张佳佳',
-      levelStatus: '1'
+      level: '1'
     }
-  ];
+  ]
+});
+
+
+const handleEventLevelOpen = () => {
+  eventLevelState.show = true;
 };
 const handleEventLevelClose = () => {
   eventLevelState.show = false;
 };
 
+// 下载总结报告
+let summaryFiles = ref([]);
+const downloadSummaryFile = (url) => {
+  window.open(url);
+};
+
 // 事件跟踪数据
-const eventTrackState = reactive({
-  active: 2,
-  listData: [
+let eventTrackState = reactive({
+  active: 0,
+  items: [
     {
       title: '事件登记',
-      description: '3月01日17:30'
+      description: ''
     },
     {
       title: '进入指挥',
-      description: '3月01日17:30'
+      description: ''
     },
     {
       title: '结束指挥',
@@ -190,35 +215,137 @@ const eventTrackState = reactive({
 });
 // 返回上一级
 const handleBack = () => {
-  proxy?.$tab.closePage();
+  router.go(-1);
 };
+
 let eventId = ref('');
-let detailData = ref({
-  eventId: '',
-  eventTitle: '',
-  eventType: '',
-  eventLevel: '',
-  eventStatus: '',
-  eventTime: '',
+const detailData = ref({
+  event_id: '',
+  event_title: '',
+  event_type: '',
+  event_level: '',
+  event_status: '',
+  event_time: '',
   address: '',
-  reportTime: '',
-  eventSource: '',
-  reportedBy: ''
+  report_time: '',
+  event_source: '',
+  reported_by: '',
+  event_description: '',
+  contact: '',
+  plan_name: '',
+  casualties: '',
+  deaths: '',
+  injuries: '',
+  missing: '',
+  del_flag: ''
+});
+
+let startDialogState = reactive({
+  show: false,
+  form: {
+    eventId: '',
+    event_level: '',
+    deaths: '',
+    injuries: '',
+    missing: ''
+  }
 });
 
 const closeDialogState = reactive({
   show: false,
+  form: {
+    eventId: '',
+    deaths: '',
+    injuries: '',
+    missing: '',
+    fileNames: []
+  }
+});
+
+const editCasualtiesDialogState = reactive({
+  show: false,
+  form: {
+    eventId: '',
+    deaths: '',
+    injuries: '',
+    missing: ''
+  }
 });
 
+// 开始指挥(事件)
+const handleStartEvent = () => {
+  startDialogState.form.eventId = eventId.value
+  startDialogState.form.deaths = detailData.value.deaths
+  startDialogState.form.injuries = detailData.value.injuries
+  startDialogState.form.missing = detailData.value.missing
+  startDialogState.form.event_level = detailData.value.event_level
+  startDialogState.show = true;
+};
+
 // 关闭事件
 const handleCloseEvent = () => {
+  closeDialogState.form.eventId = eventId.value
+  closeDialogState.form.deaths = detailData.value.deaths
+  closeDialogState.form.injuries = detailData.value.injuries
+  closeDialogState.form.missing = detailData.value.missing
+  closeDialogState.form.fileNames = []
   closeDialogState.show = true;
 };
-onMounted(() => {
-  eventId.value = route.query.eventId;
-  getEventDetail({ eventId: eventId.value }).then((res) => {
+
+// 删除事件
+const handleDeleteEvent = () => {
+  ElMessageBox.confirm('确认删除事件吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'info',
+    }).then(() => {
+      deleteEvent({ eventId: eventId.value }).then((res) => {
+        proxy?.$modal.msgSuccess(res.msg);
+        fetchEventDetail()
+      });
+    })
+};
+
+// 上报伤亡情况
+const uploadeCasualties = () => {
+  editCasualtiesDialogState.form.eventId = eventId.value
+  editCasualtiesDialogState.form.deaths = ''
+  editCasualtiesDialogState.form.injuries = ''
+  editCasualtiesDialogState.form.missing = ''
+  editCasualtiesDialogState.show = true;
+}
+
+
+const eventEditDialogState = reactive({
+  show: false,
+  title: ''
+})
+
+const fetchEventDetail =  () => {
+  console.log('fetchEventDetail');
+  closeDialogState.show = false
+  startDialogState.show = false
+  eventEditDialogState.show = false
+  editCasualtiesDialogState.show = false
+
+  getEventDetail({ event_id: eventId.value }).then((res) => {
     detailData.value = res.data;
+    eventTrackState = res.data.event_status_tracks;
+    eventLevelState.data = res.data.event_level_tracks;
+    summaryFiles.value = res.data.summary_file;
   });
+}
+
+
+const handleUpdate = () => {
+  console.log('handleUpdate')
+  eventEditDialogState.title = "修改事件"
+  eventEditDialogState.show = true
+};
+
+onMounted(() => {
+  eventId.value = route.query.event_id as string;
+  fetchEventDetail()
 });
 </script>
 

+ 97 - 190
src/views/duty/eventing/index.vue

@@ -6,8 +6,8 @@
           <el-row :gutter="10">
             <!-- 第一行 -->
             <el-col :span="6">
-              <el-form-item label="事件类型" prop="eventType">
-                <el-select v-model="queryParams.eventType" placeholder="全部" clearable>
+              <el-form-item label="事件类型" prop="event_type">
+                <el-select v-model="queryParams.event_type" placeholder="全部" clearable>
                   <el-option label="全部" value=""></el-option>
                   <el-option
                     v-for="item in mm_event_type"
@@ -19,8 +19,8 @@
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="事件等级" prop="eventLevel">
-                <el-select v-model="queryParams.eventLevel" placeholder="全部" clearable>
+              <el-form-item label="事件等级" prop="event_level">
+                <el-select v-model="queryParams.event_level" placeholder="全部" clearable>
                   <el-option label="全部" value=""></el-option>
                   <el-option
                     v-for="item in mm_event_level"
@@ -32,8 +32,8 @@
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="事件状态" prop="eventStatus">
-                <el-select v-model="queryParams.eventStatus" placeholder="全部" clearable>
+              <el-form-item label="事件状态" prop="event_status">
+                <el-select v-model="queryParams.event_status" placeholder="全部" clearable>
                   <el-option label="全部" value=""></el-option>
                   <el-option
                     v-for="item in mm_event_state"
@@ -45,8 +45,8 @@
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="行政区划" prop="regionCode">
-                <el-select v-model="queryParams.regionCode" placeholder="全部" clearable>
+              <el-form-item label="行政区划" prop="region_code">
+                <el-select v-model="queryParams.region_code" placeholder="全部" clearable>
                   <el-option label="全部" value=""></el-option>
                   <el-option v-for="item in region" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
                 </el-select>
@@ -55,17 +55,17 @@
           </el-row>
           <el-row :gutter="10" class="mt-[10px]">
             <el-col :span="6">
-              <el-form-item label="事发时间" prop="eventTime">
+              <el-form-item label="事发时间" prop="event_time">
                 <el-date-picker
-                  v-model="queryParams.eventTime"
-                  type="datetime"
-                  value-format="YYYY-MM-DD HH:mm:ss"
+                  v-model="queryParams.event_time"
+                  type="date"
+                  value-format="YYYY-MM-DD"
                   placeholder="选择事发时间"
                 ></el-date-picker>
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item>
+              <el-form-item prop="keyword">
                 <el-input v-model="queryParams.keyword" placeholder="请输入事件标题/事件地点" clearable @keyup.enter="handleQuery" />
               </el-form-item>
             </el-col>
@@ -75,6 +75,7 @@
         </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>
@@ -83,28 +84,29 @@
         <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="event_id" />
+      <el-table-column label="事件标题" align="center" prop="event_title" />
+      <el-table-column label="事件类型" align="center" prop="event_type">
         <template #default="scope">
-          <dict-tag :options="mm_event_type" :value="scope.row.eventType" />
+          <dict-tag :options="mm_event_type" :value="scope.row.event_type" />
         </template>
       </el-table-column>
-      <el-table-column label="事件等级" align="center" prop="eventLevel">
+      <el-table-column label="事件等级" align="center" prop="event_level">
         <template #default="scope">
-          <dict-tag :options="mm_event_level" :value="scope.row.eventLevel" />
+          <dict-tag :options="mm_event_level" :value="scope.row.event_level" />
         </template>
       </el-table-column>
       <el-table-column label="事件地点" align="center" prop="address" />
-      <el-table-column label="事件状态" align="center" prop="eventStatus">
+      <el-table-column label="事件状态" align="center" prop="event_status">
         <template #default="scope">
-          <dict-tag :options="mm_event_state" :value="scope.row.eventStatus" />
+          <dict-tag :options="mm_event_state" :value="scope.row.event_status" />
         </template>
       </el-table-column>
-      <el-table-column label="事件时间" align="center" prop="eventTime" />
+      <el-table-column label="事件时间" align="center" prop="event_time" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template #default="scope">
           <el-tooltip content="查看" placement="top">
@@ -119,89 +121,25 @@
         </template>
       </el-table-column>
     </el-table>
+    
+    <EventEditDialog v-model="eventEditDialogState.show" :title="eventEditDialogState.title" :eventId="eventId" @update:model-value="getList"/>
+    <CloseEventDialog v-model="closeDialogState.show" :data="closeDialogState.form" :eventId="eventId" @update:model-value="handleCloseEventDialog" />
 
-    <pagination v-show="total > 0" v-model:page="queryParams.page" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
-
-    <!-- 新增/修改弹窗 -->
-    <el-dialog v-model="dialog.visible" :title="dialog.title" width="650px" 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 mm_event_type" :key="item.value" :label="item.label" :value="item.value"></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 mm_event_level" :key="item.value" :label="item.label" :value="item.value"></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 mm_event_state" :key="item.value" :label="item.label" :value="item.value"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="事件地点" prop="address">
-          <el-button type="primary" @click="openMapDialog">地图定位</el-button>
-          <el-input v-model="form.address" placeholder="请输入事件地点" readonly />
-        </el-form-item>
-        <el-form-item label="事发时间" prop="eventTime">
-          <el-date-picker v-model="form.eventTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择事发时间"></el-date-picker>
-        </el-form-item>
-        <el-form-item label="上报时间" prop="reportTime">
-          <el-date-picker v-model="form.reportTime" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择上报时间"></el-date-picker>
-        </el-form-item>
-        <el-form-item label="伤亡情况">
-          <el-row :gutter="10">
-            <el-col :span="6">
-              <el-input v-model="form.deaths" placeholder="死亡">
-                <template #suffix>人</template>
-              </el-input>
-            </el-col>
-            <el-col :span="6">
-              <el-input v-model="form.injuries" placeholder="受伤">
-                <template #suffix>人</template>
-              </el-input>
-            </el-col>
-            <el-col :span="6">
-              <el-input v-model="form.missing" placeholder="失踪">
-                <template #suffix>人</template>
-              </el-input>
-            </el-col>
-          </el-row>
-        </el-form-item>
-        <el-form-item label="事件来源" prop="eventSource">
-          <el-input v-model="form.eventSource" placeholder="请输入事件来源" />
-        </el-form-item>
-        <el-form-item label="事件描述" prop="eventDescription">
-          <el-input type="textarea" v-model="form.eventDescription" placeholder="请输入事件描述" />
-        </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>
-    <CloseEventDialog v-model="closeDialogState.show" :eventId="closeDialogState.eventId" />
-    <!-- 地图弹窗 -->
-    <company-map v-model:visible="mapDialogVisible" :address="form.address" @confirm="handleMapChange"></company-map>
+    <pagination v-show="total > 0" v-model:page="queryParams.page" v-model:limit="queryParams.page_size" :total="total" @pagination="getList" />
   </div>
 </template>
 
 <script setup lang="ts">
 import { ref, reactive, toRefs, onMounted } from 'vue';
-import { addEvent, getEvent } from '@/api/duty/eventing';
-import CloseEventDialog from '@/views/duty/eventing/CloseEventDialog.vue';
+import { getEvent, deleteEvent } from '@/api/duty/eventing';
+
+import EventEditDialog from './EventEditDialog.vue';
+import CloseEventDialog from './CloseEventDialog.vue';
 
 const proxy = getCurrentInstance()?.proxy;
 const { mm_event_type, mm_event_level, mm_event_state, region } = toRefs<any>(proxy?.useDict('mm_event_type', 'mm_event_level', 'mm_event_state', 'region'));
 const router = useRouter();
 const eventList = ref([]);
-const buttonLoading = ref(false);
 const loading = ref(true);
 const showSearch = ref(true);
 const ids = ref([]);
@@ -209,62 +147,46 @@ const single = ref(true);
 const multiple = ref(true);
 const total = ref(0);
 const selectedRow = ref(null);
-
+const eventId = ref('');
 const queryFormRef = ref();
-const eventFormRef = ref();
 
-const dialog = reactive({
-  visible: false,
-  title: ''
-});
  // 表单初始数据
 const initFormData = {
-  // eventId: '',
-  eventTitle: '', // 事件标题
-  eventType: '', // 事件类型
-  eventLevel: '', // 事件等级
-  eventStatus: '', // 事件状态
+  event_title: '', // 事件标题
+  event_type: '', // 事件类型
+  event_level: '', // 事件等级
+  event_status: '', // 事件状态
   address: '', // 事件地点
   longitude: '', // 经度
   latitude: '', // 纬度
-  eventTime: '',// 事发时间
-  reportTime: '',// 上报时间
+  event_time: '',// 事发时间
+  report_time: '',// 上报时间
   deaths: '',
   injuries: '',
   missing: '',
-  eventSource: '', // 事件来源
-  eventDescription: '' // 事件描述
+  event_source: '', // 事件来源
+  event_description: '', // 事件描述
+  contact: '' // 联系方式
 };
 // 表单数据
 const data = reactive({
   form: { ...initFormData },
   queryParams: {
     page: 1,
-    pageSize: 10,
-    eventType: '',
-    eventLevel: '',
-    eventStatus: '',
-    eventTime: '',
-    regionCode: '',
+    page_size: 10,
+    event_type: '',
+    event_level: '',
+    event_status: '',
+    event_time: '',
+    region_code: '',
     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' }],
-    reportTime: [{ required: true, message: '上报时间不能为空', trigger: 'blur' }],
-    eventSource: [{ required: true, message: '事件来源不能为空', trigger: 'blur' }],
-    eventDescription: [{ required: true, message: '事件描述不能为空', trigger: 'blur' }]
-  },
-  eventLevelSelection: [],
-  eventStatusSelection: [],
+  event_levelSelection: [],
+  event_statusSelection: [],
   regionSelection: []
 });
 
-const { queryParams, form, rules } = toRefs(data);
+const { queryParams, form } = toRefs(data);
 
 const getList = () => {
   loading.value = true;
@@ -278,16 +200,6 @@ const getList = () => {
     });
 };
 
-const cancel = () => {
-  reset();
-  dialog.visible = false;
-};
-
-const reset = () => {
-  form.value = { ...initFormData };
-  eventFormRef.value?.resetFields();
-};
-
 const handleQuery = () => {
   queryParams.value.page = 1;
   getList();
@@ -295,7 +207,7 @@ const handleQuery = () => {
 
 // 重置查询条件
 const resetQuery = () => {
-  queryParams.value = { page: 1, pageSize: 10, eventType: '', eventLevel: '', eventStatus: '', eventTime: '', regionCode: '', keyword: '' };
+  queryParams.value = { page: 1, page_size: 10, event_type: '', event_level: '', event_status: '', event_time: '', region_code: '', keyword: '' };
   handleQuery();
 };
 
@@ -306,60 +218,69 @@ const handleSelectionChange = (selection) => {
   multiple.value = !selection.length;
 };
 
+const eventEditDialogState = reactive({
+  show: false,
+  title: ''
+})
+
 const handleAdd = () => {
-  reset();
-  dialog.visible = true;
-  dialog.title = '新增事件';
+  eventId.value = ""
+  eventEditDialogState.title = "新增事件"
+  eventEditDialogState.show = true
 };
 
 // 修改事件
 const handleUpdate = (row) => {
   if (row) {
-    reset();
-    Object.assign(form.value, row);
-    dialog.visible = true;
-    dialog.title = '修改事件';
+    eventId.value = row.event_id;
+    eventEditDialogState.title = "修改事件"
+    eventEditDialogState.show = true
   }
 };
 
-// 提交表单
-const submitForm = () => {
-  eventFormRef.value?.validate((valid) => {
-    if (valid) {
-      buttonLoading.value = true;
-      // 打印表单数据
-      console.log('表单数据', form.value);
-      addEvent(form.value)
-        .then(() => {
-          dialog.visible = false;
-          getList();
-        })
-        .finally(() => {
-          buttonLoading.value = false;
-        });
-    }
-  });
-};
-
 const handleDelete = (row) => {
   if (row) {
-    // 删除逻辑
-    setTimeout(() => {
-      eventList.value = eventList.value.filter((item) => item.eventId !== row.eventId);
-      getList();
-    }, 500);
+    ElMessageBox.confirm('确认删除事件吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'info',
+    }).then(() => {
+      eventList.value = eventList.value.filter((item) => item.eventId !== row.event_id);
+      deleteEvent({ eventId: row.event_id }).then((res) => {
+        proxy?.$modal.msgSuccess(res.msg);
+        setTimeout(() => {
+          getList();
+        }, 500);
+      });
+    })
   }
 };
 
+// 关闭事件
 const closeDialogState = reactive({
   show: false,
-  eventId: ''
+  form: {
+    eventId: '',
+    deaths: '',
+    injuries: '',
+    missing: '',
+    fileNames: []
+  }
 });
 
-// 关闭事件
 const handleClose = (row) => {
-  row.eventId = row.eventId;
-  closeDialogState.show = true;
+  if (row) {
+    console.log(row)
+    closeDialogState.form.eventId = row.event_id
+    closeDialogState.form.deaths = row.deaths
+    closeDialogState.form.injuries = row.injuries
+    closeDialogState.form.missing = row.missing
+    closeDialogState.show = true;
+  }
+};
+
+const handleCloseEventDialog = (b) => {
+  console.log('handleCloseEventDialog', b)
 };
 
 // 查看事件详情
@@ -369,25 +290,11 @@ const handleView = (row) => {
     console.log('查看事件详情', row);
     router.push({
       path: '/duty/eventing/eventDetails',
-      query: { eventId: row.eventId }
+      query: { event_id: row.event_id }
     });
   }
 };
 
-// 地图定位
-const mapDialogVisible = ref(false);
-
-const openMapDialog = () => {
-  mapDialogVisible.value = true;
-};
-
-const handleMapChange = (data) => {
-  form.value.address = data.address;
-  form.value.longitude = data.lnglat[0];
-  form.value.latitude = data.lnglat[1];
-  mapDialogVisible.value = false;
-};
-
 onMounted(() => {
   getList();
 });