feat: 添加风险规则及 agent assets 功能增强

This commit is contained in:
caoxiaozhu
2026-05-19 16:19:03 +00:00
parent d460ee0fe7
commit 54ffef66d3
52 changed files with 26036 additions and 25171 deletions

View File

@@ -7,7 +7,6 @@ import { useSystemState } from '../../composables/useSystemState.js'
import { useToast } from '../../composables/useToast.js'
import {
activateAgentAsset,
compareAgentAssetSpreadsheetVersions,
createAgentAssetReview,
createAgentAssetVersion,
fetchAgentAssetDetail,
@@ -969,6 +968,17 @@ function buildRowMetric(asset, typeKey) {
return normalizeText(asset.config_json?.agent) || '未配置 Agent'
}
function formatSpreadsheetChangeSummary(summary) {
const normalized = normalizeText(summary)
return (
normalized
.replace(/^(ONLYOFFICE\s*)?在线编辑[:]\s*/i, '')
.replace(/^ONLYOFFICE\s*在线编辑保存[。.]?\s*/i, '')
.replace(/^保存表格[:]\s*/i, '')
.trim() || '表格内容已保存。'
)
}
function buildListItem(asset) {
const typeKey = resolveTypeKey(asset.asset_type)
const tabId = resolveTabId(asset, typeKey)
@@ -993,6 +1003,9 @@ function buildListItem(asset) {
: ''
)
const isRiskRule = tabId === 'riskRules'
const usesSpreadsheetRule = typeKey === 'rules' && isSpreadsheetRuleSource(asset)
const usesJsonRiskRule = typeKey === 'rules' && isJsonRiskRuleSource(asset)
const ruleDocument = readRuleDocumentMeta(asset)
const riskCategory = isRiskRule ? resolveRiskRuleCategory(asset) : ''
const listSubtitle = isRiskRule
? buildRiskListSubtitle(asset.description)
@@ -1003,6 +1016,9 @@ function buildListItem(asset) {
tabId,
type: typeKey,
isPreviewMock: Boolean(asset.isPreviewMock),
usesSpreadsheetRule,
usesJsonRiskRule,
ruleDocument,
typeLabel: tabMeta.typeLabel,
short: makeShort(asset.name),
name: asset.name,
@@ -1582,12 +1598,6 @@ export default {
const versionTimelineLoading = ref(false)
const versionTimelineError = ref('')
const versionTimelineItems = ref([])
const versionCompareOpen = ref(false)
const versionCompareLoading = ref(false)
const versionCompareError = ref('')
const versionComparePayload = ref(null)
const compareBaseVersion = ref('')
const compareTargetVersion = ref('')
const spreadsheetChangeRecordsByAsset = ref({})
const spreadsheetChangeDetailOpen = ref(false)
const selectedSpreadsheetChangeRecord = ref(null)
@@ -1595,8 +1605,7 @@ export default {
let spreadsheetOnlyOfficeLoadTimer = null
let spreadsheetOnlyOfficeHadLocalEdits = false
let spreadsheetOnlyOfficeSyncSeq = 0
let spreadsheetOnlyOfficeVersionPollTimer = null
let spreadsheetOnlyOfficeRefreshTimer = null
let spreadsheetOnlyOfficeChangePollTimer = null
const assetBuckets = ref({
financialRules: [],
riskRules: [],
@@ -1649,8 +1658,7 @@ export default {
() =>
canEditSelected.value &&
selectedSkillUsesSpreadsheet.value &&
!detailBusy.value &&
selectedSkill.value?.displayVersion === selectedSkill.value?.workingVersion
!detailBusy.value
)
const canDownloadSpreadsheet = computed(
() =>
@@ -1661,26 +1669,17 @@ export default {
const canEditSpreadsheetInline = computed(
() =>
selectedSkillUsesSpreadsheet.value &&
selectedSkill.value?.displayVersion === selectedSkill.value?.workingVersion &&
(selectedSkill.value?.isPreviewMock || canEditSelected.value)
)
const selectedDisplayHistory = computed(
() =>
selectedSkill.value?.history?.find((item) => item.version === selectedSkill.value?.displayVersion) || null
)
const selectedSpreadsheetFileName = computed(
() =>
normalizeText(
selectedDisplayHistory.value?.spreadsheetMeta?.file_name || selectedSkill.value?.ruleDocument?.file_name
) || '未上传规则表'
normalizeText(selectedSkill.value?.ruleDocument?.file_name) || '未上传规则表'
)
const selectedSpreadsheetVersionModeLabel = computed(() => {
const selectedSpreadsheetModeLabel = computed(() => {
if (selectedSkill.value?.isPreviewMock) {
return canEditSpreadsheetInline.value ? 'ONLYOFFICE 可编辑' : 'ONLYOFFICE 预览'
return canEditSpreadsheetInline.value ? '可编辑' : '只读'
}
return selectedSkill.value?.displayVersion === selectedSkill.value?.workingVersion
? '在线可编辑'
: '只读预览'
return canEditSpreadsheetInline.value ? '在线可编辑' : '只读'
})
const selectedVersionTimelineItems = computed(() =>
versionTimelineItems.value.map((item) => ({
@@ -1709,6 +1708,7 @@ export default {
return {
...item,
time: formatDateTime(item.changed_at),
summary: formatSpreadsheetChangeSummary(item.summary),
changeCountLabel: item.changed_cell_count
? `${item.changed_cell_count} 处改动`
: `${item.changed_sheet_count || changedSheetNames.length || 0} 个工作表`,
@@ -1736,22 +1736,6 @@ export default {
}))
: []
)
const versionCompareCellRows = computed(() =>
Array.isArray(versionComparePayload.value?.cell_changes)
? versionComparePayload.value.cell_changes.map((item) => ({
...item,
meta: resolveDiffChangeMeta(item.change_type)
}))
: []
)
const versionCompareSheetRows = computed(() =>
Array.isArray(versionComparePayload.value?.sheet_changes)
? versionComparePayload.value.sheet_changes.map((item) => ({
...item,
meta: resolveDiffChangeMeta(item.change_type)
}))
: []
)
const detailBusy = computed(() => Boolean(actionState.value))
const showReviewNote = computed(
() => selectedSkillIsRule.value && (selectedSkill.value?.reviewNote || selectedSkill.value?.reviewTimeLabel)
@@ -1922,7 +1906,6 @@ export default {
watch(
() => [
selectedSkill.value?.id || '',
selectedSkill.value?.displayVersion || '',
selectedSkill.value?.loading ? '1' : '0',
selectedSkill.value?.usesSpreadsheetRule ? '1' : '0'
],
@@ -1938,7 +1921,6 @@ export default {
)
watch(activeType, () => {
stopSpreadsheetOnlyOfficeDeferredRefresh()
destroySpreadsheetOnlyOfficeEditor()
selectedSkill.value = null
versionSwitchTarget.value = null
@@ -2034,8 +2016,7 @@ export default {
window.clearTimeout(spreadsheetOnlyOfficeLoadTimer)
spreadsheetOnlyOfficeLoadTimer = null
}
stopSpreadsheetOnlyOfficeVersionSync()
clearSpreadsheetPendingChangeRecord(selectedSkill.value?.id, selectedSkill.value?.displayVersion)
stopSpreadsheetOnlyOfficeChangeSync()
spreadsheetOnlyOfficeHadLocalEdits = false
spreadsheetOnlyOfficeSyncSeq += 1
if (spreadsheetOnlyOfficeEditor.value?.destroyEditor) {
@@ -2045,87 +2026,10 @@ export default {
spreadsheetOnlyOfficeReady.value = false
}
function appendSpreadsheetChangeRecord(record) {
const assetId = normalizeText(record?.assetId)
const version = normalizeText(record?.version)
if (!assetId || !version) {
return
}
const nextRecord = {
version,
operationLabel: normalizeText(record?.operationLabel) || '表格修改',
operationActor: normalizeText(record?.operationActor) || resolveActor(),
note: normalizeText(record?.note) || '用户修改了表格内容。',
time: record?.time || new Date().toISOString(),
isWorking: record?.isWorking !== false,
isPendingLocalEdit: Boolean(record?.isPendingLocalEdit),
disabledReason: normalizeText(record?.disabledReason)
}
const current = spreadsheetChangeRecordsByAsset.value[assetId] || []
const deduped = current.filter(
(item) =>
!(
item.version === nextRecord.version &&
item.operationLabel === nextRecord.operationLabel &&
item.note === nextRecord.note
)
)
spreadsheetChangeRecordsByAsset.value = {
...spreadsheetChangeRecordsByAsset.value,
[assetId]: [nextRecord, ...deduped].slice(0, 30)
}
}
function clearSpreadsheetPendingChangeRecord(assetId, version) {
const normalizedAssetId = normalizeText(assetId)
const normalizedVersion = normalizeText(version)
if (!normalizedAssetId) {
return
}
const current = spreadsheetChangeRecordsByAsset.value[normalizedAssetId] || []
spreadsheetChangeRecordsByAsset.value = {
...spreadsheetChangeRecordsByAsset.value,
[normalizedAssetId]: current.filter(
(item) => !(item.isPendingLocalEdit && (!normalizedVersion || item.version === normalizedVersion))
)
}
}
function markSpreadsheetPendingChange(assetId, version) {
const normalizedAssetId = normalizeText(assetId)
const normalizedVersion = normalizeText(version)
if (!normalizedAssetId || !normalizedVersion) {
return
}
clearSpreadsheetPendingChangeRecord(normalizedAssetId, normalizedVersion)
appendSpreadsheetChangeRecord({
assetId: normalizedAssetId,
version: normalizedVersion,
operationLabel: '编辑中',
operationActor: resolveActor(),
note: '检测到未保存的表格改动,保存后会生成新版本并可查看差异。',
time: new Date().toISOString(),
isWorking: true,
isPendingLocalEdit: true,
disabledReason: '当前是本地未保存修改,保存后才会生成可对比的版本。'
})
}
function stopSpreadsheetOnlyOfficeVersionSync() {
if (spreadsheetOnlyOfficeVersionPollTimer) {
window.clearTimeout(spreadsheetOnlyOfficeVersionPollTimer)
spreadsheetOnlyOfficeVersionPollTimer = null
}
}
function stopSpreadsheetOnlyOfficeDeferredRefresh() {
if (spreadsheetOnlyOfficeRefreshTimer) {
window.clearTimeout(spreadsheetOnlyOfficeRefreshTimer)
spreadsheetOnlyOfficeRefreshTimer = null
function stopSpreadsheetOnlyOfficeChangeSync() {
if (spreadsheetOnlyOfficeChangePollTimer) {
window.clearTimeout(spreadsheetOnlyOfficeChangePollTimer)
spreadsheetOnlyOfficeChangePollTimer = null
}
}
@@ -2164,7 +2068,6 @@ export default {
latest.id,
latest.changed_at,
latest.actor,
latest.version,
latest.summary,
latest.changed_sheet_count,
latest.changed_cell_count,
@@ -2193,36 +2096,14 @@ export default {
return refreshSpreadsheetChangeRecordsAfterSave(normalizedAssetId, previousLatestKey, attempt + 1)
}
function scheduleSpreadsheetEditorRefreshAfterSave(assetId, savedVersion) {
function scheduleSpreadsheetOnlyOfficeChangeSync(assetId, attempt = 0) {
const normalizedAssetId = normalizeText(assetId)
const normalizedSavedVersion = normalizeText(savedVersion)
if (!normalizedAssetId || !normalizedSavedVersion) {
return
}
stopSpreadsheetOnlyOfficeDeferredRefresh()
spreadsheetOnlyOfficeRefreshTimer = window.setTimeout(async () => {
spreadsheetOnlyOfficeRefreshTimer = null
if (
selectedSkill.value?.id !== normalizedAssetId ||
selectedSkill.value?.displayVersion === normalizedSavedVersion
) {
return
}
await loadSelectedAssetDetail(normalizedAssetId)
}, 3200)
}
function scheduleSpreadsheetOnlyOfficeVersionSync(assetId, version, attempt = 0) {
const normalizedAssetId = normalizeText(assetId)
const normalizedVersion = normalizeText(version)
if (!normalizedAssetId || !normalizedVersion) {
if (!normalizedAssetId) {
return
}
const syncSeq = ++spreadsheetOnlyOfficeSyncSeq
stopSpreadsheetOnlyOfficeVersionSync()
stopSpreadsheetOnlyOfficeChangeSync()
const previousLatestChangeKey = getLatestSpreadsheetChangeKey(normalizedAssetId)
const runSync = async () => {
@@ -2231,31 +2112,13 @@ export default {
}
try {
const detail = await fetchAgentAssetDetail(normalizedAssetId)
const nextWorkingVersion = normalizeText(detail?.working_version || detail?.current_version)
if (nextWorkingVersion && nextWorkingVersion !== normalizedVersion) {
clearSpreadsheetPendingChangeRecord(normalizedAssetId, normalizedVersion)
await refreshCurrentAssets()
await refreshSpreadsheetChangeRecordsAfterSave(normalizedAssetId, previousLatestChangeKey)
if (syncSeq !== spreadsheetOnlyOfficeSyncSeq || selectedSkill.value?.id !== normalizedAssetId) {
return
}
// ONLYOFFICE 的保存回调刚结束时立即销毁并重挂编辑器,偶发会让新文档会话
// 还没完全就绪就被再次打开,表现为“加载超时”。先刷新右侧修改记录,再留
// 一个很短的缓冲窗口后切换到新工作版本,用户无需退出重进。
scheduleSpreadsheetEditorRefreshAfterSave(normalizedAssetId, nextWorkingVersion)
stopSpreadsheetOnlyOfficeVersionSync()
return
}
const changeRecordRefreshed = await refreshSpreadsheetChangeRecordsAfterSave(
normalizedAssetId,
previousLatestChangeKey
)
if (changeRecordRefreshed) {
clearSpreadsheetPendingChangeRecord(normalizedAssetId, normalizedVersion)
await refreshCurrentAssets()
stopSpreadsheetOnlyOfficeVersionSync()
stopSpreadsheetOnlyOfficeChangeSync()
return
}
} catch {
@@ -2268,22 +2131,21 @@ export default {
if (attempt >= 29) {
return
}
spreadsheetOnlyOfficeVersionPollTimer = window.setTimeout(() => {
scheduleSpreadsheetOnlyOfficeVersionSync(normalizedAssetId, normalizedVersion, attempt + 1)
spreadsheetOnlyOfficeChangePollTimer = window.setTimeout(() => {
scheduleSpreadsheetOnlyOfficeChangeSync(normalizedAssetId, attempt + 1)
}, 2000)
}
spreadsheetOnlyOfficeVersionPollTimer = window.setTimeout(() => {
spreadsheetOnlyOfficeChangePollTimer = window.setTimeout(() => {
runSync().catch(() => {})
}, attempt === 0 ? 800 : 2000)
}
function isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version) {
function isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId) {
return (
mountSeq !== spreadsheetOnlyOfficeMountSeq ||
!selectedSkillUsesSpreadsheet.value ||
selectedSkill.value?.id !== assetId ||
selectedSkill.value?.displayVersion !== version ||
selectedSkill.value?.loading
)
}
@@ -2296,7 +2158,6 @@ export default {
const mountSeq = ++spreadsheetOnlyOfficeMountSeq
const assetId = selectedSkill.value.id
const version = selectedSkill.value.displayVersion
const editable = canEditSpreadsheetInline.value
spreadsheetOnlyOfficeLoading.value = true
@@ -2305,25 +2166,25 @@ export default {
destroySpreadsheetOnlyOfficeEditor()
try {
const payload = await fetchAgentAssetSpreadsheetOnlyOfficeConfig(assetId, version)
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
const payload = await fetchAgentAssetSpreadsheetOnlyOfficeConfig(assetId)
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
await loadOnlyOfficeApi(payload.documentServerUrl)
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
if (!window.DocsAPI?.DocEditor) {
throw new Error('ONLYOFFICE 编辑器未正确加载。')
throw new Error('表格编辑器未正确加载。')
}
// Host id must be unique for every mount. ONLYOFFICE mutates its host DOM
// during lifecycle teardown; reusing the same element can leave the next
// DocEditor instance with a dead container even though config loading succeeds.
spreadsheetOnlyOfficeHostId.value = `audit-rule-onlyoffice-${assetId}-${version}-${mountSeq}`
spreadsheetOnlyOfficeHostId.value = `audit-rule-onlyoffice-${assetId}-${mountSeq}`
await nextTick()
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
@@ -2334,7 +2195,7 @@ export default {
})
const upstreamEvents = config.events || {}
spreadsheetOnlyOfficeLoadTimer = window.setTimeout(() => {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
if (retryAttempt < 1) {
@@ -2345,14 +2206,14 @@ export default {
}, 600)
return
}
spreadsheetOnlyOfficeError.value = 'ONLYOFFICE 加载超时,请重新切换版本后重试。'
spreadsheetOnlyOfficeError.value = '表格加载超时,请退出详情后重试。'
spreadsheetOnlyOfficeLoading.value = false
destroySpreadsheetOnlyOfficeEditor()
}, 15000)
config.events = {
...upstreamEvents,
onAppReady(event) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
if (spreadsheetOnlyOfficeLoadTimer) {
@@ -2364,7 +2225,7 @@ export default {
upstreamEvents.onAppReady?.(event)
},
onError(event) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
if (spreadsheetOnlyOfficeLoadTimer) {
@@ -2374,8 +2235,8 @@ export default {
const errorCode = event?.data?.errorCode
const errorDescription = event?.data?.errorDescription
spreadsheetOnlyOfficeError.value = errorDescription
? `ONLYOFFICE 加载失败:${errorDescription}`
: `ONLYOFFICE 加载失败${errorCode ? `(错误码 ${errorCode}` : '。'}`
? `表格加载失败:${errorDescription}`
: `表格加载失败${errorCode ? `(错误码 ${errorCode}` : '。'}`
spreadsheetOnlyOfficeLoading.value = false
upstreamEvents.onError?.(event)
},
@@ -2383,17 +2244,16 @@ export default {
const hasChanges = Boolean(event?.data)
if (hasChanges) {
spreadsheetOnlyOfficeHadLocalEdits = true
markSpreadsheetPendingChange(assetId, version)
if (!spreadsheetOnlyOfficeVersionPollTimer) {
scheduleSpreadsheetOnlyOfficeVersionSync(assetId, version)
if (!spreadsheetOnlyOfficeChangePollTimer) {
scheduleSpreadsheetOnlyOfficeChangeSync(assetId)
}
} else if (
spreadsheetOnlyOfficeHadLocalEdits &&
editable &&
!isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)
!isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)
) {
spreadsheetOnlyOfficeHadLocalEdits = false
scheduleSpreadsheetOnlyOfficeVersionSync(assetId, version)
scheduleSpreadsheetOnlyOfficeChangeSync(assetId)
}
upstreamEvents.onDocumentStateChange?.(event)
}
@@ -2402,11 +2262,11 @@ export default {
spreadsheetOnlyOfficeHostId.value,
config
)
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
destroySpreadsheetOnlyOfficeEditor()
}
} catch (error) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId, version)) {
if (isSpreadsheetOnlyOfficeMountStale(mountSeq, assetId)) {
return
}
spreadsheetOnlyOfficeError.value = error?.message || '规则表加载失败,请稍后重试。'
@@ -2431,7 +2291,6 @@ export default {
try {
const blob = await fetchAgentAssetSpreadsheetBlob(
selectedSkill.value.id,
selectedSkill.value.displayVersion,
'attachment'
)
const objectUrl = URL.createObjectURL(blob)
@@ -2462,7 +2321,7 @@ export default {
await refreshCurrentAssets()
await loadSelectedAssetDetail(selectedSkill.value.id)
await loadSpreadsheetChangeRecords(selectedSkill.value.id)
toast(`已导入 ${file.name} 的表格内容,并生成新版本`)
toast(`已导入 ${file.name} 的表格内容,右侧会记录本次修改`)
} catch (error) {
toast(error?.message || '规则表内容导入失败,请稍后重试。')
} finally {
@@ -2560,7 +2419,7 @@ export default {
const detail = await fetchAgentAssetDetail(assetId)
selectedSkill.value = buildDetailViewModel(detail, runs.value)
if (selectedSkill.value?.type === 'rules') {
if (!selectedSkill.value.usesJsonRiskRule) {
if (!selectedSkill.value.usesSpreadsheetRule && !selectedSkill.value.usesJsonRiskRule) {
loadVersionTimeline(assetId, { silent: true }).catch(() => {})
}
if (selectedSkill.value.usesSpreadsheetRule) {
@@ -2677,7 +2536,6 @@ export default {
}
function openAssetDetail(asset) {
stopSpreadsheetOnlyOfficeDeferredRefresh()
destroySpreadsheetOnlyOfficeEditor()
spreadsheetOnlyOfficeError.value = ''
spreadsheetOnlyOfficeLoading.value = false
@@ -2688,17 +2546,18 @@ export default {
versionSwitchTarget.value = null
return
}
const opensSpreadsheetRule = Boolean(asset?.usesSpreadsheetRule)
selectedSkill.value = {
...asset,
configJson: {},
isPreviewMock: false,
usesSpreadsheetRule: false,
usesJsonRiskRule: false,
usesSpreadsheetRule: opensSpreadsheetRule,
usesJsonRiskRule: Boolean(asset?.usesJsonRiskRule),
riskRuleJsonText: '{}',
riskRuleSummary: null,
riskRuleDescription: '',
riskRuleSourceRef: '',
ruleDocument: null,
ruleDocument: asset?.ruleDocument || null,
scenarioList: [],
fields: [],
promptSections: [],
@@ -2714,16 +2573,18 @@ export default {
runtimeKind: 'policy_rule_draft',
displayVersion: asset.version,
displayVersionChangeNote: '无版本说明',
loading: true,
reviewStatusLabel: '加载中',
loading: !opensSpreadsheetRule,
reviewStatusLabel: opensSpreadsheetRule ? '' : '加载中',
reviewStatusTone: 'draft'
}
versionSwitchTarget.value = null
if (opensSpreadsheetRule) {
loadSpreadsheetChangeRecords(asset.id).catch(() => {})
}
loadSelectedAssetDetail(asset.id).catch(() => {})
}
function closeDetail() {
stopSpreadsheetOnlyOfficeDeferredRefresh()
destroySpreadsheetOnlyOfficeEditor()
spreadsheetOnlyOfficeError.value = ''
spreadsheetOnlyOfficeLoading.value = false
@@ -2732,9 +2593,7 @@ export default {
detailLoading.value = false
versionSwitchTarget.value = null
versionTimelineOpen.value = false
versionCompareOpen.value = false
versionTimelineItems.value = []
versionComparePayload.value = null
}
function openVersionSwitch(version) {
@@ -3062,66 +2921,6 @@ export default {
versionTimelineOpen.value = false
}
async function openVersionCompare(options = {}) {
if (!selectedSkill.value?.id) {
return
}
const defaultBase =
options.baseVersion || selectedSkill.value.publishedVersion || selectedSkill.value.workingVersion || ''
let defaultTarget =
options.targetVersion || selectedSkill.value.workingVersion || selectedSkill.value.publishedVersion || ''
if (!options.targetVersion && defaultBase === defaultTarget) {
defaultTarget =
selectedSkill.value.history.find((item) => item.version !== defaultBase)?.version || defaultTarget
}
compareBaseVersion.value = defaultBase
compareTargetVersion.value = defaultTarget
versionCompareOpen.value = true
await loadVersionCompare()
}
function openSpreadsheetChangeRecord(item) {
if (selectedSkill.value?.isPreviewMock) {
toast('预览数据暂不支持真实的线上差异对比。')
return
}
const publishedVersion = normalizeText(selectedSkill.value?.publishedVersion)
if (!selectedSkill.value?.id || !publishedVersion || publishedVersion === '-') {
toast('当前还没有线上版本,暂时无法查看与线上差异。')
return
}
openVersionCompare({
baseVersion: publishedVersion,
targetVersion: item.version
}).catch(() => {})
}
function closeVersionCompare() {
versionCompareOpen.value = false
}
async function loadVersionCompare() {
if (!selectedSkill.value?.id || !compareBaseVersion.value || !compareTargetVersion.value) {
return
}
versionCompareLoading.value = true
versionCompareError.value = ''
try {
versionComparePayload.value = await compareAgentAssetSpreadsheetVersions(
selectedSkill.value.id,
compareBaseVersion.value,
compareTargetVersion.value
)
} catch (error) {
versionComparePayload.value = null
versionCompareError.value = error?.message || '版本差异对比失败,请稍后重试。'
} finally {
versionCompareLoading.value = false
}
}
onMounted(() => {
document.addEventListener('click', handleDocumentClick)
loadAssets({ force: true }).catch(() => {})
@@ -3129,7 +2928,6 @@ export default {
})
onBeforeUnmount(() => {
stopSpreadsheetOnlyOfficeDeferredRefresh()
destroySpreadsheetOnlyOfficeEditor()
document.removeEventListener('click', handleDocumentClick)
})
@@ -3186,7 +2984,7 @@ export default {
selectedSkillUsesSpreadsheet,
selectedSkillUsesJsonRisk,
selectedSpreadsheetFileName,
selectedSpreadsheetVersionModeLabel,
selectedSpreadsheetModeLabel,
selectedVersionTimelineItems,
selectedSpreadsheetChangeRecords,
detailBusy,
@@ -3205,18 +3003,10 @@ export default {
versionTimelineOpen,
versionTimelineLoading,
versionTimelineError,
versionCompareOpen,
versionCompareLoading,
versionCompareError,
versionComparePayload,
versionCompareCellRows,
versionCompareSheetRows,
spreadsheetChangeDetailOpen,
selectedSpreadsheetChangeRecord,
selectedSpreadsheetChangeSheetRows,
selectedSpreadsheetChangeCellRows,
compareBaseVersion,
compareTargetVersion,
openAssetDetail,
closeDetail,
resetFilters,
@@ -3243,12 +3033,8 @@ export default {
restoreSelectedVersion,
openVersionTimeline,
closeVersionTimeline,
openSpreadsheetChangeRecord,
openSpreadsheetChangeDetail,
closeSpreadsheetChangeDetail,
openVersionCompare,
closeVersionCompare,
loadVersionCompare,
loadAssets
}
}

File diff suppressed because it is too large Load Diff