Explorar el Código

feat: 添加初始化页-角色、菜单

xieyonghong hace 3 años
padre
commit
e61bb62ff7

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2179 - 0
src/pages/init-home/components/data/RoleData.ts


+ 75 - 6
src/pages/init-home/components/menu.tsx

@@ -1,12 +1,81 @@
-const Menu = () => {
+import {useEffect, useRef, useState, forwardRef, useImperativeHandle} from "react";
+import BaseMenu from '@/pages/system/Menu/Setting/baseMenu'
+import {service} from '../index'
+import { observable } from '@formily/reactive';
+
+export const MenuDataModel = observable<{menuData: any[]}>({
+  menuData: []
+});
+
+const Menu = forwardRef((_, ref) => {
+
+  const [count, setCount] = useState(0)
+  const menuRef = useRef<any[]>()
+
+  const menuCount = (menus: any[]) => {
+    return menus.reduce((pre,next) => {
+      let _count = 1
+      if (next.children) {
+        _count = menuCount(next.children)
+      }
+      return pre + _count
+    }, 0)
+  }
+
+  /**
+   * 根据权限过滤菜单
+   */
+  const filterMenu = (permissions:  string[], menus: any[]) => {
+    return menus.filter(item => {
+      let isPermissions = true
+      if (item.permissions && item.permissions.length) {
+        isPermissions = item.permissions.some((pItem: any) => permissions.includes(pItem.permission))
+      }
+
+      if (item.children) {
+        item.children = filterMenu(permissions, item.children)
+      }
+
+      return isPermissions || !!item.children?.length
+    })
+  }
+
+
+  /**
+   * 获取当前系统所有权限
+   */
+  const getSystemPermissions = async () => {
+    const resp = await service.getPermissionAll()
+    if (resp.status === 200) {
+      const newTree = filterMenu(resp.result.map((item: any) => item.id), BaseMenu)
+      const _count = menuCount(newTree)
+      menuRef.current = newTree
+      MenuDataModel.menuData = newTree
+      setCount(_count)
+    }
+  }
+
+  useImperativeHandle(ref, () => ({
+    save: () => {
+      console.log(menuRef.current)
+    }
+  }))
+
+  useEffect(() => {
+    getSystemPermissions()
+  }, [])
+
   return (
-    <div style={{ display: 'flex' }}>
-      <div>
+    <div style={{ display: 'flex', alignItems: 'center' }}>
+      <div style={{ marginRight: 16}}>
         <img src={require('/public/images/init-home/menu.png')} />
       </div>
-      <div>系统将初始化XXX个菜单 初始化后的菜单可在“菜单管理”页面进行维护管理</div>
+      <div>
+        <b>系统将初始化{count}个菜单</b>
+        <div>初始化后的菜单可在“菜单管理”页面进行维护管理</div>
+      </div>
     </div>
   );
-};
+});
 
-export default Menu;
+export default Menu ;

+ 52 - 3
src/pages/init-home/components/role.tsx

@@ -1,5 +1,54 @@
-const Role = () => {
-  return <div>系统将初始化XXX个菜单 初始化后的菜单可在“菜单管理”页面进行维护管理</div>;
-};
+import {Checkbox} from 'antd'
+import { useState, forwardRef, useImperativeHandle} from "react";
+import classNames from "classnames";
+
+import '../index.less';
+
+const Role = forwardRef((_, ref) => {
+
+  const [ keys, setKeys ] = useState<string[]>([])
+
+  useImperativeHandle(ref, () => ({
+    save: () => {
+      console.log(keys)
+    // 获取当前选中的角色
+    }
+  }), [keys])
+
+  return (
+    <div className={'init-home-role'}>
+      <Checkbox.Group onChange={(e) => {
+        setKeys(e as string[])
+      }}>
+        <div className={'init-home-role-content'}>
+          <div className={classNames('role-item role-image-1', {active: keys.includes('device')})}>
+            <div className={'role-item-title'} >
+              <Checkbox value={'device'}></Checkbox>
+              <div>设备接入岗</div>
+            </div>
+            <div className={'role-item-content'}></div>
+            <div className={'role-item-footer'}>该角色负责设备接入模块的维护管理</div>
+          </div>
+          <div className={classNames('role-item role-image-2', {active: keys.includes('link')})}>
+            <div className={'role-item-title'} >
+              <Checkbox value={'link'}></Checkbox>
+              <div>运维管理岗</div>
+            </div>
+            <div className={'role-item-content'}></div>
+            <div className={'role-item-footer'}>该角色负责系统运维模块的维护管理</div>
+          </div>
+          <div className={classNames('role-item role-image-3', {active: keys.includes('complex')})}>
+            <div className={'role-item-title'} >
+              <Checkbox value={'complex'}></Checkbox>
+              <div>综合管理岗</div>
+            </div>
+            <div className={'role-item-content'}></div>
+            <div className={'role-item-footer'}>该角色负责系统运维和设备接入模块的维护管理</div>
+          </div>
+        </div>
+      </Checkbox.Group>
+    </div>
+  );
+});
 
 export default Role;

