lind 3 лет назад
Родитель
Сommit
4502ad7a4f

+ 39 - 16
src/components/Player/ScreenPlayer.tsx

@@ -24,6 +24,7 @@ interface ScreenProps {
   id?: string;
   channelId: string;
   className?: string;
+  historyHandle?: (deviceId: string, channelId: string) => string;
   /**
    *
    * @param id 当前选中播发视频ID
@@ -136,11 +137,33 @@ export default forwardRef((props: ScreenProps, ref) => {
     [players, playerActive, screen, props.showScreen],
   );
 
-  const handleHistory = (item: any) => {
-    const log = JSON.parse(item.content || '{}');
-    setScreen(log.screen);
-    setPlayers(log.players);
-  };
+  const handleHistory = useCallback(
+    (item: any) => {
+      if (props.historyHandle) {
+        const log = JSON.parse(item.content || '{}');
+        setScreen(log.screen);
+        const oldPlayers = [...players];
+
+        setPlayers(
+          oldPlayers.map((oldPlayer, index) => {
+            oldPlayer.show = false;
+            if (index < log.screen) {
+              const { deviceId, channelId } = log.players[index];
+              return {
+                ...oldPlayer,
+                id: deviceId,
+                channelId: deviceId,
+                url: deviceId ? props.historyHandle!(deviceId, channelId) : '',
+                show: true,
+              };
+            }
+            return oldPlayer;
+          }),
+        );
+      }
+    },
+    [players, props.historyHandle],
+  );
 
   const getHistory = async () => {
     const resp = await service.history.query(DEFAULT_SAVE_CODE);
@@ -163,7 +186,7 @@ export default forwardRef((props: ScreenProps, ref) => {
       name: historyValue.alias,
       content: JSON.stringify({
         screen: screen,
-        players: players,
+        players: players.map((item) => ({ deviceId: item.id, channelId: item.channelId })),
       }),
     };
     const resp = await service.history.save(DEFAULT_SAVE_CODE, param);
@@ -183,7 +206,6 @@ export default forwardRef((props: ScreenProps, ref) => {
         id: '',
         channelId: '',
         url: '',
-        updateTime: 0,
         key: 'time_' + new Date().getTime() + i,
         show: i === 0,
       });
@@ -233,13 +255,15 @@ export default forwardRef((props: ScreenProps, ref) => {
       {historyList.length ? (
         historyList.map((item: any) => {
           return (
-            <Menu.Item
-              key={item.id}
-              onClick={() => {
-                handleHistory(item);
-              }}
-            >
-              {item.name}
+            <Menu.Item key={item.id}>
+              <span
+                onClick={() => {
+                  handleHistory(item);
+                }}
+                style={{ padding: '0 4px' }}
+              >
+                {item.name}
+              </span>
               <Popconfirm
                 title={'确认删除'}
                 onConfirm={(e) => {
@@ -378,8 +402,7 @@ export default forwardRef((props: ScreenProps, ref) => {
                       }
                     }}
                   >
-                    {' '}
-                    刷新{' '}
+                    刷新
                   </div>
                   <LivePlayer url={item.url} />
                 </div>

+ 1 - 1
src/components/ProTableCard/CardItems/mediaDevice.tsx

@@ -49,7 +49,7 @@ export default (props: ProductCardProps) => {
             </div>
             <div>
               <label>接入方式</label>
-              <div className={'ellipsis'}>{props.transport || '--'}</div>
+              <div className={'ellipsis'}>{props.provider || '--'}</div>
             </div>
           </div>
         </div>

+ 4 - 0
src/pages/device/Instance/index.tsx

@@ -172,6 +172,8 @@ const Instance = () => {
     {
       title: 'ID',
       dataIndex: 'id',
+      width: 300,
+      ellipsis: true,
     },
     {
       title: intl.formatMessage({
@@ -180,6 +182,7 @@ const Instance = () => {
       }),
       dataIndex: 'name',
       ellipsis: true,
+      width: 200,
     },
     {
       title: intl.formatMessage({
@@ -187,6 +190,7 @@ const Instance = () => {
         defaultMessage: '产品名称',
       }),
       dataIndex: 'productName',
+      width: 200,
       ellipsis: true,
     },
     {

+ 7 - 0
src/pages/device/Product/index.tsx

@@ -232,14 +232,19 @@ const Product = observer(() => {
     {
       title: 'ID',
       dataIndex: 'id',
+      width: 300,
+      ellipsis: true,
     },
     {
       title: '名称',
       dataIndex: 'name',
+      width: 200,
+      ellipsis: true,
     },
     {
       title: '接入方式',
       dataIndex: 'transportProtocol',
+      width: 120,
     },
     {
       title: '设备类型',
@@ -259,6 +264,7 @@ const Product = observer(() => {
           status: 'gateway',
         },
       },
+      width: 120,
       render: (_, row) => <>{row.deviceType ? row.deviceType.text : undefined}</>,
     },
     {
@@ -266,6 +272,7 @@ const Product = observer(() => {
       dataIndex: 'state',
       render: (_, row) => <Space size={0}>{status[row.state]}</Space>,
       valueType: 'select',
+      width: '90px',
       valueEnum: {
         // 2: {
         //   text: intl.formatMessage({

+ 1 - 1
src/pages/media/Device/Save/index.tsx

@@ -273,7 +273,7 @@ export default (props: SaveProps) => {
                       buttonStyle="solid"
                       options={[
                         { label: 'UDP', value: 'UDP' },
-                        { label: 'TCP', value: 'TCP' },
+                        { label: 'TCP', value: 'TCP_PASSIVE' },
                       ]}
                     />
                   </Form.Item>

+ 31 - 1
src/pages/media/Device/index.tsx

@@ -63,8 +63,8 @@ const Device = () => {
           defaultMessage: '操作成功!',
         }),
       );
+      actionRef.current?.reload();
     }
-    actionRef.current?.reload();
   };
 
   /**
@@ -99,6 +99,18 @@ const Device = () => {
       render: (_, row) => {
         return providerType[row.provider];
       },
+      valueType: 'select',
+      valueEnum: {
+        [ProviderValue.FIXED]: {
+          text: '固定地址',
+          status: ProviderValue.FIXED,
+        },
+        [ProviderValue.GB281]: {
+          text: 'GB/T28181',
+          status: ProviderValue.GB281,
+        },
+      },
+      filterMultiple: false,
     },
     {
       dataIndex: 'channelNumber',
@@ -135,6 +147,7 @@ const Device = () => {
         id: 'pages.searchTable.titleStatus',
         defaultMessage: '状态',
       }),
+      valueType: 'select',
       render: (_, record) => (
         <BadgeStatus
           status={record.state.value}
@@ -146,6 +159,23 @@ const Device = () => {
           text={record.state.text}
         />
       ),
+      valueEnum: {
+        offline: {
+          text: intl.formatMessage({
+            id: 'pages.device.instance.status.offLine',
+            defaultMessage: '离线',
+          }),
+          status: 'offline',
+        },
+        online: {
+          text: intl.formatMessage({
+            id: 'pages.device.instance.status.onLine',
+            defaultMessage: '在线',
+          }),
+          status: 'online',
+        },
+      },
+      filterMultiple: false,
     },
     {
       title: intl.formatMessage({

+ 7 - 4
src/pages/media/SplitScreen/index.tsx

@@ -3,9 +3,8 @@ import { PageContainer } from '@ant-design/pro-layout';
 import { Card } from 'antd';
 import LeftTree from './tree';
 import { ScreenPlayer } from '@/components';
-import { ptzStop, ptzTool } from './service';
+import { ptzStart, ptzStop, ptzTool } from './service';
 import { useRef, useState } from 'react';
-import { ptzStart } from './service';
 import './index.less';
 
 const SplitScreen = () => {
@@ -13,11 +12,14 @@ const SplitScreen = () => {
   const [channelId, setChannelId] = useState('');
   const player = useRef<any>(null);
 
+  const getMediaUrl = (dId: string, cId: string): string => {
+    return ptzStart(dId, cId, 'mp4');
+  };
+
   const mediaStart = async (dId: string, cId: string) => {
     setChannelId(cId);
     setDeviceId(dId);
-    const url = ptzStart(dId, cId, 'mp4');
-    player.current?.replaceVideo(dId, cId, url);
+    player.current?.replaceVideo(dId, cId, getMediaUrl(dId, cId));
   };
 
   return (
@@ -36,6 +38,7 @@ const SplitScreen = () => {
               onMouseDown={(id, cId, type) => {
                 ptzTool(id, cId, type);
               }}
+              historyHandle={(dId, cId) => getMediaUrl(dId, cId)}
             />
           </div>
         </div>

+ 7 - 0
src/pages/system/Department/index.tsx

@@ -211,6 +211,7 @@ export default observer(() => {
             label: 'name',
             value: 'id',
           },
+          placeholder: '请选择上级部门',
         },
         enum: treeData,
       },
@@ -223,6 +224,9 @@ export default observer(() => {
         required: true,
         'x-decorator': 'FormItem',
         'x-component': 'Input',
+        'x-component-props': {
+          placeholder: '请输入名称',
+        },
         'x-validator': [
           {
             max: 64,
@@ -243,6 +247,9 @@ export default observer(() => {
         required: true,
         'x-decorator': 'FormItem',
         'x-component': 'NumberPicker',
+        'x-component-props': {
+          placeholder: '请输入排序',
+        },
         'x-validator': [
           {
             required: true,

+ 5 - 3
src/pages/system/Menu/Detail/buttons.tsx

@@ -219,6 +219,7 @@ export default (props: ButtonsProps) => {
           onConfirm={() => {
             deleteItem(record.id);
           }}
+          disabled={getButtonPermission('system/Menu', 'delete')}
         >
           <Tooltip
             title={intl.formatMessage({
@@ -259,6 +260,7 @@ export default (props: ButtonsProps) => {
             key="button"
             icon={<PlusOutlined />}
             type="primary"
+            disabled={getButtonPermission('system/Menu', ['add'])}
           >
             {intl.formatMessage({
               id: 'pages.data.option.add',
@@ -311,7 +313,7 @@ export default (props: ButtonsProps) => {
               },
             ]}
           >
-            <Input disabled={!!(disabled || id)} />
+            <Input disabled={!!(disabled || id)} placeholder={'请输入编码'} />
           </Form.Item>
           <Form.Item
             name="name"
@@ -325,7 +327,7 @@ export default (props: ButtonsProps) => {
               { max: 64, message: '最多可输入64个字符' },
             ]}
           >
-            <Input disabled={disabled} />
+            <Input disabled={disabled} placeholder={'请输入名称'} />
           </Form.Item>
           <Form.Item
             label={intl.formatMessage({
@@ -352,7 +354,7 @@ export default (props: ButtonsProps) => {
               defaultMessage: '描述',
             })}
           >
-            <Input.TextArea disabled={disabled} />
+            <Input.TextArea disabled={disabled} placeholder={'请输入描述'} />
           </Form.Item>
         </Form>
       </Modal>

+ 6 - 1
src/pages/system/Menu/Detail/edit.tsx

@@ -22,7 +22,7 @@ import type { MenuItem } from '@/pages/system/Menu/typing';
 import Title from '../components/Title';
 import Icons from '../components/Icons';
 import { QuestionCircleFilled } from '@ant-design/icons';
-import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 
 type EditProps = {
   data: MenuItem;
@@ -327,6 +327,11 @@ export default (props: EditProps) => {
                 saveData();
               }
             }}
+            disabled={
+              disabled
+                ? getButtonPermission('system/Menu', ['update'])
+                : getButtonPermission('system/Menu', ['add'])
+            }
           >
             {intl.formatMessage({
               id: `pages.data.option.${disabled ? 'edit' : 'save'}`,

+ 1 - 0
src/utils/menu/router.ts

@@ -114,6 +114,7 @@ export type BUTTON_PERMISSION =
   | 'export'
   | 'update'
   | 'action'
+  | 'push'
   | string;
 
 export const getDetailNameByCode = {