feat: 新增票据夹模块并优化 OCR 与员工画像服务
后端新增票据夹端点、数据模型和服务模块,优化 OCR 端点 Schema 和附件操作逻辑,完善员工行为画像服务和辅助函数, 前端新增票据夹视图和服务层,优化文档中心样式和侧边栏导 航,完善员工画像详情弹窗和权限控制,补充单元测试。
This commit is contained in:
@@ -9,6 +9,7 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import CurrentUserContext, get_current_user, get_db
|
||||
from app.models.employee import Employee
|
||||
from app.schemas.employee_profile import EmployeeProfileLatestRead
|
||||
from app.services.account_behavior_profile import AccountBehaviorProfileService
|
||||
from app.services.employee_behavior_profile_service import EmployeeBehaviorProfileService
|
||||
|
||||
router = APIRouter(prefix="/employee-profiles")
|
||||
@@ -31,13 +32,13 @@ def get_current_employee_latest_profile(
|
||||
) -> EmployeeProfileLatestRead:
|
||||
employee = _resolve_current_employee(db, current_user)
|
||||
if employee is None:
|
||||
return EmployeeProfileLatestRead(
|
||||
employee_id=current_user.username,
|
||||
employee_name=current_user.name,
|
||||
return AccountBehaviorProfileService(db).get_latest_account_profile(
|
||||
account_id=current_user.username,
|
||||
account_name=current_user.name,
|
||||
identifiers=_current_account_identifiers(current_user),
|
||||
scene=scene,
|
||||
window_days=window_days,
|
||||
expense_type_scope=expense_type_scope,
|
||||
empty_reason="当前登录用户未匹配到员工目录,暂无法形成用户画像。",
|
||||
)
|
||||
|
||||
service = EmployeeBehaviorProfileService(db)
|
||||
@@ -47,7 +48,7 @@ def get_current_employee_latest_profile(
|
||||
window_days=window_days,
|
||||
expense_type_scope=expense_type_scope,
|
||||
)
|
||||
if latest.empty_reason:
|
||||
if latest.empty_reason or _missing_usage_duration_metric(latest):
|
||||
service.refresh_employee_profiles(
|
||||
employee_id=employee.id,
|
||||
window_days=(window_days,),
|
||||
@@ -115,3 +116,24 @@ def _resolve_current_employee(
|
||||
|
||||
stmt = select(Employee).where(or_(*conditions)).order_by(Employee.created_at.asc()).limit(1)
|
||||
return db.scalars(stmt).first()
|
||||
|
||||
|
||||
def _missing_usage_duration_metric(latest: EmployeeProfileLatestRead) -> bool:
|
||||
if latest.scene != "operations":
|
||||
return False
|
||||
|
||||
for profile in latest.profiles:
|
||||
if profile.profile_type == "ai_usage":
|
||||
return "ai_run_duration_ms" not in profile.metrics
|
||||
return False
|
||||
|
||||
|
||||
def _current_account_identifiers(current_user: CurrentUserContext) -> set[str]:
|
||||
return {
|
||||
item
|
||||
for item in (
|
||||
current_user.username,
|
||||
current_user.name,
|
||||
)
|
||||
if str(item or "").strip()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user