Parcourir la source

fix: merge next

wzyyy il y a 3 ans
Parent
commit
6349c8ec7b
37 fichiers modifiés avec 262 ajouts et 122 suppressions
  1. BIN
      public/images/device/device-number.png
  2. BIN
      public/images/device/device-product.png
  3. BIN
      public/images/home/bottom-1.png
  4. BIN
      public/images/home/bottom-10.png
  5. BIN
      public/images/home/bottom-11.png
  6. BIN
      public/images/home/bottom-4.png
  7. BIN
      public/images/home/bottom-9.png
  8. BIN
      public/images/home/content1.png
  9. BIN
      public/images/home/top-1.png
  10. BIN
      public/images/home/top-2.png
  11. 3 0
      public/images/home/top-3.svg
  12. 3 0
      public/images/home/top-4.svg
  13. BIN
      public/images/media/dashboard-1.png
  14. BIN
      public/images/media/dashboard-2.png
  15. BIN
      public/images/media/dashboard-3.png
  16. BIN
      public/images/media/dashboard-4.png
  17. 1 0
      src/components/DashBoard/index.less
  18. 5 0
      src/components/ProTableCard/index.tsx
  19. 29 3
      src/components/SearchComponent/index.tsx
  20. 44 29
      src/pages/device/DashBoard/index.tsx
  21. 14 2
      src/pages/home/components/BaseStatistics.tsx
  22. 6 3
      src/pages/home/components/CardStatics.tsx
  23. 6 1
      src/pages/home/components/GuideHome.tsx
  24. 22 4
      src/pages/home/components/Pie.tsx
  25. 2 0
      src/pages/home/components/index.less
  26. 11 6
      src/pages/home/comprehensive/index.tsx
  27. 2 2
      src/pages/iot-card/Dashboard/index.tsx
  28. 6 1
      src/pages/iot-card/Home/index.tsx
  29. 16 1
      src/pages/media/DashBoard/index.tsx
  30. 3 0
      src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx
  31. 8 5
      src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx
  32. 2 2
      src/pages/rule-engine/Scene/Save/components/TimingTrigger/index.tsx
  33. 4 40
      src/pages/rule-engine/Scene/Save/device/addModel.tsx
  34. 1 1
      src/pages/rule-engine/Scene/Save/device/index.tsx
  35. 15 4
      src/pages/rule-engine/Scene/Save/device/type.tsx
  36. 13 5
      src/pages/rule-engine/Scene/Save/terms/index.tsx
  37. 46 13
      src/pages/rule-engine/Scene/Save/timer/TimerTrigger/index.tsx

BIN
public/images/device/device-number.png


BIN
public/images/device/device-product.png


BIN
public/images/home/bottom-1.png


BIN
public/images/home/bottom-10.png


BIN
public/images/home/bottom-11.png


BIN
public/images/home/bottom-4.png


BIN
public/images/home/bottom-9.png


BIN
public/images/home/content1.png


BIN
public/images/home/top-1.png


BIN
public/images/home/top-2.png


Fichier diff supprimé car celui-ci est trop grand
+ 3 - 0
public/images/home/top-3.svg


Fichier diff supprimé car celui-ci est trop grand
+ 3 - 0
public/images/home/top-4.svg


BIN
public/images/media/dashboard-1.png


BIN
public/images/media/dashboard-2.png


BIN
public/images/media/dashboard-3.png


BIN
public/images/media/dashboard-4.png


+ 1 - 0
src/components/DashBoard/index.less

@@ -13,6 +13,7 @@
 }
 
 .title {
+  margin: auto;
   font-weight: bold;
   font-size: 16px;
 }

+ 5 - 0
src/components/ProTableCard/index.tsx

@@ -63,6 +63,7 @@ const ProTableCard = <
   const [dataLength, setDataLength] = useState<number>(0);
 
   const domRef = useRef<HTMLDivElement>(null);
