feat: 财务看板口径重构与半年模拟数据及报销状态注册表

- 重构 finance_dashboard 口径计算,新增模拟公司画像数据生成与筛选
- 引入 expense_claim_status_registry 统一报销状态流转
- 完善报销草稿流程、Item Sync 与本体解析器
- 优化总览页趋势图、分页组件与请求进度步骤
- 增强报销申请快速预览、本体工具与详情展示
- 新增半年报销模拟数据种子脚本与状态审计工具
- 补充财务看板、报销状态注册与模拟数据测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-02 16:22:59 +08:00
parent ca691f3ee0
commit 0c74b4ab4a
54 changed files with 6810 additions and 1238 deletions

View File

@@ -314,7 +314,13 @@ class ExpenseClaimOntologyResolverMixin:
) -> datetime | None:
review_form_values = context_json.get("review_form_values")
if isinstance(review_form_values, dict):
for key in ("occurred_date", "time_range", "business_time"):
for key in (
"occurred_date",
"time_range",
"business_time",
"application_business_time",
"application_time",
):
value = str(review_form_values.get(key) or "").strip()
if not value:
continue
@@ -322,7 +328,9 @@ class ExpenseClaimOntologyResolverMixin:
parsed = date.fromisoformat(value)
return datetime(parsed.year, parsed.month, parsed.day, tzinfo=UTC)
except ValueError:
continue
parsed = ExpenseClaimOntologyResolverMixin._resolve_first_date_from_text(value)
if parsed is not None:
return datetime(parsed.year, parsed.month, parsed.day, tzinfo=UTC)
start_date = ontology.time_range.start_date
if start_date:
@@ -333,6 +341,21 @@ class ExpenseClaimOntologyResolverMixin:
pass
return None
@staticmethod
def _resolve_first_date_from_text(value: str) -> date | None:
match = re.search(r"20\d{2}[-/.]\d{1,2}[-/.]\d{1,2}", str(value or ""))
if not match:
return None
normalized = match.group(0).replace("/", "-").replace(".", "-")
parts = [part for part in normalized.split("-") if part]
if len(parts) != 3:
return None
try:
year, month, day = (int(part) for part in parts)
return date(year, month, day)
except ValueError:
return None
@staticmethod
def _resolve_amount(
entities: list[OntologyEntity],