20260904173136

This commit is contained in:
oneao committed 2026-09-04 17:31:36 +08:00
1 parent 0928437c67
commit 4e167df0f0
40 files changed
+3471 -2314

No files matched your search

+45 -1
View File
@@ -4,6 +4,35 @@ export function cloneData(value) {
return JSON.parse(JSON.stringify(value))
}
/**
* 剔除派生字段:下划线前缀(_*)与视图前缀(v_*),与 diffRow 的 isIgnorableKey 对齐。
* 前者为前端派生/虚拟字段(字段面板的 __form/__list/__query 参与勾选、i18n 透视行的
* _id/_localeIds/_managedId 等),后者为视图只读列;均不参与比较、不提交后端。
* 数组逐元素递归处理,其余非对象原样返回。
* @template T
* @param {T} value
* @returns {T}
*/
export function stripInternalKeys(value) {
if (Array.isArray(value)) return value.map(stripInternalKeys)
if (!value || typeof value !== 'object') return value
const stripped = {}
for (const [key, val] of Object.entries(value)) {
if (key.startsWith('_') || key.startsWith('v_')) continue
stripped[key] = val
}
return stripped
}
/**
* 行集合差异比对(子表;单条记录字段级比对请用 diffRow)。
* 比较时忽略派生字段(_* / v_*),避免字段面板的参与勾选等虚拟列造成「打开即脏」。
*
* 注意:inserts / updates 返回的是 current 中的原对象引用(不拷贝)——
* 保存编排的 allocateTemporaryIds 依赖该引用共享,把临时 id → 真实 id 原地回灌到草稿行,
* 随后的 remapForeignKeys 才能据此修正跨表外键。派生字段的剥离统一延后到
* 提交前由 sanitizeSaveReqs 处理,切勿在此处返回剥离副本。
*/
export function diffRows(current, previous) {
const previousById = new Map(previous.map((item) => [String(item.b_id), item]))
const currentById = new Map(current.map((item) => [String(item.b_id), item]))
@@ -11,7 +40,8 @@ export function diffRows(current, previous) {
inserts: current.filter((item) => !previousById.has(String(item.b_id))),
updates: current.filter((item) => {
const old = previousById.get(String(item.b_id))
return old && JSON.stringify(item) !== JSON.stringify(old)
if (!old) return false
return JSON.stringify(stripInternalKeys(item)) !== JSON.stringify(stripInternalKeys(old))
}),
deletes: previous
.filter((item) => !currentById.has(String(item.b_id)))
@@ -19,6 +49,20 @@ export function diffRows(current, previous) {
}
}
/**
* 提交前剥离保存请求中的派生字段(_* / v_*),返回请求副本,不改原对象。
* 必须在分配真实主键与跨表外键重映射之后调用:剥离产生副本,提前调用会切断
* 请求行与草稿行的引用共享,导致临时 id 无法回灌(见 diffRows 注释)。
*/
export function sanitizeSaveReqs(saveReqs) {
return (saveReqs || []).map((req) => {
const next = { ...req }
if (next.inserts) next.inserts = next.inserts.map(stripInternalKeys)
if (next.updates) next.updates = next.updates.map(stripInternalKeys)
return next
})
}
export async function allocateTemporaryIds(rowGroups) {
const temporaryIds = [
...new Set(