+  const cardItemsRef = useRef<HTMLDivElement>(null);
   const { minHeight } = useDomFullHeight(domRef);
 
   /**
@@ -125,6 +126,7 @@ const ProTableCard = <
             <div style={{ paddingBottom: 38 }}>
               <div
                 className={classNames('pro-table-card-items', props.cardBodyClass)}
+                ref={cardItemsRef}
                 style={{ gridTemplateColumns: `repeat(${column}, 1fr)`, ...style }}
               >
                 {dataSource.map((item) =>
@@ -173,6 +175,9 @@ const ProTableCard = <
     setPageIndex(_current - 1);
     setPageSize(size);
     props.onPageChange?.(_current - 1, size);
+    if (cardItemsRef.current) {
+      cardItemsRef.current.scrollTop = 0;
+    }
   };
 
   useEffect(() => {

+ 29 - 3
src/components/SearchComponent/index.tsx

@@ -211,6 +211,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
               if (isModified) {
                 f.setFieldState(typeFiled.query('.termType'), async (state) => {
                   state.value = 'eq';
+                  state.dataSource = termType;
                 });
               }
               f.setFieldState(typeFiled.query('.value'), async (state) => {
@@ -228,6 +229,19 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   let __option: { label: any; value: any }[] | FieldDataSource | undefined = [];
                   f.setFieldState(typeFiled.query('.termType'), async (state) => {
                     state.value = 'eq';
+                    state.dataSource = termType;
+                    if (_field?.dataIndex === 'state') {
+                      state.dataSource = [
+                        { label: '=', value: 'eq' },
+                        { label: '!=', value: 'not' },
+                        { label: '>', value: 'gt' },
+                        { label: '>=', value: 'gte' },
+                        { label: '<', value: 'lt' },
+                        { label: '<=', value: 'lte' },
+                        { label: '属于', value: 'in' },
+                        { label: '不属于', value: 'nin' },
+                      ];
+                    }
                   });
                   if (_field?.valueEnum) {
                     __option = Object.values(_field?.valueEnum || {}).map((item) => ({
@@ -240,6 +254,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   if (isModified) {
                     f.setFieldState(typeFiled.query('.termType'), async (state) => {
                       state.value = 'eq';
+                      state.dataSource = termType;
                     });
                   }
 
@@ -267,6 +282,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   if (isModified) {
                     f.setFieldState(typeFiled.query('.termType'), (_state) => {
                       _state.value = 'eq';
+                      _state.dataSource = termType;
                     });
                   }
 
@@ -291,6 +307,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   if (isModified) {
                     f.setFieldState(typeFiled.query('.termType'), async (state) => {
                       state.value = 'eq';
+                      state.dataSource = termType;
                     });
                   }
 
@@ -301,12 +318,20 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                     state.componentProps = { showTime: true, allowClear: true };
                   });
                   f.setFieldState(typeFiled.query('.termType'), async (state) => {
-                    state.value = 'eq';
+                    state.value = 'gt';
+                    state.dataSource = [
+                      { label: '>', value: 'gt' },
+                      { label: '<', value: 'lt' },
+                    ];
                   });
                   // console.log(isModified);
                   if (isModified) {
                     f.setFieldState(typeFiled.query('.termType'), async (state) => {
-                      state.value = 'eq';
+                      state.value = 'gt';
+                      state.dataSource = [
+                        { label: '>', value: 'gt' },
+                        { label: '<', value: 'lt' },
+                      ];
                     });
                   }
 
@@ -315,6 +340,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   if (isModified) {
                     f.setFieldState(typeFiled.query('.termType'), async (state) => {
                       state.value = 'like';
+                      state.dataSource = termType;
                     });
                   }
 
@@ -336,7 +362,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
           });
         },
       }),
-    [target, expand],
+    [target, expand, initParams],
   );
 
   const historyForm = createForm();

+ 44 - 29
src/pages/device/DashBoard/index.tsx

@@ -130,8 +130,9 @@ const DeviceBoard = () => {
             name: '在线数',
             data: y.reverse(),
             type: 'bar',
+            showBackground: true,
             itemStyle: {
-              color: '#2F54EB',
+              color: '#D3ADF7',
             },
           },
         ],
@@ -214,8 +215,9 @@ const DeviceBoard = () => {
             name: '消息量',
             data: y,
             type: 'line',
-            smooth: true,
-            color: '#685DEB',
+            smooth: true, // 是否平滑曲线
+            symbolSize: 0, // 拐点大小
+            color: '#F29B55',
             areaStyle: {
               color: {
                 type: 'linear',
@@ -226,7 +228,7 @@ const DeviceBoard = () => {
                 colorStops: [
                   {
                     offset: 0,
-                    color: '#685DEB', // 100% 处的颜色
+                    color: '#FBBB87', // 100% 处的颜色
                   },
                   {
                     offset: 1,
@@ -285,6 +287,9 @@ const DeviceBoard = () => {
         .map((item: any) => (_time === '1h' ? `${item.data.timeString}时` : item.data.timeString))
         .reverse();
       const y = res.result.map((item: any) => item.data.value).reverse();
+      const maxY = Math.max.apply(null, y.length ? y : [0]);
+      // const sum = y.reduce((acc, cur) => acc + cur, 0)
+      // const percentageY = y.map(item => parseFloat(((item / sum) * 100).toFixed(2)));
       setOptions({
         xAxis: {
           type: 'category',
@@ -296,43 +301,53 @@ const DeviceBoard = () => {
         },
         tooltip: {
           trigger: 'axis',
-          // axisPointer: {
-          //   type: 'shadow',
-          // },
+          formatter: '{b0}<br />{a0}: {c0}',
+          // formatter: '{b0}<br />{a0}: {c0}<br />{a1}: {c1}%'
         },
         grid: {
           top: '2%',
           bottom: '5%',
-          left: '50px',
+          left: maxY > 100000 ? '90px' : '50px',
           right: '50px',
         },
         series: [
           {
             name: '消息量',
             data: y,
+            type: 'bar',
+            // type: 'line',
+            // smooth: true,
+            color: '#597EF7',
+            barWidth: '30%',
+            // areaStyle: {
+            //   color: {
+            //     type: 'linear',
+            //     x: 0,
+            //     y: 0,
+            //     x2: 0,
+            //     y2: 1,
+            //     colorStops: [
+            //       {
+            //         offset: 0,
+            //         color: '#685DEB', // 100% 处的颜色
+            //       },
+            //       {
+            //         offset: 1,
+            //         color: '#FFFFFF', //   0% 处的颜色
+            //       },
+            //     ],
+            //     global: false, // 缺省为 false
+            //   },
+            // },
+          },
+          {
+            name: '占比',
+            data: y,
+            // data: percentageY,
             type: 'line',
             smooth: true,
-            color: '#685DEB',
-            areaStyle: {
-              color: {
-                type: 'linear',
-                x: 0,
-                y: 0,
-                x2: 0,
-                y2: 1,
-                colorStops: [
-                  {
-                    offset: 0,
-                    color: '#685DEB', // 100% 处的颜色
-                  },
-                  {
-                    offset: 1,
-                    color: '#FFFFFF', //   0% 处的颜色
-                  },
-                ],
-                global: false, // 缺省为 false
-              },
-            },
+            symbolSize: 0, // 拐点大小
+            color: '#96ECE3',
           },
         ],
       });

+ 14 - 2
src/pages/home/components/BaseStatistics.tsx

@@ -53,12 +53,24 @@ const BaseStatistics = () => {
         {
           name: 'CPU使用率',
           value: String(cpuValue) + '%',
-          children: <Pie value={cpuValue} />,
+          children: (
+            <Pie
+              value={cpuValue}
+              color={['#EBEBEB', '#D3ADF7']}
+              image={require('/public/images/home/top-3.svg')}
+            />
+          ),
         },
         {
           name: 'JVM内存',
           value: String(jvmValue) + '%',
-          children: <Pie value={jvmValue} />,
+          children: (
+            <Pie
+              value={jvmValue}
+              color={['#D6E4FF', '#85A5FF']}
+              image={require('/public/images/home/top-4.svg')}
+            />
+          ),
         },
       ]}
       title="基础统计"

+ 6 - 3
src/pages/home/components/CardStatics.tsx

@@ -29,9 +29,9 @@ const CardStatistics = (props: StatisticsProps) => {
           <div className={'home-guide-item'} key={item.name}>
             <div className={'item-english'}>{item.name}</div>
             {item.node ? (
-              <div style={{ display: 'flex', marginTop: 15, width: '60%' }}>
+              <div style={{ display: 'flex', marginTop: 15, width: '80%' }}>
                 {item.node.map((i: any) => (
-                  <div style={{ marginRight: 7 }}>
+                  <div key={i.name + i.value} style={{ minWidth: 58, marginRight: 8, zIndex: 1 }}>
                     <div style={{ fontSize: '14px', fontWeight: 'bold' }}>{i.value}</div>
                     <div className={`state ${i.className}`}>{i.name}</div>
                   </div>
@@ -46,7 +46,10 @@ const CardStatistics = (props: StatisticsProps) => {
                 <img src={item.children || defaultImage} />
               </div>
             ) : (
-              <div className={'item-index-echarts'} style={{ height: 75, width: 110 }}>
+              <div
+                className={'item-index-echarts'}
+                style={item.style || { height: 75, width: 110 }}
+              >
                 {item.children}
               </div>
             )}

+ 6 - 1
src/pages/home/components/GuideHome.tsx

@@ -40,7 +40,12 @@ const GuideItem = (props: GuideItemProps) => {
     <div
       className={'home-guide-item step-bar pointer'}
       onClick={jumpPage}
-      style={{ marginTop: 12, padding: 10, border: '1px solid #eee' }}
+      style={{
+        marginTop: 12,
+        padding: 10,
+        border: '1px solid #eee',
+        borderLeft: '2px solid #85a5ff',
+      }}
     >
       <div style={{ display: 'flex', alignItems: 'center' }}>
         <div>

+ 22 - 4
src/pages/home/components/Pie.tsx

@@ -4,23 +4,41 @@ import type { EChartsOption } from 'echarts';
 
 interface Props {
   value: number;
+  color: array;
+  image: string;
 }
 
 const Pie = (props: Props) => {
   const [options, setOptions] = useState<EChartsOption>({});
-
   useEffect(() => {
     setOptions({
-      color: ['#2F54EB', '#979AFF'],
+      color: props.color || ['#D3ADF7', '#979AFF'],
+      graphic: [
+        {
+          type: 'image',
+          style: {
+            image: props.image || '',
+            width: 16,
+            height: 16,
+          },
+          left: 'center',
+          top: '41%',
+        },
+      ],
       series: [
         {
           type: 'pie',
-          radius: ['100%', '50%'],
+          radius: ['100%', '60%'],
           center: ['50%', '50%'],
           label: {
             show: false,
           },
-          data: [props.value, 100 - props.value],
+          data: [100 - props.value, props.value],
+          itemStyle: {
+            // borderRadius: 10,
+            borderColor: '#fff',
+            borderWidth: 2,
+          },
         },
       ],
     });

+ 2 - 0
src/pages/home/components/index.less

@@ -76,6 +76,7 @@
 
     right: 12px;
     bottom: 5%;
+    z-index: 0;
     width: 50%;
   }
 }
@@ -117,6 +118,7 @@
   margin-bottom: @margin;
   padding-bottom: 26.5%;
   overflow: hidden;
+  border-bottom: 1px solid #2f54eb;
 
   .home-body-img {
     position: absolute;

+ 11 - 6
src/pages/home/comprehensive/index.tsx

@@ -156,7 +156,7 @@ const Comprehensive = () => {
                 {
                   name: '设备数量',
                   value: deviceCount,
-                  children: '',
+                  children: require('/public/images/home/top-1.png'),
                   permission: deviceMessage,
                 },
               ]}
@@ -206,6 +206,7 @@ const Comprehensive = () => {
           data={[
             {
               title: '创建产品',
+              url: require('/public/images/home/bottom-4.png'),
               content:
                 '产品是设备的集合,通常指一组具有相同功能的设备。物联设备必须通过产品进行接入方式配置。',
               onClick: () => {
@@ -221,6 +222,7 @@ const Comprehensive = () => {
             },
             {
               title: '配置产品接入方式',
+              url: require('/public/images/home/bottom-1.png'),
               content:
                 '通过产品对同一类型的设备进行统一的接入方式配置。请参照设备铭牌说明选择匹配的接入方式。',
               onClick: () => {
@@ -233,6 +235,7 @@ const Comprehensive = () => {
             },
             {
               title: '添加测试设备',
+              url: require('/public/images/home/bottom-5.png'),
               content: '添加单个设备,用于验证产品模型是否配置正确。',
               onClick: () => {
                 const path = getMenuPathByCode('device/Instance');
@@ -247,6 +250,7 @@ const Comprehensive = () => {
             },
             {
               title: '功能调试',
+              url: require('/public/images/home/bottom-2.png'),
               content: '对添加的测试设备进行功能调试,验证能否连接到平台,设备功能是否配置正确。',
               onClick: () => {
                 if (!!devicePermission.update) {
@@ -258,6 +262,7 @@ const Comprehensive = () => {
             },
             {
               title: '批量添加设备',
+              url: require('/public/images/home/bottom-3.png'),
               content: '批量添加同一产品下的设备',
               onClick: () => {
                 const path = getMenuPathByCode('device/Instance');
@@ -286,8 +291,8 @@ const Comprehensive = () => {
           data={[
             {
               title: '协议管理',
+              url: require('/public/images/home/bottom-9.png'),
               content: '根据业务需求自定义开发对应的产品(设备模型)接入协议,并上传到平台。',
-              url: require('/public/images/home/bottom-1.png'),
               onClick: () => {
                 const url = getMenuPathByCode(MENUS_CODE['link/Protocol']);
                 if (!!url) {
@@ -299,8 +304,8 @@ const Comprehensive = () => {
             },
             {
               title: '证书管理',
+              url: require('/public/images/home/bottom-9.png'),
               content: '统一维护平台内的证书,用于数据通信加密。',
-              url: require('/public/images/home/bottom-6.png'),
               onClick: () => {
                 const url = getMenuPathByCode(MENUS_CODE['link/Certificate']);
                 if (!!url) {
@@ -313,7 +318,7 @@ const Comprehensive = () => {
             {
               title: '网络组件',
               content: '根据不同的传输类型配置平台底层网络组件相关参数。',
-              url: require('/public/images/home/bottom-3.png'),
+              url: require('/public/images/home/bottom-10.png'),
               onClick: () => {
                 const url = getMenuPathByCode(MENUS_CODE['link/Type']);
                 if (!!url) {
@@ -326,7 +331,7 @@ const Comprehensive = () => {
             {
               title: '设备接入网关',
               content: '根据不同的传输类型,关联消息协议,配置设备接入网关相关参数。',
-              url: require('/public/images/home/bottom-4.png'),
+              url: require('/public/images/home/bottom-11.png'),
               onClick: () => {
                 const url = getMenuPathByCode(MENUS_CODE['link/AccessConfig']);
                 if (!!url) {
@@ -339,7 +344,7 @@ const Comprehensive = () => {
             {
               title: '日志管理',
               content: '监控系统日志,及时处理系统异常。',
-              url: require('/public/images/home/bottom-5.png'),
+              url: require('/public/images/home/bottom-9.png'),
               onClick: () => {
                 const url = getMenuPathByCode(MENUS_CODE['Log']);
                 if (!!url) {

+ 2 - 2
src/pages/iot-card/Dashboard/index.tsx

@@ -344,8 +344,8 @@ const Dashboard = () => {
           />
         </div>
         <div className={styles['total-echarts-right']}>
-          <div className={styles.topName} style={{ height: 50 }}>
-            <span>流量使用TOP10</span>
+          <div className={styles.topName} style={{ height: 32 }}>
+            <span style={{ marginTop: 3.5 }}>流量使用TOP10</span>
             <div>
               {
                 // @ts-ignore

+ 6 - 1
src/pages/iot-card/Home/index.tsx

@@ -191,6 +191,10 @@ export default () => {
                 name: '物联卡',
                 value: 0,
                 node: pieChartData.current,
+                style: {
+                  width: 70,
+                  height: 70,
+                },
                 children: <Echarts options={cardOptions} />,
               },
             ]}
@@ -211,7 +215,8 @@ export default () => {
             }
           />
         </Col>
-        <Col span={24} style={{ backgroundColor: 'white', minHeight: 580 }}>
+        <Col span={24} style={{ minHeight: 580 }}>
+          {/* <Col span={24} style={{ backgroundColor: 'white', minHeight: 580 }}> */}
           <Body
             className="bottomImg"
             title={'平台架构图'}

