Files
jizhi/frontend/lib/shared/services/recognition_diagnostic_formatter.dart
T

186 lines
7.3 KiB
Dart

import 'package:miaoji_zhang/shared/services/screenshot_channel.dart';
class RecognitionDiagnosticDisplay {
final String stageLabel;
final String resultLabel;
final String summaryLabel;
final String reasonLabel;
final String? recognitionKindLabel;
final String? amountSourceLabel;
final String? statusStrengthLabel;
final bool statusStrengthPositive;
const RecognitionDiagnosticDisplay({
required this.stageLabel,
required this.resultLabel,
required this.summaryLabel,
required this.reasonLabel,
this.recognitionKindLabel,
this.amountSourceLabel,
this.statusStrengthLabel,
this.statusStrengthPositive = false,
});
factory RecognitionDiagnosticDisplay.from(RecognitionDiagnostic diagnostic) {
final reason = diagnostic.reason;
return RecognitionDiagnosticDisplay(
stageLabel: _stageLabel(diagnostic.stage),
resultLabel: _resultLabel(diagnostic.result),
summaryLabel: _summaryLabel(diagnostic.result, reason),
reasonLabel: _reasonLabel(reason),
recognitionKindLabel: _recognitionKindLabel(diagnostic.recognitionKind),
amountSourceLabel: _amountSourceLabel(diagnostic.amountSource),
statusStrengthLabel: _statusStrengthLabel(diagnostic.statusStrength),
statusStrengthPositive: diagnostic.statusStrength == 'strong',
);
}
static String _stageLabel(String value) {
return switch (value) {
'capture' => '本地截屏',
'ocr' => '本地 OCR',
'tree' => '控件树识别',
_ => '无障碍事件',
};
}
static String _resultLabel(String value) {
return switch (value) {
'matched' || 'auto_ready' => '已识别',
'confirm' => '待确认',
'started' => '处理中',
'waiting' => '等待结果页',
'failed' => '失败',
_ => '未触发入账',
};
}
static String _summaryLabel(String result, String reason) {
if (reason == 'duplicate_result_surface') return '已合并';
if (result == 'waiting') return '等待结果页';
if (_captureFailureReasons.contains(reason)) return '截图失败';
if (_ocrNoResultReasons.contains(reason)) return 'OCR 无结果';
if (_ruleRejectedReasons.contains(reason) || result == 'rejected') {
return '规则拒绝';
}
return switch (result) {
'matched' || 'auto_ready' => '已识别',
'confirm' => '待确认',
'started' => '处理中',
'waiting' => '等待结果页',
'failed' => '失败',
_ => '没事件',
};
}
static String _reasonLabel(String reason) {
return switch (reason) {
'history_page' => '当前是账单或交易历史页',
'blocked_status' => '当前状态为失败、处理中或已取消',
'no_text' => '截图中没有识别到文字',
'no_success_status' => '暂未找到完成状态,正在按计划复核结果页',
'payment_input_page' => '当前仍是付款输入或确认页面,等待结果页,不会提前入账',
'result_page_timeout' => '90 秒内未等到明确结果页,本次流程已停止追踪',
'direction_unknown' => '识别到完成状态,但无法确认收支方向',
'missing_amount' => '成功状态已识别,但没有找到金额',
'expected_amount_missing' => '结果页没有金额,且付款前金额不唯一或未捕获',
'expected_amount_fallback' => '结果页未读到金额,已使用本次付款流程确认的金额',
'weak_expected_fallback' => '结果页未读到金额,付款前金额来源不可靠,请确认后入账',
'result_amount_conflict' => '结果页金额与本次付款金额不一致,请确认后入账',
'amount_source_untrusted' => '金额无法与当前付款流程可靠关联,请确认后入账',
'red_packet_not_settled' => '红包尚未明确到账或退回,不会自动入账',
'duplicate_result_surface' => '同一结果页已处理,本次刷新已忽略',
'weak_status_confirm' => '只识别到弱完成状态,组合证据不足,需确认后入账',
'combined_high_confidence' => '弱完成状态已通过流程、跳转和金额组合校验',
'ambiguous_or_unarmed' => '金额存在歧义或未捕获到完整支付流程',
'secure_window' => '当前页面被系统禁止截屏',
'window_fallback' => '单窗口截图失败,正在切换整屏截图',
'invalid_window' => '支付页面窗口已切换,单窗口截图已失效',
'internal_error' => '系统单窗口截图失败,请停留在成功页重试',
'display_capture_start_failed' => '整屏截图请求无法启动',
'invalid_display' => '当前屏幕暂时无法截取',
'capture_timeout' => '系统截屏长时间没有返回结果,已自动结束',
'capture_start_failed' => '系统截屏请求无法启动',
'ocr_timeout' => '本地 OCR 超时,已自动结束,可在支付成功页重试',
'ocr_start_failed' => '本地 OCR 请求无法启动',
'ocr_init_failed' => '本地 OCR 组件初始化失败,请重新开启无障碍服务',
'ocr_model_unavailable' => '本地中文识别模型不可用,请重新安装内测包',
'ocr_unavailable' => '本地 OCR 服务暂不可用,请稍后重试',
'ocr_failed' => '本地 OCR 识别失败,请停留在支付成功页重试',
'ocr_parse_failed' => '本地 OCR 结果处理失败',
'operation_interrupted' => '识别进程曾被系统中断,任务已自动结束',
'interval_short' => '系统限制了过于频繁的截屏',
'accessibility_unavailable' => '无障碍截屏能力暂不可用',
'image_encode_failed' => '截图结果编码失败,请重试',
'success' || 'high_confidence' => '成功状态和金额均已确认',
_ => reason.isEmpty ? '等待新的支付事件' : reason,
};
}
static String? _recognitionKindLabel(String? value) {
return switch (value) {
'payment' => '扫码支付',
'transfer' => '转账',
'red_packet_send' => '发出红包',
'red_packet_receive' => '红包到账',
'red_packet_refund' => '红包退回',
_ => null,
};
}
static String? _amountSourceLabel(String? value) {
return switch (value) {
'expected' => '使用本次付款金额',
'result' => '使用结果页金额',
_ => null,
};
}
static String? _statusStrengthLabel(String value) {
return switch (value) {
'strong' => '明确成功状态',
'weak' => '弱完成状态',
_ => null,
};
}
static const _captureFailureReasons = {
'secure_window',
'invalid_window',
'internal_error',
'display_capture_start_failed',
'invalid_display',
'capture_timeout',
'capture_start_failed',
'interval_short',
'accessibility_unavailable',
'image_encode_failed',
};
static const _ocrNoResultReasons = {
'no_text',
'ocr_timeout',
'ocr_start_failed',
'ocr_init_failed',
'ocr_model_unavailable',
'ocr_unavailable',
'ocr_failed',
'ocr_parse_failed',
};
static const _ruleRejectedReasons = {
'history_page',
'blocked_status',
'result_page_timeout',
'direction_unknown',
'missing_amount',
'expected_amount_missing',
'red_packet_not_settled',
'weak_status_confirm',
'ambiguous_or_unarmed',
'weak_expected_fallback',
'result_amount_conflict',
'amount_source_untrusted',
};
}