实施 P0–P4 时加载。与 00-migration-plan.md 配套。
| bx-backend 源 | shanxia2.0 目标 | 改造程度 |
|---|---|---|
schemas/common.py |
schemas/bx/common.py |
原样 |
schemas/expense_item.py 等 |
schemas/bx/*.py |
id 改 str |
services/*.py |
services/bx/*.py |
tenant + uuid + user |
routers/*.py |
api/bx/*.py |
Depends + prefix + import |
models/*.py |
models/bx_models.py |
按 DDL 重写 |
utils/codegen.py |
utils/bx_codegen.py 或 utils/codegen.py |
租户隔离可选 |
core/deps.py |
不复制 | 用 core/bx_auth.py |
services/minio.py |
不复制 | 门户 storage 适配 |
复制每个 router 后逐项核对:
APIRouter(prefix="/api/xxx") → prefix="/xxx"(去掉 /api)from app.database import get_db → from app.core.database import get_dbDepends(get_current_user) → Depends(get_bx_current_user)User 类型 → BxUserContextrequire_roles("ADMIN") → Depends(get_bx_current_user) 或 require_menu_code("bx:...")(P5 后){advance_id}: int → strresponse_model=ApiResponse[...] 保持不变return success_response(...)get_by_id(model, db, id: int) → id: strModel.tenant_no == tenant_nogenerate_uuid()、tenant_no、create_by、create_dept_idapplicant_id / approver_id 使用 sys_user.id(str)SysUser.nick_name 写入 applicant_name 等generate_apply_code 加租户维度(同日重置逻辑保留)del_flag=1,查询默认 del_flag=0AdvanceApplyOut.id: int → strexpense_item_id: Optional[int] → Optional[str]model_config:populate_by_name=True, alias_generator=to_camelDatetimeToStr / apply_time 等字段 alias# backend/app/core/bx_auth.py(实施 P0 时落地)
from dataclasses import dataclass
from fastapi import Depends
from app.core.menu_guard import require_admin_or_super_admin
@dataclass
class BxUserContext:
id: str
name: str
dept_id: str
def get_bx_current_user(
user: dict = Depends(require_admin_or_super_admin),
) -> BxUserContext:
return BxUserContext(
id=user.get("user_id") or "",
name=user.get("nick_name") or user.get("username") or "",
dept_id=user.get("dept_id") or "",
)
Service 中需要 tenant 时:
from app.core.tenant_context import get_tenant_no
tenant_no = get_tenant_no(db, {"user_id": user.id, "role": ...})
from app.api.bx import bx_router
app.include_router(bx_router, prefix=settings.API_V1_PREFIX)
api/bx/__init__.py:
from fastapi import APIRouter
from app.api.bx import expense_item, workflow, advance, reimburse, payment, attachment
bx_router = APIRouter()
bx_router.include_router(expense_item.router)
bx_router.include_router(workflow.router)
# ...
app/api/__init__.py 增加 bx_router 导出(可选,或直接 main 引用)。
在 API_ENCRYPT_EXCLUDE_PATHS 追加(逗号分隔):
/api/expense-items,
/api/workflows,
/api/advances,
/api/reimburses,
/api/payments,
/api/attachments
后端 CRUD 落地后,若 WriteBody 字段较多,可扩展 scripts/check_field_consistency.py 支持 bx_* 表,规则同 CRM。
| 阶段 | 方式 |
|---|---|
| P1 | Swagger /docs 手动测 expense-items / workflows |
| P2 | 备用金完整流程 + 附件 upload |
| P3–P4 | 对照 bx 原环境相同操作序列 |
| 协议 | 断言响应 code===0、data.rows 存在 |
原 bx 环境(8011)可与门户(8000)并行,便于 diff 响应结构。