project content / request 接口调整 (2026-03-24)

接口变更

content

  • POST /api/content/projects/list
    • 功能:获取公开 project 列表
    • 变更:新增关键字、分类、画风、发布者、价格区间、排序等筛选参数;排序支持 latestdeadlinemost_applicantshighest_budget
  • GET /api/content/projects/filters
    • 功能:获取 project 筛选项元数据
    • 变更:新增接口,返回 categoriesart_styles
  • GET /api/content/projects/info
    • 功能:获取公开 project 详情
    • 变更:直接返回 color_modesize_specprod_format,其中 prod_format 与 service 一致为数组;不再返回旧的 formatscolorModelsdata.user 新增简介、评价、语言、timezone 信息;匿名应征不再出现在 project_requests 中,改为返回 hidden_project_requests_count

user

  • POST /api/projects/create
    • 功能:创建 project
    • 变更:正式使用 color_modesize_spec 字符串字段,以及 prod_format 数组字段
  • POST /api/projects/update
    • 功能:更新 project
    • 变更:正式使用 color_modesize_spec 字符串字段,以及 prod_format 数组字段
  • GET /api/projects/info
    • 功能:获取当前用户的 project 详情
    • 变更:直接返回 color_modesize_specprod_format,其中 prod_format 为数组;不再返回旧的 formatscolorModels
  • GET /api/projects/meta
    • 功能:获取 project 表单元数据
    • 变更:不再返回 formatscolor_modelsuse_rangestranslations
  • POST /api/project_requests/requested_list
    • 功能:获取当前用户 project 的应征列表
    • 变更:返回中的 artist 新增 languages
  • POST /api/project_requests/choosed_list
    • 功能:获取当前用户已选中的应征列表
    • 变更:返回中的 artist 新增 languages
  • POST /api/project_requests/choose
    • 功能:选择某个 project 应征并创建 worktask
    • 变更:创建 project 来源 worktask 时会生成 project_snap,并将 project / project_request 快照写入 busable_snapreqable_snap
  • POST /api/work_tasks/list
    • 功能:获取当前用户 worktask 列表
    • 变更:project 来源 worktask 的 reqable 改为返回 project_snap,不再依赖 service request 专属字段
  • GET /api/work_tasks/info
    • 功能:获取当前用户 worktask 详情
    • 变更:project 来源 worktask 的 reqable 改为返回 project_snap,并补充 project request 的币种、作品附件等信息
  • POST /api/artist_rec_reviews/create_work_task_review
    • 功能:用户对 worktask 中的 artist 发起评价
    • 变更:project 来源 worktask 的评价会将 bizable_type 写为 project_snap

artist_center

  • POST /api/artist_center/project_request/create
    • 功能:artist 对 project 发起应征
    • 变更:新增 is_anonymous;创建后会为 detail 自动创建翻译记录
  • POST /api/artist_center/project_request/list
    • 功能:artist 获取自己的 project 应征列表
    • 变更:列表对象显式返回 is_anonymous
  • POST /api/artist_center/project_request/list_by_chosen
    • 功能:artist 获取自己被选中的 project 应征列表
    • 变更:列表对象显式返回 is_anonymous
  • POST /api/artist_center/work_tasks/list
    • 功能:artist 获取自己的 worktask 列表
    • 变更:project 来源 worktask 的 reqable 改为返回 project_snap,不再依赖 service request 专属字段
  • GET /api/artist_center/work_tasks/info
    • 功能:artist 获取自己的 worktask 详情
    • 变更:project 来源 worktask 的 reqable 改为返回 project_snap,并补充 project request 的币种、作品附件等信息
  • POST /api/artist_center/user_rec_reviews/create_work_task_review
    • 功能:artist 对 worktask 中的 user 发起评价
    • 变更:type 仅支持真实业务值 serviceproject;project 来源 worktask 的评价会将 bizable_type 写为 project_snap

接口示例

content

