Browse Source

feat: 活动组织

LAPTOP-2ACP37JG\shark 4 years ago
parent
commit
8d6d95e62f
53 changed files with 9015 additions and 17 deletions
  1. 75 0
      src/api/sys/department.ts
  2. 143 0
      src/api/sys/event.ts
  3. 40 0
      src/api/sys/model/departmentModel.ts
  4. 72 0
      src/api/sys/model/eventModel.ts
  5. 95 0
      src/views/department/department/customCom/CustomInput.vue
  6. 96 0
      src/views/department/department/customCom/member/customCom/CustomInput.vue
  7. 625 0
      src/views/department/department/customCom/member/customCom/person/data.ts
  8. 168 0
      src/views/department/department/customCom/member/customCom/person/index.vue
  9. 109 0
      src/views/department/department/customCom/member/customCom/person/popup.vue
  10. 43 0
      src/views/department/department/customCom/member/customCom/popup.vue
  11. 682 0
      src/views/department/department/customCom/member/customCom/unit/data.ts
  12. 158 0
      src/views/department/department/customCom/member/customCom/unit/index.vue
  13. 115 0
      src/views/department/department/customCom/member/customCom/unit/popup.vue
  14. 415 0
      src/views/department/department/customCom/member/data.ts
  15. 167 0
      src/views/department/department/customCom/member/index.vue
  16. 148 0
      src/views/department/department/customCom/member/popup.vue
  17. 42 0
      src/views/department/department/customCom/popup.vue
  18. 276 0
      src/views/department/department/data.ts
  19. 317 0
      src/views/department/department/index.vue
  20. 127 0
      src/views/department/department/popup.vue
  21. 422 0
      src/views/event/activity/data.ts
  22. 317 0
      src/views/event/activity/index.vue
  23. 125 0
      src/views/event/activity/popup.vue
  24. 96 0
      src/views/event/meeting/customCom/member copy/customCom/CustomInput.vue
  25. 625 0
      src/views/event/meeting/customCom/member copy/customCom/person/data.ts
  26. 168 0
      src/views/event/meeting/customCom/member copy/customCom/person/index.vue
  27. 109 0
      src/views/event/meeting/customCom/member copy/customCom/person/popup.vue
  28. 43 0
      src/views/event/meeting/customCom/member copy/customCom/popup.vue
  29. 682 0
      src/views/event/meeting/customCom/member copy/customCom/unit/data.ts
  30. 158 0
      src/views/event/meeting/customCom/member copy/customCom/unit/index.vue
  31. 115 0
      src/views/event/meeting/customCom/member copy/customCom/unit/popup.vue
  32. 415 0
      src/views/event/meeting/customCom/member copy/data.ts
  33. 167 0
      src/views/event/meeting/customCom/member copy/index.vue
  34. 148 0
      src/views/event/meeting/customCom/member copy/popup.vue
  35. 397 0
      src/views/event/meeting/data.ts
  36. 317 0
      src/views/event/meeting/index.vue
  37. 125 0
      src/views/event/meeting/popup.vue
  38. 13 0
      src/views/member/person/data.ts
  39. 50 0
      src/views/money/account/customCom/accountrecord/data.ts
  40. 107 0
      src/views/money/account/customCom/accountrecord/index.vue
  41. 43 0
      src/views/money/account/customCom/popup.vue
  42. 3 4
      src/views/money/account/index.vue
  43. 6 1
      src/views/money/bill/customCom/CustomInput.vue
  44. 35 0
      src/views/money/bill/customCom/attachment/customComponents/Image.vue
  45. 98 0
      src/views/money/bill/customCom/attachment/data.ts
  46. 147 0
      src/views/money/bill/customCom/attachment/index.vue
  47. 99 0
      src/views/money/bill/customCom/attachment/popup.vue
  48. 3 1
      src/views/money/bill/customCom/popup.vue
  49. 51 5
      src/views/money/bill/data.ts
  50. 2 2
      src/views/money/bill/index.vue
  51. 12 0
      src/views/money/bill/popup.vue
  52. 2 2
      src/views/money/dues/index.vue
  53. 2 2
      src/views/money/type/index.vue

+ 75 - 0
src/api/sys/department.ts

