Files
X-Financial/web/src/views/scripts/spreadsheetChangeRecords.js
caoxiaozhu 5106d286a1 feat(agent_assets): 添加规则版本送审时的命名副本创建逻辑
当提交的版本与当前工作版本不同时,自动创建命名副本:
- 新增 _create_named_working_copy_for_review 方法处理送审时的版本复制
- 支持将工作版本快照复制为指定版本进行送审
- 新增 AgentAssetSpreadsheetChangeRecordRead schema
- API 端点新增 /rules/{id}/spreadsheet-versions/{version}/change-records 接口
2026-05-18 09:42:23 +00:00

125 lines
3.3 KiB
JavaScript

function normalizeText(value) {
if (typeof value === 'string') {
return value.trim()
}
if (value === null || value === undefined) {
return ''
}
return String(value).trim()
}
function resolveOperationLabelFromSource(source) {
switch (normalizeText(source).toLowerCase()) {
case 'onlyoffice':
return '在线编辑保存'
case 'content-import':
return '导入表格'
case 'upload':
return '上传表格'
case 'restore':
return '恢复历史版本'
case 'review-submit':
return '提交审核固化'
case 'preview':
return '预览版本'
default:
return ''
}
}
export function resolveSpreadsheetOperationLabel(record) {
const explicitLabel = normalizeText(record?.operationLabel)
if (explicitLabel) {
return explicitLabel
}
const sourceLabel = resolveOperationLabelFromSource(record?.spreadsheetMeta?.source)
if (sourceLabel) {
return sourceLabel
}
const note = normalizeText(record?.note).toLowerCase()
if (note.includes('onlyoffice')) {
return '在线编辑保存'
}
if (note.includes('导入')) {
return '导入表格'
}
if (note.includes('恢复')) {
return '恢复历史版本'
}
if (note.includes('上传')) {
return '上传表格'
}
return '表格修改'
}
function normalizeChangeRecord(record) {
const version = normalizeText(record?.version)
if (!version) {
return null
}
return {
version,
operationLabel: resolveSpreadsheetOperationLabel(record),
operationActor:
normalizeText(record?.operationActor || record?.createdBy || record?.spreadsheetMeta?.updated_by) ||
'系统',
note: normalizeText(record?.note) || '用户修改了表格内容。',
time: normalizeText(record?.time || record?.createdAt || record?.spreadsheetMeta?.updated_at),
isWorking: record?.isWorking !== false,
isPendingLocalEdit: Boolean(record?.isPendingLocalEdit),
disabledReason: normalizeText(record?.disabledReason)
}
}
function toTimestamp(value) {
const normalized = normalizeText(value)
if (!normalized) {
return 0
}
const parsed = Date.parse(normalized)
return Number.isNaN(parsed) ? 0 : parsed
}
function dedupeChangeRecords(records) {
const seen = new Set()
return records.filter((item) => {
const key = [item.version, item.operationLabel, item.note].join('::')
if (seen.has(key)) {
return false
}
seen.add(key)
return true
})
}
export function buildSpreadsheetChangeRecords({
history = [],
localRecords = [],
publishedVersion = '',
limit = 5
} = {}) {
const normalizedPublishedVersion = normalizeText(publishedVersion)
const normalizedHistoryRecords = Array.isArray(history)
? history.map(normalizeChangeRecord).filter(Boolean)
: []
const normalizedLocalRecords = Array.isArray(localRecords)
? localRecords.map(normalizeChangeRecord).filter(Boolean)
: []
const unpublishedHistoryRecords = normalizedHistoryRecords.filter(
(item) => item.version !== normalizedPublishedVersion
)
const preferredHistoryRecords =
unpublishedHistoryRecords.length || !normalizedPublishedVersion
? unpublishedHistoryRecords
: normalizedHistoryRecords
return dedupeChangeRecords([...normalizedLocalRecords, ...preferredHistoryRecords])
.sort((left, right) => toTimestamp(right.time) - toTimestamp(left.time))
.slice(0, limit)
}