Open Call(后端模型名为 Project)不再使用独立的开启/关闭开关和 is_private 控制招募。Project.status 统一为三个状态:
status | 产品名称 | 公开列表展示 | 通过 ID 链接访问 | 接受新应征 | 处理已有应征 |
|---|---|---|---|---|---|
public | 公开招募 | 是 | 是 | 是 | 是 |
link_only | 链接访问 | 否 | 是 | 是 | 是 |
closed | 停止招募 | 否 | 是 | 否 | 是 |
Project.status、ProjectRequest.status 和 WorkTask.status 是相互独立的状态:
POST /api/content/projects/list
status=public 且未归档的 Open CallGET /api/content/projects/info
public、link_only、closed;不提供防猜测 TokenPOST /api/projects/create
statusPOST /api/projects/update
is_private 修改招募状态;状态只能由 update_status 修改POST /api/projects/update_status
public、link_only、closedPOST /api/projects/list
GET /api/projects/info
can_apply、is_publicly_listedPOST /api/project_requests/choose
POST /api/project_requests/requested_list
filter=exited 和 counts.exitedPOST /api/project_requests/choosed_list
POST /api/artist_center/project_request/create
project_id;停止招募时禁止应征POST /api/artist_center/project_request/exit
POST /api/artist_center/project_request/update
is_exited=false 时编辑并恢复原应征;不创建新的 ProjectRequestPOST /api/artist_center/project_request/list
status=all|joined|exited 筛选并返回计数POST /api/artist_center/project_request/list_by_chosen
POST /api/content/projects/liststatus=public 且 is_archived=false 的数据。link_only 和 closed 均不进入公开列表、搜索和排序结果。沿用原有分页、分类、画风、发布者、关键词、价格和排序参数,无新增请求字段。
每个 Project 新增或调整以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
status | string | 固定为 public |
can_apply | boolean | 当前是否允许画师应征,公开列表固定为 true |
is_publicly_listed | boolean | 是否出现在公开列表,公开列表固定为 true |
无新增,沿用原有参数校验语义。
GET /api/content/projects/infopublic、link_only、closed 均可通过该接口访问。link_only 只是不进入公开列表,不使用额外访问凭证;系统接受用户枚举或猜测 Project ID 的风险。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | number | 是 | Open Call ID |
404:Open Call 不存在或已归档POST /api/projects/createstatus 控制公开范围和招募能力;链接访问直接使用响应中的 Project ID。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
status | string | 否 | public / link_only / closed,默认 public |
422:status 不是三个合法值之一,或其他字段校验失败POST /api/projects/updatestatus;招募状态只能通过 update_status 修改。| 操作 | 接口 | 说明 |
|---|---|---|
| 修改标题、预算等内容 | POST /api/projects/update | 不读取 status,不会改变招募状态 |
| 修改招募状态 | POST /api/projects/update_status | 必须提交 id 和三态 status |
前端若把 status 提交给 /api/projects/update,接口会成功更新其他内容,但招募状态不会变化。
无新增,沿用原有错误语义。
POST /api/projects/update_status| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | number | 是 | 当前用户拥有的 Open Call ID |
status | string | 是 | public / link_only / closed |
状态切换不会修改已有 ProjectRequest、WorkTask、Order、Group 或 Stage。重新切换到 public / link_only 后恢复接受新应征。
403:Open Call 不属于当前用户422:状态值不合法POST /api/projects/list| 字段 | 类型 | 说明 |
|---|---|---|
data[].status | string | Open Call 三态 |
data[].can_apply | boolean | 是否接受新的画师应征 |
data[].is_publicly_listed | boolean | 是否出现在公开区域 |
data[].project_requests[].is_exited | boolean | 画师是否已退出 |
data[].project_requests[].participation_status | string | joined / exited |
data[].project_requests[].has_created_commission | boolean | 是否曾创建 Commission |
data[].project_requests[].can_choose | boolean | 是否还能选中并创建新 Commission |
project_requests_count 只统计当前仍加入的应征;chosen_project_requests_count 包含已退出但曾产生 Commission 的历史应征。
无新增,沿用原有错误语义。
GET /api/projects/infocan_apply、is_publicly_listed;三种状态和已归档数据均可由 owner 管理接口访问。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | number | 是 | Open Call ID |
无新增,沿用原有错误语义。
POST /api/project_requests/chooseclosed 只禁止新的画师应征,不影响从已有有效应征创建 Commission。应征画师已退出或 Open Call 已归档时禁止创建;已有 Commission 不受影响。沿用原有 project_request_id、deadline、remuneration 和多语言 name。
400:Open Call 已归档,不能继续创建 Commission,错误码 82001。
400:画师已退出当前应征,错误码 82003。
POST /api/project_requests/requested_listcan_choose=false。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
project_id | number | 是 | 当前 owner 拥有的 Open Call ID |
filter | string | 否 | all / public / hidden / selected / joined / exited |
page | number | 否 | 页码,默认 1 |
size | number | 否 | 每页数量,默认 15,最大 50 |
order_by | string | 否 | latest / lower_price / artist_commission |
filter=selected 会同时包含:
status=user_chosen 的应征;filter=joined 返回所有未退出的应征,包括 status=pending 和 status=user_chosen。owner 应征列表页面只展示“应征中”和“已退出”两个筛选项,分别对应 joined 和 exited。
filter=exited 只返回已退出且至少存在一条关联 WorkTask 的应征;未产生 Commission 就退出的应征不会出现在 owner 列表。
ProjectRequest 原始 status 直接返回 exited;is_exited 和 participation_status 可用于简化前端判断。
无新增,沿用原有错误语义。
POST /api/project_requests/choosed_list与 requested_list 相同,新增 is_exited、participation_status、has_created_commission、can_choose。
无新增,沿用原有错误语义。
POST /api/artist_center/project_request/createproject_id 应征,不需要额外访问凭证;停止招募不允许新应征。400 + 82001:Open Call 已停止招募400 + 82002:当前画师已经存在 pending 或 user_chosen 应征400 + 82005:当前画师存在已退出应征,必须通过 update 恢复原记录退出后不能通过 create 创建新的 ProjectRequest;必须通过 update 恢复原记录。
POST /api/artist_center/project_request/exitpending 和 user_chosen 均可退出。退出只更新 ProjectRequest,不修改已有 Commission。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | number | 是 | 当前画师拥有的 ProjectRequest ID |
82004;传 is_exited=false 时允许编辑并恢复应征。| 项目 | 退出前 | 退出后:未产生 Commission | 退出后:已产生 Commission |
|---|---|---|---|
ProjectRequest status | pending / user_chosen | exited | exited |
is_exited | false | true | true |
participation_status | joined | exited | exited |
画师端 list | 返回 | 返回,可用 status=exited | 返回,可用 status=exited |
Owner requested_list | 返回 | 不返回 | 返回,可用 filter=exited |
Owner choosed_list | 选中后且存在 Commission 时返回 | 不返回 | 返回 |
| 公开 content 详情 | 按应征 visibility 规则返回 | 不返回 | 不返回 |
can_exit | true | false | false |
can_choose | 按 Open Call 状态决定 | false | false |
| 编辑当前应征 | 允许 | 普通编辑返回 82004 | 普通编辑返回 82004 |
| 基于当前应征新建 Commission | 允许 | 禁止,错误码 82003 | 禁止,错误码 82003 |
| 已有 Commission | 正常 | 无 | 完整保留,不改变状态 |
| 再次应征 | 有活跃应征时禁止 | update 恢复原 Request ID | update 恢复原 Request ID |
首次退出会向 owner 发送 project_request.artist_exited 站内通知,但不发送邮件;重复退出幂等成功且不重复通知。
404:ProjectRequest 不存在或不属于当前画师422:请求参数校验失败POST /api/artist_center/project_request/updatepending,已有 Commission 关系保持不变。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
is_exited | boolean | 否 | 恢复已退出应征时必须传 false;不传时仅执行普通编辑,不接受 true |
恢复必须同时满足:
exited。public 或 link_only。恢复成功后返回同一个 ProjectRequest ID,status=pending、is_exited=false。若该记录已有 Commission,list_by_chosen 和 owner choosed_list 仍保留历史记录。
400 + 82001:Open Call 已停止招募或已归档,不能恢复。400 + 82004:应征已经退出,但请求没有传 is_exited=false。422:is_exited=true 或其他不合法值。POST /api/artist_center/project_request/list| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
status | string | 否 | all / joined / exited,默认 all |
joined 包含 pending 和 user_chosen;exited 对应数据库状态 exited。
旧参数 filter 已删除,传入时返回 422。
422:status 不是合法值,或仍传入旧参数 filterPOST /api/artist_center/project_request/list_by_chosen与 list 相同,新增 is_exited、participation_status、has_created_commission、can_exit、can_choose。
无新增,沿用原有错误语义。
| 错误码 | 枚举名称 | HTTP | 场景 |
|---|---|---|---|
82001 | OpenCallNotAcceptingApplications | 400 | Open Call 已停止招募或已归档时禁止新应征与恢复;已归档时也禁止创建 Commission |
82002 | OpenCallRequestAlreadyJoined | 400 | 当前画师已有活跃应征 |
82003 | OpenCallRequestCannotChooseExited | 400 | owner 尝试选中已退出应征 |
82004 | OpenCallRequestCannotUpdateExited | 400 | 画师尝试编辑已退出应征 |
82005 | OpenCallRequestMustRestoreExited | 400 | 画师存在已退出应征,不能通过 create 新建,必须恢复原记录 |
前端必须根据 code 处理业务失败,不依赖 message 文案。
原 status | 原 is_private | 新 status |
|---|---|---|
open | false | public |
open | true | link_only |
close / closed | 任意 | closed |
share_token。兼容清理迁移会删除曾执行早期实现时创建的 projects.share_token 字段。is_private 数据库字段暂时保留兼容,新代码不再用它查询公开内容。is_archived 继续独立存在;归档后的 Open Call 不允许通过 ID 访问。open / close 不再是 API 合法入参。exited,不保留 artist_canceled。/api/artist_center/project_request/cancel 路由已删除,只使用 /exit。artist_canceled 记录一次性转换为 exited,再从 ENUM 中删除旧值。该迁移不保留旧 API、旧路由或旧状态入参兼容。can_choose=false。public / link_only / closed,删除原独立 Open Calls 开关。GET /api/content/projects/info?id={project_id} 获取详情;link_only 和 closed 不进入公开列表,但知道 ID 即可访问。can_apply=false 时隐藏或禁用应征入口,并展示停止招募状态。link_only 应征与公开招募相同,只提交 project_id 和原有应征字段。status=exited,也可使用 is_exited / participation_status。has_created_commission=true && is_exited=true 时保留历史卡片、置灰并设置不可选中。/exit,操作前展示二次确认;说明已有 Commission 不受影响。status=joined|exited 和服务端 counts,不要再传旧参数 filter,也不要在当前分页结果上自行过滤。update 表单与接口,并额外传 is_exited=false;成功后继续使用原 ProjectRequest ID。filter=exited 展示已退出且存在历史 Commission 的应征。82001 ~ 82004 错误码处理。