Jelajahi Sumber

fix: (merge) sc

sun-chaochao 3 tahun lalu
induk
melakukan
ea2aa6d079

+ 7 - 0
src/components/AIcon/index.tsx

@@ -0,0 +1,7 @@
+import { createFromIconfontCN } from '@ant-design/icons';
+
+const AIcon = createFromIconfontCN({
+  scriptUrl: '/icons/iconfont.js', // 在 iconfont.cn 上生成
+});
+
+export default AIcon;

+ 1 - 0
src/components/index.ts

@@ -6,3 +6,4 @@ export { default as BadgeStatus } from './BadgeStatus';
 export { default as Player } from './Player';
 export { default as ScreenPlayer } from './Player/ScreenPlayer';
 export { default as Modal } from './Modal';
+export { default as AIcon } from './AIcon';

+ 7 - 0
src/pages/device/Category/Save/index.tsx

@@ -103,6 +103,9 @@ const Save = (props: Props) => {
         }),
         'x-decorator': 'FormItem',
         'x-component': 'Input',
+        'x-component-props': {
+          placeholder: '请输入名称',
+        },
         required: true,
         name: 'name',
       },
@@ -113,6 +116,9 @@ const Save = (props: Props) => {
         }),
         'x-decorator': 'FormItem',
         'x-component': 'NumberPicker',
+        'x-component-props': {
+          placeholder: '请输入分类排序',
+        },
         name: 'sortIndex',
       },
       description: {
@@ -125,6 +131,7 @@ const Save = (props: Props) => {
         'x-component': 'Input.TextArea',
         'x-component-props': {
           rows: 3,
+          placeholder: '请输入描述',
         },
         name: 'description',
       },

+ 12 - 3
src/pages/device/Instance/Save/index.tsx

@@ -157,7 +157,7 @@ const Save = (props: Props) => {
             >
               <Input
                 disabled={props.model === 'edit'}
-                placeholder={intlFormat('pages.form.tip.input', '请输入')}
+                placeholder={`${intlFormat('pages.form.tip.input', '请输入')}ID`}
               />
             </Form.Item>
             <Form.Item
@@ -183,7 +183,12 @@ const Save = (props: Props) => {
               ]}
               required
             >
-              <Input placeholder={intlFormat('pages.form.tip.input', '请输入')} />
+              <Input
+                placeholder={
+                  intlFormat('pages.form.tip.input', '请输入') +
+                  intlFormat('pages.table.name', '名称')
+                }
+              />
             </Form.Item>
           </Col>
         </Row>
@@ -213,6 +218,7 @@ const Save = (props: Props) => {
                     productName: node.label,
                   });
                 }}
+                placeholder={'请选择所属产品'}
                 filterOption={(input, option) => option.label.includes(input)}
               />
             </Form.Item>
