Przeglądaj źródła

fix: 合并代码

100011797 3 lat temu
rodzic
commit
bf3b0300fc

BIN
public/images/init-home/role1.png


BIN
public/images/init-home/role2.png


BIN
public/images/init-home/role3.png


Plik diff jest za duży
+ 2789 - 0
src/pages/init-home/components/data/RoleData.ts


+ 77 - 5
src/pages/init-home/components/menu.tsx

@@ -1,12 +1,84 @@
-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;

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

@@ -1,5 +1,63 @@
-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

@@ -62,3 +62,66 @@
     }
   }
 }
+
+.init-home-role {
+  .init-home-role-content {
+    display: flex;
+    gap: 24px;
+
+    .role-item {
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      margin-bottom: 30px;
+      padding: 24px;
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: 370px;
+      border: 1px solid rgba(245, 245, 245, 1);
+
+      .role-item-title {
+        display: flex;
+
+        > div {
+          flex: 1 1 auto;
+          padding-left: 90px;
+          font-weight: bold;
+          font-size: 16px;
+        }
+      }
+
+      .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;
+        width: 100%;
+        color: #999;
+        font-size: 12px;
+        text-align: center;
+      }
+
+      &.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;

+ 182 - 161
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,13 @@ export default () => {
           newList = localResp.result.map((item: recordsItemType) => {
             return {
               ...item,
-              isServer: serviceResp.result.some(
-                (serverFile: any) =>
-                  item.startTime >= serverFile.streamStartTime &&
-                  serverFile.streamEndTime <= item.endTime,
-              ),
+              isServer: serviceResp.result.length
+                ? serviceResp.result.some(
+                    (serverFile: any) =>
+                      item.startTime >= serverFile.streamStartTime &&
+                      serverFile.streamEndTime <= item.endTime,
+                  )
+                : false,
             };
           });
           setHistoryList(newList);
@@ -132,37 +137,49 @@ export default () => {
           setHistoryList(newList);
         }
       } else {
+        setLoading(false);
         setHistoryList([]);
       }
     }
   };
 
