refactor(audit): split list detail flows

This commit is contained in:
caoxiaozhu
2026-05-29 09:44:03 +08:00
parent 064eeb614f
commit 99e90798d2
28 changed files with 2636 additions and 2142 deletions

View File

@@ -0,0 +1,214 @@
import { computed, ref } from 'vue'
import {
fetchAgentAssetDetail,
fetchAgentAssets,
fetchAgentRuns
} from '../../services/agentAssets.js'
import {
buildDetailViewModel,
buildListItem
} from './auditViewModel.js'
export function useAuditAssetData({
activeType,
activeMeta,
selectedSkill,
loadVersionTimeline,
loadSpreadsheetChangeRecords,
loadRiskRuleJson,
toast
}) {
const loading = ref(false)
const errorMessage = ref('')
const detailLoading = ref(false)
const detailError = ref('')
const runLoading = ref(false)
const runs = ref([])
const assetBuckets = ref({
financialRules: [],
riskRules: [],
mcp: []
})
const currentAssets = computed(() => assetBuckets.value[activeType.value] || [])
async function loadRuns(options = {}) {
if (runLoading.value && !options.force) {
return
}
runLoading.value = true
try {
const payload = await fetchAgentRuns({ limit: 50 })
runs.value = Array.isArray(payload) ? payload : []
} finally {
runLoading.value = false
}
}
async function loadAssets(options = {}) {
const shouldShowLoading = !options.silent && !options.background
if (shouldShowLoading) {
loading.value = true
}
if (!options.silent) {
errorMessage.value = ''
}
try {
const payload = await fetchAgentAssets({ assetType: activeMeta.value.assetType })
const items = Array.isArray(payload) ? payload.map(buildListItem).filter(Boolean) : []
if (activeMeta.value.assetType === 'rule') {
const nextBuckets = {
financialRules: [],
riskRules: []
}
items.forEach((item) => {
if (item?.tabId === 'financialRules' || item?.tabId === 'riskRules') {
nextBuckets[item.tabId].push(item)
}
})
assetBuckets.value = {
...assetBuckets.value,
...nextBuckets
}
} else {
assetBuckets.value = {
...assetBuckets.value,
[activeType.value]: items
}
}
} catch (error) {
if (options.silent || options.background) {
return
}
if (activeMeta.value.assetType === 'rule') {
assetBuckets.value = {
...assetBuckets.value,
financialRules:
activeType.value === 'financialRules' ? [] : assetBuckets.value.financialRules,
riskRules: []
}
} else {
assetBuckets.value = {
...assetBuckets.value,
[activeType.value]: []
}
}
errorMessage.value = error?.message || '资产数据加载失败,请稍后重试。'
toast(errorMessage.value)
} finally {
if (shouldShowLoading) {
loading.value = false
}
}
}
async function refreshCurrentAssets() {
await loadAssets({ force: true, silent: true, background: true })
}
async function loadSelectedAssetDetail(assetId) {
detailLoading.value = true
detailError.value = ''
try {
if (!runs.value.length) {
await loadRuns()
}
const detail = await fetchAgentAssetDetail(assetId)
selectedSkill.value = buildDetailViewModel(detail, runs.value)
if (selectedSkill.value?.type !== 'rules') {
return
}
if (!selectedSkill.value.usesSpreadsheetRule && !selectedSkill.value.usesJsonRiskRule) {
loadVersionTimeline(assetId, { silent: true }).catch(() => {})
}
if (selectedSkill.value.usesSpreadsheetRule) {
loadSpreadsheetChangeRecords(assetId).catch(() => {})
}
if (!selectedSkill.value.usesJsonRiskRule) {
return
}
if (selectedSkill.value.riskRuleGenerationFailed || selectedSkill.value.riskRuleGenerationBusy) {
return
}
try {
await loadRiskRuleJson(assetId)
} catch (jsonError) {
console.warn('Failed to load risk rule JSON:', jsonError)
const jsonMessage =
jsonError?.message || '风险规则 JSON 文件缺失或无法读取,请同步规则库后重试。'
toast(jsonMessage)
selectedSkill.value = {
...selectedSkill.value,
riskRuleJsonText: '{}',
riskRuleDescription:
selectedSkill.value.riskRuleDescription ||
'规则 JSON 尚未就绪,请联系管理员执行平台风险规则同步。'
}
}
} catch (error) {
detailError.value = error?.message || '资产详情加载失败,请稍后重试。'
toast(detailError.value)
} finally {
detailLoading.value = false
}
}
function mergeSelectedRuleLifecycle(detail) {
if (!selectedSkill.value || !detail) {
return
}
const next = buildDetailViewModel(detail, runs.value)
selectedSkill.value = {
...selectedSkill.value,
status: next.status,
statusValue: next.statusValue,
statusTone: next.statusTone,
publishedVersion: next.publishedVersion,
workingVersion: next.workingVersion,
currentVersion: next.currentVersion,
displayVersion: next.displayVersion,
reviewer: next.reviewer,
publisher: next.publisher,
publishedAt: next.publishedAt,
isOnlineValue: next.isOnlineValue,
isOnlineLabel: next.isOnlineLabel,
isOnlineTone: next.isOnlineTone,
isEnabledValue: next.isEnabledValue,
isEnabledLabel: next.isEnabledLabel,
isEnabledTone: next.isEnabledTone,
latestTestSummary: next.latestTestSummary,
lastOperationLabel: next.lastOperationLabel,
lastOperationTone: next.lastOperationTone,
publishMeta: next.publishMeta,
publishState: next.publishState,
updatedAt: next.updatedAt,
configJson: next.configJson
}
}
return {
loading,
errorMessage,
detailLoading,
detailError,
runLoading,
runs,
assetBuckets,
currentAssets,
loadRuns,
loadAssets,
refreshCurrentAssets,
loadSelectedAssetDetail,
mergeSelectedRuleLifecycle
}
}