!112 feat: 【ANTD】新增 general 标准模式批量删除代码示例

Merge pull request !112 from puhui999/dev-new
pull/88/MERGE
芋道源码 2025-05-20 12:55:32 +00:00 committed by Gitee
commit 0e6c46ea09
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
16 changed files with 391 additions and 168 deletions

View File

@ -47,7 +47,7 @@ export function deleteDemo01Contact(id: number) {
}
/** 批量删除示例联系人 */
export function deleteDemo01ContactByIds(ids: number[]) {
export function deleteDemo01ContactListByIds(ids: number[]) {
return requestClient.delete(
`/infra/demo01-contact/delete-list?ids=${ids.join(',')}`,
);

View File

@ -62,7 +62,7 @@ export function deleteDemo03Student(id: number) {
}
/** 批量删除学生 */
export function deleteDemo03StudentByIds(ids: number[]) {
export function deleteDemo03StudentListByIds(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 deleteDemo03CourseByIds(ids: number[]) {
export function deleteDemo03CourseListByIds(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 deleteDemo03GradeByIds(ids: number[]) {
export function deleteDemo03GradeListByIds(ids: number[]) {
return requestClient.delete(
`/infra/demo03-student-erp/demo03-grade/delete-list?ids=${ids.join(',')}`,
);

View File

@ -64,7 +64,7 @@ export function deleteDemo03Student(id: number) {
}
/** 批量删除学生 */
export function deleteDemo03StudentByIds(ids: number[]) {
export function deleteDemo03StudentListByIds(ids: number[]) {
return requestClient.delete(
`/infra/demo03-student-inner/delete-list?ids=${ids.join(',')}`,
);

View File

@ -64,7 +64,7 @@ export function deleteDemo03Student(id: number) {
}
/** 批量删除学生 */
export function deleteDemo03StudentByIds(ids: number[]) {
export function deleteDemo03StudentListByIds(ids: number[]) {
return requestClient.delete(
`/infra/demo03-student-normal/delete-list?ids=${ids.join(',')}`,
);

View File

@ -1,18 +1,22 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type {
OnActionClickParams,
VxeTableGridOptions,
} from '#/adapter/vxe-table';
import type { Demo01ContactApi } from '#/api/infra/demo/demo01';
import { ref } from 'vue';
import { h, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Download, Plus, Trash2 } from '@vben/icons';
import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
import { message } from 'ant-design-vue';
import { Button, message } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo01Contact,
deleteDemo01ContactByIds,
deleteDemo01ContactListByIds,
exportDemo01Contact,
getDemo01ContactPage,
} from '#/api/infra/demo/demo01';
@ -31,35 +35,26 @@ function onRefresh() {
gridApi.query();
}
/** 导出表格 */
async function handleExport() {
const data = await exportDemo01Contact(await gridApi.formApi.getValues());
downloadFileFromBlobPart({ fileName: '示例联系人.xls', source: data });
}
/** 创建示例联系人 */
function handleCreate() {
function onCreate() {
formModalApi.setData({}).open();
}
/** 编辑示例联系人 */
function handleEdit(row: Demo01ContactApi.Demo01Contact) {
function onEdit(row: Demo01ContactApi.Demo01Contact) {
formModalApi.setData(row).open();
}
/** 删除示例联系人 */
async function handleDelete(row: Demo01ContactApi.Demo01Contact) {
async function onDelete(row: Demo01ContactApi.Demo01Contact) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
duration: 0,
key: 'action_key_msg',
key: 'action_process_msg',
});
try {
await deleteDemo01Contact(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.name]),
key: 'action_key_msg',
});
message.success($t('ui.actionMessage.deleteSuccess', [row.id]));
onRefresh();
} finally {
hideLoading();
@ -67,17 +62,15 @@ async function handleDelete(row: Demo01ContactApi.Demo01Contact) {
}
/** 批量删除示例联系人 */
async function handleDeleteBatch() {
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo01ContactByIds(deleteIds.value);
message.success({
content: $t('ui.actionMessage.deleteSuccess'),
key: 'action_key_msg',
});
await deleteDemo01ContactListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {
hideLoading();
@ -93,12 +86,35 @@ function setDeleteIds({
deleteIds.value = records.map((item) => item.id);
}
/** 导出表格 */
async function onExport() {
const data = await exportDemo01Contact(await gridApi.formApi.getValues());
downloadFileFromBlobPart({ fileName: '示例联系人.xls', source: data });
}
/** 表格操作按钮的回调函数 */
function onActionClick({
code,
row,
}: OnActionClickParams<Demo01ContactApi.Demo01Contact>) {
switch (code) {
case 'delete': {
onDelete(row);
break;
}
case 'edit': {
onEdit(row);
break;
}
}
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(onActionClick),
height: 'auto',
pagerConfig: {
enabled: true,
@ -136,56 +152,34 @@ const [Grid, gridApi] = useVbenVxeGrid({
<Grid table-title="">
<template #toolbar-tools>
<TableAction
:actions="[
{
label: $t('ui.actionTitle.create', ['示例联系人']),
type: 'primary',
icon: ACTION_ICON.ADD,
auth: ['infra:demo01-contact:create'],
onClick: handleCreate,
},
{
label: $t('ui.actionTitle.export'),
type: 'primary',
icon: ACTION_ICON.DOWNLOAD,
auth: ['infra:demo01-contact:export'],
onClick: handleExport,
},
{
label: $t('common.deleteBatch'),
type: 'primary',
icon: ACTION_ICON.DELETE,
auth: ['infra:demo01-contact:delete'],
disabled: isEmpty(deleteIds),
onClick: handleDeleteBatch,
},
]"
/>
</template>
<template #actions="{ row }">
<TableAction
:actions="[
{
label: $t('common.edit'),
type: 'link',
icon: ACTION_ICON.EDIT,
auth: ['system:post:update'],
onClick: handleEdit.bind(null, row),
},
{
label: $t('common.delete'),
type: 'link',
danger: true,
icon: ACTION_ICON.DELETE,
auth: ['system:post:delete'],
popConfirm: {
title: $t('ui.actionMessage.deleteConfirm', [row.name]),
confirm: handleDelete.bind(null, row),
},
},
]"
/>
<Button
:icon="h(Plus)"
type="primary"
@click="onCreate"
v-access:code="['infra:demo01-contact:create']"
>
{{ $t('ui.actionTitle.create', ['示例联系人']) }}
</Button>
<Button
:icon="h(Download)"
type="primary"
class="ml-2"
@click="onExport"
v-access:code="['infra:demo01-contact:export']"
>
{{ $t('ui.actionTitle.export') }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo01-contact:delete']"
>
批量删除
</Button>
</template>
</Grid>
</Page>

View File

@ -16,7 +16,7 @@ import { Button, message, Tabs } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentByIds,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/erp';
@ -75,7 +75,7 @@ async function onDeleteBatch() {
key: 'action_process_msg',
});
try {
await deleteDemo03StudentByIds(deleteIds.value);
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {

View File

@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Course,
deleteDemo03CourseByIds,
deleteDemo03CourseListByIds,
getDemo03CoursePage,
} from '#/api/infra/demo/demo03/erp';
import { $t } from '#/locales';
@ -74,7 +74,7 @@ async function onDeleteBatch() {
key: 'action_process_msg',
});
try {
await deleteDemo03CourseByIds(deleteIds.value);
await deleteDemo03CourseListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {

View File

@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Grade,
deleteDemo03GradeByIds,
deleteDemo03GradeListByIds,
getDemo03GradePage,
} from '#/api/infra/demo/demo03/erp';
import { $t } from '#/locales';
@ -74,7 +74,7 @@ async function onDeleteBatch() {
key: 'action_process_msg',
});
try {
await deleteDemo03GradeByIds(deleteIds.value);
await deleteDemo03GradeListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {

View File

@ -16,7 +16,7 @@ import { Button, message, Tabs } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentByIds,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/inner';
@ -74,7 +74,7 @@ async function onDeleteBatch() {
key: 'action_process_msg',
});
try {
await deleteDemo03StudentByIds(deleteIds.value);
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {

View File

@ -16,7 +16,7 @@ import { Button, message } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentByIds,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/normal';
@ -77,7 +77,7 @@ async function onDeleteBatch() {
key: 'action_process_msg',
});
try {
await deleteDemo03StudentByIds(deleteIds.value);
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
onRefresh();
} finally {

View File

@ -4,11 +4,12 @@ import type { Demo01ContactApi } from '#/api/infra/demo/demo01';
import { h, onMounted, reactive, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Download, Plus } from '@vben/icons';
import { Download, Plus, Trash2 } from '@vben/icons';
import {
cloneDeep,
downloadFileFromBlobPart,
formatDateTime,
isEmpty,
} from '@vben/utils';
import {
@ -24,6 +25,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo01Contact,
deleteDemo01ContactListByIds,
exportDemo01Contact,
getDemo01ContactPage,
} from '#/api/infra/demo/demo01';
@ -38,6 +40,7 @@ import Demo01ContactForm from './modules/form.vue';
const loading = ref(true); //
const list = ref<Demo01ContactApi.Demo01Contact[]>([]); //
const total = ref(0); //
const queryParams = reactive({
pageNo: 1,
@ -96,13 +99,14 @@ function onEdit(row: Demo01ContactApi.Demo01Contact) {
async function onDelete(row: Demo01ContactApi.Demo01Contact) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo01Contact(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
await getList();
} finally {
@ -110,6 +114,31 @@ async function onDelete(row: Demo01ContactApi.Demo01Contact) {
}
}
/** 批量删除示例联系人 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo01ContactListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo01ContactApi.Demo01Contact[];
}) {
deleteIds.value = records.map((item) => item.id);
}
/** 导出表格 */
async function onExport() {
try {
@ -207,9 +236,28 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.export') }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo01-contact:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable ref="tableRef" :data="list" show-overflow :loading="loading">
<VxeTable
ref="tableRef"
:data="list"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<VxeColumn field="id" title="编号" align="center" />
<VxeColumn field="name" title="名字" align="center" />
<VxeColumn field="sex" title="性别" align="center">
@ -242,6 +290,7 @@ onMounted(() => {
<Button
size="small"
type="link"
danger
class="ml-2"
@click="onDelete(row as any)"
v-access:code="['infra:demo01-contact:delete']"

View File

@ -4,16 +4,16 @@ import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
import { h, onMounted, reactive, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Download, Plus } from '@vben/icons';
import { Download, Plus, Trash2 } from '@vben/icons';
import {
cloneDeep,
downloadFileFromBlobPart,
formatDateTime,
isEmpty,
} from '@vben/utils';
import {
Button,
DatePicker,
Form,
Input,
message,
@ -26,6 +26,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/erp';
@ -56,7 +57,6 @@ const queryParams = reactive({
pageSize: 10,
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined,
createTime: undefined,
});
@ -68,9 +68,6 @@ const getList = async () => {
loading.value = true;
try {
const params = cloneDeep(queryParams) as any;
if (params.birthday && Array.isArray(params.birthday)) {
params.birthday = (params.birthday as string[]).join(',');
}
if (params.createTime && Array.isArray(params.createTime)) {
params.createTime = (params.createTime as string[]).join(',');
}
@ -113,13 +110,14 @@ function onEdit(row: Demo03StudentApi.Demo03Student) {
async function onDelete(row: Demo03StudentApi.Demo03Student) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03Student(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
await getList();
} finally {
@ -127,6 +125,31 @@ async function onDelete(row: Demo03StudentApi.Demo03Student) {
}
}
/** 批量删除学生 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo03StudentApi.Demo03Student[];
}) {
deleteIds.value = records.map((item) => item.id);
}
/** 导出表格 */
async function onExport() {
try {
@ -180,15 +203,6 @@ onMounted(() => {
</Select.Option>
</Select>
</Form.Item>
<Form.Item label="出生日期" name="birthday">
<DatePicker
v-model:value="queryParams.birthday"
value-format="YYYY-MM-DD"
placeholder="选择出生日期"
allow-clear
class="w-full"
/>
</Form.Item>
<Form.Item label="创建时间" name="createTime">
<RangePicker
v-model:value="queryParams.createTime"
@ -231,6 +245,17 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.export') }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo03-student:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable
@ -244,7 +269,10 @@ onMounted(() => {
}"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<VxeColumn field="id" title="编号" align="center" />
<VxeColumn field="name" title="名字" align="center" />
<VxeColumn field="sex" title="性别" align="center">

View File

@ -4,8 +4,8 @@ import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
import { h, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons';
import { cloneDeep, formatDateTime } from '@vben/utils';
import { Plus, Trash2 } from '@vben/icons';
import { cloneDeep, formatDateTime, isEmpty } from '@vben/utils';
import {
Button,
@ -19,6 +19,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo03Course,
deleteDemo03CourseListByIds,
getDemo03CoursePage,
} from '#/api/infra/demo/demo03/erp';
import { ContentWrap } from '#/components/content-wrap';
@ -56,20 +57,46 @@ function onEdit(row: Demo03StudentApi.Demo03Course) {
async function onDelete(row: Demo03StudentApi.Demo03Course) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03Course(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
getList();
await getList();
} finally {
hideLoading();
}
}
/** 批量删除学生课程 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03CourseListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo03StudentApi.Demo03Course[];
}) {
deleteIds.value = records.map((item) => item.id);
}
const loading = ref(true); //
const list = ref<Demo03StudentApi.Demo03Course[]>([]); //
const total = ref(0); //
@ -102,9 +129,6 @@ const getList = async () => {
return [];
}
const params = cloneDeep(queryParams) as any;
if (params.birthday && Array.isArray(params.birthday)) {
params.birthday = (params.birthday as string[]).join(',');
}
if (params.createTime && Array.isArray(params.createTime)) {
params.createTime = (params.createTime as string[]).join(',');
}
@ -202,9 +226,28 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.create', ['学生']) }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo03-student:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable ref="tableRef" :data="list" show-overflow :loading="loading">
<VxeTable
ref="tableRef"
:data="list"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<VxeColumn field="id" title="编号" align="center" />
<VxeColumn field="studentId" title="学生编号" align="center" />
<VxeColumn field="name" title="名字" align="center" />

View File

@ -4,8 +4,8 @@ import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
import { h, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Plus } from '@vben/icons';
import { cloneDeep, formatDateTime } from '@vben/utils';
import { Plus, Trash2 } from '@vben/icons';
import { cloneDeep, formatDateTime, isEmpty } from '@vben/utils';
import {
Button,
@ -19,6 +19,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo03Grade,
deleteDemo03GradeListByIds,
getDemo03GradePage,
} from '#/api/infra/demo/demo03/erp';
import { ContentWrap } from '#/components/content-wrap';
@ -56,20 +57,46 @@ function onEdit(row: Demo03StudentApi.Demo03Grade) {
async function onDelete(row: Demo03StudentApi.Demo03Grade) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03Grade(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
getList();
await getList();
} finally {
hideLoading();
}
}
/** 批量删除学生班级 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03GradeListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo03StudentApi.Demo03Grade[];
}) {
deleteIds.value = records.map((item) => item.id);
}
const loading = ref(true); //
const list = ref<Demo03StudentApi.Demo03Grade[]>([]); //
const total = ref(0); //
@ -102,9 +129,6 @@ const getList = async () => {
return [];
}
const params = cloneDeep(queryParams) as any;
if (params.birthday && Array.isArray(params.birthday)) {
params.birthday = (params.birthday as string[]).join(',');
}
if (params.createTime && Array.isArray(params.createTime)) {
params.createTime = (params.createTime as string[]).join(',');
}
@ -202,9 +226,28 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.create', ['学生']) }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo03-student:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable ref="tableRef" :data="list" show-overflow :loading="loading">
<VxeTable
ref="tableRef"
:data="list"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<VxeColumn field="id" title="编号" align="center" />
<VxeColumn field="studentId" title="学生编号" align="center" />
<VxeColumn field="name" title="名字" align="center" />

View File

@ -4,16 +4,16 @@ import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
import { h, onMounted, reactive, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Download, Plus } from '@vben/icons';
import { Download, Plus, Trash2 } from '@vben/icons';
import {
cloneDeep,
downloadFileFromBlobPart,
formatDateTime,
isEmpty,
} from '@vben/utils';
import {
Button,
DatePicker,
Form,
Input,
message,
@ -26,6 +26,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/normal';
@ -52,7 +53,6 @@ const queryParams = reactive({
pageSize: 10,
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined,
createTime: undefined,
});
@ -64,9 +64,6 @@ const getList = async () => {
loading.value = true;
try {
const params = cloneDeep(queryParams) as any;
if (params.birthday && Array.isArray(params.birthday)) {
params.birthday = (params.birthday as string[]).join(',');
}
if (params.createTime && Array.isArray(params.createTime)) {
params.createTime = (params.createTime as string[]).join(',');
}
@ -109,13 +106,14 @@ function onEdit(row: Demo03StudentApi.Demo03Student) {
async function onDelete(row: Demo03StudentApi.Demo03Student) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03Student(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
await getList();
} finally {
@ -123,6 +121,31 @@ async function onDelete(row: Demo03StudentApi.Demo03Student) {
}
}
/** 批量删除学生 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo03StudentApi.Demo03Student[];
}) {
deleteIds.value = records.map((item) => item.id);
}
/** 导出表格 */
async function onExport() {
try {
@ -176,15 +199,6 @@ onMounted(() => {
</Select.Option>
</Select>
</Form.Item>
<Form.Item label="出生日期" name="birthday">
<DatePicker
v-model:value="queryParams.birthday"
value-format="YYYY-MM-DD"
placeholder="选择出生日期"
allow-clear
class="w-full"
/>
</Form.Item>
<Form.Item label="创建时间" name="createTime">
<RangePicker
v-model:value="queryParams.createTime"
@ -227,9 +241,28 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.export') }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo03-student:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable ref="tableRef" :data="list" show-overflow :loading="loading">
<VxeTable
ref="tableRef"
:data="list"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<!-- 子表的列表 -->
<VxeColumn type="expand" width="60">
<template #content="{ row }">

View File

@ -4,16 +4,16 @@ import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
import { h, onMounted, reactive, ref } from 'vue';
import { Page, useVbenModal } from '@vben/common-ui';
import { Download, Plus } from '@vben/icons';
import { Download, Plus, Trash2 } from '@vben/icons';
import {
cloneDeep,
downloadFileFromBlobPart,
formatDateTime,
isEmpty,
} from '@vben/utils';
import {
Button,
DatePicker,
Form,
Input,
message,
@ -25,6 +25,7 @@ import {
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import {
deleteDemo03Student,
deleteDemo03StudentListByIds,
exportDemo03Student,
getDemo03StudentPage,
} from '#/api/infra/demo/demo03/normal';
@ -46,7 +47,6 @@ const queryParams = reactive({
pageSize: 10,
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined,
createTime: undefined,
});
@ -58,9 +58,6 @@ const getList = async () => {
loading.value = true;
try {
const params = cloneDeep(queryParams) as any;
if (params.birthday && Array.isArray(params.birthday)) {
params.birthday = (params.birthday as string[]).join(',');
}
if (params.createTime && Array.isArray(params.createTime)) {
params.createTime = (params.createTime as string[]).join(',');
}
@ -103,13 +100,14 @@ function onEdit(row: Demo03StudentApi.Demo03Student) {
async function onDelete(row: Demo03StudentApi.Demo03Student) {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting', [row.id]),
key: 'action_key_msg',
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03Student(row.id as number);
message.success({
content: $t('ui.actionMessage.deleteSuccess', [row.id]),
key: 'action_key_msg',
key: 'action_process_msg',
});
await getList();
} finally {
@ -117,6 +115,31 @@ async function onDelete(row: Demo03StudentApi.Demo03Student) {
}
}
/** 批量删除学生 */
async function onDeleteBatch() {
const hideLoading = message.loading({
content: $t('ui.actionMessage.deleting'),
duration: 0,
key: 'action_process_msg',
});
try {
await deleteDemo03StudentListByIds(deleteIds.value);
message.success($t('ui.actionMessage.deleteSuccess'));
await getList();
} finally {
hideLoading();
}
}
const deleteIds = ref<number[]>([]); // ID
function setDeleteIds({
records,
}: {
records: Demo03StudentApi.Demo03Student[];
}) {
deleteIds.value = records.map((item) => item.id);
}
/** 导出表格 */
async function onExport() {
try {
@ -170,15 +193,6 @@ onMounted(() => {
</Select.Option>
</Select>
</Form.Item>
<Form.Item label="出生日期" name="birthday">
<DatePicker
v-model:value="queryParams.birthday"
value-format="YYYY-MM-DD"
placeholder="选择出生日期"
allow-clear
class="w-full"
/>
</Form.Item>
<Form.Item label="创建时间" name="createTime">
<RangePicker
v-model:value="queryParams.createTime"
@ -221,9 +235,28 @@ onMounted(() => {
>
{{ $t('ui.actionTitle.export') }}
</Button>
<Button
:icon="h(Trash2)"
type="primary"
danger
class="ml-2"
:disabled="isEmpty(deleteIds)"
@click="onDeleteBatch"
v-access:code="['infra:demo03-student:delete']"
>
批量删除
</Button>
</TableToolbar>
</template>
<VxeTable ref="tableRef" :data="list" show-overflow :loading="loading">
<VxeTable
ref="tableRef"
:data="list"
show-overflow
:loading="loading"
@checkbox-all="setDeleteIds"
@checkbox-change="setDeleteIds"
>
<VxeColumn type="checkbox" width="40" />
<VxeColumn field="id" title="编号" align="center" />
<VxeColumn field="name" title="名字" align="center" />
<VxeColumn field="sex" title="性别" align="center">