Quellcode durchsuchen

校验错误提示

wangwei vor 4 Jahren
Ursprung
Commit
8608d9c4db

+ 4 - 3
src/components/Form/src/hooks/useFormEvents.ts

@@ -10,7 +10,8 @@ import { dateItemType, handleInputNumberValue } from '../helper';
 import { dateUtil } from '/@/utils/dateUtil';
 import { cloneDeep, uniqBy } from 'lodash-es';
 import { error } from '/@/utils/log';
-
+import { useMessage } from '/@/hooks/web/useMessage';
+const { createMessage } = useMessage();
 interface UseFormActionContext {
   emit: EmitType;
   getProps: ComputedRef<FormProps>;
@@ -241,11 +242,11 @@ export function useFormEvents({
       const res = handleFormValues(values);
       emit('submit', res);
     } catch (error) {
-      console.log(`error`, error);
       if (error.errorFields[0].errors[0]) {
         error = error.errorFields[0].errors[0];
       }
-      throw new Error(error);
+      createMessage.error(error);
+      // throw new Error(error);
     }
   }
 

+ 12 - 6
src/views/admin/admin/popup.vue

@@ -8,6 +8,7 @@
   import { Tree } from 'ant-design-vue';
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { BasicForm, useForm } from '/@/components/Form/index';
   import { schemas } from './data';
   interface PopupData {
@@ -28,6 +29,8 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
       const role = reactive<Role>({
         id: 0,
       });
@@ -71,13 +74,16 @@
       });
 
       async function confirm() {
-        const data = await validate();
-        if (role.id) {
-          data.id = role.id;
+        try {
+          const data = await validate();
+          if (role.id) {
+            data.id = role.id;
+          }
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
       }
       return {
         register,

+ 1 - 3
src/views/admin/group/data.ts

@@ -8,9 +8,6 @@ const adaptWidth = adapt();
 
 export const columns: BasicColumn[] = [
   {
-    // title: '**',
-    // dataIndex: '',
-
     align: 'left',
     width: 70,
   },
@@ -75,6 +72,7 @@ export const schemas: FormSchema[] = [
     colProps: {
       span: adaptWidth.elContainer,
     },
+    required: true,
   },
   //   {
   //     field: 'rules',

+ 13 - 6
src/views/admin/group/popup.vue

@@ -22,6 +22,7 @@
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
   import { getAllowRule } from '/@/api/sys/user';
 
@@ -51,6 +52,8 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
       const reactData = reactive<ReactData>({
         id: 0,
         allowRule: [],
@@ -150,13 +153,17 @@
       }
 
       async function confirm() {
-        const data = await validate();
-        data.rules = [...reactData.rules];
-        if (reactData.id) {
-          data.id = reactData.id;
+        try {
+          const data = await validate();
+          data.rules = [...reactData.rules];
+          if (reactData.id) {
+            data.id = reactData.id;
+          }
+          const childData = { closeModal, data };
+          emit('saveData', childData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
-        const childData = { closeModal, data };
-        emit('saveData', childData);
       }
       return {
         register,

+ 5 - 1
src/views/admin/rule/popup.vue

@@ -8,6 +8,7 @@
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
 
   interface PopupData {
@@ -29,6 +30,8 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
       const state = reactive<State>({
         rule_id: 0,
         ismenu: false,
@@ -87,7 +90,8 @@
           }
           const popupData = { closeModal, data, menuChange };
           emit('saveData', popupData);
-        } finally {
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
       }
       return {

+ 625 - 0
src/views/expense/account_info/data.ts

@@ -0,0 +1,625 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import moment from 'moment';
+
+const adaptWidth = adapt();
+
+export const columns: BasicColumn[] = [
+  {
+    title: 'ID',
+    dataIndex: 'id',
+    editComponentProps: {
+      prefix: '$',
+    },
+    width: 100,
+    sorter: true,
+  },
+  {
+    title: '姓名',
+    dataIndex: 'name',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '性别',
+    dataIndex: 'gender',
+    width: 130,
+    customRender({ record }) {
+      const options = ['男', '女'];
+      return options[record.gender];
+    },
+    sorter: true,
+  },
+  {
+    title: '籍贯',
+    dataIndex: 'origin',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '出生年月',
+    dataIndex: 'birthday',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.birthday).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '党派',
+    dataIndex: 'party',
+    width: 150,
+    customRender({ record }) {
+      const options = ['无', '民革', '民盟', '民建', '民进', '农工', '致公党', '九三学社', '台盟'];
+      return options[record.party];
+    },
+    sorter: true,
+  },
+  {
+    title: '民族',
+    dataIndex: 'nation',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '单位',
+    dataIndex: 'company',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '人大职务',
+    dataIndex: 'peopleJob',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '政协职务',
+    dataIndex: 'cppccJob',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '社会职务',
+    dataIndex: 'job',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '联系方式',
+    dataIndex: 'mobile',
+    width: 160,
+    sorter: true,
+  },
+];
+
+export function getFormConfig(): Partial<FormProps> {
+  return {
+    labelWidth: 100,
+    schemas: [
+      {
+        field: `id`,
+        label: `ID`,
+        component: 'Input',
+        componentProps: {
+          placeholder: 'ID',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `name`,
+        label: `姓名`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '姓名',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `gender`,
+        label: `性别`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '男',
+              value: 0,
+            },
+            {
+              label: '女',
+              value: 1,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `origin`,
+        label: `籍贯`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '籍贯',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `birthday`,
+        label: `出生年月`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '出生年月',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `party`,
+        label: `党派`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '无',
+              value: 0,
+            },
+            {
+              label: '民革',
+              value: 1,
+            },
+            {
+              label: '民盟',
+              value: 2,
+            },
+            {
+              label: '民建',
+              value: 3,
+            },
+            {
+              label: '民进',
+              value: 4,
+            },
+            {
+              label: '农工',
+              value: 5,
+            },
+            {
+              label: '致公党',
+              value: 6,
+            },
+            {
+              label: '九三学社',
+              value: 7,
+            },
+            {
+              label: '台盟',
+              value: 8,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `nation`,
+        label: `民族`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '名族',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `company`,
+        label: `单位`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '单位',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `peopleJob`,
+        label: `人大职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '人大职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `cppccJob`,
+        label: `政协职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '政协职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `job`,
+        label: `社会职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '社会职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `mobile`,
+        label: `联系方式`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '联系方式',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+    ],
+  };
+}
+
+// =================popup================================
+export const schemas: FormSchema[] = [
+  {
+    field: 'name',
+    component: 'Input',
+    label: '姓名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '姓名',
+    },
+    required: true,
+  },
+  {
+    field: 'gender',
+    component: 'Select',
+    label: '性别',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '性别',
+      options: [
+        {
+          label: '男',
+          value: 0,
+        },
+        {
+          label: '女',
+          value: 1,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'birthday',
+    component: 'DatePicker',
+    label: '出生年月',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '出生年月',
+    },
+    required: true,
+  },
+  {
+    field: 'origin',
+    component: 'Input',
+    label: '籍贯',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '籍贯',
+    },
+    required: true,
+  },
+  {
+    field: 'birthplace',
+    component: 'Input',
+    label: '出生地',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '出生地',
+    },
+    required: true,
+  },
+  {
+    field: 'cardNo',
+    component: 'Input',
+    label: '身份证号码',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '身份证号码',
+    },
+    required: true,
+  },
+  {
+    field: 'nation',
+    component: 'Input',
+    label: '民族',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '民族',
+    },
+    required: true,
+  },
+  {
+    field: 'party',
+    label: '党派',
+    component: 'Select',
+    componentProps: {
+      placeholder: '党派',
+      options: [
+        {
+          label: '无',
+          value: 0,
+        },
+        {
+          label: '民革',
+          value: 1,
+        },
+        {
+          label: '民盟',
+          value: 2,
+        },
+        {
+          label: '民建',
+          value: 3,
+        },
+        {
+          label: '民进',
+          value: 4,
+        },
+        {
+          label: '农工',
+          value: 5,
+        },
+        {
+          label: '致公党',
+          value: 6,
+        },
+        {
+          label: '九三学社',
+          value: 7,
+        },
+        {
+          label: '台盟',
+          value: 8,
+        },
+      ],
+    },
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    required: true,
+  },
+  {
+    field: 'edu',
+    component: 'Input',
+    label: '学历',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '学历',
+    },
+    required: true,
+  },
+  {
+    field: 'title',
+    component: 'Input',
+    label: '职称',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职称',
+    },
+  },
+  {
+    field: 'job',
+    component: 'Input',
+    label: '职务',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职务',
+    },
+    required: true,
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '地址',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地址',
+    },
+    required: true,
+  },
+  {
+    field: 'zipcode',
+    component: 'Input',
+    label: '邮编',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '邮编',
+    },
+  },
+  {
+    field: 'tel',
+    component: 'Input',
+    label: '电话',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电话',
+    },
+  },
+  {
+    field: 'mobile',
+    component: 'Input',
+    label: '手机',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '手机',
+    },
+    required: true,
+  },
+  {
+    field: 'old',
+    component: 'Input',
+    label: '办企业前工作单位',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '办企业前工作单位',
+    },
+  },
+  {
+    field: 'peopleJob',
+    component: 'Input',
+    label: '人大职务',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '人大职务',
+    },
+  },
+  {
+    field: 'cppccJob',
+    component: 'Input',
+    label: '政协职务',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '政协职务',
+    },
+  },
+  {
+    field: 'family',
+    component: 'ArrCom',
+    label: '家庭主要成员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    defaultValue: [],
+    componentProps: ({ formModel }) => {
+      return {
+        placeholder: '家庭主要成员',
+        value: formModel.family,
+        onChange: () => {},
+      };
+    },
+    required: true,
+  },
+  {
+    field: 'info',
+    component: 'InputTextArea',
+    label: '本人简历',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '本人简历',
+    },
+  },
+  {
+    field: 'company',
+    component: 'Input',
+    label: '所在单位',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '所在单位',
+    },
+    required: true,
+  },
+];

+ 311 - 0
src/views/expense/account_info/index.vue

@@ -0,0 +1,311 @@
+<template>
+  <CollapseContainer
+    class="sys-container"
+    title="个人管理"
+    :canExpan="false"
+    helpMessage="个人管理"
+  >
+    <BasicTable
+      ref="tableRef"
+      @register="registerTable"
+      rowKey="id"
+      @selectionChange="selectionChange"
+      @rowClick="rowClick"
+      @rowDbClick="handleEdit"
+      showTableSetting
+      :canResize="true"
+      :pagination="{
+        pageSize: 10,
+        defaultPageSize: 10,
+        showSizeChanger: false,
+      }"
+    >
+      <template #toolbar>
+        <a-button type="primary" @click="addRole"> 添加 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button @click="openModal"> 导出 </a-button>
+      </template>
+      <template #form-custom> custom-slot </template>
+      <template #action="{ record }">
+        <TableAction :actions="createActions(record)" stopButtonPropagation />
+      </template>
+    </BasicTable>
+    <ExpExcelModel @register="register" @success="defaultHeader" />
+    <Popup @register="addRegister" :popupData="popupData" @saveData="saveData" />
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, ref, toRefs, unref, createVNode } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
+  import { Modal } from 'ant-design-vue';
+  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
+  import { getFormConfig, columns } from './data';
+  import moment from 'moment';
+  import {
+    getPersonList,
+    addPerson,
+    deleteBatchesPerson,
+    getPerson,
+    editPerson,
+    deletePerson,
+  } from '/@/api/sys/member';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'AccountInfo',
+    components: { CollapseContainer, BasicTable, TableAction, Popup, ExpExcelModel },
+    setup() {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const popupData = reactive<PopupData>({
+        title: '添加',
+      });
+      const btn = reactive<Btn>({
+        disable_btn: true,
+      });
+      const [registerTable] = useTable({
+        rowSelection: { type: 'checkbox' },
+        columns: columns,
+        // clickToRowSelect: false, // 点击行不勾选
+        api: getPersonList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        showIndexColumn: false,
+        bordered: true,
+      });
+      const [register, { openModal }] = useModal();
+      const [addRegister, { openModal: openPopup }] = useModal();
+      function getTableAction() {
+        // 获取组件
+        const tableAction = unref(tableRef);
+        if (!tableAction) {
+          throw new Error('tableAction is null');
+        }
+        return tableAction;
+      }
+      // 请求之前处理
+      function beforeFetch(params) {
+        for (let k in params) {
+          if (k !== 'page' && k !== 'pageSize' && k !== 'field' && k !== 'order') {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.birthday) {
+                params.birthday = moment(params.birthday).format('YYYY-MM-DD');
+              } else {
+                delete params.birthday;
+              }
+              params.filter[k] = params[k];
+              delete params[k];
+            }
+          }
+        }
+        params.filter = JSON.stringify(params.filter);
+        params.offset = params.page;
+        params.limit = params.pageSize;
+        delete params.page;
+        delete params.pageSize;
+      }
+
+      function afterFetch(result) {
+        console.log(`result`, result);
+        // tableData.result = result;
+      }
+
+      function addRole() {
+        popupData.title = '添加';
+        openPopup(true, { family: [] });
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getPerson({ id: record.id }).then((res) => {
+          const data = res.row;
+          console.log(`data`, data);
+          openPopup(true, data);
+        });
+      }
+
+      async function handleDelete(record: Recordable) {
+        console.log(record);
+        await deletePerson({ id: record.id }).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          success('删除成功!');
+        });
+      }
+
+      function selectionChange() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+      function rowClick() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+
+      async function deleteBatches() {
+        const keys = await getTableAction().getSelectRowKeys();
+        const count = keys.length;
+        const ids = keys.toString();
+        if (!ids) {
+          return;
+        }
+        Modal.confirm({
+          title: '删除提示',
+          icon: createVNode(ExclamationCircleOutlined),
+          content: '确定删除选中的' + count + '项?',
+          okText: '确定',
+          okType: 'danger',
+          cancelText: '取消',
+          maskClosable: true,
+          async onOk() {
+            await deleteBatchesPerson({ ids }).then((res) => {
+              console.log(res);
+              getTableAction().reload();
+              success('删除成功!');
+              getTableAction().setSelectedRowKeys([]);
+            });
+          },
+          onCancel() {
+            console.log('Cancel');
+          },
+        });
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        if (!data.id) {
+          await addPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('修改成功!');
+          });
+          console.log('----------edit---');
+        }
+      }
+
+      // 导出
+      function defaultHeader({ filename, bookType }: ExportModalResult) {
+        // 默认Object.keys(data[0])作为header
+        jsonToSheetXlsx({
+          data: getTableAction().getDataSource(),
+          filename,
+          write2excelOpts: {
+            bookType,
+          },
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '编辑',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '删除',
+            color: 'error',
+            icon: 'ic:outline-delete-outline',
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDelete.bind(null, record),
+            },
+          },
+        ];
+      }
+      return {
+        popupData,
+        tableRef,
+        registerTable,
+        addRole,
+        handleEdit,
+        deleteBatches,
+        createActions,
+        getTableAction,
+        rowClick,
+        selectionChange,
+        addRegister,
+        saveData,
+        defaultHeader,
+        openModal,
+        register,
+        ...toRefs(btn),
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+
+  /* @media (max-width: 639px) {
+    .sys-container .vben-basic-table-header__toolbar > * {
+      padding: 6px !important;
+      margin-right: 3px;
+      font-size: 12px !important;
+    }
+
+    .sys-container .vben-basic-table .ant-table-wrapper {
+      padding: 3px;
+    }
+  } */
+</style>

+ 107 - 0
src/views/expense/account_info/popup.vue

@@ -0,0 +1,107 @@
+<template>
+  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" :title="title">
+    <BasicForm @register="registerForm" :model="model" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { schemas } from './data';
+  import moment from 'moment';
+  interface PopupData {
+    title: string;
+  }
+  interface Role {
+    id: string | number;
+  }
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      popupData: {
+        type: Object as PropType<PopupData>,
+        default: () => {},
+      },
+    },
+    emits: ['saveData'],
+    setup(props, { emit }) {
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
+
+      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      //   const [register, { closeModal }] = useModalInner((data) => {
+      //     modelRef.value = data;
+
+      //
+      //   });
+      const [register, { closeModal }] = useModalInner((data) => {
+        resetFields();
+        console.log(`data ----id?`, data.id);
+        if (data.id) {
+          role.id = data.id;
+        } else {
+          role.id = 0;
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        const data = await validate();
+        console.log(`确定`, data);
+        const not_validate = data.family.some((item) => {
+          if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
+            error('家庭成员信息不能为空');
+            return true;
+          }
+        });
+        if (not_validate) {
+          return;
+        }
+        data.id = role.id;
+        data.birthday = moment(data.birthday).format('YYYY-MM-DD');
+        data.family = JSON.stringify(data.family);
+        const popupData = { closeModal, data };
+        emit('saveData', popupData);
+        // closeModal(); // 关闭弹窗
+      }
+      return {
+        register,
+        schemas,
+        registerForm,
+        model: modelRef,
+        confirm,
+        ...toRefs(popupData),
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .ant-form-item-label {
+    overflow: hidden;
+    text-align: center !important;
+    // white-space: pre-wrap !important;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  @media (max-width: 639px) {
+    .ant-form-item-label {
+      line-height: 2.5715 !important;
+      text-align: center !important;
+    }
+  }
+</style>

+ 459 - 0
src/views/expense/account_manage/data.ts

@@ -0,0 +1,459 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import moment from 'moment';
+
+const adaptWidth = adapt();
+
+export const columns: BasicColumn[] = [
+  {
+    title: 'ID',
+    dataIndex: 'id',
+    editComponentProps: {
+      prefix: '$',
+    },
+    width: 100,
+    sorter: true,
+  },
+  {
+    title: '交易类型',
+    dataIndex: 'type',
+    width: 130,
+    customRender({ record }) {
+      const options = ['支出', '收入', '内部转账'];
+      return options[record.type];
+    },
+    sorter: true,
+  },
+  {
+    title: '交易名称',
+    dataIndex: 'name',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '交易账户',
+    dataIndex: 'account',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '金额',
+    dataIndex: 'money',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '相关人员',
+    dataIndex: 'people',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '是否开票',
+    dataIndex: 'invoice',
+    width: 130,
+    customRender({ record }) {
+      const options = ['是', '否'];
+      return options[record.invoice];
+    },
+    sorter: true,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 200,
+    sorter: true,
+  },
+  {
+    title: '交易日期',
+    dataIndex: 'time',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.time).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+];
+
+export function getFormConfig(): Partial<FormProps> {
+  return {
+    labelWidth: 100,
+    schemas: [
+      {
+        field: `id`,
+        label: `ID`,
+        component: 'Input',
+        componentProps: {
+          placeholder: 'ID',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `type`,
+        label: `交易类型`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '支出',
+              value: 0,
+            },
+            {
+              label: '收入',
+              value: 1,
+            },
+            {
+              label: '内部转账',
+              value: 2,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `name`,
+        label: `姓名`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '姓名',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `origin`,
+        label: `籍贯`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '籍贯',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `birthday`,
+        label: `出生年月`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '出生年月',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `party`,
+        label: `党派`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '无',
+              value: 0,
+            },
+            {
+              label: '民革',
+              value: 1,
+            },
+            {
+              label: '民盟',
+              value: 2,
+            },
+            {
+              label: '民建',
+              value: 3,
+            },
+            {
+              label: '民进',
+              value: 4,
+            },
+            {
+              label: '农工',
+              value: 5,
+            },
+            {
+              label: '致公党',
+              value: 6,
+            },
+            {
+              label: '九三学社',
+              value: 7,
+            },
+            {
+              label: '台盟',
+              value: 8,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `nation`,
+        label: `民族`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '名族',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `company`,
+        label: `单位`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '单位',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `peopleJob`,
+        label: `人大职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '人大职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `cppccJob`,
+        label: `政协职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '政协职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `job`,
+        label: `社会职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '社会职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `mobile`,
+        label: `联系方式`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '联系方式',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+    ],
+  };
+}
+
+// =================popup================================
+export const schemas: FormSchema[] = [
+  {
+    field: 'type',
+    component: 'Select',
+    label: '交易类型',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '交易类型',
+      options: [
+        {
+          label: '支出',
+          value: 0,
+        },
+        {
+          label: '收入',
+          value: 1,
+        },
+        {
+          label: '内部转账',
+          value: 2,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'name',
+    component: 'Select',
+    label: '交易名称',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '交易名称',
+      options: [],
+    },
+    required: true,
+  },
+  {
+    field: 'inflow_account',
+    component: 'Select',
+    label: '流入账户',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '流入账户',
+      options: [],
+    },
+    required: true,
+    show: ({ values }) => {
+      if (values.type === 2) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'year',
+    component: 'Select',
+    label: '会费年份',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '会费年份',
+      options: [],
+    },
+    required: true,
+    show: ({ values }) => {
+      if (values.name === '会费') {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'money',
+    component: 'Input',
+    label: '金额',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '金额',
+    },
+    required: true,
+  },
+  {
+    field: 'people',
+    component: 'Select',
+    label: '相关人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '相关人员',
+      options: [],
+    },
+    required: true,
+  },
+  {
+    field: 'invoice',
+    component: 'Select',
+    label: '是否开票',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '是否开票',
+      options: [
+        {
+          label: '是',
+          value: 0,
+        },
+        {
+          label: '否',
+          value: 1,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'invoiceNo',
+    component: 'Input',
+    label: '发票号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '发票号',
+    },
+    show: ({ values }) => {
+      if (values.invoice) {
+        return true;
+      }
+      return false;
+    },
+    required: true,
+  },
+  {
+    field: 'enclosure',
+    component: 'Input',
+    label: '附件',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '上传',
+    },
+    required: true,
+  },
+  {
+    field: 'remark',
+    component: 'Input',
+    label: '备注',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '备注',
+    },
+  },
+];

+ 311 - 0
src/views/expense/account_manage/index.vue

@@ -0,0 +1,311 @@
+<template>
+  <CollapseContainer
+    class="sys-container"
+    title="个人管理"
+    :canExpan="false"
+    helpMessage="个人管理"
+  >
+    <BasicTable
+      ref="tableRef"
+      @register="registerTable"
+      rowKey="id"
+      @selectionChange="selectionChange"
+      @rowClick="rowClick"
+      @rowDbClick="handleEdit"
+      showTableSetting
+      :canResize="true"
+      :pagination="{
+        pageSize: 10,
+        defaultPageSize: 10,
+        showSizeChanger: false,
+      }"
+    >
+      <template #toolbar>
+        <a-button type="primary" @click="addRole"> 添加 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button @click="openModal"> 导出 </a-button>
+      </template>
+      <template #form-custom> custom-slot </template>
+      <template #action="{ record }">
+        <TableAction :actions="createActions(record)" stopButtonPropagation />
+      </template>
+    </BasicTable>
+    <ExpExcelModel @register="register" @success="defaultHeader" />
+    <Popup @register="addRegister" :popupData="popupData" @saveData="saveData" />
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, ref, toRefs, unref, createVNode } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
+  import { Modal } from 'ant-design-vue';
+  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
+  import { getFormConfig, columns } from './data';
+  import moment from 'moment';
+  import {
+    getPersonList,
+    addPerson,
+    deleteBatchesPerson,
+    getPerson,
+    editPerson,
+    deletePerson,
+  } from '/@/api/sys/member';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'AccountManage',
+    components: { CollapseContainer, BasicTable, TableAction, Popup, ExpExcelModel },
+    setup() {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const popupData = reactive<PopupData>({
+        title: '添加',
+      });
+      const btn = reactive<Btn>({
+        disable_btn: true,
+      });
+      const [registerTable] = useTable({
+        rowSelection: { type: 'checkbox' },
+        columns: columns,
+        // clickToRowSelect: false, // 点击行不勾选
+        api: getPersonList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        showIndexColumn: false,
+        bordered: true,
+      });
+      const [register, { openModal }] = useModal();
+      const [addRegister, { openModal: openPopup }] = useModal();
+      function getTableAction() {
+        // 获取组件
+        const tableAction = unref(tableRef);
+        if (!tableAction) {
+          throw new Error('tableAction is null');
+        }
+        return tableAction;
+      }
+      // 请求之前处理
+      function beforeFetch(params) {
+        for (let k in params) {
+          if (k !== 'page' && k !== 'pageSize' && k !== 'field' && k !== 'order') {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.birthday) {
+                params.birthday = moment(params.birthday).format('YYYY-MM-DD');
+              } else {
+                delete params.birthday;
+              }
+              params.filter[k] = params[k];
+              delete params[k];
+            }
+          }
+        }
+        params.filter = JSON.stringify(params.filter);
+        params.offset = params.page;
+        params.limit = params.pageSize;
+        delete params.page;
+        delete params.pageSize;
+      }
+
+      function afterFetch(result) {
+        console.log(`result`, result);
+        // tableData.result = result;
+      }
+
+      function addRole() {
+        popupData.title = '添加';
+        openPopup(true, { family: [] });
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getPerson({ id: record.id }).then((res) => {
+          const data = res.row;
+          console.log(`data`, data);
+          openPopup(true, data);
+        });
+      }
+
+      async function handleDelete(record: Recordable) {
+        console.log(record);
+        await deletePerson({ id: record.id }).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          success('删除成功!');
+        });
+      }
+
+      function selectionChange() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+      function rowClick() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+
+      async function deleteBatches() {
+        const keys = await getTableAction().getSelectRowKeys();
+        const count = keys.length;
+        const ids = keys.toString();
+        if (!ids) {
+          return;
+        }
+        Modal.confirm({
+          title: '删除提示',
+          icon: createVNode(ExclamationCircleOutlined),
+          content: '确定删除选中的' + count + '项?',
+          okText: '确定',
+          okType: 'danger',
+          cancelText: '取消',
+          maskClosable: true,
+          async onOk() {
+            await deleteBatchesPerson({ ids }).then((res) => {
+              console.log(res);
+              getTableAction().reload();
+              success('删除成功!');
+              getTableAction().setSelectedRowKeys([]);
+            });
+          },
+          onCancel() {
+            console.log('Cancel');
+          },
+        });
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        if (!data.id) {
+          await addPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('修改成功!');
+          });
+          console.log('----------edit---');
+        }
+      }
+
+      // 导出
+      function defaultHeader({ filename, bookType }: ExportModalResult) {
+        // 默认Object.keys(data[0])作为header
+        jsonToSheetXlsx({
+          data: getTableAction().getDataSource(),
+          filename,
+          write2excelOpts: {
+            bookType,
+          },
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '编辑',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '删除',
+            color: 'error',
+            icon: 'ic:outline-delete-outline',
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDelete.bind(null, record),
+            },
+          },
+        ];
+      }
+      return {
+        popupData,
+        tableRef,
+        registerTable,
+        addRole,
+        handleEdit,
+        deleteBatches,
+        createActions,
+        getTableAction,
+        rowClick,
+        selectionChange,
+        addRegister,
+        saveData,
+        defaultHeader,
+        openModal,
+        register,
+        ...toRefs(btn),
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+
+  /* @media (max-width: 639px) {
+    .sys-container .vben-basic-table-header__toolbar > * {
+      padding: 6px !important;
+      margin-right: 3px;
+      font-size: 12px !important;
+    }
+
+    .sys-container .vben-basic-table .ant-table-wrapper {
+      padding: 3px;
+    }
+  } */
+</style>

+ 110 - 0
src/views/expense/account_manage/popup.vue

@@ -0,0 +1,110 @@
+<template>
+  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" :title="title">
+    <BasicForm @register="registerForm" :model="model" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { schemas } from './data';
+  import moment from 'moment';
+  interface PopupData {
+    title: string;
+  }
+  interface Role {
+    id: string | number;
+  }
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      popupData: {
+        type: Object as PropType<PopupData>,
+        default: () => {},
+      },
+    },
+    emits: ['saveData'],
+    setup(props, { emit }) {
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
+
+      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      //   const [register, { closeModal }] = useModalInner((data) => {
+      //     modelRef.value = data;
+
+      //
+      //   });
+      const [register, { closeModal }] = useModalInner((data) => {
+        resetFields();
+        console.log(`data ----id?`, data.id);
+        if (data.id) {
+          role.id = data.id;
+        } else {
+          role.id = 0;
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          const not_validate = data.family.some((item) => {
+            if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
+              error('家庭成员信息不能为空');
+              return true;
+            }
+          });
+          if (not_validate) {
+            return;
+          }
+          data.id = role.id;
+          data.birthday = moment(data.birthday).format('YYYY-MM-DD');
+          data.family = JSON.stringify(data.family);
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
+        }
+      }
+      return {
+        register,
+        schemas,
+        registerForm,
+        model: modelRef,
+        confirm,
+        ...toRefs(popupData),
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .ant-form-item-label {
+    overflow: hidden;
+    text-align: center !important;
+    // white-space: pre-wrap !important;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  @media (max-width: 639px) {
+    .ant-form-item-label {
+      line-height: 2.5715 !important;
+      text-align: center !important;
+    }
+  }
+</style>

+ 625 - 0
src/views/expense/transaction_type/data.ts

@@ -0,0 +1,625 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import moment from 'moment';
+
+const adaptWidth = adapt();
+
+export const columns: BasicColumn[] = [
+  {
+    title: 'ID',
+    dataIndex: 'id',
+    editComponentProps: {
+      prefix: '$',
+    },
+    width: 100,
+    sorter: true,
+  },
+  {
+    title: '姓名',
+    dataIndex: 'name',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '性别',
+    dataIndex: 'gender',
+    width: 130,
+    customRender({ record }) {
+      const options = ['男', '女'];
+      return options[record.gender];
+    },
+    sorter: true,
+  },
+  {
+    title: '籍贯',
+    dataIndex: 'origin',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '出生年月',
+    dataIndex: 'birthday',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.birthday).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '党派',
+    dataIndex: 'party',
+    width: 150,
+    customRender({ record }) {
+      const options = ['无', '民革', '民盟', '民建', '民进', '农工', '致公党', '九三学社', '台盟'];
+      return options[record.party];
+    },
+    sorter: true,
+  },
+  {
+    title: '民族',
+    dataIndex: 'nation',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '单位',
+    dataIndex: 'company',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '人大职务',
+    dataIndex: 'peopleJob',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '政协职务',
+    dataIndex: 'cppccJob',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '社会职务',
+    dataIndex: 'job',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '联系方式',
+    dataIndex: 'mobile',
+    width: 160,
+    sorter: true,
+  },
+];
+
+export function getFormConfig(): Partial<FormProps> {
+  return {
+    labelWidth: 100,
+    schemas: [
+      {
+        field: `id`,
+        label: `ID`,
+        component: 'Input',
+        componentProps: {
+          placeholder: 'ID',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `name`,
+        label: `姓名`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '姓名',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `gender`,
+        label: `性别`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '男',
+              value: 0,
+            },
+            {
+              label: '女',
+              value: 1,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `origin`,
+        label: `籍贯`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '籍贯',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `birthday`,
+        label: `出生年月`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '出生年月',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `party`,
+        label: `党派`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '无',
+              value: 0,
+            },
+            {
+              label: '民革',
+              value: 1,
+            },
+            {
+              label: '民盟',
+              value: 2,
+            },
+            {
+              label: '民建',
+              value: 3,
+            },
+            {
+              label: '民进',
+              value: 4,
+            },
+            {
+              label: '农工',
+              value: 5,
+            },
+            {
+              label: '致公党',
+              value: 6,
+            },
+            {
+              label: '九三学社',
+              value: 7,
+            },
+            {
+              label: '台盟',
+              value: 8,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `nation`,
+        label: `民族`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '名族',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `company`,
+        label: `单位`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '单位',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `peopleJob`,
+        label: `人大职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '人大职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `cppccJob`,
+        label: `政协职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '政协职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `job`,
+        label: `社会职务`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '社会职务',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `mobile`,
+        label: `联系方式`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '联系方式',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+    ],
+  };
+}
+
+// =================popup================================
+export const schemas: FormSchema[] = [
+  {
+    field: 'name',
+    component: 'Input',
+    label: '姓名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '姓名',
+    },
+    required: true,
+  },
+  {
+    field: 'gender',
+    component: 'Select',
+    label: '性别',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '性别',
+      options: [
+        {
+          label: '男',
+          value: 0,
+        },
+        {
+          label: '女',
+          value: 1,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'birthday',
+    component: 'DatePicker',
+    label: '出生年月',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '出生年月',
+    },
+    required: true,
+  },
+  {
+    field: 'origin',
+    component: 'Input',
+    label: '籍贯',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '籍贯',
+    },
+    required: true,
+  },
+  {
+    field: 'birthplace',
+    component: 'Input',
+    label: '出生地',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '出生地',
+    },
+    required: true,
+  },
+  {
+    field: 'cardNo',
+    component: 'Input',
+    label: '身份证号码',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '身份证号码',
+    },
+    required: true,
+  },
+  {
+    field: 'nation',
+    component: 'Input',
+    label: '民族',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '民族',
+    },
+    required: true,
+  },
+  {
+    field: 'party',
+    label: '党派',
+    component: 'Select',
+    componentProps: {
+      placeholder: '党派',
+      options: [
+        {
+          label: '无',
+          value: 0,
+        },
+        {
+          label: '民革',
+          value: 1,
+        },
+        {
+          label: '民盟',
+          value: 2,
+        },
+        {
+          label: '民建',
+          value: 3,
+        },
+        {
+          label: '民进',
+          value: 4,
+        },
+        {
+          label: '农工',
+          value: 5,
+        },
+        {
+          label: '致公党',
+          value: 6,
+        },
+        {
+          label: '九三学社',
+          value: 7,
+        },
+        {
+          label: '台盟',
+          value: 8,
+        },
+      ],
+    },
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    required: true,
+  },
+  {
+    field: 'edu',
+    component: 'Input',
+    label: '学历',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '学历',
+    },
+    required: true,
+  },
+  {
+    field: 'title',
+    component: 'Input',
+    label: '职称',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职称',
+    },
+  },
+  {
+    field: 'job',
+    component: 'Input',
+    label: '职务',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职务',
+    },
+    required: true,
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '地址',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地址',
+    },
+    required: true,
+  },
+  {
+    field: 'zipcode',
+    component: 'Input',
+    label: '邮编',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '邮编',
+    },
+  },
+  {
+    field: 'tel',
+    component: 'Input',
+    label: '电话',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电话',
+    },
+  },
+  {
+    field: 'mobile',
+    component: 'Input',
+    label: '手机',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '手机',
+    },
+    required: true,
+  },
+  {
+    field: 'old',
+    component: 'Input',
+    label: '办企业前工作单位',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '办企业前工作单位',
+    },
+  },
+  {
+    field: 'peopleJob',
+    component: 'Input',
+    label: '人大职务',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '人大职务',
+    },
+  },
+  {
+    field: 'cppccJob',
+    component: 'Input',
+    label: '政协职务',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '政协职务',
+    },
+  },
+  {
+    field: 'family',
+    component: 'ArrCom',
+    label: '家庭主要成员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    defaultValue: [],
+    componentProps: ({ formModel }) => {
+      return {
+        placeholder: '家庭主要成员',
+        value: formModel.family,
+        onChange: () => {},
+      };
+    },
+    required: true,
+  },
+  {
+    field: 'info',
+    component: 'InputTextArea',
+    label: '本人简历',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '本人简历',
+    },
+  },
+  {
+    field: 'company',
+    component: 'Input',
+    label: '所在单位',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '所在单位',
+    },
+    required: true,
+  },
+];