POST /api/content/projects/list

  • 功能说明:获取公开 project 列表。
  • 变更说明:新增关键字、分类、画风、发布者、价格区间、排序等筛选参数;价格筛选按 project 预算区间与筛选区间是否有交集来判断命中。

请求参数

字段类型必填说明
pagenumber页码,默认 1
sizenumber每页数量,默认 15
keywordstring搜索关键字,匹配 project namecontent、发布者 name/cname
category_idsnumber[]project 分类 id 列表
art_style_idsnumber[]画风 id 列表
user_cnamestringproject 发布者的 cname 或 id
price_currency_idnumber价格筛选所使用的币种 id
price_fromnumber最低价格
price_tonumber最高价格
order_bystring排序方式。latest: id descdeadline: deadline asc, id descmost_applicants: project_requests_count desc, id deschighest_budget: price_end desc, id desc

其他校验规则

  • page >= 1
  • size >= 1 && size <= 50
  • category_ids.* 必须存在于 categories.id
  • art_style_ids.* 必须存在于 art_styles.id
  • price_currency_id 必须存在于 currencies.id
  • price_from >= 0
  • price_to >= 0
  • order_by 仅支持 latestdeadlinemost_applicantshighest_budget
  • 各排序规则如下:
    • latest:按 id desc
    • deadline:按 deadline asc,同值再按 id desc
    • most_applicants:按 project_requests_count desc,同值再按 id desc
    • highest_budget:按 price_end desc,同值再按 id desc
  • 当同时传 price_fromprice_to 时,筛选逻辑为:
    • project 的 [price_start, price_end] 与筛选区间 [price_from, price_to] 有交集才命中

请求示例

{
  "keyword": "watercolor",
  "category_ids": [12],
  "art_style_ids": [5],
  "user_cname": "target-owner",
  "price_currency_id": 2,
  "price_from": 650,
  "price_to": 800,
  "order_by": "most_applicants",
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 101,
      "price_start": 90,
      "price_end": 110,
      "project_requests_count": 2
    }
  ],
  "total": 1
}

错误响应

422:参数校验失败

{
  "message": "The category ids.0 field must exist in categories.id."
}

GET /api/content/projects/filters

  • 功能说明:获取公开 project 列表筛选项。
  • 变更说明:新增接口,统一返回 project 的分类与画风筛选项。

请求参数

其他校验规则

请求示例

{}

响应示例

{
  "data": {
    "categories": [
      {
        "id": 12,
        "name": "Illustration"
      }
    ],
    "art_styles": [
      {
        "id": 5,
        "name": "Anime"
      }
    ]
  }
}

错误响应

  • 无新增,沿用原有错误语义。

GET /api/content/projects/info

  • 功能说明:获取公开 project 详情。
  • 变更说明:直接返回 color_modesize_specprod_format,其中 prod_format 与 service 一致为数组;不再返回旧的 formatscolorModelsdata.user 新增 intro、评价、语言、timezone 信息;匿名应征不再出现在 project_requests,改为返回 hidden_project_requests_count

请求参数

字段类型必填说明
idnumberproject id

其他校验规则

  • id >= 1
  • id 必须存在于 projects.id

请求示例

{
  "id": 101
}

响应示例

{
  "data": {
    "id": 101,
    "color_mode": "RGB",
    "size_spec": "A4",
    "prod_format": ["PNG"],
    "user": {
      "id": 1001,
      "cname": "project-owner",
      "intro": {
        "en": "Collector and commissioner"
      },
      "timezone": "Asia/Tokyo",
      "language": {
        "id": 1,
        "code": "en"
      },
      "languages": [
        {
          "id": 1,
          "code": "en",
          "pivot": {
            "fluency": "native"
          }
        }
      ],
      "rating_score": 4.5,
      "rec_reviews_count": 1
    },
    "project_requests": [
      {
        "id": 9001,
        "is_anonymous": false,
        "artist": {
          "id": 301,
          "cname": "visible-artist"
        }
      }
    ],
    "hidden_project_requests_count": 1
  }
}

