Sfoglia il codice sorgente

fix: 优化设备通道左侧树样式

xieyonghong 3 anni fa
parent
commit
33094dc8e8

+ 0 - 4
src/pages/media/Device/Channel/Tree/index.less

@@ -1,9 +1,5 @@
 .channel-tree {
   height: 100%;
-  margin-right: 16px;
-  padding: 20px;
-  background-color: #fff;
-  border-radius: 2px;
 
   .channel-tree-query {
     margin-bottom: 16px;

+ 2 - 0
src/pages/media/Device/Channel/Tree/index.tsx

@@ -9,6 +9,7 @@ import { debounce } from 'lodash';
 interface TreeProps {
   deviceId: string;
   onSelect: (id: React.Key) => void;
+  onTreeLoad: (type: boolean) => void;
 }
 
 export default (props: TreeProps) => {
@@ -19,6 +20,7 @@ export default (props: TreeProps) => {
     formatResult: (res) => res.result,
     onSuccess: (res) => {
       treeData[0].children = res.result || [];
+      props.onTreeLoad(treeData[0].children.length > 10);
       setTreeData(treeData);
     },
   });

+ 39 - 2
src/pages/media/Device/Channel/index.less

@@ -1,8 +1,45 @@
 .device-channel-warp {
   display: flex;
 
-  .left {
-    width: 300px;
+  .left-warp {
+    position: relative;
+    margin-right: 16px;
+    padding: 20px;
+    background-color: #fff;
+    border-radius: 2px;
+
+    .left-content {
+      width: 0;
+      height: 100%;
+      overflow: hidden;
+
+      &.active {
+        width: 260px;
+      }
+    }
+
+    .left-warp--btn {
+      position: absolute;
+      top: 50%;
+      right: 0;
+      padding: 20px 4px;
+      color: rgba(#000, 0.3);
+      background-color: rgba(#f0f0f0, 6);
+      border-radius: ~'100% 0 0 100% / 50% 0 0 50%';
+      cursor: pointer;
+
+      &:hover {
+        color: rgba(#000, 0.5);
+        background-color: rgba(#f0f0f0, 8);
+      }
+
+      &.active {
+        right: 50%;
+        background-color: transparent;
+        border-radius: 0;
+        transform: translateX(50%) rotate(180deg);
+      }
+    }
   }
 
   .right {

+ 31 - 17
src/pages/media/Device/Channel/index.tsx

@@ -13,6 +13,7 @@ import {
   DeleteOutlined,
   EditOutlined,
   PlusOutlined,
+  LeftOutlined,
   VideoCameraAddOutlined,
   VideoCameraOutlined,
 } from '@ant-design/icons';
@@ -23,6 +24,7 @@ import Live from './Live';
 import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import Tree from './Tree';
 import { useDomFullHeight } from '@/hooks';
+import classnames from 'classnames';
 
 export const service = new Service('media');
 
@@ -37,6 +39,7 @@ export default () => {
   const [channelId, setChannelId] = useState('');
   const [type, setType] = useState('');
   const { minHeight } = useDomFullHeight(`.channelDevice`, 24);
+  const [show, setShow] = useState(false);
 
   const location = useLocation();
   const history = useHistory();
@@ -210,24 +213,35 @@ export default () => {
     <PageContainer>
       <div className={'device-channel-warp'}>
         {type === ProviderValue.GB281 && (
-          <div className={'left'}>
-            <Tree
-              deviceId={deviceId}
-              onSelect={(key) => {
-                if (key === deviceId && actionRef.current?.reset) {
-                  actionRef.current?.reset();
-                } else {
-                  setQueryParam({
-                    terms: [
-                      {
-                        column: 'parentId',
-                        value: key,
-                      },
-                    ],
-                  });
-                }
+          <div className={classnames('left-warp')}>
+            <div className={classnames('left-content', { active: show })}>
+              <Tree
+                deviceId={deviceId}
+                onSelect={(key) => {
+                  if (key === deviceId && actionRef.current?.reset) {
+                    actionRef.current?.reset();
+                  } else {
+                    setQueryParam({
+                      terms: [
+                        {
+                          column: 'parentId',
+                          value: key,
+                        },
+                      ],
+                    });
+                  }
+                }}
+                onTreeLoad={setShow}
+              />
+            </div>
+            <div
+              className={classnames('left-warp--btn', { active: !show })}
+              onClick={() => {
+                setShow(!show);
               }}
-            />
+            >
+              <LeftOutlined />
+            </div>
           </div>
         )}
         <div className={'right'}>

+ 72 - 113
src/pages/rule-engine/Scene/Save/action/VariableItems/user.tsx

@@ -1,13 +1,14 @@
 // 收信人
 import { useEffect, useState } from 'react';
 import { ItemGroup } from '@/pages/rule-engine/Scene/Save/components';
-import { Input, Select } from 'antd';
+import { Input, Select, TreeSelect } from 'antd';
 import {
   queryDingTalkUsers,
   queryPlatformUsers,
   queryRelationUsers,
   queryWechatUsers,
 } from '@/pages/rule-engine/Scene/Save/action/service';
+import { forkJoin, filter, from, defer, map } from 'rxjs';
 
 type ChangeType = {
   source?: string;
@@ -26,8 +27,11 @@ interface UserProps {
 export default (props: UserProps) => {
   const [source, setSource] = useState(props.value?.source);
   const [value, setValue] = useState<string | undefined>();
-  const [userList, setUserList] = useState({ platform: [], relation: [] });
   const [relationList, setRelationList] = useState([]);
+  const [treeData, setTreeData] = useState([
+    { name: '平台用户', id: 'p1', selectable: false, children: [] },
+    { name: '关系用户', id: 'p2', selectable: false, children: [] },
+  ]);
 
   useEffect(() => {
     setSource(props.value?.source);
@@ -48,31 +52,26 @@ export default (props: UserProps) => {
   }, [props.value]);
 
   const getPlatformUser = async () => {
-    const _userList: any = {
-      platform: [],
-      relation: [],
-    };
-    const resp1 = await queryPlatformUsers();
-    if (resp1.status === 200) {
-      _userList.platform = resp1.result.map((item: any) => ({
-        label: item.name,
-        value: item.id,
-        username: item.username,
-      }));
-    }
-
-    const resp2 = await queryRelationUsers();
-    if (resp2.status === 200) {
-      _userList.relation = resp2.result.map((item: any) => ({
-        label: item.name,
-        value: item.relation,
-        username: '',
-      }));
-    }
-
-    setUserList(_userList);
+    forkJoin(
+      defer(() => from(queryPlatformUsers())).pipe(
+        filter((item) => item.status === 200),
+        map((resp) => resp.result),
+      ),
+      defer(() => from(queryRelationUsers())).pipe(
+        filter((item) => item.status === 200),
+        map((resp) => resp.result),
+      ),
+    ).subscribe((res) => {
+      const newTree = [...treeData];
+      res.forEach((item, index) => {
+        newTree[index].children = item;
+      });
+      setTreeData(newTree);
+    });
   };
 
+  console.log('treeData', treeData);
+
   const getRelationUsers = async (notifyType: string, configId: string) => {
     if (notifyType === 'dingTalk') {
       const resp = await queryDingTalkUsers(configId);
@@ -170,55 +169,56 @@ export default (props: UserProps) => {
     } else {
       obj.value = _value;
     }
-    console.log(obj);
+
     if (props.onChange) {
       props.onChange(obj);
     }
   };
 
   const filterOption = (input: string, option: any) => {
-    return option.label ? option.label.toLowerCase().includes(input.toLowerCase()) : false;
+    return option.name ? option.name.toLowerCase().includes(input.toLowerCase()) : false;
+  };
+
+  const createTreeNode = (data: any): React.ReactNode => {
+    return data.map((item: any) => {
+      if (item.children) {
+        return (
+          <TreeSelect.TreeNode value={item.id} title={item.name} selectable={false}>
+            {createTreeNode(item.children)}
+          </TreeSelect.TreeNode>
+        );
+      } else {
+        return (
+          <TreeSelect.TreeNode
+            name={item.name}
+            value={item.id}
+            title={
+              <div style={{ display: 'flex', justifyContent: 'space-between' }}>
+                <span>{item.name}</span>
+                <span style={{ color: '#cfcfcf' }}>{item.username}</span>
+              </div>
+            }
+          />
+        );
+      }
+    });
   };
 
   const userSelect =
     source === 'relation' ? (
-      <Select
+      <TreeSelect
         showSearch
         value={value}
-        onChange={(key, node) => {
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        placeholder={'请选择收信人'}
+        onSelect={(key: any, node: any) => {
           setValue(key);
           onchange(source, key, node.isRelation);
         }}
-        placeholder={'请选择收信人'}
-        listHeight={200}
-        filterOption={filterOption}
-        optionLabelProp="label"
+        filterTreeNode={filterOption}
       >
-        {userList.platform.length ? (
-          <Select.OptGroup label={'平台用户'}>
-            {userList.platform.map((item: any) => (
-              <Select.Option value={item.value} isRelation={false} label={item.label}>
-                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-                  <span>{item.label}</span>
-                  <span style={{ color: '#cfcfcf' }}>{item.username}</span>
-                </div>
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-        {userList.relation.length ? (
-          <Select.OptGroup label={'关系用户'}>
-            {userList.relation.map((item: any) => (
-              <Select.Option value={item.value} isRelation={false} label={item.label}>
-                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-                  <span>{item.label}</span>
-                  <span style={{ color: '#cfcfcf' }}>{item.username}</span>
-                </div>
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-      </Select>
+        {createTreeNode(treeData)}
+      </TreeSelect>
     ) : (
       <Select
         showSearch
@@ -239,43 +239,19 @@ export default (props: UserProps) => {
 
   const emailSelect =
     source === 'relation' ? (
-      <Select
+      <TreeSelect
         showSearch
         value={value}
-        onChange={(key, node) => {
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        placeholder={'请选择收信人'}
+        onSelect={(key: any, node: any) => {
           setValue(key);
           onchange(source, key, node.isRelation);
         }}
-        placeholder={'请选择收信人'}
-        listHeight={200}
-        filterOption={filterOption}
-        optionLabelProp="label"
+        filterTreeNode={filterOption}
       >
-        {userList.platform.length ? (
-          <Select.OptGroup label={'平台用户'}>
-            {userList.platform.map((item: any) => (
-              <Select.Option value={item.value} isRelation={false} label={item.label}>
-                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-                  <span>{item.label}</span>
-                  <span style={{ color: '#cfcfcf' }}>{item.username}</span>
-                </div>
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-        {userList.relation.length ? (
-          <Select.OptGroup label={'关系用户'}>
-            {userList.relation.map((item: any) => (
-              <Select.Option value={item.value} isRelation={true} label={item.label}>
-                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-                  <span>{item.label}</span>
-                  <span style={{ color: '#cfcfcf' }}>{item.username}</span>
-                </div>
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-      </Select>
+        {createTreeNode(treeData)}
+      </TreeSelect>
     ) : (
       <Input
         value={value}
@@ -288,36 +264,19 @@ export default (props: UserProps) => {
 
   const voiceSelect =
     source === 'relation' ? (
-      <Select
+      <TreeSelect
         showSearch
         value={value}
-        onChange={(key, node) => {
+        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        placeholder={'请选择收信人'}
+        onSelect={(key: any, node: any) => {
           setValue(key);
           onchange(source, key, node.isRelation);
         }}
-        placeholder={'请选择收信人'}
-        listHeight={200}
-        filterOption={filterOption}
+        filterTreeNode={filterOption}
       >
-        {userList.platform.length ? (
-          <Select.OptGroup label={'平台用户'}>
-            {userList.platform.map((item: any) => (
-              <Select.Option value={item.value} isRelation={false}>
-                {item.label}
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-        {userList.relation.length ? (
-          <Select.OptGroup label={'关系用户'}>
-            {userList.relation.map((item: any) => (
-              <Select.Option value={item.value} isRelation={true}>
-                {item.label}
-              </Select.Option>
-            ))}
-          </Select.OptGroup>
-        ) : null}
-      </Select>
+        {createTreeNode(treeData)}
+      </TreeSelect>
     ) : (
       <Input
         value={value}