wzyyy 3 anni fa
parent
commit
8aae57070d
65 ha cambiato i file con 333 aggiunte e 199 eliminazioni
  1. 7 2
      src/app.tsx
  2. 20 5
      src/components/DashBoard/header.tsx
  3. 21 4
      src/components/DashBoard/timePicker.tsx
  4. 1 0
      src/components/FRuleEditor/Editor/index.tsx
  5. 1 1
      src/components/FRuleEditor/Operator/index.tsx
  6. 1 0
      src/components/FormItems/MetadataJsonInput/index.tsx
  7. 5 8
      src/components/NoticeIcon/index.tsx
  8. 2 2
      src/components/ProTableCard/CardItems/aliyun.tsx
  9. 2 2
      src/components/ProTableCard/CardItems/device.tsx
  10. 4 4
      src/components/ProTableCard/CardItems/mediaDevice.tsx
  11. 1 1
      src/components/ProTableCard/CardItems/noticeTemplate.tsx
  12. 1 1
      src/components/ProTableCard/CardItems/scene.tsx
  13. 32 7
      src/components/SearchComponent/index.tsx
  14. 3 3
      src/hooks/route/useHistory.tsx
  15. 2 2
      src/hooks/route/useLocation.tsx
  16. 1 1
      src/pages/Log/System/index.tsx
  17. 3 3
      src/pages/Northbound/DuerOS/Detail/Doc.tsx
  18. 16 5
      src/pages/Northbound/DuerOS/Detail/index.tsx
  19. 5 5
      src/pages/account/NotificationRecord/detail/index.tsx
  20. 7 4
      src/pages/account/NotificationRecord/index.tsx
  21. 1 0
      src/pages/device/Command/cat/index.tsx
  22. 5 5
      src/pages/device/Instance/Detail/Config/index.tsx
  23. 1 0
      src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx
  24. 1 1
      src/pages/device/Instance/Detail/Info/index.tsx
  25. 2 2
      src/pages/device/Instance/Detail/Reation/index.tsx
  26. 3 1
      src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx
  27. 1 1
      src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx
  28. 1 1
      src/pages/device/Instance/Detail/Running/Property/index.tsx
  29. 3 3
      src/pages/device/Instance/Detail/Tags/index.tsx
  30. 1 1
      src/pages/device/Instance/index.tsx
  31. 1 0
      src/pages/device/Instance/typings.d.ts
  32. 1 1
      src/pages/device/Product/index.tsx
  33. 1 0
      src/pages/device/components/Metadata/Cat/index.tsx
  34. 1 1
      src/pages/home/index.tsx
  35. 3 3
      src/pages/link/AccessConfig/Detail/Channel/index.tsx
  36. 3 3
      src/pages/link/AccessConfig/Detail/Cloud/Finish/index.tsx
  37. 2 2
      src/pages/link/AccessConfig/Detail/Cloud/Protocol/index.tsx
  38. 13 6
      src/pages/link/DashBoard/index.tsx
  39. 3 0
      src/pages/link/Protocol/FileUpload/index.tsx
  40. 4 12
      src/pages/link/Protocol/save/index.tsx
  41. 1 1
      src/pages/media/Device/Channel/Live/index.tsx
  42. 1 1
      src/pages/media/Device/Channel/Save.tsx
  43. 5 5
      src/pages/media/Device/Save/ProviderSelect.tsx
  44. 8 8
      src/pages/media/Device/Save/index.tsx
  45. 11 12
      src/pages/media/Device/index.tsx
  46. 3 3
      src/pages/notice/Config/Detail/doc/AliyunSms.tsx
  47. 1 1
      src/pages/notice/Config/Detail/doc/AliyunVoice.tsx
  48. 2 2
      src/pages/notice/Config/Detail/doc/DingTalk.tsx
  49. 1 1
      src/pages/notice/Config/Detail/doc/DingTalkRebot.tsx
  50. 4 4
      src/pages/notice/Config/Detail/doc/Email.tsx
  51. 2 2
      src/pages/notice/Config/Detail/doc/Webhook.tsx
  52. 2 2
      src/pages/notice/Config/Detail/doc/WeixinApp.tsx
  53. 2 2
      src/pages/notice/Config/Detail/doc/WeixinCorp.tsx
  54. 1 1
      src/pages/notice/Config/SyncUser/index.tsx
  55. 31 24
      src/pages/notice/Template/Debug/index.tsx
  56. 3 3
      src/pages/notice/Template/Detail/doc/DingTalk.tsx
  57. 1 1
      src/pages/notice/Template/Detail/doc/DingTalkRebot.tsx
  58. 4 4
      src/pages/notice/Template/Detail/doc/Email.tsx
  59. 7 7
      src/pages/notice/Template/Detail/doc/WeixinApp.tsx
  60. 2 2
      src/pages/notice/Template/Detail/doc/WeixinCorp.tsx
  61. 3 1
      src/pages/notice/Template/index.tsx
  62. 6 6
      src/pages/rule-engine/Alarm/Log/Detail/Info.tsx
  63. 1 0
      src/pages/rule-engine/Alarm/Log/SolveLog/index.tsx
  64. 2 2
      src/pages/rule-engine/DashBoard/index.less
  65. 43 1
      src/pages/system/Role/Detail/Permission/Allocate/MenuPermission.tsx

+ 7 - 2
src/app.tsx

@@ -171,7 +171,12 @@ export const request: RequestConfig = {
       history.push('/user/login');
       return;
     }
