Bladeren bron

feat: 添加设备告警管理模块,优化导入导出功能及相关表格配置

sunqijun 1 maand geleden
bovenliggende
commit
7f44191baa

+ 17 - 1
src/router/routers/production-safety-router/risk-identification-and-control.ts

@@ -382,6 +382,22 @@ const riskIdentificationAndControlRoutes: RouteComponent[] = [{
         noCache: false,
       }
     },
+    // 设备告警管理
+    {
+      id: 93036,
+      parentId: 90014,
+      name: 'equipmentHighAlert',
+      path: 'equipment-high-alert',
+      component: '/production-safety/risk-identification-and-control/equipment-high-alert/list',
+      meta: {
+        title: '设备告警管理',
+        icon: 'OverviewIcon',
+        activeMenu: '/work-safety/risk-identification-and-control/equipment-high-alert',
+        isRoot: false,
+        hidden: false,
+        noCache: false,
+      }
+    },
     {
       id: 93019,
       parentId: 90014,
@@ -587,6 +603,7 @@ const riskIdentificationAndControlRoutes: RouteComponent[] = [{
       component: '/production-safety/risk-identification-and-control/work-injury-apply-manage/list',
       meta: {
         title: '工伤认定申请',
+        activeMenu: '/work-safety/risk-identification-and-control/work-injury-apply-manage',
         icon: 'OverviewIcon',
         isRoot: false,
         hidden: false,
@@ -640,5 +657,4 @@ const riskIdentificationAndControlRoutes: RouteComponent[] = [{
     },
   ],
 }];
-
 export default riskIdentificationAndControlRoutes; 

+ 10 - 10
src/views/production-safety/implement-safety-duty/non-public-list-responsibilities/list.vue

@@ -18,6 +18,7 @@
           "
           >添加
         </el-button>
+        <el-button @click="batchImportVisible = true">导入</el-button>
       </div>
       <div class="search-form">
         <el-form :inline="true">
@@ -57,11 +58,9 @@
         </el-form>
 
         <div>
-          <!-- <el-button @click="batchImportVisible = true">导入</el-button>
-          <el-button type="primary" @click="handleDownload">导出</el-button> -->
-
           <el-button type="primary" @click="queryTableList">查询</el-button>
           <el-button @click="handleRestParams">重置</el-button>
+          <el-button @click="handleDownload">导出</el-button>
         </div>
       </div>
 
@@ -166,7 +165,7 @@
     :visible="batchImportVisible"
     :importApiUrl="importApiUrl"
     :templateUrl="templateUrl"
-    :templateName="'责任清单-批量导入模版'"
+    :templateName="'责任清单(非区域管理员)-批量导入模版'"
     @close="() => (batchImportVisible = false)"
     @update="handleUpdate"
   />
@@ -191,6 +190,7 @@
   import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
   import { getAllDepartments } from '@/api/auth/dept';
   import { useUserInfoHook } from '@/views/disaster/hooks';
+  import { downloadByData } from '@/utils/file/download';
 
   const { id } = useUserInfoHook();
   const router = useRouter();
@@ -259,13 +259,13 @@
   };
 
   async function handleDownload() {
-    // getQuery();
     try {
-      const res = await areaCheckListExportArea(queryParams.queryParam);
-      if (res.size === 0) return;
-      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
-      const url = window.URL.createObjectURL(blob);
-      downloadFile(url, '责任清单.xlsx');
+      const response = await areaCheckListExportArea(queryParams.queryParam);
+        if (response) {
+            const fileName = `责任清单(非区域管理员)_${new Date().toISOString().split('T')[0]}.xlsx`;
+            downloadByData(response, fileName);
+            ElMessage.success('导出成功');
+        }
     } catch (e) {
       ElMessage.error('下载失败');
       console.log(e);

+ 9 - 1
src/views/production-safety/implement-safety-duty/public-list-responsibilities/list.vue

@@ -314,7 +314,15 @@
     });
   };
   const queryTableList = () => {
-    areaCheckListQueryPage(queryParams).then((res) => {
+    let params = {
+        pageNumber: queryParams.pageNumber,
+        pageSize: queryParams.pageSize,
+        queryParam:{
+            ...queryParams.queryParam,
+            safetyResponsibleDepartmentId: JSON.stringify(queryParams.queryParam.safetyResponsibleDepartmentId)
+        }
+    }
+    areaCheckListQueryPage(params).then((res) => {
       tableData.data = res.records;
       tableData.total = res.totalRow;
     });

+ 74 - 0
src/views/production-safety/risk-identification-and-control/equipment-high-alert/configs/form.ts

@@ -0,0 +1,74 @@
+/*
+ * @Author: liuJie
+ * @Date: 2026-03-05 10:11:20
+ * @LastEditors: liuJie
+ * @LastEditTime: 2026-03-10 14:44:38
+ * @Describe: file describe
+ */
+import type { FormConfig } from '@/types/basic-form';
+
+/** 设备类别选项(设备类别名称) */
+export const DEVICE_CATEGORY_OPTIONS = [
+  { label: 'GC2', value: 1 },
+  { label: '机动工艺车辆', value: 2 },
+];
+
+/** 设备种类选项(设备种类名称) */
+export const DEVICE_TYPE_OPTIONS = [
+  { label: '压力容器', value: 1 },
+  { label: '固定式压力容器', value: 2 },
+  { label: '压力管道', value: 3 },
+];
+
+
+export const SPECIAL_EQUIPMENT_FORM_DATA = {
+  deviceId: '',
+  assetId: '',
+  deviceName: '',
+  useUnit: '',
+  categoryId: undefined as number | undefined,
+  typeId: undefined as number | undefined,
+  registerCode: '',
+  licenseNo: '',
+  deviceCode: '',
+  safeLocation: '',
+  useDepartment: '',
+  responsibilityDeptId: undefined as number | undefined,
+  responsiblePerson: '',
+  jobNo: '',
+  factoryNo: '',
+  productionDate: '',
+  startUseDate: '',
+  inspectionCycle: undefined as number | undefined,
+  useYears: undefined as number | undefined,
+  inspectionTime: '',
+  deviceStatus: 1,
+  nextInspectionDate: '',
+};
+
+export const SPECIAL_EQUIPMENT_FORM_RULES = {
+  deviceId: [{ required: true, message: '设备ID不能为空', trigger: 'blur' }],
+  assetId: [{ required: true, message: '设备固资ID不能为空', trigger: 'blur' }],
+  deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
+  useUnit: [{ required: true, message: '使用单位不能为空', trigger: 'blur' }],
+  categoryId: [{ required: true, message: '请选择设备类别', trigger: 'change' }],
+  typeId: [{ required: true, message: '请选择设备种类', trigger: 'change' }],
+  registerCode: [{ required: true, message: '注册代码不能为空', trigger: 'blur' }],
+  licenseNo: [{ required: true, message: '使用证号不能为空', trigger: 'blur' }],
+  // deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }],
+  safeLocation: [{ required: true, message: '安全地点不能为空', trigger: 'blur' }],
+  useDepartment: [{ required: true, message: '请选择使用部门', trigger: 'change' }],
+  responsibilityDeptId: [{ required: true, message: '请选择责任部门', trigger: 'change' }],
+  responsiblePerson: [{ required: true, message: '责任人不能为空', trigger: 'blur' }],
+  jobNo: [{ required: true, message: '工号不能为空', trigger: 'blur' }],
+  // factoryNo: [{ required: true, message: '出厂编号不能为空', trigger: 'blur' }],
+  // productionDate: [{ required: true, message: '请选择生产日期', trigger: 'change' }],
+  startUseDate: [{ required: true, message: '请选择启用日期', trigger: 'change' }],
+  inspectionCycle: [{ required: true, message: '检测周期不能为空', trigger: 'blur' }],
+  useYears: [{ required: true, message: '使用年限不能为空', trigger: 'blur' }],
+  inspectionTime: [{ required: true, message: '请选择检测时间', trigger: 'change' }],
+  deviceStatus: [{ required: true, message: '请选择设备状态', trigger: 'change' }],
+  // nextInspectionDate: [{ required: true, message: '请选择下次检测时间', trigger: 'change' }],
+};
+
+

+ 93 - 0
src/views/production-safety/risk-identification-and-control/equipment-high-alert/configs/tables.ts

@@ -0,0 +1,93 @@
+/*
+ * @Author: liuJie
+ * @Date: 2026-02-26 13:57:24
+ * @LastEditors: liuJie
+ * @LastEditTime: 2026-03-10 14:43:50
+ * @Describe: file describe
+ */
+import type { TableColumnProps } from '@/types/basic-table';
+
+// 特种设备设施管理 - 表格基础配置
+export const TABLE_OPTIONS = {
+  emptyText: '暂无数据',
+  loading: true,
+  maxHeight: 'calc(70vh - 150px)',
+};
+
+export const SPECIAL_EQUIPMENT_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '序号',
+    type: 'index',
+    align: 'center',
+    width: '80px',
+  },
+  {
+    label: '设备编号',
+    prop: 'deviceNo',
+    align: 'left',
+    minWidth: '160px',
+  },
+  {
+    label: '设备类型',
+    prop: 'deviceType',
+    align: 'left',
+    minWidth: '160px',
+  },
+  {
+    label: '所属部门',
+    prop: 'deptName',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '所属区域',
+    prop: 'regionName',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '告警名称',
+    prop: 'alarmTitle',
+    align: 'left',
+    minWidth: '180px',
+  },
+  {
+    label: '告警内容',
+    prop: 'alarmContent',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '告警类型',
+    prop: 'alarmType',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '告警时刻',
+    prop: 'firstAlarmTime',
+    align: 'center',
+    minWidth: '140px',
+  },
+  {
+    label: '告警次数',
+    prop: 'alarmCount',
+    align: 'center',
+    minWidth: '140px',
+  },
+  {
+    label: '告警来源',
+    prop: 'location',
+    align: 'center',
+    minWidth: '140px',
+  },
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
+    width: '220px',
+    align: 'left',
+  },
+];
+

