feat:初始化 dept 部门(from 官方 example)
							parent
							
								
									c1691955f7
								
							
						
					
					
						commit
						1f03da9ccb
					
				| 
						 | 
					@ -0,0 +1,135 @@
 | 
				
			||||||
 | 
					import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import type { VbenFormSchema } from '#/adapter/form';
 | 
				
			||||||
 | 
					import type { OnActionClickFn } from '#/adapter/vxe-table';
 | 
				
			||||||
 | 
					// import type { SystemDeptApi } from '#/api/system/dept';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { z } from '#/adapter/form';
 | 
				
			||||||
 | 
					// import { getDeptList } from '#/api/system/dept';
 | 
				
			||||||
 | 
					import { $t } from '#/locales';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 获取编辑表单的字段配置。如果没有使用多语言,可以直接export一个数组常量
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function useSchema(): VbenFormSchema[] {
 | 
				
			||||||
 | 
					  return [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      component: 'Input',
 | 
				
			||||||
 | 
					      fieldName: 'name',
 | 
				
			||||||
 | 
					      label: $t('system.dept.deptName'),
 | 
				
			||||||
 | 
					      rules: z
 | 
				
			||||||
 | 
					        .string()
 | 
				
			||||||
 | 
					        .min(2, $t('ui.formRules.minLength', [$t('system.dept.deptName'), 2]))
 | 
				
			||||||
 | 
					        .max(
 | 
				
			||||||
 | 
					          20,
 | 
				
			||||||
 | 
					          $t('ui.formRules.maxLength', [$t('system.dept.deptName'), 20]),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //   component: 'ApiTreeSelect',
 | 
				
			||||||
 | 
					    //   componentProps: {
 | 
				
			||||||
 | 
					    //     allowClear: true,
 | 
				
			||||||
 | 
					    //     api: getDeptList,
 | 
				
			||||||
 | 
					    //     class: 'w-full',
 | 
				
			||||||
 | 
					    //     labelField: 'name',
 | 
				
			||||||
 | 
					    //     valueField: 'id',
 | 
				
			||||||
 | 
					    //     childrenField: 'children',
 | 
				
			||||||
 | 
					    //   },
 | 
				
			||||||
 | 
					    //   fieldName: 'pid',
 | 
				
			||||||
 | 
					    //   label: $t('system.dept.parentDept'),
 | 
				
			||||||
 | 
					    // },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      component: 'RadioGroup',
 | 
				
			||||||
 | 
					      componentProps: {
 | 
				
			||||||
 | 
					        buttonStyle: 'solid',
 | 
				
			||||||
 | 
					        options: [
 | 
				
			||||||
 | 
					          { label: $t('common.enabled'), value: 1 },
 | 
				
			||||||
 | 
					          { label: $t('common.disabled'), value: 0 },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        optionType: 'button',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      defaultValue: 1,
 | 
				
			||||||
 | 
					      fieldName: 'status',
 | 
				
			||||||
 | 
					      label: $t('system.dept.status'),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      component: 'Textarea',
 | 
				
			||||||
 | 
					      componentProps: {
 | 
				
			||||||
 | 
					        maxLength: 50,
 | 
				
			||||||
 | 
					        rows: 3,
 | 
				
			||||||
 | 
					        showCount: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      fieldName: 'remark',
 | 
				
			||||||
 | 
					      label: $t('system.dept.remark'),
 | 
				
			||||||
 | 
					      rules: z
 | 
				
			||||||
 | 
					        .string()
 | 
				
			||||||
 | 
					        .max(50, $t('ui.formRules.maxLength', [$t('system.dept.remark'), 50]))
 | 
				
			||||||
 | 
					        .optional(),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 获取表格列配置
 | 
				
			||||||
 | 
					 * @description 使用函数的形式返回列数据而不是直接export一个Array常量,是为了响应语言切换时重新翻译表头
 | 
				
			||||||
 | 
					 * @param onActionClick 表格操作按钮点击事件
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function useColumns(
 | 
				
			||||||
 | 
					  onActionClick?: OnActionClickFn<SystemDeptApi.SystemDept>,
 | 
				
			||||||
 | 
					): VxeTableGridOptions<SystemDeptApi.SystemDept>['columns'] {
 | 
				
			||||||
 | 
					  return [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      align: 'left',
 | 
				
			||||||
 | 
					      field: 'name',
 | 
				
			||||||
 | 
					      fixed: 'left',
 | 
				
			||||||
 | 
					      title: $t('system.dept.deptName'),
 | 
				
			||||||
 | 
					      treeNode: true,
 | 
				
			||||||
 | 
					      width: 150,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      cellRender: { name: 'CellTag' },
 | 
				
			||||||
 | 
					      field: 'status',
 | 
				
			||||||
 | 
					      title: $t('system.dept.status'),
 | 
				
			||||||
 | 
					      width: 100,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: 'createTime',
 | 
				
			||||||
 | 
					      title: $t('system.dept.createTime'),
 | 
				
			||||||
 | 
					      width: 180,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: 'remark',
 | 
				
			||||||
 | 
					      title: $t('system.dept.remark'),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      align: 'right',
 | 
				
			||||||
 | 
					      cellRender: {
 | 
				
			||||||
 | 
					        attrs: {
 | 
				
			||||||
 | 
					          nameField: 'name',
 | 
				
			||||||
 | 
					          nameTitle: $t('system.dept.name'),
 | 
				
			||||||
 | 
					          onClick: onActionClick,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        name: 'CellOperation',
 | 
				
			||||||
 | 
					        options: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            code: 'append',
 | 
				
			||||||
 | 
					            text: '新增下级',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          'edit', // 默认的编辑按钮
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            code: 'delete', // 默认的删除按钮
 | 
				
			||||||
 | 
					            disabled: (row: SystemDeptApi.SystemDept) => {
 | 
				
			||||||
 | 
					              return !!(row.children && row.children.length > 0);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      field: 'operation',
 | 
				
			||||||
 | 
					      fixed: 'right',
 | 
				
			||||||
 | 
					      headerAlign: 'center',
 | 
				
			||||||
 | 
					      showOverflow: false,
 | 
				
			||||||
 | 
					      title: $t('system.dept.operation'),
 | 
				
			||||||
 | 
					      width: 200,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,143 @@
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import type {
 | 
				
			||||||
 | 
					  OnActionClickParams,
 | 
				
			||||||
 | 
					  VxeTableGridOptions,
 | 
				
			||||||
 | 
					} from '#/adapter/vxe-table';
 | 
				
			||||||
 | 
					// import type { SystemDeptApi } from '#/api/system/dept';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Page, useVbenModal } from '@vben/common-ui';
 | 
				
			||||||
 | 
					import { Plus } from '@vben/icons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Button, message } from 'ant-design-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useVbenVxeGrid } from '#/adapter/vxe-table';
 | 
				
			||||||
 | 
					// import { deleteDept, getDeptList } from '#/api/system/dept';
 | 
				
			||||||
 | 
					import { $t } from '#/locales';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useColumns } from './data';
 | 
				
			||||||
 | 
					import Form from './modules/form.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const [FormModal, formModalApi] = useVbenModal({
 | 
				
			||||||
 | 
					  connectedComponent: Form,
 | 
				
			||||||
 | 
					  destroyOnClose: true,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 编辑部门
 | 
				
			||||||
 | 
					 * @param row
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function onEdit(row: SystemDeptApi.SystemDept) {
 | 
				
			||||||
 | 
					  formModalApi.setData(row).open();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 添加下级部门
 | 
				
			||||||
 | 
					 * @param row
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function onAppend(row: SystemDeptApi.SystemDept) {
 | 
				
			||||||
 | 
					  formModalApi.setData({ pid: row.id }).open();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 创建新部门
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function onCreate() {
 | 
				
			||||||
 | 
					  formModalApi.setData(null).open();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 删除部门
 | 
				
			||||||
 | 
					 * @param row
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function onDelete(row: SystemDeptApi.SystemDept) {
 | 
				
			||||||
 | 
					  const hideLoading = message.loading({
 | 
				
			||||||
 | 
					    content: $t('ui.actionMessage.deleting', [row.name]),
 | 
				
			||||||
 | 
					    duration: 0,
 | 
				
			||||||
 | 
					    key: 'action_process_msg',
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  deleteDept(row.id)
 | 
				
			||||||
 | 
					    .then(() => {
 | 
				
			||||||
 | 
					      message.success({
 | 
				
			||||||
 | 
					        content: $t('ui.actionMessage.deleteSuccess', [row.name]),
 | 
				
			||||||
 | 
					        key: 'action_process_msg',
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      refreshGrid();
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(() => {
 | 
				
			||||||
 | 
					      hideLoading();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 表格操作按钮的回调函数
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function onActionClick({
 | 
				
			||||||
 | 
					  code,
 | 
				
			||||||
 | 
					  row,
 | 
				
			||||||
 | 
					}: OnActionClickParams<SystemDeptApi.SystemDept>) {
 | 
				
			||||||
 | 
					  switch (code) {
 | 
				
			||||||
 | 
					    case 'append': {
 | 
				
			||||||
 | 
					      onAppend(row);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case 'delete': {
 | 
				
			||||||
 | 
					      onDelete(row);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    case 'edit': {
 | 
				
			||||||
 | 
					      onEdit(row);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const [Grid, gridApi] = useVbenVxeGrid({
 | 
				
			||||||
 | 
					  gridEvents: {},
 | 
				
			||||||
 | 
					  gridOptions: {
 | 
				
			||||||
 | 
					    columns: useColumns(onActionClick),
 | 
				
			||||||
 | 
					    height: 'auto',
 | 
				
			||||||
 | 
					    keepSource: true,
 | 
				
			||||||
 | 
					    pagerConfig: {
 | 
				
			||||||
 | 
					      enabled: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    proxyConfig: {
 | 
				
			||||||
 | 
					      ajax: {
 | 
				
			||||||
 | 
					        query: async (_params) => {
 | 
				
			||||||
 | 
					          return await getDeptList();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    toolbarConfig: {
 | 
				
			||||||
 | 
					      custom: true,
 | 
				
			||||||
 | 
					      export: false,
 | 
				
			||||||
 | 
					      refresh: { code: 'query' },
 | 
				
			||||||
 | 
					      zoom: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    treeConfig: {
 | 
				
			||||||
 | 
					      parentField: 'pid',
 | 
				
			||||||
 | 
					      rowField: 'id',
 | 
				
			||||||
 | 
					      transform: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  } as VxeTableGridOptions,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 刷新表格
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function refreshGrid() {
 | 
				
			||||||
 | 
					  gridApi.query();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <Page auto-content-height>
 | 
				
			||||||
 | 
					    <FormModal @success="refreshGrid" />
 | 
				
			||||||
 | 
					    <Grid table-title="部门列表">
 | 
				
			||||||
 | 
					      <template #toolbar-tools>
 | 
				
			||||||
 | 
					        <Button type="primary" @click="onCreate">
 | 
				
			||||||
 | 
					          <Plus class="size-5" />
 | 
				
			||||||
 | 
					          {{ $t('ui.actionTitle.create', [$t('system.dept.name')]) }}
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					  </Page>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,78 @@
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					// import type { SystemDeptApi } from '#/api/system/dept';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { computed, ref } from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useVbenModal } from '@vben/common-ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Button } from 'ant-design-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useVbenForm } from '#/adapter/form';
 | 
				
			||||||
 | 
					// import { createDept, updateDept } from '#/api/system/dept';
 | 
				
			||||||
 | 
					import { $t } from '#/locales';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useSchema } from '../data';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emit = defineEmits(['success']);
 | 
				
			||||||
 | 
					const formData = ref<SystemDeptApi.SystemDept>();
 | 
				
			||||||
 | 
					const getTitle = computed(() => {
 | 
				
			||||||
 | 
					  return formData.value?.id
 | 
				
			||||||
 | 
					    ? $t('ui.actionTitle.edit', [$t('system.dept.name')])
 | 
				
			||||||
 | 
					    : $t('ui.actionTitle.create', [$t('system.dept.name')]);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const [Form, formApi] = useVbenForm({
 | 
				
			||||||
 | 
					  layout: 'vertical',
 | 
				
			||||||
 | 
					  schema: useSchema(),
 | 
				
			||||||
 | 
					  showDefaultActions: false,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function resetForm() {
 | 
				
			||||||
 | 
					  formApi.resetForm();
 | 
				
			||||||
 | 
					  formApi.setValues(formData.value || {});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const [Modal, modalApi] = useVbenModal({
 | 
				
			||||||
 | 
					  async onConfirm() {
 | 
				
			||||||
 | 
					    const { valid } = await formApi.validate();
 | 
				
			||||||
 | 
					    if (valid) {
 | 
				
			||||||
 | 
					      modalApi.lock();
 | 
				
			||||||
 | 
					      const data = formApi.getValues();
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        await (formData.value?.id
 | 
				
			||||||
 | 
					          ? updateDept(formData.value.id, data)
 | 
				
			||||||
 | 
					          : createDept(data));
 | 
				
			||||||
 | 
					        modalApi.close();
 | 
				
			||||||
 | 
					        emit('success');
 | 
				
			||||||
 | 
					      } finally {
 | 
				
			||||||
 | 
					        modalApi.lock(false);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  onOpenChange(isOpen) {
 | 
				
			||||||
 | 
					    if (isOpen) {
 | 
				
			||||||
 | 
					      const data = modalApi.getData<SystemDeptApi.SystemDept>();
 | 
				
			||||||
 | 
					      if (data) {
 | 
				
			||||||
 | 
					        if (data.pid === 0) {
 | 
				
			||||||
 | 
					          data.pid = undefined;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        formData.value = data;
 | 
				
			||||||
 | 
					        formApi.setValues(formData.value);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <Modal :title="getTitle">
 | 
				
			||||||
 | 
					    <Form class="mx-4" />
 | 
				
			||||||
 | 
					    <template #prepend-footer>
 | 
				
			||||||
 | 
					      <div class="flex-auto">
 | 
				
			||||||
 | 
					        <Button type="primary" danger @click="resetForm">
 | 
				
			||||||
 | 
					          {{ $t('common.reset') }}
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </Modal>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue