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 ```
98 lines
4.0 KiB
Python
98 lines
4.0 KiB
Python
from typing import Any
|
||
|
||
|
||
from app.modules.reports.constants import (
|
||
LifecycleResponseKey,
|
||
LifecycleSection,
|
||
MetricKey,
|
||
ReportText,
|
||
)
|
||
from app.modules.reports.services.common import _json_safe, _money
|
||
|
||
|
||
class ReportLifecycleRenderingMixin:
|
||
def _lifecycle_lines(
|
||
self,
|
||
filters: dict[str, Any],
|
||
metrics: dict[str, Any],
|
||
recommendations: list[str],
|
||
) -> list[str]:
|
||
scope = (
|
||
"、".join(f"{key}={value}" for key, value in filters.items() if value)
|
||
or ReportText.DEFAULT_SCOPE
|
||
)
|
||
projects = metrics[LifecycleSection.PROJECTS]
|
||
tasks = metrics[LifecycleSection.TASKS]
|
||
procurements = metrics[LifecycleSection.PROCUREMENTS]
|
||
expenses = metrics[LifecycleSection.EXPENSES]
|
||
funds = metrics[LifecycleSection.FUNDS]
|
||
suppliers = metrics[LifecycleSection.SUPPLIERS]
|
||
attendance = metrics[LifecycleSection.ATTENDANCE]
|
||
risks = metrics[LifecycleSection.RISKS]
|
||
health = metrics[LifecycleSection.HEALTH]
|
||
lines = [
|
||
f"- 范围:{scope}",
|
||
f"- 生命周期健康分:{health[MetricKey.SCORE]}({health[MetricKey.LEVEL]})",
|
||
(
|
||
f"- 项目:总数 {projects[MetricKey.TOTAL]},"
|
||
f"活跃 {projects[MetricKey.ACTIVE]},"
|
||
f"平均进度 {projects[MetricKey.AVERAGE_PROGRESS_PERCENT]}%"
|
||
),
|
||
(
|
||
f"- 成本:预算 {_money(projects[MetricKey.BUDGET_TOTAL])},"
|
||
f"实际 {_money(projects[MetricKey.ACTUAL_TOTAL])},"
|
||
f"预算使用率 {projects[MetricKey.BUDGET_USAGE_RATE]}%"
|
||
),
|
||
(
|
||
f"- 任务:总数 {tasks[MetricKey.TOTAL]},"
|
||
f"完成 {tasks[MetricKey.COMPLETED]},"
|
||
f"完成率 {tasks[MetricKey.COMPLETION_RATE]}%,"
|
||
f"逾期 {tasks[MetricKey.OVERDUE]}"
|
||
),
|
||
(
|
||
f"- 采购/费用:待批采购 {procurements[MetricKey.PENDING_APPROVAL]},"
|
||
f"待批费用 {expenses[MetricKey.PENDING_APPROVAL]},"
|
||
f"未付款采购 {procurements[MetricKey.UNPAID]}"
|
||
),
|
||
(
|
||
f"- 资金:余额 {_money(funds[MetricKey.CURRENT_BALANCE_TOTAL])},"
|
||
f"净头寸 {_money(funds[MetricKey.NET_POSITION])},"
|
||
f"风险账户 {funds[MetricKey.RISK_ACCOUNTS]}"
|
||
),
|
||
(
|
||
f"- 风险:等级 {risks[MetricKey.RISK_LEVEL]},"
|
||
f"风险分 {risks[MetricKey.RISK_SCORE]},"
|
||
f"延期项目 {risks[MetricKey.DELAYED_PROJECTS]},"
|
||
f"超预算项目 {risks[MetricKey.OVER_BUDGET_PROJECTS]},"
|
||
f"打开事件 {risks[MetricKey.OPEN_EVENTS]}"
|
||
),
|
||
(
|
||
f"- 供应商/考勤:风险供应商 {suppliers[MetricKey.RISKY]},"
|
||
f"异常打卡 {attendance[MetricKey.ABNORMAL]},"
|
||
f"异常率 {attendance[MetricKey.ABNORMAL_RATE]}%"
|
||
),
|
||
ReportText.ACTION_HEADER,
|
||
]
|
||
lines.extend(f" - {item}" for item in recommendations)
|
||
return lines
|
||
|
||
def _lifecycle_ai_analysis(self, report: dict[str, Any], actor: str) -> dict[str, Any]:
|
||
try:
|
||
from app.modules.ai_agent.constants import AIResponseKey
|
||
from app.modules.ai_agent.skills import AISkillId
|
||
from app.modules.ai_agent.service import AIService
|
||
|
||
report_snapshot = _json_safe(report)
|
||
result = AIService(self.db).run_skill(
|
||
AISkillId.PROJECT_LIFECYCLE_ANALYSIS,
|
||
context={LifecycleResponseKey.PROJECT_LIFECYCLE_REPORT: report_snapshot},
|
||
actor=actor,
|
||
)
|
||
except Exception as exc:
|
||
return {
|
||
AIResponseKey.OK: False,
|
||
AIResponseKey.ERROR: str(exc),
|
||
AIResponseKey.TYPE: type(exc).__name__,
|
||
}
|
||
return _json_safe({AIResponseKey.OK: True, **result})
|