瀏覽代碼

1. 修复编辑联系人标签时,标签候选项不能按联系人类型返显的问题
2. 增加 sop 任务列表页面

boweniac 9 月之前
父節點
當前提交
7c341814a8

+ 4 - 0
.gitignore

@@ -33,3 +33,7 @@ package-lock.json
 pnpm-lock.yaml
 
 .history
+
+.env.development
+.env.production
+.vscode/launch.json

+ 23 - 0
src/api/wechat/model/sopTaskModel.ts

@@ -0,0 +1,23 @@
+import { BaseListResp } from '@/api/model/baseModel';
+
+/**
+ *  @description: SopTask info response
+ */
+export interface SopTaskInfo {
+  id?: number;
+  createdAt?: number;
+  updatedAt?: number;
+  status?: number;
+  name?: string;
+  botWxidList?: []*string;
+  type?: number;
+  planStartTime?: number;
+  planEndTime?: number;
+  creatorId?: number;
+}
+
+/**
+ *  @description: SopTask list response
+ */
+
+export type SopTaskListResp = BaseListResp<SopTaskInfo>;

+ 74 - 0
src/api/wechat/sopTask.ts

@@ -0,0 +1,74 @@
+import { defHttp } from '@/utils/http/axios';
+import { ErrorMessageMode } from '/#/axios';
+import { BaseDataResp, BaseListReq, BaseResp, BaseIDsReq, BaseIDReq } from '@/api/model/baseModel';
+import { SopTaskInfo, SopTaskListResp } from './model/sopTaskModel';
+
+enum Api {
+  CreateSopTask = '/wechat-api/sop_task/create',
+  UpdateSopTask = '/wechat-api/sop_task/update',
+  GetSopTaskList = '/wechat-api/sop_task/list',
+  DeleteSopTask = '/wechat-api/sop_task/delete',
+  GetSopTaskById = '/wechat-api/sop_task',
+}
+
+/**
+ * @description: Get sop task list
+ */
+
+export const getSopTaskList = (params: BaseListReq, mode: ErrorMessageMode = 'notice') => {
+  return defHttp.post<BaseDataResp<SopTaskListResp>>(
+    { url: Api.GetSopTaskList, params },
+    { errorMessageMode: mode },
+  );
+};
+
+/**
+ *  @description: Create a new sop task
+ */
+export const createSopTask = (params: SopTaskInfo, mode: ErrorMessageMode = 'notice') => {
+  return defHttp.post<BaseResp>(
+    { url: Api.CreateSopTask, params: params },
+    {
+      errorMessageMode: mode,
+      successMessageMode: mode,
+    },
+  );
+};
+
+/**
+ *  @description: Update the sop task
+ */
+export const updateSopTask = (params: SopTaskInfo, mode: ErrorMessageMode = 'notice') => {
+  return defHttp.post<BaseResp>(
+    { url: Api.UpdateSopTask, params: params },
+    {
+      errorMessageMode: mode,
+      successMessageMode: mode,
+    },
+  );
+};
+
+/**
+ *  @description: Delete sop tasks
+ */
+export const deleteSopTask = (params: BaseIDsReq, mode: ErrorMessageMode = 'notice') => {
+  return defHttp.post<BaseResp>(
+    { url: Api.DeleteSopTask, params: params },
+    {
+      errorMessageMode: mode,
+      successMessageMode: mode,
+    },
+  );
+};
+
+/**
+ *  @description: Get sop task By ID
+ */
+export const getSopTaskById = (params: BaseIDReq, mode: ErrorMessageMode = 'notice') => {
+  return defHttp.post<BaseDataResp<SopTaskInfo>>(
+    { url: Api.GetSopTaskById, params: params },
+    {
+      errorMessageMode: mode,
+    },
+  );
+};

+ 1 - 0
src/components/Drawer/src/typing.ts