+ 63 - 0
src/pages/init-home/index.less

@@ -46,3 +46,66 @@
     }
   }
 }
+
+.init-home-role {
+  .init-home-role-content {
+    display: flex;
+    gap: 24px;
+
+    .role-item {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      padding: 24px;
+      border: 1px solid rgba(245, 245, 245, 1);
+      position: relative;
+      margin-bottom: 30px;
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: 370px;
+
+      .role-item-title {
+        display: flex;
+
+        > div {
+          flex: 1 1 auto;
+          font-size: 16px;
+          font-weight: bold;
+          padding-left: 90px;
+        }
+      }
+
+      .role-item-content {
+        width: 320px;
+        height: 260px;
+        margin-top: 24px;
+      }
+
+      &.role-image-1 {
+        background-image: url("/images/init-home/role1.png");
+      }
+
+      &.role-image-2 {
+        background-image: url("/images/init-home/role2.png");
+      }
+
+      &.role-image-3 {
+        background-image: url("/images/init-home/role3.png");
+      }
+
+      .role-item-footer {
+        position: absolute;
+        bottom: -30px;
+        left: 0;
+        text-align: center;
+        width: 100%;
+        color: #999;
+        font-size: 12px;
+      }
+
+      &.active {
+        background-color: #F5F5F5;
+      }
+    }
+  }
+}

+ 2 - 0
src/pages/init-home/service.ts

@@ -45,6 +45,8 @@ class Service extends BaseService<any> {
       method: 'POST',
       data,
     });
+  getPermissionAll = () =>
+    request(`${SystemConst.API_BASE}/permission/_query/no-paging?paging=false`,);
 }
 
 export default Service;

+ 21 - 8
src/pages/media/Device/Playback/index.tsx

@@ -2,7 +2,7 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import LivePlayer from '@/components/Player';
 import { useCallback, useEffect, useRef, useState } from 'react';
-import { Calendar, Empty, List, Tooltip } from 'antd';
+import {Calendar, Empty, List, Spin, Tooltip} from 'antd';
 import { useLocation } from 'umi';
 import Service from './service';
 import './index.less';