-    if (response.status === 400 || response.status === 500 || response.status === 404) {
+    if (
+      response.status === 400 ||
+      response.status === 500 ||
+      response.status === 404 ||
+      response.status === 403
+    ) {
       // 添加clone() 避免后续其它地方用response.text()时报错
       response
         .clone()
@@ -180,7 +185,7 @@ export const request: RequestConfig = {
           if (resp) {
             notification.error({
               key: 'error',
-              message: JSON.parse(resp).message || '服务器内部错误!',
+              message: JSON.parse(resp || '{}').message || '服务器内部错误!',
             });
           } else {
             response

+ 20 - 5
src/components/DashBoard/header.tsx

@@ -4,6 +4,11 @@ import { Col, Form, Radio, Row } from 'antd';
 import type { TimeType } from './timePicker';
 import RangePicker, { TimeKey } from './timePicker';
 
+interface timeToolOptions {
+  label: string;
+  value: string;
+}
+
 export interface HeaderProps {
   title: string;
   /**
@@ -20,9 +25,10 @@ export interface HeaderProps {
    * true 关闭初始化时触发onParamsChange
    */
   closeInitialParams?: boolean;
-  defaultTime?: TimeType;
+  defaultTime?: TimeType & string;
   showTime?: boolean;
   showTimeTool?: boolean;
+  timeToolOptions?: timeToolOptions[];
 }
 
 export default forwardRef((props: HeaderProps, ref) => {
@@ -83,16 +89,25 @@ export default forwardRef((props: HeaderProps, ref) => {
                       }
                     }}
                   >
-                    <Radio.Button value={TimeKey.today}>当天</Radio.Button>
-                    <Radio.Button value={TimeKey.week}>近一周</Radio.Button>
-                    <Radio.Button value={TimeKey.month}>近一月</Radio.Button>
-                    <Radio.Button value={TimeKey.year}>近一年</Radio.Button>
+                    {props.timeToolOptions && Array.isArray(props.timeToolOptions) ? (
+                      props.timeToolOptions.map((item) => (
+                        <Radio.Button value={item.value}>{item.label}</Radio.Button>
+                      ))
+                    ) : (
+                      <>
+                        <Radio.Button value={TimeKey.today}>当天</Radio.Button>
+                        <Radio.Button value={TimeKey.week}>近一周</Radio.Button>
+                        <Radio.Button value={TimeKey.month}>近一月</Radio.Button>
+                        <Radio.Button value={TimeKey.year}>近一年</Radio.Button>
+                      </>
+                    )}
                   </Radio.Group>
                 ) : null}
                 <Form.Item noStyle name={'time'}>
                   <RangePicker
                     ref={pickerRef}
                     defaultTime={props.defaultTime}
+                    timeToolOptions={props.timeToolOptions}
                     showTime={props.showTime}
                     showTimeTool={props.showTimeTool}
                     pickerTimeChange={() => {

+ 21 - 4
src/components/DashBoard/timePicker.tsx

@@ -4,6 +4,7 @@ import moment from 'moment';
 import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
 
 export enum TimeKey {
+  'hour' = 'hour',
   'today' = 'today',
   'week' = 'week',
   'month' = 'month',
@@ -14,6 +15,11 @@ export type TimeType = keyof typeof TimeKey;
 
 type ValueType = { start: number; end: number; type: TimeType };
 
+type timeToolOptions = {
+  label: string;
+  value: string;
+};
+
 interface ExtraTimePickerProps extends Omit<DatePickerProps, 'onChange' | 'value'> {
   onChange?: (data: ValueType) => void;
   value?: ValueType;
@@ -21,10 +27,13 @@ interface ExtraTimePickerProps extends Omit<DatePickerProps, 'onChange' | 'value
   pickerTimeChange?: () => void;
   showTime?: boolean;
   showTimeTool?: boolean;
+  timeToolOptions?: timeToolOptions[];
 }
 
 export const getTimeByType = (type: TimeType) => {
   switch (type) {
+    case TimeKey.hour:
+      return moment().subtract(1, 'hours').valueOf();
     case TimeKey.week:
       return moment().subtract(6, 'days').valueOf();
     case TimeKey.month:
@@ -101,10 +110,18 @@ export default forwardRef((props: ExtraTimePickerProps, ref) => {
                         timeChange(e.target.value);
                       }}
                     >
-                      <Radio.Button value={TimeKey.today}>当天</Radio.Button>
-                      <Radio.Button value={TimeKey.week}>近一周</Radio.Button>
-                      <Radio.Button value={TimeKey.month}>近一月</Radio.Button>
-                      <Radio.Button value={TimeKey.year}>近一年</Radio.Button>
+                      {props.timeToolOptions && Array.isArray(props.timeToolOptions) ? (
+                        props.timeToolOptions.map((item) => (
+                          <Radio.Button value={item.value}>{item.label}</Radio.Button>
+                        ))
+                      ) : (
+                        <>
+                          <Radio.Button value={TimeKey.today}>当天</Radio.Button>
+                          <Radio.Button value={TimeKey.week}>近一周</Radio.Button>
+                          <Radio.Button value={TimeKey.month}>近一月</Radio.Button>
+                          <Radio.Button value={TimeKey.year}>近一年</Radio.Button>
+                        </>
+                      )}
                     </Radio.Group>
                   </div>
                 )

+ 1 - 0
src/components/FRuleEditor/Editor/index.tsx

@@ -90,6 +90,7 @@ interface Props {
 const Editor = (props: Props) => {
   const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor>();
   const editorDidMountHandle = (editor: monacoEditor.editor.IStandaloneCodeEditor) => {
+    editor.getAction('editor.action.formatDocument').run();
     editorRef.current = editor;
   };
 

+ 1 - 1
src/components/FRuleEditor/Operator/index.tsx

@@ -28,7 +28,7 @@ const Operator = () => {
         description: `### ${p.name}
         \n 数据类型: ${p.valueType?.type}
         \n 是否只读: ${p.expands?.readOnly || 'false'}
-        \n 可写数值范围: ---`,
+        \n 可写数值范围: `,
         type: 'property',
       })),
     };

+ 1 - 0
src/components/FormItems/MetadataJsonInput/index.tsx

@@ -55,6 +55,7 @@ export default (props: MetaDataJsonInputProps) => {
   };
 
   const editorDidMountHandle = (editor: any) => {
+    editor.getAction('editor.action.formatDocument').run();
     editor.onDidContentSizeChange?.(() => {
       editor.getAction('editor.action.formatDocument').run();
     });

+ 5 - 8
src/components/NoticeIcon/index.tsx

@@ -9,7 +9,6 @@ import encodeQuery from '@/utils/encodeQuery';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import useHistory from '@/hooks/route/useHistory';
 import { throttleTime } from 'rxjs/operators';
-import Icon from '@ant-design/icons';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 
 export type GlobalHeaderRightProps = {
@@ -100,14 +99,14 @@ const NoticeIconView = () => {
       ?.pipe(throttleTime(2000))
       .subscribe((resp: any) => {
         getUnread();
-        notification.open({
+        notification.warning({
           message: resp?.payload?.topicName,
           description: resp?.payload?.message,
           key: resp.payload.id,
-          top: 60,
           btn: (
             <Button
               type="primary"
+              size="small"
               onClick={() => {
                 service.changeNoticeReadState(resp.payload.id).then((response) => {
                   if (response.status === 200) {
@@ -120,7 +119,6 @@ const NoticeIconView = () => {
               标记已读
             </Button>
           ),
-          icon: <Icon type="exclamation-circle" style={{ color: '#E23D38' }} />,
         });
       });
   };
@@ -136,11 +134,10 @@ const NoticeIconView = () => {
   const changeReadState = async (item: any) => {
     const resp = await service.changeNoticeReadState(item.id);
     if (resp.status === 200) {
-      getUnread();
+      const url = getMenuPathByCode(MENUS_CODE['account/NotificationRecord']);
+      history.push(url, { ...item });
+      setVisible(false);
     }
-    const url = getMenuPathByCode(MENUS_CODE['account/NotificationRecord']);
-    history.push(url, { ...item });
-    setVisible(false);
   };
 
   const clearReadState = async (title: string) => {

+ 2 - 2
src/components/ProTableCard/CardItems/aliyun.tsx

@@ -36,11 +36,11 @@ export default (props: AliyunCardProps) => {
           <div className={'card-item-content'}>
             <div>
               <label>网桥产品</label>
-              <div className={'ellipsis'}>{props?.bridgeProductName || '--'}</div>
+              <div className={'ellipsis'}>{props?.bridgeProductName || ''}</div>
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>{props?.description || '--'}</div>
+              <div className={'ellipsis'}>{props?.description || ''}</div>
             </div>
           </div>
         </div>

+ 2 - 2
src/components/ProTableCard/CardItems/device.tsx

@@ -148,11 +148,11 @@ export default (props: DeviceCardProps) => {
           <div className={'card-item-content'}>
             <div>
               <label>设备类型</label>
-              <div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : '--'}</div>
+              <div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : ''}</div>
             </div>
             <div>
               <label>产品名称</label>
-              <div className={'ellipsis'}>{props.productName || '--'}</div>
+              <div className={'ellipsis'}>{props.productName || ''}</div>
             </div>
           </div>
         </div>

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

@@ -38,19 +38,19 @@ export default (props: ProductCardProps) => {
           <div className={'card-item-content'}>
             <div>
               <label>厂商</label>
-              <div className={'ellipsis'}>{props.manufacturer || '--'}</div>
+              <div className={'ellipsis'}>{props.manufacturer || ''}</div>
             </div>
             <div>
               <label>通道数量</label>
-              <div className={'ellipsis'}>{props.channelNumber || '--'}</div>
+              <div className={'ellipsis'}>{props.channelNumber || ''}</div>
             </div>
             <div>
               <label>型号</label>
-              <div className={'ellipsis'}>{props.model || '--'}</div>
+              <div className={'ellipsis'}>{props.model || ''}</div>
             </div>
             <div>
               <label>接入方式</label>
-              <div className={'ellipsis'}>{props.provider || '--'}</div>
+              <div className={'ellipsis'}>{props.provider || ''}</div>
             </div>
           </div>
         </div>

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

@@ -49,7 +49,7 @@ export const typeList = {
     aliyunSms: '阿里云短信',
   },
   email: {
-    embedded: '默认',
+    embedded: '邮件',
   },
   webhook: {
     http: 'webhook',

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

@@ -48,7 +48,7 @@ export default (props: DeviceCardProps) => {
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>{props.description || '--'}</div>
+              <div className={'ellipsis'}>{props.description || ''}</div>
             </div>
           </div>
         </div>

+ 32 - 7
src/components/SearchComponent/index.tsx

@@ -399,7 +399,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
 
   const handleForm = (_expand?: boolean) => {
     const value = form.values;
-    const __expand = _expand || expand;
+    const __expand = _expand !== undefined ? _expand : expand;
     // 第一组条件值
     const _terms1 = _.cloneDeep(value.terms1?.[0]);
     const uiParam = uiParamRef.current;
@@ -416,11 +416,12 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
         uiParam?.[1]?.terms?.[2] || defaultTerms(5),
       ];
     } else {
-      value.terms1 = _terms1 ? [_terms1] : [defaultTerms(0)];
+      value.terms1 = [uiParam?.[0]?.terms?.[0] || _terms1 || defaultTerms(0)];
       value.terms2 = [];
     }
     setInitParams(value);
   };
+
   const handleExpand = () => {
     handleForm();
     setExpand(!expand);
@@ -451,7 +452,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
     setLogVisible(false);
     uiParamRef.current = ui2Server(log);
     const _expand =
-      (log.terms1 && log.terms1?.length > 1) || (log.terms2 && log.terms2?.length > 1);
+      !!(log.terms1 && log.terms1.length > 1) || !!(log.terms2 && log.terms2.length > 1);
     if (_expand) {
       setExpand(false);
     }
@@ -532,6 +533,17 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
     _terms.terms1 = filterTerms(_terms.terms1);
     _terms.terms2 = filterTerms(_terms.terms2);
     const _temp = formatValue(_terms);
+
+    if (
+      (_terms.terms1 && _terms.terms1.length > 1) ||
+      (_terms.terms2 && _terms.terms2.length > 1)
+    ) {
+      // 展开高级搜索
+      uiParamRef.current = ui2Server(value);
+      setExpand(false);
+      handleForm(true);
+    }
+
     if (type) {
       setUrl({ q: JSON.stringify(value) });
     }
@@ -566,7 +578,8 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
     setAliasVisible(!aliasVisible);
   };
 
-  const resetForm = async () => {
+  const resetForm = async (type: boolean) => {
+    console.log('resetForm', type);
     const value = form.values;
     if (!expand) {
       value.terms1 = [defaultTerms(0), defaultTerms(1), defaultTerms(2)];
@@ -576,7 +589,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
       value.terms2 = [];
     }
     setInitParams(value);
-    await handleSearch();
+    await handleSearch(type);
   };
 
   const SearchBtn = {
@@ -584,7 +597,13 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
       <>
         {
           // @ts-ignore
-          <Button icon={<SearchOutlined />} onClick={handleSearch} type="primary">
+          <Button
+            icon={<SearchOutlined />}
+            onClick={() => {
+              handleSearch(false);
+            }}
+            type="primary"
+          >
             搜索
           </Button>
         }
@@ -665,7 +684,13 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
             <Space>
               {enableSave ? SearchBtn.advance : SearchBtn.simple}
               {enableSave && SaveBtn}
-              <Button icon={<ReloadOutlined />} block onClick={resetForm}>
+              <Button
+                icon={<ReloadOutlined />}
+                block
+                onClick={() => {
+                  resetForm(model !== 'simple');
+                }}
+              >
                 重置
               </Button>
             </Space>

+ 3 - 3
src/hooks/route/useHistory.tsx

@@ -1,6 +1,6 @@
 import { useHistory } from 'umi';
 import { useEffect, useState } from 'react';
-import type { LocationDescriptor, LocationState, Path } from 'history';
+import type { LocationState, Path } from 'history';
 import { model } from '@formily/reactive';
 
 export const historyStateModel = model<{ state: any }>({ state: {} });
@@ -10,9 +10,9 @@ const useHistories = () => {
 
   const [history, setHistory] = useState<any>();
 
-  const push = (location: Path | LocationDescriptor<LocationState>, state?: LocationState) => {
+  const push = (location: Path, state?: LocationState) => {
     if (state) {
-      historyStateModel.state = state;
+      historyStateModel.state[location] = state;
     }
     umiHistory.push(location, state);
   };

+ 2 - 2
src/hooks/route/useLocation.tsx

@@ -8,11 +8,11 @@ const useLocations = () => {
   useEffect(() => {
     setLocation({
       ...umiLocation,
-      state: historyStateModel.state,
+      state: historyStateModel.state[umiLocation.pathname],
     });
 
     return () => {
-      historyStateModel.state = undefined;
+      delete historyStateModel.state[umiLocation.pathname];
     };
   }, [umiLocation]);
 

+ 1 - 1
src/pages/Log/System/index.tsx

@@ -71,7 +71,7 @@ const System = () => {
       dataIndex: 'context.server',
       width: 150,
       ellipsis: true,
-      render: (text, record) => record?.context?.server || '--',
+      render: (text, record) => record?.context?.server || '',
     },
     {
       title: intl.formatMessage({

+ 3 - 3
src/pages/Northbound/DuerOS/Detail/Doc.tsx

@@ -25,7 +25,7 @@ const Doc = () => {
       </div>
       <h1>2. 操作步骤</h1>
       <div>
-        <h2>1、在百度小度技能平台创建技能,并授权。完成物联网平台与dueros的关联。</h2>
+        <h2>1、在百度小度技能平台创建技能,并授权。完成物联网平台与DuerOS的关联。</h2>
         <div className={'image'}>
           <Image width="100%" src={image} />
         </div>
@@ -59,7 +59,7 @@ const Doc = () => {
         <div></div>
         <h1>WebService</h1>
         <div>请复制并填写:/dueros/product/_query</div>
-        <h2>2、登录物联网平台,进行平台内产品与dueros产品的数据映射。</h2>
+        <h2>2、登录物联网平台,进行平台内产品与DuerOS产品的数据映射。</h2>
         <h2>
           3、智能家居用户通过物联网平台中的用户,登录小度APP,获取平台内当前用户的所属设备。获取后即可进行语音控制。
         </h2>
@@ -67,7 +67,7 @@ const Doc = () => {
       <h1>3. 配置说明</h1>
       <div>
         <h2>
-          1、“设备类型”为dueros平台拟定的标准规范,设备类型将决定【动作映射】中“动作”的下拉选项,以及【属性映射】中“Dueros属性”的下拉选项
+          1、“设备类型”为DuerOS平台拟定的标准规范,设备类型将决定【动作映射】中“动作”的下拉选项,以及【属性映射】中“Dueros属性”的下拉选项
         </h2>
       </div>
     </div>

+ 16 - 5
src/pages/Northbound/DuerOS/Detail/index.tsx

@@ -136,6 +136,13 @@ const Save = () => {
               });
             },
           );
+          onFieldValueChange('id', (field, form1) => {
+            form1.setFieldState(field.query('productName'), (state) => {
+              if (field && field.inputValues && field && field.inputValues[1]) {
+                state.value = field.inputValues[1].label;
+              }
+            });
+          });
           onFieldReact('propertyMappings.*.layout.source', (field, f) => {
             const productType = field.query('applianceType').value();
             const propertiesList = findApplianceType(productType)?.properties;
@@ -292,6 +299,13 @@ const Save = () => {
             'x-reactions': '{{useAsyncDataSource(getTypes)}}',
             required: true,
           },
+          productName: {
+            title: '产品名称',
+            type: 'string',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            'x-hidden': true,
+          },
         },
       },
       actionMappings: {
@@ -639,14 +653,11 @@ const Save = () => {
 
   const handleSave = async () => {
     const data: any = await form.submit();
-    const productName = Store.get('product-list')?.find((item: any) => item.id === data.id)?.name;
-    const resp: any = await service.savePatch({ ...data, productName });
+    const resp: any = await service.savePatch(data);
     if (resp.status === 200) {
       onlyMessage('保存成功!');
-    } else {
-      onlyMessage('保存失败!', 'error');
+      history.back();
     }
-    history.back();
   };
   return (
     <PageContainer>

+ 5 - 5
src/pages/account/NotificationRecord/detail/index.tsx

@@ -34,15 +34,15 @@ const Detail = (props: Props) => {
         {data?.targetType === 'device' && (
           <>
             <Descriptions.Item label="告警设备" span={1}>
-              {data?.targetName || '--'}
+              {data?.targetName || ''}
             </Descriptions.Item>
             <Descriptions.Item label="设备ID" span={1}>
-              {data?.targetId || '--'}
+              {data?.targetId || ''}
             </Descriptions.Item>
           </>
         )}
         <Descriptions.Item label="告警名称" span={1}>
-          {data?.alarmName || '--'}
+          {data?.alarmName || ''}
         </Descriptions.Item>
         <Descriptions.Item label="告警时间" span={1}>
           {moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')}
@@ -52,10 +52,10 @@ const Detail = (props: Props) => {
             ?.title || data?.level}
         </Descriptions.Item>
         <Descriptions.Item label="告警说明" span={1}>
-          {data?.description || '--'}
+          {data?.description || ''}
         </Descriptions.Item>
         <Descriptions.Item label="告警流水" span={2}>
-          {data?.alarmInfo || '--'}
+          {data?.alarmInfo || ''}
         </Descriptions.Item>
       </Descriptions>
     </Modal>

+ 7 - 4
src/pages/account/NotificationRecord/index.tsx

@@ -13,7 +13,7 @@ import encodeQuery from '@/utils/encodeQuery';
 import { useDomFullHeight } from '@/hooks';
 import { onlyMessage } from '@/utils/util';
 import type { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
-import { historyStateModel } from '@/hooks/route/useHistory';
+import useLocations from '@/hooks/route/useLocation';
 import { observer } from '@formily/reactive-react';
 
 export const service = new Service('notifications');
@@ -27,6 +27,8 @@ const NotificationRecord = observer(() => {
   const [typeList, setTypeList] = useState<any>({});
   const { minHeight } = useDomFullHeight(`.record`, 24);
 
+  const location = useLocations();
+
   useEffect(() => {
     service.getProvidersList().then((resp) => {
       const obj: any = {};
@@ -38,11 +40,12 @@ const NotificationRecord = observer(() => {
   }, []);
 
   useEffect(() => {
-    if (historyStateModel.state.id) {
+    console.log(location.state);
+    if (location.state?.id) {
       setVisible(true);
-      setCurrent(historyStateModel.state);
+      setCurrent(location.state);
     }
-  }, [historyStateModel.state]);
+  }, [location.state]);
 
   const ReadSvg = () => (
     <svg

+ 1 - 0
src/pages/device/Command/cat/index.tsx

@@ -24,6 +24,7 @@ const Cat = (props: Props) => {
         height={300}
         language={'json'}
         editorDidMount={(editor) => {
+          editor.getAction('editor.action.formatDocument').run();
           editor.onDidContentSizeChange?.(() => {
             editor.getAction('editor.action.formatDocument').run();
             // .finally(() => {

+ 5 - 5
src/pages/device/Instance/Detail/Config/index.tsx

@@ -64,7 +64,7 @@ const Config = () => {
       if (isExit(item.property)) {
         return (
           <div>
-            <span style={{ marginRight: '10px' }}>{config[item.property] || '--'}</span>
+            <span style={{ marginRight: '10px' }}>{config[item.property] || ''}</span>
             <Tooltip title={`有效值:${config[item.property]}`}>
               <QuestionCircleOutlined />
             </Tooltip>
@@ -73,16 +73,16 @@ const Config = () => {
       } else {
         return (
           <div>
-            <Tooltip title={config[item.property] || '--'} placement="topLeft">
-              <div className="ellipsis" style={{ maxWidth: 300 }}>
-                {config[item.property] || '--'}
+            <Tooltip title={config[item.property] || ''} placement="topLeft">
+              <div className="ellipsis" style={{ width: 300 }}>
+                {config[item.property] || ''}
               </div>
             </Tooltip>
           </div>
         );
       }
     } else {
-      return '--';
+      return '';
     }
   };
 

+ 1 - 0
src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx

@@ -80,6 +80,7 @@ export default (props: FunctionProps) => {
 
   const editorDidMountHandle = (editor: any) => {
     monacoRef.current = editor;
+    editor.getAction('editor.action.formatDocument').run();
     editor.onDidContentSizeChange?.(() => {
       editor.getAction('editor.action.formatDocument').run();
     });

+ 1 - 1
src/pages/device/Instance/Detail/Info/index.tsx

@@ -118,7 +118,7 @@ const Info = observer(() => {
           >
             {InstanceModel.detail?.onlineTime
               ? moment(InstanceModel.detail?.onlineTime).format('YYYY-MM-DD HH:mm:ss')
-              : '--'}
+              : ''}
           </Descriptions.Item>
           <Descriptions.Item
             label={intl.formatMessage({

+ 2 - 2
src/pages/device/Instance/Detail/Reation/index.tsx

@@ -58,11 +58,11 @@ const Reation = () => {
         {(data || [])?.map((item: any) => (
           <Descriptions.Item span={1} label={item.relationName} key={item.objectId}>
             <Tooltip
-              title={item?.related ? _.map(item?.related || [], 'name').join(',') : '--'}
+              title={item?.related ? _.map(item?.related || [], 'name').join(',') : ''}
               placement="topLeft"
             >
               <div className="ellipsis" style={{ width: 300 }}>
-                {item?.related ? _.map(item?.related || [], 'name').join(',') : '--'}
+                {item?.related ? _.map(item?.related || [], 'name').join(',') : ''}
               </div>
             </Tooltip>
           </Descriptions.Item>

+ 3 - 1
src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx

@@ -33,7 +33,9 @@ const FileComponent = (props: Props) => {
 
   const renderValue = () => {
     if (value?.formatValue !== 0 && !value?.formatValue) {
-      return <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>--</div>;
+      return (
+        <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>{''}</div>
+      );
     } else if (data?.valueType?.type === 'file') {
       if (
         data?.valueType?.fileType === 'base64' ||

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx

@@ -107,7 +107,7 @@ const Property = (props: Props) => {
           <div style={{ marginTop: 10 }}>
             <div style={{ color: 'rgba(0, 0, 0, .65)', fontSize: 12 }}>更新时间</div>
             <div style={{ marginTop: 5, fontSize: 16, color: 'black' }} className="value">
-              {value?.timestamp ? moment(value?.timestamp).format('YYYY-MM-DD HH:mm:ss') : '--'}
+              {value?.timestamp ? moment(value?.timestamp).format('YYYY-MM-DD HH:mm:ss') : ''}
             </div>
           </div>
         </div>

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/index.tsx

@@ -288,7 +288,7 @@ const Property = (props: Props) => {
               <Row gutter={[16, 16]} style={{ minHeight: 450 }}>
                 {dataSource.data.map((item: any) => (
                   <Col {...ColResponsiveProps} key={item.id}>
-                    <PropertyCard data={item} value={item?.id ? propertyValue[item?.id] : '--'} />
+                    <PropertyCard data={item} value={item?.id ? propertyValue[item?.id] : ''} />
                   </Col>
                 ))}
               </Row>

+ 3 - 3
src/pages/device/Instance/Detail/Tags/index.tsx

@@ -45,9 +45,9 @@ const Tags = () => {
       >
         {(tags || [])?.map((item: any) => (
           <Descriptions.Item span={1} label={`${item.name}(${item.key})`} key={item.key}>
-            <Tooltip title={item.value || '--'} placement="topLeft">
-              <div className="ellipsis" style={{ maxWidth: 300 }}>
-                {item.value || '--'}
+            <Tooltip title={item.value || ''} placement="topLeft">
+              <div className="ellipsis" style={{ width: 300 }}>
+                {item.value || ''}
               </div>
             </Tooltip>
           </Descriptions.Item>

+ 1 - 1
src/pages/device/Instance/index.tsx

@@ -659,7 +659,7 @@ const Instance = () => {
                   onConfirm: async () => {
                     if (record.state.value === 'notActive') {
                       const resp: any = await service.remove(record.id);
-                      if (resp.code === 200) {
+                      if (resp.status === 200) {
                         onlyMessage(
                           intl.formatMessage({
                             id: 'pages.data.option.success',

+ 1 - 0
src/pages/device/Instance/typings.d.ts

@@ -41,6 +41,7 @@ export type DeviceInstance = {
   photoUrl: string;
   independentMetadata?: boolean;
   accessProvider?: string;
+  accessId?: string;
   features?: any[];
 };
 

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

@@ -335,7 +335,7 @@ const Product = observer(() => {
       // hideInSearch: true,
     },
     {
-      dataIndex: 'categoryId',
+      dataIndex: 'classifiedId',
       title: '分类',
       valueType: 'treeSelect',
       hideInTable: true,

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

@@ -98,6 +98,7 @@ const Cat = observer((props: Props) => {
                 language="json"
                 value={value}
                 editorDidMount={(editor) => {
+                  editor.getAction('editor.action.formatDocument').run();
                   editor.onDidScrollChange?.(() => {
                     editor.getAction('editor.action.formatDocument').run();
                   });

+ 1 - 1
src/pages/home/index.tsx

@@ -9,7 +9,7 @@ import Service from './service';
 export const service = new Service();
 const Home = () => {
   type ViewType = keyof typeof ViewMap;
-  const [current, setCurrent] = useState<ViewType>('comprehensive');
+  const [current, setCurrent] = useState<ViewType>('init'); // 默认为初始化
 
   const ViewMap = {
     init: <Init changeView={(value: ViewType) => setCurrent(value)} />,

+ 3 - 3
src/pages/link/AccessConfig/Detail/Channel/index.tsx

@@ -109,11 +109,11 @@ const Media = (props: Props) => {
             <div style={{ marginLeft: 10 }}>
               <TitleComponent data={'配置概览'} />
               <div>
-                <p>接入方式:{props.provider?.name || '--'}</p>
-                {props.provider?.description && <p>{props.provider?.description || '--'}</p>}
+                <p>接入方式:{props.provider?.name || ''}</p>
+                {props.provider?.description && <p>{props.provider?.description || ''}</p>}
                 <p>消息协议:{procotol}</p>
                 {config?.document && (
-                  <div>{<ReactMarkdown>{config?.document}</ReactMarkdown> || '--'}</div>
+                  <div>{<ReactMarkdown>{config?.document}</ReactMarkdown> || ''}</div>
                 )}
               </div>
               <TitleComponent data={'设备接入指引'} />

+ 3 - 3
src/pages/link/AccessConfig/Detail/Cloud/Finish/index.tsx

@@ -101,11 +101,11 @@ const Finish = (props: Props) => {
         <div style={{ marginLeft: 10 }}>
           <TitleComponent data={'配置概览'} />
           <div>
-            <p>接入方式:{props.provider?.name || '--'}</p>
-            {props.provider?.description && <p>{props.provider?.description || '--'}</p>}
+            <p>接入方式:{props.provider?.name || ''}</p>
+            {props.provider?.description && <p>{props.provider?.description || ''}</p>}
             <p>消息协议:{props.procotol}</p>
             {config?.document && (
-              <div>{<ReactMarkdown>{config?.document}</ReactMarkdown> || '--'}</div>
+              <div>{<ReactMarkdown>{config?.document}</ReactMarkdown> || ''}</div>
             )}
           </div>
           <TitleComponent data={'设备接入指引'} />

+ 2 - 2
src/pages/link/AccessConfig/Detail/Cloud/Protocol/index.tsx

@@ -99,8 +99,8 @@ const Protocol = (props: Props) => {
                 }}
               >
                 <div style={{ height: '45px' }}>
-                  <div className={styles.title}>{item.name || '--'}</div>
-                  <div className={styles.desc}>{item.description || '--'}</div>
+                  <div className={styles.title}>{item.name || ''}</div>
+                  <div className={styles.desc}>{item.description || ''}</div>
                 </div>
               </Card>
             </Col>

+ 13 - 6
src/pages/link/DashBoard/index.tsx

@@ -151,6 +151,11 @@ export default () => {
   const [cpuOptions, setCpuOptions] = useState<EChartsOption | undefined>(undefined);
   const [jvmOptions, setJvmOptions] = useState<EChartsOption | undefined>(undefined);
   const [serverId, setServerId] = useState(undefined);
+  const [timeToolOptions] = useState([
+    { label: '最近1小时', value: 'hour' },
+    { label: '当天', value: 'today' },
+    { label: '近一周', value: 'week' },
+  ]);
 
   const [topValues, setTopValues] = useState({
     cpu: 0,
@@ -185,6 +190,8 @@ export default () => {
         return 'MM-DD';
       case 'week':
         return 'MM-DD HH';
+      case 'hour':
+        return 'HH:mm';
       default:
         return 'HH';
     }
@@ -389,7 +396,6 @@ export default () => {
           params: {
             from: cpuData.time.start,
             to: cpuData.time.end,
-            interval: getInterval(cpuData.time.type),
           },
         },
         {
@@ -401,7 +407,6 @@ export default () => {
           params: {
             from: jvmData.time.start,
             to: jvmData.time.end,
-            interval: getInterval(jvmData.time.type),
           },
         },
       ])
@@ -438,13 +443,13 @@ export default () => {
                 if (!_jvmOptions[nodeID]) {
                   _jvmOptions[nodeID] = [];
                 }
-                _jvmXAxis.add(moment(value.timestamp).format(getTimeFormat('week')));
+                _jvmXAxis.add(moment(value.timestamp).format(getTimeFormat(jvmData.time.type)));
                 _jvmOptions[nodeID].push(_value);
               } else {
                 if (!_cpuOptions[nodeID]) {
                   _cpuOptions[nodeID] = [];
                 }
-                _cpuXAxis.add(moment(value.timestamp).format(getTimeFormat('week')));
+                _cpuXAxis.add(moment(value.timestamp).format(getTimeFormat(cpuData.time.type)));
                 _cpuOptions[nodeID].push(Number(value.cpuSystemUsage).toFixed(2));
               }
             });
@@ -729,8 +734,9 @@ export default () => {
             closeInitialParams={true}
             ref={CPURef}
             height={400}
-            defaultTime={'week'}
+            defaultTime={'hour'}
             options={cpuOptions}
+            timeToolOptions={timeToolOptions}
             onParamsChange={getCPUEcharts}
           />
           <DashBoard
@@ -738,8 +744,9 @@ export default () => {
             closeInitialParams={true}
             ref={JVMRef}
             height={400}
-            defaultTime={'week'}
+            defaultTime={'hour'}
             options={jvmOptions}
+            timeToolOptions={timeToolOptions}
             onParamsChange={getJVMEcharts}
           />
         </div>

+ 3 - 0
src/pages/link/Protocol/FileUpload/index.tsx

@@ -51,6 +51,9 @@ const FileUpload = connect((props: Props) => {
               e.stopPropagation();
             }}
             placeholder="请上传文件"
+            onBlur={(e) => {
+              props.onChange(e.target.value);
+            }}
           />
           <Button
             disabled={props?.disabled}

+ 4 - 12
src/pages/link/Protocol/save/index.tsx

@@ -242,19 +242,11 @@ const Save = (props: Props) => {
     },
   };
 
-  const save = async (deploy: boolean) => {
+  const save = async () => {
     const value = await form.submit<ProtocolItem>();
-    let response = undefined;
-    if (!props.data?.id) {
-      response = await service.save(value);
-    } else {
-      response = await service.update(value);
-    }
-    if (response && response.status === 200) {
+    const response: any = await service.savePatch({ ...props.data, ...value });
+    if (response && response?.status === 200) {
       onlyMessage('操作成功');
-      if (deploy) {
-        await service.modifyState(value.id, 'deploy');
-      }
       props.reload();
       if ((window as any).onTabSaveSuccess) {
         (window as any).onTabSaveSuccess(response);
@@ -278,7 +270,7 @@ const Save = (props: Props) => {
           type="primary"
           key={2}
           onClick={() => {
-            save(false);
+            save();
           }}
           disabled={props.data?.id ? !permission.update : !permission.add}
         >

+ 1 - 1
src/pages/media/Device/Channel/Live/index.tsx

@@ -30,7 +30,7 @@ const LiveFC = (props: LiveProps) => {
     if (props.channelId && props.deviceId) {
       //   查询当前视频是否在录像
       service.ptzIsRecord(props.deviceId, props.channelId).then((res) => {
-        if (res.code === 200) {
+        if (res.status === 200) {
           setIsRecord(res.result ? 2 : 0);
         }
       });

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

@@ -110,7 +110,6 @@ const Save = (props: SaveModalProps) => {
             ],
             'x-decorator-props': {
               gridSpan: 1,
-              tooltip: '不同厂家的RTSP固定地址规则不同,请按对应厂家的规则填写',
             },
           },
           manufacturer: {
@@ -166,6 +165,7 @@ const Save = (props: SaveModalProps) => {
             ],
             'x-decorator-props': {
               gridSpan: 2,
+              tooltip: '不同厂家的RTSP固定地址规则不同,请按对应厂家的规则填写',
             },
           },
           username: {

+ 5 - 5
src/pages/media/Device/Save/ProviderSelect.tsx

@@ -113,12 +113,12 @@ export default (props: ProviderProps) => {
                 </div>
                 <div className={styles.card}>
                   <div className={styles.header}>
-                    <div className={styles.title}>{item.name || '--'}</div>
-                    <div className={styles.desc}>{item.description || '--'}</div>
+                    <div className={styles.title}>{item.name || ''}</div>
+                    <div className={styles.desc}>{item.description || ''}</div>
                   </div>
                   <div className={styles.container}>
                     <div className={styles.server}>
-                      <div className={styles.subTitle}>{item?.channelInfo?.name || '--'}</div>
+                      <div className={styles.subTitle}>{item?.channelInfo?.name || ''}</div>
                       <div style={{ width: '100%' }}>
                         {item.channelInfo?.addresses.map((i: any, index: number) => (
                           <p key={i.address + `_address${index}`}>
@@ -128,8 +128,8 @@ export default (props: ProviderProps) => {
                       </div>
                     </div>
                     <div className={styles.procotol}>
-                      <div className={styles.subTitle}>{item?.protocolDetail?.name || '--'}</div>
-                      <p>{item.protocolDetail?.description || '--'}</p>
+                      <div className={styles.subTitle}>{item?.protocolDetail?.name || ''}</div>
+                      <p>{item.protocolDetail?.description || ''}</p>
                     </div>
                   </div>
                 </div>

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

@@ -277,7 +277,7 @@ const Save = () => {
                             buttonStyle="solid"
                             options={[
                               { label: 'UDP', value: 'UDP' },
-                              { label: 'TCP', value: 'TCP_PASSIVE' },
+                              { label: 'TCP被动', value: 'TCP_PASSIVE' },
                             ]}
                           />
                         </Form.Item>
@@ -342,13 +342,13 @@ const Save = () => {
               </Form>
             </Col>
             <Col span={12}>
-              {accessType === 'gb28181-2016' ? (
+              {accessType === DefaultAccessType ? (
                 <div className={styles.doc} style={{ height: 800 }}>
-                  <h1>1概述</h1>
+                  <h1>1.概述</h1>
                   <div>
                     视频设备通过GB/T28181接入平台整体分为2部分,包括平台端配置和设备端配置,不同的设备端配置的路径或页面存在差异,但配置项基本大同小异。
                   </div>
-                  <h1>2配置说明</h1>
+                  <h1>2.配置说明</h1>
                   <h1>平台端配置</h1>
                   <h2>1、ID</h2>
                   <div>设备唯一标识,若不填写,系统将自动生成唯一标识</div>
@@ -393,16 +393,16 @@ const Save = () => {
                   <div>不影响设备接入平台,可保持设备初始化值。</div>
                 </div>
               ) : (
-                <div className={styles.doc}>
-                  <h1>1概述</h1>
+                <div className={styles.doc} style={{ height: 600 }}>
+                  <h1>1.概述</h1>
                   <div>视频设备通过RTSP、RTMP固定地址接入平台分为2步。</div>
                   <div>1.添加视频设备</div>
                   <div>2.添加视频下的通道地址。</div>
                   <div>注:当前页面为新增视频设备,新增完成后点击设备的“通道”按钮,添加通道。</div>
                   <h1>2.配置说明</h1>
-                  <h2>1. ID</h2>
+                  <h2>1ID</h2>
                   <div>设备唯一标识,若不填写,系统将自动生成唯一标识。</div>
-                  <h2>2. 所属产品</h2>
+                  <h2>2所属产品</h2>
                   <div>
                     只能选择接入方式为固定地址的产品,若当前无对应产品,可点击右侧快速添加按钮,填写产品名称和选择固定地址类型的网关完成产品创建。
                   </div>

+ 11 - 12
src/pages/media/Device/index.tsx

@@ -277,7 +277,7 @@ const Device = () => {
         <PermissionButton
           key={'delete'}
           tooltip={{
-            title: '删除',
+            title: record.state.value === 'online' ? '在线设备无法删除' : '删除',
           }}
           popConfirm={{
             title: (
@@ -292,7 +292,7 @@ const Device = () => {
               </div>
             ),
             onConfirm: async () => {
-              if (record.state.value === 'offline') {
+              if (record.state.value !== 'online') {
                 await deleteItem(record.id);
               } else {
                 onlyMessage('在线设备不能进行删除操作', 'error');
@@ -302,7 +302,7 @@ const Device = () => {
           type={'link'}
           style={{ padding: 0 }}
           isPermission={permission.delete}
-          disabled={record.state.value !== 'offline'}
+          disabled={record.state.value === 'online'}
         >
           <DeleteOutlined />
         </PermissionButton>,
@@ -398,9 +398,7 @@ const Device = () => {
                 key={'updateChannel'}
                 isPermission={permission.update}
                 tooltip={
-                  record.state.value === 'offline' ||
-                  record.state.value === 'notActive' ||
-                  record.provider === providerType['fixed-media']
+                  record.state.value !== 'online' || record.provider === providerType['fixed-media']
                     ? {
                         title:
                           record.provider === providerType['fixed-media']
@@ -414,9 +412,7 @@ const Device = () => {
                     : undefined
                 }
                 disabled={
-                  record.state.value === 'offline' ||
-                  record.state.value === 'notActive' ||
-                  record.provider === providerType['fixed-media']
+                  record.state.value !== 'online' || record.provider === providerType['fixed-media']
                 }
                 onClick={() => {
                   updateChannel(record.id);
@@ -430,23 +426,26 @@ const Device = () => {
                 popConfirm={{
                   title: intl.formatMessage({
                     id:
-                      record.state.value === 'online'
+                      record.state.value !== 'online'
                         ? 'page.table.isDelete'
                         : 'pages.device.instance.deleteTip',
                     defaultMessage: '是否删除?',
                   }),
                   onConfirm: async () => {
-                    if (record.state.value === 'offline' || record.state.value === 'notActive') {
+                    if (record.state.value !== 'online') {
                       await deleteItem(record.id);
                     } else {
                       onlyMessage('在线设备不能进行删除操作', 'error');
                     }
                   },
                 }}
+                tooltip={
+                  record.state.value === 'online' ? { title: '在线设备无法删除' } : undefined
+                }
                 type={'link'}
                 style={{ padding: 0 }}
                 isPermission={permission.delete}
-                disabled={record.state.value !== 'offline'}
+                disabled={record.state.value === 'online'}
               >
                 <DeleteOutlined />
               </PermissionButton>,

+ 3 - 3
src/pages/notice/Config/Detail/doc/AliyunSms.tsx

@@ -11,19 +11,19 @@ const AliyunSms = () => {
           https://home.console.aliyun.com
         </a>
       </div>
-      <h1>1. 概述</h1>
+      <h1>1.概述</h1>
       <div>
         通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2>1. RegionID</h2>
+        <h2>1RegionID</h2>
         <div>阿里云内部给每台机器设置的唯一编号。请根据购买的阿里云服务器地址进行填写。</div>
         <div>
           阿里云地域和可用区对照表地址:https://help.aliyun.com/document_detail/40654.html?spm=a2c6h.13066369.0.0.54a174710O7rWH
         </div>
       </div>
-      <h2>2. AccesskeyID/Secret</h2>
+      <h2>2AccesskeyID/Secret</h2>
       <div>
         <div>用于程序通知方式调用云服务费API的用户标识和秘钥</div>
         <div>获取路径:“阿里云管理控制台”--“用户头像”--“”--“AccessKey管理”--“查看”</div>

+ 1 - 1
src/pages/notice/Config/Detail/doc/AliyunVoice.tsx

@@ -18,7 +18,7 @@ const AliyunVoice = () => {
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2>1. RegionID</h2>
+        <h2>1RegionID</h2>
         <div>
           阿里云内部给每台机器设置的唯一编号。请根据购买的阿里云服务器阿里云地域和可用区对照表地址:https://help.aliyun.com/document_detail/40654.html?spm=a2c6h.13066369.0.0.54a174710O7rWH获取路径:“微信公众平台”管理后台--“设置与开发”--“基本配置”
         </div>

+ 2 - 2
src/pages/notice/Config/Detail/doc/DingTalk.tsx

@@ -18,7 +18,7 @@ const DingTalk = () => {
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2>1. AppKey</h2>
+        <h2>1AppKey</h2>
         <div>
           企业内部应用的唯一身份标识。在钉钉开发者后台创建企业内部应用后,系统会自动生成一对AppKey和AppSecret。
         </div>
@@ -27,7 +27,7 @@ const DingTalk = () => {
           <Image width="100%" src={appKey} />
         </div>
       </div>
-      <h2>2. AppSecret</h2>
+      <h2>2AppSecret</h2>
       <div>
         <div>钉钉应用对应的调用密钥</div>
         <div>获取路径:“钉钉开放平台”--“应用开发”--“应用信息”</div>

+ 1 - 1
src/pages/notice/Config/Detail/doc/DingTalkRebot.tsx

@@ -15,7 +15,7 @@ const DingTalkRebot = () => {
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2> 1. WebHook</h2>
+        <h2> 1WebHook</h2>
         <div>在钉钉群内每创建一个钉钉群自定义机器人都会产生唯一的WebHook地址。</div>
         <div>获取路径:“钉钉桌面客户端”--“群设置”--“智能群助手”--“机器人信息”</div>
         <div className={'image'}>

+ 4 - 4
src/pages/notice/Config/Detail/doc/Email.tsx

@@ -8,16 +8,16 @@ const Email = () => {
         通知配置可以结合通知配置为告警消息通知提供支撑。也可以用于系统中其他自定义模块的调用。
       </div>
       <h1>2.通知配置说明</h1>
-      <h2>1. 服务器地址</h2>
+      <h2>1 服务器地址</h2>
       <div>下拉可选择国内常用的邮箱服务配置,也支持手动输入其他地址。</div>
       <div>
         系统POP协议。POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的操作(如:移动邮件、标记已读等),这是不会反馈到服务器上。
       </div>
-      <h2>2. 发件人</h2>
+      <h2>2发件人</h2>
       <div>用于发送邮件时“发件人“信息的显示</div>
-      <h2>3. 用户名</h2>
+      <h2>3 用户名</h2>
       <div>用该账号进行发送邮件。</div>
-      <h2>4. 密码</h2>
+      <h2>4密码</h2>
       <div>用与账号身份认证,认证通过后可通过该账号进行发送邮件。</div>
     </div>
   );

+ 2 - 2
src/pages/notice/Config/Detail/doc/Webhook.tsx

@@ -9,10 +9,10 @@ const Webhook = () => {
         POST请求),实现了Webhook的第三方系统可以基于该URL订阅本平台系统信息,本平台按配置把特定的事件结果推送到指定的地址,便于系统做后续处理。
       </div>
       <h1>2.通知配置说明</h1>
-      <h2>1. Webhook</h2>
+      <h2>1Webhook</h2>
       <div>Webhook地址。</div>
 
-      <h2>2. 请求头</h2>
+      <h2>2请求头</h2>
       <div>支持根据系统提供的接口设置不同的请求头。如 Accept-Language 、Content-Type</div>
     </div>
   );

+ 2 - 2
src/pages/notice/Config/Detail/doc/WeixinApp.tsx

@@ -19,14 +19,14 @@ const WeixinApp = () => {
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2>1. AppID</h2>
+        <h2>1AppID</h2>
         <div>微信服务号的唯一专属编号。</div>
         <div>获取路径:“微信公众平台”管理后台--“设置与开发”--“基本配置”</div>
         <div className={'image'}>
           <Image width="100%" src={appId} />
         </div>
       </div>
-      <h2>2. AppSecret</h2>
+      <h2>2AppSecret</h2>
       <div>
         <div>公众号开发者身份的密码</div>
         <div>获取路径:“微信公众平台”管理后台--“设置与开发”--“基本配置”</div>

+ 2 - 2
src/pages/notice/Config/Detail/doc/WeixinCorp.tsx

@@ -18,7 +18,7 @@ const WeixinCorp = () => {
       </div>
       <h1>2.通知配置说明</h1>
       <div>
-        <h2>1. corpId</h2>
+        <h2>1corpId</h2>
         <div>企业号的唯一专属编号。</div>
         <div>获取路径:“企业微信”管理后台--“我的企业”--“企业ID”</div>
         <div className={'image'}>
@@ -26,7 +26,7 @@ const WeixinCorp = () => {
         </div>
       </div>
 
-      <h2>2. corpSecret</h2>
+      <h2>2corpSecret</h2>
       <div>
         <div>应用的唯一secret,一个企业微信中可以有多个corpSecret</div>
         <div>获取路径:“企业微信”--“应用与小程序”--“自建应用”中获取</div>

+ 1 - 1
src/pages/notice/Config/SyncUser/index.tsx

@@ -45,7 +45,7 @@ const SyncUser = observer(() => {
       dataIndex: 'userId',
       title: `用户`,
       render: (text: any, record: any) => (
-        <span>{record?.userId ? `${record?.userName}(${record?.username})` : '--'}</span>
+        <span>{record?.userId ? `${record?.userName}(${record?.username})` : ''}</span>
       ),
     },
     {

+ 31 - 24
src/pages/notice/Template/Debug/index.tsx

@@ -74,20 +74,25 @@ const Debug = observer(() => {
               const a = variableRef.current?.find((i: any) => i.id === _id.value);
               const _configId = configId.value();
               const businessType = a?.expands?.businessType;
-              if (id === 'dingTalk' && _configId) {
-                switch (businessType) {
-                  case 'org':
-                    // 获取org
-                    const orgList = await service.dingTalk.getDepartments(_configId);
-                    format.setComponent(Select);
-                    format.setDataSource(orgList);
-                    break;
-                  case 'user':
-                    // 获取user
-                    const userList = await service.dingTalk.getUser(_configId);
-                    format.setComponent(Select);
-                    format.setDataSource(userList);
-                    break;
+              if (id === 'dingTalk' || id === 'weixin') {
+                if (_configId) {
+                  switch (businessType) {
+                    case 'org':
+                      // 获取org
+                      const orgList = await service[id].getDepartments(_configId);
+                      format.setComponent(Select);
+                      format.setDataSource(orgList);
+                      break;
+                    case 'user':
+                      // 获取user
+                      const userList = await service[id].getUser(_configId);
+                      format.setComponent(Select);
+                      format.setDataSource(userList);
+                      break;
+                  }
+                } else if (businessType === 'org' || businessType === 'user') {
+                  format.setComponent(Select);
+                  format.setDataSource([]);
                 }
               }
             }
@@ -100,16 +105,18 @@ const Debug = observer(() => {
   useEffect(() => {
     // const data = state.current;
     // 从后端接口来获取变量参数
-    service.getVariableDefinitions(state.current?.id || '').then((resp) => {
-      const _template = resp.result;
-      if (_template?.variableDefinitions?.length > 0) {
-        variableRef.current = _template?.variableDefinitions;
-        form.setFieldState('variableDefinitions', (state1) => {
-          state1.visible = true;
-          state1.value = _template?.variableDefinitions;
-        });
-      }
-    });
+    if (state.current?.id) {
+      service.getVariableDefinitions(state.current?.id || '').then((resp) => {
+        const _template = resp.result;
+        if (_template?.variableDefinitions?.length > 0) {
+          variableRef.current = _template?.variableDefinitions;
+          form.setFieldState('variableDefinitions', (state1) => {
+            state1.visible = true;
+            state1.value = _template?.variableDefinitions;
+          });
+        }
+      });
+    }
   }, [state.current, state.debug]);
 
   const SchemaField = createSchemaField({

+ 3 - 3
src/pages/notice/Template/Detail/doc/DingTalk.tsx

@@ -26,13 +26,13 @@ const DingTalk = () => {
       <h1> 2.模板配置说明</h1>
       <h2> 1、绑定配置</h2>
       <div> 使用固定的通知配置发送此通知模板</div>
-      <h2> 2. Agentid</h2>
+      <h2> 2Agentid</h2>
       <div> 应用唯一标识</div>
       <div className="image">
         <Image width="100%" src={agentId} />
       </div>
       <div> 获取路径:“钉钉开发平台”--“应用开发”--“查看应用”</div>
-      <h2> 3. 收信人ID、收信部门ID</h2>
+      <h2> 3收信人ID、收信部门ID</h2>
       <div>
         接收通知的2种方式,2个字段若在此页面都没有填写,则在模板调试和配置告警通知时需要手动填写
       </div>
@@ -42,7 +42,7 @@ const DingTalk = () => {
         <Image width="100%" src={userId} />
         <Image width="100%" src={dept} />
       </div>
-      <h2> 4. 模板内容</h2>
+      <h2> 4模板内容</h2>
       <div>
         支持填写带变量的动态模板。变量填写规范示例:${a}
         。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。

+ 1 - 1
src/pages/notice/Template/Detail/doc/DingTalkRebot.tsx

@@ -20,7 +20,7 @@ const DingTalkRebot = () => {
         <div> 使用固定的通知配置发送此通知模板</div>
         <h2> 2、消息类型</h2>
         <div> 目前支持text、markdown、link3种。</div>
-        <h2> 3. 模板内容</h2>
+        <h2> 3模板内容</h2>
         <div>
           支持填写带变量的动态模板。变量填写规范示例:${b}
           。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。

+ 4 - 4
src/pages/notice/Template/Detail/doc/Email.tsx

@@ -12,13 +12,13 @@ const Email = () => {
       </div>
       <h1>2.模板配置说明</h1>
       <div>
-        <h2> 1. 服务器地址</h2>
+        <h2> 1服务器地址</h2>
         <div>服务器地址支持自定义输入</div>
-        <h2> 2. 标题</h2>
+        <h2> 2标题</h2>
         <div>支持输入变量,变量格式${a}</div>
-        <h2> 3. 收件人</h2>
+        <h2> 3收件人</h2>
         <div> 支持录入多个邮箱地址,可填写变量参数。</div>
-        <h2> 4. 模板内容</h2>
+        <h2> 4模板内容</h2>
         <div>
           支持填写带变量的动态模板。变量填写规范示例:${b}
           。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。

+ 7 - 7
src/pages/notice/Template/Detail/doc/WeixinApp.tsx

@@ -18,34 +18,34 @@ const WeixinApp = () => {
       </div>
       <h1>2.模板配置说明</h1>
       <div>
-        <h2>1. 绑定配置</h2>
+        <h2>1绑定配置</h2>
         <div>使用固定的通知配置发送此通知模板</div>
       </div>
       <div>
-        <h2>2. 用户标签</h2>
+        <h2>2用户标签</h2>
         <div>以标签的维度通知该标签下所有用户</div>
       </div>
       <div>
-        <h2>3. 消息模板</h2>
+        <h2>3消息模板</h2>
         <div>微信公众号中配置的消息模板</div>
       </div>
       <div>
-        <h2>4. 模板跳转链接</h2>
+        <h2>4模板跳转链接</h2>
         <div>点击消息之后进行页面跳转</div>
       </div>
       <div>
-        <h2>5. 跳转小程序Appid</h2>
+        <h2>5跳转小程序Appid</h2>
         <div>点击消息之后打开对应的小程序</div>
       </div>
       <div>
-        <h2>6. 跳转小程序具体路径</h2>
+        <h2>6跳转小程序具体路径</h2>
         <div>点击消息之后跳转到小程序的具体页面</div>
         <div className="image">
           <Image width="100%" src={appId} />
         </div>
       </div>
       <div>
-        <h2>7. 模板内容</h2>
+        <h2>7模板内容</h2>
         <div>
           支持填写带变量的动态模板。变量填写规范示例:${name}
           。填写动态参数后,可对变量的名称、类型、格式进行配置,以便告警通知时填写。

+ 2 - 2
src/pages/notice/Template/Detail/doc/WeixinCorp.tsx

@@ -23,13 +23,13 @@ const WeixinCorp = () => {
       <div>
         <h2> 1、绑定配置</h2>
         <div> 使用固定的通知配置发送此通知模板</div>
-        <h2> 2. Agentid</h2>
+        <h2> 2Agentid</h2>
         <div> 应用唯一标识</div>
         <div> 获取路径:“企业微信”管理后台--“应用管理”--“应用”--“查看应用”</div>
         <div className="image">
           <Image width="100%" src={agentId} />
         </div>
-        <h2> 3. 收信人ID、收信部门ID、标签推送</h2>
+        <h2> 3收信人ID、收信部门ID、标签推送</h2>
         <div>
           接收通知的3种方式,3个字段若在此页面都没有填写,则在模板调试和配置告警通知时需要手动填写
         </div>

+ 3 - 1
src/pages/notice/Template/index.tsx

@@ -103,7 +103,9 @@ const Template = observer(() => {
     {
       dataIndex: 'provider',
       title: '通知方式',
-      renderText: (text, record) => typeList[record.type][record.provider],
+      renderText: (text, record) => {
+        return typeList[record.type][record.provider];
+      },
       valueType: 'select',
       valueEnum: list[id],
     },

+ 6 - 6
src/pages/rule-engine/Alarm/Log/Detail/Info.tsx

@@ -29,15 +29,15 @@ const Info = (props: Props) => {
         {data.targetType === 'device' && (
           <>
             <Descriptions.Item label="告警设备" span={1}>
-              {data?.targetName || '--'}
+              {data?.targetName || ''}
             </Descriptions.Item>
             <Descriptions.Item label="设备ID" span={1}>
-              {data?.targetId || '--'}
+              {data?.targetId || ''}
             </Descriptions.Item>
           </>
         )}
         <Descriptions.Item label="告警名称" span={1}>
-          {data?.alarmConfigName || '--'}
+          {data?.alarmConfigName || ''}
         </Descriptions.Item>
         <Descriptions.Item label="告警时间" span={1}>
           {moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')}
@@ -57,14 +57,14 @@ const Info = (props: Props) => {
           </Tooltip>
         </Descriptions.Item>
         <Descriptions.Item label="告警说明" span={1}>
-          <Tooltip placement="topLeft" title={data?.description || '--'}>
+          <Tooltip placement="topLeft" title={data?.description || ''}>
             <div className="ellipsis" style={{ maxWidth: 1 }}>
-              {data?.description || '--'}
+              {data?.description || ''}
             </div>
           </Tooltip>
         </Descriptions.Item>
         <Descriptions.Item label="告警流水" span={2}>
-          {data?.alarmInfo || '--'}
+          {data?.alarmInfo || ''}
         </Descriptions.Item>
       </Descriptions>
     </Modal>

+ 1 - 0
src/pages/rule-engine/Alarm/Log/SolveLog/index.tsx

@@ -85,6 +85,7 @@ const SolveLog = (props: Props) => {
         field={columns}
         target="bind-channel"
         enableSave={false}
+        model={'simple'}
         onSearch={(data) => {
           actionRef.current?.reload();
           const terms = [

+ 2 - 2
src/pages/rule-engine/DashBoard/index.less

@@ -58,11 +58,11 @@
         }
 
         .new-alarm-item-content {
-          flex-grow: 1;
+          width: ~'calc(100% - 360px)';
         }
 
         .new-alarm-item-state {
-          width: 110px;
+          width: 90px;
           text-align: center;
 
           .error {

+ 43 - 1
src/pages/system/Role/Detail/Permission/Allocate/MenuPermission.tsx

@@ -99,6 +99,26 @@ const MenuPermission = (props: Props) => {
                 fontWeight: value.id === 'menu-permission' ? 600 : 400,
               }}
               onChange={(e) => {
+                let access: any[] = [];
+                if (e.target.checked && !checkValue) {
+                  setCheckValue('creator');
+                  access = (value?.assetAccesses || []).map((i: any) => {
+                    return {
+                      ...i,
+                      granted: i.supportId === 'creator',
+                    };
+                  });
+                } else if (!e.target.checked) {
+                  setCheckValue('');
+                  access = (value?.assetAccesses || []).map((i: any) => {
+                    return {
+                      ...i,
+                      granted: false,
+                    };
+                  });
+                } else {
+                  access = value?.assetAccesses || [];
+                }
                 setCheckAll(e.target.checked);
                 setIndeterminate(false);
                 const buttons = (value?.buttons || []).map((i: any) => {
@@ -109,6 +129,7 @@ const MenuPermission = (props: Props) => {
                 });
                 props.change({
                   ...value,
+                  assetAccesses: [...access],
                   check: e.target.checked ? 1 : 3, // 1: 全选 2: 只选了部分 3: 一个都没选
                   buttons: [...buttons],
                   children: checkAllData(value.children || [], e.target.checked),
@@ -131,6 +152,26 @@ const MenuPermission = (props: Props) => {
                   'id',
                 )}
                 onChange={(data: CheckboxValueType[]) => {
+                  let access: any[] = [];
+                  if (data.length > 0 && !checkValue) {
+                    setCheckValue('creator');
+                    access = (value?.assetAccesses || []).map((i: any) => {
+                      return {
+                        ...i,
+                        granted: i.supportId === 'creator',
+                      };
+                    });
+                  } else if (data.length === 0) {
+                    setCheckValue('');
+                    access = (value?.assetAccesses || []).map((i: any) => {
+                      return {
+                        ...i,
+                        granted: false,
+                      };
+                    });
+                  } else {
+                    access = value?.assetAccesses || [];
+                  }
                   const buttons = value.buttons.map((i: any) => {
                     return {
                       ...i,
@@ -152,6 +193,7 @@ const MenuPermission = (props: Props) => {
                   const d = {
                     ...value,
                     check,
+                    assetAccesses: [...access],
                     buttons: [...buttons],
                   };
                   props.change(d);
@@ -220,7 +262,7 @@ const MenuPermission = (props: Props) => {
                 <div>{value?.accessDescription}</div>
               ) : (
                 <Radio.Group
-                  defaultValue={value?.assetAccesses[0]?.supportId}
+                  defaultValue={'creator'}
                   value={checkValue}
                   onChange={(e) => {
                     setCheckValue(e.target.value);