lind 4 лет назад
Родитель
Сommit
16bd038488

+ 8 - 8
package.json

@@ -62,20 +62,20 @@
     "@ant-design/pro-descriptions": "^1.6.8",
     "@ant-design/pro-form": "^1.18.3",
     "@ant-design/pro-layout": "^6.27.2",
-    "@formily/antd": "2.0.0-rc.17",
-    "@formily/core": "2.0.0-rc.17",
-    "@formily/json-schema": "2.0.0-rc.17",
-    "@formily/react": "2.0.0-rc.17",
-    "@formily/reactive": "2.0.0-rc.17",
-    "@formily/reactive-react": "2.0.0-rc.17",
-    "@formily/shared": "2.0.0-rc.17",
+    "@formily/antd": "2.0.18",
+    "@formily/core": "2.0.18",
+    "@formily/json-schema": "2.0.18",
+    "@formily/react": "2.0.18",
+    "@formily/reactive": "2.0.18",
+    "@formily/reactive-react": "2.0.18",
+    "@formily/shared": "2.0.18",
     "@jetlinks/pro-list": "^1.10.8",
     "@jetlinks/pro-table": "^2.63.11",
     "@liveqing/liveplayer": "^2.6.4",
     "@types/react-syntax-highlighter": "^13.5.2",
     "@umijs/route-utils": "^1.0.36",
     "ahooks": "^2.10.9",
-    "antd": "^4.18.8",
+    "antd": "^4.19.5",
     "braft-editor": "^2.3.9",
     "classnames": "^2.3.1",
     "dexie": "^3.0.3",

+ 2 - 1
src/components/SearchComponent/index.tsx

@@ -119,7 +119,6 @@ const sortField = (field: ProColumns[]) => {
   if (!_temp) {
     // 如果没有index 就默认name字段最第一个
     field.map((item) => {
-      console.log(item, 'items');
       if (item.dataIndex === 'name') {
         item.index = 0;
         return item;
@@ -356,6 +355,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
   const handleHistory = (item: SearchHistory) => {
     const log = JSON.parse(item.content) as SearchTermsUI;
     form.setValues(log);
+    // @ts-ignore
     setExpand(!(log.terms1?.length > 1 || log.terms2?.length > 1));
   };
 
@@ -411,6 +411,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
         _value = _value.concat([{ terms: defaultParam }]);
       }
     }
+
     return _value
       .filter((i) => i.terms?.length > 0)
       .map((term) => {

+ 82 - 0
src/pages/notice/Config/Debug/index.tsx

@@ -0,0 +1,82 @@
+import { Button, Modal } from 'antd';
+import { useMemo } from 'react';
+import { createForm } from '@formily/core';
+import { createSchemaField, observer } from '@formily/react';
+import { Form, FormItem, Input, Select } from '@formily/antd';
+import { ISchema } from '@formily/json-schema';
+import { state } from '@/pages/notice/Template';
+import { useLocation } from 'umi';
+import { useAsyncDataSource } from '@/utils/util';
+
+const Debug = observer(() => {
+  const location = useLocation<{ id: string }>();
+  const id = (location as any).query?.id;
+
+  const form = useMemo(
+    () =>
+      createForm({
+        validateFirst: true,
+        effects() {},
+      }),
+    [],
+  );
+
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Select,
+    },
+  });
+
+  console.log(id, 'testt');
+
+  const getTemplate = () => {};
+  // const getConfig = () =>
+  //   configService
+  //     .queryNoPagingPost({
+  //       terms: [{column: 'type$IN', value: id}],
+  //     })
+  //     .then((resp: any) => {
+  //       return resp.result?.map((item) => ({
+  //         label: item.name,
+  //         value: item.id,
+  //       }));
+  //     });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      configId: {
+        title: '通知模版',
+        type: 'string',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+        'x-reactions': '{{useAsyncDataSource(getTemplate)}}',
+      },
+      bianliang: {
+        title: '变量',
+        type: 'string',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+      },
+    },
+  };
+  return (
+    <Modal
+      width="40vw"
+      visible={state.debug}
+      onCancel={() => (state.debug = false)}
+      footer={
+        <Button type="primary" onClick={() => (state.debug = false)}>
+          关闭
+        </Button>
+      }
+    >
+      <Form form={form} layout={'vertical'}>
+        <SchemaField schema={schema} scope={{ getTemplate, useAsyncDataSource }} />
+      </Form>
+    </Modal>
+  );
+});
+export default Debug;

+ 31 - 16
src/pages/notice/Config/Detail/index.tsx

@@ -1,9 +1,9 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import { createForm, onFieldValueChange } from '@formily/core';
-import { Card, Col, Input, Row } from 'antd';
+import { Card, Col, Input, message, Row } from 'antd';
 import { ISchema } from '@formily/json-schema';
