瀏覽代碼

feat(alarm): alarm config

lind 3 年之前
父節點
當前提交
8173315dfd

二進制
public/images/alarm/alarm1.png


二進制
public/images/alarm/alarm2.png


二進制
public/images/alarm/alarm3.png


二進制
public/images/alarm/alarm4.png


二進制
public/images/alarm/alarm5.png


+ 33 - 0
src/components/FLevelInput/index.tsx

@@ -0,0 +1,33 @@
+import { ArrayItems } from '@formily/antd';
+import { Input } from 'antd';
+
+interface Props {
+  name?: string;
+  value: string;
+  onChange: () => void;
+}
+
+const LevelInput = (props: Props) => {
+  const alarm1 = require('/public/images/alarm/alarm1.png');
+  const alarm2 = require('/public/images/alarm/alarm2.png');
+  const alarm3 = require('/public/images/alarm/alarm3.png');
+  const alarm4 = require('/public/images/alarm/alarm4.png');
+  const alarm5 = require('/public/images/alarm/alarm5.png');
+
+  const imgMap = {
+    0: alarm1,
+    1: alarm2,
+    2: alarm3,
+    3: alarm4,
+    4: alarm5,
+  };
+  const index = ArrayItems.useIndex!();
+  return (
+    <div>
+      <img src={imgMap[index]} alt="" />
+      级别{index + 1}
+      <Input onChange={props.onChange} value={props.value} />
+    </div>
+  );
+};
+export default LevelInput;

+ 155 - 22
src/pages/notice/Config/SyncUser/index.tsx

@@ -1,47 +1,180 @@
 import { Button, Col, Input, Modal, Row, Tree } from 'antd';
 import { observer } from '@formily/react';