+ 374 - 0
src/views/production-safety/risk-identification-and-control/equipment-high-alert/list.vue

@@ -0,0 +1,374 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <div class="breadcrumb-title">告警列表</div>
+    </header>
+    <main class="safety-platform-container__main">
+      <div class="search-table-container">
+        <header>
+          <div class="act-search">
+            <section class="select-box">
+                <div class="select-box--item">
+                <span>搜索设备编号:</span>
+                <el-input
+                  v-model="queryParams.queryParam.deviceNo"
+                  placeholder="请输入设备编号"
+                  class="act-search-input"
+                  clearable
+                />
+              </div>
+              <div class="select-box--item">
+                <span>搜索设备名称:</span>
+                <el-input
+                  v-model="queryParams.queryParam.deviceName"
+                  placeholder="请输入设备名称"
+                  class="act-search-input"
+                  clearable
+                />
+              </div>
+              <div class="select-box--item">
+                <span>设备类型:</span>
+                <el-select
+                  v-model="queryParams.queryParam.deviceType"
+                  placeholder="请选择设备类型"
+                  clearable
+                  class="act-search-input"
+                >
+                  <el-option
+                    v-for="opt in DEVICE_CATEGORY_OPTIONS"
+                    :key="opt.value"
+                    :label="opt.label"
+                    :value="opt.value"
+                  />
+                </el-select>
+              </div>
+              <div class="select-box--item">
+                <span>所属部门:</span>
+                <el-cascader
+                  v-model="useDeptPath"
+                  :options="deptOptions"
+                  :props="deptCascaderProps"
+                  :show-all-levels="false"
+                  placeholder="请选择责任部门"
+                  class="act-search-input"
+                  filterable
+                  clearable
+                  @change="handleUseDeptChange"
+                />
+              </div>
+              <div>
+                <span>计划日期范围:</span>
+                <el-date-picker
+                  v-model="dateRange"
+                  type="daterange"
+                  range-separator="至"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                />
+              </div>
+            </section>
+            <section class="search-btn">
+              <el-button type="primary" @click="queryTableList">查询</el-button>
+              <el-button @click="handleRestParams">重置</el-button>
+              <el-button plain  @click="handleDownload">
+               导出
+              </el-button>
+            </section>
+          </div>
+        </header>
+
+        <div class="batch-table">
+          <BasicTable
+            ref="basicTableRef"
+            :tableData="tableData"
+            :tableConfig="tableConfig"
+            @update:pageSize="handleSizeChange"
+            @update:pageNumber="handleCurrentChange"
+          >
+            <template #action="scope">
+              <div class="action-container--div" style="justify-content: left">
+                <ActionButton
+                  text="查看"
+                  @click="handleView(scope.row)"
+                />
+              </div>
+            </template>
+          </BasicTable>
+        </div>
+      </div>
+    </main>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { onMounted, reactive, ref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import {
+    querySpecialEquipmentPage,
+    deleteSpecialEquipment,
+    exportSpecialEquipment,
+    type SpecialEquipment,
+    type SpecialEquipmentQueryParam,
+  } from '@/api/production-safety/special-equipment';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
+  import BasicTable from '@/components/BasicTable.vue';
+  import useTableConfig from '@/hooks/useTableConfigHook';
+  import ActionButton from '@/components/ActionButton.vue';
+  import { TABLE_OPTIONS, SPECIAL_EQUIPMENT_TABLE_COLUMNS } from './configs/tables';
+  import { DEVICE_CATEGORY_OPTIONS, DEVICE_TYPE_OPTIONS } from './configs/form';
+  import { downloadByData } from '@/utils/file/download';
+import { http } from '@/utils/http/axios';
+  import dayjs from 'dayjs';
+  const loading = ref(false);
+  const dateRange = ref<[string, string] | null>(null);
+  interface  QueryParamType {
+    pageNumber: number;
+    pageSize: number;
+    queryParam: {
+      //设备编码
+      deviceNo?: string | undefined;
+      //设备名称
+      deviceName?: string | undefined;
+      // 设备类型
+      deviceType?: string | number | undefined;
+      // 所属部门
+      deptName?: string | undefined;
+      // 开始时间
+      startTime: string | undefined,
+      // 结束
+      endTime: string | undefined,
+    };
+  }
+  // 列表数据
+const equipmentHighAlertList = (query: QueryParamType)=>{
+  return http.request({
+    url: '/prodAlarm/queryProdAlarm',
+    method: 'post',
+    data: query,
+  });
+}
+// 导出接口
+const exportTableData = (params)=>{
+    return http.request({
+        url: '/prodAlarm/export',
+        method: 'post',
+        data: params,
+        responseType: 'blob',
+    }, {
+        isTransformResponse: false,
+    });
+}
+
+  // BasicTable
+  const basicTableRef = ref<InstanceType<typeof BasicTable>>();
+  const { tableConfig, pagination } = useTableConfig(SPECIAL_EQUIPMENT_TABLE_COLUMNS, TABLE_OPTIONS);
+
+  const queryParams = reactive<QueryParamType>({
+    pageNumber: 1,
+    pageSize: 10,
+    queryParam: {
+      //设备编码
+      deviceNo: undefined,
+      //设备名称
+      deviceName: undefined,
+      // 设备类型
+      deviceType: undefined,
+      // 所属部门
+      deptName: undefined,
+      // 开始时间
+      startTime: undefined,
+      // 结束
+      endTime: undefined,
+    },
+  });
+
+  // 部门树(queryAllDeptTree 样式)
+  const deptOptions = ref<any[]>([]);
+  const useDeptPath = ref<number[]>([]);
+  const deptCascaderProps = {
+    expandTrigger: 'click',
+    checkStrictly: true,
+    value: 'id',
+    label: 'deptName',
+  };
+
+  const tableData = ref([]);
+
+  const handleSizeChange = (value: number) => {
+    pagination.pageSize = value;
+    queryParams.pageSize = value;
+    queryParams.pageNumber = 1;
+    queryTableList();
+  };
+
+  const handleCurrentChange = (value: number) => {
+    pagination.pageNumber = value;
+    queryParams.pageNumber = value;
+    queryTableList();
+  };
+
+  const getStatusText = (status?: number, statusName?: string) => {
+    if (statusName) return statusName;
+    if (status === 1) return '在用';
+    if (status === 2) return '停用';
+    if (status === 3) return '报废';
+    return '-';
+  };
+
+  const loadDeptTree = async () => {
+    try {
+      const res = await getAllDepartments();
+      deptOptions.value = formatDeptTree(res);
+    } catch (e) {
+      console.error('获取部门树失败:', e);
+      deptOptions.value = [];
+    }
+  };
+
+  const handleUseDeptChange = (val: number[]) => {
+    if (Array.isArray(val) && val.length) {
+      queryParams.queryParam.deptName = JSON.stringify(val[val.length - 1]);
+    } else {
+      queryParams.queryParam.deptName = undefined;
+    }
+  };
+
+  const handleView = (row)=>{
+    ElMessage.warning('请给跳转地址')
+  }
+
+
+  const queryTableList = () => {
+    loading.value = true;
+    tableConfig.loading = true;
+    let data = {
+        pageNumber: queryParams.pageNumber,
+        pageSize: queryParams.pageSize,
+        queryParam:{
+            ...queryParams.queryParam,
+            startTime: dateRange?.[0]
+                ? dayjs(dateRange?.[0]).format('YYYY-MM-DD')
+                : undefined,
+            endTime: dateRange?.[1]
+                ? dayjs(dateRange?.[1]).format('YYYY-MM-DD')
+                : undefined,
+        }
+    }
+    equipmentHighAlertList({
+        ...queryParams
+
+    })
+      .then((res: any) => {
+        tableData.value = res?.records;
+        pagination.total = res?.totalRow ?? res?.total ?? 0;
+      })
+      .finally(() => {
+        loading.value = false;
+        tableConfig.loading = false;
+      });
+  };
+// 导出相关
+  const handleDownload = async () => {
+    try {
+      const response = await exportTableData(queryParams.queryParam);
+      if (response) {
+        const fileName = `告警列表_${new Date().toISOString().split('T')[0]}.xlsx`;
+        downloadByData(response, fileName);
+        ElMessage.success('导出成功');
+      }
+    } catch (e) {
+      console.error('导出告警列表失败:', e);
+      ElMessage.error('导出失败,请重试');
+    }
+  };
+
+  const handleRestParams = () => {
+    pagination.pageNumber = 1;
+    pagination.pageSize = 10;
+    queryParams.pageNumber = 1;
+    queryParams.pageSize = 10;
+    queryParams.queryParam = {
+      //设备编码
+      deviceNo: undefined,
+      //设备名称
+      deviceName: undefined,
+      // 设备类型
+      deviceType: undefined,
+      // 所属部门
+      deptName: undefined,
+      // 开始时间
+      startTime: undefined,
+      // 结束
+      endTime: undefined,
+    };
+    useDeptPath.value = [];
+    dateRange.value = null
+    queryTableList();
+  };
+
+  onMounted(() => {
+    loadDeptTree();
+    queryTableList();
+  });
+</script>
+
+<style lang="scss" scoped>
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+  @use '@/views/traffic/violation/style/act-search-table.scss' as *;
+
+  :deep(.el-tabs__header) {
+    margin: 0;
+  }
+  :deep(.el-tabs__item) {
+    font-size: 14px !important;
+  }
+  :deep(.flexContent) {
+    display: flex;
+  }
+  :deep(.breadcrumb .title) {
+    margin-left: 0;
+  }
+
+  :deep(.el-form) {
+    flex: 1;
+    display: flex;
+    row-gap: 15px;
+    flex-wrap: wrap;
+  }
+  :deep(.el-form-item) {
+    margin-bottom: 0;
+  }
+  :deep(main) {
+    display: flex;
+    flex-direction: column;
+  }
+  .search-form {
+    min-width: 800px;
+    display: flex;
+
+    justify-content: space-between;
+    align-items: flex-end;
+    margin-bottom: 20px;
+  }
+
+  .button-content {
+    margin-bottom: 20px;
+  }
+  .table-content {
+    flex: 1;
+    overflow: hidden;
+    overflow-y: auto;
+  }
+  .page-content {
+    display: flex;
+    justify-content: flex-end;
+  }
+  .dateRange {
+    align-items: flex-end;
+  }
+</style>

+ 1 - 1
src/views/production-safety/risk-identification-and-control/work-injury-apply-manage/Item.vue

@@ -2,7 +2,7 @@
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
       <BreadcrumbBack />
-      <span class="breadcrumb-title">{{ headerTitle }}</span>
+      <span class="breadcrumb-title">{{ headerTitle }} 1212121</span>
     </header>
     <Detail />
   </div>

+ 7 - 7
src/views/production-safety/safetyTrainingAndEducation/educationTrainingPlanManagement/educationTrainingPlanManagement.vue

@@ -185,11 +185,11 @@
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
     queryParam: {
-      keyword: '',
-      status: '',
-      categoryName: '',
-      startDate: '',
-      endDate: '',
+      keyword: undefined,
+      status: undefined,
+      categoryName: undefined,
+      startDate: undefined,
+      endDate: undefined,
     },
   });
 
@@ -208,8 +208,8 @@
   async function getTableData() {
     tableConfig.loading = true;
     try {
-      tableQuery.queryParam.startDate = dateRange.value ? dateRange.value[0] : '';
-      tableQuery.queryParam.endDate = dateRange.value ? dateRange.value[1] : '';
+      tableQuery.queryParam.startDate = dateRange.value ? dateRange.value[0] : undefined;
+      tableQuery.queryParam.endDate = dateRange.value ? dateRange.value[1] : undefined;
       const res = await getEducationAndTrainingProgramList(tableQuery);
       if (res) {
         // 映射返回数据字段到表格字段