@@ -0,0 +1,75 @@
+import { defHttp } from '/@/utils/http/axios';
+import {
+  GetDepartmentListModel,
+  DeleteBatchesParams,
+  DepartmentIdParams,
+  AddDepartmentParams,
+  EditDepartmentParams,
+  GetDepartmentModel,
+} from './model/departmentModel';
+
+enum Api {
+  DepartmentUrl = '/department/',
+}
+
+/**
+ * @description: GetDepartmentList
+ */
+export function getDepartmentList(params) {
+  console.log('-------------------getDepartmentList---------------');
+  return defHttp.request<GetDepartmentListModel>({
+    url: Api.DepartmentUrl,
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: addDepartment
+ */
+export function addDepartment(params: AddDepartmentParams) {
+  return defHttp.request<GetDepartmentListModel>({
+    url: Api.DepartmentUrl,
+    method: 'POST',
+    params,
+  });
+}
+/**
+ * @description: 批量删除交易类型
+ */
+export function deleteBatchesDepartment(params: DeleteBatchesParams) {
+  return defHttp.request<GetDepartmentListModel>({
+    url: Api.DepartmentUrl,
+    method: 'DELETE',
+    params,
+  });
+}
+
+/**
+ * @description: 获取单个交易类型
+ */
+export function getDepartment(params: DepartmentIdParams) {
+  return defHttp.request<GetDepartmentModel>({
+    url: Api.DepartmentUrl + '/' + params.id,
+    method: 'GET',
+  });
+}
+/**
+ * @description: 修改单个交易类型
+ */
+export function editDepartment(params: EditDepartmentParams) {
+  return defHttp.request<GetDepartmentListModel>({
+    url: Api.DepartmentUrl + '/' + params.id,
+    method: 'PUT',
+    params,
+  });
+}
+/**
+ * @description: 删除单个交易类型
+ */
+export function deleteDepartment(params: DepartmentIdParams) {
+  return defHttp.request<GetDepartmentListModel>({
+    url: Api.DepartmentUrl + '/' + params.id,
+    method: 'DELETE',
+  });
+}

+ 143 - 0
src/api/sys/event.ts

@@ -0,0 +1,143 @@
+import { defHttp } from '/@/utils/http/axios';
+import {
+  GetMeetingListModel,
+  DeleteBatchesParams,
+  MeetingIdParams,
+  AddMeetingParams,
+  EditMeetingParams,
+  GetActivityListModel,
+  GetMeetingModel,
+  GetActivityModel,
+  ActivityIdParams,
+  AddActivityParams,
+  EditActivityParams,
+} from './model/eventModel';
+
+enum Api {
+  MeetingUrl = '/event/meeting',
+  ActivityUrl = '/event/activity',
+}
+
+/**
+ * @description: GetMeetingList
+ */
+export function getMeetingList(params) {
+  console.log('-------------------getMeetingList---------------');
+  return defHttp.request<GetMeetingListModel>({
+    url: Api.MeetingUrl,
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: addMeeting
+ */
+export function addMeeting(params: AddMeetingParams) {
+  return defHttp.request<GetMeetingListModel>({
+    url: Api.MeetingUrl,
+    method: 'POST',
+    params,
+  });
+}
+/**
+ * @description: 批量删除交易类型
+ */
+export function deleteBatchesMeeting(params: DeleteBatchesParams) {
+  return defHttp.request<GetMeetingListModel>({
+    url: Api.MeetingUrl,
+    method: 'DELETE',
+    params,
+  });
+}
+
+/**
+ * @description: 获取单个交易类型
+ */
+export function getMeeting(params: MeetingIdParams) {
+  return defHttp.request<GetMeetingModel>({
+    url: Api.MeetingUrl + '/' + params.id,
+    method: 'GET',
+  });
+}
+/**
+ * @description: 修改单个交易类型
+ */
+export function editMeeting(params: EditMeetingParams) {
+  return defHttp.request<GetMeetingListModel>({
+    url: Api.MeetingUrl + '/' + params.id,
+    method: 'PUT',
+    params,
+  });
+}
+/**
+ * @description: 删除单个交易类型
+ */
+export function deleteMeeting(params: MeetingIdParams) {
+  return defHttp.request<GetMeetingListModel>({
+    url: Api.MeetingUrl + '/' + params.id,
+    method: 'DELETE',
+  });
+}
+
+/**
+ * @description: GetActivityList -----------------------------------------------
+ */
+export function getActivityList(params) {
+  console.log('-------------------getActivityList---------------');
+  return defHttp.request<GetActivityListModel>({
+    url: Api.ActivityUrl,
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: addActivity
+ */
+export function addActivity(params: AddActivityParams) {
+  return defHttp.request<GetActivityListModel>({
+    url: Api.ActivityUrl,
+    method: 'POST',
+    params,
+  });
+}
+/**
+ * @description: 批量删除账户
+ */
+export function deleteBatchesActivity(params: DeleteBatchesParams) {
+  return defHttp.request<GetActivityListModel>({
+    url: Api.ActivityUrl,
+    method: 'DELETE',
+    params,
+  });
+}
+
+/**
+ * @description: 获取单个账户
+ */
+export function getActivity(params: ActivityIdParams) {
+  return defHttp.request<GetActivityModel>({
+    url: Api.ActivityUrl + '/' + params.id,
+    method: 'GET',
+  });
+}
+/**
+ * @description: 修改单个账户
+ */
+export function editActivity(params: EditActivityParams) {
+  return defHttp.request<GetActivityListModel>({
+    url: Api.ActivityUrl + '/' + params.id,
+    method: 'PUT',
+    params,
+  });
+}
+/**
+ * @description: 删除单个账户
+ */
+export function deleteActivity(params: ActivityIdParams) {
+  return defHttp.request<GetActivityListModel>({
+    url: Api.ActivityUrl + '/' + params.id,
+    method: 'DELETE',
+  });
+}

+ 40 - 0
src/api/sys/model/departmentModel.ts

@@ -0,0 +1,40 @@
+/**
+ * @description: Get Department list
+ */
+export interface GetDepartmentListModel {
+  count: number;
+  list: object[];
+}
+
+/**
+ * @description: Get event information return value
+ */
+export interface DeleteBatchesParams {
+  ids: string | string[] | number[];
+}
+
+/**
+ * @description: id
+ */
+export interface DepartmentIdParams {
+  id: string | number;
+}
+/**
+ * @description: id
+ */
+export interface GetDepartmentModel {
+  row: object[];
+}
+
+/**
+ * @description: add Department
+ */
+export interface AddDepartmentParams {
+  id: number;
+}
+/**
+ * @description: edit Department
+ */
+export interface EditDepartmentParams {
+  id: number;
+}

+ 72 - 0
src/api/sys/model/eventModel.ts

@@ -0,0 +1,72 @@
+/**
+ * @description: Get Meeting list
+ */
+export interface GetMeetingListModel {
+  count: number;
+  list: object[];
+}
+
+/**
+ * @description: Get event information return value
+ */
+export interface DeleteBatchesParams {
+  ids: string | string[] | number[];
+}
+
+/**
+ * @description: id
+ */
+export interface MeetingIdParams {
+  id: string | number;
+}
+/**
+ * @description: id
+ */
+export interface GetMeetingModel {
+  row: object[];
+}
+
+/**
+ * @description: add Meeting
+ */
+export interface AddMeetingParams {
+  id: number;
+}
+/**
+ * @description: edit Meeting
+ */
+export interface EditMeetingParams {
+  id: number;
+}
+/**
+ * @description: Get Activity list----------------------
+ */
+export interface GetActivityListModel {
+  count: number;
+  list: object[];
+}
+/**
+ * @description: Get Activity
+ */
+export interface GetActivityModel {
+  row: object[];
+}
+
+/**
+ * @description: add Activity
+ */
+export interface AddActivityParams {
+  id: number;
+}
+/**
+ * @description: id
+ */
+export interface ActivityIdParams {
+  id: string | number;
+}
+/**
+ * @description: edit Activity
+ */
+export interface EditActivityParams {
+  id: number;
+}

+ 95 - 0
src/views/department/department/customCom/CustomInput.vue

@@ -0,0 +1,95 @@
+<template>
+  <!-- <BasicTable @register="registerTable" /> -->
+  <div class="wrap">
+    <div class="content">
+      <Input :placeholder="placeholder" disabled v-model:value="value" />
+      <a-button
+        class="mr-2 add-btn"
+        color="success"
+        :disabled="disabled"
+        @click="openAddPop(placeholder)"
+      >
+        添加
+      </a-button>
+    </div>
+    <Popup @register="register" @select="select" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, onUpdated, reactive, nextTick, toRefs } from 'vue';
+  import { Input } from 'ant-design-vue';
+  import Popup from './popup.vue';
+  import { useModal } from '/@/components/Modal';
+
+  const props = {
+    value: { type: Object, default: '' },
+    placeholder: { type: String, default: '' },
+  };
+  interface State {
+    value: object | string;
+    placeholder: string;
+    disabled: boolean;
+  }
+
+  export default defineComponent({
+    name: 'CustomInput',
+    components: { Input, Popup },
+    props,
+    emits: ['change'],
+    setup(props, { emit }) {
+      const state = reactive<State>({
+        value: '',
+        placeholder: props.placeholder,
+        disabled: false,
+      });
+      const [register, { openModal: openPopup }] = useModal();
+      // 初始化
+      function init() {
+        nextTick(() => {
+          if (props.value.name) {
+            console.log(`props.value.name`, props.value.name);
+            state.value = props.value.name;
+          } else if (props.value.url) {
+            state.value = props.value.url;
+          } else {
+            state.value = props.value;
+          }
+          if (
+            state.value !== '' &&
+            (typeof props.value === 'string' || typeof props.value === 'number')
+          ) {
+            state.disabled = true;
+          } else {
+            state.disabled = false;
+          }
+        });
+      }
+      onUpdated(() => {
+        init();
+      });
+      function openAddPop(title) {
+        openPopup(true, title);
+      }
+      function select(data) {
+        emit('change', data);
+      }
+
+      return {
+        openAddPop,
+        select,
+        openPopup,
+        register,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>
+<style scoped>
+  .content {
+    display: flex;
+  }
+
+  .add-btn {
+    margin-left: 2px;
+  }
+</style>

+ 96 - 0
src/views/department/department/customCom/member/customCom/CustomInput.vue

@@ -0,0 +1,96 @@
+<template>
+  <!-- <BasicTable @register="registerTable" /> -->
+  <div class="wrap">
+    <div class="content">
+      <Input :placeholder="placeholder" disabled v-model:value="value" />
+      <a-button
+        class="mr-2 add-btn"
+        color="success"
+        :disabled="disabled"
+        @click="openAddPop(placeholder)"
+      >
+        添加
+      </a-button>
+    </div>
+    <Popup @register="register" @select="select" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, onUpdated, reactive, nextTick, toRefs } from 'vue';
+  import { Input } from 'ant-design-vue';
+  import Popup from './popup.vue';
+  import { useModal } from '/@/components/Modal';
+
+  const props = {
+    value: { type: Object, default: '' },
+    placeholder: { type: String, default: '' },
+  };
+  interface State {
+    value: object | string;
+    placeholder: string;
+    disabled: boolean;
+  }
+
+  export default defineComponent({
+    name: 'CustomInput',
+    components: { Input, Popup },
+    props,
+    emits: ['change'],
+    setup(props, { emit }) {
+      const state = reactive<State>({
+        value: '',
+        placeholder: props.placeholder,
+        disabled: false,
+      });
+      const [register, { openModal: openPopup }] = useModal();
+      // 初始化
+      function init() {
+        nextTick(() => {
+          if (props.value.name) {
+            console.log(`props.value.name`, props.value.name);
+            state.value = props.value.name;
+          } else {
+            state.value = props.value;
+          }
+          if (state.value !== '' && typeof props.value === 'string') {
+            state.disabled = true;
+          } else {
+            state.disabled = false;
+          }
+        });
+      }
+      onUpdated(() => {
+        init();
+      });
+      function openAddPop(title) {
+        if (title === '添加相关个人') {
+          title = '添加个人';
+        }
+        if (title === '添加相关单位') {
+          title = '添加单位';
+        }
+        openPopup(true, title);
+      }
+      function select(data) {
+        emit('change', data);
+      }
+
+      return {
+        openAddPop,
+        select,
+        openPopup,
+        register,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>
+<style scoped>
+  .content {
+    display: flex;
+  }
+
+  .add-btn {
+    margin-left: 2px;
+  }
+</style>

+ 625 - 0
src/views/department/department/customCom/member/customCom/person/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,
+  },
+];

+ 168 - 0
src/views/department/department/customCom/member/customCom/person/index.vue

@@ -0,0 +1,168 @@
+<template>
+  <a-button type="primary" @click="handleAdd"> 添加 </a-button>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getPersonList, addPerson } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Person',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getPersonList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addPerson(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</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>

+ 109 - 0
src/views/department/department/customCom/member/customCom/person/popup.vue

@@ -0,0 +1,109 @@
+<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();
+        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>

+ 43 - 0
src/views/department/department/customCom/member/customCom/popup.vue

@@ -0,0 +1,43 @@
+<template>
+  <BasicModal
+    :showCancelBtn="false"
+    :showOkBtn="false"
+    width="800px"
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+    helpMessage="点击最右侧选择按钮"
+  >
+    <Person v-if="title === '添加个人'" @select="select" />
+    <Unit v-if="title === '添加单位'" @select="select" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import Person from './person/index.vue';
+  import Unit from './unit/index.vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { defineComponent, reactive, toRefs } from 'vue';
+
+  export default defineComponent({
+    components: { BasicModal, Person, Unit },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const state = reactive({
+        title: '',
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        state.title = data;
+      });
+
+      function select(data) {
+        emit('select', data);
+        closeModal();
+      }
+      return {
+        register,
+        select,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>

+ 682 - 0
src/views/department/department/customCom/member/customCom/unit/data.ts

@@ -0,0 +1,682 @@
+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: 'legalman',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '成立时间',
+    dataIndex: 'foundingtime',
+    width: 150,
+    customRender({ record }) {
+      return moment(record.foundingtime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '工商登记号',
+    dataIndex: 'businessNo',
+    width: 350,
+    sorter: true,
+  },
+  {
+    title: '单位性质',
+    dataIndex: 'nature',
+    width: 160,
+    customRender: ({ record }) => {
+      const options = [
+        '国有企业',
+        '集体所有制',
+        '私营企业',
+        '股份制企业',
+        '有限合伙企业',
+        '联营企业',
+        '外商投资企业',
+        '个人独资企业',
+      ];
+      return options[record.nature];
+    },
+    sorter: true,
+  },
+  {
+    title: '行业分类',
+    dataIndex: 'job',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '注册资金',
+    dataIndex: 'regMoney',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '职工人数',
+    dataIndex: 'jobnum',
+    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: `legalman`,
+        label: `法人代表`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '法人代表',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `foundingtime`,
+        label: `成立时间`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '成立时间',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `businessNo`,
+        label: `工商登记号`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '工商登记号',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `nature`,
+        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,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `job`,
+        label: `行业分类`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '行业分类',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `regMoney`,
+        label: `注册资金`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '注册资金',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `jobnum`,
+        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: 'legalman',
+    component: 'Input',
+    label: '法人代表',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '法人代表',
+    },
+    required: true,
+  },
+  {
+    field: 'businessNo',
+    component: 'Input',
+    label: '工商登记号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '工商登记号',
+    },
+    required: true,
+  },
+  {
+    field: 'centralTax',
+    component: 'Input',
+    label: '国税税号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '国税税号',
+    },
+  },
+  {
+    field: 'landTax',
+    component: 'Input',
+    label: '地税税号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地税税号',
+    },
+  },
+  {
+    field: 'nature',
+    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,
+        },
+      ],
+    },
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    required: true,
+  },
+  {
+    field: 'foundingtime',
+    component: 'DatePicker',
+    label: '成立时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '成立时间',
+    },
+    required: true,
+  },
+  {
+    field: 'job',
+    component: 'Input',
+    label: '行业分类',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '行业分类',
+    },
+    required: true,
+  },
+  {
+    field: 'jobnum',
+    component: 'Input',
+    label: '职工人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '职工人数',
+    },
+  },
+  {
+    field: 'partynum',
+    component: 'Input',
+    label: '党员数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '党员数',
+    },
+  },
+  {
+    field: 'tel',
+    component: 'Input',
+    label: '电话',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电话',
+    },
+  },
+  {
+    field: 'fax',
+    component: 'Input',
+    label: '传真',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '传真',
+    },
+  },
+  {
+    field: 'zipcode',
+    component: 'Input',
+    label: '邮编',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '邮箱',
+    },
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '地址',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地址',
+    },
+    required: true,
+  },
+  {
+    field: 'culturalnum',
+    component: 'Input',
+    label: '大专以上文化人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '大专以上文化人数',
+    },
+  },
+  {
+    field: 'laidnum',
+    component: 'Input',
+    label: '安置下岗人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '安置下岗人数',
+    },
+  },
+  {
+    field: 'partyCase',
+    component: 'Input',
+    label: '党、团工会情况',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '党、团工会情况',
+    },
+  },
+  {
+    field: 'web',
+    component: 'Input',
+    label: '网址',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '网址',
+    },
+  },
+  {
+    field: 'email',
+    component: 'Input',
+    label: '电子邮箱',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电子邮箱',
+    },
+  },
+  {
+    field: 'technology',
+    label: '高新技术企业认证',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '高新技术企业认证',
+    },
+  },
+  {
+    field: 'technologyDept',
+    component: 'Input',
+    label: '高新技术企业认证部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.technology) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '高新技术企业认证部门',
+    },
+    required: ({ values }) => {
+      if (values.technology) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'foreignTrade',
+    label: '外贸自营进出口权',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '外贸自营进出口权',
+    },
+  },
+  {
+    field: 'foreignTradeDept',
+    component: 'Input',
+    label: '外贸自营进出口权批准部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.foreignTrade) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '外贸自营进出口权批准部门',
+    },
+    required: ({ values }) => {
+      if (values.foreignTrade) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'quality',
+    label: '质量管理、质量保证系列认证标准',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '质量管理、质量保证系列认证标准',
+    },
+  },
+  {
+    field: 'qualityDept',
+    component: 'Input',
+    label: '质量管理、质量保证系列认证标准认证部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.quality) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '质量管理、质量保证系列认证标准认证部门',
+    },
+    required: ({ values }) => {
+      if (values.quality) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'regMoney',
+    component: 'Input',
+    label: '注册资金(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '注册资金(万元)',
+    },
+    required: true,
+  },
+  {
+    field: 'money',
+    component: 'Input',
+    label: '资产(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '资产(万元)',
+    },
+  },
+  {
+    field: 'ownerMoney',
+    component: 'Input',
+    label: '所有者权益(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '所有者权益(万元)',
+    },
+  },
+  {
+    field: 'sellMoney',
+    component: 'Input',
+    label: '销售收入(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '销售收入(万元)',
+    },
+  },
+  {
+    field: 'product',
+    component: 'InputTextArea',
+    label: '主要经营项目',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '主要经营项目',
+    },
+    required: true,
+  },
+];

