refactor(core,ai): 调整模块导入路径并移除废弃文件

- 修复 scheduler.py 中的导入路径错误,将 reports.service
  改为 reports.services
- 移除废弃的 app/core/background/task_queue.py 文件
- 移除废弃的 app/modules/ai_agent/adapters.py 文件
- 修复 ai_memory/service.py 中的导入路径错误,将
  events.service 改为 events.services
```
This commit is contained in:
2026-07-09 18:50:52 +08:00
parent dc8605ce3f
commit bf309ecdf7
83 changed files with 4871 additions and 4153 deletions

View File

@@ -0,0 +1,123 @@
from datetime import date
from decimal import Decimal
from typing import Any
from sqlalchemy import select
from app.core.http.pagination import bounded_limit
from app.modules.business.constants import (
DONE_STATUSES,
GENERATED_RISK_EVENT_TYPES,
PROJECT_CLOSED_STATUSES,
SUPPLIER_RISK_LEVELS,
StatusValue,
)
from app.modules.business.models import (
FundAccount,
Project,
RiskEvent,
RiskEventAction,
Supplier,
WorkTask,
)
from app.modules.business.service import serialize_model
from app.modules.risk.constants import (
RISK_SCORE_WEIGHTS,
RiskEventPayloadKey,
RiskSummaryKey,
risk_level_for_score,
)
class RiskQueryMixin:
def overdue_tasks(self) -> list[dict[str, Any]]:
stmt = select(WorkTask).where(
WorkTask.due_date.is_not(None),
WorkTask.due_date < date.today(),
WorkTask.status.notin_(DONE_STATUSES),
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def delayed_projects(self) -> list[dict[str, Any]]:
stmt = select(Project).where(
Project.due_date.is_not(None),
Project.due_date < date.today(),
Project.status.notin_(PROJECT_CLOSED_STATUSES),
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def over_budget_projects(self) -> list[dict[str, Any]]:
stmt = select(Project).where(
Project.budget_amount > 0,
Project.actual_amount > Project.budget_amount,
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def fund_risks(self) -> list[dict[str, Any]]:
stmt = select(FundAccount).where(FundAccount.current_balance < FundAccount.safety_line)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def supplier_risks(self) -> list[dict[str, Any]]:
stmt = select(Supplier).where(
(Supplier.blacklist_status != StatusValue.NORMAL)
| Supplier.risk_level.in_(SUPPLIER_RISK_LEVELS)
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def list_events(
self,
limit: int = 100,
status_filter: str | None = None,
) -> list[dict[str, Any]]:
limit_value = bounded_limit(limit)
stmt = select(RiskEvent).order_by(RiskEvent.id.desc()).limit(limit_value)
if status_filter:
stmt = (
select(RiskEvent)
.where(RiskEvent.status == status_filter)
.order_by(RiskEvent.id.desc())
.limit(limit_value)
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def list_actions(self, risk_event_id: int, limit: int = 100) -> list[dict[str, Any]]:
self._get_event(risk_event_id)
stmt = (
select(RiskEventAction)
.where(RiskEventAction.risk_event_id == risk_event_id)
.order_by(RiskEventAction.id.desc())
.limit(bounded_limit(limit))
)
return [serialize_model(item) for item in self.db.execute(stmt).scalars()]
def summary(self) -> dict[str, Any]:
overdue_tasks = self.overdue_tasks()
delayed_projects = self.delayed_projects()
over_budget_projects = self.over_budget_projects()
fund_risks = self.fund_risks()
supplier_risks = self.supplier_risks()
open_events = self.list_events(status_filter=StatusValue.OPEN)
external_open_events = [
item
for item in open_events
if item.get(RiskEventPayloadKey.RISK_TYPE) not in GENERATED_RISK_EVENT_TYPES
]
risk_score = (
len(overdue_tasks) * RISK_SCORE_WEIGHTS[RiskSummaryKey.OVERDUE_TASKS]
+ len(delayed_projects) * RISK_SCORE_WEIGHTS[RiskSummaryKey.DELAYED_PROJECTS]
+ len(over_budget_projects)
* RISK_SCORE_WEIGHTS[RiskSummaryKey.OVER_BUDGET_PROJECTS]
+ len(fund_risks) * RISK_SCORE_WEIGHTS[RiskSummaryKey.FUND_RISKS]
+ len(supplier_risks) * RISK_SCORE_WEIGHTS[RiskSummaryKey.SUPPLIER_RISKS]
+ len(external_open_events) * RISK_SCORE_WEIGHTS[RiskSummaryKey.OPEN_EVENTS]
)
return {
RiskSummaryKey.RISK_LEVEL: risk_level_for_score(risk_score),
RiskSummaryKey.RISK_SCORE: Decimal(risk_score),
RiskSummaryKey.OVERDUE_TASKS: overdue_tasks,
RiskSummaryKey.DELAYED_PROJECTS: delayed_projects,
RiskSummaryKey.OVER_BUDGET_PROJECTS: over_budget_projects,
RiskSummaryKey.FUND_RISKS: fund_risks,
RiskSummaryKey.SUPPLIER_RISKS: supplier_risks,
RiskSummaryKey.OPEN_EVENTS: open_events,
}