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:
@@ -0,0 +1,59 @@
|
||||
"""task claims and task display fields
|
||||
|
||||
Revision ID: f9f4eaef2e6f
|
||||
Revises: 0007_user_classification
|
||||
Create Date: 2026-08-25 18:23:09.123825
|
||||
|
||||
仅包含本次「任务中心 + 扫码接单」改动:tasks 增加展示/流转字段 + 新增 task_claims 流水表。
|
||||
(autogenerate 曾误带 training_* 删除与 users 列改动,已剔除,勿并入。)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
|
||||
revision = 'f9f4eaef2e6f'
|
||||
down_revision = '0007_user_classification'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ---- task_claims 接单流水表 ----
|
||||
op.create_table('task_claims',
|
||||
sa.Column('id', sa.String(), nullable=False),
|
||||
sa.Column('task_id', sa.String(), nullable=False),
|
||||
sa.Column('claimer_user_id', sa.String(), nullable=True),
|
||||
sa.Column('claimer_name', sa.String(), nullable=False, server_default=''),
|
||||
sa.Column('claim_source', sa.String(), nullable=False, server_default='scan'),
|
||||
sa.Column('claimed_at', sa.String(), nullable=False, server_default=''),
|
||||
sa.Column('status', sa.String(), nullable=False, server_default='claimed'),
|
||||
sa.Column('created_at', sa.String(), nullable=False, server_default=''),
|
||||
sa.Column('updated_at', sa.String(), nullable=False, server_default=''),
|
||||
sa.ForeignKeyConstraint(['claimer_user_id'], ['users.id'], ondelete='SET NULL'),
|
||||
sa.ForeignKeyConstraint(['task_id'], ['tasks.id'], ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_task_claims_task_id'), 'task_claims', ['task_id'], unique=False)
|
||||
|
||||
# ---- tasks 增加展示/流转字段 ----
|
||||
op.add_column('tasks', sa.Column('task_code', sa.String(), nullable=True))
|
||||
op.add_column('tasks', sa.Column('tags', sa.String(), nullable=True))
|
||||
op.add_column('tasks', sa.Column('display_priority', sa.Integer(), nullable=True))
|
||||
op.add_column('tasks', sa.Column('claimed_by', sa.String(), nullable=True))
|
||||
op.add_column('tasks', sa.Column('claimed_at', sa.String(), nullable=True))
|
||||
op.add_column('tasks', sa.Column('doing_at', sa.String(), nullable=True))
|
||||
op.create_index(op.f('ix_tasks_task_code'), 'tasks', ['task_code'], unique=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index(op.f('ix_tasks_task_code'), table_name='tasks')
|
||||
op.drop_column('tasks', 'doing_at')
|
||||
op.drop_column('tasks', 'claimed_at')
|
||||
op.drop_column('tasks', 'claimed_by')
|
||||
op.drop_column('tasks', 'display_priority')
|
||||
op.drop_column('tasks', 'tags')
|
||||
op.drop_column('tasks', 'task_code')
|
||||
op.drop_index(op.f('ix_task_claims_task_id'), table_name='task_claims')
|
||||
op.drop_table('task_claims')
|
||||
Reference in New Issue
Block a user