perf: 保存调整后的列宽

pull/361/head
xiaojunnuo 2025-03-18 10:00:16 +08:00
parent 4453070060
commit 873f2b618b
2 changed files with 185 additions and 171 deletions

View File

@ -6,16 +6,48 @@ import { FsExtendsCopyable, FsExtendsEditor, FsExtendsJson, FsExtendsTime, FsExt
import "@fast-crud/fast-extends/dist/style.css";
import UiAntdv from "@fast-crud/ui-antdv4";
import "@fast-crud/ui-antdv4/dist/style.css";
import { merge } from "lodash-es";
import { debounce, merge } from "lodash-es";
import { useCrudPermission } from "../permission";
import { App } from "vue";
import { notification } from "ant-design-vue";
import { usePreferences } from "/@/vben/preferences";
import { LocalStorage } from "/@/utils/util.storage";
class ColumnSizeSaver {
save: (key: string, size: number) => void;
constructor() {
this.save = debounce((key: string, size: number) => {
const saveKey = this.getKey();
let data = LocalStorage.get(saveKey);
if (!data) {
data = {};
}
data[key] = size;
LocalStorage.set(saveKey, data);
});
}
getKey() {
const loc = window.location;
const currentUrl = `${loc.pathname}${loc.search}${loc.hash}`;
return `columnSize-${currentUrl}`;
}
get(key: string) {
const saveKey = this.getKey();
const row = LocalStorage.get(saveKey);
return row?.[key];
}
clear() {
const saveKey = this.getKey();
LocalStorage.remove(saveKey);
}
}
const columnSizeSaver = new ColumnSizeSaver();
function install(app: App, options: any = {}) {
app.use(UiAntdv);
//设置日志级别
setLogger({ level: "info" });
app.use(FastCrud, {
i18n: options.i18n,
async dictRequest({ url }: any) {
@ -39,20 +71,21 @@ function install(app: App, options: any = {}) {
mobile: {
enabled: true,
props: {
isMobile: isMobile
}
}
}
isMobile: isMobile,
},
},
},
},
table: {
scroll: {
x: 960
x: 960,
},
size: "small",
pagination: false,
onResizeColumn: (w: number | string, col: any) => {
onResizeColumn: (w: number, col: any) => {
if (crudBinding.value?.table?.columnsMap && crudBinding.value?.table?.columnsMap[col.key]) {
crudBinding.value.table.columnsMap[col.key].width = w;
columnSizeSaver.save(col.key, w);
}
},
conditionalRender: {
@ -70,13 +103,18 @@ function install(app: App, options: any = {}) {
},
render() {
return "-";
}
}
},
},
},
toolbar: {
export: {
fileType: "excel"
}
fileType: "excel",
},
columnsFilter: {
async onReset() {
columnSizeSaver.clear();
},
},
},
rowHandle: {
fixed: "right",
@ -84,13 +122,15 @@ function install(app: App, options: any = {}) {
view: { type: "link", text: null, icon: "ion:eye-outline" },
copy: { show: true, type: "link", text: null, icon: "ion:copy-outline" },
edit: { type: "link", text: null, icon: "ion:create-outline" },
remove: { type: "link", style: { color: "red" }, text: null, icon: "ion:trash-outline" }
remove: { type: "link", style: { color: "red" }, text: null, icon: "ion:trash-outline" },
},
dropdown: {
more: {
type: "link"
}
}
type: "link",
},
},
resizable: true,
width: 200,
},
request: {
transformQuery: ({ page, form, sort }: PageQuery): UserPageQuery => {
@ -103,10 +143,10 @@ function install(app: App, options: any = {}) {
return {
page: {
limit,
offset
offset,
},
query: form,
sort
sort,
};
},
transformRes: ({ res }: TransformResProps): PageRes => {
@ -116,16 +156,16 @@ function install(app: App, options: any = {}) {
currentPage++;
}
return { currentPage, pageSize, records: res.records, total: res.total, ...res };
}
},
},
search: {
formItem: {
wrapperCol: {
style: {
width: "50%"
}
}
}
width: "50%",
},
},
},
},
form: {
display: "flex",
@ -133,8 +173,8 @@ function install(app: App, options: any = {}) {
//固定label宽度
span: null,
style: {
width: "145px"
}
width: "145px",
},
},
async afterSubmit({ mode }) {
if (mode === "add") {
@ -144,13 +184,13 @@ function install(app: App, options: any = {}) {
}
},
wrapperCol: {
span: null
span: null,
},
wrapper: {
saveRemind: true
saveRemind: true,
// inner: true,
// innerContainerSelector: "main.fs-framework-content"
}
},
},
columns: {
//最后一列空白,用于自动伸缩列宽
@ -158,23 +198,23 @@ function install(app: App, options: any = {}) {
title: "",
type: "text",
form: {
show: false
show: false,
},
column: {
order: 99999,
width: -1,
columnSetShow: false,
resizable: false
}
}
}
resizable: false,
},
},
},
};
// 从 useCrud({permission}) 里获取permission参数去设置各个按钮的权限
const permission = props.context?.permission || null;
const crudPermission = useCrudPermission({ permission });
return crudPermission.merge(opts);
}
},
});
// fast-extends里面的扩展组件均为异步组件只有在使用时才会被加载并不会影响首页加载速度
@ -202,19 +242,19 @@ function install(app: App, options: any = {}) {
url: action,
method: "post",
headers: {
"Content-Type": "multipart/form-data"
"Content-Type": "multipart/form-data",
},
timeout: 60000,
data,
onUploadProgress: (p: any) => {
onProgress({ percent: Math.round((p.loaded / p.total) * 100) });
}
},
});
},
successHandle(res: any) {
return res;
}
}
},
},
});
//安装editor
@ -222,10 +262,10 @@ function install(app: App, options: any = {}) {
//编辑器的公共配置
wangEditor: {
editorConfig: {
MENU_CONF: {}
MENU_CONF: {},
},
toolbarConfig: {}
}
toolbarConfig: {},
},
});
app.use(FsExtendsJson);
app.use(FsExtendsTime);
@ -250,8 +290,8 @@ function install(app: App, options: any = {}) {
column: { component: { name: "fs-date-format", format: "YYYY-MM-DD" } },
valueBuilder(context: any) {
console.log("time2,valueBuilder", context);
}
}
},
},
});
// 此处演示自定义字段合并插件
@ -266,32 +306,14 @@ function install(app: App, options: any = {}) {
// 合并column配置
merge(columnProps, {
form: { show: false },
viewForm: { show: true }
viewForm: { show: true },
});
}
return columnProps;
}
},
});
//默认宽度,支持自动拖动调整列宽
registerMergeColumnPlugin({
name: "resize-column-plugin",
order: 2,
handle: (columnProps: ColumnCompositionProps) => {
if (!columnProps.column) {
columnProps.column = {};
}
if (columnProps.column.resizable == null) {
columnProps.column.resizable = true;
if (!columnProps.column.width) {
columnProps.column.width = 200;
}
}
return columnProps;
}
});
registerMergeColumnPlugin({
name: "resize-column-plugin",
order: 2,
@ -300,16 +322,19 @@ function install(app: App, options: any = {}) {
columnProps.column = {};
}
columnProps.column.resizable = true;
if (columnProps.column.width == null) {
const savedColumnWidth = columnSizeSaver.get(columnProps.key as string);
if (savedColumnWidth) {
columnProps.column.width = savedColumnWidth;
} else if (columnProps.column.width == null) {
columnProps.column.width = 200;
} else if (typeof columnProps.column?.width === "string" && columnProps.column.width.indexOf("px") > -1) {
columnProps.column.width = parseInt(columnProps.column.width.replace("px", ""));
}
return columnProps;
}
},
});
}
export default {
install
install,
};