+ 158 - 0
src/views/department/department/customCom/member/customCom/unit/index.vue

@@ -0,0 +1,158 @@
+<template>
+  <a-button type="primary" @click="handleAdd"> 添加 </a-button>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getUnitList, addUnit } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Unit',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getUnitList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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.foundingtime) {
+                params.foundingtime = moment(params.foundingtime).format('YYYY-MM-DD');
+              } else {
+                delete params.foundingtime;
+              }
+              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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addUnit(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+</style>

+ 115 - 0
src/views/department/department/customCom/member/customCom/unit/popup.vue

@@ -0,0 +1,115 @@
+<template>
+  <BasicModal 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 { createMessage } = useMessage();
+      const { error } = createMessage;
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+
+      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();
+        setFieldsValue(data);
+        role.id = data.id;
+      });
+
+      async function confirm() {
+        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);
+        } 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>

+ 415 - 0
src/views/department/department/customCom/member/data.ts

@@ -0,0 +1,415 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import { h } from 'vue';
+import CustomInput from './customCom/CustomInput.vue';
+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: 100,
+    sorter: true,
+  },
+  {
+    title: '会员身份',
+    dataIndex: 'status',
+    width: 130,
+    customRender({ record }) {
+      const options = ['个人', '单位'];
+      return options[record.status];
+    },
+    sorter: true,
+  },
+  {
+    title: '职务',
+    dataIndex: 'duty',
+    width: 130,
+    customRender({ record }) {
+      const options = ['会长', '副会长', '秘书长', '副秘书长', '理事', '会员'];
+      return options[record.duty];
+    },
+    sorter: true,
+  },
+  {
+    title: '入会时间',
+    dataIndex: 'jointime',
+    width: 150,
+    customRender({ record }) {
+      return moment(record.jointime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '当年会费',
+    dataIndex: 'current',
+    width: 200,
+    sorter: true,
+  },
+  {
+    title: '去年会费',
+    dataIndex: 'party',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '当年参会率',
+    dataIndex: 'nation',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '去年参会率',
+    dataIndex: 'company',
+    width: 130,
+    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: `status`,
+        label: `会员身份`,
+        component: 'Select',
+        componentProps: {
+          placeholder: '会员身份',
+          options: [
+            { label: '个人', value: 0 },
+            { label: '单位', value: 1 },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `jointime`,
+        label: `入会时间`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '入会时间',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `email`,
+        label: `当年费率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '全年费率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime`,
+        label: `去年费率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '去年费率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime1`,
+        label: `当年参会率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '当年参会率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime2`,
+        label: `去年参会率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '去年参会率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+    ],
+  };
+}
+
+// =================popup================================
+export const schemas: FormSchema[] = [
+  {
+    field: 'status',
+    label: '会员身份',
+    component: 'RadioButtonGroup',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: (value) => {
+      console.log(`value ---- status`, value);
+      return {
+        // disabled: true,
+        options: [
+          { label: '个人', value: 0 },
+          { label: '单位', value: 1 },
+        ],
+      };
+    },
+    defaultValue: 0,
+  },
+  {
+    field: 'name',
+    component: 'Select',
+    label: '姓名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.name,
+        placeholder: '添加个人',
+        onChange(value) {
+          model[field] = value;
+        },
+      });
+    },
+    show: ({ values }) => {
+      if (!values.status) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (!values.status) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'unitName',
+    component: 'Select',
+    label: '名称',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.name,
+        placeholder: '添加单位',
+        onChange(value) {
+          model.name = value;
+          model[field] = value;
+        },
+      });
+    },
+    show: ({ values }) => {
+      if (values.status) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (values.status) {
+        return true;
+      }
+      return false;
+    },
+  },
+  // {
+  //   field: 'relationUnit',
+  //   component: 'Input',
+  //   label: '相关单位',
+  //   labelWidth: adaptWidth.labelWidth,
+  //   colProps: {
+  //     span: adaptWidth.elContainer,
+  //   },
+  //   render: ({ model, field }) => {
+  //     return h(CustomInput, {
+  //       value: model[field],
+  //       placeholder: '添加相关单位',
+  //       onChange(value) {
+  //         model[field] = value;
+  //       },
+  //     });
+  //   },
+  //   show: ({ values }) => {
+  //     if (values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  //   required: ({ values }) => {
+  //     if (values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  // },
+  // {
+  //   field: 'relation',
+  //   component: 'Input',
+  //   label: '相关个人',
+  //   labelWidth: adaptWidth.labelWidth,
+  //   colProps: {
+  //     span: adaptWidth.elContainer,
+  //   },
+  //   render: ({ model, field }) => {
+  //     return h(CustomInput, {
+  //       value: model[field],
+  //       placeholder: '添加相关个人',
+  //       onChange(value) {
+  //         model[field] = value;
+  //       },
+  //     });
+  //   },
+  //   show: ({ values }) => {
+  //     if (!values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  //   required: ({ values }) => {
+  //     if (!values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  // },
+  {
+    field: 'duty',
+    component: 'Select',
+    label: '职务',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职务',
+      options: [
+        {
+          label: '会长',
+          value: 0,
+        },
+        {
+          label: '副会长',
+          value: 1,
+        },
+        {
+          label: '秘书长',
+          value: 2,
+        },
+        {
+          label: '副秘书长',
+          value: 3,
+        },
+        {
+          label: '理事',
+          value: 4,
+        },
+        {
+          label: '会员',
+          value: 5,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'jointime',
+    component: 'DatePicker',
+    label: '入会时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '入会时间',
+    },
+    required: true,
+  },
+  {
+    field: 'username',
+    component: 'Input',
+    label: '用户名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '用户名',
+    },
+    required: true,
+  },
+  {
+    field: 'password',
+    component: 'InputPassword',
+    label: '密码',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '密码',
+    },
+    required: true,
+  },
+];

+ 167 - 0
src/views/department/department/customCom/member/index.vue

@@ -0,0 +1,167 @@
+<template>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getMemberList, addMember } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Member',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getMemberList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addMember(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</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>

+ 148 - 0
src/views/department/department/customCom/member/popup.vue

@@ -0,0 +1,148 @@
+<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 { createMessage } = useMessage();
+      const { error } = createMessage;
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
+
+      const [registerForm, { updateSchema, setFieldsValue, resetFields, validate }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        resetFields();
+        if (data.id) {
+          role.id = data.id;
+          updateSchema([
+            {
+              field: 'status',
+              componentProps: {
+                disabled: true,
+                options: [
+                  { label: '个人', value: 0 },
+                  { label: '单位', value: 1 },
+                ],
+              },
+            },
+            {
+              field: 'username',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
+              field: 'password',
+              required: false,
+            },
+          ]);
+          data.username = data.admin.username;
+          setFieldsValue(data);
+        } else {
+          role.id = 0;
+          updateSchema([
+            {
+              field: 'status',
+              componentProps: {
+                disabled: false,
+                options: [
+                  { label: '个人', value: 0 },
+                  { label: '单位', value: 1 },
+                ],
+              },
+            },
+            {
+              field: 'username',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
+              field: 'password',
+              required: true,
+            },
+          ]);
+        }
+      });
+
+      async function confirm() {
+        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]);
+        }
+      }
+      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>

+ 42 - 0
src/views/department/department/customCom/popup.vue

@@ -0,0 +1,42 @@
+<template>
+  <BasicModal
+    :showCancelBtn="false"
+    :showOkBtn="false"
+    width="800px"
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+    helpMessage="点击最右侧选择按钮"
+  >
+    <Member v-if="title === '总负责人'" @select="select" />
+    <Member v-if="title === '分管人'" @select="select" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import Member from './member/index.vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { defineComponent, reactive, toRefs } from 'vue';
+
+  export default defineComponent({
+    components: { BasicModal, Member },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const state = reactive({
+        title: '',
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        state.title = data;
+      });
+
+      function select(data) {
+        emit('select', data);
+        closeModal();
+      }
+      return {
+        register,
+        select,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>

+ 276 - 0
src/views/department/department/data.ts

@@ -0,0 +1,276 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import CustomInput from './customCom/CustomInput.vue';
+import { formatToDate } from '/@/utils/dateUtil';
+import { h } from 'vue';
+
+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: 'high',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '下属部门',
+    dataIndex: 'low',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '部门人数',
+    dataIndex: 'num',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '总负责人',
+    dataIndex: 'master',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '操作员',
+    dataIndex: 'manager',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '创建日期',
+    dataIndex: 'createtime',
+    width: 200,
+    customRender: ({ record }) => {
+      const createtime = record.createtime;
+      return formatToDate(createtime * 1000);
+    },
+  },
+];
+
+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: `high`,
+        label: `部门归属`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '部门归属',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `low`,
+        label: `下属部门`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '下属部门',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `num`,
+        label: `部门人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '部门人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `master`,
+        label: `总负责人`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '总负责人',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `manager`,
+        label: `操作员`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '操作员',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `remark`,
+        label: `备注`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '备注',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `createtime`,
+        label: `创建日期`,
+        component: 'DatePicker',
+        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: 'pid',
+    component: 'Input',
+    label: '上级部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '上级部门',
+    },
+  },
+  {
+    field: 'member',
+    component: 'Input',
+    label: '部门人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '部门人员',
+    },
+  },
+  {
+    field: 'master',
+    component: 'Select',
+    label: '总负责人',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.master,
+        placeholder: '总负责人',
+        onChange(value) {
+          model[field] = value;
+        },
+      });
+    },
+  },
+  {
+    field: 'manager',
+    component: 'Input',
+    label: '分管人',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.manager,
+        placeholder: '分管人',
+        onChange(value) {
+          model[field] = value;
+        },
+      });
+    },
+  },
+  {
+    field: 'remark',
+    component: 'Input',
+    label: '备注',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '备注',
+    },
+  },
+];

