feat(task): 任务中心扫码接单(多端) —— 服务端任务状态机/端口/迁移
- Task 加 task_code/tags/display_priority/claimed_by/claimed_at/doing_at;新增 TaskClaim 流水表。
- TaskService 加 claimed/doing/completed 状态机(claim/start_doing/complete),grab 并入 claim。
- TaskRepository 加 list_published/get_by_code/update/claim/set_doing + TaskClaimRepository;挂 Database。
- 端口:
· opc /tasks/grab-by-code、/tasks/{id}/doing、/tasks/{id}/complete
· operator POST /tasks(auto task_code) + PATCH /tasks/:id
· park /park/api/tasks(大屏展示,含 scan_payload 二维码载荷)
· training /api/tasks/claim-by-code、/api/tasks/my(小程序 C 端账号→OPC 身份 find-or-create 领单)
- 迁移 0008(tasks 加列 + task_claims)已应用+stamp;seed 补 task_code/tags/grab demo。
- tests/test_task_claim.py(自包含内存库, 状态机+流水+list_published), 直接 async 校验通过。
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -196,26 +196,57 @@ class Agent(Base):
|
||||
# ── 运营端业务模型(平台运营/任务/服务商/内容/配置)────────────────────────
|
||||
|
||||
class Task(Base):
|
||||
"""平台任务(运营端可审核/下架;后续各端口接入)。"""
|
||||
"""平台任务(运营端可审核/下架;后续各端口接入)。
|
||||
|
||||
状态机(扩展支持扫码接单):draft/pending/review/published/claimed/doing/completed/cancelled。
|
||||
扫码接单流转:published → claimed(claimed_by/claimed_at) → doing(doing_at) → completed。
|
||||
历史接单流水见 TaskClaim;claim 记录 claimed_by/claimed_at/doing_at。
|
||||
"""
|
||||
|
||||
__tablename__ = "tasks"
|
||||
|
||||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
task_code: Mapped[str] = mapped_column(String, default="", index=True) # 展示/扫码短码(唯一)
|
||||
title: Mapped[str] = mapped_column(String, default="")
|
||||
category: Mapped[str] = mapped_column(String, default="") # 设计创意/技术开发/...
|
||||
sub_category: Mapped[str] = mapped_column(String, default="")
|
||||
description: Mapped[str] = mapped_column(Text, default="")
|
||||
tags: Mapped[str] = mapped_column(String, default="") # 逗号分隔展示标签
|
||||
mode: Mapped[str] = mapped_column(String, default="grab") # grab/bid/designated/dispatch
|
||||
budget_min: Mapped[int] = mapped_column(Integer, default=0)
|
||||
budget_max: Mapped[int] = mapped_column(Integer, default=0)
|
||||
deadline: Mapped[str] = mapped_column(String, default="")
|
||||
status: Mapped[str] = mapped_column(String, default="draft") # draft/pending/review/published/completed/cancelled
|
||||
display_priority: Mapped[int] = mapped_column(Integer, default=0) # 大屏展示排序(越大越前)
|
||||
status: Mapped[str] = mapped_column(String, default="draft") # draft/pending/review/published/claimed/doing/completed/cancelled
|
||||
claimed_by: Mapped[str | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
||||
claimed_at: Mapped[str] = mapped_column(String, default="")
|
||||
doing_at: Mapped[str] = mapped_column(String, default="")
|
||||
publisher_org_id: Mapped[str | None] = mapped_column(ForeignKey("organizations.id"), nullable=True)
|
||||
publisher_name: Mapped[str] = mapped_column(String, default="")
|
||||
created_at: Mapped[str] = mapped_column(String, default="")
|
||||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||||
|
||||
|
||||
class TaskClaim(Base):
|
||||
"""任务接单流水(扫码/抢单/投标中标),rich 记录任务状态流转历史。"""
|
||||
|
||||
__tablename__ = "task_claims"
|
||||
|
||||
id: Mapped[str] = mapped_column(String, primary_key=True)
|
||||
task_id: Mapped[str] = mapped_column(
|
||||
ForeignKey("tasks.id", ondelete="CASCADE"), nullable=False, index=True,
|
||||
)
|
||||
claimer_user_id: Mapped[str] = mapped_column(
|
||||
ForeignKey("users.id", ondelete="SET NULL"), nullable=True,
|
||||
)
|
||||
claimer_name: Mapped[str] = mapped_column(String, default="")
|
||||
claim_source: Mapped[str] = mapped_column(String, default="scan") # scan/grab/bid/dispatch
|
||||
claimed_at: Mapped[str] = mapped_column(String, default="")
|
||||
status: Mapped[str] = mapped_column(String, default="claimed") # claimed/doing/completed/withdrawn
|
||||
created_at: Mapped[str] = mapped_column(String, default="")
|
||||
updated_at: Mapped[str] = mapped_column(String, default="")
|
||||
|
||||
|
||||
class ServiceProvider(Base):
|
||||
"""服务商(运营端审核/评级/考核)。"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user