错误响应

404:project 不存在或不可访问

{
  "message": "Project not found"
}

user

POST /api/projects/create

  • 功能说明:创建当前用户的 project。
  • 变更说明:正式使用 color_modesize_spec 字符串字段,以及 prod_format 数组字段。

请求参数

字段类型必填说明
namestringproject 名称
name_langstringname 的语言代码
contentstringproject 内容说明
content_langstringcontent 的语言代码
currency_idnumber币种 id
price_startnumber最低价格
price_endnumber最高价格
deadlinestring截止时间
color_modestring颜色模式
size_specstring尺寸说明
prod_formatstring[]成品格式数组
categoriesnumber[]分类 id 列表
art_stylesnumber[]画风 id 列表

其他校验规则

  • currency_id 必须存在于 currencies.id
  • price_start >= 0
  • price_end >= 0
  • color_mode / size_spec 最长 255
  • prod_format.* 最长 255
  • examples 最多 8

请求示例

{
  "name": "String Field Project",
  "name_lang": "en",
  "content": "Need a detailed illustration",
  "content_lang": "en",
  "currency_id": 1,
  "price_start": 100,
  "price_end": 180,
  "deadline": "2026-04-07 00:00:00",
  "color_mode": "RGB",
  "size_spec": "A4",
  "prod_format": ["PNG"],
  "categories": [3],
  "art_styles": [8]
}

响应示例

{
  "data": {
    "id": 101,
    "color_mode": "RGB",
    "size_spec": "A4",
    "prod_format": ["PNG"]
  }
}

错误响应

422:参数校验失败

{
  "message": "The currency id field is required."
}

POST /api/projects/update

  • 功能说明:更新当前用户的 project。
  • 变更说明:正式使用 color_modesize_spec 字符串字段,以及 prod_format 数组字段。

请求参数

字段类型必填说明
idnumberproject id
color_modestring颜色模式
size_specstring尺寸说明
prod_formatstring[]成品格式数组
price_startnumber最低价格
price_endnumber最高价格
deadlinestring截止时间

其他校验规则

  • id 为当前登录用户自己的 project
  • color_mode / size_spec 最长 255
  • prod_format.* 最长 255

请求示例

{
  "id": 101,
  "color_mode": "CMYK",
  "size_spec": "A3",
  "prod_format": ["PSD"]
}

响应示例

{
  "ok": true
}

错误响应

403:project 不属于当前登录用户

{
  "status": "error"
}

GET /api/projects/info

  • 功能说明:获取当前用户的 project 详情。
  • 变更说明:直接返回 color_modesize_specprod_format,其中 prod_format 为数组;不再返回旧的 formatscolorModels

请求参数

字段类型必填说明
idnumberproject id

其他校验规则

  • id 必须属于当前登录用户

请求示例

{
  "id": 101
}

响应示例

{
  "data": {
    "id": 101,
    "color_mode": "RGB",
    "size_spec": "A4",
    "prod_format": ["PNG"]
  }
}

错误响应

  • 无新增,沿用原有错误语义。

GET /api/projects/meta

  • 功能说明:获取 project 表单元数据。
  • 变更说明:不再返回 formatscolor_modelsuse_rangestranslations

请求参数

其他校验规则

请求示例

{}

响应示例

{
  "data": {
    "tags": [],
    "categories": [],
    "stages": [],
    "art_styles": [],
    "feedback_intervals": [3, 5, 7],
    "stage_templates": []
  }
}

错误响应

  • 无新增,沿用原有错误语义。

POST /api/project_requests/requested_list

  • 功能说明:获取当前用户某个 project 的应征列表。
  • 变更说明:返回中的 artist 新增 languages

请求参数

字段类型必填说明
project_idnumberproject id
pagenumber页码,默认 1
sizenumber每页数量,默认 15

其他校验规则

  • project_id 必须属于当前登录用户
  • page >= 1
  • size >= 1 && size <= 50

