# 新项目 API 规格(/v1) ## 0. 通用约定 ### 0.1 Base URL 与租户 - Base:`/v1` - 多租户路径 `/t/:tenant_code/v1` 为后续规划,待统一改造后启用 ### 0.2 认证 - 现实现:OTP 登录 + JWT,所有受保护接口需携带 `Authorization: Bearer ` - Admin:同上(Bearer Token) ### 0.3 响应 - 成功:`200`(或 201/204),JSON - 业务错误:`400`(含错误信息) - 未登录:`401` - 无权限:`403` - 不存在:`404` --- ### 0.4 当前实现说明 - 当前端到端实现已切换为 OTP + JWT;以下 WeChat OAuth/H5 内容为历史规格,待后续统一重写 --- ## 1. OTP 登录 ### 1.1 发送验证码 `POST /auth/otp` Body: ```json { "phone": "13800000000" } ``` ### 1.2 登录/注册 `POST /auth/login` Body: ```json { "phone": "13800000000", "otp": "1234" } ``` --- ## 2. WeChat H5 内容与用户 ### 2.1 曲谱列表(仅已发布) `GET /posts` Query: - `page`(默认 1) - `limit`(默认 10) - `keyword`(可选) Response(示例结构): ```json { "items": [ { "id": 1, "title": "标题", "description": "简介", "price": 19900, "discount": 80, "views": 10, "likes": 0, "tags": ["tag"], "head_images": ["https://signed-url..."], "bought": false, "recharge_wechat": "联系微信(可选)" } ], "total": 123, "page": 1, "limit": 10 } ``` ### 2.2 曲谱详情(仅已发布) `GET /posts/:id/show` Response:同 `PostItem`,额外含 `content` ### 2.3 获取播放 URL `GET /posts/:id/play` Response: ```json { "url": "https://signed-url..." } ``` 规则:未购买返回 `metas.short=true` 的视频 URL;已购买返回 `metas.short=false` 的视频 URL。 ### 2.4 我的已购 `GET /posts/mine` Query:`page`、`limit`、`keyword`(可选) Response:同分页结构 ### 2.5 余额购买 `POST /posts/:id/buy` Response(余额支付成功): - 可直接返回 `{ "ok": true }` 或返回订单信息(由你最终 UI/交互决定) 错误: - 余额不足:`400`,message 建议为“余额不足,请联系管理员充值” - 已购买:`400` ### 2.6 用户资料 `GET /users/profile` Response: ```json { "id": 1001, "created_at": "2025-01-01T00:00:00Z", "username": "xx", "avatar": "url", "balance": 10000 } ``` ### 2.7 修改用户名 `PUT /users/username` Body: ```json { "username": "新昵称" } ``` 约束:trim 后不能为空;最大 12 个字符(按 rune 计)。 ### 2.8 JS-SDK 配置 `GET /wechats/js-sdk?url=` Response:JS-SDK 签名数据(结构按前端 `weixin-js-sdk` 需要输出) --- ## 3. Admin(租户后台) ### 3.1 登录 `POST /admin/auth` Body: ```json { "username": "admin", "password": "******" } ``` Response: ```json { "token": "..." } ``` ### 3.2 仪表盘统计 `GET /admin/statistics` Response: ```json { "post_draft": 0, "post_published": 0, "media": 0, "order": 0, "user": 0, "amount": 0 } ``` ### 3.3 媒体库 `GET /admin/medias?page=&limit=&keyword=` `GET /admin/medias/:id`:302 跳转到 OSS 签名 URL `DELETE /admin/medias/:id`:删除 OSS 对象并软删/删 DB 记录(最终由你决定) ### 3.4 上传(预签名) `GET /admin/uploads/pre-uploaded-check/:md5.:ext?mime=` Response: ```json { "exists": false, "pre_sign": { "...": "..." } } ``` 说明: - `md5` 在租户内去重 - OSS Key:`quyun//.` `POST /admin/uploads/post-uploaded-action` Body: ```json { "originalName": "a.mp4", "md5": "...", "mimeType": "video/mp4", "size": 123 } ``` ### 3.5 曲谱管理 `GET /admin/posts?page=&limit=&keyword=` `POST /admin/posts`、`PUT /admin/posts/:id` Body(示例): ```json { "title": "标题", "head_images": [1,2,3], "price": 19900, "discount": 80, "introduction": "简介", "content": "正文", "status": 1, "medias": [10,11,12] } ``` `GET /admin/posts/:id`:返回曲谱 + medias 列表 `DELETE /admin/posts/:id` `POST /admin/posts/:id/send-to/:userId`:赠送曲谱(写入授权记录) ### 3.6 用户管理 `GET /admin/users?page=&limit=&keyword=` `GET /admin/users/:id` `GET /admin/users/:id/articles?page=&limit=` `POST /admin/users/:id/balance` Body: ```json { "balance": 10000 } ``` ### 3.7 订单管理 `GET /admin/orders?page=&limit=&order_number=&user_id=` `POST /admin/orders/:id/refund`:仅余额订单可退款