feat(task): 完善任务系统 —— 分类字典/字段/四种接单方式/独占限额/交付时限

- Task 加 published_at/delivery_days/headcount/exclusive/publisher_id/category_id;新增 TaskCategory 分类字典表(35 类)。
- mode 归一 grab/bid/assign/recommend(旧 designated→assign、dispatch→recommend);TaskService 加 assign/recommend/select_recommend,claim 支持独占/限额、published+claimed 均可抢(多人)。
- TaskClaim 支持 source=assign/recommend、status=assigned/recommended/withdrawn + count_active_by_task;TaskCategoryRepository;Database 装配 task_categories。
- 端口:operator GET /admin/task-categories + POST tasks/{id}/assign|recommend|select;opc 同;park /api/tasks 返回 mode/deadline/delivery_days/headcount/exclusive/publisher_name。
- 迁移 0009(tasks 加列+task_categories)已应用+stamp;seed 35 分类字典 + task 新字段(含独占/推荐演示) + 补种已初始化库。
- 测试 test_task_system.py(独占/限额/指派/推荐/list_published/publish/category)+补齐 test_task_claim 语义, 15 passed。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Pine
2026-08-25 19:30:16 +08:00
parent b9b5e2e2ff
commit ea904d3a50
12 changed files with 555 additions and 43 deletions
+12
View File
@@ -10,6 +10,18 @@ class TaskClaimRequest(BaseModel):
task_id: str = ""
class TaskAssignRequest(BaseModel):
taker_user_id: str
class TaskRecommendRequest(BaseModel):
candidates: list[str] = []
class TaskSelectRecommendRequest(BaseModel):
taker_user_id: str = ""
class ProfileUpdate(BaseModel):
nickname: str | None = None
+31 -1
View File
@@ -3,21 +3,27 @@ from pydantic import BaseModel
class TaskCreateRequest(BaseModel):
title: str
category: str = ""
category_id: str | None = None
sub_category: str = ""
description: str = ""
tags: str = ""
mode: str = "grab"
mode: str = "grab" # grab/bid/assign/recommend
budget_min: int = 0
budget_max: int = 0
deadline: str = ""
delivery_days: int = 0
headcount: int = 0
exclusive: bool = False
task_code: str = ""
display_priority: int = 0
publisher_id: str | None = None
publisher_name: str = ""
class TaskUpdateRequest(BaseModel):
title: str | None = None
category: str | None = None
category_id: str | None = None
sub_category: str | None = None
description: str | None = None
tags: str | None = None
@@ -25,8 +31,12 @@ class TaskUpdateRequest(BaseModel):
budget_min: int | None = None
budget_max: int | None = None
deadline: str | None = None
delivery_days: int | None = None
headcount: int | None = None
exclusive: bool | None = None
task_code: str | None = None
display_priority: int | None = None
publisher_id: str | None = None
publisher_name: str | None = None
@@ -34,6 +44,26 @@ class TaskStatusRequest(BaseModel):
status: str # review/published/completed/cancelled/claimed/doing
class TaskAssignRequest(BaseModel):
taker_user_id: str
class TaskRecommendRequest(BaseModel):
candidates: list[str] = []
class TaskSelectRecommendRequest(BaseModel):
taker_user_id: str
class TaskCategoryItem(BaseModel):
id: str
name: str
sort: int = 0
modes: str = ""
status: str = "active"
class ProviderCreateRequest(BaseModel):
name: str