+ 311 - 0
src/views/expense/transaction_type/index.vue

@@ -0,0 +1,311 @@
+<template>
+  <CollapseContainer
+    class="sys-container"
+    title="个人管理"
+    :canExpan="false"
+    helpMessage="个人管理"
+  >
+    <BasicTable
+      ref="tableRef"
+      @register="registerTable"
+      rowKey="id"
+      @selectionChange="selectionChange"
+      @rowClick="rowClick"
+      @rowDbClick="handleEdit"
+      showTableSetting
+      :canResize="true"
+      :pagination="{
+        pageSize: 10,
+        defaultPageSize: 10,
+        showSizeChanger: false,
+      }"
+    >
+      <template #toolbar>
+        <a-button type="primary" @click="addRole"> 添加 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button @click="openModal"> 导出 </a-button>
+      </template>
+      <template #form-custom> custom-slot </template>
+      <template #action="{ record }">
+        <TableAction :actions="createActions(record)" stopButtonPropagation />
+      </template>
+    </BasicTable>
+    <ExpExcelModel @register="register" @success="defaultHeader" />
+    <Popup @register="addRegister" :popupData="popupData" @saveData="saveData" />
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, ref, toRefs, unref, createVNode } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { jsonToSheetXlsx, ExpExcelModel, ExportModalResult } from '/@/components/Excel';
+  import { Modal } from 'ant-design-vue';
+  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
+  import { getFormConfig, columns } from './data';
+  import moment from 'moment';
+  import {
+    getPersonList,
+    addPerson,
+    deleteBatchesPerson,
+    getPerson,
+    editPerson,
+    deletePerson,
+  } from '/@/api/sys/member';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'TransactionType',
+    components: { CollapseContainer, BasicTable, TableAction, Popup, ExpExcelModel },
+    setup() {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const popupData = reactive<PopupData>({
+        title: '添加',
+      });
+      const btn = reactive<Btn>({
+        disable_btn: true,
+      });
+      const [registerTable] = useTable({
+        rowSelection: { type: 'checkbox' },
+        columns: columns,
+        // clickToRowSelect: false, // 点击行不勾选
+        api: getPersonList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        showIndexColumn: false,
+        bordered: true,
+      });
+      const [register, { openModal }] = useModal();
+      const [addRegister, { openModal: openPopup }] = useModal();
+      function getTableAction() {
+        // 获取组件
+        const tableAction = unref(tableRef);
+        if (!tableAction) {
+          throw new Error('tableAction is null');
+        }
+        return tableAction;
+      }
+      // 请求之前处理
+      function beforeFetch(params) {
+        for (let k in params) {
+          if (k !== 'page' && k !== 'pageSize' && k !== 'field' && k !== 'order') {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.birthday) {
+                params.birthday = moment(params.birthday).format('YYYY-MM-DD');
+              } else {
+                delete params.birthday;
+              }
+              params.filter[k] = params[k];
+              delete params[k];
+            }
+          }
+        }
+        params.filter = JSON.stringify(params.filter);
+        params.offset = params.page;
+        params.limit = params.pageSize;
+        delete params.page;
+        delete params.pageSize;
+      }
+
+      function afterFetch(result) {
+        console.log(`result`, result);
+        // tableData.result = result;
+      }
+
+      function addRole() {
+        popupData.title = '添加';
+        openPopup(true, { family: [] });
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getPerson({ id: record.id }).then((res) => {
+          const data = res.row;
+          console.log(`data`, data);
+          openPopup(true, data);
+        });
+      }
+
+      async function handleDelete(record: Recordable) {
+        console.log(record);
+        await deletePerson({ id: record.id }).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          success('删除成功!');
+        });
+      }
+
+      function selectionChange() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+      function rowClick() {
+        const keys = getTableAction().getSelectRowKeys();
+        if (keys.length) {
+          btn.disable_btn = false;
+        } else {
+          btn.disable_btn = true;
+        }
+      }
+
+      async function deleteBatches() {
+        const keys = await getTableAction().getSelectRowKeys();
+        const count = keys.length;
+        const ids = keys.toString();
+        if (!ids) {
+          return;
+        }
+        Modal.confirm({
+          title: '删除提示',
+          icon: createVNode(ExclamationCircleOutlined),
+          content: '确定删除选中的' + count + '项?',
+          okText: '确定',
+          okType: 'danger',
+          cancelText: '取消',
+          maskClosable: true,
+          async onOk() {
+            await deleteBatchesPerson({ ids }).then((res) => {
+              console.log(res);
+              getTableAction().reload();
+              success('删除成功!');
+              getTableAction().setSelectedRowKeys([]);
+            });
+          },
+          onCancel() {
+            console.log('Cancel');
+          },
+        });
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        if (!data.id) {
+          await addPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editPerson(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('修改成功!');
+          });
+          console.log('----------edit---');
+        }
+      }
+
+      // 导出
+      function defaultHeader({ filename, bookType }: ExportModalResult) {
+        // 默认Object.keys(data[0])作为header
+        jsonToSheetXlsx({
+          data: getTableAction().getDataSource(),
+          filename,
+          write2excelOpts: {
+            bookType,
+          },
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '编辑',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '删除',
+            color: 'error',
+            icon: 'ic:outline-delete-outline',
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDelete.bind(null, record),
+            },
+          },
+        ];
+      }
+      return {
+        popupData,
+        tableRef,
+        registerTable,
+        addRole,
+        handleEdit,
+        deleteBatches,
+        createActions,
+        getTableAction,
+        rowClick,
+        selectionChange,
+        addRegister,
+        saveData,
+        defaultHeader,
+        openModal,
+        register,
+        ...toRefs(btn),
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+
+  /* @media (max-width: 639px) {
+    .sys-container .vben-basic-table-header__toolbar > * {
+      padding: 6px !important;
+      margin-right: 3px;
+      font-size: 12px !important;
+    }
+
+    .sys-container .vben-basic-table .ant-table-wrapper {
+      padding: 3px;
+    }
+  } */
+</style>

+ 107 - 0
src/views/expense/transaction_type/popup.vue

@@ -0,0 +1,107 @@
+<template>
+  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" :title="title">
+    <BasicForm @register="registerForm" :model="model" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { schemas } from './data';
+  import moment from 'moment';
+  interface PopupData {
+    title: string;
+  }
+  interface Role {
+    id: string | number;
+  }
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      popupData: {
+        type: Object as PropType<PopupData>,
+        default: () => {},
+      },
+    },
+    emits: ['saveData'],
+    setup(props, { emit }) {
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
+
+      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      //   const [register, { closeModal }] = useModalInner((data) => {
+      //     modelRef.value = data;
+
+      //
+      //   });
+      const [register, { closeModal }] = useModalInner((data) => {
+        resetFields();
+        console.log(`data ----id?`, data.id);
+        if (data.id) {
+          role.id = data.id;
+        } else {
+          role.id = 0;
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        const data = await validate();
+        console.log(`确定`, data);
+        const not_validate = data.family.some((item) => {
+          if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
+            error('家庭成员信息不能为空');
+            return true;
+          }
+        });
+        if (not_validate) {
+          return;
+        }
+        data.id = role.id;
+        data.birthday = moment(data.birthday).format('YYYY-MM-DD');
+        data.family = JSON.stringify(data.family);
+        const popupData = { closeModal, data };
+        emit('saveData', popupData);
+        // closeModal(); // 关闭弹窗
+      }
+      return {
+        register,
+        schemas,
+        registerForm,
+        model: modelRef,
+        confirm,
+        ...toRefs(popupData),
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .ant-form-item-label {
+    overflow: hidden;
+    text-align: center !important;
+    // white-space: pre-wrap !important;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  @media (max-width: 639px) {
+    .ant-form-item-label {
+      line-height: 2.5715 !important;
+      text-align: center !important;
+    }
+  }
+</style>

+ 51 - 18
src/views/member/member/customCom/person/popup.vue

@@ -1,25 +1,41 @@
 <template>
-  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" title="添加个人">
+  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" :title="title">
     <BasicForm @register="registerForm" :model="model" />
   </BasicModal>
 </template>
 <script lang="ts">
-  import { defineComponent, ref } from 'vue';
+  import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
   import moment from 'moment';
+  interface PopupData {
+    title: string;
+  }
+  interface Role {
+    id: string | number;
+  }
 
   export default defineComponent({
     components: { BasicModal, BasicForm },
+    props: {
+      popupData: {
+        type: Object as PropType<PopupData>,
+        default: () => {},
+      },
+    },
     emits: ['saveData'],
-    setup(_, { emit }) {
+    setup(props, { emit }) {
+      const popupData = props.popupData as PopupData;
       const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
       const { createMessage } = useMessage();
       const { error } = createMessage;
 
-      const [registerForm, { resetFields, validate }] = useForm({
+      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
         labelWidth: 120,
         schemas,
         showActionButtonGroup: false,
@@ -27,26 +43,42 @@
           span: 24,
         },
       });
-      const [register, { closeModal }] = useModalInner(() => {
+      //   const [register, { closeModal }] = useModalInner((data) => {
+      //     modelRef.value = data;
+
+      //
+      //   });
+      const [register, { closeModal }] = useModalInner((data) => {
         resetFields();
+        if (data.id) {
+          role.id = data.id;
+        } else {
+          role.id = 0;
+        }
+        setFieldsValue(data);
       });
 
       async function confirm() {
-        const data = await validate();
-        const not_validate = data.family.some((item) => {
-          if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
-            error('家庭成员信息不能为空');
-            return true;
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          const not_validate = data.family.some((item) => {
+            if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
+              error('家庭成员信息不能为空');
+              return true;
+            }
+          });
+          if (not_validate) {
+            return;
           }
-        });
-        if (not_validate) {
-          return;
+          data.id = role.id;
+          data.birthday = moment(data.birthday).format('YYYY-MM-DD');
+          data.family = JSON.stringify(data.family);
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
-        data.birthday = moment(data.birthday).format('YYYY-MM-DD');
-        data.family = JSON.stringify(data.family);
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
       }
       return {
         register,
@@ -54,6 +86,7 @@
         registerForm,
         model: modelRef,
         confirm,
+        ...toRefs(popupData),
       };
     },
   });

+ 61 - 29
src/views/member/member/customCom/unit/popup.vue

@@ -1,25 +1,41 @@
 <template>
-  <BasicModal width="800px" v-bind="$attrs" @register="register" @ok="confirm" title="添加个人">
+  <BasicModal v-bind="$attrs" @register="register" @ok="confirm" :title="title">
     <BasicForm @register="registerForm" :model="model" />
   </BasicModal>
 </template>
 <script lang="ts">
-  import { defineComponent, ref } from 'vue';
+  import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
-  // import { useMessage } from '/@/hooks/web/useMessage';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
   import moment from 'moment';
+  interface PopupData {
+    title: string;
+  }
+  interface Role {
+    id: string | number;
+  }
 
   export default defineComponent({
     components: { BasicModal, BasicForm },
+    props: {
+      popupData: {
+        type: Object as PropType<PopupData>,
+        default: () => {},
+      },
+    },
     emits: ['saveData'],
-    setup(_, { emit }) {
+    setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const popupData = props.popupData as PopupData;
       const modelRef = ref({});
-      // const { createMessage } = useMessage();
-      // const { error } = createMessage;
 
-      const [registerForm, { resetFields, validate }] = useForm({
+      const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
         labelWidth: 120,
         schemas,
         showActionButtonGroup: false,
@@ -27,33 +43,48 @@
           span: 24,
         },
       });
-      const [register, { closeModal }] = useModalInner(() => {
+      //   const [register, { closeModal }] = useModalInner((data) => {
+      //     modelRef.value = data;
+
+      //
+      //   });
+      const [register, { closeModal }] = useModalInner((data) => {
         resetFields();
+        setFieldsValue(data);
+        role.id = data.id;
       });
 
       async function confirm() {
-        const data = await validate();
-        console.log(`确定`, data);
-        if (data.technology) {
-          data.technology = 1;
-        } else {
-          data.technology = 0;
-        }
-        if (data.foreignTrade) {
-          data.foreignTrade = 1;
-        } else {
-          data.foreignTrade = 0;
-        }
-        if (data.quality) {
-          data.quality = 1;
-        } else {
-          data.quality = 0;
-        }
-        data.foundingtime = moment(data.foundingtime).format('YYYY-MM-DD');
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          if (role.id) {
+            data.id = role.id;
+          } else {
+            role.id = 0;
+          }
+          if (data.technology) {
+            data.technology = 1;
+          } else {
+            data.technology = 0;
+          }
+          if (data.foreignTrade) {
+            data.foreignTrade = 1;
+          } else {
+            data.foreignTrade = 0;
+          }
+          if (data.quality) {
+            data.quality = 1;
+          } else {
+            data.quality = 0;
+          }
+          data.foundingtime = moment(data.foundingtime).format('YYYY-MM-DD');
 
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
+        }
       }
       return {
         register,
@@ -61,6 +92,7 @@
         registerForm,
         model: modelRef,
         confirm,
+        ...toRefs(popupData),
       };
     },
   });

+ 2 - 2
src/views/member/member/data.ts

@@ -214,7 +214,7 @@ export const schemas: FormSchema[] = [
   },
   {
     field: 'name',
-    component: 'Input',
+    component: 'Select',
     label: '姓名',
     labelWidth: adaptWidth.labelWidth,
     colProps: {
@@ -244,7 +244,7 @@ export const schemas: FormSchema[] = [
   },
   {
     field: 'unitName',
-    component: 'Input',
+    component: 'Select',
     label: '名称',
     labelWidth: adaptWidth.labelWidth,
     colProps: {

+ 23 - 20
src/views/member/member/popup.vue

@@ -7,7 +7,7 @@
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
-  // import { useMessage } from '/@/hooks/web/useMessage';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
   import moment from 'moment';
   interface PopupData {
@@ -27,13 +27,13 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
       const popupData = props.popupData as PopupData;
       const modelRef = ref({});
       const role = reactive<Role>({
         id: 0,
       });
-      // const { createMessage } = useMessage();
-      // const { error } = createMessage;
 
       const [registerForm, { updateSchema, setFieldsValue, resetFields, validate }] = useForm({
         labelWidth: 120,
@@ -69,6 +69,8 @@
               required: false,
             },
           ]);
+          data.username = data.admin.username;
+          setFieldsValue(data);
         } else {
           role.id = 0;
           updateSchema([
@@ -94,27 +96,28 @@
             },
           ]);
         }
-        data.username = data.admin.username;
-        setFieldsValue(data);
       });
 
       async function confirm() {
-        const data = await validate();
-        console.log(`确定`, data);
-        data.id = role.id;
-        if (data.name) {
-          data.fromId = data.name.id;
-        } else {
-          data.fromId = data.unitName.id;
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          data.id = role.id;
+          if (data.name) {
+            data.fromId = data.name.id;
+          } else {
+            data.fromId = data.unitName.id;
+          }
+          data.jointime = moment(data.jointime).format('YYYY-MM-DD');
+          delete data.relation;
+          delete data.relationUnit;
+          delete data.unitName;
+          delete data.name;
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
-        data.jointime = moment(data.jointime).format('YYYY-MM-DD');
-        delete data.relation;
-        delete data.relationUnit;
-        delete data.unitName;
-        delete data.name;
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
       }
       return {
         register,

+ 1 - 1
src/views/member/person/index.vue

@@ -150,7 +150,7 @@
 
       function addRole() {
         popupData.title = '添加';
-        openPopup(true, { family: [] });
+        openPopup(true, {});
       }
 
       async function handleEdit(record: EditRecordRow) {

+ 18 - 16
src/views/member/person/popup.vue

@@ -50,7 +50,6 @@
       //   });
       const [register, { closeModal }] = useModalInner((data) => {
         resetFields();
-        console.log(`data ----id?`, data.id);
         if (data.id) {
           role.id = data.id;
         } else {
@@ -60,23 +59,26 @@
       });
 
       async function confirm() {
-        const data = await validate();
-        console.log(`确定`, data);
-        const not_validate = data.family.some((item) => {
-          if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
-            error('家庭成员信息不能为空');
-            return true;
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          const not_validate = data.family.some((item) => {
+            if (item.relation === '' || item.age === '' || item.job === '' || item.company === '') {
+              error('家庭成员信息不能为空');
+              return true;
+            }
+          });
+          if (not_validate) {
+            return;
           }
-        });
-        if (not_validate) {
-          return;
+          data.id = role.id;
+          data.birthday = moment(data.birthday).format('YYYY-MM-DD');
+          data.family = JSON.stringify(data.family);
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
         }
-        data.id = role.id;
-        data.birthday = moment(data.birthday).format('YYYY-MM-DD');
-        data.family = JSON.stringify(data.family);
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
       }
       return {
         register,

+ 32 - 26
src/views/member/unit/popup.vue

@@ -7,6 +7,7 @@
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
   import { schemas } from './data';
   import moment from 'moment';
   interface PopupData {
@@ -26,6 +27,8 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const { error } = createMessage;
       const role = reactive<Role>({
         id: 0,
       });
@@ -52,33 +55,36 @@
       });
 
       async function confirm() {
-        const data = await validate();
-        console.log(`确定`, data);
-        if (role.id) {
-          data.id = role.id;
-        } else {
-          role.id = 0;
-        }
-        if (data.technology) {
-          data.technology = 1;
-        } else {
-          data.technology = 0;
-        }
-        if (data.foreignTrade) {
-          data.foreignTrade = 1;
-        } else {
-          data.foreignTrade = 0;
-        }
-        if (data.quality) {
-          data.quality = 1;
-        } else {
-          data.quality = 0;
-        }
-        data.foundingtime = moment(data.foundingtime).format('YYYY-MM-DD');
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          if (role.id) {
+            data.id = role.id;
+          } else {
+            role.id = 0;
+          }
+          if (data.technology) {
+            data.technology = 1;
+          } else {
+            data.technology = 0;
+          }
+          if (data.foreignTrade) {
+            data.foreignTrade = 1;
+          } else {
+            data.foreignTrade = 0;
+          }
+          if (data.quality) {
+            data.quality = 1;
+          } else {
+            data.quality = 0;
+          }
+          data.foundingtime = moment(data.foundingtime).format('YYYY-MM-DD');
 
-        const popupData = { closeModal, data };
-        emit('saveData', popupData);
-        // closeModal(); // 关闭弹窗
+          const popupData = { closeModal, data };
+          emit('saveData', popupData);
+        } catch (err) {
+          error(err.errorFields[0].errors[0]);
+        }
       }
       return {
         register,