feat: 风险可见性控制与差旅详情页交互优化
- 新增风险可见性工具函数与风险日趋势图表组件 - 优化差旅请求详情页费用模型与视图交互 - 完善顶部导航栏样式与应用壳路由逻辑 - 补充风险可见性、风险看板与差旅详情测试覆盖
This commit is contained in:
@@ -205,26 +205,31 @@
|
||||
<span>条款填写时间</span>
|
||||
</td>
|
||||
<td :class="['expense-time col-time', { 'has-major-risk': hasExpenseRiskIndicator(item) }]">
|
||||
<button
|
||||
v-if="hasExpenseRiskIndicator(item)"
|
||||
class="expense-risk-indicator"
|
||||
type="button"
|
||||
:title="resolveExpenseRiskIndicatorTitle(item)"
|
||||
:aria-label="resolveExpenseRiskIndicatorTitle(item)"
|
||||
@click="focusExpenseRisk(item)"
|
||||
>
|
||||
<i class="mdi mdi-alert"></i>
|
||||
</button>
|
||||
<template v-if="editingExpenseId === item.id">
|
||||
<div class="cell-editor">
|
||||
<input v-model="expenseEditor.itemDate" class="editor-input" type="date" />
|
||||
<span>{{ item.dayLabel }}</span>
|
||||
<div class="expense-time-content">
|
||||
<button
|
||||
v-if="hasExpenseRiskIndicator(item)"
|
||||
class="expense-risk-indicator"
|
||||
type="button"
|
||||
:title="resolveExpenseRiskIndicatorTitle(item)"
|
||||
:aria-label="resolveExpenseRiskIndicatorTitle(item)"
|
||||
@click="focusExpenseRisk(item)"
|
||||
>
|
||||
<i class="mdi mdi-alert"></i>
|
||||
</button>
|
||||
<span v-else class="expense-risk-indicator-placeholder" aria-hidden="true"></span>
|
||||
<div class="expense-time-value">
|
||||
<template v-if="editingExpenseId === item.id">
|
||||
<div class="cell-editor">
|
||||
<input v-model="expenseEditor.itemDate" class="editor-input" type="date" />
|
||||
<span>{{ item.dayLabel }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong>{{ item.time }}</strong>
|
||||
<span>{{ item.dayLabel }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<strong>{{ item.time }}</strong>
|
||||
<span>{{ item.dayLabel }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</td>
|
||||
<td class="expense-type col-type">
|
||||
<template v-if="editingExpenseId === item.id">
|
||||
|
||||
@@ -1682,7 +1682,7 @@ export default {
|
||||
const target = card
|
||||
? document.getElementById(resolveRiskCardDomId(card))
|
||||
: riskSection
|
||||
target?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
target?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })
|
||||
|
||||
if (highlightedRiskCardTimer) {
|
||||
window.clearTimeout(highlightedRiskCardTimer)
|
||||
|
||||
@@ -454,10 +454,33 @@ function resolveSourceStandardAdjustment(source, id, requestModel) {
|
||||
if (reimbursableAmount === null) {
|
||||
return null
|
||||
}
|
||||
const originalAmount = parseOptionalCurrency(
|
||||
source?.originalItemAmount
|
||||
?? source?.original_item_amount
|
||||
?? source?.originalAmount
|
||||
?? source?.original_amount
|
||||
)
|
||||
const employeeAbsorbedAmount = parseOptionalCurrency(
|
||||
source?.employeeAbsorbedAmount
|
||||
?? source?.employee_absorbed_amount
|
||||
) || 0
|
||||
const hasExplicitAdjustmentMarker = Boolean(
|
||||
source?.standardAdjustmentAccepted
|
||||
|| source?.standard_adjustment_accepted
|
||||
|| source?.hasStandardAdjustment
|
||||
|| source?.has_standard_adjustment
|
||||
|| String(source?.standardAdjustmentMessage || source?.standard_adjustment_message || '').trim()
|
||||
|| employeeAbsorbedAmount > 0
|
||||
|| (originalAmount !== null && reimbursableAmount < originalAmount)
|
||||
)
|
||||
if (!hasExplicitAdjustmentMarker) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
originalAmount: parseOptionalCurrency(source?.originalItemAmount ?? source?.original_item_amount ?? source?.originalAmount ?? source?.original_amount),
|
||||
originalAmount,
|
||||
reimbursableAmount,
|
||||
employeeAbsorbedAmount: parseOptionalCurrency(source?.employeeAbsorbedAmount ?? source?.employee_absorbed_amount) || 0,
|
||||
employeeAbsorbedAmount,
|
||||
message: String(source?.standardAdjustmentMessage || source?.standard_adjustment_message || '').trim()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user