Sfoglia il codice sorgente

feat(视频分屏): 优化分屏样式

xieyonghong 3 anni fa
parent
commit
932b4aaf93

+ 2 - 1
src/components/BadgeStatus/index.tsx

@@ -1,4 +1,5 @@
 import { Badge } from 'antd';
+import React from 'react';
 
 /**
  * 状态色
@@ -14,7 +15,7 @@ export enum StatusColorEnum {
 export type StatusColorType = keyof typeof StatusColorEnum;
 
 export interface BadgeStatusProps {
-  text: string;
+  text: string | React.ReactNode;
   status: string | number;
   /**
    * 自定义status值颜色

+ 33 - 32
src/components/Player/ScreenPlayer.tsx

@@ -11,7 +11,7 @@ import {
   CaretRightOutlined,
   PlusOutlined,
   MinusOutlined,
-  AudioOutlined,
+  // AudioOutlined,
 } from '@ant-design/icons';
 
 type Player = {
@@ -22,18 +22,19 @@ type Player = {
 interface ScreenProps {
   url?: string;
   id?: string;
+  channelId?: string;
   /**
    *
    * @param id 当前选中播发视频ID
    * @param type 当前操作动作
    */
-  onMouseDown?: (id: string, type: string) => void;
+  onMouseDown?: (id: string, channelId: string, type: string) => void;
   /**
    *
    * @param id 当前选中播发视频ID
    * @param type 当前操作动作
    */
-  onMouseLeave?: (id: string, type: string) => void;
+  onMouseLeave?: (id: string, channelId: string, type: string) => void;
 }
 
 export default (props: ScreenProps) => {
@@ -126,13 +127,13 @@ export default (props: ScreenProps) => {
           <div
             className={'direction-item up'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'UP');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'UP');
               }
             }}
           >
@@ -141,13 +142,13 @@ export default (props: ScreenProps) => {
           <div
             className={'direction-item right'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'RIGHT');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'RIGHT');
               }
             }}
           >
@@ -156,13 +157,13 @@ export default (props: ScreenProps) => {
           <div
             className={'direction-item left'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'LEFT');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'LEFT');
               }
             }}
           >
@@ -171,13 +172,13 @@ export default (props: ScreenProps) => {
           <div
             className={'direction-item down'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'DOWN');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'DOWN');
               }
             }}
           >
@@ -186,30 +187,30 @@ export default (props: ScreenProps) => {
           <div
             className={'direction-audio'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'AUDIO');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'AUDIO');
               }
             }}
           >
-            <AudioOutlined />
+            {/*<AudioOutlined />*/}
           </div>
         </div>
         <div className={'zoom'}>
           <div
             className={'zoom-item zoom-in'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'ZOOM_IN');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'ZOOM_IN');
               }
             }}
           >