@@ -8,6 +8,7 @@ export interface DrawerInstance {
 }
 
 export interface ReturnMethods extends DrawerInstance {
+  openGroupLabelDrawer: <T = any>(open?: boolean, data?: T, openOnSet?: boolean) => void;
   openDrawer: <T = any>(open?: boolean, data?: T, openOnSet?: boolean) => void; 
   openDrawerMsg: <T = any>(open?: boolean, data?: T, openOnSet?: boolean) => void;
   closeDrawer: () => void;

+ 15 - 0
src/components/Drawer/src/useDrawer.ts

@@ -72,7 +72,22 @@ export function useDrawer(): UseDrawerReturnType {
     getOpen: computed((): boolean => {
       return openData[~~unref(uid)];
     }),
+    openGroupLabelDrawer: <T = any>(open = true, data?: T, openOnSet = true): void => {
+      getInstance()?.setDrawerProps({
+        open,
+      });
+      if (!data) return;
 
+      if (openOnSet) {
+        dataTransferRef[unref(uid)] = null;
+        dataTransferRef[unref(uid)] = toRaw(data);
+        return;
+      }
+      const equal = isEqual(toRaw(dataTransferRef[unref(uid)]), toRaw(data));
+      if (!equal) {
+        dataTransferRef[unref(uid)] = toRaw(data);
+      }
+    },
     openDrawer: <T = any>(open = true, data?: T, openOnSet = true): void => {
       getInstance()?.setDrawerProps({
         open,

+ 48 - 0
src/locales/lang/en/wechat.ts

@@ -107,4 +107,52 @@ export default {
     editLabelRelationship: 'Edit LabelRelationship',
     labelRelationshipList: 'LabelRelationship List',
   },
+  sopTask: {
+    status: 'Status',
+    name: 'Name',
+    botWxidList: 'BotWxidList',
+    type: 'Type',
+    planStartTime: 'PlanStartTime',
+    planEndTime: 'PlanEndTime',
+    creatorId: 'CreatorId',
+    addSopTask: 'Add SopTask',
+    editSopTask: 'Edit SopTask',
+    sopTaskList: 'SopTask List',
+  },
+  sopTask: {
+    status: 'Status',
+    name: 'Name',
+    botWxidList: 'BotWxidList',
+    type: 'Type',
+    planStartTime: 'PlanStartTime',
+    planEndTime: 'PlanEndTime',
+    creatorId: 'CreatorId',
+    addSopTask: 'Add SopTask',
+    editSopTask: 'Edit SopTask',
+    sopTaskList: 'SopTask List',
+  },
+  sopTask: {
+    status: 'Status',
+    name: 'Name',
+    botWxidList: 'BotWxidList',
+    type: 'Type',
+    planStartTime: 'PlanStartTime',
+    planEndTime: 'PlanEndTime',
+    creatorId: 'CreatorId',
+    addSopTask: 'Add SopTask',
+    editSopTask: 'Edit SopTask',
+    sopTaskList: 'SopTask List',
+  },
+  sopTask: {
+    status: 'Status',
+    name: 'Name',
+    botWxidList: 'BotWxidList',
+    type: 'Type',
+    planStartTime: 'PlanStartTime',
+    planEndTime: 'PlanEndTime',
+    creatorId: 'CreatorId',
+    addSopTask: 'Add SopTask',
+    editSopTask: 'Edit SopTask',
+    sopTaskList: 'SopTask List',
+  },
 };

+ 13 - 0
src/locales/lang/zh-CN/wechat.ts

@@ -70,4 +70,17 @@ export default {
     editLabelRelationship: '编辑 LabelRelationship',
     labelRelationshipList: 'LabelRelationship 列表',
   },
+  sopTask: {
+    status: 'Status',
+    name: '名称',
+    botWxidList: '微信机器人',
+    type: '类型',
+    planStartTime: '计划开始时间',
+    planEndTime: '计划结束时间',
+    creatorId: 'CreatorId',
+    addSopTask: '添加',
+    editSopTask: '编辑',
+    sopTaskList: 'SOP 列表',
+  },
+  sop_task_type: ['好友', '群组', '公众号', '企业微信联系人'],
 };

+ 84 - 0
src/views/wechat/contact/GroupLabelDrawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <BasicDrawer
+    v-bind="$attrs"
+    @register="registerDrawer"
+    showFooter
+    :title="getTitle"
+    width="500px"
+    @ok="handleSubmit"
+  >
+    <BasicForm @register="registerForm" />
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, computed, unref } from 'vue';
+  import { BasicForm, useForm } from '@/components/Form/index';
+  import { groupLabelFormSchema } from './contact.data';
+  import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
+  import { useI18n } from 'vue-i18n';
+
+  import { createContact } from '@/api/wechat/contact';
+  import {updateLabelRelationships} from "@/api/wechat/labelRelationship";
+
+  export default defineComponent({
+    name: 'GroupLabelDrawer',
+    components: { BasicDrawer, BasicForm },
+    emits: ['success', 'register'],
+    setup(_, { emit }) {
+      const isUpdate = ref(true);
+      const { t } = useI18n();
+
+      const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
+        labelWidth: 160,
+        baseColProps: { span: 24 },
+        layout: 'vertical',
+        schemas: groupLabelFormSchema,
+        showActionButtonGroup: false,
+      });
+
+      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        resetFields();
+        setDrawerProps({ confirmLoading: false });
+
+        isUpdate.value = !!data?.isUpdate;
+
+        if (unref(isUpdate)) {
+          setFieldsValue({
+            ...data.record,
+          });
+        }
+      });
+
+      const getTitle = computed(() =>
+        !unref(isUpdate) ? t('wechat.contact.addContact') : t('wechat.contact.editContact'),
+      );
+
+      async function handleSubmit() {
+        const values = await validate();
+        console.log(values,'values')
+        setDrawerProps({ confirmLoading: true });
+        values['id'] = unref(isUpdate) ? Number(values['id']) : 0;
+
+        const labelRelationshipsInfo = {
+          status: 1,
+          labelIds: values.labelRelationships,
+          contactId: values.id,
+        };
+
+        let result = unref(isUpdate) ? await updateLabelRelationships(labelRelationshipsInfo) : await createContact(values);
+        if (result.code === 0) {
+          closeDrawer();
+          emit('success');
+        }
+        setDrawerProps({ confirmLoading: false });
+      }
+
+      return {
+        registerDrawer,
+        registerForm,
+        getTitle,
+        handleSubmit,
+      };
+    },
+  });
+</script>