View File

@ -38,8 +38,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
data: [
{ label: "成功", value: "ok", color: "green" },
{ label: "检查中", value: "checking", color: "blue" },
{ label: "异常", value: "error", color: "red" }
]
{ label: "异常", value: "error", color: "red" },
],
});
return {
crudOptions: {
@ -47,22 +47,22 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
pageRequest,
addRequest,
editRequest,
delRequest
delRequest,
},
form: {
labelCol: {
//固定label宽度
span: null,
style: {
width: "100px"
}
width: "100px",
},
},
col: {
span: 22
span: 22,
},
wrapper: {
width: 600
}
width: 600,
},
},
actionbar: {
buttons: {
@ -72,7 +72,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
//非plus
if (crudBinding.value.data.length >= 1) {
notification.error({
message: "基础版只能添加一个监控站点,请赞助升级专业版"
message: "基础版只能添加一个监控站点,请赞助升级专业版",
});
mitter.emit("openVipModal");
return;
@ -86,15 +86,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const max = suiteDetail.monitorCount.max;
if (max != -1 && max <= suiteDetail.monitorCount.used) {
notification.error({
message: `对不起,您最多只能创建条${max}监控记录,请购买或升级套餐`
message: `对不起,您最多只能创建条${max}监控记录,请购买或升级套餐`,
});
return;
}
}
await crudExpose.openAdd({});
}
}
}
},
},
},
},
rowHandle: {
fixed: "right",
@ -105,18 +105,18 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
type: "link",
text: null,
tooltip: {
title: "立即检查"
title: "立即检查",
},
icon: "ion:play-sharp",
click: async ({ row }) => {
await api.DoCheck(row.id);
await crudExpose.doRefresh();
notification.success({
message: "检查完成"
message: "检查完成",
});
}
}
}
},
},
},
},
columns: {
id: {
@ -124,78 +124,67 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
key: "id",
type: "number",
search: {
show: false
show: false,
},
column: {
width: 80,
align: "center"
align: "center",
},
form: {
show: false
}
show: false,
},
},
name: {
title: "站点名称",
search: {
show: true
show: true,
},
type: "text",
form: {
rules: [{ required: true, message: "请输入站点名称" }]
rules: [{ required: true, message: "请输入站点名称" }],
},
column: {
width: 160
}
width: 160,
},
},
domain: {
title: "网站域名",
search: {
show: true
show: true,
},
type: "text",
form: {
rules: [
{ required: true, message: "请输入域名" },
//@ts-ignore
{ type: "domains", message: "请输入正确的域名" }
]
{ type: "domains", message: "请输入正确的域名" },
],
},
column: {
width: 200,
width: 230,
sorter: true,
cellRender({ value }) {
cellRender({ value, row }) {
const url = `https://${value}:${row.httpsPort}`;
return (
<a-tooltip title={value} placement="left">
<fs-copyable modelValue={value}></fs-copyable>
<fs-copyable modelValue={value}>
<a target="_blank" href={url}>
{value}:{row.httpsPort}
</a>
</fs-copyable>
</a-tooltip>
);
}
}
},
httpsPort: {
title: "HTTPS端口",
search: {
show: false
},
},
type: "number",
form: {
value: 443,
rules: [{ required: true, message: "请输入端口" }]
},
column: {
align: "center",
width: 110,
show: false
}
},
certDomains: {
title: "证书域名",
search: {
show: true
show: true,
},
type: "text",
form: {
show: false
show: false,
},
column: {
width: 200,
@ -207,56 +196,56 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
{value}
</a-tooltip>
);
}
}
},
},
},
certProvider: {
title: "颁发机构",
search: {
show: false
show: false,
},
type: "text",
form: {
show: false
show: false,
},
column: {
width: 200,
sorter: true,
cellRender({ value }) {
return <a-tooltip title={value}>{value}</a-tooltip>;
}
}
},
},
},
certStatus: {
title: "证书状态",
search: {
show: true
show: true,
},
type: "dict-select",
dict: dict({
data: [
{ label: "正常", value: "ok", color: "green" },
{ label: "过期", value: "expired", color: "red" }
]
{ label: "过期", value: "expired", color: "red" },
],
}),
form: {
show: false
show: false,
},
column: {
width: 110,
width: 100,
sorter: true,
show: true,
align: "center"
}
align: "center",
},
},
certExpiresTime: {
title: "证书到期时间",
search: {
show: false
show: false,
},
type: "date",
form: {
show: false
show: false,
},
column: {
sorter: true,
@ -269,35 +258,56 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const color = leftDays < 20 ? "red" : "#389e0d";
const percent = (leftDays / 90) * 100;
return <a-progress title={expireDate + "过期"} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}`} />;
}
}
},
},
},
lastCheckTime: {
title: "上次检查时间",
search: {
show: false
show: false,
},
type: "datetime",
form: {
show: false
show: false,
},
column: {
sorter: true,
width: 155
}
width: 155,
},
},
disabled: {
title: "禁用启用",
search: {
show: false,
},
type: "dict-switch",
dict: dict({
data: [
{ label: "启用", value: false, color: "green" },
{ label: "禁用", value: true, color: "red" },
],
}),
form: {
value: false,
},
column: {
width: 100,
sorter: true,
align: "center",
},
},
checkStatus: {
title: "检查状态",
search: {
show: false
show: false,
},
type: "dict-select",
dict: checkStatusDict,
form: {
show: false
show: false,
},
column: {
width: 110,
width: 100,
align: "center",
sorter: true,
cellRender({ value, row, key }) {
@ -306,8 +316,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
<fs-values-format v-model={value} dict={checkStatusDict}></fs-values-format>
</a-tooltip>
);
}
}
},
},
},
// error: {
// title: "错误信息",
@ -329,51 +339,30 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
pipelineId: {
title: "关联流水线id",
search: {
show: false
show: false,
},
form: { show: false },
type: "number",
column: {
width: 200,
sorter: true,
show: false
}
show: false,
},
},
certInfoId: {
title: "证书id",
search: {
show: false
show: false,
},
type: "number",
form: { show: false },
column: {
width: 100,
sorter: true,
show: false
}
show: false,
},
},
disabled: {
title: "禁用启用",
search: {
show: false
},
type: "dict-switch",
dict: dict({
data: [
{ label: "启用", value: false, color: "green" },
{ label: "禁用", value: true, color: "red" }
]
}),
form: {
value: false
},
column: {
width: 110,
sorter: true,
align: "center"
}
}
}
}
},
},
};
}