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, options = {}) { const silent = Boolean(options.silent) if (!silent) { 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) { const message = error?.message || '资产详情加载失败,请稍后重试。' if (silent) { console.warn('Silent asset detail refresh failed:', error) } else { detailError.value = message toast(message) } } finally { if (!silent) { 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 } }