+ 16 - 1
src/pages/media/DashBoard/index.tsx

@@ -131,6 +131,9 @@ export default () => {
           sData.push(item.data.value);
         });
 
+      const maxY = Math.max.apply(null, sData.length ? sData : [0]);
+      // const sum = sData.reduce((acc, cur) => acc + cur, 0)
+      // const percentageY = sData.map(item => parseFloat(((item / sum) * 100).toFixed(2)));
       setOptions({
         xAxis: {
           type: 'category',
@@ -138,13 +141,15 @@ export default () => {
         },
         tooltip: {
           trigger: 'axis',
+          formatter: '{b0}<br />{a0}: {c0}',
         },
         yAxis: {
           type: 'value',
           // minInterval: 1,
         },
         grid: {
-          left: 50,
+          // left: 50,
+          left: maxY > 100000 ? 90 : 50,
           right: 0,
           top: '2%',
           bottom: 20,
@@ -152,10 +157,20 @@ export default () => {
         color: ['#2F54EB'],
         series: [
           {
+            name: '播放数量(人次)',
             data: sData,
             type: 'bar',
             barWidth: 16,
           },
+          {
+            name: '占比',
+            data: sData,
+            // data: percentageY,
+            type: 'line',
+            smooth: true,
+            symbolSize: 0, // 拐点大小
+            color: '#96ECE3',
+          },
         ],
       });
     }

+ 3 - 0
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -353,6 +353,9 @@ export default (props: ItemProps) => {
 
   useEffect(() => {
     getParams();
+    return () => {
+      setParamsOptions([]);
+    };
   }, []);
 
   return (

+ 8 - 5
src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx

@@ -283,12 +283,15 @@ export default (props: ParamsDropdownProps) => {
     <ParamsSelect
       value={myValue}
       onChange={(value, source) => {
-        console.log(value, source);
         setActiveKey(source);
-        // props.onChange?.({
-        //   value,
-        //   source
-        // }, label )
+        // onValueChange(undefined, '')
+        setMyValue(undefined);
+        setLabel('');
+        const changeValue = {
+          value: value,
+          source: source,
+        };
+        props.onChange?.(changeValue, '', {});
       }}
       tabKey={activeKey}
       itemList={_itemList}

+ 2 - 2
src/pages/rule-engine/Scene/Save/components/TimingTrigger/index.tsx

@@ -140,8 +140,8 @@ export default (props: TimmingTriggerProps) => {
             <Form.Item
               name={[...name, 'period']}
               initialValue={{
-                from: moment(new Date()).format('HH:mm:ss'),
-                to: moment(new Date()).format('HH:mm:ss'),
+                from: moment(new Date()).startOf('day').format('HH:mm:ss'),
+                to: moment(new Date()).endOf('day').format('HH:mm:ss'),
               }}
             >
               <RangePicker name={[...name, 'period']} form={form} />

+ 4 - 40
src/pages/rule-engine/Scene/Save/device/addModel.tsx

@@ -7,11 +7,11 @@ import type { TriggerDevice, TriggerDeviceOptions } from '@/pages/rule-engine/Sc
 import Product from './product';
 import Device from './device';
 import Type from './type';
-import { numberToString } from '../components/TimingTrigger/whenOption';
 import { timeUnitEnum } from '../components/TimingTrigger';
 import { Store } from 'jetlinks-store';
 import { FormModel } from '@/pages/rule-engine/Scene/Save';
-import { isArray, isEqual } from 'lodash';
+import { isEqual } from 'lodash';
+import { continuousValue } from '@/pages/rule-engine/Scene/Save/timer/TimerTrigger';
 
 interface AddProps {
   options?: any;
@@ -20,42 +20,6 @@ interface AddProps {
   onSave?: (data: TriggerDevice, options: any) => void;
 }
 
-type continuousValueFn = (data: (string | number)[], type: string) => (number | string)[];
-
-const continuousValue: continuousValueFn = (data, type) => {
-  let start = 0;
-  const newArray: (number | string)[] = [];
-  const isWeek = type === 'week';
-  if (isArray(data)) {
-    data.forEach((item, index) => {
-      const _item = Number(item);
-      const nextValue = data[index + 1];
-      const previousValue = data[index - 1];
-      const nextItemValue = _item + 1;
-      const previousItemValue = _item - 1;
-      if (nextItemValue === nextValue && previousItemValue !== previousValue) {
-        start = _item;
-      } else if (previousItemValue === previousValue && nextItemValue !== nextValue) {
-        // 表示前start和item连续,并且item与nextValue不连续
-        if (_item - start >= 2) {
-          // 至少三位连续
-          newArray.push(
-            isWeek
-              ? `${numberToString[start]} - ${numberToString[_item]}`
-              : `${start} - ${_item}号`,
-          );
-        } else {
-          newArray.push(isWeek ? numberToString[start] : `${start}号`);
-          newArray.push(isWeek ? numberToString[_item] : `${_item}号`);
-        }
-      } else if (previousItemValue !== previousValue && nextItemValue !== nextValue) {
-        newArray.push(isWeek ? numberToString[_item] : `${_item}号`);
-      }
-    });
-  }
-  return newArray;
-};
-
 export interface DeviceModelProps extends Partial<TriggerDevice> {
   steps: { key: string; title: string }[];
   stepNumber: number;
@@ -220,8 +184,8 @@ export default observer((props: AddProps) => {
         if (_timer.when!.length) {
           whenStr = _timer!.trigger === 'week' ? '每周' : '每月';
           const whenStrArr = continuousValue(_timer.when! || [], _timer!.trigger);
-          whenStrArr.length = 3;
-          whenStr += whenStrArr.join('、');
+          const whenStrArr3 = whenStrArr.splice(0, 3);
+          whenStr += whenStrArr3.join('、');
           whenStr += `等${_timer.when!.length}天`;
         }
         _options.when = whenStr;

+ 1 - 1
src/pages/rule-engine/Scene/Save/device/index.tsx

@@ -33,7 +33,7 @@ export default observer((props: Props) => {
       service.detail(FormModel.current.trigger!.device?.productId).then((res) => {
         if (res.status === 200) {
           TriggerDeviceModel.productDetail = res.result;
-          handleMetadata(res.result.metadata);
+          handleMetadata(res.result?.metadata);
         } else {
           Store.set('TriggerDeviceModel', {
             update: true,

+ 15 - 4
src/pages/rule-engine/Scene/Save/device/type.tsx

@@ -222,11 +222,22 @@ export default forwardRef((props: Props, ref) => {
                   onChange={(v: any, propertyItems: any[]) => {
                     const names = propertyItems.map((item) => item.name);
                     let extraStr = '';
-                    if (names.length >= 2) {
-                      names.length = 2;
-                      extraStr = `等${propertyItems.length}个属性`;
+                    let isLimit = false;
+                    let indexOf = 0;
+                    extraStr = names.reduce((_prev, next, index) => {
+                      if (_prev.length <= 30) {
+                        indexOf = index;
+                        return index === 0 ? next : _prev + '、' + next;
+                      } else {
+                        isLimit = true;
+                      }
+                      return _prev;
+                    }, '');
+
+                    if (isLimit && names.length - 1 > indexOf) {
+                      extraStr += `等${propertyItems.length}个属性`;
                     }
-                    TriggerDeviceModel.options.action = `读取 ${names.join('、')}${extraStr}`;
+                    TriggerDeviceModel.options.action = `读取 ${extraStr}`;
                   }}
                 />
               </Form.Item>

+ 13 - 5
src/pages/rule-engine/Scene/Save/terms/index.tsx

@@ -148,11 +148,19 @@ export default observer((props: Props) => {
                     FormModel.current.options?.when?.splice(index, 1);
                   }}
                   onDeleteAll={() => {
-                    FormModel.current.branches?.splice(
-                      index,
-                      FormModel.current.branches!.length - 1,
-                      null as any,
-                    );
+                    const newBranches: any[] =
+                      FormModel.current.branches?.filter((bItem, bIndex) => {
+                        return bIndex === 0 || (bItem && bItem.key === item.key);
+                      }) || [];
+                    newBranches.push(null);
+                    console.log(FormModel.current.options?.when);
+                    FormModel.current.branches = newBranches;
+                    if (FormModel.current.options?.when) {
+                      FormModel.current.options.when = [
+                        FormModel.current.options?.when[0],
+                        FormModel.current.options?.when[index],
+                      ];
+                    }
                   }}
                 />
               ) : (

+ 46 - 13
src/pages/rule-engine/Scene/Save/timer/TimerTrigger/index.tsx

@@ -5,6 +5,7 @@ import TimingTrigger, {
 } from '@/pages/rule-engine/Scene/Save/components/TimingTrigger';
 import { numberToString } from '@/pages/rule-engine/Scene/Save/components/TimingTrigger/whenOption';
 import { useEffect } from 'react';
+import { isArray } from 'lodash';
 
 interface Props {
   close: () => void;
@@ -12,6 +13,42 @@ interface Props {
   save: (data: OperationTimer, options: any) => void;
 }
 
+type continuousValueFn = (data: (string | number)[], type: string) => (number | string)[];
+
+export const continuousValue: continuousValueFn = (data, type) => {
+  let start = 0;
+  const newArray: (number | string)[] = [];
+  const isWeek = type === 'week';
+  if (isArray(data)) {
+    data.forEach((item, index) => {
+      const _item = Number(item);
+      const nextValue = data[index + 1];
+      const previousValue = data[index - 1];
+      const nextItemValue = _item + 1;
+      const previousItemValue = _item - 1;
+      if (nextItemValue === nextValue && previousItemValue !== previousValue) {
+        start = _item;
+      } else if (previousItemValue === previousValue && nextItemValue !== nextValue) {
+        // 表示前start和item连续,并且item与nextValue不连续
+        if (_item - start >= 2) {
+          // 至少三位连续
+          newArray.push(
+            isWeek
+              ? `${numberToString[start]} - ${numberToString[_item]}`
+              : `${start} - ${_item}号`,
+          );
+        } else {
+          newArray.push(isWeek ? numberToString[start] : `${start}号`);
+          newArray.push(isWeek ? numberToString[_item] : `${_item}号`);
+        }
+      } else if (previousItemValue !== previousValue && nextItemValue !== nextValue) {
+        newArray.push(isWeek ? numberToString[_item] : `${_item}号`);
+      }
+    });
+  }
+  return newArray;
+};
+
 export default (props: Props) => {
   const [form] = Form.useForm();
 
@@ -32,19 +69,15 @@ export default (props: Props) => {
     if (_timer.trigger === 'cron') {
       _options.time = _timer.cron;
     } else {
-      _options.when =
-        _timer.when!.length === 0
-          ? '每天'
-          : `每${_timer
-              .when!.map((item) => {
-                if (_timer!.trigger === 'week') {
-                  return numberToString[item];
-                } else {
-                  return item + '号';
-                }
-              })
-              .join(',')}`;
-
+      let whenStr = '每天';
+      if (_timer.when!.length) {
+        whenStr = _timer!.trigger === 'week' ? '每周' : '每月';
+        const whenStrArr = continuousValue(_timer.when! || [], _timer!.trigger);
+        const whenStrArr3 = whenStrArr.splice(0, 3);
+        whenStr += whenStrArr3.join('、');
+        whenStr += `等${_timer.when!.length}天`;
+      }
+      _options.when = whenStr;
       if (_timer.once) {
         _options.time = _timer.once.time + ' 执行1次';
       } else if (_timer.period) {