From 2c9032e595919f038223e8dc0a2f9610a6b1aa7a Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 6 Jun 2025 15:44:37 +0800 Subject: [PATCH 01/75] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3=E7=9A=84=20ByIds?= =?UTF-8?q?=EF=BC=8C=E8=BF=99=E7=A7=8D=E6=8C=89=E7=85=A7=E7=BA=A6=E5=AE=9A?= =?UTF-8?q?=EF=BC=8C=E6=98=AF=E4=B8=8D=E5=B8=A6=E7=9A=84=EF=BC=8C=E9=92=88?= =?UTF-8?q?=E5=AF=B9=20Id=20=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/api/infra/demo/demo01/index.ts | 3 +-- apps/web-antd/src/api/infra/demo/demo03/erp/index.ts | 6 +++--- apps/web-antd/src/api/infra/demo/demo03/inner/index.ts | 2 +- apps/web-antd/src/api/infra/demo/demo03/normal/index.ts | 2 +- apps/web-antd/src/views/infra/demo/demo01/index.vue | 4 ++-- apps/web-antd/src/views/infra/demo/demo03/erp/index.vue | 4 ++-- .../infra/demo/demo03/erp/modules/demo03-course-list.vue | 4 ++-- .../infra/demo/demo03/erp/modules/demo03-grade-list.vue | 4 ++-- apps/web-antd/src/views/infra/demo/demo03/inner/index.vue | 4 ++-- apps/web-antd/src/views/infra/demo/demo03/normal/index.vue | 4 ++-- apps/web-antd/src/views/infra/demo/general/demo01/index.vue | 4 ++-- .../src/views/infra/demo/general/demo03/erp/index.vue | 4 ++-- .../demo/general/demo03/erp/modules/demo03-course-list.vue | 4 ++-- .../demo/general/demo03/erp/modules/demo03-grade-list.vue | 4 ++-- .../src/views/infra/demo/general/demo03/inner/index.vue | 4 ++-- .../src/views/infra/demo/general/demo03/normal/index.vue | 4 ++-- 16 files changed, 30 insertions(+), 31 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 d1f646c61..c54a533f3 100644 --- a/apps/web-antd/src/api/infra/demo/demo01/index.ts +++ b/apps/web-antd/src/api/infra/demo/demo01/index.ts @@ -47,8 +47,7 @@ export function deleteDemo01Contact(id: number) { } /** 批量删除示例联系人 */ -// TODO @puhui999:ByIds,这种按照约定,是不带的,针对 Id 的情况哈。 -export function deleteDemo01ContactListByIds(ids: number[]) { +export function deleteDemo01ContactList(ids: number[]) { return requestClient.delete( `/infra/demo01-contact/delete-list?ids=${ids.join(',')}`, ); diff --git a/apps/web-antd/src/api/infra/demo/demo03/erp/index.ts b/apps/web-antd/src/api/infra/demo/demo03/erp/index.ts index ec18150cc..aac1829b7 100644 --- a/apps/web-antd/src/api/infra/demo/demo03/erp/index.ts +++ b/apps/web-antd/src/api/infra/demo/demo03/erp/index.ts @@ -62,7 +62,7 @@ export function deleteDemo03Student(id: number) { } /** 批量删除学生 */ -export function deleteDemo03StudentListByIds(ids: number[]) { +export function deleteDemo03StudentList(ids: number[]) { return requestClient.delete( `/infra/demo03-student-erp/delete-list?ids=${ids.join(',')}`, ); @@ -109,7 +109,7 @@ export function deleteDemo03Course(id: number) { } /** 批量删除学生课程 */ -export function deleteDemo03CourseListByIds(ids: number[]) { +export function deleteDemo03CourseList(ids: number[]) { return requestClient.delete( `/infra/demo03-student-erp/demo03-course/delete-list?ids=${ids.join(',')}`, ); @@ -155,7 +155,7 @@ export function deleteDemo03Grade(id: number) { } /** 批量删除学生班级 */ -export function deleteDemo03GradeListByIds(ids: number[]) { +export function deleteDemo03GradeList(ids: number[]) { return requestClient.delete( `/infra/demo03-student-erp/demo03-grade/delete-list?ids=${ids.join(',')}`, ); diff --git a/apps/web-antd/src/api/infra/demo/demo03/inner/index.ts b/apps/web-antd/src/api/infra/demo/demo03/inner/index.ts index 1521923b2..76b18fc01 100644 --- a/apps/web-antd/src/api/infra/demo/demo03/inner/index.ts +++ b/apps/web-antd/src/api/infra/demo/demo03/inner/index.ts @@ -64,7 +64,7 @@ export function deleteDemo03Student(id: number) { } /** 批量删除学生 */ -export function deleteDemo03StudentListByIds(ids: number[]) { +export function deleteDemo03StudentList(ids: number[]) { return requestClient.delete( `/infra/demo03-student-inner/delete-list?ids=${ids.join(',')}`, ); diff --git a/apps/web-antd/src/api/infra/demo/demo03/normal/index.ts b/apps/web-antd/src/api/infra/demo/demo03/normal/index.ts index 79143c82e..4d22e2e27 100644 --- a/apps/web-antd/src/api/infra/demo/demo03/normal/index.ts +++ b/apps/web-antd/src/api/infra/demo/demo03/normal/index.ts @@ -64,7 +64,7 @@ export function deleteDemo03Student(id: number) { } /** 批量删除学生 */ -export function deleteDemo03StudentListByIds(ids: number[]) { +export function deleteDemo03StudentList(ids: number[]) { return requestClient.delete( `/infra/demo03-student-normal/delete-list?ids=${ids.join(',')}`, ); 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 47841830c..3361e1682 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo01/index.vue @@ -12,7 +12,7 @@ import { message } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo01Contact, - deleteDemo01ContactListByIds, + deleteDemo01ContactList, exportDemo01Contact, getDemo01ContactPage, } from '#/api/infra/demo/demo01'; @@ -65,7 +65,7 @@ async function handleDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo01ContactListByIds(checkedIds.value); + await deleteDemo01ContactList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue b/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue index d2f5da257..ee39c7b4a 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue @@ -16,7 +16,7 @@ import { Button, message, Tabs } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/erp'; @@ -75,7 +75,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { 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 22afe3e33..86cc2b468 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 @@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Course, - deleteDemo03CourseListByIds, + deleteDemo03CourseList, getDemo03CoursePage, } from '#/api/infra/demo/demo03/erp'; import { $t } from '#/locales'; @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03CourseListByIds(deleteIds.value); + await deleteDemo03CourseList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { 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 5f774dcc2..25664ba4e 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 @@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Grade, - deleteDemo03GradeListByIds, + deleteDemo03GradeList, getDemo03GradePage, } from '#/api/infra/demo/demo03/erp'; import { $t } from '#/locales'; @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03GradeListByIds(deleteIds.value); + await deleteDemo03GradeList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue b/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue index af4289b39..24d768b26 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue @@ -16,7 +16,7 @@ import { Button, message, Tabs } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/inner'; @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue b/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue index e492af9cd..0f2fa9492 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue @@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/normal'; @@ -77,7 +77,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo01/index.vue b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue index 08ffc3bd8..3684e3b2c 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue @@ -25,7 +25,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo01Contact, - deleteDemo01ContactListByIds, + deleteDemo01ContactList, exportDemo01Contact, getDemo01ContactPage, } from '#/api/infra/demo/demo01'; @@ -122,7 +122,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo01ContactListByIds(deleteIds.value); + await deleteDemo01ContactList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue index fedc033fd..2a92757a0 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue @@ -26,7 +26,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/erp'; @@ -133,7 +133,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue index 00caaca15..1a2a8a273 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue @@ -19,7 +19,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo03Course, - deleteDemo03CourseListByIds, + deleteDemo03CourseList, getDemo03CoursePage, } from '#/api/infra/demo/demo03/erp'; import { ContentWrap } from '#/components/content-wrap'; @@ -80,7 +80,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03CourseListByIds(deleteIds.value); + await deleteDemo03CourseList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue index f25c1be21..d3bf48fc1 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue @@ -19,7 +19,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo03Grade, - deleteDemo03GradeListByIds, + deleteDemo03GradeList, getDemo03GradePage, } from '#/api/infra/demo/demo03/erp'; import { ContentWrap } from '#/components/content-wrap'; @@ -80,7 +80,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03GradeListByIds(deleteIds.value); + await deleteDemo03GradeList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue index edc1a9a4b..cd635dcef 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue @@ -26,7 +26,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/normal'; @@ -129,7 +129,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue index 1777eec6f..efa97f4d4 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue @@ -25,7 +25,7 @@ import { import { VxeColumn, VxeTable } from '#/adapter/vxe-table'; import { deleteDemo03Student, - deleteDemo03StudentListByIds, + deleteDemo03StudentList, exportDemo03Student, getDemo03StudentPage, } from '#/api/infra/demo/demo03/normal'; @@ -123,7 +123,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentListByIds(deleteIds.value); + await deleteDemo03StudentList(deleteIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { -- Gitee From 2abe2e21bc4f7dd647688cc494cfffe3604883cd Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 6 Jun 2025 16:03:13 +0800 Subject: [PATCH 02/75] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=20setCheckedIds=20->=20handleRowCheckboxChange=E3=80=81deleteI?= =?UTF-8?q?ds=20->=20checkedIds=20=E7=84=B6=E5=90=8E=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web-antd/src/views/infra/demo/demo01/index.vue | 10 ++++------ .../src/views/infra/demo/demo03/erp/index.vue | 14 +++++++------- .../demo/demo03/erp/modules/demo03-course-list.vue | 14 +++++++------- .../demo/demo03/erp/modules/demo03-grade-list.vue | 14 +++++++------- .../src/views/infra/demo/demo03/inner/index.vue | 14 +++++++------- .../src/views/infra/demo/demo03/normal/index.vue | 14 +++++++------- .../src/views/infra/demo/general/demo01/index.vue | 14 +++++++------- .../views/infra/demo/general/demo03/erp/index.vue | 14 +++++++------- .../demo03/erp/modules/demo03-course-list.vue | 14 +++++++------- .../demo03/erp/modules/demo03-grade-list.vue | 14 +++++++------- .../infra/demo/general/demo03/inner/index.vue | 14 +++++++------- .../infra/demo/general/demo03/normal/index.vue | 14 +++++++------- 12 files changed, 81 insertions(+), 83 deletions(-) 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 3361e1682..f3f988055 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo01/index.vue @@ -73,10 +73,8 @@ async function handleDeleteBatch() { } } -// TODO @puhui999:方法名,改成 handleRowCheckboxChange;注释:处理选中表格行 -// TODO @puhui999:deleteIds => checkedIds;然后注释去掉? -const checkedIds = ref([]); // 待删除示例联系人 ID -function setCheckedIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo01ContactApi.Demo01Contact[]; @@ -121,8 +119,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, gridEvents: { - checkboxAll: setCheckedIds, - checkboxChange: setCheckedIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); diff --git a/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue b/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue index ee39c7b4a..0e7955340 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/erp/index.vue @@ -75,7 +75,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { @@ -83,13 +83,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Grade[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -150,8 +150,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ cellClick: ({ row }: { row: Demo03StudentApi.Demo03Student }) => { selectDemo03Student.value = row; }, - checkboxAll: setDeleteIds, - checkboxChange: setDeleteIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); @@ -185,7 +185,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > 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 86cc2b468..c92e81003 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 @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03CourseList(deleteIds.value); + await deleteDemo03CourseList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { @@ -82,13 +82,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生课程 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Course[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 表格操作按钮的回调函数 */ @@ -143,8 +143,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, gridEvents: { - checkboxAll: setDeleteIds, - checkboxChange: setDeleteIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); @@ -184,7 +184,7 @@ watch( type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > 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 25664ba4e..a752b5991 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 @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03GradeList(deleteIds.value); + await deleteDemo03GradeList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { @@ -82,13 +82,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生班级 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Grade[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 表格操作按钮的回调函数 */ @@ -143,8 +143,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, gridEvents: { - checkboxAll: setDeleteIds, - checkboxChange: setDeleteIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); @@ -184,7 +184,7 @@ watch( type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > diff --git a/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue b/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue index 24d768b26..f003d8c9c 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/inner/index.vue @@ -74,7 +74,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { @@ -82,13 +82,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Student[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -145,8 +145,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, gridEvents: { - checkboxAll: setDeleteIds, - checkboxChange: setDeleteIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); @@ -190,7 +190,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > diff --git a/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue b/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue index 0f2fa9492..85d19daa2 100644 --- a/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo03/normal/index.vue @@ -61,13 +61,13 @@ async function onDelete(row: Demo03StudentApi.Demo03Student) { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Student[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 批量删除学生 */ async function onDeleteBatch() { @@ -77,7 +77,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); onRefresh(); } finally { @@ -139,8 +139,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, } as VxeTableGridOptions, gridEvents: { - checkboxAll: setDeleteIds, - checkboxChange: setDeleteIds, + checkboxAll: handleRowCheckboxChange, + checkboxChange: handleRowCheckboxChange, }, }); @@ -173,7 +173,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo01/index.vue b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue index 3684e3b2c..b76e8f0db 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue @@ -122,7 +122,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo01ContactList(deleteIds.value); + await deleteDemo01ContactList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -130,13 +130,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除示例联系人 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo01ContactApi.Demo01Contact[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -241,7 +241,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo01-contact:delete']" > @@ -254,8 +254,8 @@ onMounted(() => { :data="list" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue index 2a92757a0..62385532b 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/index.vue @@ -133,7 +133,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -141,13 +141,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Student[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -250,7 +250,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > @@ -269,8 +269,8 @@ onMounted(() => { }" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue index 1a2a8a273..47ed647c8 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-course-list.vue @@ -80,7 +80,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03CourseList(deleteIds.value); + await deleteDemo03CourseList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -88,13 +88,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生课程 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Course[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } const loading = ref(true); // 列表的加载中 @@ -231,7 +231,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > @@ -244,8 +244,8 @@ onMounted(() => { :data="list" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue index d3bf48fc1..0f8435c4b 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/erp/modules/demo03-grade-list.vue @@ -80,7 +80,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03GradeList(deleteIds.value); + await deleteDemo03GradeList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -88,13 +88,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生班级 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Grade[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } const loading = ref(true); // 列表的加载中 @@ -231,7 +231,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > @@ -244,8 +244,8 @@ onMounted(() => { :data="list" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue index cd635dcef..b093a83de 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/inner/index.vue @@ -129,7 +129,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -137,13 +137,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Student[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -246,7 +246,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > @@ -259,8 +259,8 @@ onMounted(() => { :data="list" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > diff --git a/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue b/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue index efa97f4d4..75db2f158 100644 --- a/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue +++ b/apps/web-antd/src/views/infra/demo/general/demo03/normal/index.vue @@ -123,7 +123,7 @@ async function onDeleteBatch() { key: 'action_process_msg', }); try { - await deleteDemo03StudentList(deleteIds.value); + await deleteDemo03StudentList(checkedIds.value); message.success($t('ui.actionMessage.deleteSuccess')); await getList(); } finally { @@ -131,13 +131,13 @@ async function onDeleteBatch() { } } -const deleteIds = ref([]); // 待删除学生 ID -function setDeleteIds({ +const checkedIds = ref([]); +function handleRowCheckboxChange({ records, }: { records: Demo03StudentApi.Demo03Student[]; }) { - deleteIds.value = records.map((item) => item.id); + checkedIds.value = records.map((item) => item.id); } /** 导出表格 */ @@ -240,7 +240,7 @@ onMounted(() => { type="primary" danger class="ml-2" - :disabled="isEmpty(deleteIds)" + :disabled="isEmpty(checkedIds)" @click="onDeleteBatch" v-access:code="['infra:demo03-student:delete']" > @@ -253,8 +253,8 @@ onMounted(() => { :data="list" show-overflow :loading="loading" - @checkbox-all="setDeleteIds" - @checkbox-change="setDeleteIds" + @checkbox-all="handleRowCheckboxChange" + @checkbox-change="handleRowCheckboxChange" > -- Gitee From ffdccfb19b80277de10f618c8137b37fa67e5134 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 6 Jun 2025 16:12:11 +0800 Subject: [PATCH 03/75] =?UTF-8?q?fix:=20TableAction=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20disabled=20=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/infra/demo/demo01/index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 f3f988055..7ac328ea8 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo01/index.vue @@ -5,7 +5,7 @@ import type { Demo01ContactApi } from '#/api/infra/demo/demo01'; import { ref } from 'vue'; import { Page, useVbenModal } from '@vben/common-ui'; -import { downloadFileFromBlobPart } from '@vben/utils'; +import {downloadFileFromBlobPart, isEmpty} from '@vben/utils'; import { message } from 'ant-design-vue'; @@ -151,6 +151,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: '批量删除', type: 'primary', danger: true, + disabled: isEmpty(checkedIds), icon: ACTION_ICON.DELETE, auth: ['infra:demo01-contact:delete'], onClick: handleDeleteBatch, -- Gitee From 95e7ffafe0bd5c238bfb973e5e782fb80b6f0ab5 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Fri, 6 Jun 2025 17:03:02 +0800 Subject: [PATCH 04/75] =?UTF-8?q?fix:=20TableAction=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20disabled=20=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/infra/demo/demo01/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7ac328ea8..48eed5386 100644 --- a/apps/web-antd/src/views/infra/demo/demo01/index.vue +++ b/apps/web-antd/src/views/infra/demo/demo01/index.vue @@ -5,7 +5,7 @@ import type { Demo01ContactApi } from '#/api/infra/demo/demo01'; import { ref } from 'vue'; import { Page, useVbenModal } from '@vben/common-ui'; -import {downloadFileFromBlobPart, isEmpty} from '@vben/utils'; +import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; import { message } from 'ant-design-vue'; -- Gitee From 5e77558efd5513b2a88823289fc960d67b2b3ff6 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Fri, 6 Jun 2025 20:44:39 +0800 Subject: [PATCH 05/75] feat: vxe add formatPast2 --- apps/web-antd/src/adapter/vxe-table.ts | 32 ++++++++++++++++++++++++++ apps/web-antd/src/utils/formatTime.ts | 32 -------------------------- apps/web-antd/src/utils/index.ts | 1 - 3 files changed, 32 insertions(+), 33 deletions(-) delete mode 100644 apps/web-antd/src/utils/formatTime.ts diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index c4dcb2a86..78b0d0d08 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -267,6 +267,38 @@ setupVbenVxeTable({ // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 // vxeUI.formats.add + + vxeUI.formats.add('formatPast2', { + tableCellFormatMethod({ cellValue }) { + if (cellValue === null || cellValue === undefined) { + return ''; + } + // 定义时间单位常量,便于维护 + const SECOND = 1000; + const MINUTE = 60 * SECOND; + const HOUR = 60 * MINUTE; + const DAY = 24 * HOUR; + + // 计算各时间单位 + const day = Math.floor(cellValue / DAY); + const hour = Math.floor((cellValue % DAY) / HOUR); + const minute = Math.floor((cellValue % HOUR) / MINUTE); + const second = Math.floor((cellValue % MINUTE) / SECOND); + + // 根据时间长短返回不同格式 + if (day > 0) { + return `${day} 天${hour} 小时 ${minute} 分钟`; + } + if (hour > 0) { + return `${hour} 小时 ${minute} 分钟`; + } + if (minute > 0) { + return `${minute} 分钟`; + } + return second > 0 ? `${second} 秒` : `${0} 秒`; + }, + }); + // add by 星语:数量格式化,例如说:金额 vxeUI.formats.add('formatNumber', { tableCellFormatMethod({ cellValue }, digits = 2) { diff --git a/apps/web-antd/src/utils/formatTime.ts b/apps/web-antd/src/utils/formatTime.ts deleted file mode 100644 index 45fe64421..000000000 --- a/apps/web-antd/src/utils/formatTime.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * 将毫秒,转换成时间字符串。例如说,xx 分钟 - * - * @param ms 毫秒 - * @returns {string} 字符串 - */ -// TODO @xingyu:这个要融合到哪里去 date 么? -export function formatPast2(ms: number): string { - // 定义时间单位常量,便于维护 - const SECOND = 1000; - const MINUTE = 60 * SECOND; - const HOUR = 60 * MINUTE; - const DAY = 24 * HOUR; - - // 计算各时间单位 - const day = Math.floor(ms / DAY); - const hour = Math.floor((ms % DAY) / HOUR); - const minute = Math.floor((ms % HOUR) / MINUTE); - const second = Math.floor((ms % MINUTE) / SECOND); - - // 根据时间长短返回不同格式 - if (day > 0) { - return `${day} 天${hour} 小时 ${minute} 分钟`; - } - if (hour > 0) { - return `${hour} 小时 ${minute} 分钟`; - } - if (minute > 0) { - return `${minute} 分钟`; - } - return second > 0 ? `${second} 秒` : `${0} 秒`; -} diff --git a/apps/web-antd/src/utils/index.ts b/apps/web-antd/src/utils/index.ts index b33984b78..eb173b636 100644 --- a/apps/web-antd/src/utils/index.ts +++ b/apps/web-antd/src/utils/index.ts @@ -2,7 +2,6 @@ export * from './constants'; export * from './dict'; export * from './download'; export * from './formatNumber'; -export * from './formatTime'; export * from './formCreate'; export * from './rangePickerProps'; export * from './routerHelper'; -- Gitee From 7e8f2a1328cd3a9e8e80b82816c79a908f8d19fe Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Fri, 6 Jun 2025 20:45:27 +0800 Subject: [PATCH 06/75] refactor: modal select --- .../select-modal/dept-select-modal.vue | 108 +++--- .../select-modal/user-select-modal.vue | 308 +++++++++--------- 2 files changed, 194 insertions(+), 222 deletions(-) diff --git a/apps/web-antd/src/components/select-modal/dept-select-modal.vue b/apps/web-antd/src/components/select-modal/dept-select-modal.vue index 8fc25665e..d3f469f58 100644 --- a/apps/web-antd/src/components/select-modal/dept-select-modal.vue +++ b/apps/web-antd/src/components/select-modal/dept-select-modal.vue @@ -9,7 +9,7 @@ import { ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; import { handleTree } from '@vben/utils'; -import { Button, Card, Col, Row, Tree } from 'ant-design-vue'; +import { Card, Col, Row, Tree } from 'ant-design-vue'; import { getSimpleDeptList } from '#/api/system/dept'; @@ -41,51 +41,64 @@ const emit = defineEmits<{ confirm: [deptList: SystemDeptApi.Dept[]]; }>(); +type checkedKeys = number[] | { checked: number[]; halfChecked: number[] }; +// 部门树形结构 +const deptTree = ref([]); +// 选中的部门 ID 列表 +const selectedDeptIds = ref([]); +// 部门数据 +const deptData = ref([]); + // 对话框配置 const [Modal, modalApi] = useVbenModal({ - title: props.title, + async onConfirm() { + // 获取选中的部门ID + const selectedIds: number[] = Array.isArray(selectedDeptIds.value) + ? selectedDeptIds.value + : selectedDeptIds.value.checked || []; + const deptArray = deptData.value.filter((dept) => + selectedIds.includes(dept.id!), + ); + emit('confirm', deptArray); + // 关闭并提示 + await modalApi.close(); + }, async onOpenChange(isOpen: boolean) { if (!isOpen) { - resetData(); + deptTree.value = []; + selectedDeptIds.value = []; + return; + } + // 加载数据 + const data = modalApi.getData(); + if (!data) { return; } - modalApi.setState({ loading: true }); + modalApi.lock(); try { deptData.value = await getSimpleDeptList(); deptTree.value = handleTree(deptData.value) as DataNode[]; + // // 设置已选择的部门 + if (data.selectedList?.length) { + const selectedIds = data.selectedList + .map((dept: SystemDeptApi.Dept) => dept.id) + .filter((id: number) => id !== undefined); + selectedDeptIds.value = props.checkStrictly + ? { + checked: selectedIds, + halfChecked: [], + } + : selectedIds; + } } finally { - modalApi.setState({ loading: false }); + modalApi.unlock(); } }, destroyOnClose: true, }); -type checkedKeys = number[] | { checked: number[]; halfChecked: number[] }; -// 部门树形结构 -const deptTree = ref([]); -// 选中的部门 ID 列表 -const selectedDeptIds = ref([]); -// 部门数据 -const deptData = ref([]); - -/** 打开对话框 */ -const open = async (selectedList?: SystemDeptApi.Dept[]) => { - modalApi.open(); - // // 设置已选择的部门 - if (selectedList?.length) { - const selectedIds = selectedList - .map((dept) => dept.id) - .filter((id): id is number => id !== undefined); - selectedDeptIds.value = props.checkStrictly - ? { - checked: selectedIds, - halfChecked: [], - } - : selectedIds; - } -}; /** 处理选中状态变化 */ -const handleCheck = () => { +function handleCheck() { if (!props.multiple) { // 单选模式下,只保留最后选择的节点 if (Array.isArray(selectedDeptIds.value)) { @@ -106,37 +119,10 @@ const handleCheck = () => { } } } -}; - -/** 提交选择 */ -const handleConfirm = async () => { - // 获取选中的部门ID - const selectedIds: number[] = Array.isArray(selectedDeptIds.value) - ? selectedDeptIds.value - : selectedDeptIds.value.checked || []; - const deptArray = deptData.value.filter((dept) => - selectedIds.includes(dept.id!), - ); - // 关闭并提示 - await modalApi.close(); - emit('confirm', deptArray); -}; - -const handleCancel = () => { - modalApi.close(); -}; - -/** 重置数据 */ -const resetData = () => { - deptTree.value = []; - selectedDeptIds.value = []; -}; - -/** 提供 open 方法,用于打开对话框 */ -defineExpose({ open }); +} diff --git a/apps/web-antd/src/components/select-modal/user-select-modal.vue b/apps/web-antd/src/components/select-modal/user-select-modal.vue index e55cca14c..23fce5aec 100644 --- a/apps/web-antd/src/components/select-modal/user-select-modal.vue +++ b/apps/web-antd/src/components/select-modal/user-select-modal.vue @@ -17,7 +17,6 @@ import { message, Pagination, Row, - Spin, Transfer, Tree, } from 'ant-design-vue'; @@ -66,16 +65,66 @@ const expandedKeys = ref([]); const selectedDeptId = ref(); const deptSearchKeys = ref(''); -// 加载状态 -const loading = ref(false); - // 用户数据管理 const userList = ref([]); // 存储所有已知用户 const selectedUserIds = ref([]); +// 弹窗配置 +const [Modal, modalApi] = useVbenModal({ + onCancel: handleCancel, + onClosed: handleClosed, + async onOpenChange(isOpen: boolean) { + if (!isOpen) { + resetData(); + return; + } + // 加载数据 + const data = modalApi.getData(); + if (!data) { + return; + } + modalApi.lock(); + try { + // 加载部门数据 + const deptData = await getSimpleDeptList(); + deptList.value = deptData; + const treeData = handleTree(deptData); + deptTree.value = treeData.map((node) => processDeptNode(node)); + expandedKeys.value = deptTree.value.map((node) => node.key); + + // 加载初始用户数据 + await loadUserData(1, leftListState.value.pagination.pageSize); + + // 设置已选用户 + if (data.userIds?.length) { + selectedUserIds.value = data.userIds.map(String); + // 加载已选用户的完整信息 TODO 目前接口暂不支持 多个用户ID 查询, 需要后端支持 + const { list } = await getUserPage({ + pageNo: 1, + pageSize: 100, // 临时使用固定值确保能加载所有已选用户 + userIds: data.userIds, + }); + // 使用 Map 来去重,以用户 ID 为 key + const userMap = new Map(userList.value.map((user) => [user.id, user])); + list.forEach((user) => { + if (!userMap.has(user.id)) { + userMap.set(user.id, user); + } + }); + userList.value = [...userMap.values()]; + updateRightListData(); + } + + modalApi.open(); + } finally { + modalApi.unlock(); + } + }, + destroyOnClose: true, +}); + // 左侧列表状态 const leftListState = ref({ - loading: false, searchValue: '', dataSource: [] as SystemUserApi.User[], pagination: { @@ -145,8 +194,7 @@ const filteredDeptTree = computed(() => { }); // 加载用户数据 -const loadUserData = async (pageNo: number, pageSize: number) => { - leftListState.value.loading = true; +async function loadUserData(pageNo: number, pageSize: number) { try { const { list, total } = await getUserPage({ pageNo, @@ -167,13 +215,11 @@ const loadUserData = async (pageNo: number, pageSize: number) => { if (newUsers.length > 0) { userList.value.push(...newUsers); } - } finally { - leftListState.value.loading = false; - } -}; + } finally {} +} // 更新右侧列表数据 -const updateRightListData = () => { +function updateRightListData() { // 使用 Set 来去重选中的用户ID const uniqueSelectedIds = new Set(selectedUserIds.value); @@ -202,22 +248,22 @@ const updateRightListData = () => { const endIndex = startIndex + pageSize; rightListState.value.dataSource = filteredUsers.slice(startIndex, endIndex); -}; +} // 处理左侧分页变化 -const handleLeftPaginationChange = async (page: number, pageSize: number) => { +async function handleLeftPaginationChange(page: number, pageSize: number) { await loadUserData(page, pageSize); -}; +} // 处理右侧分页变化 -const handleRightPaginationChange = (page: number, pageSize: number) => { +function handleRightPaginationChange(page: number, pageSize: number) { rightListState.value.pagination.current = page; rightListState.value.pagination.pageSize = pageSize; updateRightListData(); -}; +} // 处理用户搜索 -const handleUserSearch = async (direction: string, value: string) => { +async function handleUserSearch(direction: string, value: string) { if (direction === 'left') { leftListState.value.searchValue = value; leftListState.value.pagination.current = 1; @@ -227,18 +273,18 @@ const handleUserSearch = async (direction: string, value: string) => { rightListState.value.pagination.current = 1; updateRightListData(); } -}; +} // 处理用户选择变化 -const handleUserChange = (targetKeys: string[]) => { +function handleUserChange(targetKeys: string[]) { // 使用 Set 来去重选中的用户ID selectedUserIds.value = [...new Set(targetKeys)]; emit('update:value', selectedUserIds.value.map(Number)); updateRightListData(); -}; +} // 重置数据 -const resetData = () => { +function resetData() { userList.value = []; selectedUserIds.value = []; @@ -249,7 +295,6 @@ const resetData = () => { selectedUserIds.value = []; leftListState.value = { - loading: false, searchValue: '', dataSource: [], pagination: { @@ -268,61 +313,20 @@ const resetData = () => { total: 0, }, }; -}; - -// 打开弹窗 -const open = async (userIds: string[]) => { - resetData(); - loading.value = true; - try { - // 加载部门数据 - const deptData = await getSimpleDeptList(); - deptList.value = deptData; - const treeData = handleTree(deptData); - deptTree.value = treeData.map((node) => processDeptNode(node)); - expandedKeys.value = deptTree.value.map((node) => node.key); - - // 加载初始用户数据 - await loadUserData(1, leftListState.value.pagination.pageSize); - - // 设置已选用户 - if (userIds?.length) { - selectedUserIds.value = userIds.map(String); - // 加载已选用户的完整信息 TODO 目前接口暂不支持 多个用户ID 查询, 需要后端支持 - const { list } = await getUserPage({ - pageNo: 1, - pageSize: 100, // 临时使用固定值确保能加载所有已选用户 - userIds, - }); - // 使用 Map 来去重,以用户 ID 为 key - const userMap = new Map(userList.value.map((user) => [user.id, user])); - list.forEach((user) => { - if (!userMap.has(user.id)) { - userMap.set(user.id, user); - } - }); - userList.value = [...userMap.values()]; - updateRightListData(); - } - - modalApi.open(); - } finally { - loading.value = false; - } -}; +} // TODO 后端接口目前仅支持 username 检索, 筛选条件需要跟后端请求参数保持一致。 -const filterOption = (inputValue: string, option: any) => { +function filterOption(inputValue: string, option: any) { return option.username.toLowerCase().includes(inputValue.toLowerCase()); -}; +} // 处理部门树展开/折叠 -const handleExpand = (keys: Key[]) => { +function handleExpand(keys: Key[]) { expandedKeys.value = keys; -}; +} // 处理部门搜索 -const handleDeptSearch = (value: string) => { +function handleDeptSearch(value: string) { deptSearchKeys.value = value; // 如果有搜索结果,自动展开所有节点 @@ -342,10 +346,10 @@ const handleDeptSearch = (value: string) => { // 清空搜索时,只展开第一级节点 expandedKeys.value = deptTree.value.map((node) => node.key); } -}; +} // 处理部门选择 -const handleDeptSelect = async (selectedKeys: Key[], _info: any) => { +async function handleDeptSelect(selectedKeys: Key[], _info: any) { // 更新选中的部门ID const newDeptId = selectedKeys.length > 0 ? Number(selectedKeys[0]) : undefined; @@ -356,10 +360,10 @@ const handleDeptSelect = async (selectedKeys: Key[], _info: any) => { const { pageSize } = leftListState.value.pagination; leftListState.value.pagination.current = 1; await loadUserData(1, pageSize); -}; +} // 确认选择 -const handleConfirm = () => { +function handleConfirm() { if (selectedUserIds.value.length === 0) { message.warning('请选择用户'); return; @@ -371,115 +375,101 @@ const handleConfirm = () => { ), ); modalApi.close(); -}; +} // 取消选择 -const handleCancel = () => { +function handleCancel() { emit('cancel'); modalApi.close(); // 确保在动画结束后再重置数据 setTimeout(() => { resetData(); }, 300); -}; +} // 关闭弹窗 -const handleClosed = () => { +function handleClosed() { emit('closed'); resetData(); -}; - -// 弹窗配置 -const [ModalComponent, modalApi] = useVbenModal({ - title: props.title, - onCancel: handleCancel, - onClosed: handleClosed, - destroyOnClose: true, -}); +} // 递归处理部门树节点 -const processDeptNode = (node: any): DeptTreeNode => { +function processDeptNode(node: any): DeptTreeNode { return { key: String(node.id), title: `${node.name} (${node.id})`, name: node.name, children: node.children?.map((child: any) => processDeptNode(child)), }; -}; - -defineExpose({ - open, -}); +} diff --git a/apps/web-ele/src/components/table-action/typing.ts b/apps/web-ele/src/components/table-action/typing.ts new file mode 100644 index 000000000..7d41b1a23 --- /dev/null +++ b/apps/web-ele/src/components/table-action/typing.ts @@ -0,0 +1,36 @@ +import type { ButtonProps } from 'element-plus'; + +export type ButtonType = + | 'danger' + | 'default' + | 'info' + | 'primary' + | 'success' + | 'text' + | 'warning'; + +export interface PopConfirm { + title: string; + okText?: string; + cancelText?: string; + confirm: () => void; + cancel?: () => void; + icon?: string; + disabled?: boolean; +} + +export interface ActionItem extends Partial { + onClick?: () => void; + type?: ButtonType; + label?: string; + color?: 'error' | 'success' | 'warning'; + icon?: string; + popConfirm?: PopConfirm; + disabled?: boolean; + divider?: boolean; + // 权限编码控制是否显示 + auth?: string[]; + // 业务控制是否显示 + ifShow?: ((action: ActionItem) => boolean) | boolean; + tooltip?: string | { [key: string]: any; content?: string }; +} diff --git a/apps/web-ele/src/locales/langs/en-US/page.json b/apps/web-ele/src/locales/langs/en-US/page.json index e889bfc10..00a8c90b2 100644 --- a/apps/web-ele/src/locales/langs/en-US/page.json +++ b/apps/web-ele/src/locales/langs/en-US/page.json @@ -23,7 +23,8 @@ "cancel": "Cancel", "confirm": "Confirm", "reset": "Reset", - "search": "Search" + "search": "Search", + "more": "More" }, "tenant": { "placeholder": "Please select tenant", diff --git a/apps/web-ele/src/locales/langs/zh-CN/page.json b/apps/web-ele/src/locales/langs/zh-CN/page.json index a7781960b..eefc4924b 100644 --- a/apps/web-ele/src/locales/langs/zh-CN/page.json +++ b/apps/web-ele/src/locales/langs/zh-CN/page.json @@ -23,7 +23,8 @@ "cancel": "取消", "confirm": "确认", "reset": "重置", - "search": "搜索" + "search": "搜索", + "more": "更多" }, "tenant": { "placeholder": "请选择租户", diff --git a/apps/web-ele/src/views/system/user/data.ts b/apps/web-ele/src/views/system/user/data.ts index c209c8ced..b2cbd00bd 100644 --- a/apps/web-ele/src/views/system/user/data.ts +++ b/apps/web-ele/src/views/system/user/data.ts @@ -1,8 +1,7 @@ import type { VbenFormSchema } from '#/adapter/form'; -import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { SystemUserApi } from '#/api/system/user'; -import { useAccess } from '@vben/access'; import { $t } from '@vben/locales'; import { handleTree } from '@vben/utils'; @@ -17,8 +16,6 @@ import { getRangePickerDefaultProps, } from '#/utils'; -const { hasAccessByCodes } = useAccess(); - /** 新增/修改的表单 */ export function useFormSchema(): VbenFormSchema[] { return [ @@ -282,7 +279,6 @@ export function useGridFormSchema(): VbenFormSchema[] { /** 列表的字段 */ export function useGridColumns( - onActionClick: OnActionClickFn, onStatusChange?: ( newStatus: number, row: T, @@ -335,41 +331,10 @@ export function useGridColumns( formatter: 'formatDateTime', }, { - field: 'operation', title: '操作', - minWidth: 130, + width: 180, fixed: 'right', - align: 'center', - cellRender: { - attrs: { - nameField: 'username', - nameTitle: '用户', - onClick: onActionClick, - }, - name: 'CellOperation', - // TODO @芋艿:后续把 delete、assign-role、reset-password 搞成"更多" - options: [ - { - code: 'edit', - show: hasAccessByCodes(['system:user:update']), - }, - { - code: 'delete', - show: hasAccessByCodes(['system:user:delete']), - }, - { - code: 'assign-role', - text: '分配角色', - show: hasAccessByCodes(['system:permission:assign-user-role']), - 'v-access:code': 'system:user:assign-role1', - }, - { - code: 'reset-password', - text: '重置密码', - show: hasAccessByCodes(['system:user:update-password']), - }, - ], - }, + slots: { default: 'actions' }, }, ]; } diff --git a/apps/web-ele/src/views/system/user/index.vue b/apps/web-ele/src/views/system/user/index.vue index ed8b01c05..e7b293716 100644 --- a/apps/web-ele/src/views/system/user/index.vue +++ b/apps/web-ele/src/views/system/user/index.vue @@ -9,10 +9,9 @@ import type { SystemUserApi } from '#/api/system/user'; import { ref } from 'vue'; import { confirm, Page, useVbenModal } from '@vben/common-ui'; -import { Download, Plus, Upload } from '@vben/icons'; import { downloadFileFromBlobPart } from '@vben/utils'; -import { ElButton, ElLoading, ElMessage } from 'element-plus'; +import { ElLoading, ElMessage } from 'element-plus'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { @@ -22,6 +21,7 @@ import { updateUserStatus, } from '#/api/system/user'; import { DocAlert } from '#/components/doc-alert'; +import { ACTION_ICON, TableAction } from '#/components/table-action'; import { $t } from '#/locales'; import { DICT_TYPE, getDictLabel } from '#/utils'; @@ -216,32 +216,69 @@ const [Grid, gridApi] = useVbenVxeGrid({
+
-- Gitee From 9258716ba7097f294c7f9141afce053053c12424 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 11:53:06 +0800 Subject: [PATCH 17/75] feat: vxe add CellImages renderer --- apps/web-antd/src/adapter/vxe-table.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts index 78b0d0d08..cff57ed94 100644 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -74,6 +74,16 @@ setupVbenVxeTable({ }, }); + vxeUI.renderer.add('CellImages', { + renderTableDefault(_renderOpts, params) { + const { column, row } = params; + if (column && column.field && row[column.field]) { + return row[column.field].map((item: any) => h(Image, { src: item })); + } + return ''; + }, + }); + // 表格配置项可以用 cellRender: { name: 'CellLink' }, vxeUI.renderer.add('CellLink', { renderTableDefault(renderOpts) { -- Gitee From 1b3e2eef812b6f5e55c40eb2cc8b8fadbc6af4d7 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 11:53:32 +0800 Subject: [PATCH 18/75] feat: mall comment --- apps/web-antd/src/api/mall/product/comment.ts | 10 +- .../src/views/mall/product/comment/data.ts | 205 ++++++++++++++++++ .../src/views/mall/product/comment/index.vue | 173 ++++++++++++--- .../mall/product/comment/modules/form.vue | 83 +++++++ 4 files changed, 445 insertions(+), 26 deletions(-) create mode 100644 apps/web-antd/src/views/mall/product/comment/data.ts create mode 100644 apps/web-antd/src/views/mall/product/comment/modules/form.vue diff --git a/apps/web-antd/src/api/mall/product/comment.ts b/apps/web-antd/src/api/mall/product/comment.ts index 7ca1e45fa..8990c2048 100644 --- a/apps/web-antd/src/api/mall/product/comment.ts +++ b/apps/web-antd/src/api/mall/product/comment.ts @@ -3,6 +3,12 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace MallCommentApi { + export interface Property { + propertyId: number; + propertyName: string; + valueId: number; + valueName: string; + } /** 商品评论 */ export interface Comment { id: number; @@ -20,11 +26,13 @@ export namespace MallCommentApi { descriptionScores: number; benefitScores: number; content: string; - picUrls: string; + picUrls: string[]; replyStatus: boolean; replyUserId: number; replyContent: string; replyTime: Date; + createTime: Date; + skuProperties: Property[]; } /** 评论可见性更新 */ diff --git a/apps/web-antd/src/views/mall/product/comment/data.ts b/apps/web-antd/src/views/mall/product/comment/data.ts new file mode 100644 index 000000000..f422155d6 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/comment/data.ts @@ -0,0 +1,205 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeGridPropTypes } from '#/adapter/vxe-table'; +import type { MallCommentApi } from '#/api/mall/product/comment'; + +import { getSpuSimpleList } from '#/api/mall/product/spu'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'spuId', + label: '商品', + component: 'ApiSelect', + componentProps: { + api: getSpuSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'userAvatar', + label: '用户头像', + component: 'ImageUpload', + componentProps: { + maxSize: 1, + }, + rules: 'required', + }, + { + fieldName: 'userNickname', + label: '用户名称', + component: 'Input', + rules: 'required', + }, + { + fieldName: 'content', + label: '评论内容', + component: 'Textarea', + rules: 'required', + }, + { + fieldName: 'descriptionScores', + label: '描述星级', + component: 'Rate', + rules: 'required', + }, + { + fieldName: 'benefitScores', + label: '服务星级', + component: 'Rate', + rules: 'required', + }, + { + fieldName: 'picUrls', + label: '评论图片', + component: 'ImageUpload', + componentProps: { + maxSize: 9, + }, + rules: 'required', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'replyStatus', + label: '回复状态', + component: 'Select', + componentProps: { + options: [ + { label: '已回复', value: true }, + { label: '未回复', value: false }, + ], + }, + }, + { + fieldName: 'spuName', + label: '商品名称', + component: 'Input', + }, + { + fieldName: 'userNickname', + label: '用户名称', + component: 'Input', + }, + { + fieldName: 'orderId', + label: '订单编号', + component: 'Input', + }, + { + fieldName: 'createTime', + label: '评论时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 表格列配置 */ +export function useGridColumns( + onStatusChange?: ( + newStatus: boolean, + row: T, + ) => PromiseLike, +): VxeGridPropTypes.Columns { + return [ + { + field: 'id', + title: '评论编号', + fixed: 'left', + }, + { + field: 'skuPicUrl', + title: '商品图片', + cellRender: { + name: 'CellImage', + }, + }, + { + field: 'spuName', + title: '商品名称', + minWidth: 200, + }, + { + field: 'skuProperties', + title: '商品属性', + minWidth: 200, + formatter: ({ cellValue }) => { + return cellValue && cellValue.length > 0 + ? cellValue + .map((item: any) => `${item.propertyName} : ${item.valueName}`) + .join('\n') + : '-'; + }, + }, + { + field: 'userNickname', + title: '用户名称', + }, + { + field: 'descriptionScores', + title: '商品评分', + }, + { + field: 'benefitScores', + title: '服务评分', + }, + { + field: 'content', + title: '评论内容', + }, + { + field: 'picUrls', + title: '评论图片', + cellRender: { + name: 'CellImages', + }, + }, + { + field: 'replyContent', + title: '回复内容', + }, + { + field: 'createTime', + title: '评论时间', + formatter: 'formatDateTime', + }, + { + field: 'visible', + title: '是否展示', + align: 'center', + cellRender: { + attrs: { beforeChange: onStatusChange }, + name: 'CellSwitch', + props: { + checkedValue: true, + unCheckedValue: false, + }, + }, + }, + { + title: '操作', + width: 80, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mall/product/comment/index.vue b/apps/web-antd/src/views/mall/product/comment/index.vue index 1a59c945a..8511c5a00 100644 --- a/apps/web-antd/src/views/mall/product/comment/index.vue +++ b/apps/web-antd/src/views/mall/product/comment/index.vue @@ -1,34 +1,157 @@ diff --git a/apps/web-antd/src/views/mall/product/comment/modules/form.vue b/apps/web-antd/src/views/mall/product/comment/modules/form.vue new file mode 100644 index 000000000..71352fa82 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/comment/modules/form.vue @@ -0,0 +1,83 @@ + + + -- Gitee From e95c01d8cc08c31c8ee7b2f441ef7ed5cd00c9c1 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 7 Jun 2025 12:08:21 +0800 Subject: [PATCH 19/75] =?UTF-8?q?fix:=20=E3=80=90ele=E3=80=91user=20remove?= =?UTF-8?q?=20onActionClick?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-ele/src/views/system/user/index.vue | 29 ++------------------ 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/apps/web-ele/src/views/system/user/index.vue b/apps/web-ele/src/views/system/user/index.vue index e7b293716..7b0417e36 100644 --- a/apps/web-ele/src/views/system/user/index.vue +++ b/apps/web-ele/src/views/system/user/index.vue @@ -1,8 +1,5 @@ + + diff --git a/apps/web-ele/src/views/infra/demo/demo01/modules/form.vue b/apps/web-ele/src/views/infra/demo/demo01/modules/form.vue new file mode 100644 index 000000000..943b97698 --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/demo01/modules/form.vue @@ -0,0 +1,91 @@ + + + diff --git a/apps/web-ele/src/views/system/user/index.vue b/apps/web-ele/src/views/system/user/index.vue index 7b0417e36..51776e637 100644 --- a/apps/web-ele/src/views/system/user/index.vue +++ b/apps/web-ele/src/views/system/user/index.vue @@ -10,7 +10,7 @@ import { downloadFileFromBlobPart } from '@vben/utils'; import { ElLoading, ElMessage } from 'element-plus'; -import { useVbenVxeGrid } from '#/adapter/vxe-table'; +import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteUser, exportUser, @@ -18,7 +18,6 @@ import { updateUserStatus, } from '#/api/system/user'; import { DocAlert } from '#/components/doc-alert'; -import { ACTION_ICON, TableAction } from '#/components/table-action'; import { $t } from '#/locales'; import { DICT_TYPE, getDictLabel } from '#/utils'; -- Gitee From b28476d0c8c457cd8766261281aa9eea32ae651d Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 7 Jun 2025 12:28:59 +0800 Subject: [PATCH 21/75] =?UTF-8?q?feat:=20=E3=80=90ele=E3=80=91=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=A0=91=E8=A1=A8=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/infra/demo/demo02/data.ts | 120 ++++++++++++ .../src/views/infra/demo/demo02/index.vue | 176 ++++++++++++++++++ .../views/infra/demo/demo02/modules/form.vue | 92 +++++++++ 3 files changed, 388 insertions(+) create mode 100644 apps/web-ele/src/views/infra/demo/demo02/data.ts create mode 100644 apps/web-ele/src/views/infra/demo/demo02/index.vue create mode 100644 apps/web-ele/src/views/infra/demo/demo02/modules/form.vue diff --git a/apps/web-ele/src/views/infra/demo/demo02/data.ts b/apps/web-ele/src/views/infra/demo/demo02/data.ts new file mode 100644 index 000000000..74430fb28 --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/demo02/data.ts @@ -0,0 +1,120 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo02CategoryApi } from '#/api/infra/demo/demo02'; + +import { handleTree } from '@vben/utils'; + +import { getDemo02CategoryList } from '#/api/infra/demo/demo02'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'parentId', + label: '上级示例分类', + component: 'ApiTreeSelect', + componentProps: { + allowClear: true, + api: async () => { + const data = await getDemo02CategoryList({}); + data.unshift({ + id: 0, + name: '顶级示例分类', + }); + return handleTree(data); + }, + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择上级示例分类', + treeDefaultExpandAll: true, + }, + rules: 'selectRequired', + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'parentId', + label: '父级编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入父级编号', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + treeNode: true, + }, + { + field: 'parentId', + title: '父级编号', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/infra/demo/demo02/index.vue b/apps/web-ele/src/views/infra/demo/demo02/index.vue new file mode 100644 index 000000000..e92e9aeea --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/demo02/index.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-ele/src/views/infra/demo/demo02/modules/form.vue b/apps/web-ele/src/views/infra/demo/demo02/modules/form.vue new file mode 100644 index 000000000..bfabb2601 --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/demo02/modules/form.vue @@ -0,0 +1,92 @@ + + + -- Gitee From 759c6b975f331504dab3a1fbeedf3a00a235c600 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 12:35:07 +0800 Subject: [PATCH 22/75] feat: product list --- .../src/views/mall/product/spu/data.ts | 122 +++++++ .../src/views/mall/product/spu/index.vue | 328 ++++++++++++++++-- .../views/mall/product/spu/modules/detail.vue | 3 + .../views/mall/product/spu/modules/form.vue | 3 + 4 files changed, 431 insertions(+), 25 deletions(-) create mode 100644 apps/web-antd/src/views/mall/product/spu/data.ts create mode 100644 apps/web-antd/src/views/mall/product/spu/modules/detail.vue create mode 100644 apps/web-antd/src/views/mall/product/spu/modules/form.vue diff --git a/apps/web-antd/src/views/mall/product/spu/data.ts b/apps/web-antd/src/views/mall/product/spu/data.ts new file mode 100644 index 000000000..fa55151dd --- /dev/null +++ b/apps/web-antd/src/views/mall/product/spu/data.ts @@ -0,0 +1,122 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MallSpuApi } from '#/api/mall/product/spu'; + +import { getCategoryList } from '#/api/mall/product/category'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '商品名称', + component: 'Input', + }, + { + fieldName: 'categoryId', + label: '商品分类', + component: 'ApiTreeSelect', + componentProps: { + api: () => getCategoryList({}), + fieldNames: { label: 'name', value: 'id', children: 'children' }, + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onStatusChange?: ( + newStatus: number, + row: T, + ) => PromiseLike, +): VxeTableGridOptions['columns'] { + return [ + { + type: 'expand', + width: 80, + slots: { content: 'expand_content' }, + fixed: 'left', + }, + { + field: 'id', + title: '商品编号', + fixed: 'left', + }, + { + field: 'name', + title: '商品名称', + fixed: 'left', + minWidth: 200, + }, + { + field: 'picUrl', + title: '商品图片', + cellRender: { + name: 'CellImage', + }, + }, + { + field: 'price', + title: '价格', + formatter: 'formatFraction', + }, + { + field: 'marketPrice', + title: '市场价', + formatter: 'formatFraction', + }, + { + field: 'costPrice', + title: '成本价', + formatter: 'formatFraction', + }, + { + field: 'salesCount', + title: '销量', + }, + { + field: 'stock', + title: '库存', + }, + { + field: 'sort', + title: '排序', + }, + { + field: 'status', + title: '销售状态', + cellRender: { + attrs: { beforeChange: onStatusChange }, + name: 'CellSwitch', + props: { + checkedValue: 1, + checkedChildren: '上架', + unCheckedValue: 0, + unCheckedChildren: '下架', + }, + }, + }, + { + field: 'createTime', + title: '创建时间', + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 300, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mall/product/spu/index.vue b/apps/web-antd/src/views/mall/product/spu/index.vue index 761da1334..393320652 100644 --- a/apps/web-antd/src/views/mall/product/spu/index.vue +++ b/apps/web-antd/src/views/mall/product/spu/index.vue @@ -1,34 +1,312 @@ diff --git a/apps/web-antd/src/views/mall/product/spu/modules/detail.vue b/apps/web-antd/src/views/mall/product/spu/modules/detail.vue new file mode 100644 index 000000000..c28ebc684 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/spu/modules/detail.vue @@ -0,0 +1,3 @@ + + + diff --git a/apps/web-antd/src/views/mall/product/spu/modules/form.vue b/apps/web-antd/src/views/mall/product/spu/modules/form.vue new file mode 100644 index 000000000..5b6413575 --- /dev/null +++ b/apps/web-antd/src/views/mall/product/spu/modules/form.vue @@ -0,0 +1,3 @@ + + + -- Gitee From 7dced16ca664f0f712be88f3533340fe8ecfc5d2 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 7 Jun 2025 12:50:57 +0800 Subject: [PATCH 23/75] =?UTF-8?q?fix:=20=E3=80=90ele=E3=80=91=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E8=A1=A8=E5=8D=95=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-ele/src/views/infra/codegen/data.ts | 2 +- apps/web-ele/src/views/infra/codegen/edit/index.vue | 3 ++- .../src/views/infra/codegen/modules/generation-info.vue | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/web-ele/src/views/infra/codegen/data.ts b/apps/web-ele/src/views/infra/codegen/data.ts index b9b354a2a..45c0adb3c 100644 --- a/apps/web-ele/src/views/infra/codegen/data.ts +++ b/apps/web-ele/src/views/infra/codegen/data.ts @@ -350,7 +350,7 @@ export function useGenerationInfoSubTableFormSchema( }, { label: '一对一', - value: 'false', + value: false, }, ], }, diff --git a/apps/web-ele/src/views/infra/codegen/edit/index.vue b/apps/web-ele/src/views/infra/codegen/edit/index.vue index e338334cd..ec090172f 100644 --- a/apps/web-ele/src/views/infra/codegen/edit/index.vue +++ b/apps/web-ele/src/views/infra/codegen/edit/index.vue @@ -131,11 +131,12 @@ getDetail(); v-for="(step, index) in steps" :key="index" :title="step.title" + class="cursor-pointer" + @click="() => (currentStep = index)" />
- Date: Sat, 7 Jun 2025 12:53:03 +0800 Subject: [PATCH 24/75] =?UTF-8?q?fix:=20=E3=80=90antd=E3=80=91=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E8=A1=A8=E5=8D=95=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/infra/codegen/modules/generation-info.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/web-antd/src/views/infra/codegen/modules/generation-info.vue b/apps/web-antd/src/views/infra/codegen/modules/generation-info.vue index da859ef2f..3d89656f8 100644 --- a/apps/web-antd/src/views/infra/codegen/modules/generation-info.vue +++ b/apps/web-antd/src/views/infra/codegen/modules/generation-info.vue @@ -69,6 +69,8 @@ function updateTreeSchema(): void { treeFormApi.setState({ schema: useGenerationInfoTreeFormSchema(props.columns), }); + // 树表信息回显 + treeFormApi.setValues(props.table as any); } /** 更新主子表信息表单 schema */ @@ -76,6 +78,8 @@ function updateSubSchema(): void { subFormApi.setState({ schema: useGenerationInfoSubTableFormSchema(props.columns, tables.value), }); + // 主子表信息回显 + subFormApi.setValues(props.table as any); } /** 获取合并的表单值 */ -- Gitee From c7013a030ef8d782a86f1203a8aa0ead09e13beb Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 12:54:50 +0800 Subject: [PATCH 25/75] feat: treeToString --- packages/@core/base/shared/src/utils/tree.ts | 46 +++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/@core/base/shared/src/utils/tree.ts b/packages/@core/base/shared/src/utils/tree.ts index ca2a6765b..468d204f7 100644 --- a/packages/@core/base/shared/src/utils/tree.ts +++ b/packages/@core/base/shared/src/utils/tree.ts @@ -164,4 +164,48 @@ function handleTree( return tree; } -export { filterTree, handleTree, mapTree, traverseTreeValues }; +/** + * 获取节点的完整结构 + * @param tree 树数据 + * @param nodeId 节点 id + */ +function treeToString(tree: any[], nodeId: number | string) { + if (tree === undefined || !Array.isArray(tree) || tree.length === 0) { + console.warn('tree must be an array'); + return ''; + } + // 校验是否是一级节点 + const node = tree.find((item) => item.id === nodeId); + if (node !== undefined) { + return node.name; + } + let str = ''; + + function performAThoroughValidation(arr: any[]) { + if (arr === undefined || !Array.isArray(arr) || arr.length === 0) { + return false; + } + for (const item of arr) { + if (item.id === nodeId) { + str += ` / ${item.name}`; + return true; + } else if (item.children !== undefined && item.children.length > 0) { + str += ` / ${item.name}`; + if (performAThoroughValidation(item.children)) { + return true; + } + } + } + return false; + } + + for (const item of tree) { + str = `${item.name}`; + if (performAThoroughValidation(item.children)) { + break; + } + } + return str; +} + +export { filterTree, handleTree, mapTree, traverseTreeValues, treeToString }; -- Gitee From e3429f644b741c6a9b8b62a471bfbe00930a414b Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Sat, 7 Jun 2025 12:55:04 +0800 Subject: [PATCH 26/75] feat: spu expant --- .../src/views/mall/product/spu/data.ts | 17 +++--- .../src/views/mall/product/spu/index.vue | 52 ++++++++++++++++--- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/apps/web-antd/src/views/mall/product/spu/data.ts b/apps/web-antd/src/views/mall/product/spu/data.ts index fa55151dd..bd1050fee 100644 --- a/apps/web-antd/src/views/mall/product/spu/data.ts +++ b/apps/web-antd/src/views/mall/product/spu/data.ts @@ -2,6 +2,8 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MallSpuApi } from '#/api/mall/product/spu'; +import { handleTree } from '@vben/utils'; + import { getCategoryList } from '#/api/mall/product/category'; import { getRangePickerDefaultProps } from '#/utils'; @@ -18,7 +20,10 @@ export function useGridFormSchema(): VbenFormSchema[] { label: '商品分类', component: 'ApiTreeSelect', componentProps: { - api: () => getCategoryList({}), + api: async () => { + const res = await getCategoryList({}); + return handleTree(res, 'id', 'parentId', 'children'); + }, fieldNames: { label: 'name', value: 'id', children: 'children' }, }, }, @@ -71,16 +76,6 @@ export function useGridColumns( title: '价格', formatter: 'formatFraction', }, - { - field: 'marketPrice', - title: '市场价', - formatter: 'formatFraction', - }, - { - field: 'costPrice', - title: '成本价', - formatter: 'formatFraction', - }, { field: 'salesCount', title: '销量', diff --git a/apps/web-antd/src/views/mall/product/spu/index.vue b/apps/web-antd/src/views/mall/product/spu/index.vue index 393320652..1bf26e5de 100644 --- a/apps/web-antd/src/views/mall/product/spu/index.vue +++ b/apps/web-antd/src/views/mall/product/spu/index.vue @@ -6,11 +6,16 @@ import { onMounted, ref } from 'vue'; import { useRouter } from 'vue-router'; import { confirm, Page } from '@vben/common-ui'; -import { downloadFileFromBlobPart } from '@vben/utils'; +import { + downloadFileFromBlobPart, + handleTree, + treeToString, +} from '@vben/utils'; -import { message, Tabs } from 'ant-design-vue'; +import { Descriptions, message, Tabs } from 'ant-design-vue'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; +import { getCategoryList } from '#/api/mall/product/category'; import { deleteSpu, exportSpu, @@ -20,13 +25,15 @@ import { } from '#/api/mall/product/spu'; import { DocAlert } from '#/components/doc-alert'; import { $t } from '#/locales'; -import { ProductSpuStatusEnum } from '#/utils'; +import { fenToYuan, ProductSpuStatusEnum } from '#/utils'; import { useGridColumns, useGridFormSchema } from './data'; const { push } = useRouter(); const tabType = ref(0); +const categoryList = ref(); + // tabs 数据 const tabsData = ref([ { @@ -171,7 +178,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ height: 80, }, expandConfig: { - height: 150, + height: 100, }, keepSource: true, proxyConfig: { @@ -204,6 +211,9 @@ function onChangeTab(key: any) { onMounted(() => { getTabCount(); + getCategoryList({}).then((res) => { + categoryList.value = handleTree(res, 'id', 'parentId', 'children'); + }); }); @@ -247,10 +257,36 @@ onMounted(() => { /> -- Gitee From 6ad994b6214b90f13cf4d7ebded7e711b941845a Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Mon, 9 Jun 2025 21:29:31 +0800 Subject: [PATCH 71/75] feat: mall article --- .../src/views/mall/promotion/article/data.ts | 213 ++++++++++++++++++ .../views/mall/promotion/article/index.vue | 145 +++++++++--- .../mall/promotion/article/modules/form.vue | 87 +++++++ 3 files changed, 419 insertions(+), 26 deletions(-) create mode 100644 apps/web-antd/src/views/mall/promotion/article/data.ts create mode 100644 apps/web-antd/src/views/mall/promotion/article/modules/form.vue diff --git a/apps/web-antd/src/views/mall/promotion/article/data.ts b/apps/web-antd/src/views/mall/promotion/article/data.ts new file mode 100644 index 000000000..e4476977e --- /dev/null +++ b/apps/web-antd/src/views/mall/promotion/article/data.ts @@ -0,0 +1,213 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeGridPropTypes } from '#/adapter/vxe-table'; + +import { z } from '#/adapter/form'; +import { getSimpleArticleCategoryList } from '#/api/mall/promotion/articleCategory'; +import { + CommonStatusEnum, + DICT_TYPE, + getDictOptions, + getRangePickerDefaultProps, +} from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'title', + label: '文章标题', + component: 'Input', + rules: 'required', + }, + { + fieldName: 'categoryId', + label: '文章分类', + component: 'ApiSelect', + componentProps: { + api: getSimpleArticleCategoryList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'author', + label: '文章作者', + component: 'Input', + }, + { + fieldName: 'introduction', + label: '文章简介', + component: 'Input', + }, + { + fieldName: 'picUrl', + label: '文章封面', + component: 'ImageUpload', + componentProps: { + maxSize: 1, + }, + rules: 'required', + }, + { + fieldName: 'recommendHot', + label: '是否热门', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + fieldName: 'recommendBanner', + label: '是否轮播图', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + // TODO: 商品关联 + fieldName: 'spuId', + label: '商品关联', + component: 'Input', + }, + { + fieldName: 'sort', + label: '排序', + component: 'InputNumber', + componentProps: { + min: 0, + controlsPosition: 'right', + placeholder: '请输入品牌排序', + }, + rules: z.number().min(0).default(1), + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'description', + label: '文章内容', + component: 'RichTextarea', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '文章分类', + component: 'ApiSelect', + componentProps: { + api: getSimpleArticleCategoryList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'title', + label: '文章标题', + component: 'Input', + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 表格列配置 */ +export function useGridColumns(): VxeGridPropTypes.Columns { + return [ + { + field: 'id', + title: '编号', + fixed: 'left', + }, + { + field: 'title', + title: '标题', + }, + { + field: 'picUrl', + title: '封面', + cellRender: { + name: 'CellImage', + }, + }, + { + field: 'categoryId', + title: '分类', + }, + { + field: 'browseCount', + title: '浏览量', + }, + { + field: 'author', + title: '作者', + }, + { + field: 'introduction', + title: '文章简介', + }, + { + field: 'sort', + title: '排序', + }, + { + field: 'status', + title: '状态', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 180, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mall/promotion/article/index.vue b/apps/web-antd/src/views/mall/promotion/article/index.vue index de9715d80..7c035ec02 100644 --- a/apps/web-antd/src/views/mall/promotion/article/index.vue +++ b/apps/web-antd/src/views/mall/promotion/article/index.vue @@ -1,34 +1,127 @@ diff --git a/apps/web-antd/src/views/mall/promotion/article/modules/form.vue b/apps/web-antd/src/views/mall/promotion/article/modules/form.vue new file mode 100644 index 000000000..22a0e31a2 --- /dev/null +++ b/apps/web-antd/src/views/mall/promotion/article/modules/form.vue @@ -0,0 +1,87 @@ + + + -- Gitee From 3b5c939a615458fff5a14d58b6f06a68a4966b4d Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 10 Jun 2025 14:46:50 +0800 Subject: [PATCH 72/75] fix: bugs --- .../web-antd/src/views/mall/trade/delivery/pickUpOrder/data.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/data.ts b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/data.ts index 1c56a70ff..f68f275fa 100644 --- a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/data.ts +++ b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/data.ts @@ -42,7 +42,8 @@ export function useGridFormSchema(): VbenFormSchema[] { }, dependencies: { triggerFields: ['deliveryType'], - show: (values) => values.deliveryType === DeliveryTypeEnum.PICK_UP.type, + trigger: (values) => + values.deliveryType === DeliveryTypeEnum.PICK_UP.type, }, }, ]; -- Gitee From 057ea74e0e455488c3b63100e5a6a7605774ebc6 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 10 Jun 2025 16:21:40 +0800 Subject: [PATCH 73/75] feat: add doc alert common ui --- .../src/components/doc-alert/doc-alert.vue | 38 +++++++++++++++++++ .../src/components/doc-alert/index.ts | 2 + .../src/components/doc-alert/types.ts | 4 ++ .../effects/common-ui/src/components/index.ts | 1 + .../common-ui/src/components/page/page.vue | 2 +- 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 packages/effects/common-ui/src/components/doc-alert/doc-alert.vue create mode 100644 packages/effects/common-ui/src/components/doc-alert/index.ts create mode 100644 packages/effects/common-ui/src/components/doc-alert/types.ts diff --git a/packages/effects/common-ui/src/components/doc-alert/doc-alert.vue b/packages/effects/common-ui/src/components/doc-alert/doc-alert.vue new file mode 100644 index 000000000..4f2436d6e --- /dev/null +++ b/packages/effects/common-ui/src/components/doc-alert/doc-alert.vue @@ -0,0 +1,38 @@ + + diff --git a/packages/effects/common-ui/src/components/doc-alert/index.ts b/packages/effects/common-ui/src/components/doc-alert/index.ts new file mode 100644 index 000000000..9f90d3d49 --- /dev/null +++ b/packages/effects/common-ui/src/components/doc-alert/index.ts @@ -0,0 +1,2 @@ +export { default as DocAlert } from './doc-alert.vue'; +export * from './types'; diff --git a/packages/effects/common-ui/src/components/doc-alert/types.ts b/packages/effects/common-ui/src/components/doc-alert/types.ts new file mode 100644 index 000000000..8ac5dfaa7 --- /dev/null +++ b/packages/effects/common-ui/src/components/doc-alert/types.ts @@ -0,0 +1,4 @@ +export interface DocAlertProps { + title: string; + url: string; +} diff --git a/packages/effects/common-ui/src/components/index.ts b/packages/effects/common-ui/src/components/index.ts index fc50391ed..f1609b1c8 100644 --- a/packages/effects/common-ui/src/components/index.ts +++ b/packages/effects/common-ui/src/components/index.ts @@ -2,6 +2,7 @@ export * from './api-component'; export * from './captcha'; export * from './col-page'; export * from './count-to'; +export * from './doc-alert'; export * from './ellipsis-text'; export * from './icon-picker'; export * from './json-viewer'; diff --git a/packages/effects/common-ui/src/components/page/page.vue b/packages/effects/common-ui/src/components/page/page.vue index 1a6ca913b..31c944ba9 100644 --- a/packages/effects/common-ui/src/components/page/page.vue +++ b/packages/effects/common-ui/src/components/page/page.vue @@ -63,7 +63,7 @@ onMounted(() => { ref="docRef" :class=" cn( - 'bg-card border-border relative flex items-end rounded-md border-b p-4', + 'bg-card border-border relative flex items-start rounded-md border-b p-1', ) " > -- Gitee From f32eef482f8a1a7fa04e76c3ade32a58b11b88dc Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 10 Jun 2025 16:32:29 +0800 Subject: [PATCH 74/75] refactor: use vben/common-ui docAlert --- apps/web-antd/src/views/ai/chat/manager/index.vue | 8 ++++---- apps/web-antd/src/views/ai/image/manager/index.vue | 8 ++++---- .../src/views/ai/knowledge/knowledge/index.vue | 8 ++++---- .../src/views/ai/mindmap/manager/index.vue | 8 ++++---- apps/web-antd/src/views/ai/model/apiKey/index.vue | 8 ++++---- .../web-antd/src/views/ai/model/chatRole/index.vue | 8 ++++---- apps/web-antd/src/views/ai/model/model/index.vue | 8 ++++---- apps/web-antd/src/views/ai/model/tool/index.vue | 14 +++++++------- apps/web-antd/src/views/ai/music/manager/index.vue | 8 ++++---- apps/web-antd/src/views/ai/write/manager/index.vue | 8 ++++---- apps/web-antd/src/views/bpm/category/index.vue | 3 +-- apps/web-antd/src/views/bpm/form/index.vue | 3 +-- apps/web-antd/src/views/bpm/group/index.vue | 3 +-- apps/web-antd/src/views/bpm/oa/leave/index.vue | 3 +-- .../src/views/bpm/processExpression/index.vue | 3 +-- .../src/views/bpm/processInstance/index.vue | 3 +-- .../views/bpm/processInstance/manager/index.vue | 3 +-- .../src/views/bpm/processListener/index.vue | 3 +-- apps/web-antd/src/views/bpm/task/copy/index.vue | 3 +-- apps/web-antd/src/views/bpm/task/done/index.vue | 3 +-- apps/web-antd/src/views/bpm/task/manager/index.vue | 3 +-- apps/web-antd/src/views/bpm/task/todo/index.vue | 3 +-- apps/web-antd/src/views/crm/business/index.vue | 3 +-- .../src/views/crm/business/status/index.vue | 3 +-- apps/web-antd/src/views/crm/clue/index.vue | 3 +-- apps/web-antd/src/views/crm/contact/index.vue | 3 +-- apps/web-antd/src/views/crm/contract/index.vue | 3 +-- apps/web-antd/src/views/crm/customer/index.vue | 3 +-- .../src/views/crm/customer/limitConfig/index.vue | 3 +-- .../web-antd/src/views/crm/customer/pool/index.vue | 3 +-- .../src/views/crm/product/category/index.vue | 3 +-- apps/web-antd/src/views/crm/receivable/index.vue | 3 +-- .../src/views/crm/receivable/plan/index.vue | 3 +-- .../src/views/erp/finance/account/index.vue | 14 +++++++------- .../src/views/erp/finance/payment/index.vue | 14 +++++++------- .../src/views/erp/finance/receipt/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/home/index.vue | 14 +++++++------- .../src/views/erp/product/category/index.vue | 14 +++++++------- .../src/views/erp/product/product/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/product/unit/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/purchase/in/index.vue | 14 +++++++------- .../src/views/erp/purchase/order/index.vue | 14 +++++++------- .../src/views/erp/purchase/return/index.vue | 14 +++++++------- .../src/views/erp/purchase/supplier/index.vue | 14 +++++++------- .../web-antd/src/views/erp/sale/customer/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/sale/order/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/sale/out/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/sale/return/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/stock/check/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/stock/in/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/stock/move/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/stock/out/index.vue | 14 +++++++------- apps/web-antd/src/views/erp/stock/record/index.vue | 4 +--- apps/web-antd/src/views/erp/stock/stock/index.vue | 4 +--- .../src/views/erp/stock/warehouse/index.vue | 4 +--- .../src/views/infra/apiAccessLog/index.vue | 3 +-- .../web-antd/src/views/infra/apiErrorLog/index.vue | 3 +-- apps/web-antd/src/views/infra/codegen/index.vue | 3 +-- apps/web-antd/src/views/infra/druid/index.vue | 3 +-- apps/web-antd/src/views/infra/job/index.vue | 3 +-- apps/web-antd/src/views/infra/job/logger/index.vue | 3 +-- apps/web-antd/src/views/infra/redis/index.vue | 3 +-- apps/web-antd/src/views/infra/server/index.vue | 3 +-- apps/web-antd/src/views/infra/skywalking/index.vue | 3 +-- apps/web-antd/src/views/infra/swagger/index.vue | 3 +-- apps/web-antd/src/views/infra/webSocket/index.vue | 3 +-- apps/web-antd/src/views/mall/home/index.vue | 8 ++++++-- .../src/views/mall/product/category/index.vue | 3 +-- .../src/views/mall/product/comment/index.vue | 3 +-- .../src/views/mall/product/property/index.vue | 4 +--- apps/web-antd/src/views/mall/product/spu/index.vue | 3 +-- .../src/views/mall/promotion/banner/index.vue | 4 +--- .../mall/promotion/bargain/activity/index.vue | 4 +--- .../views/mall/promotion/bargain/record/index.vue | 4 +--- .../mall/promotion/combination/activity/index.vue | 4 +--- .../mall/promotion/combination/record/index.vue | 4 +--- .../src/views/mall/promotion/coupon/index.vue | 4 +--- .../views/mall/promotion/coupon/template/index.vue | 4 +--- .../mall/promotion/discountActivity/index.vue | 4 +--- .../src/views/mall/promotion/diy/page/index.vue | 4 +--- .../views/mall/promotion/diy/template/index.vue | 4 +--- .../views/mall/promotion/point/activity/index.vue | 4 +--- .../views/mall/promotion/rewardActivity/index.vue | 4 +--- .../mall/promotion/seckill/activity/index.vue | 4 +--- .../views/mall/promotion/seckill/config/index.vue | 4 +--- .../src/views/mall/statistics/member/index.vue | 4 +--- .../src/views/mall/statistics/product/index.vue | 4 +--- .../src/views/mall/statistics/trade/index.vue | 4 +--- .../src/views/mall/trade/afterSale/index.vue | 3 +-- .../views/mall/trade/brokerage/record/index.vue | 4 +--- .../src/views/mall/trade/brokerage/user/index.vue | 4 +--- .../views/mall/trade/brokerage/withdraw/index.vue | 4 +--- .../web-antd/src/views/mall/trade/config/index.vue | 3 +-- apps/web-antd/src/views/mall/trade/order/index.vue | 3 +-- apps/web-antd/src/views/member/tag/index.vue | 3 +-- apps/web-antd/src/views/member/user/index.vue | 3 +-- apps/web-antd/src/views/mp/autoReply/index.vue | 4 +--- apps/web-antd/src/views/mp/draft/index.vue | 4 +--- apps/web-antd/src/views/mp/freePublish/index.vue | 4 +--- apps/web-antd/src/views/mp/material/index.vue | 4 +--- apps/web-antd/src/views/mp/menu/index.vue | 4 +--- apps/web-antd/src/views/mp/user/index.vue | 4 +--- apps/web-antd/src/views/pay/app/index.vue | 3 +-- apps/web-antd/src/views/pay/demo/order/index.vue | 3 +-- .../web-antd/src/views/pay/demo/withdraw/index.vue | 3 +-- apps/web-antd/src/views/pay/notify/index.vue | 3 +-- apps/web-antd/src/views/pay/order/index.vue | 3 +-- apps/web-antd/src/views/pay/refund/index.vue | 3 +-- apps/web-antd/src/views/pay/transfer/index.vue | 3 +-- .../src/views/pay/wallet/balance/index.vue | 3 +-- apps/web-antd/src/views/report/goview/index.vue | 3 +-- apps/web-antd/src/views/report/jmreport/bi.vue | 3 +-- apps/web-antd/src/views/report/jmreport/index.vue | 3 +-- apps/web-antd/src/views/system/area/index.vue | 3 +-- apps/web-antd/src/views/system/dict/index.vue | 4 +--- apps/web-antd/src/views/system/loginlog/index.vue | 3 +-- .../src/views/system/mail/account/index.vue | 3 +-- apps/web-antd/src/views/system/mail/log/index.vue | 3 +-- .../src/views/system/mail/template/index.vue | 3 +-- apps/web-antd/src/views/system/menu/index.vue | 3 +-- .../src/views/system/notify/message/index.vue | 3 +-- apps/web-antd/src/views/system/notify/my/index.vue | 3 +-- .../src/views/system/notify/template/index.vue | 3 +-- .../src/views/system/oauth2/client/index.vue | 3 +-- .../src/views/system/oauth2/token/index.vue | 3 +-- .../web-antd/src/views/system/operatelog/index.vue | 3 +-- apps/web-antd/src/views/system/role/index.vue | 3 +-- .../src/views/system/sms/channel/index.vue | 3 +-- apps/web-antd/src/views/system/sms/log/index.vue | 3 +-- .../src/views/system/sms/template/index.vue | 3 +-- .../src/views/system/social/client/index.vue | 3 +-- .../src/views/system/social/user/index.vue | 3 +-- apps/web-antd/src/views/system/tenant/index.vue | 3 +-- .../src/views/system/tenantPackage/index.vue | 3 +-- apps/web-antd/src/views/system/user/index.vue | 3 +-- .../web-ele/src/views/infra/apiAccessLog/index.vue | 3 +-- apps/web-ele/src/views/infra/apiErrorLog/index.vue | 3 +-- apps/web-ele/src/views/infra/codegen/index.vue | 3 +-- apps/web-ele/src/views/infra/druid/index.vue | 3 +-- apps/web-ele/src/views/infra/job/index.vue | 3 +-- apps/web-ele/src/views/infra/job/logger/index.vue | 3 +-- apps/web-ele/src/views/infra/redis/index.vue | 3 +-- apps/web-ele/src/views/infra/server/index.vue | 3 +-- apps/web-ele/src/views/infra/skywalking/index.vue | 3 +-- apps/web-ele/src/views/infra/swagger/index.vue | 3 +-- apps/web-ele/src/views/infra/webSocket/index.vue | 3 +-- apps/web-ele/src/views/system/area/index.vue | 3 +-- apps/web-ele/src/views/system/dict/index.vue | 4 +--- apps/web-ele/src/views/system/loginlog/index.vue | 3 +-- .../src/views/system/mail/account/index.vue | 3 +-- apps/web-ele/src/views/system/mail/log/index.vue | 3 +-- .../src/views/system/mail/template/index.vue | 3 +-- apps/web-ele/src/views/system/menu/index.vue | 3 +-- .../src/views/system/notify/message/index.vue | 3 +-- apps/web-ele/src/views/system/notify/my/index.vue | 3 +-- .../src/views/system/notify/template/index.vue | 3 +-- .../src/views/system/oauth2/client/index.vue | 3 +-- .../src/views/system/oauth2/token/index.vue | 3 +-- apps/web-ele/src/views/system/operatelog/index.vue | 3 +-- apps/web-ele/src/views/system/role/index.vue | 3 +-- .../web-ele/src/views/system/sms/channel/index.vue | 3 +-- apps/web-ele/src/views/system/sms/log/index.vue | 3 +-- .../src/views/system/sms/template/index.vue | 3 +-- .../src/views/system/social/client/index.vue | 3 +-- .../web-ele/src/views/system/social/user/index.vue | 3 +-- apps/web-ele/src/views/system/tenant/index.vue | 3 +-- .../src/views/system/tenantPackage/index.vue | 3 +-- apps/web-ele/src/views/system/user/index.vue | 3 +-- .../src/views/infra/apiAccessLog/index.vue | 3 +-- .../src/views/infra/apiErrorLog/index.vue | 3 +-- apps/web-naive/src/views/infra/codegen/index.vue | 3 +-- apps/web-naive/src/views/infra/druid/index.vue | 3 +-- apps/web-naive/src/views/infra/job/index.vue | 3 +-- .../web-naive/src/views/infra/job/logger/index.vue | 3 +-- apps/web-naive/src/views/infra/redis/index.vue | 3 +-- apps/web-naive/src/views/infra/server/index.vue | 3 +-- .../web-naive/src/views/infra/skywalking/index.vue | 3 +-- apps/web-naive/src/views/infra/swagger/index.vue | 3 +-- apps/web-naive/src/views/infra/webSocket/index.vue | 3 +-- apps/web-naive/src/views/system/area/index.vue | 3 +-- apps/web-naive/src/views/system/dict/index.vue | 4 +--- apps/web-naive/src/views/system/loginlog/index.vue | 3 +-- .../src/views/system/mail/account/index.vue | 3 +-- apps/web-naive/src/views/system/mail/log/index.vue | 3 +-- .../src/views/system/mail/template/index.vue | 3 +-- apps/web-naive/src/views/system/menu/index.vue | 3 +-- .../src/views/system/notify/message/index.vue | 3 +-- .../web-naive/src/views/system/notify/my/index.vue | 3 +-- .../src/views/system/notify/template/index.vue | 3 +-- .../src/views/system/oauth2/client/index.vue | 3 +-- .../src/views/system/oauth2/token/index.vue | 3 +-- .../src/views/system/operatelog/index.vue | 3 +-- apps/web-naive/src/views/system/role/index.vue | 3 +-- .../src/views/system/sms/channel/index.vue | 3 +-- apps/web-naive/src/views/system/sms/log/index.vue | 3 +-- .../src/views/system/sms/template/index.vue | 3 +-- .../src/views/system/social/client/index.vue | 3 +-- .../src/views/system/social/user/index.vue | 3 +-- apps/web-naive/src/views/system/tenant/index.vue | 3 +-- .../src/views/system/tenantPackage/index.vue | 3 +-- apps/web-naive/src/views/system/user/index.vue | 3 +-- 201 files changed, 353 insertions(+), 553 deletions(-) diff --git a/apps/web-antd/src/views/ai/chat/manager/index.vue b/apps/web-antd/src/views/ai/chat/manager/index.vue index 9bc7fbd0c..64ca682f6 100644 --- a/apps/web-antd/src/views/ai/chat/manager/index.vue +++ b/apps/web-antd/src/views/ai/chat/manager/index.vue @@ -1,14 +1,14 @@