feat: 数字员工财务报告体系与定时提醒及看板快照调度

- 新增数字员工财务报告生成、邮件投递与渲染调度器
- 引入员工画像扫描调度与定时提醒任务
- 完善财务看板快照、排行口径与部门人员占比计算
- 优化数字员工工作看板仪表盘与技能目录
- 增强前端总览页图表、工作台摘要与顶部导航栏交互
- 新增差旅申请规划推动提醒与报销创建会话状态管理
- 补充财务报告、看板调度、数字员工工作记录测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-03 09:25:23 +08:00
parent 0c74b4ab4a
commit 15006a05a7
114 changed files with 7356 additions and 650 deletions

View File

@@ -693,6 +693,92 @@ def test_user_agent_application_submit_blocks_duplicate_business_time() -> None:
assert second_response.draft_payload is None
def test_user_agent_application_edit_resubmits_returned_application_claim() -> None:
session_factory = build_session_factory()
with session_factory() as db:
claim = ExpenseClaim(
id="application-edit-1",
claim_no="AP-20260220-EDIT",
employee_name="pytest",
department_name="技术部",
expense_type="travel_application",
reason="旧事由",
location="上海",
amount=Decimal("1000.00"),
currency="CNY",
invoice_count=0,
occurred_at=datetime(2026, 2, 20, tzinfo=UTC),
status="returned",
approval_stage="待提交",
risk_flags_json=[
{
"source": "manual_return",
"event_type": "expense_application_return",
"message": "请修改事由",
},
{
"source": "application_detail",
"application_detail": {
"reason": "旧事由",
"time": "2026-02-20 至 2026-02-23",
},
},
],
)
db.add(claim)
db.commit()
response = build_application_user_agent_response(
db,
"确认提交",
context_overrides={
"manager_name": "向万红",
"application_edit_mode": True,
"application_edit_claim_id": claim.id,
"application_preview": {
"fields": {
"applicationType": "差旅费用申请",
"time": "2026-02-20 至 2026-02-23",
"location": "上海市",
"reason": "支撑国网仿生产环境建设",
"days": "4天",
"transportMode": "火车",
"amount": "4660元",
"grade": "P5",
"department": "技术部",
"position": "财务智能化产品经理",
"managerName": "向万红",
}
},
},
)
db.refresh(claim)
claims = db.query(ExpenseClaim).filter(ExpenseClaim.claim_no.like("AP-%")).all()
assert len(claims) == 1
assert "申请单据已修改并重新提交" in response.answer
assert response.draft_payload is not None
assert response.draft_payload.claim_id == claim.id
assert claim.status == "submitted"
assert claim.approval_stage == "直属领导审批"
assert claim.reason == "支撑国网仿生产环境建设"
assert claim.location == "上海市"
assert claim.amount == Decimal("4660.00")
assert claim.occurred_at.date().isoformat() == "2026-02-20"
flags = list(claim.risk_flags_json or [])
assert any(flag.get("event_type") == "expense_application_return" for flag in flags)
assert any(flag.get("event_type") == "expense_application_submission" for flag in flags)
detail_flags = [
flag.get("application_detail")
for flag in flags
if isinstance(flag, dict) and flag.get("source") == "application_detail"
]
assert len(detail_flags) == 1
assert detail_flags[0]["reason"] == "支撑国网仿生产环境建设"
assert detail_flags[0]["transport_mode"] == "火车"
def test_user_agent_knowledge_fallback_is_honest_and_personalized() -> None:
session_factory = build_session_factory()
with session_factory() as db: