Merge pull request #104 from cshaptx4869/patch-66

feat(PageContent):  列表列增加show配置项
This commit is contained in:
Ray Hao
2024-05-17 22:33:26 +08:00
committed by GitHub
3 changed files with 100 additions and 132 deletions

View File

@@ -59,37 +59,21 @@
<template v-for="item in defaultToolbar" :key="item"> <template v-for="item in defaultToolbar" :key="item">
<!-- 刷新 --> <!-- 刷新 -->
<template v-if="item === 'refresh'"> <template v-if="item === 'refresh'">
<el-icon class="cursor-pointer ml-2" @click="handleToolbar(item)"> <el-button icon="refresh" circle @click="handleToolbar(item)" />
<i-ep-refresh />
</el-icon>
</template> </template>
<!-- 列设置 --> <!-- 列设置 -->
<template v-else-if="item === 'filter'"> <template v-else-if="item === 'filter'">
<el-popover placement="bottom" trigger="click"> <el-popover placement="bottom" trigger="click">
<template #reference> <template #reference>
<el-icon class="cursor-pointer ml-2"> <el-button icon="Operation" circle />
<i-ep-setting /> </template>
</el-icon> <template v-for="col in cols" :key="col">
<el-checkbox
v-if="col.prop"
v-model="col.show"
:label="col.label"
/>
</template> </template>
<el-checkbox
v-model="columnSetting.checkAll"
:indeterminate="columnSetting.isIndeterminate"
@change="handleCheckAllChange"
>
全选
</el-checkbox>
<el-checkbox-group
v-model="columnSetting.checkedCols"
@change="handleCheckedColumnsChange"
>
<div v-for="col in contentConfig.cols" :key="col.label">
<el-checkbox
v-if="col.label"
:value="col.label"
:label="col.label"
/>
</div>
</el-checkbox-group>
</el-popover> </el-popover>
</template> </template>
</template> </template>
@@ -102,95 +86,113 @@
:data="pageData" :data="pageData"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<template v-for="col in displayedColumns" :key="col.prop"> <template v-for="col in cols" :key="col">
<el-table-column v-if="col.show" v-bind="col"> <el-table-column v-if="col.show" v-bind="col">
<template #default="scope"> <template #default="scope">
<!-- 显示图片 --> <!-- 显示图片 -->
<template v-if="col.templet === 'image'"> <template v-if="col.templet === 'image'">
<template v-if="Array.isArray(scope.row[col.prop])"> <template v-if="col.prop">
<template <template v-if="Array.isArray(scope.row[col.prop])">
v-for="(item, index) in scope.row[col.prop]" <template
:key="item" v-for="(item, index) in scope.row[col.prop]"
> :key="item"
>
<el-image
:src="item"
:preview-src-list="scope.row[col.prop]"
:initial-index="index"
:preview-teleported="true"
:style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
/>
</template>
</template>
<template v-else>
<el-image <el-image
:src="item" :src="scope.row[col.prop]"
:preview-src-list="scope.row[col.prop]" :preview-src-list="[scope.row[col.prop]]"
:initial-index="index"
:preview-teleported="true" :preview-teleported="true"
:style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`" :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
/> />
</template> </template>
</template> </template>
<template v-else>
<el-image
:src="scope.row[col.prop]"
:preview-src-list="[scope.row[col.prop]]"
:preview-teleported="true"
:style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
/>
</template>
</template> </template>
<!-- 根据行的selectList属性返回对应列表值 --> <!-- 根据行的selectList属性返回对应列表值 -->
<template v-else-if="col.templet === 'list'"> <template v-else-if="col.templet === 'list'">
{{ (col.selectList ?? {})[scope.row[col.prop]] }} <template v-if="col.prop">
{{ (col.selectList ?? {})[scope.row[col.prop]] }}
</template>
</template> </template>
<!-- 格式化显示链接 --> <!-- 格式化显示链接 -->
<template v-else-if="col.templet === 'url'"> <template v-else-if="col.templet === 'url'">
<el-link <template v-if="col.prop">
type="primary" <el-link
:href="scope.row[col.prop]" type="primary"
target="_blank" :href="scope.row[col.prop]"
> target="_blank"
{{ scope.row[col.prop] }} >
</el-link> {{ scope.row[col.prop] }}
</el-link>
</template>
</template> </template>
<!-- 生成开关组件 --> <!-- 生成开关组件 -->
<template v-else-if="col.templet === 'switch'"> <template v-else-if="col.templet === 'switch'">
<!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 --> <template v-if="col.prop">
<el-switch <!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 -->
v-model="scope.row[col.prop]" <el-switch
:active-value="col.activeValue ?? 1" v-model="scope.row[col.prop]"
:inactive-value="col.inactiveValue ?? 0" :active-value="col.activeValue ?? 1"
:inline-prompt="true" :inactive-value="col.inactiveValue ?? 0"
:active-text="col.activeText ?? ''" :inline-prompt="true"
:inactive-text="col.inactiveText ?? ''" :active-text="col.activeText ?? ''"
:validate-event="false" :inactive-text="col.inactiveText ?? ''"
:disabled="!hasAuth(`${contentConfig.pageName}:modify`)" :validate-event="false"
@change=" :disabled="!hasAuth(`${contentConfig.pageName}:modify`)"
pageData.length > 0 && @change="
handleSwitchChange(col.prop, scope.row[col.prop], scope.row) pageData.length > 0 &&
" handleSwitchChange(
/> col.prop,
scope.row[col.prop],
scope.row
)
"
/>
</template>
</template> </template>
<!-- 格式化为价格 --> <!-- 格式化为价格 -->
<template v-else-if="col.templet === 'price'"> <template v-else-if="col.templet === 'price'">
{{ `${col.priceFormat ?? ""}${scope.row[col.prop]}` }} <template v-if="col.prop">
{{ `${col.priceFormat ?? ""}${scope.row[col.prop]}` }}
</template>
</template> </template>
<!-- 格式化为百分比 --> <!-- 格式化为百分比 -->
<template v-else-if="col.templet === 'percent'"> <template v-else-if="col.templet === 'percent'">
{{ scope.row[col.prop] }}% <template v-if="col.prop"> {{ scope.row[col.prop] }}% </template>
</template> </template>
<!-- 显示图标 --> <!-- 显示图标 -->
<template v-else-if="col.templet === 'icon'"> <template v-else-if="col.templet === 'icon'">
<template v-if="scope.row[col.prop].startsWith('el-icon-')"> <template v-if="col.prop">
<el-icon> <template v-if="scope.row[col.prop].startsWith('el-icon-')">
<component <el-icon>
:is="scope.row[col.prop].replace('el-icon-', '')" <component
/> :is="scope.row[col.prop].replace('el-icon-', '')"
</el-icon> />
</template> </el-icon>
<template v-else> </template>
<svg-icon :icon-class="scope.row[col.prop]" /> <template v-else>
<svg-icon :icon-class="scope.row[col.prop]" />
</template>
</template> </template>
</template> </template>
<!-- 格式化时间 --> <!-- 格式化时间 -->
<template v-else-if="col.templet === 'date'"> <template v-else-if="col.templet === 'date'">
{{ <template v-if="col.prop">
useDateFormat( {{
scope.row[col.prop], useDateFormat(
col.dateFormat ?? "YYYY-MM-DD HH:mm:ss" scope.row[col.prop],
).value col.dateFormat ?? "YYYY-MM-DD HH:mm:ss"
}} ).value
}}
</template>
</template> </template>
<!-- 列操作栏 --> <!-- 列操作栏 -->
<template v-else-if="col.templet === 'tool'"> <template v-else-if="col.templet === 'tool'">
@@ -271,7 +273,7 @@ import { useDateFormat } from "@vueuse/core";
import { hasAuth } from "@/plugins/permission"; import { hasAuth } from "@/plugins/permission";
import Pagination from "@/components/Pagination/index.vue"; import Pagination from "@/components/Pagination/index.vue";
import SvgIcon from "@/components/SvgIcon/index.vue"; import SvgIcon from "@/components/SvgIcon/index.vue";
import type { TableProps, CheckboxValueType } from "element-plus"; import type { TableProps } from "element-plus";
// 对象类型 // 对象类型
export type IObject = Record<string, any>; export type IObject = Record<string, any>;
@@ -322,6 +324,7 @@ export interface IContentConfig<T = any> {
prop?: string; prop?: string;
width?: string | number; width?: string | number;
align?: "left" | "center" | "right"; align?: "left" | "center" | "right";
show?: boolean;
templet?: templet?:
| "image" | "image"
| "list" | "list"
@@ -378,6 +381,15 @@ const defaultToolbar = props.contentConfig.defaultToolbar ?? [
"refresh", "refresh",
"filter", "filter",
]; ];
// 表格列
const cols = ref(
props.contentConfig.cols.map((col) => {
if (col.show === undefined) {
col.show = true;
}
return col;
})
);
// 加载状态 // 加载状态
const loading = ref(false); const loading = ref(false);
// 删除ID集合 用于批量删除 // 删除ID集合 用于批量删除
@@ -525,53 +537,6 @@ function handleSwitchChange(
ElMessage.error("未配置modifyAction"); ElMessage.error("未配置modifyAction");
} }
} }
// 列设置类型声明
interface IColumnSetting {
checkAll: boolean;
isIndeterminate: boolean;
checkedCols: string[];
}
// 列设置
const columnSetting = ref<IColumnSetting>({
checkAll: true,
isIndeterminate: false,
checkedCols: [],
});
// 创建一个响应式副本,用于存储最后显示的列配置
const displayedColumns = ref<IObject>(props.contentConfig.cols);
// 全选/取消全选
const handleCheckAllChange = (checkAll: CheckboxValueType) => {
columnSetting.value.checkedCols = checkAll
? (props.contentConfig.cols.map((col) => col.label) as any[])
: [];
columnSetting.value.isIndeterminate = false;
displayedColumns.value = displayedColumns.value.map((col: IObject) => ({
...col,
show: checkAll,
}));
};
// 选中列变化
const handleCheckedColumnsChange = (values: CheckboxValueType[]) => {
const showColumnsLength = props.contentConfig.cols.length;
const checkedCount = values.length;
columnSetting.value.checkAll = checkedCount === showColumnsLength;
columnSetting.value.isIndeterminate =
checkedCount > 0 && checkedCount < showColumnsLength;
displayedColumns.value = displayedColumns.value.map((col: IObject) => ({
...col,
show: values.includes(col.label),
}));
};
// 初始化全选状态
handleCheckAllChange(columnSetting.value.checkAll);
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@@ -33,7 +33,7 @@ const contentConfig: IContentConfig<UserQuery> = {
], ],
cols: [ cols: [
{ type: "selection", width: 50, align: "center" }, { type: "selection", width: 50, align: "center" },
{ label: "编号", align: "center", prop: "id", width: 100 }, { label: "编号", align: "center", prop: "id", width: 100, show: false },
{ label: "用户名", align: "center", prop: "username" }, { label: "用户名", align: "center", prop: "username" },
{ label: "头像", align: "center", prop: "avatar", templet: "image" }, { label: "头像", align: "center", prop: "avatar", templet: "image" },
{ label: "用户昵称", align: "center", prop: "nickname", width: 120 }, { label: "用户昵称", align: "center", prop: "nickname", width: 120 },

View File

@@ -2,6 +2,9 @@ import type { IContentConfig } from "@/components/PageContent/index.vue";
const contentConfig: IContentConfig = { const contentConfig: IContentConfig = {
pageName: "sys:user", pageName: "sys:user",
table: {
showOverflowTooltip: true,
},
indexAction: function (params) { indexAction: function (params) {
// console.log("indexAction:", params); // console.log("indexAction:", params);
return Promise.resolve({ return Promise.resolve({
@@ -44,7 +47,7 @@ const contentConfig: IContentConfig = {
}, },
cols: [ cols: [
{ type: "selection", width: 50, align: "center" }, { type: "selection", width: 50, align: "center" },
{ label: "ID", align: "center", prop: "id" }, { label: "ID", align: "center", prop: "id", show: false },
{ label: "用户名", align: "center", prop: "username" }, { label: "用户名", align: "center", prop: "username" },
{ label: "图片", align: "center", prop: "avatar", templet: "image" }, { label: "图片", align: "center", prop: "avatar", templet: "image" },
{ {