wzyyy 3 лет назад
Родитель
Сommit
044e3d1bba

+ 51 - 16
src/components/FIndicators/index.tsx

@@ -1,15 +1,29 @@
-import { Checkbox, InputNumber, Space, DatePicker, Input } from 'antd';
+import { Checkbox, InputNumber, DatePicker, Input, Select } from 'antd';
 import moment from 'moment';
+import { useEffect, useState } from 'react';
 
 interface Props {
   value: any;
   type: any;
+  enum: any;
   onChange: (value: any) => void;
 }
 
 const FIndicators = (props: Props) => {
   const { value, onChange, type } = props;
   const DatePicker1: any = DatePicker;
+  const [list, setList] = useState<any[]>([]);
+
+  useEffect(() => {
+    const arr = [];
+    if (!!props.enum?.falseText && props.enum?.falseValue !== undefined) {
+      arr.push({ text: props.enum?.falseText, value: props.enum?.falseValue });
+    }
+    if (!!props.enum?.trueText && props.enum?.trueValue !== undefined) {
+      arr.push({ text: props.enum?.trueText, value: props.enum?.trueValue });
+    }
+    setList(arr);
+  }, [props.enum]);
 
   const renderComponent = () => {
     if (['int', 'long', 'double', 'float'].includes(type)) {
@@ -82,6 +96,25 @@ const FIndicators = (props: Props) => {
           />
         );
       }
+    } else if (type === 'boolean') {
+      return (
+        <Select
+          style={{ width: '100%' }}
+          placeholder={'请选择'}
+          value={value?.value}
+          onChange={(val) => {
+            const obj = {
+              ...value,
+              value: [val],
+            };
+            onChange(obj);
+          }}
+        >
+          {list.map((item) => (
+            <Select.Option value={item.value}>{item.text}</Select.Option>
+          ))}
+        </Select>
+      );
     } else {
       return (
         <>
@@ -113,22 +146,24 @@ const FIndicators = (props: Props) => {
     }
   };
   return (
-    <Space align="baseline">
+    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
       {renderComponent()}
-      <Checkbox
-        style={{ minWidth: 60 }}
-        checked={value?.range}
-        onChange={(e) => {
-          onChange({
-            ...value,
-            value: e.target.checked ? [undefined, undefined] : [undefined],
-            range: e.target.checked,
-          });
-        }}
-      >
-        范围
-      </Checkbox>
-    </Space>
+      {type !== 'boolean' && (
+        <Checkbox
+          style={{ minWidth: 60, marginLeft: 5 }}
+          checked={value?.range}
+          onChange={(e) => {
+            onChange({
+              ...value,
+              value: e.target.checked ? [undefined, undefined] : [undefined],
+              range: e.target.checked,
+            });
+          }}
+        >
+          范围
+        </Checkbox>
+      )}
+    </div>
   );
 };
 export default FIndicators;

+ 35 - 0
src/components/Metadata/ArrayParam/index.tsx

@@ -7,6 +7,7 @@ import { Store } from 'jetlinks-store';
 import JsonParam from '@/components/Metadata/JsonParam';
 import EnumParam from '@/components/Metadata/EnumParam';
 import BooleanEnum from '@/components/Metadata/BooleanParam';
+import { registerValidateRules } from '@formily/core';
 
 const ArrayParam = () => {
   const SchemaField = createSchemaField({
@@ -24,6 +25,24 @@ const ArrayParam = () => {
     },
   });
 
+  registerValidateRules({
+    checkLength(value) {
+      if (String(value).length > 64) {
+        return {
+          type: 'error',
+          message: '最多可输入64个字符',
+        };
+      }
+      if (!(value % 1 === 0)) {
+        return {
+          type: 'error',
+          message: '请输入非0正整数',
+        };
+      }
+      return '';
+    },
+  });
+
   const schema: ISchema = {
     type: 'object',
     properties: {
@@ -53,6 +72,14 @@ const ArrayParam = () => {
             title: '精度',
             'x-decorator': 'FormItem',
             'x-component': 'NumberPicker',
+            'x-component-props': {
+              min: 1,
+            },
+            'x-validator': [
+              {
+                checkLength: true,
+              },
+            ],
             'x-reactions': {
               dependencies: ['.type'],
               fulfill: {
@@ -105,9 +132,17 @@ const ArrayParam = () => {
                 title: '最大长度',
                 'x-decorator': 'FormItem',
                 'x-component': 'NumberPicker',
+                'x-component-props': {
+                  min: 1,
+                },
                 'x-decorator-props': {
                   tooltip: '字节',
                 },
+                'x-validator': [
+                  {
+                    checkLength: true,
+                  },
+                ],
                 'x-reactions': {
                   dependencies: ['..type'],
                   fulfill: {

+ 4 - 1
src/components/Metadata/EditTable/index.tsx

@@ -8,6 +8,7 @@ import { PopoverProps } from 'antd/lib/popover';
 import { useClickAway, usePrefixCls } from '@formily/antd/lib/__builtins__';
 import cls from 'classnames';
 import { get } from 'lodash';
+import { Ellipsis } from '@/components';
 /**
  * 默认Inline展示
  */
@@ -160,7 +161,9 @@ Editable.Popover = observer((props) => {
   const headTitle = () => {
     return (
       <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
-        <div>{props.title || field.title}</div>
+        <div style={{ width: 150 }}>
+          <Ellipsis title={props.title || field.title} />
+        </div>
         <CloseOutlined
           onClick={() => {
             setVisible(false);

+ 22 - 3
src/components/Metadata/EnumParam/index.tsx

@@ -1,6 +1,7 @@
 import { createSchemaField } from '@formily/react';
-import { ArrayItems, Editable, FormItem, FormLayout, Input } from '@formily/antd';
+import { ArrayItems, FormItem, FormLayout, Input } from '@formily/antd';
 import type { ISchema } from '@formily/json-schema';
+import Editable from '../EditTable';
 
 const EnumParam = () => {
   const SchemaField = createSchemaField({
@@ -42,22 +43,40 @@ const EnumParam = () => {
                 text: {
                   type: 'string',
                   title: 'Text',
-                  required: true,
                   'x-decorator': 'FormItem',
                   'x-component': 'Input',
                   'x-component-props': {
                     placeholder: '标识',
                   },
+                  'x-validator': [
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                    {
+                      required: true,
+                      message: '请输入标识',
+                    },
+                  ],
                 },
                 value: {
                   type: 'string',
                   title: 'Value',
-                  required: true,
                   'x-decorator': 'FormItem',
                   'x-component': 'Input',
                   'x-component-props': {
                     placeholder: '对该枚举项的描述',
                   },
+                  'x-validator': [
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                    {
+                      required: true,
+                      message: '请输入描述',
+                    },
+                  ],
                 },
               },
             },

+ 45 - 0
src/components/Metadata/JsonParam/index.tsx

@@ -11,6 +11,7 @@ import EnumParam from '@/components/Metadata/EnumParam';
 import ArrayParam from '@/components/Metadata/ArrayParam';
 import { useIntl } from '@/.umi/plugin-locale/localeExports';
 import Editable from '../EditTable';
+import { registerValidateRules } from '@formily/core';
 
 // 不算是自定义组件。只是抽离了JSONSchema
 interface Props {
@@ -45,6 +46,24 @@ const JsonParam = observer((props: Props) => {
       return _data;
     });
 
+  registerValidateRules({
+    checkLength(value) {
+      if (String(value).length > 64) {
+        return {
+          type: 'error',
+          message: '最多可输入64个字符',
+        };
+      }
+      if (!(value % 1 === 0)) {
+        return {
+          type: 'error',
+          message: '请输入非0正整数',
+        };
+      }
+      return '';
+    },
+  });
+
   const schema: ISchema = {
     type: 'object',
     properties: {
@@ -100,6 +119,16 @@ const JsonParam = observer((props: Props) => {
                   required: true,
                   'x-decorator': 'FormItem',
                   'x-component': 'Input',
+                  'x-validator': [
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                    {
+                      required: true,
+                      message: '请输入名称',
+                    },
+                  ],
                 },
                 valueType: {
                   type: 'object',
@@ -232,6 +261,14 @@ const JsonParam = observer((props: Props) => {
                               defaultMessage: '字节',
                             }),
                           },
+                          'x-component-props': {
+                            min: 1,
+                          },
+                          'x-validator': [
+                            {
+                              checkLength: true,
+                            },
+                          ],
                           'x-reactions': {
                             dependencies: ['..type'],
                             fulfill: {
@@ -251,6 +288,14 @@ const JsonParam = observer((props: Props) => {
                   'x-decorator': 'FormItem',
                   'x-component': 'NumberPicker',
                   'x-visible': false,
+                  'x-validator': [
+                    {
+                      checkLength: true,
+                    },
+                  ],
+                  'x-component-props': {
+                    min: 1,
+                  },
                   'x-reactions': {
                     dependencies: ['..valueType.type'],
                     fulfill: {

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

@@ -134,6 +134,12 @@ const Save = (props: Props) => {
           min: 1,
         },
         name: 'sortIndex',
+        'x-validator': [
+          {
+            format: 'integer',
+            message: '请输入非0正整数',
+          },
+        ],
       },
       description: {
         type: 'string',

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

@@ -212,12 +212,7 @@ const Save = (props: Props) => {
               rules={[
                 {
                   required: true,
-                  message: intlFormat(
-                    'pages.form.tip.select.props',
-                    '请选择所属产品',
-                    'pages.device.instanceDetail.deviceType',
-                    '设备类型',
-                  ),
+                  message: '请选择所属产品',
                 },
               ]}
               tooltip={'只能选择“正常”状态的产品'}

+ 12 - 1
src/pages/device/Product/Detail/Access/index.tsx

@@ -499,7 +499,18 @@ const Access = () => {
         ...itemSchema,
         storePolicy: {
           type: 'string',
-          title: <TitleComponent data={'存储策略'} />,
+          title: (
+            <TitleComponent
+              data={
+                <div className="config">
+                  存储策略
+                  <Tooltip title="若修改存储策略,需要手动做数据迁移,平台只能搜索最新存储策略中的数据">
+                    <QuestionCircleOutlined />
+                  </Tooltip>
+                </div>
+              }
+            />
+          ),
           'x-decorator': 'FormItem',
           'x-component': 'Select',
           'x-component-props': {

+ 22 - 5
src/pages/device/Product/index.tsx

@@ -22,7 +22,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { PermissionButton, ProTableCard } from '@/components';
 import ProductCard from '@/components/ProTableCard/CardItems/product';
-import { downloadObject, onlyMessage } from '@/utils/util';
+import { downloadObject, isNoCommunity, onlyMessage } from '@/utils/util';
 import { service as categoryService } from '@/pages/device/Category';
 import { service as deptService } from '@/pages/system/Department';
 import { omit } from 'lodash';
@@ -267,10 +267,26 @@ const Product = observer(() => {
       hideInTable: true,
       request: () =>
         service.getProviders().then((resp: any) => {
-          return (resp?.result || []).map((item: any) => ({
-            label: item.name,
-            value: item.id,
-          }));
+          if (isNoCommunity) {
+            return (resp?.result || []).map((item: any) => ({
+              label: item.name,
+              value: item.id,
+            }));
+          } else {
+            return (resp?.result || [])
+              .filter((i: any) =>
+                [
+                  'mqtt-server-gateway',
+                  'http-server-gateway',
+                  'mqtt-client-gateway',
+                  'tcp-server-gateway',
+                ].includes(i.id),
+              )
+              .map((item: any) => ({
+                label: item.name,
+                value: item.id,
+              }));
+          }
         }),
     },
     {
@@ -498,6 +514,7 @@ const Product = observer(() => {
                     onlyMessage('请上传json格式文件', 'error');
                     return false;
                   }
+                  delete data.state;
                   const res = await service.update(data);
                   if (res.status === 200) {
                     onlyMessage('操作成功');

+ 53 - 10
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -13,7 +13,6 @@ import {
   ArrayItems,
   Checkbox,
   DatePicker,
-  Editable,
   Form,
   FormGrid,
   FormItem,
@@ -37,7 +36,6 @@ import { productModel } from '@/pages/device/Product';
 import { service } from '@/pages/device/components/Metadata';
 import { Store } from 'jetlinks-store';
 import type { MetadataItem } from '@/pages/device/Product/typings';
-
 import JsonParam from '@/components/Metadata/JsonParam';
 import ArrayParam from '@/components/Metadata/ArrayParam';
 import EnumParam from '@/components/Metadata/EnumParam';
@@ -54,6 +52,7 @@ import FIndicators from '@/components/FIndicators';
 import { action } from '@formily/reactive';
 import { asyncUpdateMedata, updateMetadata } from '../../metadata';
 import { onlyMessage } from '@/utils/util';
+import Editable from '@/components/Metadata/EditTable';
 
 interface Props {
   type: 'product' | 'device';
@@ -209,6 +208,21 @@ const Edit = observer((props: Props) => {
       const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
       return reg.exec(value) ? '' : 'ID只能由数字、字母、下划线、中划线组成';
     },
+    checkLength(value) {
+      if (String(value).length > 64) {
+        return {
+          type: 'error',
+          message: '最多可输入64个字符',
+        };
+      }
+      if (!(value % 1 === 0)) {
+        return {
+          type: 'error',
+          message: '请输入非0正整数',
+        };
+      }
+      return '';
+    },
   });
   const valueTypeConfig = {
     type: 'object',
@@ -216,7 +230,12 @@ const Edit = observer((props: Props) => {
     properties: {
       type: {
         title: schemaTitleMapping[MetadataModel.type].title,
-        required: true,
+        'x-validator': [
+          {
+            required: true,
+            message: `请选择${schemaTitleMapping[MetadataModel.type].title}`,
+          },
+        ],
         'x-decorator': 'FormItem',
         'x-component': 'Select',
         default: MetadataModel.type === 'events' ? 'object' : null,
@@ -342,6 +361,14 @@ const Edit = observer((props: Props) => {
                 defaultMessage: '字节',
               }),
             },
+            'x-component-props': {
+              min: 1,
+            },
+            'x-validator': [
+              {
+                checkLength: true,
+              },
+            ],
             'x-reactions': {
               dependencies: ['..type'],
               fulfill: {
@@ -448,7 +475,7 @@ const Edit = observer((props: Props) => {
         },
         {
           required: true,
-          message: '请输入名',
+          message: '请输入名',
         },
       ],
     },
@@ -483,7 +510,12 @@ const Edit = observer((props: Props) => {
               defaultMessage: '来源',
             }),
             'x-disabled': MetadataModel.action === 'edit',
-            required: true,
+            'x-validator': [
+              {
+                required: true,
+                message: `请选择来源`,
+              },
+            ],
             'x-decorator': 'FormItem',
             'x-component': 'Select',
             enum: PropertySource,
@@ -666,7 +698,12 @@ const Edit = observer((props: Props) => {
           },
           type: {
             title: MetadataModel.type === 'tags' ? '标签类型' : '读写类型',
-            required: true,
+            'x-validator': [
+              {
+                required: true,
+                message: `请输入${MetadataModel.type === 'tags' ? '标签类型' : '读写类型'}`,
+              },
+            ],
             'x-decorator': 'FormItem',
             'x-component': 'Select',
             'x-component-props': {
@@ -720,7 +757,7 @@ const Edit = observer((props: Props) => {
             'x-decorator-props': {
               tooltip: '场景联动页面可引用指标配置作为触发条件',
             },
-            'x-visible': props.type === 'product',
+            // 'x-visible': props.type === 'product',
             items: {
               type: 'object',
               'x-decorator': 'ArrayItems.Item',
@@ -808,11 +845,12 @@ const Edit = observer((props: Props) => {
                         layout: 'vertical',
                       },
                       'x-reactions': {
-                        dependencies: ['valueType.type'],
+                        dependencies: ['valueType.type', 'valueType'],
                         fulfill: {
                           state: {
                             componentProps: {
                               type: '{{$deps[0]}}',
+                              enum: '{{$deps[1]}}',
                             },
                           },
                         },
@@ -829,7 +867,7 @@ const Edit = observer((props: Props) => {
                                 return Promise.reject(new Error('请输入指标值'));
                               }
                             } else {
-                              if (value?.value && !value?.value[0]) {
+                              if (value?.value !== undefined && value?.value[0] === undefined) {
                                 return Promise.reject(new Error('请输入指标值'));
                               }
                             }
@@ -1050,7 +1088,12 @@ const Edit = observer((props: Props) => {
               id: 'pages.device.productDetail.metadata.level',
               defaultMessage: 'level',
             }),
-            required: true,
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择级别',
+              },
+            ],
             'x-decorator': 'FormItem',
             'x-component': 'Select',
             enum: EventLevel,

+ 9 - 1
src/pages/link/DashBoard/index.tsx

@@ -10,6 +10,7 @@ import './index.less';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
 import Echarts, { echarts } from '@/components/DashBoard/echarts';
+import { isNoCommunity } from '@/utils/util';
 
 type RefType = {
   getValues: Function;
@@ -193,8 +194,9 @@ export default () => {
 
   const [subscribeTopic] = useSendWebsocketMessage();
 
-  const { data: serverNode } = useRequest(service.serverNode, {
+  const { data: serverNode, run: serverNodeRun } = useRequest(service.serverNode, {
     formatResult: (res) => res.result.map((item: any) => ({ label: item.name, value: item.id })),
+    manual: true,
   });
 
   const arrayReverse = (data: any[]): any[] => {
@@ -660,6 +662,12 @@ export default () => {
   }, [serverId]);
 
   useEffect(() => {
+    if (isNoCommunity) {
+      serverNodeRun();
+    }
+  }, []);
+
+  useEffect(() => {
     if (serverNode && serverNode.length) {
       setServerId(serverNode[0].value);
     }

+ 6 - 6
src/pages/media/DashBoard/index.tsx

@@ -139,13 +139,13 @@ export default () => {
         },
         yAxis: {
           type: 'value',
-          minInterval: 1,
-        },
-        grid: {
-          left: '4%',
-          right: '2%',
-          top: '2%',
+          // minInterval: 1,
         },
+        // grid: {
+        //   left: '4%',
+        //   right: '2%',
+        //   top: '2%',
+        // },
         color: ['#2F54EB'],
         series: [
           {

+ 25 - 3
src/pages/notice/Template/Detail/index.tsx

@@ -34,7 +34,7 @@ import { Card, Col, Row, Tooltip } from 'antd';
 import { typeList } from '@/pages/notice';
 import { configService, service, state } from '@/pages/notice/Template';
 import FBraftEditor from '@/components/FBraftEditor';
-import { onlyMessage, useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, phoneRegEx, useAsyncDataSource } from '@/utils/util';
 import WeixinCorp from '@/pages/notice/Template/Detail/doc/WeixinCorp';
 import WeixinApp from '@/pages/notice/Template/Detail/doc/WeixinApp';
 import DingTalk from '@/pages/notice/Template/Detail/doc/DingTalk';
@@ -1017,7 +1017,7 @@ const Detail = observer(() => {
                           placeholder: '请输入模版ID',
                         },
                       },
-                      calledShowNumbers: {
+                      calledNumber: {
                         title: '被叫号码',
                         'x-component': 'Input',
                         'x-decorator': 'FormItem',
@@ -1033,11 +1033,22 @@ const Detail = observer(() => {
                             max: 64,
                             message: '最多可输入64个字符',
                           },
+                          {
+                            validator: (value: string) => {
+                              return new Promise((resolve) => {
+                                if (!value) resolve('');
+                                if (!phoneRegEx(value)) {
+                                  resolve('请输入有效号码');
+                                }
+                                resolve('');
+                              });
+                            },
+                          },
                         ],
                       },
                     },
                   },
-                  calledNumber: {
+                  calledShowNumbers: {
                     title: '被叫显号',
                     'x-component': 'Input',
                     'x-decorator': 'FormItem',
@@ -1052,6 +1063,17 @@ const Detail = observer(() => {
                         max: 64,
                         message: '最多可输入64个字符',
                       },
+                      {
+                        validator: (value: string) => {
+                          return new Promise((resolve) => {
+                            if (!value) resolve('');
+                            if (!phoneRegEx(value)) {
+                              resolve('请输入有效号码');
+                            }
+                            resolve('');
+                          });
+                        },
+                      },
                     ],
                   },
                   PlayTimes: {

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

@@ -237,7 +237,6 @@ const Template = observer(() => {
               isPermission={templatePermission.add}
               onClick={() => {
                 state.current = undefined;
-                console.log(id);
                 history.push(getMenuPathByParams(MENUS_CODE['notice/Template/Detail'], id));
               }}
               key="button"

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

@@ -5,6 +5,7 @@ import { AlarmLogModel } from './model';
 import TabComponent from './TabComponent';
 import Service from './service';
 import { Store } from 'jetlinks-store';
+import { isNoCommunity } from '@/utils/util';
 
 export const service = new Service('alarm/record');
 
@@ -31,6 +32,24 @@ const Log = observer(() => {
       tab: '其他',
     },
   ];
+  const noList = [
+    {
+      key: 'all',
+      tab: '全部',
+    },
+    {
+      key: 'product',
+      tab: '产品',
+    },
+    {
+      key: 'device',
+      tab: '设备',
+    },
+    {
+      key: 'other',
+      tab: '其他',
+    },
+  ];
 
   useEffect(() => {
     service.queryDefaultLevel().then((resp) => {
@@ -46,7 +65,7 @@ const Log = observer(() => {
       onTabChange={(key: string) => {
         AlarmLogModel.tab = key;
       }}
-      tabList={list}
+      tabList={isNoCommunity ? list : noList}
       tabActiveKey={AlarmLogModel.tab}
     >
       <TabComponent type={AlarmLogModel.tab} />

+ 15 - 6
src/pages/rule-engine/DashBoard/index.tsx

@@ -14,6 +14,7 @@ import encodeQuery from '@/utils/encodeQuery';
 import useHistory from '@/hooks/route/useHistory';
 import { getMenuPathByCode } from '@/utils/menu';
 import { Empty } from '@/components';
+import { isNoCommunity } from '@/utils/util';
 
 const service = new Service();
 export const state = model<{
@@ -494,12 +495,20 @@ const Dashboard = observer(() => {
             key: 'targetType',
             Children: (
               <Select
-                options={[
-                  { label: '设备', value: 'device' },
-                  { label: '产品', value: 'product' },
-                  { label: '组织', value: 'org' },
-                  { label: '其它', value: 'other' },
-                ]}
+                options={
+                  isNoCommunity
+                    ? [
+                        { label: '设备', value: 'device' },
+                        { label: '产品', value: 'product' },
+                        { label: '组织', value: 'org' },
+                        { label: '其它', value: 'other' },
+                      ]
+                    : [
+                        { label: '设备', value: 'device' },
+                        { label: '产品', value: 'product' },
+                        { label: '其它', value: 'other' },
+                      ]
+                }
               />
             ),
           }}

+ 35 - 17
src/pages/system/User/ResetPassword/index.tsx

@@ -4,7 +4,7 @@ import { Form, FormItem, Password } from '@formily/antd';
 import { ISchema } from '@formily/json-schema';
 import { useIntl } from 'umi';
 import { useMemo } from 'react';
-import { createForm } from '@formily/core';
+import { createForm, registerValidateRules } from '@formily/core';
 import { service } from '@/pages/system/User';
 import { onlyMessage } from '@/utils/util';
 
@@ -23,6 +23,18 @@ const ResetPassword = (props: Props) => {
     },
   });
 
+  registerValidateRules({
+    checkStrength(value: string) {
+      if (/^[0-9]+$/.test(value) || /^[a-zA-Z]+$/.test(value) || /^[~!@#$%^&*]+$/.test(value)) {
+        return {
+          type: 'error',
+          message: '密码强度不够',
+        };
+      }
+      return true;
+    },
+  });
+
   const schema: ISchema = {
     type: 'object',
     properties: {
@@ -52,14 +64,14 @@ const ResetPassword = (props: Props) => {
         ],
         name: 'password',
         'x-validator': [
-          // {
-          //   max: 128,
-          //   message: '密码最多可输入128位',
-          // },
-          // {
-          //   min: 8,
-          //   message: '密码不能少于8位',
-          // },
+          {
+            max: 64,
+            message: '密码最多可输入64位',
+          },
+          {
+            min: 8,
+            message: '密码不能少于8位',
+          },
           {
             required: true,
             message: '请输入密码',
@@ -86,6 +98,9 @@ const ResetPassword = (props: Props) => {
               });
             },
           },
+          {
+            checkStrength: true,
+          },
         ],
       },
       confirmPassword: {
@@ -101,14 +116,14 @@ const ResetPassword = (props: Props) => {
           placeholder: '请再次输入密码',
         },
         'x-validator': [
-          // {
-          //   max: 128,
-          //   message: '密码最多可输入128位',
-          // },
-          // {
-          //   min: 8,
-          //   message: '密码不能少于8位',
-          // },
+          {
+            max: 64,
+            message: '密码最多可输入64位',
+          },
+          {
+            min: 8,
+            message: '密码不能少于8位',
+          },
           {
             required: true,
             message: '请输入确认密码',
@@ -135,6 +150,9 @@ const ResetPassword = (props: Props) => {
               });
             },
           },
+          {
+            checkStrength: true,
+          },
         ],
         'x-reactions': [
           {

+ 19 - 1
src/pages/system/User/Save/index.tsx

@@ -1,7 +1,7 @@
 import { TreeSelect as ATreeSelect } from 'antd';
 import { useIntl } from 'umi';
 import type { Field } from '@formily/core';
-import { createForm } from '@formily/core';
+import { createForm, registerValidateRules } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import React, { useEffect, useState } from 'react';
 import * as ICONS from '@ant-design/icons';
@@ -57,6 +57,18 @@ const Save = (props: Props) => {
     );
   };
 
+  registerValidateRules({
+    checkStrength(value: string) {
+      if (/^[0-9]+$/.test(value) || /^[a-zA-Z]+$/.test(value) || /^[~!@#$%^&*]+$/.test(value)) {
+        return {
+          type: 'error',
+          message: '密码强度不够',
+        };
+      }
+      return true;
+    },
+  });
+
   const getUser = async () => {
     if (props.data.id) {
       const response: Response<UserItem> = await service.queryDetail(props.data?.id);
@@ -227,6 +239,9 @@ const Save = (props: Props) => {
             required: model === 'add',
             message: '请输入密码',
           },
+          {
+            checkStrength: true,
+          },
         ],
       },
       confirmPassword: {
@@ -277,6 +292,9 @@ const Save = (props: Props) => {
               });
             },
           },
+          {
+            checkStrength: true,
+          },
         ],
 
         'x-reactions': [

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

@@ -117,6 +117,7 @@ export enum MENUS_CODE {
   'device/Product/Detail/BaseInfo' = 'device/Product/Detail/BaseInfo',
   'device/Product/Detail' = 'device/Product/Detail',
   'link/AccessConfig/Detail' = 'link/AccessConfig/Detail',
+  'link/DashBoard' = 'link/DashBoard',
   'system/Menu/Detail' = 'system/Menu/Detail',
   'system/Department/Detail' = 'system/Department/Detail',
   'link/Type/Detail' = 'link/Type/Detail',
@@ -215,6 +216,7 @@ export const CommunityCodeList = [
   'link/AccessConfig',
   'link/AccessConfig/Detail',
   'link/Protocol',
+  'link/DashBoard',
   'Log',
   'link/Type',
   'link/Type/Detail',

+ 15 - 3
src/utils/util.ts

@@ -41,9 +41,9 @@ export const downloadFile = (url: string, params?: Record<string, any>) => {
 export const downloadObject = (record: Record<string, any>, fileName: string) => {
   // 创建隐藏的可下载链接
   const ghostLink = document.createElement('a');
-  ghostLink.download = `${fileName}-${
-    record?.name || moment(new Date()).format('YYYY/MM/DD HH:mm:ss')
-  }.json`;
+  ghostLink.download = `${record?.name}${fileName}_${moment(new Date()).format(
+    'YYYY/MM/DD HH:mm:ss',
+  )}.json`;
   ghostLink.style.display = 'none';
   //字符串内容转成Blob地址
   const blob = new Blob([JSON.stringify(record)]);
@@ -130,3 +130,15 @@ export const onlyMessage = (
   });
 
 export const isNoCommunity = !(localStorage.getItem(SystemConst.Version_Code) === 'community');
+/**
+ * 座机号+手机号校验
+ * @param value
+ * @returns {boolean}
+ */
+export const phoneRegEx = (value: string) => {
+  const phone = new RegExp(
+    '^(((\\+86)|(\\+86-))|((86)|(86\\-))|((0086)|(0086\\-)))?1[3|5|7|8]\\d{9}$',
+  );
+  const mobile = /(0[0-9]{2,3})([2-9][0-9]{6,7})+([0-9]{8,11})?$/;
+  return phone.test(value) || mobile.test(value);
+};