Files
mini_tp/docs/note_api.md
T
2026-04-17 07:48:44 +00:00

550 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Note 模块接口文档
## 1. 模块说明
`note` 是独立于现有 `app/api` 业务的笔记小程序模块,代码位置如下:
- [app/note/controller](/root/work/tp/app/note/controller)
- [app/note/service](/root/work/tp/app/note/service)
- [app/note/model](/root/work/tp/app/note/model)
当前已实现能力:
1. 微信小程序登录
2. 笔记创建、列表、详情、更新、删除
3. 实时转写文本保存
4. AI 总结生成与查询
路由注册位置:
- [route/app.php](/root/work/tp/route/app.php)
---
## 2. 鉴权说明
除登录接口外,其余 `note` 接口都需要携带 JWT
- Header: `Authorization: Bearer {token}`
`note` 模块复用现有 JWT 机制,但要求 token 载荷中必须包含:
```json
{
"userid": 123,
"guard": "note"
}
```
说明:
- `userid` 对应 `note_user.id`
- `guard=note` 用于和旧 `api` 模块登录态隔离
---
## 3. 环境变量
微信登录依赖以下配置:
- `WECHAT_MINI_APPID`
- `WECHAT_MINI_SECRET`
- `DB_NOTE_HOSTNAME`
- `DB_NOTE_DATABASE`
- `DB_NOTE_USERNAME`
- `DB_NOTE_PASSWORD`
- `DB_NOTE_HOSTPORT`
示例位置:
- [\.example.env](/root/work/tp/.example.env)
---
## 4. 数据表
表结构定义位置:
- [database.sql](/root/work/tp/database.sql#L26)
当前 `note` 模块使用以下 4 张表:
1. `note_user`
用于小程序用户登录和用户资料
2. `note_item`
笔记主表,包含正文、转写累计文本、状态、录音时长等
3. `note_transcript`
实时转写分片记录表
4. `note_ai_summary`
AI 总结结果表
---
## 5. 接口列表
### 5.1 获取模块概览
- 方法:`GET`
- 路径:`/note/v1/meta/interfaces`
- 是否鉴权:否
用途:
- 返回 note 模块接口规划概览
---
### 5.2 微信小程序登录
- 方法:`POST`
- 路径:`/note/v1/auth/wechat-login`
- 是否鉴权:否
请求参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `code` | string | 是 | `wx.login` 获取的临时 code |
| `nickname` | string | 否 | 用户昵称 |
| `avatar_url` | string | 否 | 用户头像地址 |
请求示例:
```json
{
"code": "021xxx",
"nickname": "张三",
"avatar_url": "https://example.com/avatar.png"
}
```
成功响应示例:
```json
{
"code": 200,
"msg": "登录成功",
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.xxx",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.xxx",
"expires_in": 604800,
"user": {
"id": 1,
"member_id": 0,
"openid": "oxxx",
"nickname": "张三",
"avatar_url": "https://example.com/avatar.png",
"mobile": "",
"is_new_user": true
}
},
"time": 1710000000
}
```
说明:
1. 首次登录时自动创建 `note_user`
2. 后续登录时按 `openid` 更新资料与最后登录时间
3. 若用户被禁用,返回 403
---
### 5.3 获取当前用户信息
- 方法:`GET`
- 路径:`/note/v1/auth/me`
- 是否鉴权:是
成功响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"id": 1,
"member_id": 0,
"openid": "oxxx",
"nickname": "张三",
"avatar_url": "https://example.com/avatar.png",
"mobile": "",
"status": 1,
"last_login_time": 1710000000,
"created_at": 1710000000
},
"time": 1710000001
}
```
---
### 5.4 创建笔记
- 方法:`POST`
- 路径:`/note/v1/item/create`
- 是否鉴权:是
请求参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `source_type` | string | 是 | `text` / `audio` / `mix` |
| `title` | string | 否 | 标题 |
| `content` | string | 否 | 正文 |
| `audio_duration_ms` | int | 否 | 录音时长 |
| `status` | string | 否 | 默认 `draft` |
请求示例:
```json
{
"source_type": "text",
"title": "会议纪要",
"content": "今天确认了下周需求排期",
"status": "draft"
}
```
成功响应示例:
```json
{
"code": 200,
"msg": "创建成功",
"data": {
"id": 10,
"note_user_id": 1,
"title": "会议纪要",
"content": "今天确认了下周需求排期",
"transcript_text": "",
"source_type": "text",
"status": "draft",
"audio_duration_ms": 0,
"summary_status": "none",
"last_transcript_time": 0,
"created_at": 1710000000,
"updated_at": 1710000000
},
"time": 1710000000
}
```
说明:
- 如果不传 `title`,后端会根据 `content` 自动生成标题
- 如果 `title``content` 都为空,标题会默认为 `未命名笔记`
---
### 5.5 笔记列表
- 方法:`GET`
- 路径:`/note/v1/item/list`
- 是否鉴权:是
查询参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `page` | int | 否 | 默认 1 |
| `page_size` | int | 否 | 默认 10,最大 100 |
| `keyword` | string | 否 | 搜索标题、正文、转写文本 |
| `status` | string | 否 | 按状态筛选 |
响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"list": [
{
"id": 10,
"note_user_id": 1,
"title": "会议纪要",
"content": "今天确认了下周需求排期",
"transcript_text": "",
"source_type": "text",
"status": "draft",
"audio_duration_ms": 0,
"summary_status": "none",
"last_transcript_time": 0,
"created_at": 1710000000,
"updated_at": 1710000000
}
],
"total": 1,
"page": 1,
"page_size": 10
},
"time": 1710000001
}
```
---
### 5.6 笔记详情
- 方法:`GET`
- 路径:`/note/v1/item/:id`
- 是否鉴权:是
响应示例:
```json
{
"code": 200,
"msg": "success",
"data": {
"id": 10,
"note_user_id": 1,
"title": "会议纪要",
"content": "今天确认了下周需求排期",
"transcript_text": "需要跟进接口联调",
"source_type": "mix",
"status": "draft",
"audio_duration_ms": 120000,
"summary_status": "success",
"last_transcript_time": 1710000100,
"created_at": 1710000000,
"updated_at": 1710000200,
"summary": {
"summary_id": 3,
"summary_type": "brief",
"summary_text": "今天确认了下周需求排期\n需要跟进接口联调",
"todo_list": [
"需要跟进接口联调"
],
"keywords": [
"需求",
"排期",
"接口联调"
],
"status": "success"
}
},
"time": 1710000201
}
```
---
### 5.7 更新笔记
- 方法:`POST`
- 路径:`/note/v1/item/update/:id`
- 是否鉴权:是
请求参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `title` | string | 否 | 标题 |
| `content` | string | 否 | 正文 |
| `status` | string | 否 | 状态 |
| `audio_duration_ms` | int | 否 | 录音时长 |
说明:
- 只更新传入字段
- 只能更新自己的笔记
---
### 5.8 删除笔记
- 方法:`POST`
- 路径:`/note/v1/item/delete/:id`
- 是否鉴权:是
说明:
- 当前为软删除,写入 `deleted_at`
成功响应示例:
```json
{
"code": 200,
"msg": "删除成功",
"data": {
"deleted": true,
"id": 10
},
"time": 1710000300
}
```
---
### 5.9 保存实时转写内容
- 方法:`POST`
- 路径:`/note/v1/item/transcript/:id`
- 是否鉴权:是
请求参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `full_text` | string | 是 | 当前累计完整转写文本 |
| `segment_no` | int | 否 | 分片序号,默认 0 |
| `segment_text` | string | 否 | 当前分片文本 |
| `is_final` | int/bool | 否 | 是否最终片段 |
| `audio_duration_ms` | int | 否 | 当前累计录音时长 |
请求示例:
```json
{
"segment_no": 3,
"segment_text": "需要跟进接口联调",
"full_text": "今天确认了下周需求排期,需要跟进接口联调",
"is_final": 1,
"audio_duration_ms": 120000
}
```
成功响应示例:
```json
{
"code": 200,
"msg": "转写保存成功",
"data": {
"note_id": 10,
"segment_no": 3,
"is_final": 1,
"transcript_text": "今天确认了下周需求排期,需要跟进接口联调",
"audio_duration_ms": 120000,
"updated_at": 1710000400
},
"time": 1710000400
}
```
说明:
- 后端会同步更新 `note_item.transcript_text`
- 同一个 `note_id + segment_no` 会覆盖写入
---
### 5.10 生成 AI 总结
- 方法:`POST`
- 路径:`/note/v1/ai/summary/:id`
- 是否鉴权:是
请求参数:
| 字段 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| `summary_type` | string | 否 | `brief` / `outline` / `todo` |
| `force_refresh` | int/bool | 否 | 是否强制重新生成 |
请求示例:
```json
{
"summary_type": "brief",
"force_refresh": 1
}
```
成功响应示例:
```json
{
"code": 200,
"msg": "总结生成成功",
"data": {
"summary_id": 3,
"note_id": 10,
"summary_type": "brief",
"summary_text": "今天确认了下周需求排期\n需要跟进接口联调",
"todo_list": [
"需要跟进接口联调"
],
"keywords": [
"需求",
"排期",
"接口联调"
],
"status": "success",
"error_message": "",
"created_at": 1710000500,
"updated_at": 1710000500
},
"time": 1710000500
}
```
说明:
- 当前实现为规则版总结,不依赖外部大模型
- 若已存在成功总结且 `force_refresh=0`,会直接返回已有结果
---
### 5.11 查看 AI 总结
- 方法:`GET`
- 路径:`/note/v1/ai/summary/:id`
- 是否鉴权:是
说明:
- 返回指定笔记最新的一条总结记录
---
## 6. 错误码约定
当前模块沿用项目统一返回结构:
```json
{
"code": 400,
"msg": "错误信息",
"data": [],
"time": 1710000000
}
```
常见情况:
- `400`:参数错误
- `401`:未登录或登录态无效
- `403`:用户被禁用
- `404`:资源不存在
- `500`:服务端错误
- `502`:调用微信接口失败
---
## 7. 调用顺序建议
小程序端推荐按以下顺序接入:
1.`wx.login`
2.`code` 发给 `POST /note/v1/auth/wechat-login`
3. 保存返回的 `token`
4. 创建笔记 `POST /note/v1/item/create`
5. 录音转写过程中持续调用 `POST /note/v1/item/transcript/:id`
6. 需要生成总结时调用 `POST /note/v1/ai/summary/:id`
7. 打开详情页时调用 `GET /note/v1/item/:id`
---
## 8. 当前限制
1. AI 总结目前是规则版,不是大模型版
2. 微信登录依赖服务端已正确配置 `WECHAT_MINI_APPID``WECHAT_MINI_SECRET`
3. 当前未实现文件音频上传,只实现了“转写文本写回后端”的数据链路