This commit is contained in:
2025-12-15 17:55:32 +08:00
commit 28ab17324d
170 changed files with 18373 additions and 0 deletions

248
specs/API.md Normal file
View File

@@ -0,0 +1,248 @@
# 新项目 API 规格(/t/:tenant_code/v1
## 0. 通用约定
### 0.1 Base URL 与租户
- Base`/t/:tenant_code/v1`
- `tenant_code` 校验:服务端对路径段做 `lower()` 后校验 `^[a-z0-9_-]+$`,并查表确认租户存在且启用
### 0.2 认证
- WeChat H5Cookie 会话(例如 `token`),请求需携带 `withCredentials`
- Admin`Authorization: Bearer <token>`
### 0.3 响应
- 成功:`200`(或 201/204JSON
- 业务错误:`400`(含错误信息)
- 未登录:`401`
- 无权限:`403`
- 不存在:`404`
---
## 1. WeChat OAuth
### 1.1 发起授权
`GET /auth/wechat?redirect=<url>`
- 行为302 跳转到微信授权 URL回调为 `/t/:tenant_code/v1/auth/login`
### 1.2 授权回调
`GET /auth/login?code=<code>&state=<state>&redirect=<url>`
- 行为:
- 获取 openid 与用户资料
- `(tenant_id, open_id)` 获取或创建 `users`
- 写入 Cookie 会话
- 302 回跳 `redirect`
---
## 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=<current_page_url_without_hash>`
ResponseJS-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=<mime>`
Response
```json
{ "exists": false, "pre_sign": { "...": "..." } }
```
说明:
- `md5` 在租户内去重
- OSS Key`quyun/<tenant_uuid>/<md5>.<ext>`
`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`:仅余额订单可退款