feat: 订单模块 v0.1 实现与样板二维平面图全量采集

- 后端分层架构: api(Controller)/services(业务)/repositories(数据)/models(ORM)
- 订单模块: 创建(契约对齐目标站{contract_id,drawing_data,pic_url})、搜索、
  详情、更新、删除、状态机(意向单→正式单→生产中→完工/取消,非法迁移拒绝)、
  7节点生产进度、审计日志
- 认证模块: JWT签发(HS256/24h)、PBKDF2密码、注册登录
- 样板库API: 分类树/模板搜索/模板详情, drawing_data 与采集样本同构
- 254张样板二维平面图全部采集并静态挂载 /static/windoor-images/
- 种子脚本: 管理员+分类树+254套样板入库
- 统一响应envelope与付费墙(code=10086)/权限(code=210)语义
- 端到端冒烟测试7/7通过, 更新API.md §12自研接口规范
This commit is contained in:
HHY
2026-09-20 08:16:03 -07:00
parent 7554f2e3c7
commit d3e6de585c
288 changed files with 1835 additions and 9 deletions
+120
View File
@@ -0,0 +1,120 @@
"""订单路由(Controller 层,只做参数编排,业务在 Service)。"""
from fastapi import APIRouter, Depends
from huamenchuang.core.deps import CurrentUser, DbSession, require_module
from huamenchuang.core.response import fail, ok, paginated
from huamenchuang.schemas.order import OrderCreate, OrderProcessUpdate, OrderSearch, OrderUpdate
from huamenchuang.services.order_service import OrderService
router = APIRouter(prefix="/orders", tags=["订单"],
dependencies=[Depends(require_module("order"))])
def _to_out(order) -> dict:
return {
"id": order.id,
"order_no": order.order_no,
"contract_id": order.contract_id,
"pic_url": order.pic_url,
"customer_id": order.customer_id,
"customer_name": order.customer_name,
"phone": order.phone,
"address": order.address,
"area": float(order.area),
"count": order.count,
"money": float(order.money),
"status": order.status,
"status_label": order.status_label,
"cut_status": order.cut_status,
"sort": order.sort,
"note": order.note,
"created_at": str(order.created_at),
"updated_at": str(order.updated_at),
}
@router.post("")
async def create_order(body: OrderCreate, user: CurrentUser, db: DbSession):
"""创建订单。契约对齐目标站:{contract_id, drawing_data, pic_url}。"""
try:
order = await OrderService(db).create_order(user, body)
except Exception:
return fail("创建订单失败")
return ok(data=_to_out(order), message="创建成功")
@router.post("/search")
async def search_orders(body: OrderSearch, user: CurrentUser, db: DbSession):
"""订单搜索(POST 搜索语义对齐目标站)。"""
items, total = await OrderService(db).search(user, body)
return ok(data=paginated([_to_out(o) for o in items], body.page, body.page_size, total))
@router.get("")
async def list_orders(user: CurrentUser, db: DbSession, page: int = 1, page_size: int = 15):
"""订单分页列表(GET 简化入口)。"""
items, total = await OrderService(db).search(
user, OrderSearch(page=page, page_size=page_size))
return ok(data=paginated([_to_out(o) for o in items], page, page_size, total))
@router.get("/{order_id}")
async def order_detail(order_id: int, user: CurrentUser, db: DbSession):
"""订单详情:含 drawing_data 与生产进度。"""
try:
order = await OrderService(db).get_detail(user, order_id)
except KeyError as e:
return fail(str(e))
data = _to_out(order)
data["drawing_data"] = order.drawing_data
data["processes"] = [
{"id": p.id, "name": p.name, "status": p.status,
"finish_time": str(p.finish_time) if p.finish_time else None}
for p in order.processes
]
return ok(data=data)
@router.put("/{order_id}")
async def update_order(order_id: int, body: OrderUpdate, user: CurrentUser, db: DbSession):
"""更新订单基础字段;action=change_status 时执行状态迁移。"""
try:
order = await OrderService(db).update_order(user, order_id, body)
except KeyError as e:
return fail(str(e))
except ValueError as e:
return fail(str(e))
return ok(data=_to_out(order), message="更新成功")
@router.delete("/{order_id}")
async def delete_order(order_id: int, user: CurrentUser, db: DbSession):
"""删除订单(软动作:记日志后物理删除)。"""
try:
await OrderService(db).delete_order(user, order_id)
except KeyError as e:
return fail(str(e))
return ok(message="删除成功")
@router.post("/{order_id}/process")
async def update_process(order_id: int, body: OrderProcessUpdate, user: CurrentUser, db: DbSession):
"""更新生产进度节点。"""
try:
proc = await OrderService(db).update_process(user, order_id, body)
except KeyError as e:
return fail(str(e))
return ok(data={"id": proc.id, "name": proc.name, "status": proc.status,
"finish_time": str(proc.finish_time) if proc.finish_time else None},
message="操作成功")
@router.get("/{order_id}/logs")
async def order_logs(order_id: int, user: CurrentUser, db: DbSession):
"""订单操作日志(对齐 order_up_logs 语义)。"""
try:
logs = await OrderService(db).list_logs(user, order_id)
except KeyError as e:
return fail(str(e))
return ok(data=[{"id": g.id, "action": g.action, "detail": g.detail,
"created_at": str(g.created_at)} for g in logs])