From 2e0c7e23e9f5c465b408880a7c7c91a8b7ad4558 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 19 May 2025 12:52:14 +0800 Subject: [PATCH 01/31] =?UTF-8?q?feat:=20=E3=80=90ANTD=E3=80=91=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E6=97=B6=EF=BC=8C=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E7=94=9F=E6=88=90=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/api/infra/codegen/index.ts | 1 + apps/web-antd/src/views/infra/codegen/data.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/web-antd/src/api/infra/codegen/index.ts b/apps/web-antd/src/api/infra/codegen/index.ts index d8fea045..0760e752 100644 --- a/apps/web-antd/src/api/infra/codegen/index.ts +++ b/apps/web-antd/src/api/infra/codegen/index.ts @@ -21,6 +21,7 @@ export namespace InfraCodegenApi { createTime: Date; updateTime: Date; templateType: number; + deleteBatch: boolean; parentMenuId: number; } diff --git a/apps/web-antd/src/views/infra/codegen/data.ts b/apps/web-antd/src/views/infra/codegen/data.ts index b9b354a2..e705dc24 100644 --- a/apps/web-antd/src/views/infra/codegen/data.ts +++ b/apps/web-antd/src/views/infra/codegen/data.ts @@ -11,6 +11,7 @@ import { useAccess } from '@vben/access'; import { IconifyIcon } from '@vben/icons'; import { handleTree } from '@vben/utils'; +import { z } from '#/adapter/form'; import { getDataSourceConfigList } from '#/api/infra/data-source-config'; import { getMenuList } from '#/api/system/menu'; import { $t } from '#/locales'; @@ -157,6 +158,17 @@ export function useGenerationInfoBaseFormSchema(): VbenFormSchema[] { }, rules: 'selectRequired', }, + { + component: 'RadioGroup', + fieldName: 'deleteBatch', + label: '批量删除?', + help: '是否生成批量删除接口', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), + class: 'w-full', + }, + rules: z.boolean().default(false), + }, { fieldName: 'parentMenuId', label: '上级菜单', @@ -350,7 +362,7 @@ export function useGenerationInfoSubTableFormSchema( }, { label: '一对一', - value: 'false', + value: false, }, ], }, From 98e9d9fbfc7e5d95181f0d988c0b7f68c2be4ef8 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 19 May 2025 12:53:10 +0800 Subject: [PATCH 02/31] =?UTF-8?q?feat:=20=E3=80=90ANTD=E3=80=91=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3=E7=A4=BA=E4=BE=8B=20demo01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/infra/demo/demo01/index.ts | 9 +++- .../src/views/infra/demo/demo01/data.ts | 2 +- .../src/views/infra/demo/demo01/index.vue | 54 +++++++++++++++++-- packages/@core/base/icons/src/lucide.ts | 1 + 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/apps/web-antd/src/api/infra/demo/demo01/index.ts b/apps/web-antd/src/api/infra/demo/demo01/index.ts index 5a940a61..0fbd3141 100644 --- a/apps/web-antd/src/api/infra/demo/demo01/index.ts +++ b/apps/web-antd/src/api/infra/demo/demo01/index.ts @@ -9,7 +9,7 @@ export namespace Demo01ContactApi { export interface Demo01Contact { id: number; // 编号 name?: string; // 名字 - sex?: boolean; // 性别 + sex?: number; // 性别 birthday?: Dayjs | string; // 出生年 description?: string; // 简介 avatar: string; // 头像 @@ -46,6 +46,13 @@ export function deleteDemo01Contact(id: number) { return requestClient.delete(`/infra/demo01-contact/delete?id=${id}`); } +// 批量删除示例联系人 +export function deleteDemo01ContactByIds(ids: number[]) { + return requestClient.delete( + `/infra/demo01-contact/delete-batch?ids=${ids.join(',')}`, + ); +} + /** 导出示例联系人 */ export function exportDemo01Contact(params: any) { return requestClient.download('/infra/demo01-contact/export-excel', params); diff --git a/apps/web-antd/src/views/infra/demo/demo01/data.ts b/apps/web-antd/src/views/infra/demo/demo01/data.ts index 6406806f..ac29a04c 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/data.ts +++ b/apps/web-antd/src/views/infra/demo/demo01/data.ts @@ -103,6 +103,7 @@ export function useGridColumns( onActionClick?: OnActionClickFn, ): VxeTableGridOptions['columns'] { return [ + { type: 'checkbox', width: 40 }, { field: 'id', title: '编号', @@ -150,7 +151,6 @@ export function useGridColumns( minWidth: 200, align: 'center', fixed: 'right', - // TODO @puhui999:headerAlign 要使用 headerAlign: 'center' 么?看着现在分成了 align 和 headerAlign 两种 headerAlign: 'center', showOverflow: false, cellRender: { diff --git a/apps/web-antd/src/views/infra/demo/demo01/index.vue b/apps/web-antd/src/views/infra/demo/demo01/index.vue index ab796bd0..49df4616 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo01/index.vue @@ -5,17 +5,18 @@ import type { } from '#/adapter/vxe-table'; import type { Demo01ContactApi } from '#/api/infra/demo/demo01'; -import { h } from 'vue'; +import { computed, h, ref } from 'vue'; import { Page, useVbenModal } from '@vben/common-ui'; -import { Download, Plus } from '@vben/icons'; -import { downloadFileFromBlobPart } from '@vben/utils'; +import { Download, Plus, Trash2 } from '@vben/icons'; +import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo01Contact, + deleteDemo01ContactByIds, exportDemo01Contact, getDemo01ContactPage, } from '#/api/infra/demo/demo01'; @@ -55,7 +56,25 @@ async function onDelete(row: Demo01ContactApi.Demo01Contact) { await deleteDemo01Contact(row.id as number); message.success($t('ui.actionMessage.deleteSuccess', [row.id])); onRefresh(); - } catch { + } finally { + hideLoading(); + } +} + +const deleteIds = ref([]); // 待删除示例联系人 ID +const showDeleteBatchBtn = computed(() => isEmpty(deleteIds.value)); +/** 批量删除示例联系人 */ +async function onDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteDemo01ContactByIds(deleteIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { hideLoading(); } } @@ -113,6 +132,22 @@ const [Grid, gridApi] = useVbenVxeGrid({ search: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: ({ + records, + }: { + records: Demo01ContactApi.Demo01Contact[]; + }) => { + deleteIds.value = records.map((item) => item.id); + }, + checkboxChange: ({ + records, + }: { + records: Demo01ContactApi.Demo01Contact[]; + }) => { + deleteIds.value = records.map((item) => item.id); + }, + }, }); @@ -139,6 +174,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ > {{ $t('ui.actionTitle.export') }} + diff --git a/packages/@core/base/icons/src/lucide.ts b/packages/@core/base/icons/src/lucide.ts index a4e6f050..a6afa568 100644 --- a/packages/@core/base/icons/src/lucide.ts +++ b/packages/@core/base/icons/src/lucide.ts @@ -68,6 +68,7 @@ export { Sun, SunMoon, SwatchBook, + Trash2, Upload, UserRoundPen, X, From eeb3fc0898fd3e719a1f49113d6175f4fd31a98d Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Mon, 19 May 2025 14:21:08 +0800 Subject: [PATCH 03/31] =?UTF-8?q?feat:=20table=20action=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BC=A0=E5=85=A5=E6=8C=89=E9=92=AE=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E4=BC=A0=E9=BB=98=E8=AE=A4link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/components/table-action/table-action.vue | 4 +--- apps/web-antd/src/components/table-action/typing.ts | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/web-antd/src/components/table-action/table-action.vue b/apps/web-antd/src/components/table-action/table-action.vue index 8e373dd4..8d483f6f 100644 --- a/apps/web-antd/src/components/table-action/table-action.vue +++ b/apps/web-antd/src/components/table-action/table-action.vue @@ -1,7 +1,5 @@ @@ -152,6 +185,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ > {{ $t('ui.actionTitle.export') }} + diff --git a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue index 32da0b65..3e95bbb7 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue @@ -5,16 +5,18 @@ import type { } from '#/adapter/vxe-table'; import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp'; -import { h, nextTick, watch } from 'vue'; +import { computed, h, nextTick, ref, watch } from 'vue'; import { useVbenModal } from '@vben/common-ui'; -import { Plus } from '@vben/icons'; +import { Plus, Trash2 } from '@vben/icons'; +import { isEmpty } from '@vben/utils'; import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Course, + deleteDemo03CourseByIds, getDemo03CoursePage, } from '#/api/infra/demo/demo03/erp'; import { $t } from '#/locales'; @@ -59,7 +61,25 @@ async function onDelete(row: Demo03StudentApi.Demo03Course) { await deleteDemo03Course(row.id as number); message.success($t('ui.actionMessage.deleteSuccess', [row.id])); onRefresh(); - } catch { + } finally { + hideLoading(); + } +} + +const deleteIds = ref([]); // 待删除学生课程 ID +const showDeleteBatchBtn = computed(() => isEmpty(deleteIds.value)); +/** 批量删除学生课程 */ +async function onDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteDemo03CourseByIds(deleteIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { hideLoading(); } } @@ -115,6 +135,22 @@ const [Grid, gridApi] = useVbenVxeGrid({ isHover: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: ({ + records, + }: { + records: Demo03StudentApi.Demo03Course[]; + }) => { + deleteIds.value = records.map((item) => item.id); + }, + checkboxChange: ({ + records, + }: { + records: Demo03StudentApi.Demo03Course[]; + }) => { + deleteIds.value = records.map((item) => item.id); + }, + }, }); /** 刷新表格 */ @@ -148,6 +184,17 @@ watch( > {{ $t('ui.actionTitle.create', ['学生课程']) }} + diff --git a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue index 7b20a705..596c8927 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue @@ -5,16 +5,18 @@ import type { } from '#/adapter/vxe-table'; import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp'; -import { h, nextTick, watch } from 'vue'; +import { computed, h, nextTick, ref, watch } from 'vue'; import { useVbenModal } from '@vben/common-ui'; -import { Plus } from '@vben/icons'; +import { Plus, Trash2 } from '@vben/icons'; +import { isEmpty } from '@vben/utils'; import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Grade, + deleteDemo03GradeByIds, getDemo03GradePage, } from '#/api/infra/demo/demo03/erp'; import { $t } from '#/locales'; @@ -59,7 +61,25 @@ async function onDelete(row: Demo03StudentApi.Demo03Grade) { await deleteDemo03Grade(row.id as number); message.success($t('ui.actionMessage.deleteSuccess', [row.id])); onRefresh(); - } catch { + } finally { + hideLoading(); + } +} + +const deleteIds = ref([]); // 待删除学生班级 ID +const showDeleteBatchBtn = computed(() => isEmpty(deleteIds.value)); +/** 批量删除学生班级 */ +async function onDeleteBatch() { + const hideLoading = message.loading({ + content: $t('ui.actionMessage.deleting'), + duration: 0, + key: 'action_process_msg', + }); + try { + await deleteDemo03GradeByIds(deleteIds.value); + message.success($t('ui.actionMessage.deleteSuccess')); + onRefresh(); + } finally { hideLoading(); } } @@ -115,6 +135,18 @@ const [Grid, gridApi] = useVbenVxeGrid({ isHover: true, }, } as VxeTableGridOptions, + gridEvents: { + checkboxAll: ({ records }: { records: Demo03StudentApi.Demo03Grade[] }) => { + deleteIds.value = records.map((item) => item.id); + }, + checkboxChange: ({ + records, + }: { + records: Demo03StudentApi.Demo03Grade[]; + }) => { + deleteIds.value = records.map((item) => item.id); + }, + }, }); /** 刷新表格 */ @@ -148,6 +180,17 @@ watch( > {{ $t('ui.actionTitle.create', ['学生班级']) }} + diff --git a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/form.vue b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/form.vue index 50cfa2cf..3c83ff97 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/erp/modules/form.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/erp/modules/form.vue @@ -64,7 +64,6 @@ const [Modal, modalApi] = useVbenModal({ formData.value = undefined; return; } - // 加载数据 let data = modalApi.getData(); if (!data) { From 7174e189187ee77c14123230cbaf28b2854e591f Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Mon, 19 May 2025 16:18:48 +0800 Subject: [PATCH 05/31] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96table=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/components/table-action/index.ts | 4 ++-- apps/web-antd/src/components/table-action/table-action.vue | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/web-antd/src/components/table-action/index.ts b/apps/web-antd/src/components/table-action/index.ts index c813f1df..672c0a53 100644 --- a/apps/web-antd/src/components/table-action/index.ts +++ b/apps/web-antd/src/components/table-action/index.ts @@ -1,4 +1,4 @@ -export { default as TableAction } from './table-action.vue'; +export * from './icons'; -export const ACTION_KEY = 'action_key_msg'; +export { default as TableAction } from './table-action.vue'; export * from './typing'; diff --git a/apps/web-antd/src/components/table-action/table-action.vue b/apps/web-antd/src/components/table-action/table-action.vue index 8d483f6f..1ad69eb2 100644 --- a/apps/web-antd/src/components/table-action/table-action.vue +++ b/apps/web-antd/src/components/table-action/table-action.vue @@ -181,10 +181,10 @@ function handleMenuClick(e: any) { - @@ -228,7 +228,7 @@ function handleMenuClick(e: any) {