请求示例

{
  "project_id": 101,
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 9001,
      "artist": {
        "id": 301,
        "cname": "artist-a",
        "languages": [
          {
            "id": 1,
            "code": "en",
            "pivot": {
              "fluency": "native"
            }
          }
        ]
      }
    }
  ],
  "total": 1
}

错误响应

404:project 不存在或不属于当前登录用户

{
  "message": "project not found"
}

POST /api/project_requests/choosed_list

  • 功能说明:获取当前用户某个 project 的已选中应征列表。
  • 变更说明:返回中的 artist 新增 languages

请求参数

字段类型必填说明
project_idnumberproject id
pagenumber页码,默认 1
sizenumber每页数量,默认 15

其他校验规则

  • project_id 必须属于当前登录用户
  • page >= 1
  • size >= 1 && size <= 50

请求示例

{
  "project_id": 101,
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 9002,
      "artist": {
        "id": 302,
        "cname": "artist-b",
        "languages": [
          {
            "id": 1,
            "code": "en",
            "pivot": {
              "fluency": "fluent"
            }
          }
        ]
      }
    }
  ],
  "total": 1
}

错误响应

404:project 不存在或不属于当前登录用户

{
  "message": "project not found"
}

POST /api/project_requests/choose

  • 功能说明:选择某个 project 应征并创建 worktask。
  • 变更说明:project 来源 worktask 创建时会同时生成 project_snap,并把 project 快照写入 busable_snap、project request 快照写入 reqable_snap,供后续 worktask 列表、详情、评价接口稳定读取。

请求参数

字段类型必填说明
project_request_idnumberproject request id
deadlinestringworktask 截止时间
namestringworktask 名称
name_langstringname 的语言代码

其他校验规则

  • project_request_id 必须存在于 project_requests.id
  • project_request_id 必须属于当前登录用户自己的 project
  • pendinguser_chosen 状态的应征允许被选择

请求示例

{
  "project_request_id": 9001,
  "deadline": "2026-04-07 00:00:00",
  "name": "Project Work Task",
  "name_lang": "en"
}

响应示例

{
  "ok": true
}

错误响应

400:应征状态不允许被选择

{
  "message": "Can not choose."
}

404:应征不存在或不属于当前登录用户

{
  "message": "Not found."
}

POST /api/work_tasks/list

  • 功能说明:获取当前用户的 worktask 列表。
  • 变更说明:project 来源 worktask 的 reqable 会返回 project_snap;service 来源 worktask 仍返回 service_snap

请求参数

字段类型必填说明
pagenumber页码,默认 1
sizenumber每页数量,默认 15
typestringworktask 类型,支持 serviceproject
statusstring[]worktask 状态列表
sort_bystring排序字段,支持 idcreated_atupdated_atdeadline
sort_orderstring排序方向,支持 descasc

其他校验规则

  • page >= 1
  • size >= 1 && size <= 50
  • type 仅支持 serviceproject

请求示例

{
  "type": "project",
  "status": ["pending"],
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 5001,
      "type": "project",
      "reqable": {
        "id": 9001,
        "project_snap": {
          "id": 61,
          "data": {
            "id": 101,
            "name": {
              "en": "Snapshot Project"
            }
          }
        }
      }
    }
  ],
  "total": 1
}

错误响应

422:参数校验失败

{
  "message": "The type field must be one of service, project."
}

GET /api/work_tasks/info

  • 功能说明:获取当前用户的 worktask 详情。
  • 变更说明:project 来源 worktask 的 reqable 改为返回 project_snap,并返回 project request 的币种、作品附件等信息,不再访问 service request 专属字段。

请求参数

字段类型必填说明
idnumberworktask id

其他校验规则

  • id 必须属于当前登录用户

请求示例

{
  "id": 5001
}

响应示例

