206 lines
6.6 KiB
JavaScript
206 lines
6.6 KiB
JavaScript
import {
|
|
resolveRiskRuleScoreLabel,
|
|
resolveRiskRuleScoreLevel,
|
|
resolveRiskRuleSeverity,
|
|
resolveRiskRuleSeverityLabel
|
|
} from './auditViewRiskRuleModel.js'
|
|
import { normalizeText } from './auditViewDataUtils.js'
|
|
import {
|
|
formatDateTime,
|
|
formatScenarioList,
|
|
formatSeverity,
|
|
makeShort,
|
|
resolveDomainLabel,
|
|
resolveStatusMeta,
|
|
resolveTypeKey
|
|
} from './auditViewFormatters.js'
|
|
import {
|
|
buildRiskListSubtitle,
|
|
isJsonRiskRuleSource,
|
|
isSpreadsheetRuleSource,
|
|
readRuleDocumentMeta,
|
|
resolveRuleScenarioCategory,
|
|
resolveRuleScenarioList,
|
|
resolveTabId,
|
|
resolveTabMeta
|
|
} from './auditViewRuleClassifier.js'
|
|
import {
|
|
resolveRiskRuleBusinessStage,
|
|
resolveRiskRuleEnabled,
|
|
resolveRiskRuleOnlineMeta
|
|
} from './auditViewRiskRuleState.js'
|
|
export function findLatestMcpCall(runs, assetCode) {
|
|
const expectedToolName = normalizeText(assetCode).replace(/^mcp\./, '')
|
|
|
|
for (const run of runs) {
|
|
for (const toolCall of run.tool_calls || []) {
|
|
const toolName = normalizeText(toolCall.tool_name)
|
|
if (
|
|
toolName === expectedToolName ||
|
|
toolName.endsWith(expectedToolName) ||
|
|
expectedToolName.endsWith(toolName)
|
|
) {
|
|
return {
|
|
run,
|
|
toolCall
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function buildRowRuntime(asset, typeKey) {
|
|
if (typeKey === 'rules') {
|
|
return formatSeverity(asset.config_json?.severity)
|
|
}
|
|
if (typeKey === 'mcp') {
|
|
return normalizeText(asset.config_json?.endpoint) || '未配置地址'
|
|
}
|
|
return ''
|
|
}
|
|
|
|
export function buildRowMetric(asset, typeKey) {
|
|
if (typeKey === 'rules') {
|
|
return normalizeText(asset.modified_by) || '未记录'
|
|
}
|
|
if (typeKey === 'mcp') {
|
|
return asset.config_json?.timeout_ms ? `${asset.config_json.timeout_ms} ms` : '未配置超时'
|
|
}
|
|
return ''
|
|
}
|
|
|
|
|
|
export function buildListItem(asset) {
|
|
const typeKey = resolveTypeKey(asset.asset_type)
|
|
const tabId = resolveTabId(asset, typeKey)
|
|
if (!tabId) {
|
|
return null
|
|
}
|
|
|
|
const tabMeta = resolveTabMeta(tabId, typeKey)
|
|
const statusMeta = resolveStatusMeta(asset.status)
|
|
const workingVersion = asset.working_version || asset.current_version || '-'
|
|
const changeCount =
|
|
typeof asset.change_count === 'number'
|
|
? asset.change_count
|
|
: Array.isArray(asset.recent_versions)
|
|
? Math.max(asset.recent_versions.length - 1, 0)
|
|
: 0
|
|
const modifiedBy =
|
|
normalizeText(asset.modified_by) ||
|
|
normalizeText(
|
|
Array.isArray(asset.recent_versions)
|
|
? asset.recent_versions.find((item) => item.version === workingVersion)?.created_by
|
|
: ''
|
|
)
|
|
const isRiskRule = tabId === 'riskRules'
|
|
const usesSpreadsheetRule = typeKey === 'rules' && isSpreadsheetRuleSource(asset)
|
|
const usesJsonRiskRule = typeKey === 'rules' && isJsonRiskRuleSource(asset)
|
|
const ruleDocument = readRuleDocumentMeta(asset)
|
|
const ruleScenarioCategory = typeKey === 'rules' ? resolveRuleScenarioCategory(asset, tabId) : ''
|
|
const listSubtitle = isRiskRule
|
|
? buildRiskListSubtitle(asset.description)
|
|
: normalizeText(asset.description)
|
|
const onlineMeta = resolveRiskRuleOnlineMeta(asset.status)
|
|
const isOnlineValue = onlineMeta.online
|
|
const isEnabledValue = usesJsonRiskRule ? resolveRiskRuleEnabled(asset) : true
|
|
const reviewer = normalizeText(asset.reviewer) || '待分配'
|
|
const creator =
|
|
normalizeText(asset.owner) ||
|
|
normalizeText(asset.config_json?.generation_request?.actor) ||
|
|
modifiedBy ||
|
|
'未知'
|
|
const publisher = isRiskRule ? creator : ''
|
|
const riskRuleCreatedAt = formatDateTime(asset.created_at || asset.updated_at)
|
|
const businessStage = usesJsonRiskRule
|
|
? resolveRiskRuleBusinessStage(asset)
|
|
: { value: '', label: '' }
|
|
const ruleScenarioList = typeKey === 'rules' ? resolveRuleScenarioList(asset, tabId) : []
|
|
const riskScoreLevel = usesJsonRiskRule
|
|
? resolveRiskRuleScoreLevel(asset.config_json, asset.config_json)
|
|
: ''
|
|
const riskLevelValue = usesJsonRiskRule
|
|
? riskScoreLevel || resolveRiskRuleSeverity(asset.config_json)
|
|
: ''
|
|
const riskLevelLabel = usesJsonRiskRule
|
|
? riskScoreLevel
|
|
? resolveRiskRuleScoreLabel(asset.config_json, asset.config_json) || resolveRiskRuleSeverityLabel(asset.config_json)
|
|
: resolveRiskRuleSeverityLabel(asset.config_json)
|
|
: ''
|
|
const displayName = asset.name
|
|
const displayCode = asset.code
|
|
const displaySummary = listSubtitle
|
|
const displayOwner = isRiskRule ? creator : asset.owner
|
|
const displayReviewer = reviewer
|
|
const displayCategory = resolveDomainLabel(asset.domain)
|
|
const displayScope = typeKey === 'rules' ? ruleScenarioCategory || '通用' : formatScenarioList(asset.scenario_json)
|
|
const displayEnabledValue = isEnabledValue
|
|
const displayEnabledLabel = isEnabledValue ? '是' : '否'
|
|
const displayEnabledTone = isEnabledValue ? 'success' : 'disabled'
|
|
const searchText = [
|
|
displayName,
|
|
displayCode,
|
|
displaySummary,
|
|
displayOwner,
|
|
displayScope,
|
|
riskLevelLabel
|
|
]
|
|
.map((value) => normalizeText(value).toLowerCase())
|
|
.filter(Boolean)
|
|
.join(' ')
|
|
|
|
return {
|
|
id: asset.id,
|
|
tabId,
|
|
type: typeKey,
|
|
isPreviewMock: Boolean(asset.isPreviewMock),
|
|
usesSpreadsheetRule,
|
|
usesJsonRiskRule,
|
|
ruleDocument,
|
|
typeLabel: tabMeta.typeLabel,
|
|
short: makeShort(displayName),
|
|
name: displayName,
|
|
code: displayCode,
|
|
rawCode: asset.code,
|
|
summary: displaySummary,
|
|
listSubtitle: displaySummary,
|
|
category: displayCategory,
|
|
owner: displayOwner,
|
|
reviewer: displayReviewer,
|
|
scope: displayScope,
|
|
riskCategory: ruleScenarioCategory,
|
|
scenarioList: ruleScenarioList,
|
|
businessStageValue: businessStage.value,
|
|
businessStageLabel: businessStage.label,
|
|
riskLevelValue,
|
|
riskLevelLabel,
|
|
riskLevelTone: riskLevelValue,
|
|
model: buildRowRuntime(asset, typeKey),
|
|
version: workingVersion,
|
|
versionDisplay: typeKey === 'rules' ? `${changeCount} 次` : workingVersion,
|
|
publishedVersion: asset.published_version || '-',
|
|
workingVersion,
|
|
status: statusMeta.label,
|
|
statusValue: asset.status,
|
|
statusTone: statusMeta.tone,
|
|
hitRate: isRiskRule ? publisher : buildRowMetric({ ...asset, modified_by: modifiedBy }, typeKey),
|
|
creator,
|
|
publisher,
|
|
publishedAt: isOnlineValue ? formatDateTime(asset.published_at || asset.updated_at) : '-',
|
|
isOnlineValue,
|
|
isOnlineLabel: onlineMeta.label,
|
|
isOnlineTone: onlineMeta.tone,
|
|
isEnabledValue: displayEnabledValue,
|
|
isEnabledLabel: displayEnabledLabel,
|
|
isEnabledTone: displayEnabledTone,
|
|
modifiedBy,
|
|
changeCount,
|
|
updatedAt: isRiskRule ? riskRuleCreatedAt : formatDateTime(asset.updated_at),
|
|
badgeTone: tabMeta.badgeTone,
|
|
domainValue: asset.domain,
|
|
searchText
|
|
}
|
|
}
|