Files
server-core/app/api/schemas/operator.py
T
Pine 91db9d1a70 feat: 微信分享图独立配置 + 默认问卷开关 + 发布方/管理员权限拆分
- 迁移 0074: events/content_items 加 share_img_timeline(朋友圈1:1)/share_img_message(会话5:4)
- 迁移 0075: events 加 show_default_question(默认问卷「最想解决的问题」admin可控)
- 迁移 0076: events 加 publishers_json(发布方手机号绑定,可编辑活动+审核报名)
- 权限拆分: _can_edit_event(发布方+创建者+运营,不含管理员)/ _can_review_booking(发布方+管理员+创建者+运营)
- 审核报名相关端点改用 _can_review_booking;活动编辑用 _can_edit_event
- event_out 输出 canEdit/canReview/publishers;create/update 接收 publishers
- 我管理的活动包含发布方+管理员命中
2026-09-09 21:52:37 +08:00

333 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pydantic import BaseModel, Field
class TaskCreateRequest(BaseModel):
title: str
category: str = ""
category_id: str | None = None
sub_category: str = ""
description: str = ""
tags: str = ""
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 = ""
# ── 多端任务体系扩展字段 ──
publisher_role: str = "" # enterprise/operator/park
visibility: str = "public" # public/assigned_only/c_visible
c_visible: bool = True # 是否进 C 端任务广场
park_public: bool = False # 是否公有任务(各园区大屏可见/本园可接)
assign_type: str = "" # opc/park(指派模式)
assign_park_id: str | None = None
assign_opc_id: str | None = None
park_id: str | None = None
bid_quota: int = 0 # 竞标报名人数上限
win_quota: int = 0 # 竞标中标人数
eligibility: str = "{}" # 接单资格条件(JSON)
settle_mode: str = "operator_escrow" # 资金托管方式
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
mode: str | None = None
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
publisher_role: str | None = None
visibility: str | None = None
c_visible: bool | None = None
park_public: bool | None = None
assign_type: str | None = None
assign_park_id: str | None = None
assign_opc_id: str | None = None
park_id: str | None = None
bid_quota: int | None = None
win_quota: int | None = None
eligibility: str | None = None
settle_mode: str | None = None
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
category: str = ""
level: str = "certified"
status: str = "pending"
contact: str = ""
class ProviderUpdateRequest(BaseModel):
level: str | None = None
status: str | None = None
contact: str | None = None
class ContentCreateRequest(BaseModel):
type: str = "news"
title: str
summary: str = ""
body: str = ""
cover: str = "" # 加宽封面图(3.35:1
cover_small: str = "" # 小封面图(1:1,可选)
share_img_timeline: str = "" # 朋友圈分享图(1:1,可选;空则回退 cover)
share_img_message: str = "" # 会话分享图(5:4,可选;空则回退 cover)
images: list[str] = [] # 图集
video: str = "" # 视频 URL
video_cover: str = "" # 视频封面
link: str = "" # 外链
publisher_name: str = "" # 发布人昵称(仅运营端可设;空则显示「官方」)
published_at: str = "" # 发布时间(ISO;可未来=定时发布;空则发布时取当前)
publisher_avatar: str = "" # 发布人头像
card_mode: str = "big" # big 大图 | small 小图(运营端设)
is_public: bool = True # 是否公开
priority: int = 0 # 优先级(越大越靠前)
status: str = "draft"
class ContentStatusRequest(BaseModel):
status: str # published/offline/draft/pending
class ContentReviewRequest(BaseModel):
"""资讯审核:approve 通过上线 | offline 下架。"""
decision: str = "approve"
class ContentUpdateRequest(BaseModel):
"""内容更新(字段全可选,仅更新传入项)。"""
type: str | None = None # policy/news/skill/dynamic
title: str | None = None
summary: str | None = None
body: str | None = None
cover: str | None = None
cover_small: str | None = None
share_img_timeline: str | None = None
share_img_message: str | None = None
images: list[str] | None = None
video: str | None = None
video_cover: str | None = None
link: str | None = None
publisher_name: str | None = None
publisher_avatar: str | None = None
published_at: str | None = None
card_mode: str | None = None
is_public: bool | None = None
source: str | None = None
tenant_id: str | None = None
priority: int | None = None
status: str | None = None
class ConfigUpdateRequest(BaseModel):
value: str
description: str = ""
class UrlRuleRequest(BaseModel):
"""站点 URL 白名单 / 黑名单单条操作。"""
rule_type: str # whitelist | blacklist
host: str
# ── 任务管理 ──────────────────────────────────────────────────────────────
# ── 算力对接(compute-engine)─────────────────────────────────────────────
# ── 培训业务四件套(课程 / 活动 / 报名 / 测评)→ 桥接 app.training ─────────
class CourseCreateRequest(BaseModel):
title: str
category: str = ""
level: str = ""
subtitle: str = ""
desc: str = ""
price: float = 0
status: str = "draft"
start_at: str = ""
end_at: str = ""
venue: str = ""
quota: int = 0
image: str = ""
host: str = ""
class CourseStatusRequest(BaseModel):
status: str # draft/published/ended/offline
class CourseUpdateRequest(BaseModel):
"""课程更新(字段全可选,仅更新传入项)。"""
title: str | None = None
category: str | None = None
level: str | None = None
subtitle: str | None = None
desc: str | None = None
price: float | None = None
status: str | None = None
start_at: str | None = None
end_at: str | None = None
venue: str | None = None
quota: int | None = None
image: str | None = None
host: str | None = None
class ActivityCreateRequest(BaseModel):
title: str
type: str | None = None # free/salon
mode: str | None = None # online/offline
status: str | None = None # open/invite/pending/done/ended
subtitle: str | None = None
desc: str | None = None
location: str | None = None
host: str | None = None
image: str | None = None
link: str | None = None
start_at: str | None = None
duration_min: int | None = None
capacity: int | None = None
price_fen: int | None = None # 定价(分),0=免费
# ── 活动体系扩展 ──
end_at: str | None = None
checkin_at: str | None = None
audit_mode: str | None = None # auto|manual
show_capacity: bool | None = None
region: str | None = None
category: str | None = None
scope: str | None = None # park|public
target_tenant_id: str | None = None
body: str | None = None # 富文本 HTML
notice: str | None = None # 活动注意事项
external_url: str | None = None
signup_mode: str | None = None # mini|external
# ── 报名体系升级 ──
form_fields_json: str | None = None # 报名表单字段定义(JSON 数组)
activity_admins_json: str | None = None # 活动管理员(JSON 数组,手机号绑定)
secret_json: str | None = None # 审核通过后可见信息(JSON 对象)
signup_deadline: str | None = None # 报名截止(ISO;空=不限制)
remind_before_min: int | None = None # 活动前提醒提前分钟数(0=关闭)
class ActivityStatusRequest(BaseModel):
status: str # open/invite/pending/done/ended
class ActivityUpdateRequest(BaseModel):
"""活动更新(字段全可选,仅更新传入项)。"""
title: str | None = None
type: str | None = None
mode: str | None = None
status: str | None = None
subtitle: str | None = None
desc: str | None = None
location: str | None = None
host: str | None = None
image: str | None = None
link: str | None = None
start_at: str | None = None
duration_min: int | None = None
capacity: int | None = None
price_fen: int | None = None # 定价(分),0=免费
# ── 报名体系升级 ──
form_fields_json: str | None = None
activity_admins_json: str | None = None
secret_json: str | None = None
signup_deadline: str | None = None
remind_before_min: int | None = None
class BookingUpdateRequest(BaseModel):
status: str | None = None
audit_status: str | None = None
note: str | None = None
# ── 报名体系升级 ──
audit_comment: str | None = None # 审核备注(与小程序 /review 口径一致)
contact: str | None = None
name: str | None = None
class TestCreateRequest(BaseModel):
title: str
category: str = ""
pass_score: int = 0
question_count: int = 30
class TestStatusRequest(BaseModel):
status: str # enabled/disabled
class ComputePingResponse(BaseModel):
ok: bool
version: str | None = None
quota_per_unit: float | None = None # 引擎 1 元 = 多少配额(500000 = $1),来自 /api/status
detail: str | None = None
class ComputeBalanceRequest(BaseModel):
"""充值/调整引擎用户余额。``value`` 为配额单位(见 quota_per_unit)。"""
engine_user_id: int
value: int = Field(ge=0, description="调整量(配额单位),add/subtract 用")
mode: str = "add" # add | subtract | override
reason: str = ""
class ComputeProvisionRequest(BaseModel):
user_id: str
class ComputeProvisionResponse(BaseModel):
engine_user_id: str | None = None
engine_username: str | None = None
pat: str | None = None
created: bool = False
detail: str | None = None