{
  "data": {
    "id": 5001,
    "type": "project",
    "reqable": {
      "id": 9001,
      "currency": {
        "id": 1,
        "code": "USD"
      },
      "project_snap": {
        "id": 61,
        "data": {
          "id": 101
        }
      },
      "artworks": []
    }
  }
}

错误响应

404:worktask 不存在或不属于当前登录用户

{
  "message": "Not found"
}

POST /api/artist_rec_reviews/create_work_task_review

  • 功能说明:用户对 worktask 中的 artist 发起评价。
  • 变更说明:project 来源 worktask 的评价会关联 project_snap,写入 artist_rec_reviews.bizable_type = project_snap

请求参数

字段类型必填说明
work_task_idnumberworktask id
rating_scorenumber评分,范围 05
rating_contentstring评价内容
rating_content_langstringrating_content 的语言代码

其他校验规则

  • work_task_id 必须属于当前登录用户
  • 同一个 worktask 只能评价一次

请求示例

{
  "work_task_id": 5001,
  "rating_score": 4.5,
  "rating_content": "Great artist",
  "rating_content_lang": "en"
}

响应示例

{
  "ok": true,
  "data": {
    "work_task_id": 5001,
    "type": "project",
    "bizable_type": "project_snap"
  }
}

错误响应

403:重复评价

{
  "msg": "Already exists"
}

artist_center

POST /api/artist_center/project_request/create

  • 功能说明:artist 对公开 project 发起应征。
  • 变更说明:新增 is_anonymous;创建后会像 service request 一样为 detail 自动创建翻译记录。

请求参数

字段类型必填说明
project_idnumberproject id
currency_idnumber币种 id
detailstring应征说明
detail_langstringdetail 的语言代码
artworksnumber[]作品 id 列表,最多 5 个
budgetnumber报价
days_neednumber预计工期
is_anonymousboolean是否匿名应征,默认 false

其他校验规则

  • project_id 必须存在于 projects.id
  • currency_id 必须存在于 currencies.id
  • artworks 最大 5
  • days_need 必须为整数
  • 不允许对自己的 project 应征
  • 对同一个 project,pending / user_chosen 状态下不能重复应征

请求示例

{
  "project_id": 101,
  "currency_id": 1,
  "detail": "这是一条匿名应征",
  "detail_lang": "zh-CN",
  "artworks": [2001],
  "budget": 300,
  "days_need": 10,
  "is_anonymous": true
}

响应示例

{
  "ok": true,
  "data": {
    "id": 9001,
    "project_id": 101,
    "is_anonymous": true,
    "status": "pending"
  }
}

错误响应

400:重复应征或对自己的 project 应征

{
  "message": "Already requested. Please cancel first."
}

POST /api/artist_center/project_request/list

  • 功能说明:artist 获取自己的 project 应征列表。
  • 变更说明:列表对象显式返回 is_anonymous

请求参数

字段类型必填说明
pagenumber页码,默认 1
sizenumber每页数量,默认 15

其他校验规则

  • page >= 1
  • size >= 1 && size <= 50

请求示例

{
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 9001,
      "is_anonymous": true,
      "status": "pending"
    }
  ],
  "total": 1
}

错误响应

  • 无新增,沿用原有错误语义。

POST /api/artist_center/project_request/list_by_chosen

  • 功能说明:artist 获取自己被选中的 project 应征列表。
  • 变更说明:列表对象显式返回 is_anonymous

请求参数

字段类型必填说明
pagenumber页码,默认 1
sizenumber每页数量,默认 15

其他校验规则

  • page >= 1
  • size >= 1 && size <= 50

请求示例

{
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 9002,
      "is_anonymous": false,
      "status": "user_chosen"
    }
  ],
  "total": 1
}

错误响应

  • 无新增,沿用原有错误语义。

POST /api/artist_center/work_tasks/list

  • 功能说明:artist 获取自己的 worktask 列表。
  • 变更说明:project 来源 worktask 的 reqable 会返回 project_snap;service 来源 worktask 仍返回 service_snap

请求参数

