Files
railwaysystem/build_ui/src/views/train/auth/authFeedback.js
T

189 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 门禁凭据与对账交互端点前端结果语义解析器 (Package A.3 - MAJ-05)
*
* 核心原则:
* 1. 杜绝依赖 AjaxResult 顶层 res.msg (防止“操作成功”假成功);
* 2. 严格按后端 DTO 真实契约解析 (ReconciliationResult, IssueResultVO);
* 3. 严禁对排队、未执行、部分失败或人工对账展示“成功”。
*/
/**
* 解析门禁注销操作结果反馈 (POST /train/access/auth/{authId}/revoke)
* @param {Object} data - res.data (ReconciliationResult)
* @returns {{ type: 'success'|'info'|'warning'|'error', message: string }}
*/
export function resolveRevokeFeedback(data) {
const d = data || {}
const decision = d.decision || ''
const success = d.success === true
const externalInvoked = d.externalInvoked === true
const reason = d.reason || ''
// 1. decision == NO_ACTION && success == true -> 无需操作或已处于安全终态 (info/success)
if (decision === 'NO_ACTION' && success) {
return {
type: 'info',
message: reason || '无需操作或已处于安全终态'
}
}
// 2. decision == REVOKE_REQUIRED && success == true && externalInvoked == true
if (decision === 'REVOKE_REQUIRED' && success && externalInvoked) {
return {
type: 'info',
message: '注销请求已提交,等待设备确认。'
}
}
// 3. decision == REVOKE_REQUIRED && success == true && externalInvoked == false
if (decision === 'REVOKE_REQUIRED' && success && !externalInvoked) {
return {
type: 'warning',
message: reason || '当前未执行外部注销,等待DMS恢复或后续处理。'
}
}
// 4. decision == FAILED || success == false -> error 直接展示 reason
if (decision === 'FAILED' || !success) {
return {
type: 'error',
message: reason || '门禁注销失败'
}
}
// 安全兜底
return {
type: 'info',
message: reason || '注销请求已提交'
}
}
/**
* 解析门禁凭据显式下发结果反馈 (POST /train/access/auth/{authId}/issue)
* @param {Object} data - res.data (IssueResultVO)
* @returns {{ type: 'success'|'warning'|'error', message: string, openCredentialDialog: boolean }}
*/
export function resolveIssueFeedback(data) {
const d = data || {}
const status = d.status || ''
const message = d.message || ''
const hasCredential = Boolean(d.oneTimePlaintextCredential && String(d.oneTimePlaintextCredential).trim().length > 0)
// 1. ACCEPTED: 仅在有 credential 时才允许弹窗;提示“凭据已提交下发,设备确认后生效。”
if (status === 'ACCEPTED') {
return {
type: 'success',
message: '凭据已提交下发,设备确认后生效。',
openCredentialDialog: hasCredential
}
}
// 2. WAITING_FOR_PREREQUISITE (包含 MISSING_STUDENT_PHONE, INVALID_VALIDITY_WINDOW, DMS_DISABLED 等真实 reason)
if (status === 'WAITING_FOR_PREREQUISITE') {
return {
type: 'warning',
message: message || '前置条件未满足,暂无法下发门禁凭据',
openCredentialDialog: false
}
}
// 3. AMBIGUOUS_EXTERNAL_MUTATION: 不得允许直接重发
if (status === 'AMBIGUOUS_EXTERNAL_MUTATION' || status === 'AMBIGUOUS') {
return {
type: 'error',
message: message || '上一次下发结果无法确认,禁止重复下发,请先核对厂商侧凭据。(AMBIGUOUS_EXTERNAL_MUTATION)',
openCredentialDialog: false
}
}
// 4. FAILED 或其他错误
return {
type: 'error',
message: message || '门禁凭据下发失败',
openCredentialDialog: false
}
}
/**
* 解析门禁手动对账结果反馈 (POST /train/access/reconcile/{enrollmentId})
* @param {Object} data - res.data (ReconciliationResult)
* @returns {{ type: 'success'|'info'|'warning'|'error', message: string, openCredentialDialog: boolean }}
*/
export function resolveReconcileFeedback(data) {
const d = data || {}
const batchResult = d.batchResult || null
const outcome = (batchResult && batchResult.outcome) || d.outcome || (d.decision === 'NO_ACTION' ? 'ALL_SETTLED' : '')
const reason = d.reason || ''
const hasCredential = Boolean(d.oneTimePlaintextCredential && String(d.oneTimePlaintextCredential).trim().length > 0)
// 1. ALL_SETTLED -> success
if (outcome === 'ALL_SETTLED') {
return {
type: 'success',
message: reason || '对账完成:所有授权均已处于安全终态或无需操作',
openCredentialDialog: hasCredential
}
}
// 2. IN_PROGRESS -> info
if (outcome === 'IN_PROGRESS') {
return {
type: 'info',
message: reason || '对账处理中:指令已派发至外部设备,等待设备确认',
openCredentialDialog: hasCredential
}
}
// 3. WAITING_FOR_DMS -> warning
if (outcome === 'WAITING_FOR_DMS') {
return {
type: 'warning',
message: reason || '门禁系统当前未启用,操作已排队等待DMS恢复后处理',
openCredentialDialog: hasCredential
}
}
// 4. PARTIAL_FAILURE -> error (明确“部分处理失败”,严禁报对账成功)
if (outcome === 'PARTIAL_FAILURE') {
return {
type: 'error',
message: reason ? ('部分处理失败:' + reason) : '对账完成:部分授权处理失败,需关注处理',
openCredentialDialog: false
}
}
// 5. ALL_FAILED -> error
if (outcome === 'ALL_FAILED') {
return {
type: 'error',
message: reason ? ('对账处理失败:' + reason) : '对账执行失败:所有授权操作均失败',
openCredentialDialog: false
}
}
// 6. REQUIRES_MANUAL_SETTLEMENT -> error (明确“需要人工核对厂商侧状态”)
if (outcome === 'REQUIRES_MANUAL_SETTLEMENT') {
return {
type: 'error',
message: reason ? ('需要人工核对厂商侧状态:' + reason) : '需要人工核对厂商侧状态:外部凭据状态不确定,阻断自动处理',
openCredentialDialog: false
}
}
// 7. 兜底逻辑:若明确 success == false
if (d.success === false) {
return {
type: 'error',
message: reason || '对账执行未成功',
openCredentialDialog: false
}
}
// 8. 默认中性提示
return {
type: 'info',
message: reason || '对账执行完成',
openCredentialDialog: hasCredential
}
}