소스 검색

feat: 新版本系统通知

qindao 1 년 전
부모
커밋
f4d0b112c2

+ 103 - 97
src/router/full-routes.ts

@@ -26,15 +26,14 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'console',
         name: 'DashboardConsole',
         component: '/dashboard/home/Home',
-        meta: { 
+        meta: {
           icon: '',
           title: '首页',
         },
-      }
-    ]
+      },
+    ],
   },
 
-
   /**
    * 场景管理
    */
@@ -42,7 +41,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/scene',
     name: 'Scene',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'ApartmentOutlined',
       title: '场景管理',
     },
@@ -52,7 +51,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'template',
         name: 'SceneTemplate',
         component: '/templateManage/templateManage',
-        meta: { 
+        meta: {
           icon: '',
           title: '模板管理',
         },
@@ -62,9 +61,9 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'workshop',
         name: 'SceneWorkshop',
         component: '/system-config/scene-manage/SceneManage',
-        meta: { 
+        meta: {
           icon: '',
-          title: '车间管理' 
+          title: '车间管理',
         },
       },
       {
@@ -72,12 +71,12 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'business',
         name: 'SceneBusiness',
         component: '/system-config/business-scene/PageBusinessScene',
-        meta: { 
+        meta: {
           icon: '',
           title: '业务创建管理',
         },
-      }
-    ]
+      },
+    ],
   },
 
   /**
@@ -87,9 +86,9 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/device',
     name: 'Device',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'CameraOutlined',
-      title: '设备管理'
+      title: '设备管理',
     },
     children: [
       {
@@ -97,9 +96,9 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'camera',
         name: 'DeviceCamera',
         component: '/cameras/overview/CamerasOverview',
-        meta: { 
+        meta: {
           icon: '',
-          title: '相机设备'
+          title: '相机设备',
         },
       },
       {
@@ -107,12 +106,12 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'nvr',
         name: 'DeviceNVR',
         component: '/cameras/nvrlist/NvrList',
-        meta: { 
+        meta: {
           icon: '',
-          title: 'NVR设备'
+          title: 'NVR设备',
         },
-      }
-    ]
+      },
+    ],
   },
 
   /**
@@ -122,7 +121,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/layout',
     name: 'Layout',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'PictureOutlined',
       title: '布局管理',
     },
@@ -132,9 +131,9 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'scene',
         name: 'LayoutScene',
         component: '/page-config/PageScene',
-        meta: { 
+        meta: {
           icon: '',
-          title: '场景布局', 
+          title: '场景布局',
         },
       },
       {
@@ -146,7 +145,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
           icon: '',
           title: '场景布局列表',
           activeMenu: 'LayoutScene',
-        }
+        },
       },
       {
         // 公司场景配置页面(菜单不可见)
@@ -157,41 +156,41 @@ const fullRoutes: AppRouteRecordRaw[] = [
           icon: '',
           title: '场景布局配置',
           activeMenu: 'LayoutScene',
-        }
+        },
       },
       {
         // 相机布局入口页,选择PC端还是手机端
         path: 'camera',
         name: 'LayoutCamera',
         component: '/page-config/PageCamera',
-        meta: { 
+        meta: {
           icon: '',
           title: '相机布局',
-        }
+        },
       },
       {
         // 相机布局卡片列表。 菜单不可见
         path: 'camera-list',
         name: 'LayoutCameraList',
         component: '/page-config/PageCameraList',
-        meta: { 
+        meta: {
           icon: '',
           title: '相机布局列表',
           activeMenu: 'LayoutCamera',
-        }
+        },
       },
       {
         // 相机布局配置
         path: 'camera-config',
         name: 'LayoutCameraConfig',
         component: '/map-config/mini-map/MiniMapConfig',
-        meta: { 
+        meta: {
           icon: '',
           title: '相机布局配置',
           activeMenu: 'LayoutCamera',
-        }
-      }
-    ]
+        },
+      },
+    ],
   },
 
   /**
@@ -201,7 +200,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/algorithm',
     name: 'Algorithm',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'FunctionOutlined',
       title: '算法管理',
     },
@@ -211,7 +210,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'preview',
         name: 'AlgorithmPreview',
         component: '/cameras/algo-management/algoManagement',
-        meta: { 
+        meta: {
           icon: '',
           title: '算法预览',
         },
@@ -221,12 +220,12 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'config',
         name: 'AlgorithmConfig',
         component: '/cameras/preview/CameraPreview',
-        meta: { 
+        meta: {
           ico: '',
           title: '算法配置',
         },
-      }
-    ]
+      },
+    ],
   },
 
   /**
@@ -236,7 +235,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/user',
     name: 'User',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'UserOutlined',
       title: '用户管理',
     },
@@ -246,30 +245,30 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'account',
         name: 'UserAccount',
         component: '/system/user/user',
-        meta: { 
+        meta: {
           icon: '',
           title: '账号管理',
-        }
+        },
       },
       {
         // 角色管理
         path: 'role',
         name: 'UserRole',
         component: '/system/role/role',
-        meta: { 
+        meta: {
           icon: '',
           title: '角色管理',
-        }
+        },
       },
       {
         // 组织管理
         path: 'department',
         name: 'UserDepartment',
         component: '/auth/dept/dept',
-        meta: { 
+        meta: {
           icon: '',
           title: '组织管理',
-        }
+        },
       },
       {
         // 岗位管理 (目前不需要)
@@ -278,10 +277,10 @@ const fullRoutes: AppRouteRecordRaw[] = [
         component: '/auth/post/post',
         meta: {
           icon: '',
-          title: '岗位管理'
-        }
-      }
-    ]
+          title: '岗位管理',
+        },
+      },
+    ],
   },
 
   /**
@@ -291,17 +290,17 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/message',
     name: 'Message',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'SendOutlined',
       title: '消息管理',
     },
     children: [
       {
-        // 报表推送 
+        // 报表推送
         path: 'report',
         name: 'MessageReport',
         component: '/message/reportmessage/ReportMessage',
-        meta: { 
+        meta: {
           icon: '',
           title: '报表推送',
         },
@@ -311,7 +310,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'report-config',
         name: 'MessageReportConfig',
         component: '/message/reportmessage/ReportOperation',
-        meta: { 
+        meta: {
           icon: '',
           title: '报表推送配置',
           activeMenu: 'MessageReport',
@@ -322,7 +321,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'alarm',
         name: 'MessageAlarm',
         component: '/message/alarmMessages/alarmMessages',
-        meta: { 
+        meta: {
           icon: '',
           title: '报警推送',
         },
@@ -332,7 +331,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'alarm-config',
         name: 'MessageAlarmConfig',
         component: '/message/alarm-config/AlarmConfig',
-        meta: { 
+        meta: {
           icon: '',
           title: '报警推送配置',
           activeMenu: 'MessageAlarm',
@@ -343,7 +342,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'sys-notification',
         name: 'MessageSysNotification',
         component: '/message/systemNotifications/systemNotifications',
-        meta: { 
+        meta: {
           icon: '',
           title: '系统通知',
         },
@@ -353,24 +352,33 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'sys-notification-config',
         name: 'MessageSysNotificationConfig',
         component: '/message/sysnotion-config/SysnotionConfig',
-        meta: { 
+        meta: {
           icon: '',
           title: '系统通知配置',
           activeMenu: 'MessageSysNotification',
         },
-      }, 
+      },
       {
         // 人员分组
         path: 'personnel-group',
         name: 'MessagePersonnelGroup',
         component: '/message/persongroup/UserGroup',
-        meta: { 
+        meta: {
           icon: '',
           title: '人员分组',
         },
-      }
-
-    ]
+      },
+      {
+        // 问题处理通知
+        path: 'question-notification',
+        name: 'QuestionNotification',
+        component: '/message/questionNotifications/questionNotifications',
+        meta: {
+          icon: '',
+          title: '问题处理通知',
+        },
+      },
+    ],
   },
 
   /**
@@ -392,8 +400,8 @@ const fullRoutes: AppRouteRecordRaw[] = [
         component: '/datamanager/platformdata/PlatformData',
         meta: {
           icon: '',
-          title: '平台统计'
-        }
+          title: '平台统计',
+        },
       },
       {
         // 历史视频 (视频回看)
@@ -402,8 +410,8 @@ const fullRoutes: AppRouteRecordRaw[] = [
         component: '/datamanager/playback/Playback',
         meta: {
           icon: '',
-          title: '历史视频'
-        }
+          title: '历史视频',
+        },
       },
       {
         // 违规问题
@@ -412,10 +420,10 @@ const fullRoutes: AppRouteRecordRaw[] = [
         component: '/datamanager/alertformdata/AlertformData',
         meta: {
           icon: '',
-          title: '违规问题'
-        }
+          title: '违规问题',
+        },
       },
-    ]
+    ],
   },
 
   /**
@@ -425,7 +433,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     path: '/system',
     name: 'System',
     component: 'LAYOUT',
-    meta: { 
+    meta: {
       icon: 'OptionsSharp',
       title: '系统管理',
     },
@@ -435,40 +443,40 @@ const fullRoutes: AppRouteRecordRaw[] = [
         path: 'tenant',
         name: 'SystemTenant',
         component: '/system/tenant/tenant',
-        meta: { 
+        meta: {
           icon: '',
           title: '租户管理',
-        }
+        },
       },
       {
         // 菜单管理
         path: 'menu',
         name: 'SystemMenu',
         component: '/system/menu/menu',
-        meta: { 
+        meta: {
           icon: '',
           title: '菜单管理',
-        }
+        },
       },
       {
         // 权限管理
         path: 'permission',
         name: 'SystemPermission',
         component: '/system/permssion/PagePermission',
-        meta: { 
+        meta: {
           icon: '',
           title: '权限管理',
-        }
+        },
       },
       {
         // 意见反馈
         path: 'feedback',
         name: 'SystemFeedback',
         component: '/feedback/feedback',
-        meta: { 
+        meta: {
           icon: '',
           title: '意见反馈',
-        }
+        },
       },
       {
         // 反馈处理 (菜单不可见)
@@ -479,34 +487,34 @@ const fullRoutes: AppRouteRecordRaw[] = [
           icon: '',
           title: '反馈处理',
           activeMenu: 'SystemFeedback',
-        }
+        },
       },
       {
         // 字典管理
         path: 'dictionary',
         name: 'SystemDictionary',
         component: '/system/dictionary/dictionary',
-        meta: { 
+        meta: {
           icon: '',
           title: '字典管理',
-        }
+        },
       },
       {
         // 系统管理
         path: 'log',
         name: 'SystemLog',
         component: '/system/log/log',
-        meta: { 
+        meta: {
           icon: '',
           title: '日志管理',
-        }
+        },
       },
-    ]
+    ],
   },
 
   /**
-  * 异常页面
-  */
+   * 异常页面
+   */
   {
     path: '/exception',
     name: 'Exception',
@@ -514,7 +522,7 @@ const fullRoutes: AppRouteRecordRaw[] = [
     redirect: '/exception/403',
     meta: {
       icon: 'ExclamationCircleOutlined',
-      title: '异常页面', 
+      title: '异常页面',
     },
     children: [
       {
@@ -544,13 +552,11 @@ const fullRoutes: AppRouteRecordRaw[] = [
           icon: '',
           title: '500',
         },
-        
       },
-    ]
+    ],
   },
 ] as const;
 