@@ -62,6 +62,7 @@ const IconNode = (props: IconNodeType) => {
   return (
     <a
       onClick={() => {
+        console.log(props,status)
         if (props.type === 'local') {
           if (status === 2) {
             // 已下载,进行跳转
@@ -85,7 +86,7 @@ export default () => {
   const [type, setType] = useState('local');
   const [historyList, setHistoryList] = useState<recordsItemType[]>([]);
   const [time, setTime] = useState<Moment | undefined>(undefined);
-  // const [loading, setLoading] = useState(false)
+  const [loading, setLoading] = useState(false)
   const [cloudTime, setCloudTime] = useState<any>();
   const location = useLocation();
   const player = useRef<any>();
@@ -103,6 +104,7 @@ export default () => {
     setPlayStatus(0);
     setUrl('');
     if (deviceId && channelId && date) {
+      setLoading(true)
       const params = {
         startTime: date.format('YYYY-MM-DD 00:00:00'),
         endTime: date.format('YYYY-MM-DD 23:59:59'),
@@ -113,6 +115,7 @@ export default () => {
           ...params,
           includeFiles: false,
         });
+        setLoading(false)
         let newList: recordsItemType[] = serviceResp.result;
 
         if (serviceResp.status === 200 && serviceResp.result) {
@@ -120,11 +123,11 @@ export default () => {
           newList = localResp.result.map((item: recordsItemType) => {
             return {
               ...item,
-              isServer: serviceResp.result.some(
+              isServer: serviceResp.result.length ? serviceResp.result.some(
                 (serverFile: any) =>
                   item.startTime >= serverFile.streamStartTime &&
                   serverFile.streamEndTime <= item.endTime,
-              ),
+              ) : false,
             };
           });
           setHistoryList(newList);
@@ -132,15 +135,21 @@ export default () => {
           setHistoryList(newList);
         }
       } else {
+        setLoading(false)
         setHistoryList([]);
       }
     }
   };
 
-  const queryServiceRecords = async (date: Moment) => {
+  /**
+   * 查询云端视频
+   * @param date
+   */
+  const queryServiceRecords = useCallback(async (date: Moment) => {
     setPlayStatus(0);
     setUrl('');
     if (deviceId && channelId && date) {
+      setLoading(true)
       const params = {
         startTime: date.format('YYYY-MM-DD 00:00:00'),
         endTime: date.format('YYYY-MM-DD 23:59:59'),
@@ -148,12 +157,12 @@ export default () => {
       };
 
       const resp = await service.recordsInServerFiles(deviceId, channelId, params);
-
+      setLoading(false)
       if (resp.status === 200) {
         setHistoryList(resp.result);
       }
     }
-  };
+  }, [deviceId, channelId])
 
   const cloudView = useCallback((startTime: number, endTime: number) => {
     setType('cloud');
@@ -162,7 +171,7 @@ export default () => {
       endTime,
     });
     queryServiceRecords(time!);
-  }, []);
+  }, [time]);
 
   const downloadClick = async (item: recordsItemType) => {
     const downloadUrl = service.downLoadFile(item.id);
@@ -240,6 +249,9 @@ export default () => {
           />
         </div>
         <div className={'playback-right'}>
+          <Spin spinning={loading}>
+
+
           <Tooltip
             // title={<>云端:存储在服务器中 本地:存储在设备本地</>}
             title={
@@ -391,6 +403,7 @@ export default () => {
               <Empty />
             )}
           </div>
+          </Spin>
         </div>
       </div>
     </PageContainer>

+ 1 - 0
src/pages/media/Device/Playback/timeLine.tsx

@@ -115,6 +115,7 @@ const Progress = forwardRef((props: Props, ref) => {
         onChange(data[0].startTime, data[0].endTime, data[0].deviceId, data[0].channelId);
       } else if (type === 'cloud') {
         // 是否从本地跳转到云端播放
+
         if (localToServer && Object.keys(localToServer).length > 0) {
           // 获取跳转播放段
           const playItem = data.find((item) => {

+ 11 - 6
src/pages/system/Menu/Setting/index.tsx

@@ -7,7 +7,7 @@ import {
 } from '@ant-design/icons';
 import Tree from './tree';
 import './index.less';
-import { Button, Tooltip } from 'antd';
+import {Button, message, Tooltip} from 'antd';
 import BaseTreeData from './baseMenu';
 import { useEffect, useState } from 'react';
 import { HTML5Backend } from 'react-dnd-html5-backend';
@@ -165,11 +165,16 @@ export default observer(() => {
 
   const updateMenu = () => {
     setLoading(true);
-    service.updateMenus(MenuSettingModel.menuData).then((res) => {
-      setLoading(false);
-      if (res.status === 200) {
-      }
-    });
+    if (MenuSettingModel.menuData && MenuSettingModel.menuData.length) {
+      service.updateMenus(MenuSettingModel.menuData).then((res) => {
+        setLoading(false);
+        if (res.status === 200) {
+          message.success('操作成功')
+        }
+      });
+    } else {
+      message.warning('请配置系统菜单')
+    }
   };
 
   return (

+ 3 - 3
src/pages/system/Menu/index.tsx

@@ -288,15 +288,15 @@ export default observer(() => {
               defaultMessage: '新增',
             })}
           </PermissionButton>,
-          <Button
+          <PermissionButton
             style={{ marginLeft: 12 }}
+            isPermission={permission.action}
             onClick={() => {
-              console.log(getMenuPathByCode('system/Menu/Setting'));
               history.push(getMenuPathByCode('system/Menu/Setting'));
             }}
           >
             菜单配置
-          </Button>,
+          </PermissionButton>,
         ]}
       />
     </PageContainer>

+ 1 - 1
src/pages/system/Menu/service.ts

@@ -29,7 +29,7 @@ class Service extends BaseService<MenuItem> {
   queryAssetsType = () => request(`${SystemConst.API_BASE}/asset/types`, { method: 'GET' });
 
   // 更新全部菜单
-  updateMenus = (data: any) => request(`${this.uri}`, { method: 'PATCH', data });
+  updateMenus = (data: any) => request(`${this.uri}/_all`, { method: 'PATCH', data });
 }
 
 export default Service;