@@ -218,13 +219,13 @@ export default (props: ScreenProps) => {
           <div
             className={'zoom-item zoom-out'}
             onMouseDown={() => {
-              if (props.onMouseDown && props.id) {
-                props.onMouseDown(props.id, '');
+              if (props.onMouseDown && props.id && props.channelId) {
+                props.onMouseDown(props.id, props.channelId, 'ZOOM_OUT');
               }
             }}
             onMouseLeave={() => {
-              if (props.onMouseLeave && props.id) {
-                props.onMouseLeave(props.id, '');
+              if (props.onMouseLeave && props.id && props.channelId) {
+                props.onMouseLeave(props.id, props.channelId, 'ZOOM_OUT');
               }
             }}
           >

+ 75 - 69
src/pages/media/Device/index.tsx

@@ -1,3 +1,4 @@
+// 视频设备列表
 import { PageContainer } from '@ant-design/pro-layout';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
@@ -7,6 +8,8 @@ import BaseCrud from '@/components/BaseCrud';
 import BaseService from '@/utils/BaseService';
 import type { DeviceItem } from '@/pages/media/Device/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { BadgeStatus } from '@/components';
+import { StatusColorEnum } from '@/components/BadgeStatus';
 
 export const service = new BaseService<DeviceItem>('media/device');
 const Device = () => {
@@ -26,81 +29,83 @@ const Device = () => {
         defaultMessage: '名称',
       }),
     },
-    {
-      dataIndex: 'transport',
-      title: intl.formatMessage({
-        id: 'pages.media.device.transport',
-        defaultMessage: '信令传输',
-      }),
-    },
-    {
-      dataIndex: 'streamMode',
-      title: intl.formatMessage({
-        id: 'pages.media.device.streamMode',
-        defaultMessage: '流传输模式',
-      }),
-    },
-    {
-      dataIndex: 'channelNumber',
-      title: intl.formatMessage({
-        id: 'pages.media.device.channelNumber',
-        defaultMessage: '通道数',
-      }),
-    },
-    {
-      dataIndex: 'state',
-      title: intl.formatMessage({
-        id: 'pages.searchTable.titleStatus',
-        defaultMessage: '状态',
-      }),
-      render: (text, record) => record.state.value,
-    },
-    {
-      dataIndex: 'host',
-      title: 'IP',
-    },
-    {
-      dataIndex: '端口',
-      title: intl.formatMessage({
-        id: 'pages.media.device.port',
-        defaultMessage: '端口',
-      }),
-    },
-    {
-      dataIndex: 'manufacturer',
-      title: intl.formatMessage({
-        id: 'pages.media.device.manufacturer',
-        defaultMessage: '设备厂家',
-      }),
-    },
-    {
-      dataIndex: 'model',
-      title: intl.formatMessage({
-        id: 'pages.media.device.model',
-        defaultMessage: '型号',
-      }),
-    },
-    {
-      dataIndex: 'firmware',
-      title: intl.formatMessage({
-        id: 'pages.media.device.firmware',
-        defaultMessage: '固件版本',
-      }),
-    },
-    {
-      dataIndex: 'networkType',
-      title: intl.formatMessage({
-        id: 'pages.table.type',
-        defaultMessage: '类型',
-      }),
-    },
+    // {
+    //   dataIndex: 'transport',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.transport',
+    //     defaultMessage: '信令传输',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'streamMode',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.streamMode',
+    //     defaultMessage: '流传输模式',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'channelNumber',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.channelNumber',
+    //     defaultMessage: '通道数',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'host',
+    //   title: 'IP',
+    // },
+    // {
+    //   dataIndex: '端口',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.port',
+    //     defaultMessage: '端口',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'manufacturer',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.manufacturer',
+    //     defaultMessage: '设备厂家',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'model',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.model',
+    //     defaultMessage: '型号',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'firmware',
+    //   title: intl.formatMessage({
+    //     id: 'pages.media.device.firmware',
+    //     defaultMessage: '固件版本',
+    //   }),
+    // },
+    // {
+    //   dataIndex: 'networkType',
+    //   title: intl.formatMessage({
+    //     id: 'pages.table.type',
+    //     defaultMessage: '类型',
+    //   }),
+    // },
     {
       dataIndex: 'state',
       title: intl.formatMessage({
         id: 'pages.searchTable.titleStatus',
         defaultMessage: '状态',
       }),
-      render: (text, record) => record.state.value,
+      render: (text, record) => (
+        <BadgeStatus
+          status={record.state.value}
+          statusNames={{
+            online: StatusColorEnum.success,
+            offline: StatusColorEnum.error,
+            notActive: StatusColorEnum.processing,
+          }}
+          text={text}
+        />
+      ),
     },
     {
       title: intl.formatMessage({
@@ -161,6 +166,7 @@ const Device = () => {
       <BaseCrud
         columns={columns}
         service={service}
+        search={false}
         title={intl.formatMessage({
           id: 'pages.media.device',
           defaultMessage: '模拟测试',

+ 24 - 3
src/pages/media/SplitScreen/index.tsx

@@ -1,17 +1,38 @@
+// 视频分屏
 import { PageContainer } from '@ant-design/pro-layout';
 import { Card } from 'antd';
 import LeftTree from './tree';
-import './index.less';
 import { ScreenPlayer } from '@/components';
+import { ptzStop, ptzTool } from './service';
+import { useState } from 'react';
+import './index.less';
 
 const SplitScreen = () => {
+  const [deviceId, setDeviceId] = useState('');
+  const [channelId] = useState('');
+  const [url] = useState('');
+
   return (
     <PageContainer>
       <Card>
         <div className="split-screen">
-          <LeftTree />
+          <LeftTree
+            onSelect={(id) => {
+              setDeviceId(id);
+            }}
+          />
           <div className="right-content">
-            <ScreenPlayer />
+            <ScreenPlayer
+              id={deviceId}
+              url={url}
+              channelId={channelId}
+              onMouseLeave={(id, cId) => {
+                ptzStop(id, cId);
+              }}
+              onMouseDown={(id, cId, type) => {
+                ptzTool(id, cId, type, 90);
+              }}
+            />
           </div>
         </div>
       </Card>

+ 20 - 0
src/pages/media/SplitScreen/service.ts

@@ -0,0 +1,20 @@
+import { request } from '@@/plugin-request/request';
+import SystemConst from '@/utils/const';
+
+const url = `/${SystemConst.API_BASE}/media`;
+
+// 设备树
+export const getMediaTree = (data?: any) =>
+  request(`${url}/device/_query/no-paging`, { method: 'POST', data });
+
+// 开始直播
+export const ptzStart = (deviceId: string, channelId: string) =>
+  request(`${url}/device/${deviceId}/${channelId}/_pzt/_start`, { method: 'POST' });
+
+// 云台控制-停止
+export const ptzStop = (deviceId: string, channelId: string) =>
+  request(`${url}/device/${deviceId}/${channelId}/_pzt/STOP`, { method: 'POST' });
+
+// 云台控制-缩放、转向等
+export const ptzTool = (deviceId: string, channelId: string, direct: string, speed: number = 90) =>
+  request(`${url}/device/${deviceId}/${channelId}/_pzt/${direct}/${speed}`, { method: 'POST' });

+ 29 - 2
src/pages/media/SplitScreen/tree.tsx

@@ -1,10 +1,37 @@
 import { Input, Tree } from 'antd';
+import { getMediaTree } from './service';
+import { useRequest } from 'umi';
+import { useEffect } from 'react';
+
+type LeftTreeTYpe = {
+  onSelect?: (deviceId: string) => void;
+};
+
+const LeftTree = (props: LeftTreeTYpe) => {
+  const { data, run: queryTree } = useRequest(getMediaTree, {
+    manual: true,
+  });
+
+  useEffect(() => {
+    queryTree({ paging: false });
+  }, []);
 
-const LeftTree = () => {
   return (
     <div className="left-content">
       <Input.Search />
-      <Tree />
+      <Tree
+        height={500}
+        fieldNames={{
+          title: 'name',
+          key: 'id',
+        }}
+        onSelect={(key) => {
+          if (props.onSelect) {
+            props.onSelect(key[0] as string);
+          }
+        }}
+        treeData={data}
+      />
     </div>
   );
 };

+ 0 - 0
src/pages/media/SplitScreen/type.d.ts


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

@@ -47,7 +47,7 @@ export const MENUS_CODE = {
 
   'notice/Type': 'notice/Type',
   'media/SplitScreen': 'media/SplitScreen',
-  'notice/Config': 'notice/Config',
+  'notice/Type/Config': 'notice/Config',
   'notice/Config/Detail': 'notice/Config/Detail',
   'notice/Template': 'notice/Template',
   'notice/Template/Detail': 'notice/Template/Detail',