-
 /**
  * 类型定义。避免与已有的定义冲突,避免与 vue-router的类型定义冲突,前面加 _ 前缀
  */
@@ -565,10 +571,10 @@ export type _RouteViewTree = _RouteView[];
  * 获取指定 父路由 下的子路由。
  * 若 父级路由 未指定,则返回一级路由
  */
-export function getChildRoutesView(parentRouteName?: string | null ): _RouteViewItem[] {
+export function getChildRoutesView(parentRouteName?: string | null): _RouteViewItem[] {
   // 未指定 parentRouteName, 则返回 level1 的路由
   if (parentRouteName == null) {
-    return fullRoutes.map(route => ({
+    return fullRoutes.map((route) => ({
       label: route.meta.title as string,
       value: route.name,
     }));
@@ -577,7 +583,7 @@ export function getChildRoutesView(parentRouteName?: string | null ): _RouteView
   // 获取指定父路由的子路由
   const parentRoute: AppRouteRecordRaw = cloneDeep(getTreeItem(fullRoutes, parentRouteName, 'name'));
   if (parentRoute.children && parentRoute.children.length > 0) {
-    return parentRoute.children.map(route => ({
+    return parentRoute.children.map((route) => ({
       label: route.meta.title as string,
       value: route.name,
     }));
@@ -600,12 +606,12 @@ export function transformToRouteViewTree(routes?: AppRouteRecordRaw[] | null) {
   const tree: _RouteViewTree = [];
   if (routes == null) return tree;
 
-  for(const route of routes) {
+  for (const route of routes) {
     const treeItem: _RouteView = {
       value: route.name,
       label: route.meta.title as string,
-      children: null
-    }
+      children: null,
+    };
 
     if (route.children && route.children.length > 0) {
       treeItem.children = transformToRouteViewTree(route.children);
@@ -614,8 +620,8 @@ export function transformToRouteViewTree(routes?: AppRouteRecordRaw[] | null) {
       tree.push(treeItem);
     }
   }
-  
+
   return tree;
 }
 
-export const routeViewTree = transformToRouteViewTree(fullRoutes);
+export const routeViewTree = transformToRouteViewTree(fullRoutes);

+ 11 - 15
src/views/message/questionNotifications/components/problemHandleTable.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="questionNotifications">
     <div style="padding-bottom: 24px; border-top: 1px solid rgba(0, 0, 0, 0.06)">
       <div class="pushWorkShopBar">
         <span class="pushiWorkShopSpan">选择推送范围:</span>
@@ -13,12 +13,7 @@
           @click="handleWorkShopEdit"
           @change="handleWorkShopEdit"
         >
-          <el-option
-            v-for="item in options"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
+          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
         </el-select>
         <!-- <img src="../img/edit.png" @click="handleWorkShopEdit()" /> -->
       </div>
@@ -42,11 +37,7 @@
       class="workShopDialog"
     >
       <!-- <WorkShopTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-      <WorkShopTree
-        @cancel="handleCancle"
-        :selectedUser="selectedUser"
-        :re-fresh-camera="setCameraChosen"
-      />
+      <WorkShopTree @cancel="handleCancle" :selectedUser="selectedUser" :re-fresh-camera="setCameraChosen" />
     </el-dialog>
     <el-dialog
       v-model="showDialog"
@@ -85,10 +76,10 @@
     getPushRange,
   } from '@/api/message/question-notifications';
 
-  import WorkShopTree from './WorkShopTree.vue';
-  import ManageContent from './ManageContent.vue';
+  import WorkShopTree from './components/WorkShopTree.vue';
+  import ManageContent from './components/ManageContent.vue';
   import { ElMessage } from 'element-plus';
-  import { treeSelected } from '../type';
+  import { treeSelected } from './type';
 
   const cameraChosen = ref<any>([]);
 
@@ -166,6 +157,11 @@
   });
 </script>
 <style lang="scss" scoped>
+  .questionNotifications {
+    // height: calc(100vh - 64px - 18px);
+    background-color: rgba(255, 255, 255, 1);
+    padding: 21px;
+  }
   .pushWorkShopBar {
     margin: 11px 0 8px 0;
     display: flex;

+ 0 - 218
src/views/message/systemNotifications/components/systemNotificationTable.vue

@@ -1,218 +0,0 @@
-<template>
-  <SearchBar />
-
-  <el-button
-    type="primary"
-    @click="createNotification"
-    style="margin-top: 24px; margin-bottom: 16px; width: 138px"
-  >
-    <img src="../img/create.png" style="margin-top: -1px; margin-right: 5px" />新建系统通知
-  </el-button>
-
-  <el-table
-    :data="sysNotionData"
-    stripe
-    height="calc(100vh - 400px)"
-    style="width: 100%; margin-top: 16px; --el-table-border-color: none"
-  >
-    <el-table-column prop="title" label="消息标题" />
-
-    <el-table-column width="300" prop="pushChannel" label="推送渠道">
-      <template #default="scope">
-        <div>
-          {{ scope.row.pushChannel.map((channel) => pushChannelMapping[channel]).join(',') }}
-        </div>
-      </template>
-    </el-table-column>
-
-    <el-table-column width="200" prop="recipientType" label="推送对象">
-      <template #default="scope">
-        <div>
-          {{ recipientTypeMapping[scope.row.recipientType] }}
-        </div>
-      </template>
-    </el-table-column>
-
-    <el-table-column width="135" prop="status" label="推送状态">
-      <template #default="scope">
-        <img src="../img//prepareToPush.png" alt="" v-if="scope.row.status === 0" />
-        <img src="../img/completed.png" alt="" v-else />
-      </template>
-    </el-table-column>
-
-    <el-table-column prop="pushAt" label="推送时间" width="200px" />
-
-    <el-table-column label="操作" fixed="right" width="120px">
-      <template #default="scope">
-        <div class="operation">
-          <el-tooltip effect="light" content="查看" placement="bottom">
-            <img src="@/views/message/alarmMessages/img/view.png" @click="handleView(scope.row.id, 'view')" />
-          </el-tooltip>
-           <el-tooltip class="box-item" effect="light" content="编辑" placement="bottom" v-if="scope.row.status === PushStatusEnum.PEDDING">
-              <img src="@/views/message/alarmMessages/img/edit.png" @click="handleView(scope.row.id, 'edit')" />
-            </el-tooltip>
-          <el-tooltip effect="light" content="删除" placement="bottom">
-            <img src="@/views/message/alarmMessages/img/delete.png" @click="handleDelete(scope.row.id)" />
-          </el-tooltip>
-        </div>
-      </template>
-    </el-table-column>
-
-    <template #empty>
-      <div class="emptyDiv">
-        <img src="../img/empty.png" class="emptyImg" />
-        <span class="emptySpan">暂无数据</span>
-      </div>
-    </template>
-  </el-table>
-
-  <div class="pagination" v-if="total != 0">
-    <el-pagination
-      :page-sizes="[10, 20, 30, 40, 50, 80]"
-      :small="false"
-      :background="true"
-      layout="total, sizes, prev, pager, next, jumper"
-      :total="total"
-      @size-change="handleSizeChange"
-      @current-change="handleCurrentChange"
-    />
-  </div>
-
-  <el-dialog v-model="deleteDialog" width="424px" top="20%" class="deleteDialog">
-    <template #header="">
-      <div class="deleteDialogHeader">
-        <img src="../img/deleteTip.png" class="deleteTip" />
-        <span class="titleSpan">请确认是否删除</span>
-      </div>
-    </template>
-    <span style="margin-left: 37px">删除之后,该条数据将无法恢复</span>
-    <div class="dialogBottom">
-      <el-button class="dialogBtn" @click="deleteDialog = false">取消</el-button>
-      <el-button class="dialogBtn" type="primary" @click="confirmDelete">确定</el-button>
-    </div>
-  </el-dialog>
-</template>
-<script lang="ts" setup>
-  import { ref, onMounted } from 'vue';
-  import { useRouter } from 'vue-router';
-  import { pushChannelMapping, recipientTypeMapping, PushStatusEnum } from '../type';
-  import SearchBar from './SearchBar.vue';
-  import { storeToRefs } from 'pinia';
-  import useSysNotion from '../store/index';
-  import { deleteSystemMessage } from '@/api/message/system-notifications';
-  import { ElMessage } from 'element-plus';
-
-  const sysNotion = useSysNotion();
-  const { total, page, pagesize, sysNotionData } = storeToRefs(sysNotion);
-  const { getSysNotion } = sysNotion;
-  const deleteDialog = ref(false);
-  const router = useRouter();
-  type ViewModel = 'view' | 'edit';
-
-  const createNotification = () => {
-    router.push('/message/sys-notification-config');
-  };
-
-  const handleView = (id: number, model: ViewModel ) => {
-    router.push(`/message/sys-notification-config?id=${id}&viewModel=${model}`);
-  };
-  const deleteId = ref<number>(0);
-  const handleDelete = (id: number) => {
-    deleteDialog.value = true;
-    deleteId.value = id;
-  };
-
-  const confirmDelete = () => {
-    deleteSystemMessage(deleteId.value).then(() => {
-      ElMessage({
-        message: '删除成功',
-        type: 'success',
-        plain: true,
-      });
-      deleteDialog.value = false;
-      getSysNotion();
-    });
-  };
-
-  const handleSizeChange = (newPageSize: number) => {
-    pagesize.value = newPageSize;
-    getSysNotion();
-  };
-
-  const handleCurrentChange = (newCurrentPage: number) => {
-    page.value = newCurrentPage;
-    getSysNotion();
-  };
-
-  onMounted(() => {
-    getSysNotion();
-  });
-</script>
-<style lang="scss" scoped>
-  .pagination {
-    position: absolute;
-    bottom: 35px;
-    right: 67px;
-  }
-
-  .deleteDialog {
-    .deleteDialogHeader {
-      display: flex;
-      .deleteTip {
-        height: 24px;
-        width: 24px;
-      }
-      .titleSpan {
-        height: 24px;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 24px;
-        text-align: center;
-        margin-left: 12px;
-      }
-    }
-    .dialogBottom {
-      display: flex;
-      justify-content: flex-end;
-      margin-top: 12px;
-    }
-  }
-
-  .operation {
-    display: flex;
-    
-    img + img {
-      margin-left: 20px;
-    }
-
-    button {
-     margin-: 20px;
-    }
-  }
-
-  .emptyDiv {
-    margin-top: 78px;
-    margin: auto;
-    width: 396px;
-    .emptyImg {
-      height: 257px;
-    }
-    .emptySpan {
-      font-family: PingFangSC, PingFang SC;
-      font-weight: 400;
-      font-size: 18px;
-      color: rgba(0, 0, 0, 0.45);
-      text-align: left;
-      font-style: normal;
-    }
-  }
-
-  :deep(.el-dialog) {
-    border-radius: 8px;
-  }
-  .pushstatus {
-    display: flex;
-    justify-content: center;
-    width: 100%;
-  }
-</style>

+ 216 - 59
src/views/message/systemNotifications/systemNotifications.vue

@@ -1,83 +1,240 @@
 <template>
   <div class="notificationPage">
-    <div class="notificationSelectionBar">
-      <div
-        :class="
-          currentNotification === notificationType.system ? 'snotificationSelected' : 'notification'
-        "
-        @click="changeNotification(notificationType.system)"
-        >系统消息通知</div
+    <el-card class="mb-3 proCard">
+      <el-space>
+        <SearchBar />
+      </el-space>
+    </el-card>
+    <el-card>
+      <template #header>
+        <el-button
+          type="primary"
+          @click="createNotification"
+          style="margin-top: 24px; margin-bottom: 16px; width: 138px"
+        >
+          <img src="./img/create.png" style="margin-top: -1px; margin-right: 5px" />新建系统通知
+        </el-button>
+      </template>
+      <el-table
+        :data="sysNotionData"
+        stripe
+        height="calc(100vh - 380px)"
+        style="width: 100%; margin-top: 16px; --el-table-border-color: none"
       >
-      <div
-        :class="
-          currentNotification === notificationType.problemHandle
-            ? 'pnotificationSelected'
-            : 'notification'
-        "
-        @click="changeNotification(notificationType.problemHandle)"
-        >问题处理通知</div
-      >
-    </div>
+        <el-table-column prop="title" label="消息标题" />
+
+        <el-table-column width="300" prop="pushChannel" label="推送渠道">
+          <template #default="scope">
+            <div>
+              {{ scope.row.pushChannel.map((channel) => pushChannelMapping[channel]).join(',') }}
+            </div>
+          </template>
+        </el-table-column>
+
+        <el-table-column width="200" prop="recipientType" label="推送对象">
+          <template #default="scope">
+            <div>
+              {{ recipientTypeMapping[scope.row.recipientType] }}
+            </div>
+          </template>
+        </el-table-column>
+
+        <el-table-column width="135" prop="status" label="推送状态">
+          <template #default="scope">
+            <img src="../img//prepareToPush.png" alt="" v-if="scope.row.status === 0" />
+            <img src="../img/completed.png" alt="" v-else />
+          </template>
+        </el-table-column>
 
-    <systemNotificationTable v-if="currentNotification === notificationType.system" />
-    <problemHandleTable v-if="currentNotification === notificationType.problemHandle" />
+        <el-table-column prop="pushAt" label="推送时间" width="200px" />
+
+        <el-table-column label="操作" fixed="right" width="120px">
+          <template #default="scope">
+            <div class="operation">
+              <el-tooltip effect="light" content="查看" placement="bottom">
+                <img src="@/views/message/alarmMessages/img/view.png" @click="handleView(scope.row.id, 'view')" />
+              </el-tooltip>
+              <el-tooltip
+                class="box-item"
+                effect="light"
+                content="编辑"
+                placement="bottom"
+                v-if="scope.row.status === PushStatusEnum.PEDDING"
+              >
+                <img src="@/views/message/alarmMessages/img/edit.png" @click="handleView(scope.row.id, 'edit')" />
+              </el-tooltip>
+              <el-tooltip effect="light" content="删除" placement="bottom">
+                <img src="@/views/message/alarmMessages/img/delete.png" @click="handleDelete(scope.row.id)" />
+              </el-tooltip>
+            </div>
+          </template>
+        </el-table-column>
+
+        <template #empty>
+          <div class="emptyDiv">
+            <img src="../img/empty.png" class="emptyImg" />
+            <span class="emptySpan">暂无数据</span>
+          </div>
+        </template>
+      </el-table>
+      <section class="mt-4 flex justify-end">
+        <div class="pagination" v-if="total != 0">
+          <el-pagination
+            :page-sizes="[10, 20, 30, 40, 50, 80]"
+            :small="false"
+            :background="true"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+          />
+        </div>
+      </section>
+    </el-card>
+    <el-dialog v-model="deleteDialog" width="424px" top="20%" class="deleteDialog">
+      <template #header="">
+        <div class="deleteDialogHeader">
+          <img src="../img/deleteTip.png" class="deleteTip" />
+          <span class="titleSpan">请确认是否删除</span>
+        </div>
+      </template>
+      <span style="margin-left: 37px">删除之后,该条数据将无法恢复</span>
+      <div class="dialogBottom">
+        <el-button class="dialogBtn" @click="deleteDialog = false">取消</el-button>
+        <el-button class="dialogBtn" type="primary" @click="confirmDelete">确定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import { ref } from 'vue';
-  import systemNotificationTable from './components/systemNotificationTable.vue';
-  import problemHandleTable from '../questionNotifications/components/problemHandleTable.vue';
+  import { ref, onMounted } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { pushChannelMapping, recipientTypeMapping, PushStatusEnum } from './type';
+  import SearchBar from './components/SearchBar.vue';
+  import { storeToRefs } from 'pinia';
+  import useSysNotion from './store/index';
+  import { deleteSystemMessage } from '@/api/message/system-notifications';
+  import { ElMessage } from 'element-plus';
 
-  enum notificationType {
-    system,
-    problemHandle,
-  }
-  const currentNotification = ref(notificationType.system);
+  const sysNotion = useSysNotion();
+  const { total, page, pagesize, sysNotionData } = storeToRefs(sysNotion);
+  const { getSysNotion } = sysNotion;
+  const deleteDialog = ref(false);
+  const router = useRouter();
+  type ViewModel = 'view' | 'edit';
+
+  const createNotification = () => {
+    router.push('/message/sys-notification-config');
+  };
+
+  const handleView = (id: number, model: ViewModel) => {
+    router.push(`/message/sys-notification-config?id=${id}&viewModel=${model}`);
+  };
+  const deleteId = ref<number>(0);
+  const handleDelete = (id: number) => {
+    deleteDialog.value = true;
+    deleteId.value = id;
+  };
+
+  const confirmDelete = () => {
+    deleteSystemMessage(deleteId.value).then(() => {
+      ElMessage({
+        message: '删除成功',
+        type: 'success',
+        plain: true,
+      });
+      deleteDialog.value = false;
+      getSysNotion();
+    });
+  };
+
+  const handleSizeChange = (newPageSize: number) => {
+    pagesize.value = newPageSize;
+    getSysNotion();
+  };
 
-  const changeNotification = (notificationType: notificationType) => {
-    currentNotification.value = notificationType;
+  const handleCurrentChange = (newCurrentPage: number) => {
+    page.value = newCurrentPage;
+    getSysNotion();
   };
+
+  onMounted(() => {
+    getSysNotion();
+  });
 </script>
 
 <style lang="scss" scoped>
   .notificationPage {
-    height: calc(100vh - 64px - 18px);
+    // height: calc(100vh - 64px - 18px);
     background-color: rgba(255, 255, 255, 1);
-    padding: 24px 44px 35px 21px;
-    position: relative;
+    padding: 21px;
+  }
+
+  .pagination {
+    position: absolute;
+    bottom: 35px;
+    right: 67px;
+  }
+
+  .deleteDialog {
+    .deleteDialogHeader {
+      display: flex;
+      .deleteTip {
+        height: 24px;
+        width: 24px;
+      }
+      .titleSpan {
+        height: 24px;
+        font-size: 16px;
+        color: rgba(0, 0, 0, 0.88);
+        line-height: 24px;
+        text-align: center;
+        margin-left: 12px;
+      }
+    }
+    .dialogBottom {
+      display: flex;
+      justify-content: flex-end;
+      margin-top: 12px;
+    }
   }
 
-  .notificationSelectionBar {
+  .operation {
     display: flex;
-    width: 376px;
-    height: 38px;
-    border: 1px solid #d9d9d9;
-    background: rgba(0, 0, 0, 0.02);
-    margin-bottom: 24px;
-    cursor: pointer;
-    border-radius: 4px;
-    .notification {
-      width: 50%;
-      background: rgba(0, 0, 0, 0.02);
-      line-height: 36px;
-      text-align: center;
+
+    img + img {
+      margin-left: 20px;
     }
-    .snotificationSelected {
-      width: 50%;
-      outline: 1px solid #1890ff;
-      background: rgba(24, 144, 255, 0.15);
-      line-height: 36px;
-      text-align: center;
-      border-radius: 4px 0 0 4px;
+
+    button {
+      margin-: 20px;
+    }
+  }
+
+  .emptyDiv {
+    margin-top: 78px;
+    margin: auto;
+    width: 396px;
+    .emptyImg {
+      height: 257px;
     }
-    .pnotificationSelected {
-      width: 50%;
-      outline: 1px solid #1890ff;
-      background: rgba(24, 144, 255, 0.15);
-      line-height: 36px;
-      text-align: center;
-      border-radius: 0 4px 4px 0;
+    .emptySpan {
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 400;
+      font-size: 18px;
+      color: rgba(0, 0, 0, 0.45);
+      text-align: left;
+      font-style: normal;
     }
   }
+
+  :deep(.el-dialog) {
+    border-radius: 8px;
+  }
+  .pushstatus {
+    display: flex;
+    justify-content: center;
+    width: 100%;
+  }
 </style>

+ 103 - 86
src/views/system/log/components/LoginLog.vue

@@ -5,19 +5,19 @@
 <template>
   <div class="login-log">
     <el-card class="mb-3 proCard">
-      <el-space >
-        <el-form ref="searchFormRef" :inline="true" :model="requestParams.queryParam" class="form-inline" >
+      <el-space>
+        <el-form ref="searchFormRef" :inline="true" :model="requestParams.queryParam" class="form-inline">
           <el-form-item prop="queryType">
-           <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select" >
-              <el-option
-                v-for="item in queryTypeSelect"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-              />
+            <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select">
+              <el-option v-for="item in queryTypeSelect" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
-            <el-input v-model="requestParams.queryParam.queryTypeContent" clearable placeholder="请输入搜索关键字"
-              @keyup.enter="queryLoginLogPage" :disabled="requestParams.queryParam.queryType === ''" />
+            <el-input
+              v-model="requestParams.queryParam.queryTypeContent"
+              clearable
+              placeholder="请输入搜索关键字"
+              @keyup.enter="queryLoginLogPage"
+              :disabled="requestParams.queryParam.queryType === ''"
+            />
           </el-form-item>
           <el-form-item label="终端类型" prop="device">
             <el-select v-model="requestParams.queryParam.device" placeholder="请选择终端类型" clearable>
@@ -25,23 +25,33 @@
             </el-select>
           </el-form-item>
           <el-form-item label="登录时间" prop="date">
-            <el-date-picker 
-              v-model="requestParams.queryParam.date" 
-              type="daterange" 
-              placeholder="请选择登录时间" 
+            <el-date-picker
+              v-model="requestParams.queryParam.date"
+              type="daterange"
+              placeholder="请选择登录时间"
               range-separator="~"
               start-placeholder="开始时间"
               end-placeholder="结束时间"
               :disabled-date="disabledDate"
-              clearable 
+              clearable
               format="YYYY/MM/DD"
               value-format="YYYY/MM/DD"
-              />
+            />
           </el-form-item>
           <el-form-item label="请选择组织:" label-position="left" prop="deptId">
-            <el-tree-select type="daterange" range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间"
-              v-model="requestParams.queryParam.deptId" :data="departmentList" :render-after-expand="false"
-              :default-expand-all="true" check-strictly placeholder="请选择组织" class="protocal-select" />
+            <el-tree-select
+              type="daterange"
+              range-separator="To"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              v-model="requestParams.queryParam.deptId"
+              :data="departmentList"
+              :render-after-expand="false"
+              :default-expand-all="true"
+              check-strictly
+              placeholder="请选择组织"
+              class="protocal-select"
+            />
           </el-form-item>
           <el-form-item>
             <el-button type="primary" :icon="Search" @click="queryLoginLogPage">查询</el-button>
@@ -59,75 +69,83 @@
         <el-table-column type="index" label="序号" width="100" />
         <el-table-column label="登录账号" prop="userName" />
         <el-table-column label="姓名" prop="realName" />
-        <el-table-column label="组织"  prop="deptName" />
-        <el-table-column label="客户端" prop="device" >
-          <template #default="{row}">
+        <el-table-column label="组织" prop="deptName" />
+        <el-table-column label="客户端" prop="device">
+          <template #default="{ row }">
             <el-icon :size="24" color="#409eff" v-if="row.device === ClientTypeEnum.PC"><Platform /></el-icon>
             <el-icon :size="24" color="#409eff" v-else><Iphone /></el-icon>
           </template>
         </el-table-column>
-        <el-table-column label="操作类型"  prop="type" >
-        <template #default="{row}">
-          <el-tag
-            :type="row.type === OperationTypeEnum.LOGIN ? 'success' : 'danger'"
-            round
-          >
-            {{  row.type === OperationTypeEnum.LOGIN ? '登录': '登出' }}
-          </el-tag>
-        </template>
+        <el-table-column label="操作类型" prop="type">
+          <template #default="{ row }">
+            <el-tag :type="row.type === OperationTypeEnum.LOGIN ? 'success' : 'danger'" round>
+              {{ row.type === OperationTypeEnum.LOGIN ? '登录' : '登出' }}
+            </el-tag>
+          </template>
         </el-table-column>
-        <el-table-column label="操作结果" prop="loginStatus" >
+        <el-table-column label="操作结果" prop="loginStatus">
           <template #default="{ row }">
-           <el-icon :size="24" color="#67C23A" v-if="row.loginStatus === LoginStatusEnum.SUCCESS"><SuccessFilled /></el-icon>
-           <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
+            <el-icon :size="24" color="#67C23A" v-if="row.loginStatus === LoginStatusEnum.SUCCESS"
+              ><SuccessFilled
+            /></el-icon>
+            <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
           </template>
         </el-table-column>
-        <el-table-column label="登录IP"  prop="loginIp" />
-        <el-table-column label="操作时间"  prop="createdAt" />
+        <el-table-column label="登录IP" prop="loginIp" />
+        <el-table-column label="操作时间" prop="createdAt" />
       </el-table>
 
       <section class="mt-4 flex justify-end">
         <!-- 分页组件,显示总条目数、每页显示条目数选择器、上一页、页码、下一页 -->
-        <el-pagination background layout="total, sizes, prev, pager, next" :page-sizes="[10, 30, 50]" :total="total"
-          v-model:page-size="requestParams.pageSize" v-model:current-page="requestParams.pageNumber"
-          @change="queryLoginLogPage" />
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next"
+          :page-sizes="[10, 30, 50]"
+          :total="total"
+          v-model:page-size="requestParams.pageSize"
+          v-model:current-page="requestParams.pageNumber"
+          @change="queryLoginLogPage"
+        />
       </section>
     </el-card>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted } from 'vue';
-import { Search, Refresh, SuccessFilled, CircleCloseFilled, Platform, Iphone } from '@element-plus/icons-vue';
-import { getAllDepartments } from '@/api/auth/dept';
-import type { FormInstance } from 'element-plus'
-import { OptionsProps, deviceList, queryTypeSelect, LoginStatusEnum, OperationTypeEnum, ClientTypeEnum } from '@/types/log/constants';
-import useSceneInfos from '@/hooks/useSceneInfos';
-import useLoginLogQuery from '../hooks/useLoginLogQuery';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { exportLoginLog } from '@/api/system/log';
-import { downloadByData } from '@/utils/file/download';
+  import { ref, onMounted } from 'vue';
+  import { Search, Refresh, SuccessFilled, CircleCloseFilled, Platform, Iphone } from '@element-plus/icons-vue';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import type { FormInstance } from 'element-plus';
+  import {
+    OptionsProps,
+    deviceList,
+    queryTypeSelect,
+    LoginStatusEnum,
+    OperationTypeEnum,
+    ClientTypeEnum,
+  } from '@/types/log/constants';
+  import useSceneInfos from '@/hooks/useSceneInfos';
+  import useLoginLogQuery from '../hooks/useLoginLogQuery';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { exportLoginLog } from '@/api/system/log';
+  import { downloadByData } from '@/utils/file/download';
 
-const sceneInfos = useSceneInfos();
-const { calculateTreeData } = sceneInfos;
-const { requestParams, total, loginLogList, queryLoginLogPage, loading, resetRequestParams } = useLoginLogQuery();
+  const sceneInfos = useSceneInfos();
+  const { calculateTreeData } = sceneInfos;
+  const { requestParams, total, loginLogList, queryLoginLogPage, loading, resetRequestParams } = useLoginLogQuery();
 
-const departmentList = ref<OptionsProps[]>([]);
+  const departmentList = ref<OptionsProps[]>([]);
 
-onMounted(async () => {
-  queryLoginLogPage();
-  getAllDepartments().then((res) => {
-    departmentList.value = calculateTreeData(
-      res,
-      { level: 3, valueKey: 'id', labelKey: 'deptName' },
-      1,
-    );
+  onMounted(async () => {
+    queryLoginLogPage();
+    getAllDepartments().then((res) => {
+      departmentList.value = calculateTreeData(res, { level: 3, valueKey: 'id', labelKey: 'deptName' }, 1);
+    });
   });
-});
 
-/* 导出数据 */
-const handleExport = () => {
-  ElMessageBox.confirm('确定导出所查询数据?', '导出', {
+  /* 导出数据 */
+  const handleExport = () => {
+    ElMessageBox.confirm('确定导出所查询数据?', '导出', {
       confirmButtonText: '确定',
       showCancelButton: true,
       type: 'warning',
@@ -147,30 +165,29 @@ const handleExport = () => {
           message: '取消导出',
         });
       });
-}
-
-/* 重置 */
-const searchFormRef = ref<FormInstance>()
-const hanleResetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  resetRequestParams();
-  formEl.resetFields();
-  queryLoginLogPage();
-}
+  };
 
-/* 设置今天之后的时间不可选 */
-const disabledDate = (time) => {
-  return time.getTime() > Date.now();
-}
+  /* 重置 */
+  const searchFormRef = ref<FormInstance>();
+  const hanleResetForm = (formEl: FormInstance | undefined) => {
+    if (!formEl) return;
+    resetRequestParams();
+    formEl.resetFields();
+    queryLoginLogPage();
+  };
 
+  /* 设置今天之后的时间不可选 */
+  const disabledDate = (time) => {
+    return time.getTime() > Date.now();
+  };
 </script>
 
 <style scoped lang="scss">
-.form-inline .el-input {
-  --el-input-width: 160px;
-}
+  .form-inline .el-input {
+    --el-input-width: 160px;
+  }
 
-.form-inline .el-select {
-  --el-select-width: 160px;
-}
+  .form-inline .el-select {
+    --el-select-width: 160px;
+  }
 </style>

+ 90 - 67
src/views/system/log/components/OperationLog.vue

@@ -5,10 +5,10 @@
 <template>
   <div class="login-log">
     <el-card class="mb-3 proCard">
-      <el-space >
+      <el-space>
         <el-form ref="searchFormRef" :inline="true" :model="requestParams.queryParam" class="form-inline">
           <el-form-item prop="userName">
-              <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select">
+            <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select">
               <el-option
                 v-for="item in operationQueryTypeSelect"
                 :key="item.value"
@@ -16,8 +16,13 @@
                 :value="item.value"
               />
             </el-select>
-            <el-input v-model="requestParams.queryParam.queryTypeContent" clearable placeholder="请输入搜索关键字"
-              @keyup.enter="queryOperationLogPage" :disabled="requestParams.queryParam.queryType ===''"/>
+            <el-input
+              v-model="requestParams.queryParam.queryTypeContent"
+              clearable
+              placeholder="请输入搜索关键字"
+              @keyup.enter="queryOperationLogPage"
+              :disabled="requestParams.queryParam.queryType === ''"
+            />
           </el-form-item>
           <el-form-item label="应用侧" prop="platform">
             <el-select v-model="requestParams.queryParam.platform" placeholder="请选择应用侧" clearable>
@@ -25,27 +30,31 @@
             </el-select>
           </el-form-item>
           <el-form-item label="所属模块" prop="module">
-            <el-input v-model="requestParams.queryParam.module" clearable placeholder="请输入所属模块"
-              @keyup.enter="queryOperationLogPage" />
-           </el-form-item>
+            <el-input
+              v-model="requestParams.queryParam.module"
+              clearable
+              placeholder="请输入所属模块"
+              @keyup.enter="queryOperationLogPage"
+            />
+          </el-form-item>
           <el-form-item label="操作类型" prop="operatorType">
             <el-select v-model="requestParams.queryParam.operatorType" placeholder="请选择操作类型" clearable>
               <el-option :label="item.label" :value="item.value" v-for="item in operationList" :key="item.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="操作时间" prop="date">
-            <el-date-picker 
-              v-model="requestParams.queryParam.date" 
-              type="daterange" 
-              placeholder="请选择操作时间" 
+            <el-date-picker
+              v-model="requestParams.queryParam.date"
+              type="daterange"
+              placeholder="请选择操作时间"
               range-separator="~"
               start-placeholder="开始时间"
               end-placeholder="结束时间"
               :disabled-date="disabledDate"
-              clearable 
+              clearable
               format="YYYY/MM/DD"
               value-format="YYYY/MM/DD"
-              />
+            />
           </el-form-item>
           <el-form-item>
             <el-button type="primary" :icon="Search" @click="queryOperationLogPage">查询</el-button>
@@ -60,25 +69,27 @@
         <el-button type="primary" @click="handleExport()">导出数据</el-button>
       </template>
       <el-table height="calc(100vh - 500px)" :data="operationLogList" v-loading="loading">
-        <el-table-column type="index" width="100" label="日志编号"/>
+        <el-table-column type="index" width="100" label="日志编号" />
         <el-table-column label="账号" prop="operatorName" />
         <el-table-column label="姓名" prop="realName" />
-        <el-table-column label="应用侧" prop="platform" >
+        <el-table-column label="应用侧" prop="platform">
           <template #default="{ row }">
-            {{  row.platform === 'ADMIN' ? '管理侧' : '平台侧' }}
+            {{ row.platform === 'ADMIN' ? '管理侧' : '平台侧' }}
           </template>
         </el-table-column>
         <el-table-column label="所属模块" prop="module" />
-        <el-table-column label="操作内容"  prop="content" />
-        <el-table-column label="操作类型"  prop="operatorType" >
-           <template #default="{ row }">
-            {{  OperationType[row.operatorType] }}
+        <el-table-column label="操作内容" prop="content" />
+        <el-table-column label="操作类型" prop="operatorType">
+          <template #default="{ row }">
+            {{ OperationType[row.operatorType] }}
           </template>
         </el-table-column>
-        <el-table-column label="操作结果" prop="isSuccess" >
+        <el-table-column label="操作结果" prop="isSuccess">
           <template #default="{ row }">
-           <el-icon :size="24" color="#67C23A" v-if="row.isSuccess === LoginStatusEnum.SUCCESS"><SuccessFilled /></el-icon>
-           <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
+            <el-icon :size="24" color="#67C23A" v-if="row.isSuccess === LoginStatusEnum.SUCCESS"
+              ><SuccessFilled
+            /></el-icon>
+            <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
           </template>
         </el-table-column>
         <el-table-column label="IP" prop="clientIp" />
@@ -86,16 +97,22 @@
         <el-table-column label="操作" width="160">
           <template #default="{ row }">
             <el-space>
-              <el-button type="primary"  text @click="openDrawer(row.id)" >详情</el-button>
+              <el-button type="primary" text @click="openDrawer(row.id)">详情</el-button>
             </el-space>
           </template>
         </el-table-column>
       </el-table>
 
       <section class="mt-4 flex justify-end">
-        <el-pagination background layout="total, sizes, prev, pager, next" :page-sizes="[10, 30, 50]" :total="total"
-          v-model:page-size="requestParams.pageSize" v-model:current-page="requestParams.pageNumber"
-          @change="queryOperationLogPage" />
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next"
+          :page-sizes="[10, 30, 50]"
+          :total="total"
+          v-model:page-size="requestParams.pageSize"
+          v-model:current-page="requestParams.pageNumber"
+          @change="queryOperationLogPage"
+        />
       </section>
     </el-card>
 
@@ -104,25 +121,32 @@
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted } from 'vue';
-import { Search, Refresh, Edit ,SuccessFilled, CircleCloseFilled} from '@element-plus/icons-vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { exportOperationLog } from '@/api/system/log';
-import { downloadByData } from '@/utils/file/download';
-import type { FormInstance } from 'element-plus'
-import DetailDialog from './DetailDialog.vue';
-import { platformList, operationList, operationQueryTypeSelect, LoginStatusEnum, OperationType } from '@/types/log/constants';
-import userOperationQuery from '../hooks/userOperationQuery';
+  import { ref, onMounted } from 'vue';
+  import { Search, Refresh, SuccessFilled, CircleCloseFilled } from '@element-plus/icons-vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { exportOperationLog } from '@/api/system/log';
+  import { downloadByData } from '@/utils/file/download';
+  import type { FormInstance } from 'element-plus';
+  import DetailDialog from './DetailDialog.vue';
+  import {
+    platformList,
+    operationList,
+    operationQueryTypeSelect,
+    LoginStatusEnum,
+    OperationType,
+  } from '@/types/log/constants';
+  import userOperationQuery from '../hooks/userOperationQuery';
 
-const { requestParams, total, operationLogList, loading, queryOperationLogPage, resetRequestParams } = userOperationQuery();
+  const { requestParams, total, operationLogList, loading, queryOperationLogPage, resetRequestParams } =
+    userOperationQuery();
 
-onMounted(async () => {
-  queryOperationLogPage();
-});
+  onMounted(async () => {
+    queryOperationLogPage();
+  });
 
-/* 导出数据 */
-const handleExport = () => {
-  ElMessageBox.confirm('确定导出所查询数据?', '导出', {
+  /* 导出数据 */
+  const handleExport = () => {
+    ElMessageBox.confirm('确定导出所查询数据?', '导出', {
       confirmButtonText: '确定',
       showCancelButton: true,
       type: 'warning',
@@ -142,35 +166,34 @@ const handleExport = () => {
           message: '取消导出',
         });
       });
-}
-
-/* 重置 */
-const searchFormRef = ref<FormInstance>()
-const handleResetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  resetRequestParams();
-  formEl.resetFields();
-  queryOperationLogPage();
-}
+  };
 
-const drawerInstance = ref<InstanceType<typeof DetailDialog>>();
-const openDrawer = (id?: number) => {
-  drawerInstance.value?.open(id);
-};
+  /* 重置 */
+  const searchFormRef = ref<FormInstance>();
+  const handleResetForm = (formEl: FormInstance | undefined) => {
+    if (!formEl) return;
+    resetRequestParams();
+    formEl.resetFields();
+    queryOperationLogPage();
+  };
 
-/* 设置今天之后的时间不可选 */
-const disabledDate = (time) => {
-  return time.getTime() > Date.now();
-}
+  const drawerInstance = ref<InstanceType<typeof DetailDialog>>();
+  const openDrawer = (id?: number) => {
+    drawerInstance.value?.open(id);
+  };
 
+  /* 设置今天之后的时间不可选 */
+  const disabledDate = (time) => {
+    return time.getTime() > Date.now();
+  };
 </script>
 
 <style scoped lang="scss">
-.form-inline .el-input {
-  --el-input-width: 160px;
-}
+  .form-inline .el-input {
+    --el-input-width: 160px;
+  }
 
-.form-inline .el-select {
-  --el-select-width: 160px;
-}
+  .form-inline .el-select {
+    --el-select-width: 160px;
+  }
 </style>

+ 25 - 26
src/views/system/log/hooks/useLoginLogQuery.ts

@@ -1,9 +1,8 @@
-
-import { reactive, ref, shallowRef } from "vue"
-import { LoginLogItem, LoginLogPageRequest } from "@/types/log/type"
-import { DEFAULT_PAGE_SIZE } from "@/types/common/constants"
-import { cloneDeep } from "lodash-es"
-import { queryLoginLogList } from "@/api/system/log"
+import { reactive, ref, shallowRef } from 'vue';
+import { LoginLogItem, LoginLogPageRequest } from '@/types/log/type';
+import { DEFAULT_PAGE_SIZE } from '@/types/common/constants';
+import { cloneDeep } from 'lodash-es';
+import { queryLoginLogList } from '@/api/system/log';
 
 const defaultLoginLogRequest: LoginLogPageRequest = {
   pageNumber: 1,
@@ -16,11 +15,11 @@ const defaultLoginLogRequest: LoginLogPageRequest = {
     deptId: undefined,
     date: '',
     queryType: '',
-    queryTypeContent: ''
-  }
-}
+    queryTypeContent: '',
+  },
+};
 
-export default function useLoginLogRequest () {
+export default function useLoginLogRequest() {
   const requestParams = reactive<LoginLogPageRequest>(cloneDeep(defaultLoginLogRequest));
   const loginLogList = shallowRef<LoginLogItem[]>([]);
   const total = ref(0);
@@ -30,36 +29,36 @@ export default function useLoginLogRequest () {
     try {
       loading.value = true;
       const { date, queryType, queryTypeContent } = requestParams.queryParam;
-       Object.entries(requestParams.queryParam).forEach(([key, value]) => { 
+      Object.entries(requestParams.queryParam).forEach(([key, value]) => {
         if (value) {
           if (queryType) {
-              requestParams.queryParam[queryType] = queryTypeContent;
-            }
+            requestParams.queryParam[queryType] = queryTypeContent;
+          }
         }
       });
       if (date && date.length > 0) {
         requestParams.queryParam.startTime = date[0] + ' 00:00:00';
         requestParams.queryParam.endTime = date[1] + ' 23:59:59';
       }
-     
+
       const data = await queryLoginLogList(requestParams);
       loginLogList.value = data.records;
       total.value = data.totalRow;
     } catch (error) {
-      console.log(error)
+      console.log(error);
     } finally {
       loading.value = false;
     }
-  }
+  };
 
   const resetRequestParams = () => {
-    requestParams.queryParam.startTime = ''
-    requestParams.queryParam.endTime = ''
-    requestParams.queryParam.queryTypeContent = ''
-    requestParams.queryParam.userName = ''
-    requestParams.queryParam.realName = ''
-    Object.assign(requestParams, defaultLoginLogRequest)
-  }
+    requestParams.queryParam.startTime = '';
+    requestParams.queryParam.endTime = '';
+    requestParams.queryParam.queryTypeContent = '';
+    requestParams.queryParam.userName = '';
+    requestParams.queryParam.realName = '';
+    Object.assign(requestParams, defaultLoginLogRequest);
+  };
 
   return {
     requestParams,
@@ -67,6 +66,6 @@ export default function useLoginLogRequest () {
     loading,
     loginLogList,
     queryLoginLogPage,
-    resetRequestParams
-  }
-}
+    resetRequestParams,
+  };
+}

+ 19 - 20
src/views/system/log/hooks/useSystemQuery.ts

@@ -1,9 +1,8 @@
-
-import { reactive, ref, shallowRef } from "vue"
-import { SystemLogRequest, SystemLogItem } from "@/types/log/type"
-import { DEFAULT_PAGE_SIZE } from "@/types/common/constants"
-import { cloneDeep } from "lodash-es"
-import { querySystemLogList } from "@/api/system/log"
+import { reactive, ref, shallowRef } from 'vue';
+import { SystemLogRequest, SystemLogItem } from '@/types/log/type';
+import { DEFAULT_PAGE_SIZE } from '@/types/common/constants';
+import { cloneDeep } from 'lodash-es';
+import { querySystemLogList } from '@/api/system/log';
 
 const defaultLoginLogRequest: SystemLogRequest = {
   pageNumber: 1,
@@ -12,11 +11,11 @@ const defaultLoginLogRequest: SystemLogRequest = {
     eventType: undefined,
     startTime: '',
     endTime: '',
-    date: ''
-  }
-}
+    date: '',
+  },
+};
 
-export default function useSystemLogRequest () {
+export default function useSystemLogRequest() {
   const requestParams = reactive<SystemLogRequest>(cloneDeep(defaultLoginLogRequest));
   const systemLogList = shallowRef<SystemLogItem[]>([]);
   const total = ref(0);
@@ -30,22 +29,22 @@ export default function useSystemLogRequest () {
         requestParams.queryParam.startTime = date[0] + ' 00:00:00';
         requestParams.queryParam.endTime = date[1] + ' 23:59:59';
       }
-     
+
       const data = await querySystemLogList(requestParams);
       systemLogList.value = data.records;
       total.value = data.totalRow;
     } catch (error) {
-      console.log(error)
+      console.log(error);
     } finally {
       loading.value = false;
     }
-  }
+  };
 
   const resetRequestParams = () => {
-    requestParams.queryParam.startTime = ''
-    requestParams.queryParam.endTime = ''
-    Object.assign(requestParams, defaultLoginLogRequest)
-  }
+    requestParams.queryParam.startTime = '';
+    requestParams.queryParam.endTime = '';
+    Object.assign(requestParams, defaultLoginLogRequest);
+  };
 
   return {
     requestParams,
@@ -53,6 +52,6 @@ export default function useSystemLogRequest () {
     loading,
     systemLogList,
     querySystemLogPage,
-    resetRequestParams
-  }
-}
+    resetRequestParams,
+  };
+}

+ 23 - 24
src/views/system/log/hooks/userOperationQuery.ts

@@ -1,9 +1,8 @@
-
-import { reactive, ref, shallowRef } from "vue"
-import { OperationLogPageRequest, OperationLogItem  } from "@/types/log/type"
-import { DEFAULT_PAGE_SIZE } from "@/types/common/constants"
-import { cloneDeep } from "lodash-es"
-import { queryOperationLogList } from "@/api/system/log"
+import { reactive, ref, shallowRef } from 'vue';
+import { OperationLogPageRequest, OperationLogItem } from '@/types/log/type';
+import { DEFAULT_PAGE_SIZE } from '@/types/common/constants';
+import { cloneDeep } from 'lodash-es';
+import { queryOperationLogList } from '@/api/system/log';
 
 const defaultOperationLogRequest: OperationLogPageRequest = {
   pageNumber: 1,
@@ -18,11 +17,11 @@ const defaultOperationLogRequest: OperationLogPageRequest = {
     endTime: '',
     date: '',
     queryType: '',
-    queryTypeContent: ''
-  }
-}
+    queryTypeContent: '',
+  },
+};
 
-export default function useOperationLogRequest () {
+export default function useOperationLogRequest() {
   const requestParams = reactive<OperationLogPageRequest>(cloneDeep(defaultOperationLogRequest));
   const operationLogList = shallowRef<OperationLogItem[]>([]);
   const total = ref(0);
@@ -31,34 +30,34 @@ export default function useOperationLogRequest () {
   const queryOperationLogPage = async () => {
     try {
       loading.value = true;
-     const { date, queryType, queryTypeContent } = requestParams.queryParam;
-       Object.entries(requestParams.queryParam).forEach(([key, value]) => { 
+      const { date, queryType, queryTypeContent } = requestParams.queryParam;
+      Object.entries(requestParams.queryParam).forEach(([key, value]) => {
         if (value) {
           if (queryType) {
-              requestParams.queryParam[queryType] = queryTypeContent;
-            }
+            requestParams.queryParam[queryType] = queryTypeContent;
+          }
         }
       });
       if (date && date.length > 0) {
         requestParams.queryParam.startTime = date[0] + ' 00:00:00';
         requestParams.queryParam.endTime = date[1] + ' 23:59:59';
       }
-     
+
       const data = await queryOperationLogList(requestParams);
       operationLogList.value = data.records;
       total.value = data.totalRow;
     } catch (error) {
-      console.log(error)
+      console.log(error);
     } finally {
       loading.value = false;
     }
-  }
+  };
 
   const resetRequestParams = () => {
-    requestParams.queryParam.startTime = ''
-    requestParams.queryParam.endTime = ''
-    Object.assign(requestParams, defaultOperationLogRequest)
-  }
+    requestParams.queryParam.startTime = '';
+    requestParams.queryParam.endTime = '';
+    Object.assign(requestParams, defaultOperationLogRequest);
+  };
 
   return {
     requestParams,
@@ -66,6 +65,6 @@ export default function useOperationLogRequest () {
     loading,
     operationLogList,
     queryOperationLogPage,
-    resetRequestParams
-  }
-}
+    resetRequestParams,
+  };
+}