手机短信验证码系统 (2026-06-02)
变更概览
- 新增手机短信验证码发送和验证接口
- 新增绑定/解绑/修改手机号接口
- 支持国际手机号,通过
area_code 区号字段区分不同国家
- 验证码有效期默认 10 分钟
- 系统以邮箱为主账户体系,手机号仅用于短信消息通知
user/info 接口新增返回 phone 和 area_code 字段
业务流程
绑定手机号流程
用户首次绑定手机号,需要先获取验证码,验证通过后执行绑定。
解绑手机号流程
用户解绑手机号,支持通过手机短信或邮箱验证码两种方式验证。
修改手机号流程
修改手机号需要对新手机号进行验证码验证。
使用指引
前置条件
- 所有接口均需要用户登录(Bearer Token)
- 用户只能绑定一个手机号
典型使用场景
场景 1:用户首次绑定手机号
适用于用户注册后希望绑定手机号以接收短信通知。
接口调用顺序:
POST /send_phone_verify_code (type: bind_phone) - 发送验证码
POST /bind_phone - 绑定手机号(会自动验证验证码)
提示: bind_phone 接口内部会先验证验证码再执行绑定,无需单独调用 verify_phone_verify_code。
场景 2:用户更换手机号
适用于用户更换手机号后需要更新绑定。
接口调用顺序:
POST /send_phone_verify_code (type: change_phone) - 向新手机号发送验证码
POST /change_phone - 修改手机号(会自动验证验证码)
场景 3:用户解绑手机号
适用于用户不再需要短信通知,希望解绑手机号。
接口调用顺序:
POST /send_phone_verify_code (type: unbind_phone) - 向当前手机号发送验证码
POST /unbind_phone - 解绑手机号(会自动验证验证码)
场景 4:仅验证验证码有效性
适用于前端需要在执行操作前先验证用户输入的验证码是否正确。
接口调用顺序:
POST /send_phone_verify_code - 发送验证码
POST /verify_phone_verify_code - 验证验证码(不执行绑定/解绑操作)
接口列表
所有接口均需登录(Bearer Token)
相关接口变更
接口详情
POST /api/user/send_phone_verify_code
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|
phone | string | 是 | 手机号(纯数字,5-20位) |
area_code | string | 是 | 区号,如 +86、+1、+81 |
type | string | 是 | 验证码类型,见下方说明 |
type 取值
| 类型 | 说明 |
|---|
bind_phone | 首次绑定手机号 |
unbind_phone | 解绑手机号(验证原手机号) |
change_phone | 修改手机号(验证新手机号) |
请求示例
{
"phone": "13800138000",
"area_code": "+86",
"type": "bind_phone"
}
响应示例
错误码
| 错误码 | 说明 |
|---|
30014 | 短信发送失败 |
30016 | 手机号已被其他用户绑定(bind_phone/change_phone 时) |
30017 | 手机号与当前用户不匹配(unbind_phone 时) |
POST /api/user/verify_phone_verify_code
- 功能说明:验证手机短信验证码(仅验证,不执行操作)
- 鉴权:需要登录
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|
phone | string | 是 | 手机号 |
area_code | string | 是 | 区号 |
code | string | 是 | 验证码(6位数字) |
type | string | 是 | 验证码类型(同上) |
请求示例
{
"phone": "13800138000",
"area_code": "+86",
"code": "123456",
"type": "bind_phone"
}
响应示例
错误码
| 错误码 | 说明 |
|---|
30012 | 验证码不存在或已使用 |
30013 | 验证码已过期 |
30015 | 验证尝试次数过多(10次/2分钟) |
POST /api/user/bind_phone
- 功能说明:绑定手机号(首次绑定)
- 鉴权:需要登录
- 前置条件:用户尚未绑定手机号
- 注意: 此接口会自动验证验证码,无需单独调用
verify_phone_verify_code
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|
phone | string | 是 | 要绑定的手机号 |
area_code | string | 是 | 区号 |
code | string | 是 | 验证码 |
请求示例
{
"phone": "13800138000",
"area_code": "+86",
"code": "123456"
}
响应示例
{
"status": "success",
"message": "Bind Phone Success",
"code": 200
}
错误码
| 错误码 | 说明 |
|---|
30012 | 验证码不存在或已使用 |
30013 | 验证码已过期 |
30016 | 用户已绑定手机号,或手机号已被其他用户绑定 |
POST /api/user/unbind_phone
- 功能说明:解绑手机号
- 鉴权:需要登录
- 前置条件:用户已绑定手机号
- 注意: 此接口会自动验证验证码,无需单独调用
verify_phone_verify_code 或 verify_email_verify_code
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|
channel | string | 是 | 验证渠道:phone(手机短信)或 email(邮箱) |
code | string | 是 | 验证码 |
请求示例
使用手机验证码:
{
"channel": "phone",
"code": "654321"
}
使用邮箱验证码:
{
"channel": "email",
"code": "A1B2C3"
}
发送验证码接口
- 手机短信:
POST /api/user/send_phone_verify_code(type: unbind_phone)
- 邮箱:
POST /api/user/send_email_verify_code(type: unbind_phone)
响应示例
{
"status": "success",
"message": "Unbind Phone Success",
"code": 200
}
错误码
| 错误码 | 说明 |
|---|
30012 | 验证码不存在或已使用 |
30013 | 验证码已过期 |
30017 | 手机号与当前用户不匹配 |
POST /api/user/change_phone
- 功能说明:修改绑定的手机号
- 鉴权:需要登录
- 前置条件:用户已绑定手机号
- 注意: 此接口会自动验证验证码,无需单独调用
verify_phone_verify_code
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|
phone | string | 是 | 新手机号 |
area_code | string | 是 | 区号 |
code | string | 是 | 新手机号的验证码 |
请求示例
{
"phone": "13900139000",
"area_code": "+86",
"code": "111222"
}
响应示例
{
"status": "success",
"message": "Change Phone Success",
"code": 200
}
错误码
| 错误码 | 说明 |
|---|
30012 | 验证码不存在或已使用 |
30013 | 验证码已过期 |
30016 | 新手机号已被其他用户绑定 |
常用区号
| 国家/地区 | 区号 |
|---|
| 中国大陆 | +86 |
| 美国/加拿大 | +1 |
| 英国 | +44 |
| 日本 | +81 |
| 韩国 | +82 |
| 中国香港 | +852 |
| 中国台湾 | +886 |
注意事项
- 区号必填: 所有接口都需要传入
area_code 参数,前端默认传 +86
- 验证码有效期: 10 分钟,过期需重新获取
- 验证码覆盖: 同一手机号(区号+手机号)同一类型下,发送新验证码会自动使旧验证码失效
- 频率限制: 2 分钟内最多 10 次验证尝试,超出后需等待
- 简化流程:
bind_phone、unbind_phone、change_phone 接口会自动验证验证码,无需单独调用 verify_phone_verify_code
- 账户体系: 系统以邮箱为主账户体系,手机号仅用于短信消息通知,不作为登录凭证
相关接口变更
GET /api/user/info
- 变更说明:响应新增
phone 和 area_code 字段,用于展示用户当前绑定的手机号信息
响应新增字段
| 字段 | 类型 | 说明 |
|---|
phone | string|null | 绑定的手机号,未绑定时为 null |
area_code | string|null | 区号,未绑定时为 null |
响应示例(部分)
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"phone": "13800138000",
"area_code": "+86",
"avatar": "https://..."
}
POST /api/user/send_email_verify_code
- 变更说明:新增支持
type: unbind_phone,用于解绑手机号时发送邮箱验证码
- 鉴权:需要登录
- 前置条件:用户已绑定手机号,且传入的邮箱必须是当前用户的邮箱
新增 type 取值
| 类型 | 说明 |
|---|
unbind_phone | 解绑手机号(向当前用户邮箱发送验证码) |
请求示例
{
"email": "zhangsan@example.com",
"type": "unbind_phone"
}
错误码
| 错误码 | 说明 |
|---|
30017 | 用户未绑定手机号 |
30009 | 邮箱与当前用户不匹配 |
POST /api/user/verify_email_verify_code
- 变更说明:新增支持
type: unbind_phone,用于验证解绑手机号的邮箱验证码
新增 type 取值
请求示例
{
"email": "zhangsan@example.com",
"code": "A1B2C3",
"type": "unbind_phone"
}
短信通知发送
功能说明
当系统发送 SystemNotificationScene 通知时,会自动检查 notification_templates 是否关联了 smsTemplate。如果关联了且模板已审核通过(canSend()),则通过 EasySms 异步发送短信通知。
工作流程
支持短信通知的场景
以下场景在发送系统通知时,会同时发送短信(前提是用户绑定了手机号且开启了短信通知):
| 场景 | 接收方 | 短信内容摘要 |
|---|
service_request.created | artist | 新的服务申请 |
service_request.artist_accepted | user | 画师已接申请,请支付 |
service_request.artist_rejected | user | 服务申请已被拒绝 |
service_request.user_canceled | artist | 客户已取消申请 |
service_request.user_paid | artist | 已收到用户付款 |
project_request.created | artist, user | 企划邀请/提交成功 |
project_request.user_choosen | artist | 已被选中参与企划 |
project_request.artist_canceled | user | 画师已取消企划 |
project_request.artist_rejected | user | 画师已谢绝企划 |
project_request.artist_accepted | user | 画师已加入企划 |
project_request.user_paid | artist, user | 客户已支付/支付成功 |
worktask.file_created | user | 画师上传了新稿件 |
worktask.artist_canceled | user, group | 画师已取消约稿 |
worktask.user_canceled | artist, group | 客户已取消约稿 |
worktask.user_confirm_stage | artist, group | 客户已确认节点 |
worktask.finished | artist, user, group | 约稿已完成 |
work_task_file_change_request.created | artist | 客户提出修改意见 |
work_task_file_change_request.updated | artist | 客户提出修改意见 |
admin.joined_group | group | 创作助手已加入群组 |
group.reminder | group | 发送了提醒 |
price_change.* | user/artist/group | 改价相关 |
deadline_change.* | user/artist/group | 交稿日期变更相关 |
artist_rec_review.created | artist | 收到客户评价 |
user_rec_review.created | user | 收到画师评价 |
user_applicant.accepted | user | 通过画师审核 |
wallet.alipay_publish | user | 支付宝支付公告 |
report.processed | user | 举报处理完成 |
SMS 模板变量格式
短信模板内容使用 ${variable} 语法,变量值从通知的 meta 数据中提取:
(PIPIPEN) Commission-${work_task_id} | 画师上传了新的稿件,请及时查看。
常用变量:
| 变量 | 说明 |
|---|
${work_task_id} | 工作任务 ID |
${service_id} | 服务 ID |
注意事项
- 异步发送: 短信通过
SendSmsJob 异步发送,不阻塞主流程
- 前置条件: 用户必须绑定手机号(
phone + area_code)才会发送短信
- 模板审核: smsTemplate 需要
platform_status 为 approved 且有 platform_template_code 才会发送
- 通知开关: 受用户通知设置中的
sms 开关控制