-import { useMemo } from 'react';
-import { createSchemaField } from '@formily/react';
+import { useEffect, useMemo } from 'react';
+import { createSchemaField, observer } from '@formily/react';
 import {
   FormButtonGroup,
   FormItem,
@@ -25,8 +25,9 @@ import { useAsyncDataSource } from '@/utils/util';
 import { useParams } from 'umi';
 import { typeList } from '@/pages/notice';
 import FUpload from '@/components/Upload';
+import { state } from '@/pages/notice/Config';
 
-const Detail = () => {
+const Detail = observer(() => {
   const { id } = useParams<{ id: string }>();
 
   const form = useMemo(
@@ -37,8 +38,8 @@ const Detail = () => {
           onFieldValueChange('type', async (field, f) => {
             const type = field.value;
             if (!type) return;
-            f.setFieldState('provider', (state) => {
-              state.value = undefined;
+            f.setFieldState('provider', (state1) => {
+              state1.value = undefined;
               // state.dataSource = providerRef.current
               //   .find((item) => type === item.id)
               //   ?.providerInfos.map((i) => ({ label: i.name, value: i.id }));
@@ -54,6 +55,12 @@ const Detail = () => {
     [id],
   );
 
+  useEffect(() => {
+    if (state.current) {
+      form.setValues(state.current);
+    }
+  }, []);
+
   const SchemaField = createSchemaField({
     components: {
       FormItem,
@@ -113,7 +120,7 @@ const Detail = () => {
             type: 'void',
             properties: {
               corpId: {
-                title: 'corpID',
+                title: 'corpId',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
                 // 企业消息
@@ -139,8 +146,8 @@ const Detail = () => {
                   },
                 },
               },
-              AppId: {
-                title: 'appId',
+              appId: {
+                title: 'appID',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
                 'x-reactions': {
@@ -152,8 +159,8 @@ const Detail = () => {
                   },
                 },
               },
-              AppSecret: {
-                title: 'appSecret',
+              appSecret: {
+                title: 'AppSecret',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
                 'x-reactions': {
@@ -172,7 +179,7 @@ const Detail = () => {
             type: 'void',
             'x-visible': id === 'dingTalk',
             properties: {
-              AppKey: {
+              appKey: {
                 title: 'AppKey',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
@@ -186,7 +193,7 @@ const Detail = () => {
                   },
                 },
               },
-              AppSecret: {
+              appSecret: {
                 title: 'AppSecret',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
@@ -200,7 +207,7 @@ const Detail = () => {
                   },
                 },
               },
-              Webhook: {
+              webhook: {
                 title: 'webHook',
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
@@ -301,6 +308,14 @@ const Detail = () => {
     },
   };
 
+  const handleSave = async () => {
+    const data: ConfigItem = await form.submit();
+    const response: any = await service.save(data);
+    if (response?.status === 200) {
+      message.success('保存成功');
+      history.back();
+    }
+  };
   return (
     <PageContainer>
       <Card>
@@ -310,7 +325,7 @@ const Detail = () => {
               <SchemaField scope={{ useAsyncDataSource, getTypes }} schema={schema} />
               <FormButtonGroup.Sticky>
                 <FormButtonGroup.FormItem>
-                  <Submit>保存</Submit>
+                  <Submit onSubmit={handleSave}>保存</Submit>
                 </FormButtonGroup.FormItem>
               </FormButtonGroup.Sticky>
             </Form>
@@ -322,6 +337,6 @@ const Detail = () => {
       </Card>
     </PageContainer>
   );
-};
+});
 
 export default Detail;

+ 74 - 0
src/pages/notice/Config/Log/index.tsx

@@ -0,0 +1,74 @@
+import { Modal } from 'antd';
+import { observer } from '@formily/react';
+import { service, state } from '..';
+import ProTable, { ProColumns } from '@jetlinks/pro-table';
+import SearchComponent from '@/components/SearchComponent';
+import { useLocation } from 'umi';
+import { InfoCircleOutlined } from '@ant-design/icons';
+
+const Log = observer(() => {
+  const location = useLocation<{ id: string }>();
+  const id = (location as any).query?.id;
+
+  const columns: ProColumns<LogItem>[] = [
+    {
+      dataIndex: 'id',
+      title: 'ID',
+    },
+    {
+      dataIndex: 'sendTime',
+      title: '发送时间',
+    },
+    {
+      dataIndex: 'state',
+      title: '状态',
+    },
+    {
+      dataIndex: 'action',
+      title: '操作',
+      render: (text, record) => [
+        <a
+          onClick={() => {
+            Modal.info({
+              title: '详情信息',
+              content: (
+                <div>
+                  <p>some messages...some messages...</p>
+                  <p>some messages...some messages...</p>
+                  {JSON.stringify(record)}
+                </div>
+              ),
+              onOk() {},
+            });
+          }}
+        >
+          <InfoCircleOutlined />
+        </a>,
+      ],
+    },
+  ];
+  return (
+    <Modal onCancel={() => (state.log = false)} title="通知记录" width={'70vw'} visible={state.log}>
+      <SearchComponent
+        defaultParam={[{ column: 'type$IN', value: id }]}
+        field={columns}
+        onSearch={(data) => {
+          // actionRef.current?.reset?.();
+          // setParam(data);
+          console.log(data);
+        }}
+        enableSave={false}
+      />
+      <ProTable<LogItem>
+        search={false}
+        pagination={{
+          pageSize: 5,
+        }}
+        columns={columns}
+        request={async (params) => service.query(params)}
+      ></ProTable>
+    </Modal>
+  );
+});
+
+export default Log;

+ 42 - 130
src/pages/notice/Config/index.tsx

@@ -4,8 +4,8 @@ import {
   ArrowDownOutlined,
   BarsOutlined,
   BugOutlined,
+  DeleteOutlined,
   EditOutlined,
-  MinusOutlined,
   PlusOutlined,
 } from '@ant-design/icons';
 import { Button, message, Popconfirm, Tooltip } from 'antd';
@@ -18,12 +18,21 @@ import { createForm, onFieldValueChange } from '@formily/core';
 import { observer } from '@formily/react';
 import SearchComponent from '@/components/SearchComponent';
 import ProTable from '@jetlinks/pro-table';
-import { history } from '@@/core/history';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
-import { useLocation } from 'umi';
+import { history, useLocation } from 'umi';
+import { model } from '@formily/reactive';
+import moment from 'moment';
 
 export const service = new Service('notifier/config');
 
+export const state = model<{
+  current?: ConfigItem;
+  debug?: boolean;
+  log?: boolean;
+}>({
+  debug: false,
+  log: false,
+});
 const Config = observer(() => {
   const intl = useIntl();
   const actionRef = useRef<ActionType>();
@@ -40,113 +49,15 @@ const Config = observer(() => {
     const DForm = form;
     if (!DForm?.values) return;
     DForm.setValuesIn('provider', DForm.values.provider);
-    // const resp = await service.getMetadata(
-    //   DForm?.values?.type,
-    //   // eslint-disable-next-line @typescript-eslint/no-use-before-define
-    //   currentType || DForm.values?.provider,
-    // );
-    // const properties = resp.result?.properties as ConfigMetadata[];
-    // setConfigSchema({
-    //   type: 'object',
-    //   properties: properties?.reduce((previousValue, currentValue) => {
-    //     if (currentValue.type?.type === 'array') {
-    //       // 单独处理邮件的其他配置功能
-    //       previousValue[currentValue.property] = {
-    //         type: 'array',
-    //         title: '其他配置',
-    //         'x-component': 'ArrayItems',
-    //         'x-decorator': 'FormItem',
-    //         items: {
-    //           type: 'object',
-    //           properties: {
-    //             space: {
-    //               type: 'void',
-    //               'x-component': 'Space',
-    //               properties: {
-    //                 sort: {
-    //                   type: 'void',
-    //                   'x-decorator': 'FormItem',
-    //                   'x-component': 'ArrayItems.SortHandle',
-    //                 },
-    //                 name: {
-    //                   type: 'string',
-    //                   title: 'key',
-    //                   'x-decorator': 'FormItem',
-    //                   'x-component': 'Input',
-    //                 },
-    //                 value: {
-    //                   type: 'string',
-    //                   title: 'value',
-    //                   'x-decorator': 'FormItem',
-    //                   'x-component': 'Input',
-    //                 },
-    //                 description: {
-    //                   type: 'string',
-    //                   title: '备注',
-    //                   'x-decorator': 'FormItem',
-    //                   'x-component': 'Input',
-    //                 },
-    //                 remove: {
-    //                   type: 'void',
-    //                   'x-decorator': 'FormItem',
-    //                   'x-component': 'ArrayItems.Remove',
-    //                 },
-    //               },
-    //             },
-    //           },
-    //         },
-    //         properties: {
-    //           add: {
-    //             type: 'void',
-    //             title: '添加条目',
-    //             'x-component': 'ArrayItems.Addition',
-    //           },
-    //         },
-    //       };
-    //     } else {
-    //       previousValue[currentValue.property] = {
-    //         title: currentValue.name,
-    //         type: 'string',
-    //         'x-component': 'Input',
-    //         'x-decorator': 'FormItem',
-    //       };
-    //     }
-    //     return previousValue;
-    //   }, {}),
-    // });
-    // DForm.setValues(CurdModel.current);
-    // setLoading(false);
   };
-  // const schema: ISchema = {
-  //   type: 'object',
-  //   properties: {
-  //     name: {
-  //       title: '名称',
-  //       'x-component': 'Input',
-  //       'x-decorator': 'FormItem',
-  //     },
-  //     type: {
-  //       title: '类型',
-  //       'x-component': 'Select',
-  //       'x-decorator': 'FormItem',
-  //       'x-reactions': ['{{useAsyncDataSource(getTypes)}}'],
-  //     },
-  //     provider: {
-  //       title: '服务商',
-  //       'x-component': 'Select',
-  //       'x-decorator': 'FormItem',
-  //     },
-  //     configuration: configSchema,
-  //   },
-  // };
 
   const formEvent = () => {
     onFieldValueChange('type', async (field, f) => {
       const type = field.value;
       if (!type) return;
-      f.setFieldState('provider', (state) => {
-        state.value = undefined;
-        state.dataSource = providerRef.current
+      f.setFieldState('provider', (state1) => {
+        state1.value = undefined;
+        state1.dataSource = providerRef.current
           .find((item) => type === item.id)
           ?.providerInfos.map((i) => ({ label: i.name, value: i.id }));
       });
@@ -191,7 +102,7 @@ const Config = observer(() => {
       dataIndex: 'type',
       title: intl.formatMessage({
         id: 'pages.notice.config.type',
-        defaultMessage: '通知类型',
+        defaultMessage: '通知方式',
       }),
     },
     {
@@ -214,10 +125,8 @@ const Config = observer(() => {
           key="edit"
           onClick={async () => {
             // setLoading(true);
-            CurdModel.update(record);
-            form.setValues(record);
-            await createSchema();
-            CurdModel.model = 'edit';
+            state.current = record;
+            history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
           }}
         >
           <Tooltip
@@ -229,7 +138,15 @@ const Config = observer(() => {
             <EditOutlined />
           </Tooltip>
         </a>,
-        <a onClick={() => downloadObject(record, '通知配置')} key="download">
+        <a
+          onClick={() =>
+            downloadObject(
+              record,
+              `通知配置${record.name}-${moment(new Date()).format('YYYY/MM/DD HH:mm:ss')}`,
+            )
+          }
+          key="download"
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.data.option.download',
@@ -239,7 +156,12 @@ const Config = observer(() => {
             <ArrowDownOutlined />
           </Tooltip>
         </a>,
-        <a key="debug">
+        <a
+          key="debug"
+          onClick={() => {
+            state.debug = true;
+          }}
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.notice.option.debug',
@@ -249,7 +171,12 @@ const Config = observer(() => {
             <BugOutlined />
           </Tooltip>
         </a>,
-        <a key="record">
+        <a
+          key="record"
+          onClick={() => {
+            state.log = true;
+          }}
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.data.option.record',
@@ -279,7 +206,7 @@ const Config = observer(() => {
                 defaultMessage: '删除',
               })}
             >
-              <MinusOutlined />
+              <DeleteOutlined />
             </Tooltip>
           </Popconfirm>
         </a>,
@@ -299,6 +226,7 @@ const Config = observer(() => {
   return (
     <PageContainer className={'page-title-show'}>
       <SearchComponent
+        defaultParam={[{ column: 'type$IN', value: id }]}
         field={columns}
         onSearch={(data) => {
           actionRef.current?.reset?.();
@@ -313,6 +241,7 @@ const Config = observer(() => {
         toolBarRender={() => [
           <Button
             onClick={() => {
+              state.current = undefined;
               history.push(getMenuPathByParams(MENUS_CODE['notice/Config/Detail'], id));
             }}
             key="button"
@@ -327,23 +256,6 @@ const Config = observer(() => {
         ]}
         request={async (params) => service.query(params)}
       />
-
-      {/*<BaseCrud*/}
-      {/*  columns={columns}*/}
-      {/*  service={service}*/}
-      {/*  title={intl.formatMessage({*/}
-      {/*    id: 'pages.notice.config',*/}
-      {/*    defaultMessage: '通知配置',*/}
-      {/*  })}*/}
-      {/*  modelConfig={{*/}
-      {/*    width: '50vw',*/}
-      {/*    loading: loading,*/}
-      {/*  }}*/}
-      {/*  schema={schema}*/}
-      {/*  form={form}*/}
-      {/*  schemaConfig={{ scope: { useAsyncDataSource, getTypes } }}*/}
-      {/*  actionRef={actionRef}*/}
-      {/*/>*/}
     </PageContainer>
   );
 });

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

@@ -1,5 +1,6 @@
 import BaseService from '@/utils/BaseService';
 import { request } from 'umi';
+import SystemConst from '@/utils/const';
 
 class Service extends BaseService<ConfigItem> {
   public getTypes = () =>
@@ -11,6 +12,12 @@ class Service extends BaseService<ConfigItem> {
     request(`${this.uri}/${type}/${provider}/metadata`, {
       method: 'GET',
     });
+
+  public getTemplate = (configId: string) =>
+    request(`${SystemConst.API_BASE}/notifier/template/${configId}/_query/no-paging`);
+
+  public getTemplateVariable = (templateId: string) =>
+    request(`${SystemConst.API_BASE}/notifier/template/${templateId}/detail`);
 }
 
 export default Service;

+ 184 - 0
src/pages/notice/Template/Debug/index.tsx

@@ -0,0 +1,184 @@
+import { Button, Modal } from 'antd';
+import { useEffect, useMemo } from 'react';
+import { createForm, Field, onFieldReact, onFieldValueChange } from '@formily/core';
+import { createSchemaField, observer } from '@formily/react';
+import {
+  ArrayTable,
+  DatePicker,
+  Form,
+  FormItem,
+  Input,
+  NumberPicker,
+  PreviewText,
+  Select,
+} from '@formily/antd';
+import { ISchema } from '@formily/json-schema';
+import { configService, state } from '@/pages/notice/Template';
+import { useLocation } from 'umi';
+import { useAsyncDataSource } from '@/utils/util';
+import { Store } from 'jetlinks-store';
+import FUpload from '@/components/Upload';
+
+const Debug = observer(() => {
+  const location = useLocation<{ id: string }>();
+  const id = (location as any).query?.id;
+
+  const form = useMemo(
+    () =>
+      createForm({
+        validateFirst: true,
+        effects() {
+          onFieldValueChange('configId', async (field, form1) => {
+            const value = (field as Field).value;
+            const configs = Store.get('notice-config');
+            const target = configs.find((item: { id: any }) => item.id === value);
+            console.log(target, 'target');
+            // 从缓存中获取通知配置信息
+            if (target && target.variableDefinitions) {
+              form1.setValuesIn('variableDefinitions', target.variableDefinitions);
+            }
+            //
+            // 获取 变量列表
+            // 然后set 值
+          });
+          onFieldReact('variableDefinitions.*.type', (field) => {
+            const value = (field as Field).value;
+            const format = field.query('.value').take() as any;
+            switch (value) {
+              case 'date':
+                format.setComponent(DatePicker);
+                break;
+              case 'string':
+                format.setComponent(Input);
+                break;
+              case 'number':
+                format.setComponent(NumberPicker);
+                break;
+              case 'file':
+                format.setComponent(FUpload, {
+                  type: 'file',
+                });
+                break;
+              case 'other':
+                format.setComponent(Input);
+                break;
+            }
+          });
+        },
+      }),
+    [id],
+  );
+
+  useEffect(() => {
+    const data = state.current;
+    form.setValuesIn('variableDefinitions', data?.variableDefinitions);
+  });
+
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Select,
+      ArrayTable,
+      PreviewText,
+    },
+  });
+
+  const getConfig = () =>
+    configService
+      .queryNoPagingPost({
+        terms: [{ column: 'type$IN', value: id }],
+      })
+      .then((resp: any) => {
+        // 缓存通知配置
+        Store.set('notice-config', resp.result);
+        return resp.result?.map((item: { name: any; id: any }) => ({
+          label: item.name,
+          value: item.id,
+        }));
+      });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      configId: {
+        title: '配置',
+        type: 'string',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+        'x-reactions': '{{useAsyncDataSource(getConfig)}}',
+      },
+      variableDefinitions: {
+        title: '变量',
+        type: 'string',
+        'x-decorator': 'FormItem',
+        'x-component': 'ArrayTable',
+        'x-component-props': {
+          pagination: { pageSize: 9999 },
+          scroll: { x: '100%' },
+        },
+        items: {
+          type: 'object',
+          properties: {
+            column1: {
+              type: 'void',
+              'x-component': 'ArrayTable.Column',
+              'x-component-props': { title: '变量', width: '120px' },
+              properties: {
+                id: {
+                  type: 'string',
+                  'x-decorator': 'FormItem',
+                  'x-component': 'PreviewText.Input',
+                  'x-disabled': true,
+                },
+              },
+            },
+            column2: {
+              type: 'void',
+              'x-component': 'ArrayTable.Column',
+              'x-component-props': { title: '名称', width: '120px' },
+              properties: {
+                name: {
+                  type: 'string',
+                  'x-decorator': 'FormItem',
+                  'x-component': 'PreviewText.Input',
+                  'x-disabled': true,
+                },
+              },
+            },
+            column3: {
+              type: 'void',
+              'x-component': 'ArrayTable.Column',
+              'x-component-props': { title: '值', width: '120px' },
+              properties: {
+                value: {
+                  type: 'string',
+                  'x-decorator': 'FormItem',
+                  'x-component': 'Input',
+                },
+              },
+            },
+          },
+        },
+      },
+    },
+  };
+  return (
+    <Modal
+      title="调试"
+      width="40vw"
+      visible={state.debug}
+      onCancel={() => (state.debug = false)}
+      footer={
+        <Button type="primary" onClick={() => (state.debug = false)}>
+          关闭
+        </Button>
+      }
+    >
+      <Form form={form} layout={'vertical'}>
+        <SchemaField schema={schema} scope={{ getConfig, useAsyncDataSource }} />
+      </Form>
+    </Modal>
+  );
+});
+export default Debug;

+ 143 - 20
src/pages/notice/Template/Detail/index.tsx

@@ -1,8 +1,10 @@
 import {
+  ArrayItems,
   ArrayTable,
   Editable,
   Form,
   FormButtonGroup,
+  FormGrid,
   FormItem,
   Input,
   NumberPicker,
@@ -36,13 +38,25 @@ const Detail = observer(() => {
       .queryNoPagingPost({
         terms: [{ column: 'type$IN', value: id }],
       })
-      .then((resp) => {
-        return resp.result?.map((item) => ({
+      .then((resp: any) => {
+        return resp.result?.map((item: any) => ({
           label: item.name,
           value: item.id,
         }));
       });
 
+  const getDingTalkDept = (configId: string) => service.dingTalk.getDepartments(configId);
+  const getDingTalkDeptTree = (configId: string) => service.dingTalk.getDepartmentsTree(configId);
+  const getDingTalkUser = (configId: string, departmentId: string) =>
+    service.dingTalk.getUserByDepartment(configId, departmentId);
+
+  const getWeixinDept = (configId: string) => service.weixin.getDepartments(configId);
+  const getWeixinTags = (configId: string) => service.weixin.getTags(configId);
+  const getWeixinUser = (configId: string) => service.weixin.getUserByDepartment(configId);
+
+  const getAliyunSigns = (configId: string) => service.aliyun.getSigns(configId);
+  const getAliyunTemplates = (configId: string) => service.aliyun.getTemplates(configId);
+
   // 正则提取${}里面的值
   const pattern = /(?<=\$\{).*?(?=\})/g;
   const form = useMemo(
@@ -53,6 +67,7 @@ const Detail = observer(() => {
           onFieldInit('template.message', (field, form1) => {
             if (id === 'email') {
               field.setComponent(FBraftEditor);
+              // form1.setValuesIn('template.message', 'testtt')
             }
             console.log(form1);
             ///给FBraftEditor 设置初始值
@@ -62,9 +77,8 @@ const Detail = observer(() => {
             if (id === 'email' && form1.modified) {
               value = value?.toHTML();
             }
-            console.log(value, 'test');
             const idList = value
-              .match(pattern)
+              ?.match(pattern)
               ?.filter((i: string) => i)
               .map((item: string) => ({ id: item, type: 'string', format: '--' }));
             if (form1.modified) {
@@ -73,7 +87,7 @@ const Detail = observer(() => {
           });
           onFieldValueChange('variableDefinitions.*.type', (field) => {
             const value = (field as Field).value;
-            const format = field.query('.format').take();
+            const format = field.query('.format').take() as any;
             switch (value) {
               case 'date':
                 format.setComponent(Select);
@@ -109,6 +123,11 @@ const Detail = observer(() => {
                 break;
             }
           });
+          // onFieldValueChange('configId', (field, form1) => {
+          //   const value = (field as Field).value;
+          //
+          //
+          // })
         },
       }),
     [id],
@@ -127,13 +146,15 @@ const Detail = observer(() => {
       Select,
       Switch,
       Radio,
-      ArrayTable,
       Editable,
       PreviewText,
       Space,
       FUpload,
       NumberPicker,
       FBraftEditor,
+      ArrayItems,
+      FormGrid,
+      ArrayTable,
     },
   });
 
@@ -248,35 +269,56 @@ const Detail = observer(() => {
               },
               toUser: {
                 title: '收信人ID',
-                'x-component': 'Input',
+                'x-component': 'Select',
                 'x-decorator': 'FormItem',
                 'x-decorator-props': {
                   tooltip: '请输入收信人ID',
                 },
                 'x-component-props': {
                   placeholder: '请输入收信人ID',
+                  mode: 'tags',
+                },
+                'x-reactions': {
+                  dependencies: ['configId'],
+                  fulfill: {
+                    run: '{{useAsyncDataSource(getWeixinUser($deps[0]))}}',
+                  },
                 },
               },
               toParty: {
                 title: '收信部门ID',
-                'x-component': 'Input',
+                'x-component': 'Select',
                 'x-decorator': 'FormItem',
                 'x-decorator-props': {
                   tooltip: '请输入收信部门ID',
                 },
                 'x-component-props': {
                   placeholder: '请输入收信部门ID',
+                  mode: 'tags',
+                },
+                'x-reactions': {
+                  dependencies: ['configId'],
+                  fulfill: {
+                    run: '{{useAsyncDataSource(getWeixinDept($deps[0]))}}',
+                  },
                 },
               },
               toTag: {
                 title: '标签推送',
-                'x-component': 'Input',
+                'x-component': 'Select',
                 'x-decorator': 'FormItem',
                 'x-decorator-props': {
                   tooltip: '标签推送',
                 },
                 'x-component-props': {
                   placeholder: '请输入标签推送,多个标签用,号分隔',
+                  mode: 'tags',
+                },
+                'x-reactions': {
+                  dependencies: ['configId'],
+                  fulfill: {
+                    run: '{{useAsyncDataSource(getWeixinTags($deps[0]))}}',
+                  },
                 },
               },
             },
@@ -311,7 +353,7 @@ const Detail = observer(() => {
                   },
                   userIdList: {
                     title: '收信人ID',
-                    'x-component': 'Input',
+                    'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
                       tooltip: '请输入收信人ID',
@@ -319,10 +361,16 @@ const Detail = observer(() => {
                     'x-component-props': {
                       placeholder: '请输入收信人ID',
                     },
+                    'x-reactions': {
+                      dependencies: ['configId'],
+                      fulfill: {
+                        run: '{{useAsyncDataSource(getDingTalkUser($deps[0]))}}',
+                      },
+                    },
                   },
                   departmentIdList: {
                     title: '收信部门ID',
-                    'x-component': 'Input',
+                    'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
                       tooltip: '请输入收信部门ID',
@@ -330,6 +378,12 @@ const Detail = observer(() => {
                     'x-component-props': {
                       placeholder: '请输入AgentID',
                     },
+                    'x-reactions': {
+                      dependencies: ['configId'],
+                      fulfill: {
+                        run: '{{useAsyncDataSource(getDingTalkDept($deps[0]))}}',
+                      },
+                    },
                   },
                 },
                 'x-reactions': {
@@ -482,7 +536,7 @@ const Detail = observer(() => {
                 properties: {
                   code: {
                     title: '模版ID',
-                    'x-component': 'Input',
+                    'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
                       tooltip: '请输入模版ID',
@@ -490,10 +544,16 @@ const Detail = observer(() => {
                     'x-component-props': {
                       placeholder: '请输入模版ID',
                     },
+                    'x-reactions': {
+                      dependencies: ['configId'],
+                      fulfill: {
+                        run: '{{useAsyncDataSource(getAliyunTemplates($deps[0]))}}',
+                      },
+                    },
                   },
                   phoneNumber: {
                     title: '收信人',
-                    'x-component': 'Input',
+                    'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
                       tooltip: '请输入收信人',
@@ -504,7 +564,7 @@ const Detail = observer(() => {
                   },
                   signName: {
                     title: '签名',
-                    'x-component': 'Input',
+                    'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
                       tooltip: '请输入签名',
@@ -512,6 +572,12 @@ const Detail = observer(() => {
                     'x-component-props': {
                       placeholder: '请输入签名',
                     },
+                    'x-reactions': {
+                      dependencies: ['configId'],
+                      fulfill: {
+                        run: '{{useAsyncDataSource(getAliyunSigns($deps[0]))}}',
+                      },
+                    },
                   },
                   // code	String	短信-模板ID
                   // signName	String	短信-签名
@@ -549,12 +615,55 @@ const Detail = observer(() => {
               //   },
               // },
               attachments: {
-                'x-component': 'FUpload',
+                type: 'array',
+                title: '附件信息',
                 'x-decorator': 'FormItem',
-                title: '附件',
-                'x-component-props': {
-                  type: 'file',
-                  placeholder: '请上传文件',
+                'x-component': 'ArrayItems',
+                'x-decorator-props': {
+                  style: {
+                    width: '100%',
+                  },
+                },
+                items: {
+                  type: 'object',
+
+                  'x-component': 'FormGrid',
+                  'x-component-props': {
+                    maxColumns: 24,
+                    minColumns: 24,
+                  },
+
+                  properties: {
+                    file: {
+                      'x-component': 'FUpload',
+                      'x-decorator': 'FormItem',
+                      'x-decorator-props': {
+                        style: {
+                          width: '100%',
+                        },
+                        gridSpan: 23,
+                      },
+                      'x-component-props': {
+                        type: 'file',
+                        placeholder: '请上传文件',
+                      },
+                    },
+                    remove: {
+                      type: 'void',
+                      'x-decorator': 'FormItem',
+                      'x-component': 'ArrayItems.Remove',
+                      'x-decorator-props': {
+                        gridSpan: 1,
+                      },
+                    },
+                  },
+                },
+                properties: {
+                  add: {
+                    type: 'void',
+                    'x-component': 'ArrayItems.Addition',
+                    title: '添加附件',
+                  },
                 },
               },
               // subject: {
@@ -668,7 +777,21 @@ const Detail = observer(() => {
         <Row>
           <Col span={10}>
             <Form className={styles.form} form={form} layout={'vertical'}>
-              <SchemaField schema={schema} scope={{ getConfig, useAsyncDataSource }} />
+              <SchemaField
+                schema={schema}
+                scope={{
+                  getConfig,
+                  getDingTalkDept,
+                  getDingTalkDeptTree,
+                  getDingTalkUser,
+                  getWeixinDept,
+                  getWeixinTags,
+                  getWeixinUser,
+                  getAliyunSigns,
+                  getAliyunTemplates,
+                  useAsyncDataSource,
+                }}
+              />
               <FormButtonGroup.Sticky>
                 <FormButtonGroup.FormItem>
                   <Submit onSubmit={handleSave}>保存</Submit>

+ 74 - 0
src/pages/notice/Template/Log/index.tsx

@@ -0,0 +1,74 @@
+import { Modal } from 'antd';
+import { observer } from '@formily/react';
+import { service, state } from '..';
+import ProTable, { ProColumns } from '@jetlinks/pro-table';
+import SearchComponent from '@/components/SearchComponent';
+import { useLocation } from 'umi';
+import { InfoCircleOutlined } from '@ant-design/icons';
+
+const Log = observer(() => {
+  const location = useLocation<{ id: string }>();
+  const id = (location as any).query?.id;
+
+  const columns: ProColumns<LogItem>[] = [
+    {
+      dataIndex: 'config',
+      title: '通知配置',
+    },
+    {
+      dataIndex: 'sendTime',
+      title: '发送时间',
+    },
+    {
+      dataIndex: 'state',
+      title: '状态',
+    },
+    {
+      dataIndex: 'action',
+      title: '操作',
+      render: (text, record) => [
+        <a
+          onClick={() => {
+            Modal.info({
+              title: '详情信息',
+              content: (
+                <div>
+                  <p>这是通知记录的详细信息。。。。。</p>
+                  <p>这是通知记录的详细信息。。。。。</p>
+                  {JSON.stringify(record)}
+                </div>
+              ),
+              onOk() {},
+            });
+          }}
+        >
+          <InfoCircleOutlined />
+        </a>,
+      ],
+    },
+  ];
+  return (
+    <Modal onCancel={() => (state.log = false)} title="通知记录" width={'70vw'} visible={state.log}>
+      <SearchComponent
+        defaultParam={[{ column: 'type$IN', value: id }]}
+        field={columns}
+        onSearch={(data) => {
+          // actionRef.current?.reset?.();
+          // setParam(data);
+          console.log(data);
+        }}
+        enableSave={false}
+      />
+      <ProTable<LogItem>
+        search={false}
+        pagination={{
+          pageSize: 5,
+        }}
+        columns={columns}
+        request={async (params) => service.query(params)}
+      ></ProTable>
+    </Modal>
+  );
+});
+
+export default Log;

+ 67 - 516
src/pages/notice/Template/index.tsx

@@ -10,21 +10,34 @@ import {
   DeleteOutlined,
   EditOutlined,
   PlusOutlined,
+  UnorderedListOutlined,
 } from '@ant-design/icons';
-import { Button, Tooltip } from 'antd';
+import { Button, Popconfirm, Tooltip } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 // import type { ISchema } from '@formily/json-schema';
 import Service from '@/pages/notice/Template/service';
+import ConfigService from '@/pages/notice/Config/service';
 import SearchComponent from '@/components/SearchComponent';
 // import Detail from '@/pages/notice/Template/Detail';
 import { history, useLocation } from 'umi';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { model } from '@formily/reactive';
+import Debug from './Debug';
+import Log from '@/pages/notice/Template/Log';
+import { downloadObject } from '@/utils/util';
+import moment from 'moment';
 
 export const service = new Service('notifier/template');
+
+export const configService = new ConfigService('notifier/config');
 export const state = model<{
   current?: TemplateItem;
-}>({});
+  debug?: boolean;
+  log?: boolean;
+}>({
+  debug: false,
+  log: false,
+});
 const Template = () => {
   const intl = useIntl();
   const location = useLocation<{ id: string }>();
@@ -43,15 +56,12 @@ const Template = () => {
       dataIndex: 'type',
       title: intl.formatMessage({
         id: 'pages.notice.config.type',
-        defaultMessage: '通知类型',
+        defaultMessage: '通知方式',
       }),
     },
     {
-      dataIndex: 'provider',
-      title: intl.formatMessage({
-        id: 'pages.table.provider',
-        defaultMessage: '服务商',
-      }),
+      dataIndex: 'description',
+      title: '说明',
     },
     {
       title: intl.formatMessage({
@@ -78,17 +88,34 @@ const Template = () => {
             <EditOutlined />
           </Tooltip>
         </a>,
-        <a key="delete">
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.data.option.remove',
-              defaultMessage: '删除',
-            })}
-          >
-            <DeleteOutlined />
-          </Tooltip>
-        </a>,
-        <a key="download">
+        <Popconfirm
+          key="delete"
+          title="确认删除?"
+          onConfirm={async () => {
+            await service.remove(record.id);
+            actionRef.current?.reload();
+          }}
+        >
+          <a key="delete">
+            <Tooltip
+              title={intl.formatMessage({
+                id: 'pages.data.option.remove',
+                defaultMessage: '删除',
+              })}
+            >
+              <DeleteOutlined />
+            </Tooltip>
+          </a>
+        </Popconfirm>,
+        <a
+          key="download"
+          onClick={() => {
+            downloadObject(
+              record,
+              `${record.name}-${moment(new Date()).format('YYYY/MM/DD HH:mm:ss')}`,
+            );
+          }}
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.data.option.download',
@@ -98,7 +125,13 @@ const Template = () => {
             <ArrowDownOutlined />
           </Tooltip>
         </a>,
-        <a key="debug">
+        <a
+          key="debug"
+          onClick={() => {
+            state.debug = true;
+            state.current = record;
+          }}
+        >
           <Tooltip
             title={intl.formatMessage({
               id: 'pages.notice.option.debug',
@@ -108,509 +141,25 @@ const Template = () => {
             <BugOutlined />
           </Tooltip>
         </a>,
+        <a
+          key="log"
+          onClick={() => {
+            state.log = true;
+          }}
+        >
+          <Tooltip title="通知记录">
+            <UnorderedListOutlined />
+          </Tooltip>
+        </a>,
       ],
     },
   ];
-  // const providerRef = useRef<NetworkType[]>([]);
-
-  // const getTypes = async () =>
-  //   service.getTypes().then((resp) => {
-  //     providerRef.current = resp.result;
-  //     return resp.result.map((item: NetworkType) => ({
-  //       label: item.name,
-  //       value: item.id,
-  //     }));
-  //   });
-  //
-  // const formEvent = () => {
-  //   onFieldValueChange('type', async (field, f) => {
-  //     const type = field.value;
-  //     if (!type) return;
-  //     f.setFieldState('provider', (state) => {
-  //       state.value = undefined;
-  //       state.dataSource = providerRef.current
-  //         .find((item) => type === item.id)
-  //         ?.providerInfos.map((i) => ({ label: i.name, value: i.id }));
-  //     });
-  //   });
-  // };
-  //
-  // const handleNetwork = (field: Field) => {
-  //   const provider = field.query('...provider').get('value');
-  //   const defaultMessage = {
-  //     MQTT_CLIENT:
-  //       'qos1 /device/${#deviceId}\n' +
-  //       '\n' +
-  //       '${T(com.alibaba.fastjson.JSON).toJSONString(#this)}',
-  //     HTTP_CLIENT:
-  //       'POST http://[host]:[port]/api\n' +
-  //       'Content-Type: application/json\n' +
-  //       '\n' +
-  //       '${T(com.alibaba.fastjson.JSON).toJSONString(#this)}',
-  //   };
-  //   field.value = defaultMessage[provider];
-  // };
-  //
-  // const schema: ISchema = {
-  //   type: 'object',
-  //   properties: {
-  //     name: {
-  //       type: 'string',
-  //       title: '名称',
-  //       required: true,
-  //       'x-component': 'Input',
-  //       'x-decorator': 'FormItem',
-  //     },
-  //     grid: {
-  //       type: 'void',
-  //       'x-component': 'FormGrid',
-  //       'x-decorator': 'FormItem',
-  //       properties: {
-  //         type: {
-  //           type: 'string',
-  //           title: '通知类型',
-  //           'x-component': 'Select',
-  //           'x-decorator': 'FormItem',
-  //           'x-decorator-props': {
-  //             labelCol: 8,
-  //             wrapperCol: 12,
-  //           },
-  //           'x-reactions': ['{{useAsyncDataSource(getTypes)}}'],
-  //         },
-  //         provider: {
-  //           type: 'string',
-  //           title: '服务商',
-  //           'x-component': 'Select',
-  //           'x-decorator-props': {
-  //             labelCol: 4,
-  //             wrapperCol: 16,
-  //           },
-  //           'x-decorator': 'FormItem',
-  //         },
-  //       },
-  //     },
-  //     template: {
-  //       type: 'object',
-  //       properties: {
-  //         voice: {
-  //           type: 'void',
-  //           properties: {
-  //             ttsCode: {
-  //               type: 'string',
-  //               title: '模版ID',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             calledShowNumbers: {
-  //               type: 'string',
-  //               title: '被叫显号',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             CalledNumber: {
-  //               type: 'string',
-  //               title: '被叫号码',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             PlayTimes: {
-  //               type: 'string',
-  //               title: '播放次数',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="voice"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //         sms: {
-  //           type: 'void',
-  //           properties: {
-  //             test: {
-  //               type: 'void',
-  //               properties: {
-  //                 text: {
-  //                   type: 'string',
-  //                   title: '应用ID',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                 },
-  //                 sendTo: {
-  //                   type: 'string',
-  //                   title: '收件人',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                   'x-component-props': {
-  //                     placeholder: '多个收件人以 , 分割',
-  //                   },
-  //                 },
-  //               },
-  //               'x-visible': false,
-  //               'x-reactions': {
-  //                 dependencies: ['...provider'],
-  //                 fulfill: {
-  //                   state: {
-  //                     visible: '{{$deps[0]==="test"}}',
-  //                   },
-  //                 },
-  //               },
-  //             },
-  //             aliyunSms: {
-  //               type: 'void',
-  //               properties: {
-  //                 code: {
-  //                   type: 'string',
-  //                   title: '模版编码',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                   required: true,
-  //                   'x-component-props': {
-  //                     placeholder: '阿里云短信模版编码',
-  //                   },
-  //                 },
-  //                 signName: {
-  //                   type: 'string',
-  //                   title: '签名',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                   required: true,
-  //                   'x-component-props': {
-  //                     placeholder: '阿里云短信模版签名',
-  //                   },
-  //                 },
-  //                 phoneNumber: {
-  //                   type: 'string',
-  //                   title: '收件人',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                   'x-component-props': {
-  //                     placeholder: '短信接收者,暂只支持单个联系人',
-  //                   },
-  //                 },
-  //               },
-  //               'x-visible': false,
-  //               'x-reactions': {
-  //                 dependencies: ['...provider'],
-  //                 fulfill: {
-  //                   state: {
-  //                     visible: '{{$deps[0]==="aliyunSms"}}',
-  //                   },
-  //                 },
-  //               },
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="sms"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //         email: {
-  //           type: 'void',
-  //           properties: {
-  //             subject: {
-  //               type: 'string',
-  //               title: '标题',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             sendTo: {
-  //               type: 'string',
-  //               title: '收件人',
-  //               'x-component': 'Input.TextArea',
-  //               'x-decorator': 'FormItem',
-  //               'x-component-props': {
-  //                 placeholder: '多个收件人以  ,  分隔',
-  //               },
-  //             },
-  //             attachments: {
-  //               type: 'string',
-  //               title: '附件',
-  //               'x-component': 'FUpload',
-  //               'x-decorator': 'FormItem',
-  //               'x-component-props': {
-  //                 type: 'multi',
-  //               },
-  //             },
-  //             emailEditor: {
-  //               type: 'string',
-  //               title: '正文',
-  //               'x-component': 'FBraftEditor',
-  //               'x-decorator': 'FormItem',
-  //               'x-component-props': {
-  //                 style: {
-  //                   height: '300px',
-  //                 },
-  //                 contentStyle: {
-  //                   height: '200px',
-  //                   // overflowY: 'auto',
-  //                 },
-  //               },
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="email"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //         weixin: {
-  //           type: 'void',
-  //           properties: {
-  //             agentId: {
-  //               type: 'string',
-  //               title: '应用ID',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             toUser: {
-  //               type: 'string',
-  //               title: '收信人ID',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             toParty: {
-  //               type: 'string',
-  //               title: '收信部门ID',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             toTag: {
-  //               type: 'string',
-  //               title: '按标签推送',
-  //               'x-component': 'Input',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //             message: {
-  //               type: 'string',
-  //               title: '内容',
-  //               'x-component': 'Input.TextArea',
-  //               'x-decorator': 'FormItem',
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="weixin"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //         dingTalk: {
-  //           type: 'void',
-  //           properties: {
-  //             dingTalkRobotWebHook: {
-  //               type: 'void',
-  //               properties: {
-  //                 messageType: {
-  //                   title: '消息类型',
-  //                   type: 'string',
-  //                   'x-component': 'Select',
-  //                   'x-decorator': 'FormItem',
-  //                   enum: ['text', 'markdown', 'link'],
-  //                 },
-  //                 text: {
-  //                   type: 'object',
-  //                   properties: {
-  //                     content: {
-  //                       title: '通知内容',
-  //                       type: 'string',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input.TextArea',
-  //                     },
-  //                   },
-  //                   'x-visible': false,
-  //                   'x-reactions': {
-  //                     dependencies: ['.messageType'],
-  //                     fulfill: {
-  //                       state: {
-  //                         visible: '{{$deps[0]==="text"}}',
-  //                       },
-  //                     },
-  //                   },
-  //                 },
-  //                 markdown: {
-  //                   type: 'object',
-  //                   properties: {
-  //                     title: {
-  //                       title: '标题',
-  //                       type: 'string',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input',
-  //                     },
-  //                     text: {
-  //                       title: '内容',
-  //                       type: 'string',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input.TextArea',
-  //                     },
-  //                   },
-  //                   'x-visible': false,
-  //                   'x-reactions': {
-  //                     dependencies: ['.messageType'],
-  //                     fulfill: {
-  //                       state: {
-  //                         visible: '{{$deps[0]==="markdown"}}',
-  //                       },
-  //                     },
-  //                   },
-  //                 },
-  //                 link: {
-  //                   type: 'object',
-  //                   properties: {
-  //                     title: {
-  //                       title: '标题',
-  //                       type: 'string',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input',
-  //                     },
-  //                     text: {
-  //                       title: '内容',
-  //                       type: 'string',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input.TextArea',
-  //                     },
-  //                     picUrl: {
-  //                       title: '图片连接',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'FUpload',
-  //                     },
-  //                     messageUrl: {
-  //                       title: '内容连接',
-  //                       'x-decorator': 'FormItem',
-  //                       'x-component': 'Input.TextArea',
-  //                     },
-  //                   },
-  //                   'x-visible': false,
-  //                   'x-reactions': {
-  //                     dependencies: ['.messageType'],
-  //                     fulfill: {
-  //                       state: {
-  //                         visible: '{{$deps[0]==="link"}}',
-  //                       },
-  //                     },
-  //                   },
-  //                 },
-  //               },
-  //               'x-visible': false,
-  //               'x-reactions': {
-  //                 dependencies: ['...provider'],
-  //                 fulfill: {
-  //                   state: {
-  //                     visible: '{{$deps[0]==="dingTalkRobotWebHook"}}',
-  //                   },
-  //                 },
-  //               },
-  //             },
-  //             dingTalkMessage: {
-  //               type: 'void',
-  //               properties: {
-  //                 agentId: {
-  //                   type: 'string',
-  //                   title: '应用ID',
-  //                   'x-component': 'Input',
-  //                   'x-decorator': 'FormItem',
-  //                 },
-  //                 userIdList: {
-  //                   type: 'string',
-  //                   title: '收信人ID',
-  //                   'x-component': 'Input',
-  //                   'x-decorator': 'FormItem',
-  //                 },
-  //                 departmentIdList: {
-  //                   type: 'string',
-  //                   title: '收信部门ID',
-  //                   'x-component': 'Input',
-  //                   'x-decorator': 'FormItem',
-  //                 },
-  //                 toAllUser: {
-  //                   type: 'string',
-  //                   title: '全部用户',
-  //                   'x-component': 'Select',
-  //                   'x-decorator': 'FormItem',
-  //                   enum: [
-  //                     { label: '是', value: true },
-  //                     { label: '否', value: false },
-  //                   ],
-  //                 },
-  //                 message: {
-  //                   type: 'string',
-  //                   title: '内容',
-  //                   'x-component': 'Input.TextArea',
-  //                   'x-decorator': 'FormItem',
-  //                 },
-  //               },
-  //               'x-visible': false,
-  //               'x-reactions': {
-  //                 dependencies: ['...provider'],
-  //                 fulfill: {
-  //                   state: {
-  //                     visible: '{{$deps[0]==="dingTalkMessage"}}',
-  //                   },
-  //                 },
-  //               },
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="dingTalk"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //         network: {
-  //           type: 'void',
-  //           properties: {
-  //             text: {
-  //               type: 'string',
-  //               title: '消息',
-  //               'x-component': 'Input.TextArea',
-  //               'x-decorator': 'FormItem',
-  //               'x-component-props': {
-  //                 rows: 5,
-  //               },
-  //               'x-reactions': '{{handleNetwork}}',
-  //             },
-  //           },
-  //           'x-visible': false,
-  //           'x-reactions': {
-  //             dependencies: ['...type'],
-  //             fulfill: {
-  //               state: {
-  //                 visible: '{{$deps[0]==="network"}}',
-  //               },
-  //             },
-  //           },
-  //         },
-  //       },
-  //     },
-  //   },
-  // };
 
   const [param, setParam] = useState({});
   return (
     <PageContainer className={'page-title-show'}>
       <SearchComponent
+        defaultParam={[{ column: 'type$IN', value: id }]}
         field={columns}
         onSearch={(data) => {
           actionRef.current?.reset?.();
@@ -618,6 +167,7 @@ const Template = () => {
         }}
       />
       <ProTable<TemplateItem>
+        rowKey="id"
         search={false}
         params={param}
         columns={columns}
@@ -643,7 +193,8 @@ const Template = () => {
         ]}
         request={async (params) => service.query(params)}
       />
-      {/*<Detail />*/}
+      <Debug />
+      <Log />
     </PageContainer>
   );
 };

+ 34 - 0
src/pages/notice/Template/service.ts

@@ -12,6 +12,40 @@ class Service extends BaseService<TemplateItem> {
     request(`${this.uri}/${type}/${provider}/metadata`, {
       method: 'GET',
     });
+
+  public getConfigs = (data: any) =>
+    request(`${SystemConst.API_BASE}/notifier/config/_query`, {
+      method: 'POST',
+      data,
+    });
+
+  public sendMessage = (notifierId: string) =>
+    request(`${SystemConst.API_BASE}/notifier/${notifierId}/_send`, {
+      method: 'POST',
+    });
+
+  dingTalk = {
+    getDepartments: (id: string) =>
+      request(`${SystemConst.API_BASE}/notifier/dingtalk/corp/${id}/departments`),
+    getDepartmentsTree: (id: string) =>
+      request(`${SystemConst.API_BASE}/notifier/dingtalk/corp/${id}/departments/tree`),
+    getUserByDepartment: (id: string, departmentId: string) =>
+      request(`${SystemConst.API_BASE}/notifier/dingtalk/corp/${id}/${departmentId}/users`),
+  };
+
+  weixin = {
+    getTags: (id: string) => request(`${SystemConst.API_BASE}/notifier/wechat/corp/${id}/tags`),
+    getDepartments: (id: string) =>
+      request(`${SystemConst.API_BASE}/notifier/wechat/corp/${id}/departments`),
+    getUserByDepartment: (id: string) =>
+      request(`${SystemConst.API_BASE}/notifier/wechat/corp/${id}/users`),
+  };
+
+  aliyun = {
+    getSigns: (id: string) => request(`${SystemConst.API_BASE}/notifier/sms/aliyun/${id}/signs`),
+    getTemplates: (id: string) =>
+      request(`${SystemConst.API_BASE}/notifier/sms/aliyun/${id}/templates`),
+  };
 }
 
 export default Service;

+ 8 - 0
src/pages/notice/Template/typings.d.ts

@@ -6,4 +6,12 @@ type TemplateItem = {
   provider: string;
   creatorId: string;
   createTime: number;
+  variableDefinitions: any;
+};
+
+type LogItem = {
+  id: string;
+  config: string;
+  sendTime: number;
+  state: string;
 };

+ 4 - 0
src/utils/BaseService.ts

@@ -23,6 +23,10 @@ class BaseService<T> implements IBaseService<T> {
     return request(`${this.uri}/_query/`, { data, method: 'POST' });
   }
 
+  queryNoPagingPost(data: any): Promise<unknown> {
+    return request(`${this.uri}/_query/no-paging?paging=false`, { data, method: 'POST' });
+  }
+
   queryNoPaging(params: any): Promise<unknown> {
     return request(`${this.uri}/_query/no-paging?paging=false`, { params, method: 'GET' });
   }

Разница между файлами не показана из-за своего большого размера
+ 4924 - 3214
yarn.lock