字段类型必填说明
pagenumber页码,默认 1
sizenumber每页数量,默认 15
busable_typestringworktask 类型,支持 serviceproject
statusstring[]worktask 状态列表

其他校验规则

  • page >= 1
  • size >= 1 && size <= 50
  • busable_type 仅支持 serviceproject

请求示例

{
  "busable_type": "project",
  "status": ["pending"],
  "page": 1,
  "size": 15
}

响应示例

{
  "data": [
    {
      "id": 5001,
      "busable_type": "project",
      "reqable": {
        "id": 9001,
        "project_snap": {
          "id": 61,
          "data": {
            "id": 101
          }
        }
      }
    }
  ],
  "total": 1
}

错误响应

422:参数校验失败

{
  "message": "The busable type field must be one of service, project."
}

GET /api/artist_center/work_tasks/info

  • 功能说明:artist 获取自己的 worktask 详情。
  • 变更说明:project 来源 worktask 的 reqable 改为返回 project_snap,并返回 project request 的币种、作品附件等信息。

请求参数

字段类型必填说明
idnumberworktask id

其他校验规则

  • id 必须属于当前登录 artist

请求示例

{
  "id": 5001
}

响应示例

{
  "data": {
    "id": 5001,
    "busable_type": "project",
    "reqable": {
      "id": 9001,
      "currency": {
        "id": 1,
        "code": "USD"
      },
      "project_snap": {
        "id": 61,
        "data": {
          "id": 101
        }
      },
      "artworks": []
    }
  }
}

错误响应

404:worktask 不存在或不属于当前登录 artist

{
  "message": "Work task not found"
}

POST /api/artist_center/user_rec_reviews/create_work_task_review

  • 功能说明:artist 对 worktask 中的 user 发起评价。
  • 变更说明:type 只接受 serviceproject;project 来源 worktask 的评价会关联 project_snap,写入 user_rec_reviews.bizable_type = project_snap

请求参数

字段类型必填说明
work_task_idnumberworktask id
typestring评价对象类型,支持 serviceproject
rating_scorenumber评分,范围 05
rating_contentstring评价内容
rating_content_langstringrating_content 的语言代码

其他校验规则

  • work_task_id 必须属于当前登录 artist
  • type 必须与 worktask 的真实业务类型一致
  • 同一个 worktask 只能评价一次

请求示例

{
  "work_task_id": 5001,
  "type": "project",
  "rating_score": 4.2,
  "rating_content": "Reliable buyer",
  "rating_content_lang": "en"
}

响应示例

{
  "ok": true,
  "data": {
    "work_task_id": 5001,
    "type": "project",
    "bizable_type": "project_snap"
  }
}

错误响应

400type 与 worktask 真实业务类型不一致

{
  "message": "Review type mismatch"
}

兼容性说明

  • GET /api/projects/meta 已不再返回 formatscolor_modelsuse_rangestranslations,前端不要继续依赖这些字段。
  • project 创建/更新时,前端应改用以下字段:
    • color_mode
    • size_spec
    • prod_format
  • 其中 prod_format 与 service 一致,为数组字段;color_modesize_spec 为字符串字段。
  • GET /api/projects/info 不再返回旧的 formatscolorModels,前端应统一读取以下字段:
    • color_mode
    • size_spec
    • prod_format
  • GET /api/content/projects/info 也不应再依赖旧的 formatscolorModels 返回结构。
  • content project info 中:
    • project_requests 是非匿名应征列表
    • hidden_project_requests_count 才是匿名应征数量
  • artist 端匿名应征只影响 content project info 的公开展示,不影响 artist 自己查看其应征记录。
  • project 来源 worktask 相关接口现在统一返回 project_snap,前端不要再假设 reqable 一定包含 service_snapserviceRequestFiles
  • POST /api/artist_center/user_rec_reviews/create_work_task_reviewtype 只支持真实业务值:
    • service
    • project
  • task 当前没有业务用途,不应再作为该接口的传参值。