+ 35 - 2
src/views/wechat/contact/contact.data.ts

@@ -95,12 +95,12 @@ export const formSchema: FormSchema[] = [
           return { label: label.label, value: label.value };
         });
       }),
-      params: { page: 1, pageSize: 100, type: renderCallbackParams.formModel.type },
+      params: { page: 1, pageSize: 100, type: 1 },
       mode: 'tags',
       tokenSeparators: [','],
       change: 'handleChange', // 这里你需要在你的组件中定义 handleChange 函数
     }),
-    required: true,
+    required: false,
   },
   // {
   //   field: 'wxWxid',
@@ -199,3 +199,36 @@ export const formSchema: FormSchema[] = [
   //   },
   // },
 ];
+
+export const groupLabelFormSchema: FormSchema[] = [
+  {
+    field: 'id',
+    label: 'ID',
+    component: 'Input',
+    show: false,
+  },
+  {
+    field: 'type',
+    label: t('wechat.contact.type'),
+    component: 'InputNumber',
+    show: false,
+    required: false,
+  },
+  {
+    field: 'labelRelationships',
+    label: t('wechat.contact.labels'),
+    component: 'ApiSelect',
+    componentProps: (renderCallbackParams) => ({
+      api: (params) => getLabelSelectList(params).then(response => {
+        return response.data.map((label) => {
+          return { label: label.label, value: label.value };
+        });
+      }),
+      params: { page: 1, pageSize: 100, type: 2 },
+      mode: 'tags',
+      tokenSeparators: [','],
+      change: 'handleChange', // 这里你需要在你的组件中定义 handleChange 函数
+    }),
+    required: false,
+  }
+];

+ 19 - 9
src/views/wechat/contact/index.vue

@@ -43,34 +43,36 @@
         </template>
       </template>
     </BasicTable>
+    <GroupLabelDrawer @register="registerGroupLabelDrawer" @success="handleSuccess" />
     <ContactDrawer @register="registerDrawer" @success="handleSuccess" />
     <SendMsgDrawer  @register="registerDrawerMsg" @success="handleSuccess1"/>
   </div>
 </template>
 <script lang="ts">
-import {createVNode, defineComponent, onMounted, ref, watch} from 'vue';
+import {createVNode, defineComponent, ref} from 'vue';
   import { Modal } from 'ant-design-vue';
   import { ExclamationCircleOutlined } from '@ant-design/icons-vue/lib/icons';
   import { BasicTable, useTable, TableAction } from '@/components/Table';
   import { Button } from '@/components/Button';
 
   import { useDrawer } from '@/components/Drawer';
