20260725172954

This commit is contained in:
oneao committed 2026-07-25 17:29:54 +08:00
1 parent 1b86e0043a
commit e3c7c6f8da
16 files changed
+714 -796

No files matched your search

@@ -0,0 +1,198 @@
import { h, ref } from "vue";
import { Dropdown, Menu, MenuItem, Modal } from "antdv-next";
import { createInputCell } from "./createEditableCellRenderer";
const stop = (e) => e.stopPropagation();
// ──────────────────────────────────────────
// 1. 通用操作触发:支持 confirm 弹窗
// ──────────────────────────────────────────
function triggerAction(action, row) {
if (action.confirm) {
Modal.confirm({
title: action.confirm,
okText: "确定",
okType: "danger",
cancelText: "取消",
onOk: () => action.onClick?.(row),
});
} else {
action.onClick?.(row);
}
}
// ──────────────────────────────────────────
// 2. checkbox 类型渲染器
// ──────────────────────────────────────────
function createCheckboxCell(col) {
return ({ row, cellValue }) => {
const checked = cellValue === 1;
return h(
"label",
{
class: checked ? "fms-checkbox checked" : "fms-checkbox",
onClick: stop,
onMousedown: stop,
},
[
h("input", {
type: "checkbox",
checked,
onChange: (e) => {
e.stopPropagation();
row[col.dataIndex] = e.target.checked ? 1 : 0;
col.onChange?.();
},
onClick: stop,
onMousedown: stop,
}),
h("span", { class: "fms-checkbox-box" }),
],
);
};
}
// ──────────────────────────────────────────
// 3. actions 类型渲染器
// ──────────────────────────────────────────
function createActionsCell(actions) {
if (!actions?.length) return undefined;
const inlineActions = actions.filter((a) => a.type !== "more");
const moreAction = actions.find((a) => a.type === "more");
const moreOpen = ref(false);
const moreRow = ref(null);
function makeButton(action, row) {
return h(
"button",
{
type: "button",
class: "fms-action-btn",
onMousedown: stop,
onClick: (e) => {
e.stopPropagation();
triggerAction(action, row);
},
},
action.label || action.type,
);
}
return ({ row }) => {
const children = [];
for (const action of inlineActions) {
children.push(makeButton(action, row));
}
if (moreAction?.items?.length) {
if (!moreOpen.value) {
children.push(
h(
"button",
{
type: "button",
class: "fms-action-btn fms-action-more",
onMousedown: stop,
onClick: (e) => {
e.stopPropagation();
moreOpen.value = true;
moreRow.value = row;
},
},
"更多",
),
);
} else {
children.push(
h(
Dropdown,
{
visible: true,
trigger: "click",
placement: "bottomRight",
onVisibleChange: (v) => {
if (!v) {
moreOpen.value = false;
moreRow.value = null;
}
},
},
{
default: () =>
h(
"button",
{
type: "button",
class: "fms-action-btn fms-action-more fms-action-more-open",
onMousedown: stop,
},
"更多",
),
overlay: () =>
h(Menu, null, {
default: () =>
moreAction.items.map((item) =>
h(MenuItem, { key: item.label }, {
default: () =>
h(
"span",
{
onClick: (e) => {
e.stopPropagation();
moreOpen.value = false;
triggerAction(item, moreRow.value);
},
},
item.label,
),
}),
),
}),
},
),
);
}
}
return h("span", { class: "fms-actions-cell" }, children);
};
}
// ──────────────────────────────────────────
// 4. 统一入口:根据 col.type 注入 customCell
// ──────────────────────────────────────────
const cellCache = new WeakMap();
/**
* 根据列定义的 type 属性自动注入 customCell 渲染器。
* - `type: "input"` → 原生 input(编辑态通过 row._editing 控制,非编辑态零 VNode 纯文本)
* - `type: "checkbox"` → 原生 checkbox
* - `type: "actions"` → 操作按钮列(从 col.actions 读取按钮配置)
* - 无 type 或有自定义 customCell → 保持原样
*
* input 类型不做缓存:因为 customCell 读的是 row._editing 运行时状态,
* 不依赖闭包捕获的外部值,每次创建相同函数亦可安全返回。
* checkbox/actions 使用 WeakMap 缓存,避免重复创建。
*/
export function resolveCustomCell(col) {
if (col.customCell) return col;
const cached = cellCache.get(col);
if (cached) return cached;
let result = col;
if (col.type === "input") {
// 不缓存:row._editing 在渲染时动态读取
return { ...col, customCell: createInputCell(col) };
} else if (col.type === "checkbox") {
result = { ...col, customCell: createCheckboxCell(col) };
} else if (col.type === "actions") {
const fn = createActionsCell(col.actions);
if (fn) result = { ...col, customCell: fn };
}
cellCache.set(col, result);
return result;
}