-  const queryServiceRecords = async (date: Moment) => {
-    setPlayStatus(0);
-    setUrl('');
-    if (deviceId && channelId && date) {
-      const params = {
-        startTime: date.format('YYYY-MM-DD 00:00:00'),
-        endTime: date.format('YYYY-MM-DD 23:59:59'),
-        includeFiles: true,
-      };
-
-      const resp = await service.recordsInServerFiles(deviceId, channelId, params);
+  /**
+   * 查询云端视频
+   * @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'),
+          includeFiles: true,
+        };
 
-      if (resp.status === 200) {
-        setHistoryList(resp.result);
+        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');
-    setCloudTime({
-      startTime,
-      endTime,
-    });
-    queryServiceRecords(time!);
-  }, []);
+  const cloudView = useCallback(
+    (startTime: number, endTime: number) => {
+      setType('cloud');
+      setCloudTime({
+        startTime,
+        endTime,
+      });
+      queryServiceRecords(time!);
+    },
+    [time],
+  );
 
   const downloadClick = async (item: recordsItemType) => {
     const downloadUrl = service.downLoadFile(item.id);
@@ -240,47 +257,48 @@ export default () => {
           />
         </div>
         <div className={'playback-right'}>
-          <Tooltip
-            // title={<>云端:存储在服务器中 本地:存储在设备本地</>}
-            title={
-              <>
-                <div>云端:存储在服务器中</div>
-                <div>本地:存储在设备本地</div>
-              </>
-            }
-            placement="topLeft"
-          >
-            <div>
-              类型: <QuestionCircleOutlined />
-            </div>
-          </Tooltip>
-          <RadioCard
-            model={'singular'}
-            value={type}
-            itemStyle={{ minWidth: 0, width: '100%' }}
-            onSelect={(key: string) => {
-              setType(key);
-              console.log(key);
-              if (key === 'cloud') {
-                queryServiceRecords(time!);
-              } else {
-                queryLocalRecords(time!);
+          <Spin spinning={loading}>
+            <Tooltip
+              // title={<>云端:存储在服务器中 本地:存储在设备本地</>}
+              title={
+                <>
+                  <div>云端:存储在服务器中</div>
+                  <div>本地:存储在设备本地</div>
+                </>
               }
-            }}
-            options={[
-              {
-                label: '云端',
-                value: 'cloud',
-                imgUrl: require('/public/images/media/cloud.png'),
-              },
-              {
-                label: '本地',
-                value: 'local',
-                imgUrl: require('/public/images/local.png'),
-              },
-            ]}
-          />
-          {/* <Select
+              placement="topLeft"
+            >
+              <div>
+                类型: <QuestionCircleOutlined />
+              </div>
+            </Tooltip>
+            <RadioCard
+              model={'singular'}
+              value={type}
+              itemStyle={{ minWidth: 0, width: '100%' }}
+              onSelect={(key: string) => {
+                setType(key);
+                console.log(key);
+                if (key === 'cloud') {
+                  queryServiceRecords(time!);
+                } else {
+                  queryLocalRecords(time!);
+                }
+              }}
+              options={[
+                {
+                  label: '云端',
+                  value: 'cloud',
+                  imgUrl: require('/public/images/media/cloud.png'),
+                },
+                {
+                  label: '本地',
+                  value: 'local',
+                  imgUrl: require('/public/images/local.png'),
+                },
+              ]}
+            />
+            {/* <Select
             value={type}
             options={[
               { label: '云端', value: 'cloud' },
@@ -296,101 +314,104 @@ export default () => {
               }
             }}
           /> */}
-          <div className={'playback-calendar'}>
-            <Calendar
-              value={time}
-              onChange={(date) => {
-                setTime(date);
-                if (type === 'cloud') {
-                  queryServiceRecords(date);
-                } else {
-                  queryLocalRecords(date);
-                }
-              }}
-              disabledDate={(currentDate) => currentDate > moment(new Date())}
-              fullscreen={false}
-            />
-          </div>
-          <div className={classNames('playback-list', { 'no-list': !historyList.length })}>
-            {historyList && historyList.length ? (
-              <List
-                className={'playback-list-items'}
-                itemLayout="horizontal"
-                dataSource={historyList}
-                renderItem={(item) => {
-                  const _startTime = item.startTime || item.mediaStartTime;
-                  const startTime = moment(item.startTime || item.mediaStartTime).format(
-                    'HH:mm:ss',
-                  );
-                  const endTime = moment(item.endTime || item.mediaEndTime).format('HH:mm:ss');
-                  let title = '下载到云端';
-
-                  if (type === 'local') {
-                    if (item.isServer) {
-                      title = '查看';
-                    }
+            <div className={'playback-calendar'}>
+              <Calendar
+                value={time}
+                onChange={(date) => {
+                  setTime(date);
+                  if (type === 'cloud') {
+                    queryServiceRecords(date);
                   } else {
-                    title = '下载录像文件';
+                    queryLocalRecords(date);
                   }
-                  return (
-                    <List.Item
-                      actions={[
-                        <Tooltip
-                          key="play-btn"
-                          title={
-                            _startTime === playNowTime.current && playStatus === 1 ? '暂停' : '播放'
-                          }
-                        >
-                          <a
-                            onClick={() => {
-                              if (playStatus === 0 || _startTime !== playNowTime.current) {
-                                if (playTimeNode.current) {
-                                  playTimeNode.current.playByStartTime(_startTime);
-                                }
-                              } else if (playStatus == 1 && _startTime === playNowTime.current) {
-                                if (player.current.getVueInstance) {
-                                  player.current.getVueInstance().pause();
-                                }
-                              } else if (playStatus == 2 && _startTime === playNowTime.current) {
-                                if (player.current.getVueInstance) {
-                                  player.current.getVueInstance().play();
-                                }
-                              }
-                            }}
+                }}
+                disabledDate={(currentDate) => currentDate > moment(new Date())}
+                fullscreen={false}
+              />
+            </div>
+            <div className={classNames('playback-list', { 'no-list': !historyList.length })}>
+              {historyList && historyList.length ? (
+                <List
+                  className={'playback-list-items'}
+                  itemLayout="horizontal"
+                  dataSource={historyList}
+                  renderItem={(item) => {
+                    const _startTime = item.startTime || item.mediaStartTime;
+                    const startTime = moment(item.startTime || item.mediaStartTime).format(
+                      'HH:mm:ss',
+                    );
+                    const endTime = moment(item.endTime || item.mediaEndTime).format('HH:mm:ss');
+                    let title = '下载到云端';
+
+                    if (type === 'local') {
+                      if (item.isServer) {
+                        title = '查看';
+                      }
+                    } else {
+                      title = '下载录像文件';
+                    }
+                    return (
+                      <List.Item
+                        actions={[
+                          <Tooltip
+                            key="play-btn"
+                            title={
+                              _startTime === playNowTime.current && playStatus === 1
+                                ? '暂停'
+                                : '播放'
+                            }
                           >
-                            {_startTime === playNowTime.current && playStatus === 1 ? (
-                              <PauseCircleOutlined />
-                            ) : (
-                              <PlayCircleOutlined />
-                            )}
-                          </a>
-                        </Tooltip>,
+                            <a
+                              onClick={() => {
+                                if (playStatus === 0 || _startTime !== playNowTime.current) {
+                                  if (playTimeNode.current) {
+                                    playTimeNode.current.playByStartTime(_startTime);
+                                  }
+                                } else if (playStatus == 1 && _startTime === playNowTime.current) {
+                                  if (player.current.getVueInstance) {
+                                    player.current.getVueInstance().pause();
+                                  }
+                                } else if (playStatus == 2 && _startTime === playNowTime.current) {
+                                  if (player.current.getVueInstance) {
+                                    player.current.getVueInstance().play();
+                                  }
+                                }
+                              }}
+                            >
+                              {_startTime === playNowTime.current && playStatus === 1 ? (
+                                <PauseCircleOutlined />
+                              ) : (
+                                <PlayCircleOutlined />
+                              )}
+                            </a>
+                          </Tooltip>,
 
-                        <Tooltip key={'download'} title={title}>
-                          <IconNode
-                            type={type}
-                            item={item}
-                            onCloudView={cloudView}
-                            onDownLoad={() => {
-                              downloadClick(item);
-                            }}
-                          />
-                        </Tooltip>,
-                      ]}
-                    >
-                      <div style={{ textAlign: 'center', paddingLeft: 10 }}>
-                        {`${startTime}`} ~ {`${endTime}`}
-                      </div>
-                    </List.Item>
-                  );
-                }}
-              >
-                <div></div>
-              </List>
-            ) : (
-              <Empty />
-            )}
-          </div>
+                          <Tooltip key={'download'} title={title}>
+                            <IconNode
+                              type={type}
+                              item={item}
+                              onCloudView={cloudView}
+                              onDownLoad={() => {
+                                downloadClick(item);
+                              }}
+                            />
+                          </Tooltip>,
+                        ]}
+                      >
+                        <div style={{ textAlign: 'center', paddingLeft: 10 }}>
+                          {`${startTime}`} ~ {`${endTime}`}
+                        </div>
+                      </List.Item>
+                    );
+                  }}
+                >
+                  <div></div>
+                </List>
+              ) : (
+                <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;