+  import GroupLabelDrawer from './GroupLabelDrawer.vue';
   import ContactDrawer from './ContactDrawer.vue';
-  import SendMsgDrawer from './SendMsgDrawer.vue'
+  import SendMsgDrawer from './SendMsgDrawer.vue';
   import { useI18n } from 'vue-i18n';
 
-import {columns, formSchema, searchFormSchema} from './contact.data';
+import {columns, searchFormSchema} from './contact.data';
   import { getContactList, deleteContact } from '@/api/wechat/contact';
-  import {getLabelList} from "@/api/wechat/label";
 
   export default defineComponent({
     name: 'ContactManagement',
-    components: { BasicTable,SendMsgDrawer, ContactDrawer, TableAction, Button },
+    components: { BasicTable,SendMsgDrawer, ContactDrawer, GroupLabelDrawer, TableAction, Button },
     setup() {
       const { t } = useI18n();
       const selectedIds = ref<number[] | string[]>();
       const showDeleteButton = ref<boolean>(false);
 
+      const [registerGroupLabelDrawer, { openGroupLabelDrawer }] = useDrawer();
       const [registerDrawer, { openDrawer }] = useDrawer();
       const [registerDrawerMsg,{ openDrawerMsg }] = useDrawer();
       const [registerTable, { reload }] = useTable({
@@ -109,10 +111,17 @@ import {columns, formSchema, searchFormSchema} from './contact.data';
       }
 
       function handleEdit(record: Recordable) {
-        openDrawer(true, {
-          record,
-          isUpdate: true,
-        });
+        if (record.type == 1) {
+          openDrawer(true, {
+            record,
+            isUpdate: true,
+          });
+        } else {
+          openGroupLabelDrawer(true, {
+            record,
+            isUpdate: true,
+          });
+        }
       }
       function handleMsg(record: Recordable) {
         console.log(record,'"')
@@ -172,6 +181,7 @@ import {columns, formSchema, searchFormSchema} from './contact.data';
       return {
         t,
         registerTable,
+        registerGroupLabelDrawer,
         registerDrawer,
         registerDrawerMsg,
         handleCreate,

+ 75 - 0
src/views/wechat/sop_task/SopTaskDrawer.vue

@@ -0,0 +1,75 @@
+<template>
+  <BasicDrawer
+    v-bind="$attrs"
+    @register="registerDrawer"
+    showFooter
+    :title="getTitle"
+    width="500px"
+    @ok="handleSubmit"
+  >
+    <BasicForm @register="registerForm" />
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, computed, unref } from 'vue';
+  import { BasicForm, useForm } from '@/components/Form/index';
+  import { formSchema } from './sopTask.data';
+  import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
+  import { useI18n } from 'vue-i18n';
+
+  import { createSopTask, updateSopTask } from '@/api/wechat/sopTask';
+
+  export default defineComponent({
+    name: 'SopTaskDrawer',
+    components: { BasicDrawer, BasicForm },
+    emits: ['success', 'register'],
+    setup(_, { emit }) {
+      const isUpdate = ref(true);
+      const { t } = useI18n();
+
+      const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
+        labelWidth: 160,
+        baseColProps: { span: 24 },
+        layout: 'vertical',
+        schemas: formSchema,
+        showActionButtonGroup: false,
+      });
+
+      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        resetFields();
+        setDrawerProps({ confirmLoading: false });
+
+        isUpdate.value = !!data?.isUpdate;
+
+        if (unref(isUpdate)) {
+          setFieldsValue({
+            ...data.record,
+          });
+        }
+      });
+
+      const getTitle = computed(() =>
+        !unref(isUpdate) ? t('wechat.sopTask.addSopTask') : t('wechat.sopTask.editSopTask'),
+      );
+
+      async function handleSubmit() {
+        const values = await validate();
+        setDrawerProps({ confirmLoading: true });
+        values['id'] = unref(isUpdate) ? Number(values['id']) : 0;
+        let result = unref(isUpdate) ? await updateSopTask(values) : await createSopTask(values);
+        if (result.code === 0) {
+          closeDrawer();
+          emit('success');
+        }
+        setDrawerProps({ confirmLoading: false });
+      }
+
+      return {
+        registerDrawer,
+        registerForm,
+        getTitle,
+        handleSubmit,
+      };
+    },
+  });
+</script>

+ 151 - 0
src/views/wechat/sop_task/index.vue

@@ -0,0 +1,151 @@
+<template>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #tableTitle>
+        <Button
+          type="primary"
+          danger
+          preIcon="ant-design:delete-outlined"
+          v-if="showDeleteButton"
+          @click="handleBatchDelete"
+        >
+          {{ t('common.delete') }}
+        </Button>
+      </template>
+      <template #toolbar>
+        <a-button type="primary" @click="handleCreate">
+          {{ t('wechat.sopTask.addSopTask') }}
+        </a-button>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:note-edit-line',
+                onClick: handleEdit.bind(null, record),
+              },
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                popConfirm: {
+                  title: t('common.deleteConfirm'),
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
+      </template>
+    </BasicTable>
+    <SopTaskDrawer @register="registerDrawer" @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+  import { createVNode, defineComponent, ref } from 'vue';
+  import { Modal } from 'ant-design-vue';
+  import { ExclamationCircleOutlined } from '@ant-design/icons-vue/lib/icons';
+  import { BasicTable, useTable, TableAction } from '@/components/Table';
+  import { Button } from '@/components/Button';
+
+  import { useDrawer } from '@/components/Drawer';
+  import SopTaskDrawer from './SopTaskDrawer.vue';
+  import { useI18n } from 'vue-i18n';
+
+  import { columns, searchFormSchema } from './sopTask.data';
+  import { getSopTaskList, deleteSopTask } from '@/api/wechat/sopTask';
+
+  export default defineComponent({
+    name: 'SopTaskManagement',
+    components: { BasicTable, SopTaskDrawer, TableAction, Button },
+    setup() {
+      const { t } = useI18n();
+      const selectedIds = ref<number[] | string[]>();
+      const showDeleteButton = ref<boolean>(false);
+
+      const [registerDrawer, { openDrawer }] = useDrawer();
+      const [registerTable, { reload }] = useTable({
+        title: t('wechat.sopTask.sopTaskList'),
+        api: getSopTaskList,
+        columns,
+        formConfig: {
+          labelWidth: 120,
+          schemas: searchFormSchema,
+        },
+        useSearchForm: true,
+        showTableSetting: true,
+        bordered: true,
+        showIndexColumn: false,
+        clickToRowSelect: false,
+        actionColumn: {
+          width: 30,
+          title: t('common.action'),
+          dataIndex: 'action',
+          fixed: undefined,
+        },
+        rowKey: 'id',
+        rowSelection: {
+          type: 'checkbox',
+          onChange: (selectedRowKeys, _selectedRows) => {
+            selectedIds.value = selectedRowKeys as number[];
+            showDeleteButton.value = selectedRowKeys.length > 0;
+          },
+        },
+      });
+
+      function handleCreate() {
+        openDrawer(true, {
+          isUpdate: false,
+        });
+      }
+
+      function handleEdit(record: Recordable) {
+        openDrawer(true, {
+          record,
+          isUpdate: true,
+        });
+      }
+
+      async function handleDelete(record: Recordable) {
+        const result = await deleteSopTask({ ids: [record.id] });
+        if (result.code === 0) {
+          await reload();
+        }
+      }
+
+      async function handleBatchDelete() {
+        Modal.confirm({
+          title: t('common.deleteConfirm'),
+          icon: createVNode(ExclamationCircleOutlined),
+          async onOk() {
+            const result = await deleteSopTask({ ids: selectedIds.value as number[] });
+            if (result.code === 0) {
+              showDeleteButton.value = false;
+              await reload();
+            }
+          },
+          onCancel() {
+            console.log('Cancel');
+          },
+        });
+      }
+
+      async function handleSuccess() {
+        await reload();
+      }
+
+      return {
+        t,
+        registerTable,
+        registerDrawer,
+        handleCreate,
+        handleEdit,
+        handleDelete,
+        handleSuccess,
+        handleBatchDelete,
+        showDeleteButton,
+      };
+    },
+  });
+</script>

+ 152 - 0
src/views/wechat/sop_task/sopTask.data.ts

@@ -0,0 +1,152 @@
+import { BasicColumn, FormSchema } from '@/components/Table';
+import { useI18n } from '@/hooks/web/useI18n';
+import { formatToDateTime } from '@/utils/dateUtil';
+import { updateSopTask } from '@/api/wechat/sopTask';
+import { Switch } from 'ant-design-vue';
+import { h } from 'vue';
+
+const { t } = useI18n();
+
+export const columns: BasicColumn[] = [
+  {
+    title: t('wechat.sopTask.name'),
+    dataIndex: 'name',
+    width: 100,
+  },
+  // {
+  //   title: t('wechat.sopTask.botWxidList'),
+  //   dataIndex: 'botWxidList',
+  //   width: 100,
+  // },
+  {
+    title: t('wechat.sopTask.type'),
+    dataIndex: 'type',
+    width: 100,
+  },
+  {
+    title: t('wechat.sopTask.planStartTime'),
+    dataIndex: 'planStartTime',
+    width: 100,
+  },
+  {
+    title: t('wechat.sopTask.planEndTime'),
+    dataIndex: 'planEndTime',
+    width: 100,
+  },
+  // {
+  //   title: t('wechat.sopTask.creatorId'),
+  //   dataIndex: 'creatorId',
+  //   width: 100,
+  // },
+  {
+    title: t('common.status'),
+    dataIndex: 'status',
+    width: 50,
+    customRender: ({ record }) => {
+      if (!Reflect.has(record, 'pendingStatus')) {
+        record.pendingStatus = false;
+      }
+      return h(Switch, {
+        checked: record.status === 1,
+        checkedChildren: t('common.on'),
+        unCheckedChildren: t('common.off'),
+        loading: record.pendingStatus,
+        onChange(checked, _) {
+          record.pendingStatus = true;
+          const newStatus = checked ? 1 : 2;
+          updateSopTask({ id: record.id, status: newStatus })
+            .then(() => {
+              record.status = newStatus;
+            })
+            .finally(() => {
+              record.pendingStatus = false;
+            });
+        },
+      });
+    },
+  },
+  {
+    title: t('common.createTime'),
+    dataIndex: 'createdAt',
+    width: 70,
+    customRender: ({ record }) => {
+      return formatToDateTime(record.createdAt);
+    },
+  },
+];
+
+export const searchFormSchema: FormSchema[] = [
+  {
+    field: 'name',
+    label: t('wechat.sopTask.name'),
+    component: 'Input',
+    colProps: { span: 8 },
+  },
+];
+
+export const formSchema: FormSchema[] = [
+  {
+    field: 'id',
+    label: 'ID',
+    component: 'Input',
+    show: false,
+  },
+  {
+    field: 'name',
+    label: t('wechat.sopTask.name'),
+    component: 'Input',
+    required: true,
+  },
+  {
+    field: 'botWxidList',
+    label: t('wechat.sopTask.botWxidList'),
+    component: 'Input',
+    required: false,
+    show: false,
+  },
+  {
+    field: 'type',
+    label: t('wechat.sopTask.type'),
+    component: 'RadioGroup',
+    required: true,
+    componentProps: {
+      options: [
+        { label: t(`wechat.label_type[0]`), value: 1 },
+        { label: t(`wechat.label_type[1]`), value: 2 },
+        { label: t(`wechat.label_type[2]`), value: 3 },
+        { label: t(`wechat.label_type[3]`), value: 4 },
+      ],
+    },
+  },
+  {
+    field: 'planStartTime',
+    label: t('wechat.sopTask.planStartTime'),
+    component: 'InputNumber',
+    required: false,
+  },
+  {
+    field: 'planEndTime',
+    label: t('wechat.sopTask.planEndTime'),
+    component: 'InputNumber',
+    required: false,
+  },
+  {
+    field: 'creatorId',
+    label: t('wechat.sopTask.creatorId'),
+    component: 'InputNumber',
+    required: false,
+    show: false,
+  },
+  {
+    field: 'status',
+    label: t('wechat.sopTask.status'),
+    component: 'RadioButtonGroup',
+    defaultValue: 1,
+    componentProps: {
+      options: [
+        { label: t('common.on'), value: 1 },
+        { label: t('common.off'), value: 2 },
+      ],
+    },
+  },
+];