feat: 表格组件增加名称更改和状态展示
This commit is contained in:
parent
96a765fa12
commit
02e686c76b
|
@ -37,7 +37,7 @@
|
||||||
"@7polo/kity": "2.0.8",
|
"@7polo/kity": "2.0.8",
|
||||||
"@7polo/kityminder-core": "1.4.53",
|
"@7polo/kityminder-core": "1.4.53",
|
||||||
"@arco-design/web-vue": "^2.49.2",
|
"@arco-design/web-vue": "^2.49.2",
|
||||||
"@arco-themes/vue-ms-theme-default": "^0.0.24",
|
"@arco-themes/vue-ms-theme-default": "^0.0.25",
|
||||||
"@form-create/arco-design": "^3.1.21",
|
"@form-create/arco-design": "^3.1.21",
|
||||||
"@vueuse/core": "^10.2.1",
|
"@vueuse/core": "^10.2.1",
|
||||||
"ace-builds": "^1.22.0",
|
"ace-builds": "^1.22.0",
|
||||||
|
|
|
@ -507,14 +507,14 @@
|
||||||
.arco-pagination-jumper {
|
.arco-pagination-jumper {
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
background: var(--color-text-n9);
|
background: var(--color-text-n9);
|
||||||
}
|
.arco-pagination-jumper-input {
|
||||||
.arco-pagination-jumper-input {
|
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
width: 57px;
|
width: 57px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
border: 1px solid var(--color-text-input-border);
|
border: 1px solid var(--color-text-input-border);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.arco-pagination-jumper-total-page {
|
.arco-pagination-jumper-total-page {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
export interface PageJumperProps {
|
export interface PageJumperProps {
|
||||||
current: number;
|
current: number;
|
||||||
simple: boolean;
|
simple?: boolean;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
pages: number;
|
pages: number;
|
||||||
size?: 'small' | 'mini' | 'medium' | 'large';
|
size?: 'small' | 'mini' | 'medium' | 'large';
|
||||||
|
|
|
@ -43,13 +43,45 @@
|
||||||
<div v-else class="title">{{ t(item.title as string) }}</div>
|
<div v-else class="title">{{ t(item.title as string) }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template #cell="{ column, record, rowIndex }">
|
<template #cell="{ column, record, rowIndex }">
|
||||||
<slot v-if="item.slotName" :name="item.slotName" v-bind="{ record, rowIndex, column }"></slot>
|
<div class="flex flex-row items-center">
|
||||||
<template v-else>{{ record[item.dataIndex as string] }}</template>
|
<template v-if="item.dataIndex === SpecialColumnEnum.ENABLE">
|
||||||
|
<div v-if="record.enable" class="flex items-center">
|
||||||
|
<icon-check-circle-fill class="mr-[2px] text-[rgb(var(--success-6))]" />
|
||||||
|
{{ t('system.user.tableEnable') }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex items-center text-[var(--color-text-4)]">
|
||||||
|
<icon-stop class="mr-[2px]" />
|
||||||
|
{{ t('system.user.tableDisable') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<a-input
|
||||||
|
v-if="editActiveKey === rowIndex && item.dataIndex === editKey"
|
||||||
|
ref="currentInputRef"
|
||||||
|
v-model="record[item.dataIndex as string]"
|
||||||
|
@blur="handleEditInputBlur()"
|
||||||
|
@press-enter="handleEditInputEnter(record)"
|
||||||
|
/>
|
||||||
|
<slot v-else :name="item.slotName" v-bind="{ record, rowIndex, column }">
|
||||||
|
<span>{{ record[item.dataIndex as string] }}</span>
|
||||||
|
</slot>
|
||||||
|
<MsIcon
|
||||||
|
v-if="item.editable && item.dataIndex === editKey"
|
||||||
|
class="ml-2 cursor-pointer"
|
||||||
|
:class="{ 'ms-table-edit-active': editActiveKey === rowIndex }"
|
||||||
|
type="icon-icon_edit_outlined"
|
||||||
|
@click="handleEdit(rowIndex)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
<div class="ms-table-footer" :class="{ 'batch-action': showBatchAction }">
|
<div
|
||||||
|
class="flex h-[64px] w-[100%] flex-row flex-nowrap items-center justify-end px-0 py-4"
|
||||||
|
:class="{ 'batch-action': showBatchAction }"
|
||||||
|
>
|
||||||
<batch-action
|
<batch-action
|
||||||
v-if="showBatchAction"
|
v-if="showBatchAction"
|
||||||
:select-row-count="selectCurrent"
|
:select-row-count="selectCurrent"
|
||||||
|
@ -71,7 +103,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useAttrs, computed, ref, onMounted } from 'vue';
|
import { useAttrs, computed, ref, onMounted } from 'vue';
|
||||||
import { useTableStore } from '@/store';
|
import { useAppStore, useTableStore } from '@/store';
|
||||||
import selectAll from './select-all.vue';
|
import selectAll from './select-all.vue';
|
||||||
import {
|
import {
|
||||||
MsTableProps,
|
MsTableProps,
|
||||||
|
@ -80,6 +112,7 @@
|
||||||
BatchActionParams,
|
BatchActionParams,
|
||||||
BatchActionConfig,
|
BatchActionConfig,
|
||||||
MsTableColumn,
|
MsTableColumn,
|
||||||
|
SpecialColumnEnum,
|
||||||
} from './type';
|
} from './type';
|
||||||
import BatchAction from './batchAction.vue';
|
import BatchAction from './batchAction.vue';
|
||||||
import MsPagination from '@/components/pure/ms-pagination/index';
|
import MsPagination from '@/components/pure/ms-pagination/index';
|
||||||
|
@ -89,7 +122,9 @@
|
||||||
const batchleft = ref('10px');
|
const batchleft = ref('10px');
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
const columns = ref<MsTableColumn>([]);
|
const columns = ref<MsTableColumn>([]);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
selectedKeys?: (string | number)[];
|
selectedKeys?: (string | number)[];
|
||||||
actionConfig?: BatchActionConfig;
|
actionConfig?: BatchActionConfig;
|
||||||
|
@ -100,28 +135,35 @@
|
||||||
(e: 'batchAction', value: BatchActionParams): void;
|
(e: 'batchAction', value: BatchActionParams): void;
|
||||||
(e: 'pageChange', value: number): void;
|
(e: 'pageChange', value: number): void;
|
||||||
(e: 'pageSizeChange', value: number): void;
|
(e: 'pageSizeChange', value: number): void;
|
||||||
|
(e: 'rowNameChange', value: TableData): void;
|
||||||
}>();
|
}>();
|
||||||
const isSelectAll = ref(false);
|
const isSelectAll = ref(false);
|
||||||
const attrs = useAttrs();
|
const attrs = useAttrs();
|
||||||
// 全选按钮-当前的条数
|
// 全选按钮-当前的条数
|
||||||
const selectCurrent = ref(0);
|
const selectCurrent = ref(0);
|
||||||
const { rowKey, pagination }: Partial<MsTableProps> = attrs;
|
|
||||||
|
|
||||||
// 全选按钮-总条数
|
// 全选按钮-总条数
|
||||||
const selectTotal = computed(() => {
|
const selectTotal = ref(0);
|
||||||
const { data }: Partial<MsTableProps> = attrs;
|
// 编辑按钮的Active状态
|
||||||
if (pagination) {
|
const editActiveKey = ref(-1);
|
||||||
const { pageSize } = pagination as MsPaginationI;
|
// 编辑input的Ref
|
||||||
return pageSize;
|
const currentInputRef = ref(null);
|
||||||
|
const { rowKey, editKey }: Partial<MsTableProps> = attrs;
|
||||||
|
|
||||||
|
const setSelectAllTotal = (isAll: boolean) => {
|
||||||
|
const { data, msPagination }: Partial<MsTableProps> = attrs;
|
||||||
|
if (isAll) {
|
||||||
|
selectTotal.value = msPagination?.total || data?.length || appStore.pageSize;
|
||||||
|
} else {
|
||||||
|
selectTotal.value = data ? data.length : appStore.pageSize;
|
||||||
}
|
}
|
||||||
return data ? data.length : 20;
|
};
|
||||||
});
|
|
||||||
|
|
||||||
const initColumn = () => {
|
const initColumn = () => {
|
||||||
columns.value = tableStore.getShowInTableColumns(attrs.tableKey as string);
|
columns.value = tableStore.getShowInTableColumns(attrs.tableKey as string);
|
||||||
};
|
};
|
||||||
// 选择行change事件
|
// 选择公共执行方法
|
||||||
const selectionChange = (arr: (string | number)[], setCurrentSelect: boolean) => {
|
const selectionChange = (arr: (string | number)[], setCurrentSelect: boolean, isAll = false) => {
|
||||||
|
setSelectAllTotal(isAll);
|
||||||
emit('selectedChange', arr);
|
emit('selectedChange', arr);
|
||||||
if (setCurrentSelect) {
|
if (setCurrentSelect) {
|
||||||
selectCurrent.value = arr.length;
|
selectCurrent.value = arr.length;
|
||||||
|
@ -130,7 +172,7 @@
|
||||||
|
|
||||||
// 全选change事件
|
// 全选change事件
|
||||||
const handleChange = (v: string) => {
|
const handleChange = (v: string) => {
|
||||||
const { data }: Partial<MsTableProps> = attrs;
|
const { data, msPagination }: Partial<MsTableProps> = attrs;
|
||||||
isSelectAll.value = v === SelectAllEnum.ALL;
|
isSelectAll.value = v === SelectAllEnum.ALL;
|
||||||
if (v === SelectAllEnum.NONE) {
|
if (v === SelectAllEnum.NONE) {
|
||||||
selectionChange([], true);
|
selectionChange([], true);
|
||||||
|
@ -144,10 +186,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v === SelectAllEnum.ALL) {
|
if (v === SelectAllEnum.ALL) {
|
||||||
const { total } = pagination as MsPaginationI;
|
const { total } = msPagination as MsPaginationI;
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
selectionChange(
|
selectionChange(
|
||||||
data.map((item: any) => item[rowKey || 'id']),
|
data.map((item: any) => item[rowKey || 'id']),
|
||||||
|
false,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
selectCurrent.value = total;
|
selectCurrent.value = total;
|
||||||
|
@ -168,6 +211,20 @@
|
||||||
return selectCurrent.value > 0 && attrs.showSelectAll;
|
return selectCurrent.value > 0 && attrs.showSelectAll;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleEditInputEnter = (record: TableData) => {
|
||||||
|
editActiveKey.value = -1;
|
||||||
|
emit('rowNameChange', record);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditInputBlur = () => {
|
||||||
|
editActiveKey.value = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑单元格的input
|
||||||
|
const handleEdit = (rowIndex: number) => {
|
||||||
|
editActiveKey.value = rowIndex;
|
||||||
|
};
|
||||||
|
|
||||||
// 根据参数获取全选按钮的位置
|
// 根据参数获取全选按钮的位置
|
||||||
const getBatchLeft = () => {
|
const getBatchLeft = () => {
|
||||||
if (attrs.enableDrag) {
|
if (attrs.enableDrag) {
|
||||||
|
@ -219,17 +276,14 @@
|
||||||
.title {
|
.title {
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
}
|
}
|
||||||
.ms-table-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
padding: 16px 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 62px;
|
|
||||||
flex-flow: row nowrap;
|
|
||||||
}
|
|
||||||
.batch-action {
|
.batch-action {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
.pop-title {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
.ms-table-edit-active {
|
||||||
|
color: rgb(var(--primary-5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -24,5 +24,10 @@ export default {
|
||||||
resetDefault: 'Reset default',
|
resetDefault: 'Reset default',
|
||||||
nonSort: 'The above properties cannot be sorted',
|
nonSort: 'The above properties cannot be sorted',
|
||||||
},
|
},
|
||||||
|
cancel: 'Cancel',
|
||||||
|
confirm: 'Confirm',
|
||||||
|
modify: 'Modify{name}',
|
||||||
|
nameIsNotNull: 'Name cannot be empty',
|
||||||
|
nameIsExist: '{name} already exists',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,5 +24,10 @@ export default {
|
||||||
resetDefault: '恢复默认',
|
resetDefault: '恢复默认',
|
||||||
nonSort: '以上属性不可排序',
|
nonSort: '以上属性不可排序',
|
||||||
},
|
},
|
||||||
|
cancel: '取消',
|
||||||
|
confirm: '确定',
|
||||||
|
modify: '修改{name}',
|
||||||
|
nameIsNotNull: 'Name cannot be empty',
|
||||||
|
nameIsExist: '已有 {name}, 请更改',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,8 @@ export interface MsTableColumnData extends TableColumnData {
|
||||||
showDrag?: boolean;
|
showDrag?: boolean;
|
||||||
// 是否展示在表格上
|
// 是否展示在表格上
|
||||||
showInTable?: boolean;
|
showInTable?: boolean;
|
||||||
|
// 是否可编辑
|
||||||
|
editable?: boolean;
|
||||||
}
|
}
|
||||||
// 表格属性
|
// 表格属性
|
||||||
export interface MsTableProps {
|
export interface MsTableProps {
|
||||||
|
@ -59,6 +61,8 @@ export interface MsTableProps {
|
||||||
showSetting?: boolean;
|
showSetting?: boolean;
|
||||||
// 分页是否是简单模式
|
// 分页是否是简单模式
|
||||||
pageSimple?: boolean;
|
pageSimple?: boolean;
|
||||||
|
// 编辑的key,默认为name
|
||||||
|
editKey?: string;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,3 +98,16 @@ export interface BatchActionConfig {
|
||||||
baseAction: BatchActionParams[];
|
baseAction: BatchActionParams[];
|
||||||
moreAction?: BatchActionParams[];
|
moreAction?: BatchActionParams[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface renamePopconfirmVisibleType {
|
||||||
|
[key: string]: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具有特殊功能的列
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
export enum SpecialColumnEnum {
|
||||||
|
// 编辑列
|
||||||
|
NAME = 'name',
|
||||||
|
// 状态列
|
||||||
|
ENABLE = 'enable',
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { TableQueryParams } from '@/models/common';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
import type { TableData } from '@arco-design/web-vue';
|
import type { TableData } from '@arco-design/web-vue';
|
||||||
import type { MsTableProps, MsTableData, MsTableColumn } from './type';
|
import { type MsTableProps, type MsTableData, type MsTableColumn, SpecialColumnEnum } from './type';
|
||||||
|
|
||||||
export interface Pagination {
|
export interface Pagination {
|
||||||
current: number;
|
current: number;
|
||||||
|
@ -18,7 +18,11 @@ export interface Pagination {
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
export default function useTableProps(
|
export default function useTableProps(
|
||||||
loadListFunc: (v: TableQueryParams) => Promise<any>,
|
loadListFunc: (v: TableQueryParams) => Promise<any>,
|
||||||
props?: Partial<MsTableProps>
|
props?: Partial<MsTableProps>,
|
||||||
|
// 数据处理的回调函数
|
||||||
|
callBack?: (item: TableData) => TableData,
|
||||||
|
// 编辑操作的保存回调函数
|
||||||
|
saveCallBack?: (item: TableData) => Promise<any>
|
||||||
) {
|
) {
|
||||||
// 行选择
|
// 行选择
|
||||||
const rowSelection = {
|
const rowSelection = {
|
||||||
|
@ -46,6 +50,8 @@ export default function useTableProps(
|
||||||
// 禁用 arco-table 的分页
|
// 禁用 arco-table 的分页
|
||||||
pagination: false,
|
pagination: false,
|
||||||
pageSimple: false,
|
pageSimple: false,
|
||||||
|
// 编辑的key
|
||||||
|
editKey: SpecialColumnEnum.NAME,
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,6 +166,9 @@ export default function useTableProps(
|
||||||
if (item.createTime) {
|
if (item.createTime) {
|
||||||
item.createTime = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss');
|
item.createTime = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss');
|
||||||
}
|
}
|
||||||
|
if (callBack) {
|
||||||
|
item = callBack(item);
|
||||||
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
setPagination({ current: data.current, total: data.total });
|
setPagination({ current: data.current, total: data.total });
|
||||||
|
@ -224,6 +233,12 @@ export default function useTableProps(
|
||||||
propsRes.value.data = _data;
|
propsRes.value.data = _data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 编辑触发
|
||||||
|
rowNameChange: (record: TableData) => {
|
||||||
|
if (saveCallBack) {
|
||||||
|
saveCallBack(record);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
showDrag: false,
|
showDrag: false,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'system.userGroup.email',
|
title: 'system.userGroup.email',
|
||||||
|
|
Loading…
Reference in New Issue