Files
airz-uniapp/packages/finance/services/compare.uts
T
hujun 71b3c25695 feat: 优化账户切换时的页面状态一致性,增加登录回跳校验和课程阅读新逻辑
- 增加账户状态监听定时器,页面切换时自动校验账户归属,避免跨账户操作
- 新增登录回跳路径校验函数,限制仅允许指定页面回跳,防止非法跳转
- 课程页改为整篇连续阅读,底部仅一次标记已读,兼容历史记录
- 完善助手、对比页、资料填写页等多处的账户状态校验逻辑,防止错版数据提交
- 优化账户资料请求逻辑,增加版本校验,避免旧请求覆盖新数据
2026-10-07 10:01:05 +08:00

53 lines
3.5 KiB
Plaintext

import { getSession } from '@/services/api.uts'
import { validRecordId, MatchDetail, MatchReason } from './matches.uts'
let scope = ''
let selected: string[] = []
export function parseCompareIds(raw: string): string[] {
if (raw.length == 0) return []
const ids = raw.split(',')
if (ids.length > 3) throw new Error('每次最多对比3个产品,请返回重新选择。')
const seen: string[] = []
ids.forEach((id: string) => {
if (!validRecordId(id) || seen.includes(id)) throw new Error('对比产品编号无效或重复,请返回重新选择。')
seen.push(id)
})
return ids
}
// 只缓存少量选择ID,不持久化产品或个人事实;换账号、会话或评估后立即隔离。
export function compareSelection(assessmentId: string, revisionId: string = ''): string[] {
const session = getSession()
const key = session == null ? '' : (session.getString('userId') ?? '') + ':' + (session.getString('token') ?? '') + ':' + assessmentId + ':' + revisionId
if (key != scope || key.length == 0) { scope = key; selected = [] }
return selected.slice()
}
export function saveCompareSelection(assessmentId: string, ids: string[], revisionId: string = ''): void {
compareSelection(assessmentId, revisionId)
selected = parseCompareIds(ids.join(','))
}
export function compareQuery(assessmentId: string, ids: string[], revisionId: string = ''): string {
return '?assessmentId=' + encodeURIComponent(assessmentId) + '&productIds=' + ids.join(',') + (revisionId.length > 0 ? '&revisionId=' + revisionId : '')
}
// 登录回跳只接受已声明页面与编号,不接受任意URL。
export function matchReturnPath(page: string, assessmentId: string, rawIds: string, revisionId: string, productId: string = '', group: string = 'eligible', tab: string = 'explanation', from: string = ''): string {
if (!['matches','product','compare'].includes(page) || (revisionId.length > 0 && !validRecordId(revisionId))) return ''
if (assessmentId.length > 0 ? !validRecordId(assessmentId) : page != 'product') return ''
let ids: string[] = []
try { ids = parseCompareIds(rawIds) } catch (err) { return '' }
if (assessmentId.length == 0 && (revisionId.length > 0 || ids.length > 0)) return ''
if (page == 'matches' && !['eligible','ineligible','unknown'].includes(group)) return ''
if (page == 'product' && (!validRecordId(productId) || !['explanation','details','conditions'].includes(tab) || (assessmentId.length == 0 && tab == 'explanation') || !['','matches','product','compare','report','next-step','archive'].includes(from))) return ''
const query = assessmentId.length > 0 ? compareQuery(assessmentId, ids, revisionId) : '?'
if (page == 'matches') return '/packages/finance/matches/matches' + query + '&group=' + group
if (page == 'compare') return '/packages/finance/compare/compare' + query
return '/packages/finance/product/product' + query + (assessmentId.length > 0 ? '&' : '') + 'productId=' + productId + '&tab=' + tab + '&from=' + from
}
export function sameMatchSnapshot(a: MatchDetail, b: MatchDetail): boolean {
return a.assessmentId == b.assessmentId && a.revisionId == b.revisionId && a.resultVersion == b.resultVersion && a.snapshotId == b.snapshotId && a.ruleVersion == b.ruleVersion && a.orderingVersion == b.orderingVersion
}
export function compareReasonText(reasons: MatchReason[], empty: string): string {
return reasons.length == 0 ? empty : reasons.map((r: MatchReason): string => r.text + '\n' + r.evidence.join('\n')).join('\n\n')
}