feat: 风险可见性控制与差旅详情页交互优化
- 新增风险可见性工具函数与风险日趋势图表组件 - 优化差旅请求详情页费用模型与视图交互 - 完善顶部导航栏样式与应用壳路由逻辑 - 补充风险可见性、风险看板与差旅详情测试覆盖
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
import {
|
||||
buildExpenseItemViewModel,
|
||||
buildDraftBlockingIssues,
|
||||
rebuildExpenseItems,
|
||||
buildStandardAdjustmentMap,
|
||||
isApplicationDocumentRequest
|
||||
} from '../src/views/scripts/travelRequestDetailExpenseModel.js'
|
||||
@@ -543,9 +544,13 @@ test('AI advice risk section uses compact card styling hooks', () => {
|
||||
|
||||
test('expense rows show a major-risk warning icon before time', () => {
|
||||
assert.match(detailViewTemplate, /'has-major-risk': hasExpenseRiskIndicator\(item\)/)
|
||||
assert.match(detailViewTemplate, /class="expense-time-content"/)
|
||||
assert.match(detailViewTemplate, /class="expense-risk-indicator"/)
|
||||
assert.match(detailViewTemplate, /class="expense-risk-indicator-placeholder"/)
|
||||
assert.match(detailViewTemplate, /@click="focusExpenseRisk\(item\)"/)
|
||||
assert.match(detailViewStyle, /\.expense-time-content \{/)
|
||||
assert.match(detailViewStyle, /\.expense-risk-indicator \{/)
|
||||
assert.match(detailViewStyle, /\.expense-risk-indicator,\s*\.expense-risk-indicator-placeholder \{/)
|
||||
assert.match(detailViewScript, /function hasExpenseRiskIndicator\(item\)/)
|
||||
assert.match(detailViewScript, /buildItemClaimRiskState\(item, resolveClaimRiskFlags\(\)\)/)
|
||||
})
|
||||
@@ -556,7 +561,7 @@ test('expense risk indicator can focus and flash related risk card', () => {
|
||||
assert.match(detailViewTemplate, /'is-highlighted': isHighlightedRiskCard\(card\)/)
|
||||
assert.match(detailViewScript, /async function focusExpenseRisk\(item\)/)
|
||||
assert.match(detailViewScript, /document\.getElementById\(resolveRiskCardDomId\(card\)\)/)
|
||||
assert.match(detailViewScript, /scrollIntoView\(\{ behavior: 'smooth', block: 'center' \}\)/)
|
||||
assert.match(detailViewScript, /scrollIntoView\(\{ behavior: 'smooth', block: 'nearest', inline: 'nearest' \}\)/)
|
||||
assert.match(detailViewStyle, /\.validation-section--risk \.risk-advice-card\.is-highlighted/)
|
||||
assert.match(detailViewStyle, /@keyframes risk-card-flash/)
|
||||
})
|
||||
@@ -748,6 +753,50 @@ test('expense detail shows standard-adjusted reimbursable amount separately from
|
||||
assert.equal(item.hasStandardAdjustment, true)
|
||||
})
|
||||
|
||||
test('plain reimbursable amount does not mark an item as standard-adjusted during detail rebuild', () => {
|
||||
const item = buildExpenseItemViewModel(
|
||||
{
|
||||
id: 'hotel-risk-item',
|
||||
itemType: 'hotel_ticket',
|
||||
itemReason: '上海住宿',
|
||||
itemAmount: 1086,
|
||||
reimbursableAmount: 1086,
|
||||
originalItemAmount: 1086,
|
||||
invoiceId: 'hotel-risk.jpg',
|
||||
standardAdjustmentAccepted: false,
|
||||
hasStandardAdjustment: false
|
||||
},
|
||||
0,
|
||||
{ riskFlags: [] }
|
||||
)
|
||||
|
||||
assert.equal(item.standardAdjustmentAccepted, false)
|
||||
assert.equal(item.hasStandardAdjustment, false)
|
||||
assert.equal(item.reimbursableAmount, 1086)
|
||||
|
||||
const rebuiltItems = rebuildExpenseItems([item], { riskFlags: [] })
|
||||
assert.equal(rebuiltItems[0].standardAdjustmentAccepted, false)
|
||||
assert.equal(rebuiltItems[0].hasStandardAdjustment, false)
|
||||
|
||||
const riskCards = [
|
||||
{
|
||||
id: 'hotel-risk',
|
||||
source: 'attachment_analysis',
|
||||
itemId: 'hotel-risk-item',
|
||||
tone: 'high',
|
||||
risk: '住宿标准超标。'
|
||||
}
|
||||
]
|
||||
const visibleCards = filterSubmitterResolvedRiskCards({
|
||||
cards: riskCards,
|
||||
businessStage: 'reimbursement',
|
||||
isCurrentApplicant: true,
|
||||
expenseItems: rebuiltItems,
|
||||
standardAdjustmentMap: new Map()
|
||||
})
|
||||
assert.deepEqual(visibleCards.map((card) => card.id), ['hotel-risk'])
|
||||
})
|
||||
|
||||
test('standard adjustment resolves submitter risk prompt only after accepted while reviewer still sees notice', () => {
|
||||
const originalRiskCard = {
|
||||
id: 'risk-hotel-1',
|
||||
|
||||
Reference in New Issue
Block a user