@@ -225,7 +231,10 @@ const Save = (props: Props) => {
           <Col span={24}>
             <Form.Item label={intlFormat('pages.table.description', '说明')} name={'describe'}>
               <Input.TextArea
-                placeholder={intlFormat('pages.form.tip.input', '请输入')}
+                placeholder={
+                  intlFormat('pages.form.tip.input', '请输入') +
+                  intlFormat('pages.table.description', '说明')
+                }
                 rows={4}
                 style={{ width: '100%' }}
                 maxLength={200}

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

@@ -192,6 +192,15 @@ const Instance = () => {
       dataIndex: 'productName',
       width: 200,
       ellipsis: true,
+      valueType: 'select',
+      request: async () => {
+        const res = await service.getProductList();
+        if (res.status === 200) {
+          return res.result.map((pItem: any) => ({ label: pItem.name, value: pItem.id }));
+        }
+        return [];
+      },
+      filterMultiple: true,
     },
     {
       title: intl.formatMessage({

+ 1 - 1
src/pages/device/Instance/service.ts

@@ -9,7 +9,7 @@ class Service extends BaseService<DeviceInstance> {
   public detail = (id: string) => request(`${this.uri}/${id}/detail`, { method: 'GET' });
 
   // 查询产品列表
-  public getProductList = (params: any) =>
+  public getProductList = (params?: any) =>
     request(`/${SystemConst.API_BASE}/device/product/_query/no-paging`, { method: 'GET', params });
 
   // 批量删除设备

+ 12 - 4
src/pages/device/Product/Save/index.tsx

@@ -169,7 +169,7 @@ const Save = (props: Props) => {
             >
               <Input
                 disabled={props.model === 'edit'}
-                placeholder={intlFormat('pages.form.tip.input', '请输入')}
+                placeholder={`${intlFormat('pages.form.tip.input', '请输入')}ID`}
               />
             </Form.Item>
             <Form.Item
@@ -195,7 +195,12 @@ const Save = (props: Props) => {
               ]}
               required
             >
-              <Input placeholder={intlFormat('pages.form.tip.input', '请输入')} />
+              <Input
+                placeholder={
+                  intlFormat('pages.form.tip.input', '请输入') +
+                  intlFormat('pages.table.name', '名称')
+                }
+              />
             </Form.Item>
           </Col>
         </Row>
@@ -210,7 +215,7 @@ const Save = (props: Props) => {
                   });
                 }}
                 filterTreeNode={(input, treeNode) => treeNode.name.includes(input)}
-                placeholder={intlFormat('pages.form.tip.select', '请选择')}
+                placeholder={`${intlFormat('pages.form.tip.select', '请选择')}分类`}
                 fieldNames={{
                   label: 'name',
                   value: 'id',
@@ -264,7 +269,10 @@ const Save = (props: Props) => {
           <Col span={24}>
             <Form.Item label={intlFormat('pages.table.description', '说明')} name={'describe'}>
               <Input.TextArea
-                placeholder={intlFormat('pages.form.tip.input', '请输入')}
+                placeholder={
+                  intlFormat('pages.form.tip.input', '请输入') +
+                  intlFormat('pages.table.description', '说明')
+                }
                 rows={4}
                 style={{ width: '100%' }}
                 maxLength={200}

+ 3 - 3
src/pages/device/Product/index.tsx

@@ -6,7 +6,6 @@ import {
   DownloadOutlined,
   EditOutlined,
   EyeOutlined,
-  PlayCircleOutlined,
   PlusOutlined,
   StopOutlined,
 } from '@ant-design/icons';
@@ -23,6 +22,7 @@ import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/me
 import { ProTableCard } from '@/components';
 import ProductCard from '@/components/ProTableCard/CardItems/product';
 import { downloadObject } from '@/utils/util';
+import AIcon from '../../../components/AIcon';
 
 export const service = new Service('device-product');
 export const statusMap = {
@@ -191,7 +191,7 @@ const Product = observer(() => {
             defaultMessage: record.state ? '禁用' : '启用',
           })}
         >
-          {record.state ? <StopOutlined /> : <PlayCircleOutlined />}
+          {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
         </Tooltip>
       </Button>
     </Popconfirm>,
@@ -481,7 +481,7 @@ const Product = observer(() => {
                   type={'link'}
                   disabled={getButtonPermission('device/Product', ['action'])}
                 >
-                  {record.state ? <StopOutlined /> : <PlayCircleOutlined />}
+                  {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
                   {intl.formatMessage({
                     id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
                     defaultMessage: record.state ? '禁用' : '启用',

+ 1 - 0
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -409,6 +409,7 @@ const Edit = observer((props: Props) => {
               id: 'pages.device.productDetail.metadata.source',
               defaultMessage: '来源',
             }),
+            'x-disabled': MetadataModel.action === 'edit',
             required: true,
             'x-decorator': 'FormItem',
             'x-component': 'Select',

+ 3 - 1
src/pages/device/components/Metadata/Import/index.tsx

@@ -35,7 +35,9 @@ const Import = (props: Props) => {
 
   const loadData = () => async (field: Field) => {
     field.loading = true;
-    const product = (await service.queryNoPaging({})) as any;
+    const product = (await service.queryNoPagingPost({
+      terms: [{ column: 'id$not', value: param.id }],
+    })) as any;
     field.dataSource = product.result.map((item: any) => ({
       label: item.name,
       value: item.metadata,

+ 74 - 34
src/pages/link/Type/Detail/index.tsx

@@ -18,7 +18,7 @@ import type { ISchema } from '@formily/json-schema';
 import { useEffect, useMemo, useRef } from 'react';
 import type { Field } from '@formily/core';
 import { createForm, onFieldValueChange } from '@formily/core';
-import { Button, Card, message } from 'antd';
+import { Card, message } from 'antd';
 import styles from './index.less';
 import { useAsyncDataSource } from '@/utils/util';
 import { service } from '../index';
@@ -97,7 +97,7 @@ const Save = observer(() => {
   const form = useMemo(
     () =>
       createForm({
-        readPretty: false,
+        // readPretty: true,
         // initialValues: {},
         effects() {
           onFieldValueChange('type', (field, f) => {
@@ -168,7 +168,7 @@ const Save = observer(() => {
   useEffect(() => {
     const subscription = Store.subscribe('current-network-data', (data) => {
       if (!data) return;
-      form.readPretty = true;
+      // form.readPretty = true;
       const _data = _.cloneDeep(data);
       // 处理一下集群模式数据
       if (!_data.shareCluster) {
@@ -255,7 +255,7 @@ const Save = observer(() => {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
               visible:
-                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER","MQTT_CLIENT"].includes($deps[0])}}',
+                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER"].includes($deps[0])}}',
             },
           },
         },
@@ -279,7 +279,7 @@ const Save = observer(() => {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
               visible:
-                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER","MQTT_CLIENT"].includes($deps[0])}}',
+                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER"].includes($deps[0])}}',
             },
           },
         },
@@ -312,7 +312,7 @@ const Save = observer(() => {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
               visible:
-                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER","MQTT_CLIENT"].includes($deps[0])}}',
+                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER"].includes($deps[0])}}',
             },
           },
         },
@@ -334,7 +334,7 @@ const Save = observer(() => {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
               visible:
-                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER","MQTT_CLIENT"].includes($deps[0])}}',
+                '{{["COAP_SERVER","MQTT_SERVER","WEB_SOCKET_SERVER","TCP_SERVER","UDP","HTTP_SERVER"].includes($deps[0])}}',
             },
           },
         },
@@ -356,43 +356,87 @@ const Save = observer(() => {
           fulfill: {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
-              visible: '{{["MQTT_Client"].includes($deps[0])}}',
+              visible: '{{["MQTT_CLIENT"].includes($deps[0])}}',
             },
           },
         },
         properties: {
           remoteHost: {
             title: '远程地址',
+            'x-decorator-props': {
+              gridSpan: 1,
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
+            'x-validator': ['ipv4'],
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
           remotePort: {
             title: '远程端口',
+            'x-decorator-props': {
+              gridSpan: 1,
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
             'x-decorator': 'FormItem',
-            'x-component': 'Input',
+            'x-component': 'NumberPicker',
           },
           clientId: {
             title: 'clientId',
+            'x-decorator-props': {
+              gridSpan: 1,
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
           username: {
             title: '用户名',
+            'x-decorator-props': {
+              gridSpan: 1,
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
           password: {
             title: '密码',
+            'x-decorator-props': {
+              gridSpan: 1,
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
           maxMessageSize: {
             title: '最大消息长度',
+            'x-decorator-props': {
+              gridSpan: 1,
+              tooltip: '单次收发消息的最大长度,单位:字节;设置过大可能会影响性能',
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
+            required: true,
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
           topicPrefix: {
             title: '订阅前缀',
+            'x-decorator-props': {
+              gridSpan: 1,
+              tooltip: '当连接的服务为EMQ时,可能需要使用共享的订阅前缀,如:$queue或$share',
+              layout: 'vertical',
+              labelAlign: 'left',
+            },
             'x-decorator': 'FormItem',
             'x-component': 'Input',
           },
@@ -413,30 +457,30 @@ const Save = observer(() => {
           fulfill: {
             state: {
               // visible: '{{$deps[0]==="UDP"}}',
-              visible: '{{["MQTT_SERVER","MQTT_CLIENT"].includes($deps[0])}}',
-            },
-          },
-        },
-      },
-      topicPrefix: {
-        title: '订阅前缀',
-        'x-decorator': 'FormItem',
-        'x-component': 'Input',
-        'x-decorator-props': {
-          gridSpan: 1,
-          labelAlign: 'left',
-          layout: 'vertical',
-        },
-        'x-reactions': {
-          dependencies: ['type'],
-          fulfill: {
-            state: {
-              // visible: '{{$deps[0]==="UDP"}}',
-              visible: '{{["MQTT_CLIENT"].includes($deps[0])}}',
+              visible: '{{["MQTT_SERVER"].includes($deps[0])}}',
             },
           },
         },
       },
+      // topicPrefix: {
+      //   title: '订阅前缀',
+      //   'x-decorator': 'FormItem',
+      //   'x-component': 'Input',
+      //   'x-decorator-props': {
+      //     gridSpan: 1,
+      //     labelAlign: 'left',
+      //     layout: 'vertical',
+      //   },
+      //   'x-reactions': {
+      //     dependencies: ['type'],
+      //     fulfill: {
+      //       state: {
+      //         // visible: '{{$deps[0]==="UDP"}}',
+      //         visible: '{{["MQTT_CLIENT"].includes($deps[0])}}',
+      //       },
+      //     },
+      //   },
+      // },
       parserType: {
         // TCP
         required: true,
@@ -741,11 +785,7 @@ const Save = observer(() => {
           />
           <FormButtonGroup.Sticky>
             <FormButtonGroup.FormItem>
-              {!form.readPretty ? (
-                <Submit onSubmit={handleSave}>保存</Submit>
-              ) : (
-                <Button onClick={() => (form.readPretty = false)}>编辑</Button>
-              )}
+              <Submit onSubmit={handleSave}>保存</Submit>
             </FormButtonGroup.FormItem>
           </FormButtonGroup.Sticky>
         </Form>

+ 3 - 3
src/pages/link/Type/index.tsx

@@ -5,7 +5,7 @@ import { Badge, Button, message, Popconfirm, Tooltip } from 'antd';
 import {
   CloseCircleOutlined,
   DeleteOutlined,
-  EyeOutlined,
+  EditOutlined,
   PlayCircleOutlined,
   PlusOutlined,
 } from '@ant-design/icons';
@@ -107,7 +107,7 @@ const Network = () => {
         <Button
           type="link"
           style={{ padding: 0 }}
-          disabled={getButtonPermission('link/Type', ['view'])}
+          // disabled={getButtonPermission('link/Type', ['view'])}
           key="edit"
           onClick={() => {
             Store.set('current-network-data', record);
@@ -115,7 +115,7 @@ const Network = () => {
           }}
         >
           <Tooltip title="查看">
-            <EyeOutlined />
+            <EditOutlined />
           </Tooltip>
         </Button>,
 

+ 49 - 32
src/pages/media/Device/Channel/index.tsx

@@ -20,7 +20,7 @@ import Save from './Save';
 import Service from './service';
 import { ProviderValue } from '../index';
 import Live from './Live';
-import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
+import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import Tree from './Tree';
 
 export const service = new Service('media');
@@ -128,14 +128,15 @@ export default () => {
             defaultMessage: '编辑',
           })}
         >
-          <a
+          <Button
             onClick={() => {
               setCurrent(record);
               setVisible(true);
             }}
+            disabled={getButtonPermission('media/Device', 'update')}
           >
             <EditOutlined />
-          </a>
+          </Button>
         </Tooltip>,
         <Tooltip key={'live'} title={'播发'}>
           <a
@@ -161,22 +162,27 @@ export default () => {
           </a>
         </Tooltip>,
         type === ProviderValue.FIXED ? (
-          <Tooltip key={'updateChannel'} title="删除">
-            <Popconfirm
-              key="delete"
-              title={intl.formatMessage({
-                id: 'page.table.isDelete',
-                defaultMessage: '是否删除?',
-              })}
-              onConfirm={async () => {
-                deleteItem(record.id);
-              }}
-            >
-              <Button type={'link'} style={{ padding: '4px' }}>
+          <Popconfirm
+            key="delete"
+            title={intl.formatMessage({
+              id: 'page.table.isDelete',
+              defaultMessage: '是否删除?',
+            })}
+            onConfirm={async () => {
+              deleteItem(record.id);
+            }}
+            disabled={getButtonPermission('media/Device', 'delete')}
+          >
+            <Tooltip title="删除">
+              <Button
+                type={'link'}
+                style={{ padding: 0 }}
+                disabled={getButtonPermission('media/Device', 'delete')}
+              >
                 <DeleteOutlined />
               </Button>
-            </Popconfirm>
-          </Tooltip>
+            </Tooltip>
+          </Popconfirm>
         ) : null,
       ],
     },
@@ -232,21 +238,32 @@ export default () => {
             rowKey="id"
             search={false}
             headerTitle={[
-              <Button
-                onClick={() => {
-                  setCurrent(undefined);
-                  setVisible(true);
-                }}
-                key="button"
-                disabled={type === ProviderValue.GB281}
-                icon={<PlusOutlined />}
-                type="primary"
-              >
-                {intl.formatMessage({
-                  id: 'pages.data.option.add',
-                  defaultMessage: '新增',
-                })}
-              </Button>,
+              type === ProviderValue.GB281 ? (
+                <Tooltip key="button" title={'接入方式为GB/T28281时,不支持新增'}>
+                  <Button disabled>
+                    {intl.formatMessage({
+                      id: 'pages.data.option.add',
+                      defaultMessage: '新增',
+                    })}
+                  </Button>
+                </Tooltip>
+              ) : (
+                <Button
+                  onClick={() => {
+                    setCurrent(undefined);
+                    setVisible(true);
+                  }}
+                  key="button"
+                  disabled={getButtonPermission('media/Device', 'add')}
+                  icon={<PlusOutlined />}
+                  type="primary"
+                >
+                  {intl.formatMessage({
+                    id: 'pages.data.option.add',
+                    defaultMessage: '新增',
+                  })}
+                </Button>
+              ),
             ]}
           />
         </div>

+ 20 - 4
src/pages/media/Device/Save/index.tsx

@@ -178,7 +178,23 @@ export default (props: SaveProps) => {
                 label={'ID'}
                 name={'id'}
                 required
-                rules={[{ required: true, message: '请输入ID' }, {}]}
+                rules={[
+                  { required: true, message: '请输入ID' },
+                  {
+                    pattern: /^[a-zA-Z0-9_\-]+$/,
+                    message: intl.formatMessage({
+                      id: 'pages.form.tip.id',
+                      defaultMessage: '请输入英文或者数字或者-或者_',
+                    }),
+                  },
+                  {
+                    max: 64,
+                    message: intl.formatMessage({
+                      id: 'pages.form.tip.max64',
+                      defaultMessage: '最多输入64个字符',
+                    }),
+                  },
+                ]}
               >
                 <Input placeholder={'请输入ID'} disabled={props.model === 'edit'} />
               </Form.Item>
@@ -213,11 +229,11 @@ export default (props: SaveProps) => {
                     placeholder={'请选择所属产品'}
                     style={{ width: props.model === 'edit' ? '100%' : 'calc(100% - 36px)' }}
                     onSelect={(_: any, node: any) => {
-                      const pasd = node.configuration ? node.configuration.access_pwd : '';
+                      const pwd = node.configuration ? node.configuration.access_pwd : '';
                       form.setFieldsValue({
-                        password: pasd,
+                        password: pwd,
                       });
-                      setOldPassword(pasd);
+                      setOldPassword(pwd);
                     }}
                   />
                 </Form.Item>

+ 0 - 3
src/pages/media/Device/index.tsx

@@ -63,7 +63,6 @@ const Device = () => {
           defaultMessage: '操作成功!',
         }),
       );
-      actionRef.current?.reload();
     }
   };
 
@@ -99,7 +98,6 @@ const Device = () => {
       render: (_, row) => {
         return providerType[row.provider];
       },
-      valueType: 'select',
       valueEnum: {
         [ProviderValue.FIXED]: {
           text: '固定地址',
@@ -147,7 +145,6 @@ const Device = () => {
         id: 'pages.searchTable.titleStatus',
         defaultMessage: '状态',
       }),
-      valueType: 'select',
       render: (_, record) => (
         <BadgeStatus
           status={record.state.value}

+ 1 - 2
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 = () => {

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

@@ -42,6 +42,7 @@ export default observer(() => {
   const [param, setParam] = useState({});
   const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]);
   const [treeData, setTreeData] = useState<any[]>([]);
+
   const rowKeys = useRef<React.Key[]>([]);
   /**
    * 根据部门ID删除数据