feat: table-toolbar
parent
b3a65f2492
commit
29e5017913
|
@ -1,79 +0,0 @@
|
|||
/* 来自 @vben/plugins/vxe-table style.css,覆盖 vxe-table 原有的样式定义,使用 vben 的样式主题 */
|
||||
:root {
|
||||
--vxe-ui-font-color: hsl(var(--foreground));
|
||||
--vxe-ui-font-primary-color: hsl(var(--primary));
|
||||
|
||||
/* --vxe-ui-font-lighten-color: #babdc0;
|
||||
--vxe-ui-font-darken-color: #86898e; */
|
||||
--vxe-ui-font-disabled-color: hsl(var(--foreground) / 50%);
|
||||
|
||||
/* base */
|
||||
--vxe-ui-base-popup-border-color: hsl(var(--border));
|
||||
--vxe-ui-input-disabled-color: hsl(var(--border) / 60%);
|
||||
|
||||
/* --vxe-ui-base-popup-box-shadow: 0px 12px 30px 8px rgb(0 0 0 / 50%); */
|
||||
|
||||
/* layout */
|
||||
--vxe-ui-layout-background-color: hsl(var(--background));
|
||||
--vxe-ui-table-resizable-line-color: hsl(var(--heavy));
|
||||
|
||||
/* --vxe-ui-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px hsl(var(--accent));
|
||||
--vxe-ui-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px hsl(var(--accent)); */
|
||||
|
||||
/* input */
|
||||
--vxe-ui-input-border-color: hsl(var(--border));
|
||||
|
||||
/* --vxe-ui-input-placeholder-color: #8d9095; */
|
||||
|
||||
/* --vxe-ui-input-disabled-background-color: #262727; */
|
||||
|
||||
/* loading */
|
||||
--vxe-ui-loading-background-color: hsl(var(--overlay-content));
|
||||
|
||||
/* table */
|
||||
--vxe-ui-table-header-background-color: hsl(var(--accent));
|
||||
--vxe-ui-table-border-color: hsl(var(--border));
|
||||
--vxe-ui-table-row-hover-background-color: hsl(var(--accent-hover));
|
||||
--vxe-ui-table-row-striped-background-color: hsl(var(--accent) / 60%);
|
||||
--vxe-ui-table-row-hover-striped-background-color: hsl(var(--accent));
|
||||
--vxe-ui-table-row-radio-checked-background-color: hsl(var(--accent));
|
||||
--vxe-ui-table-row-hover-radio-checked-background-color: hsl(
|
||||
var(--accent-hover)
|
||||
);
|
||||
--vxe-ui-table-row-checkbox-checked-background-color: hsl(var(--accent));
|
||||
--vxe-ui-table-row-hover-checkbox-checked-background-color: hsl(
|
||||
var(--accent-hover)
|
||||
);
|
||||
--vxe-ui-table-row-current-background-color: hsl(var(--accent));
|
||||
--vxe-ui-table-row-hover-current-background-color: hsl(var(--accent-hover));
|
||||
--vxe-ui-font-primary-tinge-color: hsl(var(--primary));
|
||||
--vxe-ui-font-primary-lighten-color: hsl(var(--primary) / 60%);
|
||||
--vxe-ui-font-primary-darken-color: hsl(var(--primary));
|
||||
|
||||
/* height: auto !important; */
|
||||
|
||||
/* --vxe-ui-table-fixed-scrolling-box-shadow-color: rgb(0 0 0 / 80%); */
|
||||
}
|
||||
|
||||
.vxe-tools--operate {
|
||||
margin-right: 0.25rem;
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
.vxe-table-custom--checkbox-option:hover {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.vxe-toolbar {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.vxe-buttons--wrapper:not(:empty),
|
||||
.vxe-tools--operate:not(:empty),
|
||||
.vxe-tools--wrapper:not(:empty) {
|
||||
padding: 0.6em 0;
|
||||
}
|
||||
|
||||
.vxe-tools--operate:not(:has(button)) {
|
||||
margin-left: 0;
|
||||
}
|
|
@ -6,7 +6,8 @@ import { h } from 'vue';
|
|||
import { IconifyIcon } from '@vben/icons';
|
||||
import { $te } from '@vben/locales';
|
||||
import {
|
||||
AsyncComponents,
|
||||
AsyncVxeColumn,
|
||||
AsyncVxeTable,
|
||||
createRequiredValidation,
|
||||
setupVbenVxeTable,
|
||||
useVbenVxeGrid,
|
||||
|
@ -34,8 +35,6 @@ import { $t } from '#/locales';
|
|||
|
||||
import { useVbenForm } from './form';
|
||||
|
||||
import '#/adapter/style.css';
|
||||
|
||||
setupVbenVxeTable({
|
||||
configVxeTable: (vxeUI) => {
|
||||
vxeUI.setConfig({
|
||||
|
@ -357,16 +356,8 @@ setupVbenVxeTable({
|
|||
|
||||
export { createRequiredValidation, useVbenVxeGrid };
|
||||
|
||||
const [VxeTable, VxeColumn, VxeToolbar] = AsyncComponents;
|
||||
export { VxeColumn, VxeTable, VxeToolbar };
|
||||
export const [VxeTable, VxeColumn] = [AsyncVxeTable, AsyncVxeColumn];
|
||||
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/adapter/vxe-table.ts#L264-L270
|
||||
export type OnActionClickParams<T = Recordable<any>> = {
|
||||
code: string;
|
||||
row: T;
|
||||
};
|
||||
export type OnActionClickFn<T = Recordable<any>> = (
|
||||
params: OnActionClickParams<T>,
|
||||
) => void;
|
||||
export * from '#/components/table-action';
|
||||
|
||||
export type * from '@vben/plugins/vxe-table';
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export { default as TableToolbar } from './table-toolbar.vue';
|
|
@ -1,81 +0,0 @@
|
|||
<!-- add by puhui999:vxe table 工具栏二次封装,提供给 vxe 原生列表使用 -->
|
||||
<script setup lang="ts">
|
||||
import type { VxeToolbarInstance } from '#/adapter/vxe-table';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useContentMaximize, useRefresh } from '@vben/hooks';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Button, Tooltip } from 'ant-design-vue';
|
||||
|
||||
import { VxeToolbar } from '#/adapter/vxe-table';
|
||||
|
||||
/** 列表工具栏封装 */
|
||||
defineOptions({ name: 'TableToolbar' });
|
||||
|
||||
const props = defineProps<{
|
||||
hiddenSearch: boolean;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:hiddenSearch']);
|
||||
|
||||
const toolbarRef = ref<VxeToolbarInstance>();
|
||||
const { toggleMaximizeAndTabbarHidden, contentIsMaximize } =
|
||||
useContentMaximize();
|
||||
const { refresh } = useRefresh();
|
||||
|
||||
/** 隐藏搜索栏 */
|
||||
function onHiddenSearchBar() {
|
||||
emits('update:hiddenSearch', !props.hiddenSearch);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getToolbarRef: () => toolbarRef.value,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VxeToolbar ref="toolbarRef" custom>
|
||||
<template #toolPrefix>
|
||||
<slot></slot>
|
||||
<Tooltip placement="bottom">
|
||||
<template #title>
|
||||
<div class="max-w-52">搜索</div>
|
||||
</template>
|
||||
<Button
|
||||
class="ml-2 font-normal"
|
||||
shape="circle"
|
||||
@click="onHiddenSearchBar"
|
||||
>
|
||||
<IconifyIcon icon="lucide:search" :size="15" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="bottom">
|
||||
<template #title>
|
||||
<div class="max-w-52">刷新</div>
|
||||
</template>
|
||||
<Button class="ml-2 font-medium" shape="circle" @click="refresh">
|
||||
<IconifyIcon icon="lucide:refresh-cw" :size="15" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="bottom">
|
||||
<template #title>
|
||||
<div class="max-w-52">
|
||||
{{ contentIsMaximize ? '还原' : '全屏' }}
|
||||
</div>
|
||||
</template>
|
||||
<Button
|
||||
class="ml-2 font-medium"
|
||||
shape="circle"
|
||||
@click="toggleMaximizeAndTabbarHidden"
|
||||
>
|
||||
<IconifyIcon
|
||||
:icon="contentIsMaximize ? 'lucide:minimize' : 'lucide:maximize'"
|
||||
:size="15"
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</VxeToolbar>
|
||||
</template>
|
|
@ -1 +0,0 @@
|
|||
export * from './use-table-toolbar';
|
|
@ -1,15 +1,12 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
|
||||
|
||||
import { useAccess } from '@vben/access';
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
const { hasAccessByCodes } = useAccess();
|
||||
|
||||
/** 新增/修改的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
|
@ -105,9 +102,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useGridColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Student>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
export function useGridColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
return [
|
||||
{ type: 'checkbox', width: 40 },
|
||||
{
|
||||
|
@ -147,30 +142,10 @@ export function useGridColumns(
|
|||
formatter: 'formatDateTime',
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
title: '操作',
|
||||
minWidth: 200,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'edit',
|
||||
show: hasAccessByCodes(['infra:demo03-student:update']),
|
||||
},
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -252,9 +227,7 @@ export function useDemo03CourseGridFormSchema(): VbenFormSchema[] {
|
|||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useDemo03CourseGridColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Course>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
export function useDemo03CourseGridColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
return [
|
||||
{ type: 'checkbox', width: 40 },
|
||||
{
|
||||
|
@ -284,31 +257,10 @@ export function useDemo03CourseGridColumns(
|
|||
formatter: 'formatDateTime',
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
title: '操作',
|
||||
minWidth: 200,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生课程',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'edit',
|
||||
show: hasAccessByCodes(['infra:demo03-student:update']),
|
||||
},
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -390,9 +342,7 @@ export function useDemo03GradeGridFormSchema(): VbenFormSchema[] {
|
|||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useDemo03GradeGridColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Grade>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Grade>['columns'] {
|
||||
export function useDemo03GradeGridColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Grade>['columns'] {
|
||||
return [
|
||||
{ type: 'checkbox', width: 40 },
|
||||
{
|
||||
|
@ -422,31 +372,10 @@ export function useDemo03GradeGridColumns(
|
|||
formatter: 'formatDateTime',
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
title: '操作',
|
||||
minWidth: 200,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生班级',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'edit',
|
||||
show: hasAccessByCodes(['infra:demo03-student:update']),
|
||||
},
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
|
||||
|
||||
import { h, ref } from 'vue';
|
||||
|
@ -13,7 +10,7 @@ import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
|
|||
|
||||
import { Button, message, Tabs } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
deleteDemo03Student,
|
||||
deleteDemo03StudentList,
|
||||
|
@ -99,29 +96,12 @@ async function onExport() {
|
|||
downloadFileFromBlobPart({ fileName: '学生.xls', source: data });
|
||||
}
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Student>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useGridFormSchema(),
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useGridColumns(onActionClick),
|
||||
columns: useGridColumns(),
|
||||
height: '600px',
|
||||
pagerConfig: {
|
||||
enabled: true,
|
||||
|
@ -193,6 +173,30 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
批量删除
|
||||
</Button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.edit'),
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['infra:demo03-student:update'],
|
||||
onClick: onEdit.bind(null, row),
|
||||
},
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
|
||||
<!-- 子表的表单 -->
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
|
||||
|
||||
import { h, nextTick, ref, watch } from 'vue';
|
||||
|
@ -13,7 +10,7 @@ import { isEmpty } from '@vben/utils';
|
|||
|
||||
import { Button, message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
deleteDemo03Course,
|
||||
deleteDemo03CourseList,
|
||||
|
@ -92,29 +89,12 @@ function handleRowCheckboxChange({
|
|||
checkedIds.value = records.map((item) => item.id!);
|
||||
}
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Course>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useDemo03CourseGridFormSchema(),
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useDemo03CourseGridColumns(onActionClick),
|
||||
columns: useDemo03CourseGridColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
|
@ -192,5 +172,29 @@ watch(
|
|||
批量删除
|
||||
</Button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.edit'),
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['infra:demo03-student:update'],
|
||||
onClick: onEdit.bind(null, row),
|
||||
},
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</template>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp';
|
||||
|
||||
import { h, nextTick, ref, watch } from 'vue';
|
||||
|
@ -13,7 +10,7 @@ import { isEmpty } from '@vben/utils';
|
|||
|
||||
import { Button, message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
deleteDemo03Grade,
|
||||
deleteDemo03GradeList,
|
||||
|
@ -92,29 +89,12 @@ function handleRowCheckboxChange({
|
|||
checkedIds.value = records.map((item) => item.id!);
|
||||
}
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Grade>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useDemo03GradeGridFormSchema(),
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useDemo03GradeGridColumns(onActionClick),
|
||||
columns: useDemo03GradeGridColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
|
@ -192,5 +172,29 @@ watch(
|
|||
批量删除
|
||||
</Button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.edit'),
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['infra:demo03-student:update'],
|
||||
onClick: onEdit.bind(null, row),
|
||||
},
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</template>
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/inner';
|
||||
|
||||
import { useAccess } from '@vben/access';
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
const { hasAccessByCodes } = useAccess();
|
||||
|
||||
/** 新增/修改的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
|
@ -105,9 +102,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useGridColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Student>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
export function useGridColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
return [
|
||||
{ type: 'checkbox', width: 40 },
|
||||
{ type: 'expand', width: 80, slots: { content: 'expand_content' } },
|
||||
|
@ -148,30 +143,11 @@ export function useGridColumns(
|
|||
formatter: 'formatDateTime',
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
field: 'actions',
|
||||
title: '操作',
|
||||
minWidth: 200,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'edit',
|
||||
show: hasAccessByCodes(['infra:demo03-student:update']),
|
||||
},
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -179,9 +155,7 @@ export function useGridColumns(
|
|||
// ==================== 子表(学生课程) ====================
|
||||
|
||||
/** 新增/修改列表的字段 */
|
||||
export function useDemo03CourseGridEditColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Course>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
export function useDemo03CourseGridEditColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'name',
|
||||
|
@ -196,26 +170,11 @@ export function useDemo03CourseGridEditColumns(
|
|||
slots: { default: 'score' },
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
field: 'actions',
|
||||
title: '操作',
|
||||
minWidth: 60,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/inner';
|
||||
|
||||
import { h, ref } from 'vue';
|
||||
|
@ -13,7 +10,7 @@ import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
|
|||
|
||||
import { Button, message, Tabs } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
deleteDemo03Student,
|
||||
deleteDemo03StudentList,
|
||||
|
@ -98,29 +95,12 @@ async function onExport() {
|
|||
downloadFileFromBlobPart({ fileName: '学生.xls', source: data });
|
||||
}
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Student>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useGridFormSchema(),
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useGridColumns(onActionClick),
|
||||
columns: useGridColumns(),
|
||||
height: 'auto',
|
||||
pagerConfig: {
|
||||
enabled: true,
|
||||
|
@ -198,6 +178,30 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
批量删除
|
||||
</Button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.edit'),
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['infra:demo03-student:update'],
|
||||
onClick: onEdit.bind(null, row),
|
||||
},
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
import type { OnActionClickParams } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/inner';
|
||||
|
||||
import { h, nextTick, watch } from 'vue';
|
||||
|
@ -8,7 +7,7 @@ import { Plus } from '@vben/icons';
|
|||
|
||||
import { Button, Input } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getDemo03CourseListByStudentId } from '#/api/infra/demo/demo03/inner';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
|
@ -18,22 +17,9 @@ const props = defineProps<{
|
|||
studentId?: number; // 学生编号(主表的关联字段)
|
||||
}>();
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Course>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
gridOptions: {
|
||||
columns: useDemo03CourseGridEditColumns(onActionClick),
|
||||
columns: useDemo03CourseGridEditColumns(),
|
||||
border: true,
|
||||
showOverflow: true,
|
||||
autoResize: true,
|
||||
|
@ -68,9 +54,12 @@ defineExpose({
|
|||
gridApi.grid.getRemoveRecords() as Demo03StudentApi.Demo03Course[];
|
||||
const insertRecords =
|
||||
gridApi.grid.getInsertRecords() as Demo03StudentApi.Demo03Course[];
|
||||
return data
|
||||
.filter((row) => !removeRecords.some((removed) => removed.id === row.id))
|
||||
.concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
|
||||
return [
|
||||
...data.filter(
|
||||
(row) => !removeRecords.some((removed) => removed.id === row.id),
|
||||
),
|
||||
...insertRecords.map((row: any) => ({ ...row, id: undefined })),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -98,6 +87,23 @@ watch(
|
|||
<template #score="{ row }">
|
||||
<Input v-model:value="row.score" />
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
<div class="-mt-4 flex justify-center">
|
||||
<Button
|
||||
|
|
|
@ -31,11 +31,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
});
|
||||
|
||||
/** 刷新表格 */
|
||||
const onRefresh = async () => {
|
||||
async function onRefresh() {
|
||||
await gridApi.grid.loadData(
|
||||
await getDemo03CourseListByStudentId(props.studentId!),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
|
|
@ -31,11 +31,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
});
|
||||
|
||||
/** 刷新表格 */
|
||||
const onRefresh = async () => {
|
||||
async function onRefresh() {
|
||||
await gridApi.grid.loadData([
|
||||
await getDemo03GradeByStudentId(props.studentId!),
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
|
|
@ -61,8 +61,8 @@ const [Modal, modalApi] = useVbenModal({
|
|||
// 提交表单
|
||||
const data = (await formApi.getValues()) as Demo03StudentApi.Demo03Student;
|
||||
// 拼接子表的数据
|
||||
data.demo03Courses = demo03CourseFormRef.value?.getData();
|
||||
data.demo03Grade = await demo03GradeFormRef.value?.getValues();
|
||||
data.demo03courses = demo03CourseFormRef.value?.getData();
|
||||
data.demo03grade = await demo03GradeFormRef.value?.getValues();
|
||||
try {
|
||||
await (formData.value?.id
|
||||
? updateDemo03Student(data)
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
|
||||
|
||||
import { useAccess } from '@vben/access';
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
const { hasAccessByCodes } = useAccess();
|
||||
|
||||
/** 新增/修改的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
|
@ -105,9 +102,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
}
|
||||
|
||||
/** 列表的字段 */
|
||||
export function useGridColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Student>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
export function useGridColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Student>['columns'] {
|
||||
return [
|
||||
{ type: 'checkbox', width: 40 },
|
||||
{
|
||||
|
@ -141,30 +136,11 @@ export function useGridColumns(
|
|||
formatter: 'formatDateTime',
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
field: 'actions',
|
||||
title: '操作',
|
||||
minWidth: 200,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'edit',
|
||||
show: hasAccessByCodes(['infra:demo03-student:update']),
|
||||
},
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -172,9 +148,7 @@ export function useGridColumns(
|
|||
// ==================== 子表(学生课程) ====================
|
||||
|
||||
/** 新增/修改列表的字段 */
|
||||
export function useDemo03CourseGridEditColumns(
|
||||
onActionClick?: OnActionClickFn<Demo03StudentApi.Demo03Course>,
|
||||
): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
export function useDemo03CourseGridEditColumns(): VxeTableGridOptions<Demo03StudentApi.Demo03Course>['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'name',
|
||||
|
@ -187,26 +161,11 @@ export function useDemo03CourseGridEditColumns(
|
|||
slots: { default: 'score' },
|
||||
},
|
||||
{
|
||||
field: 'operation',
|
||||
field: 'actions',
|
||||
title: '操作',
|
||||
minWidth: 60,
|
||||
align: 'center',
|
||||
width: 280,
|
||||
fixed: 'right',
|
||||
showOverflow: false,
|
||||
cellRender: {
|
||||
attrs: {
|
||||
nameField: 'id',
|
||||
nameTitle: '学生',
|
||||
onClick: onActionClick,
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'delete',
|
||||
show: hasAccessByCodes(['infra:demo03-student:delete']),
|
||||
},
|
||||
],
|
||||
},
|
||||
slots: { default: 'actions' },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
|
||||
|
||||
import { h, ref } from 'vue';
|
||||
|
@ -13,7 +10,7 @@ import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
|
|||
|
||||
import { Button, message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
deleteDemo03Student,
|
||||
deleteDemo03StudentList,
|
||||
|
@ -92,29 +89,12 @@ async function onExport() {
|
|||
downloadFileFromBlobPart({ fileName: '学生.xls', source: data });
|
||||
}
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Student>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useGridFormSchema(),
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useGridColumns(onActionClick),
|
||||
columns: useGridColumns(),
|
||||
height: 'auto',
|
||||
pagerConfig: {
|
||||
enabled: true,
|
||||
|
@ -181,6 +161,30 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
批量删除
|
||||
</Button>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.edit'),
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['infra:demo03-student:update'],
|
||||
onClick: onEdit.bind(null, row),
|
||||
},
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts" setup>
|
||||
import type { OnActionClickParams } from '#/adapter/vxe-table';
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
|
||||
|
||||
import { h, nextTick, watch } from 'vue';
|
||||
|
@ -8,7 +7,7 @@ import { Plus } from '@vben/icons';
|
|||
|
||||
import { Button, Input } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getDemo03CourseListByStudentId } from '#/api/infra/demo/demo03/normal';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
|
@ -18,22 +17,9 @@ const props = defineProps<{
|
|||
studentId?: number; // 学生编号(主表的关联字段)
|
||||
}>();
|
||||
|
||||
/** 表格操作按钮的回调函数 */
|
||||
function onActionClick({
|
||||
code,
|
||||
row,
|
||||
}: OnActionClickParams<Demo03StudentApi.Demo03Course>) {
|
||||
switch (code) {
|
||||
case 'delete': {
|
||||
onDelete(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
gridOptions: {
|
||||
columns: useDemo03CourseGridEditColumns(onActionClick),
|
||||
columns: useDemo03CourseGridEditColumns(),
|
||||
border: true,
|
||||
showOverflow: true,
|
||||
autoResize: true,
|
||||
|
@ -68,9 +54,12 @@ defineExpose({
|
|||
gridApi.grid.getRemoveRecords() as Demo03StudentApi.Demo03Course[];
|
||||
const insertRecords =
|
||||
gridApi.grid.getInsertRecords() as Demo03StudentApi.Demo03Course[];
|
||||
return data
|
||||
.filter((row) => !removeRecords.some((removed) => removed.id === row.id))
|
||||
.concat(insertRecords.map((row: any) => ({ ...row, id: undefined })));
|
||||
return [
|
||||
...data.filter(
|
||||
(row) => !removeRecords.some((removed) => removed.id === row.id),
|
||||
),
|
||||
...insertRecords.map((row: any) => ({ ...row, id: undefined })),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -98,6 +87,23 @@ watch(
|
|||
<template #score="{ row }">
|
||||
<Input v-model:value="row.score" />
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: $t('common.delete'),
|
||||
danger: true,
|
||||
type: 'link',
|
||||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['infra:demo03-student:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.id]),
|
||||
confirm: onDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
<div class="-mt-4 flex justify-center">
|
||||
<Button
|
||||
|
|
|
@ -61,8 +61,8 @@ const [Modal, modalApi] = useVbenModal({
|
|||
// 提交表单
|
||||
const data = (await formApi.getValues()) as Demo03StudentApi.Demo03Student;
|
||||
// 拼接子表的数据
|
||||
data.demo03Courses = demo03CourseFormRef.value?.getData();
|
||||
data.demo03Grade = await demo03GradeFormRef.value?.getValues();
|
||||
data.demo03courses = demo03CourseFormRef.value?.getData();
|
||||
data.demo03grade = await demo03GradeFormRef.value?.getValues();
|
||||
try {
|
||||
await (formData.value?.id
|
||||
? updateDemo03Student(data)
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
|||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
import { Download, Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
cloneDeep,
|
||||
downloadFileFromBlobPart,
|
||||
|
@ -33,8 +34,6 @@ import {
|
|||
} from '#/api/infra/demo/demo01';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -55,7 +54,7 @@ const queryFormRef = ref(); // 搜索的表单
|
|||
const exportLoading = ref(false); // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = cloneDeep(queryParams) as any;
|
||||
|
@ -68,19 +67,19 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Demo01ContactForm,
|
||||
|
@ -214,7 +213,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="示例联系人">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -248,7 +247,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -283,7 +282,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="handleEdit(row as any)"
|
||||
@click="handleEdit(row)"
|
||||
v-access:code="['infra:demo01-contact:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -293,7 +292,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="handleDelete(row as any)"
|
||||
@click="handleDelete(row)"
|
||||
v-access:code="['infra:demo01-contact:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -51,7 +51,7 @@ const getTitle = computed(() => {
|
|||
});
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
|
@ -61,7 +61,7 @@ const resetForm = () => {
|
|||
avatar: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
|
|
|
@ -5,6 +5,7 @@ import { h, onMounted, reactive, ref } from 'vue';
|
|||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { Download, Plus } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
cloneDeep,
|
||||
downloadFileFromBlobPart,
|
||||
|
@ -21,8 +22,6 @@ import {
|
|||
getDemo02CategoryList,
|
||||
} from '#/api/infra/demo/demo02';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -40,7 +39,7 @@ const queryFormRef = ref(); // 搜索的表单
|
|||
const exportLoading = ref(false); // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = cloneDeep(queryParams) as any;
|
||||
|
@ -51,18 +50,18 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Demo02CategoryForm,
|
||||
|
@ -171,7 +170,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="示例分类">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -197,7 +196,7 @@ onMounted(() => {
|
|||
>
|
||||
{{ $t('ui.actionTitle.export') }}
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -225,7 +224,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onAppend(row as any)"
|
||||
@click="onAppend(row)"
|
||||
v-access:code="['infra:demo02-category:create']"
|
||||
>
|
||||
新增下级
|
||||
|
@ -233,7 +232,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo02-category:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -243,8 +242,8 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
:disabled="!isEmpty(row?.children)"
|
||||
@click="onDelete(row as any)"
|
||||
:disabled="!isEmpty(row.children)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo02-category:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -38,17 +38,17 @@ const getTitle = computed(() => {
|
|||
});
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
parentId: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
|
||||
/** 获得示例分类树 */
|
||||
const getDemo02CategoryTree = async () => {
|
||||
async function getDemo02CategoryTree() {
|
||||
demo02CategoryTree.value = [];
|
||||
const data = await getDemo02CategoryList({});
|
||||
data.unshift({
|
||||
|
@ -56,7 +56,7 @@ const getDemo02CategoryTree = async () => {
|
|||
name: '顶级示例分类',
|
||||
});
|
||||
demo02CategoryTree.value = handleTree(data);
|
||||
};
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
|||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
import { Download, Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
cloneDeep,
|
||||
downloadFileFromBlobPart,
|
||||
|
@ -34,8 +35,6 @@ import {
|
|||
} from '#/api/infra/demo/demo03/erp';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -66,7 +65,7 @@ const queryFormRef = ref(); // 搜索的表单
|
|||
const exportLoading = ref(false); // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = cloneDeep(queryParams) as any;
|
||||
|
@ -79,7 +78,7 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
|
@ -88,10 +87,10 @@ const handleQuery = () => {
|
|||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Demo03StudentForm,
|
||||
|
@ -225,7 +224,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="学生">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -259,7 +258,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -299,7 +298,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo03-student:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -309,7 +308,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -80,7 +80,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
});
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
studentId: undefined,
|
||||
|
@ -88,7 +88,7 @@ const resetForm = () => {
|
|||
score: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { h, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
|||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import { cloneDeep, formatDateTime, isEmpty } from '@vben/utils';
|
||||
|
||||
import {
|
||||
|
@ -23,8 +24,6 @@ import {
|
|||
getDemo03CoursePage,
|
||||
} from '#/api/infra/demo/demo03/erp';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -112,18 +111,18 @@ const queryParams = reactive({
|
|||
});
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (!props.studentId) {
|
||||
|
@ -140,7 +139,7 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
@ -214,7 +213,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="学生">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -238,7 +237,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -263,7 +262,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo03-student:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -273,7 +272,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -80,7 +80,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
});
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
studentId: undefined,
|
||||
|
@ -88,7 +88,7 @@ const resetForm = () => {
|
|||
teacher: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { h, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
|||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import { cloneDeep, formatDateTime, isEmpty } from '@vben/utils';
|
||||
|
||||
import {
|
||||
|
@ -23,8 +24,6 @@ import {
|
|||
getDemo03GradePage,
|
||||
} from '#/api/infra/demo/demo03/erp';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -112,18 +111,18 @@ const queryParams = reactive({
|
|||
});
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (!props.studentId) {
|
||||
|
@ -140,7 +139,7 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
@ -214,7 +213,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="学生">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -238,7 +237,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -263,7 +262,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo03-student:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -273,7 +272,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -49,7 +49,7 @@ const getTitle = computed(() => {
|
|||
});
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
|
@ -58,7 +58,7 @@ const resetForm = () => {
|
|||
description: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
|||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
import { Download, Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
cloneDeep,
|
||||
downloadFileFromBlobPart,
|
||||
|
@ -34,8 +35,6 @@ import {
|
|||
} from '#/api/infra/demo/demo03/normal';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -62,7 +61,7 @@ const queryFormRef = ref(); // 搜索的表单
|
|||
const exportLoading = ref(false); // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = cloneDeep(queryParams) as any;
|
||||
|
@ -75,19 +74,19 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Demo03StudentForm,
|
||||
|
@ -221,7 +220,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="学生">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -255,7 +254,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -303,7 +302,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo03-student:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -313,7 +312,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import type { VxeTableInstance } from '#/adapter/vxe-table';
|
||||
import type { VxeTableInstance } from '@vben/plugins/vxe-table';
|
||||
|
||||
import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal';
|
||||
|
||||
import { h, ref, watch } from 'vue';
|
||||
|
@ -19,14 +20,14 @@ const props = defineProps<{
|
|||
const list = ref<Demo03StudentApi.Demo03Course[]>([]); // 列表的数据
|
||||
const tableRef = ref<VxeTableInstance>();
|
||||
/** 添加学生课程 */
|
||||
const onAdd = async () => {
|
||||
async function onAdd() {
|
||||
await tableRef.value?.insertAt({} as Demo03StudentApi.Demo03Course, -1);
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除学生课程 */
|
||||
const onDelete = async (row: Demo03StudentApi.Demo03Course) => {
|
||||
async function onDelete(row: Demo03StudentApi.Demo03Course) {
|
||||
await tableRef.value?.remove(row);
|
||||
};
|
||||
}
|
||||
|
||||
/** 提供获取表格数据的方法供父组件调用 */
|
||||
defineExpose({
|
||||
|
@ -73,7 +74,7 @@ watch(
|
|||
size="small"
|
||||
type="link"
|
||||
danger
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -16,7 +16,7 @@ const props = defineProps<{
|
|||
const loading = ref(true); // 列表的加载中
|
||||
const list = ref<Demo03StudentApi.Demo03Course[]>([]); // 列表的数据
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (!props.studentId) {
|
||||
|
@ -26,7 +26,7 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
|
|
@ -15,7 +15,7 @@ const props = defineProps<{
|
|||
const loading = ref(true); // 列表的加载中
|
||||
const list = ref<Demo03StudentApi.Demo03Grade[]>([]); // 列表的数据
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (!props.studentId) {
|
||||
|
@ -25,7 +25,7 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
|
|
|
@ -58,7 +58,7 @@ const demo03CourseFormRef = ref<InstanceType<typeof Demo03CourseForm>>();
|
|||
const demo03GradeFormRef = ref<InstanceType<typeof Demo03GradeForm>>();
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
function resetForm() {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
|
@ -67,7 +67,7 @@ const resetForm = () => {
|
|||
description: undefined,
|
||||
};
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
|||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictOptions } from '@vben/hooks';
|
||||
import { Download, Plus, Trash2 } from '@vben/icons';
|
||||
import { useTableToolbar, VbenVxeTableToolbar } from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
cloneDeep,
|
||||
downloadFileFromBlobPart,
|
||||
|
@ -33,8 +34,6 @@ import {
|
|||
} from '#/api/infra/demo/demo03/normal';
|
||||
import { ContentWrap } from '#/components/content-wrap';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { TableToolbar } from '#/components/table-toolbar';
|
||||
import { useTableToolbar } from '#/hooks';
|
||||
import { $t } from '#/locales';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
|
@ -56,7 +55,7 @@ const queryFormRef = ref(); // 搜索的表单
|
|||
const exportLoading = ref(false); // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = cloneDeep(queryParams) as any;
|
||||
|
@ -69,19 +68,19 @@ const getList = async () => {
|
|||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
}
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: Demo03StudentForm,
|
||||
|
@ -215,7 +214,7 @@ onMounted(() => {
|
|||
<!-- 列表 -->
|
||||
<ContentWrap title="学生">
|
||||
<template #extra>
|
||||
<TableToolbar
|
||||
<VbenVxeTableToolbar
|
||||
ref="tableToolbarRef"
|
||||
v-model:hidden-search="hiddenSearchBar"
|
||||
>
|
||||
|
@ -249,7 +248,7 @@ onMounted(() => {
|
|||
>
|
||||
批量删除
|
||||
</Button>
|
||||
</TableToolbar>
|
||||
</VbenVxeTableToolbar>
|
||||
</template>
|
||||
<VxeTable
|
||||
ref="tableRef"
|
||||
|
@ -283,7 +282,7 @@ onMounted(() => {
|
|||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="onEdit(row as any)"
|
||||
@click="onEdit(row)"
|
||||
v-access:code="['infra:demo03-student:update']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
|
@ -293,7 +292,7 @@ onMounted(() => {
|
|||
type="link"
|
||||
danger
|
||||
class="ml-2"
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -19,14 +19,14 @@ const props = defineProps<{
|
|||
const list = ref<Demo03StudentApi.Demo03Course[]>([]); // 列表的数据
|
||||
const tableRef = ref<VxeTableInstance>();
|
||||
/** 添加学生课程 */
|
||||
const onAdd = async () => {
|
||||
async function onAdd() {
|
||||
await tableRef.value?.insertAt({} as Demo03StudentApi.Demo03Course, -1);
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除学生课程 */
|
||||
const onDelete = async (row: Demo03StudentApi.Demo03Course) => {
|
||||
async function onDelete(row: Demo03StudentApi.Demo03Course) {
|
||||
await tableRef.value?.remove(row);
|
||||
};
|
||||
}
|
||||
|
||||
/** 提供获取表格数据的方法供父组件调用 */
|
||||
defineExpose({
|
||||
|
@ -73,7 +73,7 @@ watch(
|
|||
size="small"
|
||||
type="link"
|
||||
danger
|
||||
@click="onDelete(row as any)"
|
||||
@click="onDelete(row)"
|
||||
v-access:code="['infra:demo03-student:delete']"
|
||||
>
|
||||
{{ $t('ui.actionTitle.delete') }}
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
export { AsyncComponents, setupVbenVxeTable } from './init';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
|
||||
export { setupVbenVxeTable } from './init';
|
||||
export { default as VbenVxeTableToolbar } from './table-toolbar.vue';
|
||||
export type { VxeTableGridOptions } from './types';
|
||||
export * from './use-vxe-grid';
|
||||
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
|
||||
|
||||
export { useTableToolbar } from './use-vxe-toolbar';
|
||||
export * from './validation';
|
||||
|
||||
export type {
|
||||
VxeGridListeners,
|
||||
VxeGridProps,
|
||||
VxeGridPropTypes,
|
||||
VxeTableInstance,
|
||||
VxeToolbarInstance,
|
||||
} from 'vxe-table';
|
||||
|
||||
// 异步导出 vxe-table 相关组件提供给需要单独使用 vxe-table 的场景
|
||||
export const AsyncVxeTable = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeTable),
|
||||
);
|
||||
export const AsyncVxeColumn = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeColumn),
|
||||
);
|
||||
export const AsyncVxeToolbar = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeToolbar),
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type { SetupVxeTable } from './types';
|
||||
|
||||
import { defineAsyncComponent, defineComponent, watch } from 'vue';
|
||||
import { defineComponent, watch } from 'vue';
|
||||
|
||||
import { usePreferences } from '@vben/preferences';
|
||||
|
||||
|
@ -100,18 +100,6 @@ export function initVxeTable() {
|
|||
isInit = true;
|
||||
}
|
||||
|
||||
// 异步导出 vxe-table 相关组件提供给需要单独使用 vxe-table 的场景
|
||||
const AsyncVxeTable = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeTable),
|
||||
);
|
||||
const AsyncVxeColumn = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeColumn),
|
||||
);
|
||||
const AsyncVxeToolbar = defineAsyncComponent(() =>
|
||||
import('vxe-table').then((mod) => mod.VxeToolbar),
|
||||
);
|
||||
export const AsyncComponents = [AsyncVxeTable, AsyncVxeColumn, AsyncVxeToolbar];
|
||||
|
||||
export function setupVbenVxeTable(setupOptions: SetupVxeTable) {
|
||||
const { configVxeTable, useVbenForm } = setupOptions;
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<!-- add by puhui999:vxe table 工具栏二次封装,提供给 vxe 原生列表使用 -->
|
||||
<script setup lang="ts">
|
||||
import type { VxeToolbarInstance } from 'vxe-table';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useContentMaximize, useRefresh } from '@vben/hooks';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { VxeButton, VxeTooltip } from 'vxe-pc-ui';
|
||||
import { VxeToolbar } from 'vxe-table';
|
||||
|
||||
/** 列表工具栏封装 */
|
||||
defineOptions({ name: 'TableToolbar' });
|
||||
|
||||
const props = defineProps<{
|
||||
hiddenSearch: boolean;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['update:hiddenSearch']);
|
||||
|
||||
const toolbarRef = ref<VxeToolbarInstance>();
|
||||
const { toggleMaximizeAndTabbarHidden, contentIsMaximize } =
|
||||
useContentMaximize();
|
||||
const { refresh } = useRefresh();
|
||||
|
||||
/** 隐藏搜索栏 */
|
||||
function onHiddenSearchBar() {
|
||||
emits('update:hiddenSearch', !props.hiddenSearch);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getToolbarRef: () => toolbarRef.value,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VxeToolbar ref="toolbarRef" custom>
|
||||
<template #toolPrefix>
|
||||
<slot></slot>
|
||||
<VxeTooltip placement="bottom" content="搜索">
|
||||
<template #default>
|
||||
<VxeButton class="ml-2 font-normal" circle @click="onHiddenSearchBar">
|
||||
<IconifyIcon icon="lucide:search" :size="15" />
|
||||
</VxeButton>
|
||||
</template>
|
||||
</VxeTooltip>
|
||||
<VxeTooltip
|
||||
placement="bottom"
|
||||
:content="contentIsMaximize ? '还原' : '全屏'"
|
||||
>
|
||||
<template #default>
|
||||
<VxeButton class="ml-2 font-medium" circle @click="refresh">
|
||||
<IconifyIcon icon="lucide:refresh-cw" :size="15" />
|
||||
</VxeButton>
|
||||
</template>
|
||||
</VxeTooltip>
|
||||
<VxeTooltip placement="bottom" content="全屏">
|
||||
<template #default>
|
||||
<VxeButton
|
||||
class="ml-2 font-medium"
|
||||
circle
|
||||
@click="toggleMaximizeAndTabbarHidden"
|
||||
>
|
||||
<IconifyIcon
|
||||
:icon="contentIsMaximize ? 'lucide:minimize' : 'lucide:maximize'"
|
||||
:size="15"
|
||||
/>
|
||||
</VxeButton>
|
||||
</template>
|
||||
</VxeTooltip>
|
||||
</template>
|
||||
</VxeToolbar>
|
||||
</template>
|
|
@ -1,15 +1,16 @@
|
|||
import type { VxeTableInstance, VxeToolbarInstance } from '#/adapter/vxe-table';
|
||||
import type { TableToolbar } from '#/components/table-toolbar';
|
||||
import type { VxeTableInstance, VxeToolbarInstance } from 'vxe-table';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import VbenVxeTableToolbar from './table-toolbar.vue';
|
||||
|
||||
/**
|
||||
* vxe 原生工具栏挂载封装
|
||||
* 解决每个组件使用 vxe-table 组件时都需要写一遍的问题
|
||||
*/
|
||||
export function useTableToolbar() {
|
||||
const hiddenSearchBar = ref(false); // 隐藏搜索栏
|
||||
const tableToolbarRef = ref<InstanceType<typeof TableToolbar>>();
|
||||
const tableToolbarRef = ref<InstanceType<typeof VbenVxeTableToolbar>>();
|
||||
const tableRef = ref<VxeTableInstance>();
|
||||
const isBound = ref<boolean>(false);
|
||||
|
||||
|
@ -24,7 +25,7 @@ export function useTableToolbar() {
|
|||
if (!toolbar) {
|
||||
console.error('[toolbar 挂载失败] Table toolbar not found');
|
||||
}
|
||||
await table.connect(toolbar as VxeToolbarInstance);
|
||||
await table.connectToolbar(toolbar as VxeToolbarInstance);
|
||||
isBound.value = true;
|
||||
}, 1000); // 延迟挂载确保 toolbar 正确挂载
|
||||
}
|
Loading…
Reference in New Issue