-import { state } from '..';
+import { service, state } from '..';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { useRef } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
+import { history, useLocation } from 'umi';
+import { PermissionButton } from '@/components';
+import { DisconnectOutlined, EditOutlined } from '@ant-design/icons';
 
 const SyncUser = observer(() => {
+  const [dept, setDept] = useState<string>();
+  const location = useLocation<{ id: string }>();
+  const id = (location as any).query?.id;
+
+  const idMap = {
+    dingTalk: '钉钉',
+    weixin: '微信',
+  };
   const columns: ProColumns<any>[] = [
     {
-      dataIndex: 'name',
-      title: '微信用户名',
+      dataIndex: 'id',
+      title: `${idMap[id]}ID`,
     },
     {
       dataIndex: 'name',
-      title: '用户',
+      title: `${idMap[id]}用户名`,
     },
     {
-      dataIndex: 'name',
+      dataIndex: 'action',
       title: '绑定状态',
+      render: () => [
+        <PermissionButton
+          tooltip={{
+            title: '绑定用户',
+          }}
+        >
+          <EditOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          tooltip={{
+            title: '解绑用户',
+          }}
+        >
+          <DisconnectOutlined />
+        </PermissionButton>,
+      ],
     },
   ];
   const actionRef = useRef<ActionType>();
 
+  const [treeData, setTreeData] = useState([]);
+
+  /**
+   * 获取部门列表
+   */
+  const getDepartment = async () => {
+    if (state.current?.id) {
+      if (id === 'dingTalk') {
+        service.syncUser.dingTalkDept(state.current?.id).then((resp) => {
+          if (resp.status === 200) {
+            setTreeData(resp.result);
+            setDept(resp.result[0].id);
+            console.log(resp.result[0].id, 'id');
+          }
+        });
+      } else if (id === 'weixin') {
+        service.syncUser.wechatDept(state.current?.id).then((resp) => {
+          if (resp.status === 200) {
+            setTreeData(resp.result);
+            setDept(resp.result[0].id);
+            console.log(resp.result[0].id, 'id~~');
+          }
+        });
+      }
+    }
+  };
+
+  useEffect(() => {
+    if (!state.current?.id) {
+      history.goBack();
+    }
+    getDepartment();
+  }, [id]);
+
+  // const updateTreeData = (list: any[], key: React.Key, children: any[]): any[] => {
+  //   return list.map((node) => {
+  //     if (node.id === key) {
+  //       return {
+  //         ...node,
+  //         children: node.children ? [...node.children, ...children] : children,
+  //       };
+  //     }
+  //
+  //     if (node.children) {
+  //       return {
+  //         ...node,
+  //         children: updateTreeData(node.children, key, children),
+  //       };
+  //     }
+  //     return node;
+  //   });
+  // };
+
+  // const getParentKey = (key: any, tree: string | any[]): any => {
+  //   let parentKey;
+  //   for (let i = 0; i < tree.length; i++) {
+  //     const node = tree[i];
+  //     if (node.children) {
+  //       if (node.children.some((item: { key: any; }) => item.key === key)) {
+  //         parentKey = node.key;
+  //       } else if (getParentKey(key, node.children)) {
+  //         parentKey = getParentKey(key, node.children);
+  //       }
+  //     }
+  //   }
+  //   return parentKey;
+  // };
+
   return (
-    <Modal title="同步用户" visible={true} onCancel={() => (state.syncUser = false)} width="80vw">
+    <Modal
+      title="同步用户"
+      bodyStyle={{ height: '600px', overflowY: 'auto' }}
+      visible={true}
+      onCancel={() => (state.syncUser = false)}
+      width="80vw"
+    >
       <Row>
         <Col span={4}>
-          <Input.Search style={{ marginBottom: 8 }} placeholder="Search" onChange={() => {}} />
-          <Tree
-            onExpand={() => {}}
-            // expandedKeys={expandedKeys}
-            // autoExpandParent={autoExpandParent}
-            // treeData={loop(gData)}
-          />
-          这是一颗没有数据的树
+          <div style={{ borderRight: 'lightgray 1px solid', padding: '2px', height: '600px' }}>
+            <Input.Search style={{ marginBottom: 8 }} placeholder="请输入部门名称" />
+            <Tree
+              fieldNames={{
+                title: 'name',
+                key: 'id',
+              }}
+              onSelect={(key) => {
+                setDept(key[0] as string);
+              }}
+              treeData={treeData}
+              // loadData={onLoadData}
+            />
+          </div>
         </Col>
         <Col span={20}>
-          <ProTable
-            rowKey="id"
-            actionRef={actionRef}
-            search={false}
-            columns={columns}
-            headerTitle={<Button>保存</Button>}
-          />
+          {dept && (
+            <ProTable
+              rowKey="id"
+              actionRef={actionRef}
+              search={false}
+              columns={columns}
+              params={{ dept: dept }}
+              request={async (params) =>
+                service.syncUser
+                  .getDeptUser(
+                    {
+                      dingTalk: 'dingtalk',
+                      weixin: 'wechat',
+                    }[id],
+                    state.current?.id || '',
+                    params.dept || '',
+                  )
+                  .then((resp) => {
+                    return {
+                      code: resp.message,
+                      result: {
+                        data: resp.result || [],
+                        pageIndex: 0,
+                        pageSize: 0,
+                        total: 0,
+                      },
+                      status: resp.status,
+                    };
+                  })
+              }
+              headerTitle={<Button>保存</Button>}
+            />
+          )}
         </Col>
       </Row>
     </Modal>

+ 40 - 31
src/pages/notice/Config/index.tsx

@@ -11,7 +11,7 @@ import {
   TeamOutlined,
   UnorderedListOutlined,
 } from '@ant-design/icons';
-import { message, Space, Tooltip, Upload } from 'antd';
+import { message, Space, Upload } from 'antd';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { downloadObject } from '@/utils/util';
@@ -73,21 +73,25 @@ const Config = observer(() => {
       align: 'center',
       width: 200,
       render: (text, record) => [
-        <PermissionButton
-          tooltip={{
-            title: '同步用户',
-          }}
-          type="link"
-          onClick={() => {
-            state.syncUser = true;
-            state.current = record;
-          }}
-        >
-          <TeamOutlined />
-        </PermissionButton>,
+        (id === 'dingTalk' || id === 'weixin') && (
+          <PermissionButton
+            tooltip={{
+              title: '同步用户',
+            }}
+            style={{ padding: 0 }}
+            type="link"
+            onClick={() => {
+              state.syncUser = true;
+              state.current = record;
+            }}
+          >
+            <TeamOutlined />
+          </PermissionButton>
+        ),
         <PermissionButton
           key="edit"
           type="link"
+          style={{ padding: 0 }}
           isPermission={configPermission.update}
           onClick={async () => {
             // setLoading(true);
@@ -105,6 +109,7 @@ const Config = observer(() => {
         </PermissionButton>,
         <PermissionButton
           type="link"
+          style={{ padding: 0 }}
           isPermission={configPermission.export}
           onClick={() =>
             downloadObject(
@@ -124,24 +129,25 @@ const Config = observer(() => {
         </PermissionButton>,
         <PermissionButton
           type="link"
+          style={{ padding: 0 }}
           isPermission={configPermission.debug}
           key="debug"
           onClick={() => {
             state.debug = true;
             state.current = record;
           }}
-        >
-          <Tooltip
-            title={intl.formatMessage({
+          tooltip={{
+            title: intl.formatMessage({
               id: 'pages.notice.option.debug',
               defaultMessage: '调试',
-            })}
-          >
-            <BugOutlined />
-          </Tooltip>
+            }),
+          }}
+        >
+          <BugOutlined />
         </PermissionButton>,
         <PermissionButton
           type="link"
+          style={{ padding: 0 }}
           isPermission={configPermission.log}
           key="record"
           onClick={() => {
@@ -157,6 +163,7 @@ const Config = observer(() => {
           <BarsOutlined />
         </PermissionButton>,
         <PermissionButton
+          style={{ padding: 0 }}
           type="link"
           popConfirm={{
             onConfirm: async () => {
@@ -289,17 +296,19 @@ const Config = observer(() => {
               </div>
             }
             actions={[
-              <PermissionButton
-                key="syncUser"
-                isPermission={true}
-                onClick={() => {
-                  state.syncUser = true;
-                  state.current = record;
-                }}
-              >
-                <TeamOutlined />
-                同步用户
-              </PermissionButton>,
+              (id === 'dingTalk' || id === 'weixin') && (
+                <PermissionButton
+                  key="syncUser"
+                  isPermission={true}
+                  onClick={() => {
+                    state.syncUser = true;
+                    state.current = record;
+                  }}
+                >
+                  <TeamOutlined />
+                  同步用户
+                </PermissionButton>
+              ),
               <PermissionButton
                 isPermission={configPermission.update}
                 type={'link'}

+ 38 - 0
src/pages/notice/Config/service.ts

@@ -33,6 +33,44 @@ class Service extends BaseService<ConfigItem> {
       method: 'POST',
       data,
     });
+
+  syncUser = {
+    dingTalkDept: (configId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/dingtalk/corp/${configId}/departments/tree`),
+    dingTalkUser: (configId: string, departmentId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/dingtalk/corp/${configId}/${departmentId}/users`),
+    wechatDept: (configId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/wechat/corp/${configId}/departments`),
+    getDeptUser: (type: 'wechat' | 'dingTalk', configId: string, departmentId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/${type}/corp/${configId}/${departmentId}/users`, {
+        method: 'GET',
+      }),
+    wechatUser: (configId: string, departmentId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/wechat/corp/${configId}/${departmentId}/users`),
+    bindInfo: (type: string, provider: string, configId: string) =>
+      request(`${SystemConst.API_BASE}/user/third-party/${type}_${provider}/${configId}`),
+    noBindUser: (data: any) =>
+      request(`${SystemConst.API_BASE}/user/_query/no-paging`, {
+        method: 'POST',
+        data,
+      }),
+    bindUser: (
+      type: string,
+      provider: string,
+      configId: string,
+      data: { userId: string; providerName: string; thirdPartyUserId: string }[],
+    ) =>
+      request(`${SystemConst.API_BASE}/user/third-party/${type}_${provider}/${configId}`, {
+        method: 'PATCH',
+        data,
+      }),
+    getUserBindInfo: () =>
+      request(`${SystemConst.API_BASE}/user/third-party/me`, { method: 'GET' }),
+    unBindUser: (bindId: string) =>
+      request(`${SystemConst.API_BASE}/user/third-party/me/${bindId}`, {
+        method: 'DELETE',
+      }),
+  };
 }
 
 export default Service;

+ 12 - 12
src/pages/rule-engine/Alarm/Config/index.tsx

@@ -6,6 +6,7 @@ import { ArrayItems, Form, FormButtonGroup, FormGrid, FormItem, Input } from '@f
 import { ISchema } from '@formily/json-schema';
 import { useMemo, useState } from 'react';
 import { createForm } from '@formily/core';
+import FLevelInput from '@/components/FLevelInput';
 
 const Config = () => {
   const [tab, setTab] = useState<'io' | 'config' | string>('config');
@@ -15,10 +16,17 @@ const Config = () => {
       Input,
       ArrayItems,
       FormGrid,
+      FLevelInput,
     },
   });
 
-  const form = useMemo(() => createForm({}), []);
+  const form = useMemo(
+    () =>
+      createForm({
+        effects() {},
+      }),
+    [],
+  );
   const schema1: ISchema = {
     type: 'object',
     properties: {
@@ -26,6 +34,7 @@ const Config = () => {
         type: 'array',
         'x-component': 'ArrayItems',
         'x-decorator': 'FormItem',
+        maxItems: 3,
         items: {
           type: 'void',
           'x-decorator': 'FormGrid',
@@ -35,21 +44,12 @@ const Config = () => {
             columnGap: 2,
           },
           properties: {
-            index: {
-              type: 'void',
-              'x-decorator': 'FormItem',
-              'x-component': 'ArrayItems.Index',
-              title: '级别',
-              'x-decorator-props': {
-                gridSpan: 24,
-              },
-            },
             input: {
               type: 'string',
               'x-decorator': 'FormItem',
-              'x-component': 'Input',
+              'x-component': 'FLevelInput',
               'x-decorator-props': {
-                gridSpan: 22,
+                gridSpan: 23,
               },
             },
             remove: {