API 更新日志
要求
只整理 api 相关的改动,用于和前端人员对接使用。
服务可见性 visibility_status (2026-01-30)
1. 服务管理(Artist)
接口前缀: /api/artist_center
变更点
Service新增visibility_status字段(enum):public | unlisted | draft- 创建/更新接口支持传入
visibility_status
创建/更新请求示例
POST /services/create
POST /services/update
2. 服务列表/搜索(Content)
接口前缀: /api/content
变更点
- 列表/搜索仅返回
visibility_status=public的服务 unlisted与draft不会出现在列表/搜索中
3. 服务详情(Content)
POST /service/info
变更点
public:所有人可访问unlisted:仅通过info接口可访问(不会出现在列表/搜索)draft:仅作者本人可通过info接口访问
服务 Right Templates 多选与加价百分比 (2026-01-29)
1. 服务管理(Artist)
接口前缀: /api/artist_center
变更点
Service的right_template_id被移除,改为多选right_templates。right_templates为数组对象,包含id与markup_percent(整数,百分比)。
创建/更新请求示例
POST /services/create
POST /services/update
Service 详情返回变更
GET /services/info
新增返回字段:
right_templates(数组)idnamemarkup_percent(整数百分比)right_tree(权限树)
2. 服务详情(Content)
接口前缀: /api/content
变更点
GET /service/info返回right_templates(数组),不再返回rightTemplate单对象。
3. Service Request 创建(User)
接口前缀: /api
POST /service_requests/create
新增请求字段
right_template_id(单个 ID,用户选择的模板 ID,必须属于该 service)
4. Service Request 返回(User / Artist / Admin)
变更点
- Service Request 统一通过快照返回(
serviceSnap) serviceSnap.data.right_templates存储 请求创建时服务的全部 right_templates 快照- Service Request 本体仅存
right_template_id,前端需从serviceSnap.data.right_templates匹配对应模板详情 - 不要再使用 Service 实时关联数据来展示已创建请求的权益
Service Request 返回示例:
5. 前端对接说明 / 字段对照
serviceSnap为该 Service Request 的快照数据(请求创建时的服务数据)。- 用户选择模板:读取
right_template_id(可能为null,表示未选择)。 - 服务全量模板:读取
serviceSnap.data.right_templates。 - 展示与计算应基于快照字段,不再依赖实时
service关联数据。
字段对照(Service Request 返回):
6. 计算规则(前端处理)
markup_percent为整数百分比。- 多个模板加价为 求和,后端只提供关联数据,不计算最终金额。
- 计算基数为
services.price(用于前端展示)。
产品商店功能 (2025-12-03)
1. 新增产品管理接口(卖家端)
接口前缀: /api/artist_center
产品基础管理
POST /products/create- 创建产品POST /products/list- 产品列表POST /products/info- 产品详情POST /products/update- 更新产品POST /products/delete- 删除产品
产品规格管理
POST /product_options/create- 创建规格POST /product_options/list- 规格列表POST /product_options/update- 更新规格POST /product_options/delete- 删除规格
产品展示管理
POST /product_showcases/create- 创建展示(复用 ServiceShowcase 结构)POST /product_showcases/delete- 删除展示
产品文件管理
POST /product_option_files/create- 上传文件POST /product_option_files/list- 文件列表POST /product_option_files/update- 更新文件(自动版本管理)POST /product_option_files/delete- 删除文件
2. 新增产品购买接口(买家端)
接口前缀: /api
产品浏览(公开接口)
POST /content/products/list- 产品列表(已更新,新增 options 关联)POST /content/products/info- 产品详情(已更新,新增 options 关联)
购买管理(需登录)
POST /product_purchases/create- 创建购买订单POST /product_purchases/list- 购买订单列表POST /product_purchases/info- 购买订单详情POST /product_purchases/cancel- 取消购买订单POST /product_purchases/files- 获取可下载文件
3. 数据模型变更
新增表
product_options- 产品规格表product_showcases- 产品展示表(复用 ServiceShowcase 结构)product_option_files- 产品规格文件表product_file_histories- 文件历史记录表product_purchases- 产品购买表
更新表
products- 新增字段:user_id- 用户IDcategory_id- 分类IDstatus- 产品状态
4. 核心功能特性
多规格支持
- 一个产品可以有多个规格
- 每个规格独立定价和管理库存
- 支持规格封面图
库存管理
- 支持无限库存(unlimited)和固定库存(fixed)
- 使用数据库行锁防止超卖
- 订单创建时预扣库存
- 订单取消/过期时自动回滚库存
文件版本管理
- 完整的文件历史记录(创建/更新/删除)
- 自动版本号管理
- 支持更新说明(change_note)
时间访问控制
- 用户只能访问购买时间之后创建/更新的文件
- 文件更新自动对已购买用户可见
- 基于
created_at时间戳的访问控制
订单超时处理
- 订单创建后15分钟内未支付自动过期
- 定时任务每5分钟检查并处理过期订单
- 过期订单自动取消并回滚库存
多态关系
- Order 通过 busable 关联 ProductPurchase
- 与 WorkTask 订单使用相同的订单系统
5. 枚举定义
ProductStatus(产品状态)
StockType(库存类型)
FileAction(文件操作)
PurchaseStatus(购买状态)
6. 业务流程
卖家发布产品
- 创建产品基本信息
- 添加产品展示内容(图片/视频)
- 创建产品规格(价格、库存)
- 为规格上传可下载文件
- 设置产品状态为上架
买家购买流程
- 浏览产品列表/详情
- 选择规格创建购买订单(预扣库存)
- 15分钟内完成支付
- 支付成功后可下载文件
- 后续文件更新自动可见
7. 注意事项
- 库存控制: 固定库存模式下,库存不足时无法创建订单
- 文件版本: 文件更新会增加版本号,所有已购买用户可见
- 订单超时: 15分钟未支付订单会自动取消
- 规格删除: 存在已支付订单的规格无法删除
- 文件访问: 只有已支付订单才能访问下载文件
- 多语言: 产品名称、详情、规格名称、文件名称都支持多语言
- 无外键约束: 遵循项目标准,使用冗余字段优化查询
异常处理系统优化
1. 统一异常处理机制
- 变更范围: 所有 API 接口的错误响应
- 主要改进:
- 引入类型安全的
ErrorCode枚举替代字符串错误码 - 实现统一的异常处理架构,提供一致的错误响应格式
- 新增具体异常类型:
ValidationException、AuthorizationException、ResourceNotFoundException
- 引入类型安全的
2. HTTP 状态码规范化
- 验证错误: 统一返回 HTTP 400 状态码(之前部分接口返回 422)
- 权限错误: 返回 HTTP 403 状态码
- 资源未找到: 返回 HTTP 404 状态码
3. 错误响应格式
所有 API 错误响应现在遵循统一格式:
提现账户管理
1. 提现账户解绑
-
接口:
POST /withdraw_accounts/unbind: 用于执行提现账户的解绑操作。POST /withdraw_accounts/unbind_check: 新增接口,用于在解绑前预先检查是否满足条件。POST /withdraw_accounts/delete: 此路由已被移除。
-
作用: 允许用户解绑已绑定的提现账户,并提供了预检查功能以提升用户体验。
-
请求参数 (
unbind和unbind_check):
- 错误响应 (
unbind和unbind_check):
- 主要逻辑与变更:
- 前置检查: 解绑前会进行严格的安全检查,确保:
- 关联钱包余额为零。
- Stripe 账户余额为零。
- 没有正在处理中的工作任务。
- 错误处理: 优化了错误处理机制,当检查失败时,会返回包含明确
code和message的 JSON 响应。 - 数据库操作: 检查通过后,操作会软删除提现账户记录并删除关联的钱包记录。
- 逻辑优化: 将钱包余额、工作任务和 Stripe 余额检查逻辑封装为独立函数,提高了代码的可读性和维护性。增加了账户绑定状态检查,确保只有已绑定的账户才能进行解绑检查。
- 修复: 修复了余额不足时的错误提示信息。
- 前置检查: 解绑前会进行严格的安全检查,确保:
2. 提现账户列表查询
- 接口:
POST /withdraw_accounts/list - 作用: 增强了提现账户列表的筛选和关联数据查询能力。
- 新增查询参数:
- 返回数据变更:
- 在每个提现账户对象中,新增了
wallet字段,包含了完整的关联钱包信息。
- 在每个提现账户对象中,新增了
3. Stripe Connect 账户创建
- 接口:
POST /stripe/create_connect_account_link - 作用: 创建 Stripe Connect 账户的链接,用于引导用户完成 Stripe 账户的注册或关联流程。
- 新增请求参数:
- 主要逻辑与变更:
- 参数验证: 对
callback,country, 和service_agreement进行验证。 - 重复绑定检查: 防止用户重复绑定同类型的 Stripe 账户。
- 清理未完成的账户: 自动删除未完成的绑定记录。
- 动态创建账户: 根据
country和service_agreement创建不同能力的 Stripe 账户。 - 安全增强: 使用带签名的回调 URL 和在生产环境强制 HTTPS。
- 参数验证: 对
4. 获取 Stripe 仪表板链接
- 接口:
GET /stripe/stripe_dashboard_link - 作用: 为用户生成一个登录到其 Stripe Express 账户仪表板的安全链接。
- 请求参数:
- 主要逻辑:
- 验证提现账户的归属和状态。
- 调用 Stripe API 生成一次性的登录链接。
5. Stripe Connect 账户回调处理
- 接口:
GET /stripe/create_connect_account_return - 作用: 这是 Stripe Connect 账户创建流程完成后,Stripe 回调的接口。它负责处理 Stripe 返回的数据,更新用户提现账户的状态,并创建相应的钱包。
- 请求参数:
- 主要逻辑:
- 签名验证: 验证回调 URL 的签名,确保请求的合法性。
- 账户查找与更新: 根据
account_id查找对应的用户提现账户,并将其bind_status从Pending更新为Successed。 - 获取 Stripe 账户信息: 调用 Stripe API 获取完整的账户信息,包括默认货币和支持邮箱等。
- 更新提现账户信息: 使用获取到的 Stripe 账户信息更新用户提现账户的
currency_id和stripe_email字段。 - 创建用户钱包: 如果用户还没有对应货币的钱包,则会创建一个新的钱包。
- 事务处理: 所有数据库操作都在事务中进行,确保数据一致性。
- 修复: 确保在创建钱包后立即更新提现账户的
wallet_id字段。
钱包管理
1. 钱包列表查询
- 接口:
POST /wallets/list - 作用: 在钱包列表中直接返回关联的提现账户信息。
- 返回数据变更:
- 在每个钱包对象中,新增了
withdrawAccount字段,包含了已成功绑定的提现账户信息。
- 在每个钱包对象中,新增了
2. 钱包提现
- 接口:
POST /wallet_withdraws/create - 作用: 用户发起提现请求,将钱包余额提现到指定的提现账户。
- 请求参数:
- 错误响应:
- 主要逻辑与变更:
- 安全验证: 验证用户密码和提现账户的有效性。
- 余额检查: 确保钱包有足够的余额进行提现。
- 事务处理: 创建提现记录和钱包交易记录的操作在数据库事务中进行,确保数据一致性。
- 错误处理: 使用统一的异常处理机制,返回标准化的错误响应格式。
3. Stripe 连接账户支付和转账
stripe_connect_payout
- 接口:
POST /wallet_withdraws/stripe_connect_payout - 作用: 用于处理 Stripe 连接账户的支付操作,即将资金从连接账户提现到关联的银行账户。
- 请求参数:
- 主要逻辑:
- 安全验证: 验证用户密码和提现账户的有效性。
- 余额检查: 确保 Stripe 账户有足够的余额进行提现。
- Stripe API 调用: 调用 Stripe 的 Payouts API 执行提现操作。
- 错误处理: 如果 Stripe 账户余额不足,将返回
UserWithdrawStripeBalanceNotEnough(50004) 错误。
stripe_connect_transfer
- 接口:
POST /wallet_withdraws/stripe_connect_transfer - 作用: 用于处理 Stripe 连接账户的转账操作,即将资金从平台账户转账到连接账户。
- 请求参数:
- 错误响应:
- 主要逻辑:
- 安全验证: 验证用户密码和提现账户的有效性。
- 余额检查: 确保钱包有足够的余额进行转账。
- Stripe验证: 验证Stripe账户类型、绑定状态和服务协议类型。
- Stripe API 调用: 调用 Stripe 的 Transfers API 执行转账操作。
- 错误处理: 使用统一的异常处理机制,返回标准化的错误响应格式。
邮箱验证码管理
1. API 接口重构
已废弃的独立接口:
POST /user/send_sign_up_code- 发送注册验证码 (已移除)POST /user/verify_sign_up_code- 验证注册验证码 (已移除)POST /user/send_forget_psw_code- 发送忘记密码验证码 (已移除)POST /user/verify_forget_psw_code- 验证忘记密码验证码 (已移除)POST /withdraw_accounts/send_email_code- 发送提现账户验证码 (已移除)POST /user/send_change_email_code- 发送修改邮箱验证码 (已移除)
统一验证码接口:
POST /user/send_email_verify_code- 统一发送验证码接口POST /user/verify_email_verify_code- 统一验证验证码接口
发送验证码接口 (send_email_verify_code)
- 接口:
POST /user/send_email_verify_code - 作用: 根据不同业务场景向指定邮箱发送验证码
- 认证要求: 无需登录(公开接口)
请求参数:
type字段可选值:
- 未登录用户:
sign_up(注册),forget_psw(忘记密码) - 已登录用户:
manage_withdraw_account(管理提现账户),change_email_org(原邮箱验证),change_email_new(新邮箱验证)
成功响应:
验证验证码接口 (verify_email_verify_code)
- 接口:
POST /user/verify_email_verify_code - 作用: 验证用户输入的验证码是否正确
- 认证要求: 无需登录(公开接口)
请求参数:
type字段可选值:(与发送接口相同)
- 未登录用户:
sign_up(注册),forget_psw(忘记密码) - 已登录用户:
manage_withdraw_account(管理提现账户),change_email_org(原邮箱验证),change_email_new(新邮箱验证)
成功响应:
2. 业务流程整合
注册流程:
- 调用统一验证码接口发送和验证
POST /user/sign_up中直接使用EmailVerifyCodeService::use()方法标记验证码为已使用
密码重置流程:
- 调用统一验证码接口发送和验证
POST /user/forget_psw_change中直接使用EmailVerifyCodeService::use()方法标记验证码为已使用
提现账户管理流程:
- 调用统一验证码接口发送和验证
POST /withdraw_accounts/create中先验证再使用:verify()→use()
修改邮箱流程:
- 分为两步验证:原邮箱验证(
change_email_org)和新邮箱验证(change_email_new) POST /user/change_email中直接验证和使用新邮箱验证码:verify()→use()- 使用统一验证码接口替代原有的独立修改邮箱验证码接口
3. 邮箱验证逻辑优化
发送验证码时的邮箱状态检查:
- 注册验证码 (
sign_up) 和 新邮箱验证码 (change_email_new): 检查邮箱是否已存在,存在则抛出SystemEmailVerifyEmailExists错误 - 忘记密码验证码 (
forget_psw): 检查邮箱是否存在,不存在则抛出SystemEmailVerifyEmailNotFound错误 - 原邮箱验证码 (
change_email_org) 和 提现账户验证码 (manage_withdraw_account): 无需邮箱状态检查
修改邮箱接口优化 (POST /user/change_email):
- 移除了原有的独立发送验证码逻辑,统一使用
EmailVerifyCodeService - 简化了验证流程,直接验证和使用新邮箱验证码
- 优化了错误处理,使用统一的异常处理机制
4. 安全机制与限制
- 验证码格式: 6位随机数字(100000-999999)
- 有效期: 1小时过期时间
- 频率限制: 单个邮箱+验证类型组合2分钟内最多验证10次
- 唯一性: 每次发送新验证码会自动删除该邮箱同类型的旧验证码
- 状态管理: 验证码状态流转
SENT→VERIFIED→USED - 数据库事务: 确保验证码创建和清理的原子性操作
5. 实现优化
- 竞态条件修复: 使用数据库事务确保验证码创建和旧验证码清理的原子性
- 数据一致性: 先创建新验证码,再删除同类型旧验证码,避免并发导致的数据不一致
- 记录使用时间: 新增
used_at字段记录验证码使用时间 - 防刷保护: 验证失败次数限制和缓存机制
6. 错误响应
7. 数据库优化
- 新增字段:
used_at时间戳字段记录验证码使用时间 - 索引优化:
idx_email_type_status: 复合索引用于查询特定状态的验证码idx_email_type_code: 复合索引用于验证码校验idx_expired_at: 单字段索引用于清理过期数据
Model 定义
UserWithdrawAccount (用户提现账户)
- 表名:
user_withdraw_accounts - 主要字段:
id: integer, 主键user_id: integer, 用户 IDtype: enum (UserWithdrawAccountType), 提现账户类型 (例如:Alipay,Stripe)bind_status: enum (UserWithdrawAccountStatus), 绑定状态 (例如:Successed,Pending,Unbound)currency_id: integer, 关联的货币 IDalipay_account: string, 支付宝账号 (如果type是 Alipay)alipay_name: string, 支付宝姓名 (如果type是 Alipay)stripe_connect_account_id: string, Stripe Connect 账户 ID (如果type是 Stripe)stripe_service_agreement: enum (UserWithdrawStripeServiceAgreement), Stripe 服务协议类型 (例如:Full,Recipient)stripe_email: string, Stripe 账户邮箱unbound_at: datetime, 解绑时间 (软删除时记录)deleted_at: datetime, 软删除时间stripe_balance: object, Stripe 账户余额信息 (通过UserWithdrawAccount模型中的stripe_balance属性获取)
- 关联关系:
user(): 属于User模型 (多对一)currency(): 属于Currency模型 (多对一)wallet(): 属于Wallet模型 (多对一)
Wallet (钱包)
- 表名:
wallets - 主要字段:
id: integer, 主键user_id: integer, 用户 IDcurrency_id: integer, 关联的货币 IDbalance: decimal, 余额usage: enum (WalletUsage), 钱包用途deposit_type: enum (WalletDepositType), 存款类型stripe_connect_account_id: string, Stripe Connect 账户 ID (如果关联 Stripe)deleted_at: datetime, 软删除时间
- 关联关系:
user(): 属于User模型 (多对一)currency(): 属于Currency模型 (多对一)transactions(): 拥有多个WalletTransaction(一对多)withdrawAccounts(): 拥有多个UserWithdrawAccount(一对多)withdrawAccount(): 拥有一个UserWithdrawAccount(一对一,且bind_status为Successed)
Currency (货币)
- 表名:
currencies - 主要字段:
id: integer, 主键code: string, 货币代码 (例如:USD,CNY)symbol: string, 货币符号name: string, 货币名称
- 辅助属性:
is_zero_decimal: boolean, 是否是零小数货币 (例如: 日元)is_can_withdraw: boolean, 是否可提现货币is_default_withdraw: boolean, 是否默认提现货币
枚举 (Enums) 定义
UserWithdrawAccountType (用户提现账户类型)
- 类型:
string - 可能值:
alipay: 支付宝stripe: Stripe
UserWithdrawAccountStatus (用户提现账户状态)
- 类型:
string - 可能值:
pending: 待处理successed: 成功failed: 失败unbound: 已解绑
UserWithdrawStripeServiceAgreement (用户提现 Stripe 服务协议)
- 类型:
string - 可能值:
full: 完整服务协议recipient: 收款人服务协议
WalletUsage (钱包用途)
- 类型:
string - 可能值:
deposit: 艺术家收款钱包,用于提现credit: 用户礼品卡,仅用于支付抵扣plat_fee: 艺术家平台手续费,仅用于抵扣平台手续费
WalletDepositType (钱包存款类型)
- 类型:
string - 可能值:
alipay: 支付宝stripe_full: Stripe 完整服务协议stripe_recipient: Stripe 收款人服务协议
ErrorCode (错误码)
- 类型:
int

