feat: 数字员工财务报告体系与定时提醒及看板快照调度
- 新增数字员工财务报告生成、邮件投递与渲染调度器 - 引入员工画像扫描调度与定时提醒任务 - 完善财务看板快照、排行口径与部门人员占比计算 - 优化数字员工工作看板仪表盘与技能目录 - 增强前端总览页图表、工作台摘要与顶部导航栏交互 - 新增差旅申请规划推动提醒与报销创建会话状态管理 - 补充财务报告、看板调度、数字员工工作记录测试覆盖
This commit is contained in:
@@ -460,11 +460,17 @@ export default {
|
||||
const isDraftRequest = computed(() => request.value.approvalKey === 'draft')
|
||||
const isEditableRequest = computed(() => ['draft', 'supplement'].includes(request.value.approvalKey))
|
||||
const canOpenAiEntry = computed(() => isEditableRequest.value)
|
||||
const canModifyReturnedApplication = computed(() => (
|
||||
isApplicationDocument.value
|
||||
&& isEditableRequest.value
|
||||
&& isCurrentApplicant.value
|
||||
&& String(request.value.status || '').trim().toLowerCase() === 'returned'
|
||||
))
|
||||
const canManageCurrentClaim = computed(() => canManageExpenseClaims(currentUser.value))
|
||||
const isArchivedRequest = computed(() => isArchivedRequestView(request.value))
|
||||
const canDeleteRequest = computed(() => {
|
||||
if (isApplicationDocument.value) {
|
||||
return isPlatformAdminUser(currentUser.value)
|
||||
return isPlatformAdminUser(currentUser.value) || (isEditableRequest.value && isCurrentApplicant.value)
|
||||
}
|
||||
if (isArchivedRequest.value) {
|
||||
return canDeleteArchivedExpenseClaims(currentUser.value)
|
||||
@@ -1007,7 +1013,7 @@ export default {
|
||||
if (analysis) {
|
||||
return {
|
||||
label: analysis.label || '已上传',
|
||||
tone: analysis.severity === 'pass' ? 'pass' : analysis.severity || 'low',
|
||||
tone: normalizeRiskTone(analysis.severity || 'low'),
|
||||
headline: analysis.headline || 'AI提示',
|
||||
summary: analysis.summary || '',
|
||||
points: Array.isArray(analysis.points) ? analysis.points : [],
|
||||
@@ -1858,7 +1864,9 @@ export default {
|
||||
toast(
|
||||
isArchivedRequest.value
|
||||
? '已归档单据不能删除,只有高级管理员可以执行删除。'
|
||||
: '当前单据已进入流程,只有高级财务人员可以删除。'
|
||||
: isApplicationDocument.value
|
||||
? '当前申请单已进入审批流程,只有退回后申请人本人或系统管理员可以删除。'
|
||||
: '当前单据已进入流程,只有高级财务人员可以删除。'
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -2019,6 +2027,76 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
function buildApplicationEditPreview() {
|
||||
const factEntries = applicationDetailFactItems.value
|
||||
.map((item) => [String(item?.label || '').trim(), String(item?.value || '').trim()])
|
||||
.filter(([label, value]) => label && value)
|
||||
const facts = new Map(factEntries)
|
||||
const pickFact = (...labels) => {
|
||||
for (const label of labels) {
|
||||
const value = facts.get(label)
|
||||
if (value) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
const tripStart = pickFact('出发时间')
|
||||
const tripReturn = pickFact('返回时间')
|
||||
const time = tripStart && tripReturn && tripStart !== tripReturn
|
||||
? `${tripStart} 至 ${tripReturn}`
|
||||
: pickFact('行程时间', '申请时间', '招待时间', '发生时间') || tripStart
|
||||
|
||||
return {
|
||||
sourceText: '修改申请',
|
||||
modelReviewStatus: 'template',
|
||||
fields: {
|
||||
applicationType: pickFact('申请类型') || request.value.typeLabel || '费用申请',
|
||||
applicant: request.value.profileName || request.value.person || request.value.applicant || '',
|
||||
grade: pickFact('职级') || request.value.profileGrade || '',
|
||||
department: request.value.profileDepartment || request.value.departmentName || request.value.department || '',
|
||||
position: request.value.profilePosition || request.value.employeePosition || request.value.position || '',
|
||||
managerName: request.value.profileManager || request.value.managerName || request.value.manager || '',
|
||||
time,
|
||||
location: pickFact('地点') || request.value.location || request.value.city || '',
|
||||
reason: pickFact('事由') || request.value.reason || '',
|
||||
days: pickFact('天数'),
|
||||
transportMode: pickFact('出行方式'),
|
||||
lodgingDailyCap: pickFact('住宿上限/天'),
|
||||
subsidyDailyCap: pickFact('补贴标准/天'),
|
||||
transportPolicy: pickFact('交通费用口径'),
|
||||
policyEstimate: pickFact('规则测算参考'),
|
||||
amount: pickFact('系统预估费用', '用户预估费用', '预计金额') || request.value.amountDisplay || request.value.amount || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleModifyApplication() {
|
||||
if (!canModifyReturnedApplication.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const claimId = String(request.value?.claimId || '').trim()
|
||||
emit('openAssistant', {
|
||||
source: 'application',
|
||||
sessionType: 'application',
|
||||
prompt: '',
|
||||
applicationPreview: buildApplicationEditPreview(),
|
||||
request: {
|
||||
...request.value,
|
||||
applicationEditMode: true
|
||||
},
|
||||
restoreLatestConversation: false,
|
||||
initialPromptAutoSubmit: false,
|
||||
scope: claimId
|
||||
? {
|
||||
type: 'claim',
|
||||
claimId
|
||||
}
|
||||
: null
|
||||
})
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
closeAttachmentPreview()
|
||||
})
|
||||
@@ -2032,7 +2110,7 @@ export default {
|
||||
applicationDetailFactItems, relatedApplicationFactItems,
|
||||
approveBusyText, approveConfirmText, approveConfirmTitle, canDeleteRequest, canManageCurrentClaim,
|
||||
canNavigateAttachmentPreview,
|
||||
canOpenAiEntry, canApproveRequest, canPayRequest, canReturnRequest, canSubmit, canPreviewAttachment,
|
||||
canModifyReturnedApplication, canOpenAiEntry, canApproveRequest, canPayRequest, canReturnRequest, canSubmit, canPreviewAttachment,
|
||||
closeApproveConfirmDialog, closeDeleteDialog, closeAttachmentPreview, closePayConfirmDialog, closeSubmitConfirmDialog,
|
||||
closeRiskOverrideDialog,
|
||||
closeReturnDialog, confirmApproveRequest, confirmDeleteRequest, confirmSubmitRequest, confirmReturnRequest,
|
||||
@@ -2046,6 +2124,7 @@ export default {
|
||||
expenseTypeOptions: EXPENSE_TYPE_OPTIONS,
|
||||
goToNextSubmitRisk, goToPreviousSubmitRisk,
|
||||
handleAddExpenseItem, handleApproveRequest, handleDeleteRequest, handleExpenseFileChange,
|
||||
handleModifyApplication,
|
||||
handlePayRequest,
|
||||
handleReturnRequest, handleSubmit, heroFactItems, isApplicationDocument, isDraftRequest, isEditableRequest, isTravelRequest,
|
||||
isMajorExpenseRisk,
|
||||
|
||||
Reference in New Issue
Block a user