+ 317 - 0
src/views/department/department/index.vue

@@ -0,0 +1,317 @@
+<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 {
+    getDepartmentList,
+    addDepartment,
+    deleteBatchesDepartment,
+    getDepartment,
+    editDepartment,
+    deleteDepartment,
+  } from '/@/api/sys/department';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'Department',
+    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: getDepartmentList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 260,
+          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' &&
+            k !== 'createdate'
+          ) {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.createdate) {
+                params.createdate = moment(params.createdate).format('YYYY-MM-DD');
+              } else {
+                delete params.createdate;
+              }
+              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, {});
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getDepartment({ 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 deleteDepartment({ 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 deleteBatchesDepartment({ 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 addDepartment(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editDepartment(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>

+ 127 - 0
src/views/department/department/popup.vue

@@ -0,0 +1,127 @@
+<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';
+  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, { updateSchema, 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();
+        if (data.id) {
+          role.id = data.id;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: true,
+              },
+            },
+          ]);
+        } else {
+          role.id = 0;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: false,
+              },
+            },
+          ]);
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          data.id = role.id;
+          data.master = data.master.id;
+          data.manager = data.manager.id;
+          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>

+ 422 - 0
src/views/event/activity/data.ts

@@ -0,0 +1,422 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import moment from 'moment';
+import { formatToDate } from '/@/utils/dateUtil';
+
+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: 'starttime',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.starttime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '地点',
+    dataIndex: 'place',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '计划人数',
+    dataIndex: 'plan',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '报名人数',
+    dataIndex: 'apply',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '参加人数',
+    dataIndex: 'actual',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '活动状态',
+    dataIndex: 'status',
+    width: 130,
+    customRender({ record }) {
+      const options = ['筹备', '完成', '取消'];
+      return options[record.status];
+    },
+    sorter: true,
+  },
+  {
+    title: '操作员',
+    dataIndex: 'manager',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '创建日期',
+    dataIndex: 'createtime',
+    width: 200,
+    customRender: ({ record }) => {
+      const createtime = record.createtime;
+      return formatToDate(createtime * 1000);
+    },
+  },
+];
+
+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: `starttime`,
+        label: `开始日期`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '开始日期',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `place`,
+        label: `地点`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '地点',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `plan`,
+        label: `计划人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '计划人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `apply`,
+        label: `报名人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '报名人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `actual`,
+        label: `参加人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '参加人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `status`,
+        label: `活动状态`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '筹备',
+              value: 0,
+            },
+            {
+              label: '完成',
+              value: 1,
+            },
+            {
+              label: '取消',
+              value: 2,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `manager`,
+        label: `操作员`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '操作员',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `remark`,
+        label: `备注`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '备注',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `createtime`,
+        label: `创建日期`,
+        component: 'DatePicker',
+        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: 'starttime',
+    component: 'TimePicker',
+    label: '开始时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '开始时间',
+    },
+    required: true,
+  },
+  {
+    field: 'endtime',
+    component: 'TimePicker',
+    label: '结束时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '结束时间',
+    },
+    required: true,
+  },
+  {
+    field: 'place',
+    component: 'Input',
+    label: '地点',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地点',
+    },
+    required: true,
+  },
+  {
+    field: 'plan',
+    component: 'Input',
+    label: '计划参加人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '计划参加人员',
+    },
+  },
+  {
+    field: 'apply',
+    component: 'Input',
+    label: '报名参加人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '报名参加人员',
+    },
+  },
+  {
+    field: 'actual',
+    component: 'Input',
+    label: '实际参加人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '实际参加人员',
+    },
+  },
+  {
+    field: 'content',
+    component: 'InputTextArea',
+    label: '活动内容',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '活动内容',
+    },
+  },
+  {
+    field: 'hire',
+    component: 'InputTextArea',
+    label: '集体租聘',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '集体租聘',
+    },
+    required: true,
+  },
+  {
+    field: 'car',
+    component: 'InputTextArea',
+    label: '车辆登记',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '车辆登记',
+    },
+  },
+  {
+    field: 'status',
+    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: 'attachment',
+    component: 'Input',
+    label: '附件',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '附件',
+    },
+  },
+  {
+    field: 'remark',
+    component: 'Input',
+    label: '备注',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '备注',
+    },
+  },
+];

+ 317 - 0
src/views/event/activity/index.vue

@@ -0,0 +1,317 @@
+<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 {
+    getActivityList,
+    addActivity,
+    deleteBatchesActivity,
+    getActivity,
+    editActivity,
+    deleteActivity,
+  } from '/@/api/sys/event';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'Activity',
+    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: getActivityList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 260,
+          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' &&
+            k !== 'createdate'
+          ) {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.createdate) {
+                params.createdate = moment(params.createdate).format('YYYY-MM-DD');
+              } else {
+                delete params.createdate;
+              }
+              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, {});
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getActivity({ 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 deleteActivity({ 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 deleteBatchesActivity({ 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 addActivity(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editActivity(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>

+ 125 - 0
src/views/event/activity/popup.vue

@@ -0,0 +1,125 @@
+<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';
+  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, { updateSchema, 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();
+        if (data.id) {
+          role.id = data.id;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: true,
+              },
+            },
+          ]);
+        } else {
+          role.id = 0;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: false,
+              },
+            },
+          ]);
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          data.id = role.id;
+          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>

+ 96 - 0
src/views/event/meeting/customCom/member copy/customCom/CustomInput.vue

@@ -0,0 +1,96 @@
+<template>
+  <!-- <BasicTable @register="registerTable" /> -->
+  <div class="wrap">
+    <div class="content">
+      <Input :placeholder="placeholder" disabled v-model:value="value" />
+      <a-button
+        class="mr-2 add-btn"
+        color="success"
+        :disabled="disabled"
+        @click="openAddPop(placeholder)"
+      >
+        添加
+      </a-button>
+    </div>
+    <Popup @register="register" @select="select" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, onUpdated, reactive, nextTick, toRefs } from 'vue';
+  import { Input } from 'ant-design-vue';
+  import Popup from './popup.vue';
+  import { useModal } from '/@/components/Modal';
+
+  const props = {
+    value: { type: Object, default: '' },
+    placeholder: { type: String, default: '' },
+  };
+  interface State {
+    value: object | string;
+    placeholder: string;
+    disabled: boolean;
+  }
+
+  export default defineComponent({
+    name: 'CustomInput',
+    components: { Input, Popup },
+    props,
+    emits: ['change'],
+    setup(props, { emit }) {
+      const state = reactive<State>({
+        value: '',
+        placeholder: props.placeholder,
+        disabled: false,
+      });
+      const [register, { openModal: openPopup }] = useModal();
+      // 初始化
+      function init() {
+        nextTick(() => {
+          if (props.value.name) {
+            console.log(`props.value.name`, props.value.name);
+            state.value = props.value.name;
+          } else {
+            state.value = props.value;
+          }
+          if (state.value !== '' && typeof props.value === 'string') {
+            state.disabled = true;
+          } else {
+            state.disabled = false;
+          }
+        });
+      }
+      onUpdated(() => {
+        init();
+      });
+      function openAddPop(title) {
+        if (title === '添加相关个人') {
+          title = '添加个人';
+        }
+        if (title === '添加相关单位') {
+          title = '添加单位';
+        }
+        openPopup(true, title);
+      }
+      function select(data) {
+        emit('change', data);
+      }
+
+      return {
+        openAddPop,
+        select,
+        openPopup,
+        register,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>
+<style scoped>
+  .content {
+    display: flex;
+  }
+
+  .add-btn {
+    margin-left: 2px;
+  }
+</style>

+ 625 - 0
src/views/event/meeting/customCom/member copy/customCom/person/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,
+  },
+];

+ 168 - 0
src/views/event/meeting/customCom/member copy/customCom/person/index.vue

@@ -0,0 +1,168 @@
+<template>
+  <a-button type="primary" @click="handleAdd"> 添加 </a-button>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getPersonList, addPerson } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Person',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getPersonList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addPerson(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</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>

+ 109 - 0
src/views/event/meeting/customCom/member copy/customCom/person/popup.vue

@@ -0,0 +1,109 @@
+<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();
+        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>

+ 43 - 0
src/views/event/meeting/customCom/member copy/customCom/popup.vue

@@ -0,0 +1,43 @@
+<template>
+  <BasicModal
+    :showCancelBtn="false"
+    :showOkBtn="false"
+    width="800px"
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+    helpMessage="点击最右侧选择按钮"
+  >
+    <Person v-if="title === '添加个人'" @select="select" />
+    <Unit v-if="title === '添加单位'" @select="select" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import Person from './person/index.vue';
+  import Unit from './unit/index.vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { defineComponent, reactive, toRefs } from 'vue';
+
+  export default defineComponent({
+    components: { BasicModal, Person, Unit },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const state = reactive({
+        title: '',
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        state.title = data;
+      });
+
+      function select(data) {
+        emit('select', data);
+        closeModal();
+      }
+      return {
+        register,
+        select,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>

+ 682 - 0
src/views/event/meeting/customCom/member copy/customCom/unit/data.ts

@@ -0,0 +1,682 @@
+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: 'legalman',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '成立时间',
+    dataIndex: 'foundingtime',
+    width: 150,
+    customRender({ record }) {
+      return moment(record.foundingtime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '工商登记号',
+    dataIndex: 'businessNo',
+    width: 350,
+    sorter: true,
+  },
+  {
+    title: '单位性质',
+    dataIndex: 'nature',
+    width: 160,
+    customRender: ({ record }) => {
+      const options = [
+        '国有企业',
+        '集体所有制',
+        '私营企业',
+        '股份制企业',
+        '有限合伙企业',
+        '联营企业',
+        '外商投资企业',
+        '个人独资企业',
+      ];
+      return options[record.nature];
+    },
+    sorter: true,
+  },
+  {
+    title: '行业分类',
+    dataIndex: 'job',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '注册资金',
+    dataIndex: 'regMoney',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '职工人数',
+    dataIndex: 'jobnum',
+    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: `legalman`,
+        label: `法人代表`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '法人代表',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `foundingtime`,
+        label: `成立时间`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '成立时间',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `businessNo`,
+        label: `工商登记号`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '工商登记号',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `nature`,
+        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,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `job`,
+        label: `行业分类`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '行业分类',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `regMoney`,
+        label: `注册资金`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '注册资金',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `jobnum`,
+        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: 'legalman',
+    component: 'Input',
+    label: '法人代表',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '法人代表',
+    },
+    required: true,
+  },
+  {
+    field: 'businessNo',
+    component: 'Input',
+    label: '工商登记号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '工商登记号',
+    },
+    required: true,
+  },
+  {
+    field: 'centralTax',
+    component: 'Input',
+    label: '国税税号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '国税税号',
+    },
+  },
+  {
+    field: 'landTax',
+    component: 'Input',
+    label: '地税税号',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地税税号',
+    },
+  },
+  {
+    field: 'nature',
+    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,
+        },
+      ],
+    },
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    required: true,
+  },
+  {
+    field: 'foundingtime',
+    component: 'DatePicker',
+    label: '成立时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '成立时间',
+    },
+    required: true,
+  },
+  {
+    field: 'job',
+    component: 'Input',
+    label: '行业分类',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '行业分类',
+    },
+    required: true,
+  },
+  {
+    field: 'jobnum',
+    component: 'Input',
+    label: '职工人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '职工人数',
+    },
+  },
+  {
+    field: 'partynum',
+    component: 'Input',
+    label: '党员数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '党员数',
+    },
+  },
+  {
+    field: 'tel',
+    component: 'Input',
+    label: '电话',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电话',
+    },
+  },
+  {
+    field: 'fax',
+    component: 'Input',
+    label: '传真',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '传真',
+    },
+  },
+  {
+    field: 'zipcode',
+    component: 'Input',
+    label: '邮编',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '邮箱',
+    },
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '地址',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地址',
+    },
+    required: true,
+  },
+  {
+    field: 'culturalnum',
+    component: 'Input',
+    label: '大专以上文化人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '大专以上文化人数',
+    },
+  },
+  {
+    field: 'laidnum',
+    component: 'Input',
+    label: '安置下岗人数',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '安置下岗人数',
+    },
+  },
+  {
+    field: 'partyCase',
+    component: 'Input',
+    label: '党、团工会情况',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '党、团工会情况',
+    },
+  },
+  {
+    field: 'web',
+    component: 'Input',
+    label: '网址',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '网址',
+    },
+  },
+  {
+    field: 'email',
+    component: 'Input',
+    label: '电子邮箱',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '电子邮箱',
+    },
+  },
+  {
+    field: 'technology',
+    label: '高新技术企业认证',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '高新技术企业认证',
+    },
+  },
+  {
+    field: 'technologyDept',
+    component: 'Input',
+    label: '高新技术企业认证部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.technology) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '高新技术企业认证部门',
+    },
+    required: ({ values }) => {
+      if (values.technology) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'foreignTrade',
+    label: '外贸自营进出口权',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '外贸自营进出口权',
+    },
+  },
+  {
+    field: 'foreignTradeDept',
+    component: 'Input',
+    label: '外贸自营进出口权批准部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.foreignTrade) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '外贸自营进出口权批准部门',
+    },
+    required: ({ values }) => {
+      if (values.foreignTrade) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'quality',
+    label: '质量管理、质量保证系列认证标准',
+    component: 'Switch',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '质量管理、质量保证系列认证标准',
+    },
+  },
+  {
+    field: 'qualityDept',
+    component: 'Input',
+    label: '质量管理、质量保证系列认证标准认证部门',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    show: ({ values }) => {
+      if (values.quality) {
+        return true;
+      }
+      return false;
+    },
+    componentProps: {
+      placeholder: '质量管理、质量保证系列认证标准认证部门',
+    },
+    required: ({ values }) => {
+      if (values.quality) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'regMoney',
+    component: 'Input',
+    label: '注册资金(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '注册资金(万元)',
+    },
+    required: true,
+  },
+  {
+    field: 'money',
+    component: 'Input',
+    label: '资产(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '资产(万元)',
+    },
+  },
+  {
+    field: 'ownerMoney',
+    component: 'Input',
+    label: '所有者权益(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '所有者权益(万元)',
+    },
+  },
+  {
+    field: 'sellMoney',
+    component: 'Input',
+    label: '销售收入(万元)',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      type: 'number',
+      placeholder: '销售收入(万元)',
+    },
+  },
+  {
+    field: 'product',
+    component: 'InputTextArea',
+    label: '主要经营项目',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '主要经营项目',
+    },
+    required: true,
+  },
+];

+ 158 - 0
src/views/event/meeting/customCom/member copy/customCom/unit/index.vue

@@ -0,0 +1,158 @@
+<template>
+  <a-button type="primary" @click="handleAdd"> 添加 </a-button>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getUnitList, addUnit } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Unit',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getUnitList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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.foundingtime) {
+                params.foundingtime = moment(params.foundingtime).format('YYYY-MM-DD');
+              } else {
+                delete params.foundingtime;
+              }
+              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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addUnit(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+</style>

+ 115 - 0
src/views/event/meeting/customCom/member copy/customCom/unit/popup.vue

@@ -0,0 +1,115 @@
+<template>
+  <BasicModal 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 { createMessage } = useMessage();
+      const { error } = createMessage;
+      const role = reactive<Role>({
+        id: 0,
+      });
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+
+      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();
+        setFieldsValue(data);
+        role.id = data.id;
+      });
+
+      async function confirm() {
+        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);
+        } 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>

+ 415 - 0
src/views/event/meeting/customCom/member copy/data.ts

@@ -0,0 +1,415 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import { h } from 'vue';
+import CustomInput from './customCom/CustomInput.vue';
+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: 100,
+    sorter: true,
+  },
+  {
+    title: '会员身份',
+    dataIndex: 'status',
+    width: 130,
+    customRender({ record }) {
+      const options = ['个人', '单位'];
+      return options[record.status];
+    },
+    sorter: true,
+  },
+  {
+    title: '职务',
+    dataIndex: 'duty',
+    width: 130,
+    customRender({ record }) {
+      const options = ['会长', '副会长', '秘书长', '副秘书长', '理事', '会员'];
+      return options[record.duty];
+    },
+    sorter: true,
+  },
+  {
+    title: '入会时间',
+    dataIndex: 'jointime',
+    width: 150,
+    customRender({ record }) {
+      return moment(record.jointime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '当年会费',
+    dataIndex: 'current',
+    width: 200,
+    sorter: true,
+  },
+  {
+    title: '去年会费',
+    dataIndex: 'party',
+    width: 150,
+    sorter: true,
+  },
+  {
+    title: '当年参会率',
+    dataIndex: 'nation',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '去年参会率',
+    dataIndex: 'company',
+    width: 130,
+    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: `status`,
+        label: `会员身份`,
+        component: 'Select',
+        componentProps: {
+          placeholder: '会员身份',
+          options: [
+            { label: '个人', value: 0 },
+            { label: '单位', value: 1 },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `jointime`,
+        label: `入会时间`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '入会时间',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `email`,
+        label: `当年费率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '全年费率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime`,
+        label: `去年费率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '去年费率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime1`,
+        label: `当年参会率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '当年参会率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `logintime2`,
+        label: `去年参会率`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '去年参会率',
+          disabled: true,
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+    ],
+  };
+}
+
+// =================popup================================
+export const schemas: FormSchema[] = [
+  {
+    field: 'status',
+    label: '会员身份',
+    component: 'RadioButtonGroup',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: (value) => {
+      console.log(`value ---- status`, value);
+      return {
+        // disabled: true,
+        options: [
+          { label: '个人', value: 0 },
+          { label: '单位', value: 1 },
+        ],
+      };
+    },
+    defaultValue: 0,
+  },
+  {
+    field: 'name',
+    component: 'Select',
+    label: '姓名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.name,
+        placeholder: '添加个人',
+        onChange(value) {
+          model[field] = value;
+        },
+      });
+    },
+    show: ({ values }) => {
+      if (!values.status) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (!values.status) {
+        return true;
+      }
+      return false;
+    },
+  },
+  {
+    field: 'unitName',
+    component: 'Select',
+    label: '名称',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.name,
+        placeholder: '添加单位',
+        onChange(value) {
+          model.name = value;
+          model[field] = value;
+        },
+      });
+    },
+    show: ({ values }) => {
+      if (values.status) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (values.status) {
+        return true;
+      }
+      return false;
+    },
+  },
+  // {
+  //   field: 'relationUnit',
+  //   component: 'Input',
+  //   label: '相关单位',
+  //   labelWidth: adaptWidth.labelWidth,
+  //   colProps: {
+  //     span: adaptWidth.elContainer,
+  //   },
+  //   render: ({ model, field }) => {
+  //     return h(CustomInput, {
+  //       value: model[field],
+  //       placeholder: '添加相关单位',
+  //       onChange(value) {
+  //         model[field] = value;
+  //       },
+  //     });
+  //   },
+  //   show: ({ values }) => {
+  //     if (values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  //   required: ({ values }) => {
+  //     if (values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  // },
+  // {
+  //   field: 'relation',
+  //   component: 'Input',
+  //   label: '相关个人',
+  //   labelWidth: adaptWidth.labelWidth,
+  //   colProps: {
+  //     span: adaptWidth.elContainer,
+  //   },
+  //   render: ({ model, field }) => {
+  //     return h(CustomInput, {
+  //       value: model[field],
+  //       placeholder: '添加相关个人',
+  //       onChange(value) {
+  //         model[field] = value;
+  //       },
+  //     });
+  //   },
+  //   show: ({ values }) => {
+  //     if (!values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  //   required: ({ values }) => {
+  //     if (!values.status) {
+  //       return true;
+  //     }
+  //     return false;
+  //   },
+  // },
+  {
+    field: 'duty',
+    component: 'Select',
+    label: '职务',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '职务',
+      options: [
+        {
+          label: '会长',
+          value: 0,
+        },
+        {
+          label: '副会长',
+          value: 1,
+        },
+        {
+          label: '秘书长',
+          value: 2,
+        },
+        {
+          label: '副秘书长',
+          value: 3,
+        },
+        {
+          label: '理事',
+          value: 4,
+        },
+        {
+          label: '会员',
+          value: 5,
+        },
+      ],
+    },
+    required: true,
+  },
+  {
+    field: 'jointime',
+    component: 'DatePicker',
+    label: '入会时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '入会时间',
+    },
+    required: true,
+  },
+  {
+    field: 'username',
+    component: 'Input',
+    label: '用户名',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '用户名',
+    },
+    required: true,
+  },
+  {
+    field: 'password',
+    component: 'InputPassword',
+    label: '密码',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '密码',
+    },
+    required: true,
+  },
+];

+ 167 - 0
src/views/event/meeting/customCom/member copy/index.vue

@@ -0,0 +1,167 @@
+<template>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+  <Popup @register="addRegister" @saveData="saveData" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import Popup from './popup.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import { getFormConfig, columns } from './data';
+  import { getMemberList, addMember } from '/@/api/sys/member';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Member',
+    components: { BasicTable, TableAction, Popup },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const { success /*, error*/ } = createMessage;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getMemberList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      async function saveData(params: any) {
+        const data = params.data;
+        const closeModel = params.closeModal;
+        console.log(`data`, data);
+        await addMember(data).then((res) => {
+          console.log(res);
+          getTableAction().reload();
+          closeModel();
+          success('创建成功!');
+        });
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+        addRegister,
+        saveData,
+      };
+    },
+  });
+</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>

+ 148 - 0
src/views/event/meeting/customCom/member copy/popup.vue

@@ -0,0 +1,148 @@
+<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 { createMessage } = useMessage();
+      const { error } = createMessage;
+      const popupData = props.popupData as PopupData;
+      const modelRef = ref({});
+      const role = reactive<Role>({
+        id: 0,
+      });
+
+      const [registerForm, { updateSchema, setFieldsValue, resetFields, validate }] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        resetFields();
+        if (data.id) {
+          role.id = data.id;
+          updateSchema([
+            {
+              field: 'status',
+              componentProps: {
+                disabled: true,
+                options: [
+                  { label: '个人', value: 0 },
+                  { label: '单位', value: 1 },
+                ],
+              },
+            },
+            {
+              field: 'username',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
+              field: 'password',
+              required: false,
+            },
+          ]);
+          data.username = data.admin.username;
+          setFieldsValue(data);
+        } else {
+          role.id = 0;
+          updateSchema([
+            {
+              field: 'status',
+              componentProps: {
+                disabled: false,
+                options: [
+                  { label: '个人', value: 0 },
+                  { label: '单位', value: 1 },
+                ],
+              },
+            },
+            {
+              field: 'username',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
+              field: 'password',
+              required: true,
+            },
+          ]);
+        }
+      });
+
+      async function confirm() {
+        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]);
+        }
+      }
+      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>

+ 397 - 0
src/views/event/meeting/data.ts

@@ -0,0 +1,397 @@
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Form/index';
+import { adapt } from '/@/utils/adapt';
+import moment from 'moment';
+import { formatToDate } from '/@/utils/dateUtil';
+
+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: 'starttime',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.starttime).format('YYYY-MM-DD');
+    },
+    sorter: true,
+  },
+  {
+    title: '地点',
+    dataIndex: 'place',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '计划人数',
+    dataIndex: 'plan',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '报名人数',
+    dataIndex: 'apply',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '参会人数',
+    dataIndex: 'actual',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '会议状态',
+    dataIndex: 'status',
+    width: 130,
+    customRender({ record }) {
+      const options = ['筹备', '完成', '取消'];
+      return options[record.status];
+    },
+    sorter: true,
+  },
+  {
+    title: '操作员',
+    dataIndex: 'manager',
+    width: 130,
+    sorter: true,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 160,
+    sorter: true,
+  },
+  {
+    title: '创建日期',
+    dataIndex: 'createtime',
+    width: 200,
+    customRender: ({ record }) => {
+      const createtime = record.createtime;
+      return formatToDate(createtime * 1000);
+    },
+  },
+];
+
+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: `starttime`,
+        label: `开始时间`,
+        component: 'DatePicker',
+        componentProps: {
+          placeholder: '开始时间',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `place`,
+        label: `地点`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '地点',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `plan`,
+        label: `计划人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '计划人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `apply`,
+        label: `报名人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '报名人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `actual`,
+        label: `参会人数`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '参会人数',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `status`,
+        label: `会议状态`,
+        component: 'Select',
+        componentProps: {
+          options: [
+            {
+              label: '筹备',
+              value: 0,
+            },
+            {
+              label: '完成',
+              value: 1,
+            },
+            {
+              label: '取消',
+              value: 2,
+            },
+          ],
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `manager`,
+        label: `操作员`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '操作员',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `remark`,
+        label: `备注`,
+        component: 'Input',
+        componentProps: {
+          placeholder: '备注',
+        },
+        colProps: {
+          xl: 12,
+          xxl: 8,
+        },
+      },
+      {
+        field: `createtime`,
+        label: `创建日期`,
+        component: 'DatePicker',
+        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: 'starttime',
+    component: 'TimePicker',
+    label: '开始时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '开始时间',
+    },
+    required: true,
+  },
+  {
+    field: 'endtime',
+    component: 'DatePicker',
+    label: '结束时间',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '结束时间',
+    },
+    required: true,
+  },
+  {
+    field: 'place',
+    component: 'Input',
+    label: '地点',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '地点',
+    },
+    required: true,
+  },
+  {
+    field: 'plan',
+    component: 'Input',
+    label: '计划参会人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '计划参会人员',
+    },
+  },
+  {
+    field: 'apply',
+    component: 'Input',
+    label: '报名参会人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '报名参会人员',
+    },
+  },
+  {
+    field: 'actual',
+    component: 'Input',
+    label: '实际参会人员',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '实际参会人员',
+    },
+  },
+  {
+    field: 'content',
+    component: 'InputTextArea',
+    label: '会议内容',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '会议内容',
+    },
+  },
+  {
+    field: 'status',
+    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: 'attachment',
+    component: 'Input',
+    label: '附件',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '附件',
+    },
+  },
+  {
+    field: 'remark',
+    component: 'Input',
+    label: '备注',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '备注',
+    },
+  },
+];

+ 317 - 0
src/views/event/meeting/index.vue

@@ -0,0 +1,317 @@
+<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 {
+    getMeetingList,
+    addMeeting,
+    deleteBatchesMeeting,
+    getMeeting,
+    editMeeting,
+    deleteMeeting,
+  } from '/@/api/sys/event';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+  }
+
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'Meeting',
+    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: getMeetingList,
+        useSearchForm: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        formConfig: getFormConfig(),
+        actionColumn: {
+          width: 260,
+          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' &&
+            k !== 'createdate'
+          ) {
+            if (params[k] === '') {
+              delete params[k];
+            } else {
+              if (!params.filter) {
+                params.filter = {};
+              }
+              if (params.createdate) {
+                params.createdate = moment(params.createdate).format('YYYY-MM-DD');
+              } else {
+                delete params.createdate;
+              }
+              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, {});
+      }
+
+      async function handleEdit(record: EditRecordRow) {
+        popupData.title = '编辑';
+        getMeeting({ 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 deleteMeeting({ 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 deleteBatchesMeeting({ 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 addMeeting(data).then((res) => {
+            console.log(res);
+            getTableAction().reload();
+            closeModel();
+            success('创建成功!');
+          });
+          console.log('----------add---');
+        } else {
+          await editMeeting(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>

+ 125 - 0
src/views/event/meeting/popup.vue

@@ -0,0 +1,125 @@
+<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';
+  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, { updateSchema, 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();
+        if (data.id) {
+          role.id = data.id;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: true,
+              },
+            },
+          ]);
+        } else {
+          role.id = 0;
+          updateSchema([
+            {
+              field: 'year',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
+              field: 'duty',
+              componentProps: {
+                disabled: false,
+              },
+            },
+          ]);
+        }
+        setFieldsValue(data);
+      });
+
+      async function confirm() {
+        try {
+          const data = await validate();
+          console.log(`确定`, data);
+          data.id = role.id;
+          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>

+ 13 - 0
src/views/member/person/data.ts

@@ -578,6 +578,19 @@ export const schemas: FormSchema[] = [
     },
   },
   {
+    field: 'job',
+    component: 'Input',
+    label: '社会职务',
+    labelWidth: adaptWidth.labelWidth,
+    defaultValue: '',
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      placeholder: '社会职务',
+    },
+  },
+  {
     field: 'family',
     component: 'ArrCom',
     label: '家庭主要成员',

+ 50 - 0
src/views/money/account/customCom/accountrecord/data.ts

@@ -0,0 +1,50 @@
+import { BasicColumn } from '/@/components/Table';
+import moment from 'moment';
+
+export const columns: BasicColumn[] = [
+  {
+    title: 'ID',
+    dataIndex: 'id',
+    editComponentProps: {
+      prefix: '$',
+    },
+    width: 100,
+  },
+  {
+    title: '资金增减',
+    dataIndex: 'type',
+    width: 130,
+    customRender({ record }) {
+      const options = ['减少', '增加'];
+      return options[record.type];
+    },
+  },
+  {
+    title: '资金变化数额',
+    dataIndex: 'money',
+    width: 130,
+  },
+  {
+    title: '类型名称',
+    dataIndex: 'typename',
+    width: 130,
+  },
+  {
+    title: '相关会员',
+    dataIndex: 'member',
+    width: 130,
+  },
+  {
+    title: '操作者',
+    dataIndex: 'manager',
+    width: 130,
+  },
+  {
+    title: '创建日期',
+    dataIndex: 'createtime',
+    width: 200,
+    customRender({ record }) {
+      return moment(record.createtime).format('YYYY-MM-DD');
+    },
+  },
+];

+ 107 - 0
src/views/money/account/customCom/accountrecord/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <CollapseContainer class="sys-container" title="账目记录" :canExpan="false">
+    <BasicTable
+      ref="tableRef"
+      @register="registerTable"
+      rowKey="id"
+      showTableSetting
+      :canResize="true"
+      :pagination="{
+        pageSize: 10,
+        defaultPageSize: 10,
+        showSizeChanger: false,
+      }"
+    >
+      <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 } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Popup from './popup.vue';
+  import { useModal } from '/@/components/Modal';
+  import { ExpExcelModel } from '/@/components/Excel';
+  import { columns } from './data';
+  import { useUserStore } from '/@/store/modules/user';
+  import { BasicTable, useTable, TableAction, TableActionType } from '/@/components/Table';
+
+  interface PopupData {
+    title: string;
+    data: object[];
+  }
+  interface Btn {
+    disable_btn: boolean;
+  }
+
+  export default defineComponent({
+    name: 'AccountRecord',
+    components: { CollapseContainer, BasicTable, TableAction, Popup, ExpExcelModel },
+    setup() {
+      init();
+      const userStore = useUserStore();
+      const id: any = userStore.getUserInfo?.id;
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const popupData = reactive<PopupData>({
+        title: '添加',
+        Data: [],
+      });
+      const btn = reactive<Btn>({
+        disable_btn: true,
+      });
+      const [registerTable] = useTable({
+        rowSelection: {
+          type: 'checkbox',
+          getCheckboxProps: (record) => ({
+            disabled: record.id === id || !record.groups[0], // Column configuration not to be checked
+          }),
+        },
+        columns: columns,
+        // clickToRowSelect: false, // 点击行不勾选
+        dataSource: data,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      const [register, { openModal }] = useModal();
+      function getTableAction() {
+        // 获取组件
+        const tableAction = unref(tableRef);
+        if (!tableAction) {
+          throw new Error('tableAction is null');
+        }
+        return tableAction;
+      }
+
+      return {
+        popupData,
+        tableRef,
+        registerTable,
+        addRole,
+        getTableAction,
+        defaultHeader,
+        openModal,
+        register,
+        ...toRefs(btn),
+      };
+    },
+  });
+</script>
+<style>
+  .ant-calendar-picker {
+    width: 100%;
+  }
+  @media (max-width: 639px) {
+    .sys-container .vben-basic-table-header__toolbar > * {
+      margin-right: 3px;
+    }
+
+    .sys-container .vben-basic-table .ant-table-wrapper {
+      padding: 3px;
+    }
+  }
+</style>

+ 43 - 0
src/views/money/account/customCom/popup.vue

@@ -0,0 +1,43 @@
+<template>
+  <BasicModal
+    :showCancelBtn="false"
+    :showOkBtn="false"
+    width="800px"
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+  >
+    <AccountRecord v-if="title === '账户记录'" @select="select" :data="data" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import AccountRecord from './accountrecord/index.vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { defineComponent, reactive, toRefs } from 'vue';
+
+  export default defineComponent({
+    components: { BasicModal, AccountRecord },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const state = reactive({
+        title: '',
+        data: '',
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        state.title = data;
+        data = data;
+      });
+
+      function select(data) {
+        emit('select', data);
+        closeModal();
+      }
+      return {
+        register,
+        select,
+        data,
+        ...toRefs(state),
+      };
+    },
+  });
+</script>

+ 3 - 4
src/views/money/account/index.vue

@@ -1,9 +1,9 @@
 <template>
   <CollapseContainer
     class="sys-container"
-    title="个人管理"
+    title="账户管理"
     :canExpan="false"
-    helpMessage="个人管理"
+    helpMessage="账户管理"
   >
     <BasicTable
       ref="tableRef"
@@ -164,7 +164,6 @@
         popupData.title = '编辑';
         getAccount({ id: record.id }).then((res) => {
           const data = res.row;
-          console.log(`data`, data);
           openPopup(true, data);
         });
       }
@@ -173,7 +172,7 @@
         popupData.title = '详情';
         getAccountRecordList({ id: record.id }).then((res) => {
           const data = res.list;
-          openPopup(true, data);
+          console.log(data);
         });
       }
 

+ 6 - 1
src/views/money/bill/customCom/CustomInput.vue

@@ -49,10 +49,15 @@
           if (props.value.name) {
             console.log(`props.value.name`, props.value.name);
             state.value = props.value.name;
+          } else if (props.value.url) {
+            state.value = props.value.url;
           } else {
             state.value = props.value;
           }
-          if (state.value !== '' && typeof props.value === 'string') {
+          if (
+            state.value !== '' &&
+            (typeof props.value === 'string' || typeof props.value === 'number')
+          ) {
             state.disabled = true;
           } else {
             state.disabled = false;

+ 35 - 0
src/views/money/bill/customCom/attachment/customComponents/Image.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="wrap">
+    <a-image class="image" :src="src" :width="width" />
+  </div>
+</template>
+<script lang="ts">
+  import { Image } from 'ant-design-vue';
+  import { defineComponent, toRefs } from 'vue';
+
+  const props = {
+    src: { type: String, default: '' },
+    width: { type: String, default: '' },
+  };
+
+  export default defineComponent({
+    components: { aImage: Image },
+    props,
+    setup(props) {
+      return {
+        ...toRefs(props),
+      };
+    },
+  });
+</script>
+<style scoped>
+  .wrap {
+    display: flex;
+    justify-content: space-around;
+    width: 100%;
+    height: 60px;
+    align-items: center;
+    border: 1px solid #ddd;
+    border-radius: 2px;
+  }
+</style>

+ 98 - 0
src/views/money/bill/customCom/attachment/data.ts

@@ -0,0 +1,98 @@
+import { BasicColumn } from '/@/components/Table';
+import Image from './customComponents/Image.vue';
+import { h } from 'vue';
+import { Tag } from 'ant-design-vue';
+import { formatSize } from '/@/utils/foramtFileSize';
+import moment from 'moment';
+
+export const columns: BasicColumn[] = [
+  {
+    title: 'ID',
+    align: 'center',
+    dataIndex: 'id',
+    width: 100,
+  },
+  {
+    title: '预览',
+    align: 'center',
+    dataIndex: 'url',
+    width: 100,
+    customRender: ({ record }) => {
+      return h(Image, {
+        src: record.url,
+        width: '50px',
+      });
+    },
+  },
+  {
+    title: '物理路径',
+    align: 'center',
+    dataIndex: 'url',
+    width: 480,
+    customRender: ({ record }) => {
+      return h(
+        Tag,
+        {
+          color: '#18bc9c',
+          style: {
+            fontSize: '12px',
+            fontWeight: 'bold',
+            margin: '0 auto',
+          },
+        },
+        record.url
+      );
+    },
+  },
+  {
+    title: '宽度',
+    align: 'center',
+    dataIndex: 'imagewidth',
+    width: 100,
+  },
+  {
+    title: '高度',
+    align: 'center',
+    dataIndex: 'imageheight',
+    width: 100,
+  },
+  {
+    title: '图片类型',
+    align: 'center',
+    dataIndex: 'imagetype',
+    width: 100,
+  },
+  {
+    title: '储存引擎',
+    align: 'center',
+    dataIndex: 'storage',
+    width: 100,
+  },
+  {
+    title: '文件大小',
+    align: 'center',
+    dataIndex: 'filesize',
+    width: 100,
+    customRender: ({ text = 0 }) => {
+      return formatSize(text);
+    },
+  },
+  {
+    title: 'Mime类型',
+    align: 'center',
+    dataIndex: 'mimetype',
+    width: 100,
+  },
+  {
+    title: '创建日期',
+    align: 'center',
+    dataIndex: 'createtime',
+    width: 160,
+    customRender({ record }) {
+      if (!record.createtime) {
+        return null;
+      }
+      return moment(record.createtime).format('YYYY-MM-DD');
+    },
+  },
+];

+ 147 - 0
src/views/money/bill/customCom/attachment/index.vue

@@ -0,0 +1,147 @@
+<template>
+  <BasicTable
+    ref="tableRef"
+    @register="registerTable"
+    rowKey="id"
+    :pagination="{
+      pageSize: 10,
+      defaultPageSize: 10,
+      showSizeChanger: false,
+    }"
+  >
+    <template #form-custom> custom-slot </template>
+    <template #action="{ record }">
+      <TableAction :actions="createActions(record)" stopButtonPropagation />
+    </template>
+  </BasicTable>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { useModal } from '/@/components/Modal';
+  import { columns } from './data';
+  import { getAttachmentList } from '/@/api/sys/general';
+  import moment from 'moment';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    ActionItem,
+    EditRecordRow,
+    TableActionType,
+  } from '/@/components/Table';
+
+  export default defineComponent({
+    name: 'Attachment',
+    components: { BasicTable, TableAction },
+    emits: ['select'],
+    setup(_, { emit }) {
+      const tableRef = ref<Nullable<TableActionType>>(null);
+      const [registerTable] = useTable({
+        columns: columns,
+        clickToRowSelect: false, // 点击行不勾选
+        api: getAttachmentList,
+        useSearchForm: true,
+        showTableSetting: true,
+        tableSetting: {
+          redo: false,
+          size: false,
+        },
+        beforeFetch: beforeFetch,
+        afterFetch: afterFetch,
+        actionColumn: {
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        maxHeight: 190,
+        showIndexColumn: false,
+        bordered: true,
+      });
+      const [{ 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 handleAdd() {
+        // 开启弹窗
+        openPopup(true, { family: [] });
+      }
+      function handleSelect(record: EditRecordRow) {
+        emit('select', record);
+      }
+
+      function createActions(record: EditRecordRow): ActionItem[] {
+        return [
+          {
+            label: '选择',
+            icon: 'ant-design:edit-outlined',
+            color: 'warning',
+            onClick: handleSelect.bind(null, record),
+          },
+        ];
+      }
+      return {
+        tableRef,
+        registerTable,
+        handleAdd,
+        handleSelect,
+        createActions,
+        getTableAction,
+      };
+    },
+  });
+</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>

+ 99 - 0
src/views/money/bill/customCom/attachment/popup.vue

@@ -0,0 +1,99 @@
+<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 } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  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 [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() {
+        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,
+        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>

+ 3 - 1
src/views/money/bill/customCom/popup.vue

@@ -12,6 +12,7 @@
     <Account v-if="title === '添加账户'" @select="select" />
     <Type v-if="title === '交易名称'" @select="select" />
     <Dues v-if="title === '会员年份'" @select="select" />
+    <Attachment v-if="title === '添加附件'" @select="select" />
   </BasicModal>
 </template>
 <script lang="ts">
@@ -19,11 +20,12 @@
   import Account from './account/index.vue';
   import Type from './type/index.vue';
   import Dues from './dues/index.vue';
+  import Attachment from './attachment/index.vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { defineComponent, reactive, toRefs } from 'vue';
 
   export default defineComponent({
-    components: { BasicModal, Member, Account, Type, Dues },
+    components: { BasicModal, Member, Account, Type, Dues, Attachment },
     emits: ['select'],
     setup(_, { emit }) {
       const state = reactive({

+ 51 - 5
src/views/money/bill/data.ts

@@ -237,6 +237,22 @@ export const schemas: FormSchema[] = [
     required: true,
   },
   {
+    field: 'isdues',
+    label: '会费',
+    component: 'RadioButtonGroup',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    componentProps: {
+      options: [
+        { label: '否', value: 0 },
+        { label: '是', value: 1 },
+      ],
+    },
+    defaultValue: 0,
+  },
+  {
     field: 'typename',
     component: 'Select',
     label: '交易名称',
@@ -253,7 +269,18 @@ export const schemas: FormSchema[] = [
         },
       });
     },
-    required: true,
+    show: ({ values }) => {
+      if (values.isdues == 0) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (values.isdues == 0) {
+        return true;
+      }
+      return false;
+    },
   },
   {
     field: 'account',
@@ -317,10 +344,23 @@ export const schemas: FormSchema[] = [
         value: model.duesyear,
         placeholder: '会员年份',
         onChange(value) {
-          model[field] = value;
+          model[field] = value.year;
+          model['money'] = value.money;
         },
       });
     },
+    show: ({ values }) => {
+      if (values.isdues == 1) {
+        return true;
+      }
+      return false;
+    },
+    required: ({ values }) => {
+      if (values.isdues == 1) {
+        return true;
+      }
+      return false;
+    },
   },
   {
     field: 'money',
@@ -392,14 +432,20 @@ export const schemas: FormSchema[] = [
   },
   {
     field: 'attachment',
-    component: 'Input',
+    component: 'Select',
     label: '附件',
     labelWidth: adaptWidth.labelWidth,
     colProps: {
       span: adaptWidth.elContainer,
     },
-    componentProps: {
-      placeholder: '附件',
+    render: ({ model, field }) => {
+      return h(CustomInput, {
+        value: model.attachment,
+        placeholder: '添加附件',
+        onChange(value) {
+          model[field] = value;
+        },
+      });
     },
   },
   {

+ 2 - 2
src/views/money/bill/index.vue

@@ -1,9 +1,9 @@
 <template>
   <CollapseContainer
     class="sys-container"
-    title="个人管理"
+    title="账目管理"
     :canExpan="false"
-    helpMessage="个人管理"
+    helpMessage="账目管理"
   >
     <BasicTable
       ref="tableRef"

+ 12 - 0
src/views/money/bill/popup.vue

@@ -59,6 +59,12 @@
               },
             },
             {
+              field: 'isdues',
+              componentProps: {
+                disabled: true,
+              },
+            },
+            {
               field: 'type',
               componentProps: {
                 disabled: true,
@@ -75,6 +81,12 @@
               },
             },
             {
+              field: 'isdues',
+              componentProps: {
+                disabled: false,
+              },
+            },
+            {
               field: 'type',
               componentProps: {
                 disabled: false,

+ 2 - 2
src/views/money/dues/index.vue

@@ -1,9 +1,9 @@
 <template>
   <CollapseContainer
     class="sys-container"
-    title="个人管理"
+    title="会费管理"
     :canExpan="false"
-    helpMessage="个人管理"
+    helpMessage="会费管理"
   >
     <BasicTable
       ref="tableRef"

+ 2 - 2
src/views/money/type/index.vue

@@ -1,9 +1,9 @@
 <template>
   <CollapseContainer
     class="sys-container"
-    title="个人管理"
+    title="交易类型管理"
     :canExpan="false"
-    helpMessage="个人管理"
+    helpMessage="交易类型管理"
   >
     <BasicTable
       ref="tableRef"