Commit 3f27b256714e94550e202e4bae423ccc87373f58

Authored by fengtao
1 parent 4d2427ca

feat:运维管理下新增子菜单 上下线记录静态页面

@@ -20,6 +20,8 @@ import { usePermissionStore } from '/@/store/modules/permission'; @@ -20,6 +20,8 @@ import { usePermissionStore } from '/@/store/modules/permission';
20 import { RouteRecordRaw } from 'vue-router'; 20 import { RouteRecordRaw } from 'vue-router';
21 import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; 21 import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
22 import { createLocalStorage } from '/@/utils/cache/index'; 22 import { createLocalStorage } from '/@/utils/cache/index';
  23 +import { getEntitiesId } from '/@/api/dashboard/index';
  24 +
23 interface UserState { 25 interface UserState {
24 platInfo: any; 26 platInfo: any;
25 enterPriseInfo: any; 27 enterPriseInfo: any;
@@ -185,6 +187,14 @@ export const useUserStore = defineStore({ @@ -185,6 +187,14 @@ export const useUserStore = defineStore({
185 const { roles } = userInfo; 187 const { roles } = userInfo;
186 const roleList = roles.map((item) => item) as RoleEnum[]; 188 const roleList = roles.map((item) => item) as RoleEnum[];
187 this.setRoleList(roleList); 189 this.setRoleList(roleList);
  190 + try {
  191 + if (roleList[0] !== 'SYS_ADMIN') {
  192 + const res = await getEntitiesId();
  193 + const entityId = res.data[0]?.entityId;
  194 + window.localStorage.setItem('entityId', JSON.stringify(entityId));
  195 + window.sessionStorage.setItem('entityId', JSON.stringify(entityId));
  196 + }
  197 + } catch {}
188 return userInfo; 198 return userInfo;
189 }, 199 },
190 /** 200 /**
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 </div> 21 </div>
22 </template> 22 </template>
23 <script lang="ts" setup> 23 <script lang="ts" setup>
24 - import { ref, onMounted } from 'vue'; 24 + import { ref } from 'vue';
25 import GrowCard from './components/GrowCard.vue'; 25 import GrowCard from './components/GrowCard.vue';
26 import SiteAnalysis from './components/SiteAnalysis.vue'; 26 import SiteAnalysis from './components/SiteAnalysis.vue';
27 import SiteAnalysisMessage from './components/SiteAnalysisMessage.vue'; 27 import SiteAnalysisMessage from './components/SiteAnalysisMessage.vue';
@@ -30,7 +30,6 @@ @@ -30,7 +30,6 @@
30 import { USER_INFO_KEY } from '/@/enums/cacheEnum'; 30 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
31 import { getAuthCache } from '/@/utils/auth'; 31 import { getAuthCache } from '/@/utils/auth';
32 import { isAdmin } from '/@/enums/roleEnum'; 32 import { isAdmin } from '/@/enums/roleEnum';
33 - import { getEntitiesId } from '/@/api/dashboard/index';  
34 33
35 defineExpose({ 34 defineExpose({
36 isAdmin, 35 isAdmin,
@@ -45,15 +44,4 @@ @@ -45,15 +44,4 @@
45 setTimeout(() => { 44 setTimeout(() => {
46 loading.value = false; 45 loading.value = false;
47 }, 1500); 46 }, 1500);
48 -  
49 - const entityId = ref({});  
50 -  
51 - onMounted(async () => {  
52 - if (role === 'TENANT_ADMIN') {  
53 - const res = await getEntitiesId();  
54 - entityId.value = res.data[0]?.entityId;  
55 - window.localStorage.setItem('entityId', JSON.stringify(entityId.value));  
56 - window.sessionStorage.setItem('entityId', JSON.stringify(entityId.value));  
57 - }  
58 - });  
59 </script> 47 </script>
@@ -62,3 +62,8 @@ @@ -62,3 +62,8 @@
62 </BasicTable> 62 </BasicTable>
63 </section> 63 </section>
64 </template> 64 </template>
  65 +<style scoped>
  66 + :deep(.ant-table-body) {
  67 + overflow: hidden !important;
  68 + }
  69 +</style>
  1 +<template>
  2 + <BasicDrawer v-bind="$attrs" @register="registerDrawer" title="上下线记录详情" width="40%">
  3 + <BasicForm @register="registerForm" />
  4 + </BasicDrawer>
  5 +</template>
  6 +<script lang="ts" setup>
  7 + import { BasicForm, useForm } from '/@/components/Form';
  8 + import { formSchema } from './config.data';
  9 + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  10 +
  11 + defineEmits(['success', 'register']);
  12 + const [registerForm, { setFieldsValue, resetFields }] = useForm({
  13 + labelWidth: 120,
  14 + schemas: formSchema,
  15 + showActionButtonGroup: false,
  16 + });
  17 +
  18 + const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
  19 + await resetFields();
  20 + setDrawerProps({ confirmLoading: false });
  21 + await setFieldsValue(data.record);
  22 + });
  23 +</script>
  1 +import { BasicColumn, FormSchema } from '/@/components/Table';
  2 +import moment from 'moment';
  3 +import { h } from 'vue';
  4 +import { Tag } from 'ant-design-vue';
  5 +
  6 +// 表格数据
  7 +export const columns: BasicColumn[] = [
  8 + {
  9 + title: '设备名称',
  10 + dataIndex: 'deviceName',
  11 + width: 120,
  12 + },
  13 + {
  14 + title: '设备配置',
  15 + dataIndex: 'deviceConfig',
  16 + width: 120,
  17 + },
  18 + {
  19 + title: '设备类型',
  20 + dataIndex: 'entityType',
  21 + width: 180,
  22 + },
  23 + {
  24 + title: '所属组织',
  25 + dataIndex: 'orgName',
  26 + width: 120,
  27 + },
  28 + {
  29 + title: '状态',
  30 + dataIndex: 'status',
  31 + width: 180,
  32 + customRender: ({ record }) => {
  33 + const status = record.status;
  34 + const enable = status === 'SUCCESS' ? '启用' : '禁用';
  35 + const color = enable === '启用' ? 'green' : 'red';
  36 + const text = enable === '启用' ? '启用' : '禁用';
  37 + return h(Tag, { color }, () => text);
  38 + },
  39 + },
  40 + {
  41 + title: '时间',
  42 + dataIndex: 'createTime',
  43 + width: 180,
  44 + },
  45 +];
  46 +
  47 +// 分页查询
  48 +export const searchFormSchema: FormSchema[] = [
  49 + {
  50 + field: 'deviceName',
  51 + label: '设备名称',
  52 + component: 'Input',
  53 + componentProps: {
  54 + maxLength: 255,
  55 + placeholder: '请输入设备名称',
  56 + },
  57 + dynamicRules: () => {
  58 + return [
  59 + {
  60 + required: false,
  61 + validator: (_, value) => {
  62 + if (String(value).length > 255) {
  63 + return Promise.reject('字数不超过255个字');
  64 + }
  65 + return Promise.resolve();
  66 + },
  67 + },
  68 + ];
  69 + },
  70 +
  71 + colProps: { span: 6 },
  72 + },
  73 + {
  74 + field: 'status',
  75 + label: '状态',
  76 + colProps: { span: 6 },
  77 + component: 'Select',
  78 + componentProps: {
  79 + placeholder: '请选择状态',
  80 + options: [
  81 + {
  82 + label: '启用',
  83 + value: 'NOTICE',
  84 + },
  85 + {
  86 + label: '禁用',
  87 + value: 'MEETING',
  88 + },
  89 + ],
  90 + },
  91 + },
  92 + {
  93 + field: 'queryTime',
  94 + label: '查询时间',
  95 + component: 'RangePicker',
  96 + componentProps: {
  97 + showTime: {
  98 + defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  99 + },
  100 + },
  101 + colProps: { span: 6 },
  102 + },
  103 +];
  104 +
  105 +// 详情配置
  106 +export const formSchema: FormSchema[] = [
  107 + {
  108 + field: 'deviceName',
  109 + label: '设备名称',
  110 + component: 'Input',
  111 + componentProps: {
  112 + disabled: true,
  113 + },
  114 + },
  115 + {
  116 + field: 'deviceConfig',
  117 + label: '设备配置',
  118 + component: 'Input',
  119 + componentProps: {
  120 + disabled: true,
  121 + },
  122 + },
  123 + {
  124 + field: 'entityType',
  125 + label: '设备类型',
  126 + component: 'Input',
  127 + componentProps: {
  128 + disabled: true,
  129 + },
  130 + },
  131 + {
  132 + field: 'orgName',
  133 + label: '所属组织',
  134 + component: 'Input',
  135 + componentProps: {
  136 + disabled: true,
  137 + },
  138 + },
  139 + {
  140 + field: 'status',
  141 + label: '状态',
  142 + component: 'Input',
  143 + componentProps: {
  144 + disabled: true,
  145 + },
  146 + },
  147 + {
  148 + field: 'createTime',
  149 + label: '时间',
  150 + colProps: { span: 24 },
  151 + component: 'Input',
  152 + componentProps: {
  153 + disabled: true,
  154 + },
  155 + },
  156 +];
  157 +
  158 +export const mockList = [
  159 + {
  160 + deviceName: '网关/直连设备',
  161 + id: '2d2321s122131',
  162 + deviceConfig: '车车网关设备配置',
  163 + entityType: '网关',
  164 + orgName: 'cheche',
  165 + status: 'SUCCESS',
  166 + createTime: '2022-12-22 16:25:36',
  167 + },
  168 + {
  169 + deviceName: '网关/直连设备',
  170 + id: '2d22321s12131',
  171 + deviceConfig: '车车网关设备配置',
  172 + entityType: '网关',
  173 + orgName: 'cheche',
  174 + status: 'SUCCESS',
  175 + createTime: '2022-12-22 16:25:36',
  176 + },
  177 + {
  178 + deviceName: '网关/直连设备',
  179 + id: '2d232d1s12131',
  180 + deviceConfig: '车车网关设备配置',
  181 + entityType: '网关',
  182 + orgName: 'cheche',
  183 + status: 'SUCCESS',
  184 + createTime: '2022-12-22 16:25:36',
  185 + },
  186 + {
  187 + deviceName: '网关/直连设备',
  188 + id: '2d2321fs12131',
  189 + deviceConfig: '车车网关设备配置',
  190 + entityType: '网关',
  191 + orgName: 'cheche',
  192 + status: 'SUCCESS',
  193 + createTime: '2022-12-22 16:25:36',
  194 + },
  195 + {
  196 + deviceName: '网关/直连设备',
  197 + id: '2d2321ggs12131',
  198 + deviceConfig: '车车网关设备配置',
  199 + entityType: '网关',
  200 + orgName: 'cheche',
  201 + status: 'SUCCESS',
  202 + createTime: '2022-12-22 16:25:36',
  203 + },
  204 + {
  205 + deviceName: '网关/直连设备',
  206 + id: '2d2321hhs12131',
  207 + deviceConfig: '车车网关设备配置',
  208 + entityType: '网关',
  209 + orgName: 'cheche',
  210 + status: 'FATURE',
  211 + createTime: '2022-12-22 16:25:36',
  212 + },
  213 +];
  1 +<template>
  2 + <div>
  3 + <BasicTable :clickToRowSelect="false" @register="registerTable">
  4 + <template #toolbar>
  5 + <Authority value="api:yt:onlinerecord:delete">
  6 + <Popconfirm
  7 + title="您确定要批量删除数据"
  8 + ok-text="确定"
  9 + cancel-text="取消"
  10 + @confirm="handleDeleteOrBatchDelete(null)"
  11 + >
  12 + <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
  13 + </Popconfirm>
  14 + </Authority>
  15 + </template>
  16 + <template #action="{ record }">
  17 + <TableAction
  18 + :actions="[
  19 + {
  20 + label: '详情',
  21 + auth: 'api:yt:onlinerecord:get',
  22 + icon: 'clarity:note-edit-line',
  23 + onClick: handleViewDetail.bind(null, record),
  24 + },
  25 + {
  26 + label: '删除',
  27 + auth: 'api:yt:onlinerecord:delete',
  28 + icon: 'ant-design:delete-outlined',
  29 + color: 'error',
  30 + popConfirm: {
  31 + title: '是否确认删除',
  32 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  33 + },
  34 + },
  35 + ]"
  36 + />
  37 + </template>
  38 + </BasicTable>
  39 + <OnlineRecordDrawer @register="registerDrawer" @success="handleSuccess" />
  40 + </div>
  41 +</template>
  42 +
  43 +<script lang="ts" setup>
  44 + import { nextTick } from 'vue';
  45 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  46 + import { useDrawer } from '/@/components/Drawer';
  47 + import OnlineRecordDrawer from './OnlineRecordDrawer.vue';
  48 + // import { getExceptionPage } from '/@/api/log/logManager';
  49 + import { searchFormSchema, columns, mockList } from './config.data';
  50 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
  51 + import { deleteConvertApi } from '/@/api/datamanager/dataManagerApi';
  52 + import { Popconfirm } from 'ant-design-vue';
  53 + import { Authority } from '/@/components/Authority';
  54 +
  55 + const [registerTable, { setProps, reload }] = useTable({
  56 + title: '上下线记录',
  57 + dataSource: mockList,
  58 + // api: getExceptionPage,
  59 + columns,
  60 + showIndexColumn: false,
  61 + clickToRowSelect: false,
  62 + formConfig: {
  63 + labelWidth: 120,
  64 + schemas: searchFormSchema,
  65 + fieldMapToTime: [['queryTime', ['startTime', 'endTime'], 'x']],
  66 + },
  67 + useSearchForm: true,
  68 + showTableSetting: true,
  69 + bordered: true,
  70 + rowKey: 'id',
  71 + actionColumn: {
  72 + width: 200,
  73 + title: '操作',
  74 + dataIndex: 'action',
  75 + slots: { customRender: 'action' },
  76 + fixed: 'right',
  77 + },
  78 + });
  79 + const handleSuccess = () => {
  80 + reload();
  81 + resetSelectedRowKeys();
  82 + };
  83 + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
  84 + useBatchDelete(deleteConvertApi, handleSuccess, setProps);
  85 +
  86 + nextTick(() => {
  87 + setProps(selectionOptions);
  88 + });
  89 +
  90 + // 弹框
  91 + const [registerDrawer, { openDrawer }] = useDrawer();
  92 +
  93 + const handleViewDetail = (record) => {
  94 + openDrawer(true, {
  95 + isUpdate: true,
  96 + record,
  97 + });
  98 + };
  99 +</script>