# YwxApp 标准 App 接口 v1 测试文档 > 适用对象:App / 小程序 / 第三方客户端联调与测试(Apifox / Postman) > 基础路径:`/api/v1`(建议环境变量 `base_url = http://你的域名/api/v1`) > 最后更新:2026-08-17 --- 字段 值 uid 88889464 account testuser password Test@123456 status 1(正常) gid 2(普通会员) ## 1. 通用约定 ### 1.1 响应结构(统一 JSON) 所有接口均返回以下结构(强制 JSON,不受请求类型影响): ```json { "code": 0, "msg": "success", "data": {}, "timestamp": 1765900000 } ``` | 字段 | 类型 | 说明 | |---|---|---| | `code` | int | `0`=成功;`1`=业务失败;`401`=未登录/鉴权失败 | | `msg` | string | 提示信息 | | `data` | object/null | 业务数据;登录类接口含 `access_token` 等 | | `timestamp` | int | 服务器时间戳(秒) | ### 1.2 业务 code 与 HTTP 状态码 - 业务 `code` 与 HTTP 状态码**解耦**:未登录时返回 `code=401` 且 HTTP 状态也为 `401`。 - 业务失败时 HTTP 状态保持 `200`,仅 `code` 非 0(除 401 外)。 ### 1.3 鉴权(Bearer Token) - 登录 / 注册成功后,响应 `data` 内含 `access_token`、`refresh_token`、`expires_in`。 - 需登录接口在请求头携带: ``` Authorization: Bearer ``` - 跨域:路由已挂载 `AllowCrossDomain` 中间件,前端联调无 CORS 问题。 ### 1.4 接口清单一览 | 接口 | 方法 | 鉴权 | 说明 | |---|---|---|---| | `/common/init` | GET | 否 | 启动初始化(站点/注册方式/版本) | | `/common/config` | GET | 否 | 站点配置 | | `/common/upload` | POST | 是 | 文件上传 | | `/user/register` | POST | 否 | 注册 | | `/user/login` | POST | 否 | 账号密码登录 | | `/user/loginBySms` | POST | 否 | 短信验证码登录(未注册自动注册) | | `/user/refresh` | POST | 否(refresh_token) | 刷新 access_token | | `/user/logout` | POST | 是 | 退出登录 | | `/user/profile` | GET | 是 | 获取会员资料 | | `/user/updateProfile` | POST | 是 | 修改资料 | | `/user/changePwd` | POST | 是 | 修改密码 | | `/user/resetPwdBySms` | POST | 否 | 短信重置密码 | | `/user/resetPwdByEmail` | POST | 否 | 邮箱重置密码 | | `/sms/send` | POST | 否 | 发送短信验证码 | | `/sms/check` | POST | 否 | 校验短信验证码 | | `/ems/send` | POST | 否 | 发送邮箱验证码 | | `/ems/check` | POST | 否 | 校验邮箱验证码 | --- ## 2. 接口详情 ### 2.1 Common #### GET /common/init 启动初始化,App 冷启动首屏调用。 - 响应示例: ```json { "code": 0, "msg": "success", "data": { "site": {...}, "register_type": "all", "version": "1.0.0" }, "timestamp": 1765900000 } ``` #### GET /common/config 站点配置(公开)。 - 响应 `data` 结构同 `init` 中的 `site` 字段。 #### POST /common/upload 文件上传(需登录),`Content-Type: multipart/form-data`,字段名 `file`。 - 成功响应: ```json { "code": 0, "msg": "上传成功", "data": { "url": "/storage/uploads/xxx.png", "path": "uploads/xxx.png" }, "timestamp": 1765900000 } ``` --- ### 2.2 User #### POST /user/register 注册账号。 - 请求体(x-www-form-urlencoded):`account`(必填), `password`(必填,≥6位), `nickname`(可选), `mobile`(可选), `email`(可选), `captcha`(可选, 手机号注册时必填且需先调 `/sms/send`) - 成功响应(自动签发 token): ```json { "code": 0, "msg": "注册成功", "timestamp": 1765900000, "data": { "uid": 1, "account": "testuser", "nickname": "测试", "access_token": "...", "refresh_token": "...", "expires_in": 3600, "token_type": "Bearer" }, "access_token": "...", "access_expired": 3600, "refresh_token": "...", "refresh_expired": 86400 } ``` > 说明:token 同时出现在 `data` 内与响应顶层(供不同客户端习惯取用)。 #### POST /user/login 账号密码登录。 - 请求体:`account`(必填), `password`(必填) - 响应结构同 `register`。 #### POST /user/loginBySms 短信验证码登录;手机号未注册则自动注册。 - 请求体:`mobile`(必填), `captcha`(必填) - 响应结构同 `register`,自动注册时初始密码为随机值(仅短信登录可用)。 #### POST /user/refresh 使用 refresh_token 换取新 access_token。 - 请求体:`refresh_token`(必填) - 成功响应: ```json { "code": 0, "msg": "刷新成功", "data": { "access_token": "...", "refresh_token": "...", "expires_in": 3600, "token_type": "Bearer" }, "timestamp": 1765900000 } ``` - 失败(refresh_token 无效/过期):`code=401`,HTTP 401。 #### POST /user/logout 退出登录(需登录)。 - 响应:`{ "code": 0, "msg": "已登出", "data": [], "timestamp": 1765900000 }` #### GET /user/profile 获取当前会员资料(需登录,Header 带 `Authorization: Bearer `)。 - 响应 `data` 字段(password/delete_at 已隐藏,附加 status_text/last_login): ```json { "code": 0, "msg": "success", "data": { "uid": 1, "account": "testuser", "nickname": "测试", "mobile": "", "email": "", "avatar": "", "status": 1, "status_text": "正常", "last_login": "...", "create_at": 1765900000 }, "timestamp": 1765900000 } ``` #### POST /user/updateProfile 修改资料(需登录)。 - 请求体(均可选):`nickname`, `mobile`, `email`, `avatar` - 响应 `data` 为更新后的会员数组。 #### POST /user/changePwd 修改密码(需登录)。 - 请求体:`oldpassword`(必填), `newpassword`(必填,≥6位) - 错误示例:`{ "code": 1, "msg": "原密码错误", "timestamp": 1765900000 }` #### POST /user/resetPwdBySms 短信重置密码(免登录)。 - 请求体:`mobile`(必填), `captcha`(必填), `newpassword`(必填,≥6位) #### POST /user/resetPwdByEmail 邮箱重置密码(免登录)。 - 请求体:`email`(必填), `captcha`(必填), `newpassword`(必填,≥6位) --- ### 2.3 验证码 #### POST /sms/send 发送短信验证码。 - 请求体:`mobile`(必填), `event`(必填, 如 register/login/mobilelogin/resetpwd/changepwd/changemobile) - 频率限制:同手机号 60 秒内不可重复;同 IP 1 小时上限 5 条。 #### POST /sms/check 校验短信验证码。 - 请求体:`mobile`(必填), `event`(必填), `captcha`(必填) #### POST /ems/send 发送邮箱验证码。请求体:`email`(必填), `event`(可选, 默认 register)。 #### POST /ems/check 校验邮箱验证码。请求体:`email`(必填), `event`(可选), `captcha`(必填)。 --- ## 3. Apifox / Postman 联调步骤 1. 导入集合文件 `docs/postman/ywxapp-api-v1.postman_collection.json`(Postman 直接导入;Apifox 选择「导入 → Postman 格式」)。 2. 设置环境/变量 `base_url` 为你的本地域名,例如 `http://localhost/api/v1`。 3. 先调试公开接口 `GET /common/init`,确认返回 JSON(非 HTML)即链路通。 4. 调 `POST /user/login`(或先 `register`),登录成功后在 Tests 脚本里自动把 `access_token` 写入变量 `token`。 5. 之后调 `/user/profile` 等需登录接口,自动带 `Authorization: Bearer {{token}}`。 6. 故意不带 token 调 `/user/profile`,应得 `code=401` + HTTP 401。 ### 排错 - **全部 404**:清除路由缓存 `runtime/route_list.php` 后重试(TP 缓存机制)。 - **返回 HTML 而非 JSON**:确认路径为小写 `/api/v1/...`,且域名正确(非后台 admin 域)。 - **401 但 token 有效**:检查 token 是否过期,`/user/refresh` 用 `refresh_token` 换新;注意 access_token 默认有效期见 `expires_in`。 --- ## 4. 测试 Checklist(建议用例) - [ ] init / config 公开可访问且返回 JSON - [ ] register 正常注册并拿到 token - [ ] register 重复账号 → `code=1` 提示「该账号已被注册」 - [ ] login 密码错误 → `code=1` 提示「密码错误」 - [ ] login 成功后 profile 返回会员资料 - [ ] profile 不带 token → `code=401` HTTP 401 - [ ] refresh 用 refresh_token 换发新 token 成功 - [ ] refresh 用错误 token → `code=401` - [ ] changePwd 原密码错误 → `code=1` - [ ] logout 成功 → `code=0`