接口文档#
本文档覆盖 LVX 站点当前对外提供的 HTTP 接口:账号服务、论坛服务、管理接口、商店发布审核接口,以及商店 / 插件仓库接口。
- 基础地址:
https://lvx-office.com - 数据格式:除文件上传 / 下载外,均为
application/json; charset=utf-8 - 时间格式:UTC;论坛为
YYYY-MM-DD HH:MM:SS,账号服务部分字段为 ISO 8601 - 文档版本:2026-10-23(如与线上实际响应不一致,以线上为准)
浏览器跨域调用:除 /store.json 外,接口默认不带 CORS 头,只允许同源页面调用。第三方客户端请使用服务端请求。
通用约定#
鉴权#
需要登录的接口在请求头带 JWT:
Authorization: Bearer <token>
- 登录 / 注册成功返回
token - 默认有效期 7 天;传
remember: true为 30 天 - 令牌可绑定设备(
deviceId),在「登录设备管理」里撤销后立即失效 - 撤销后的令牌访问会返回
401,并带code: "REVOKED"
返回格式#
成功:
{ "ok": true }
失败:
{ "ok": false, "error": "人类可读的错误说明" }
HTTP 状态码与 error 同时使用,客户端应以 HTTP 状态码为准。
错误码#
| HTTP | 含义 | 典型场景 |
|---|---|---|
| 400 | 参数不合法 | 标题为空、JSON 不合法、颜色格式错误 |
| 401 | 未登录 / 登录过期 / 密码错误 | 缺少 Bearer、令牌被撤销 |
| 403 | 无权限 | 非管理员访问后台、被禁言后发帖 |
| 404 | 资源不存在 | 帖子已删除、用户不存在 |
| 409 | 冲突 | 用户名已被注册 |
| 413 | 请求体过大 | 备份上传超过 4GB |
| 429 | 请求过于频繁 | 触发限流、发帖间隔不足 |
| 500 | 服务异常 | 未预期错误 |
限流#
| 范围 | 限制 |
|---|---|
账号服务全部 /api/* | 300 次 / 分钟 / IP |
| 登录、注册 | 10 次 / 分钟 / IP |
论坛全部 /api/forum/* | 240 次 / 分钟 / IP |
| 发帖 | 30 秒 / 条,30 条 / 天 / 用户 |
| 回复 | 8 秒 / 条 / 用户 |
| 举报 | 30 秒 / 次 / 用户 |
插件仓库 /repo/* | 300 次 / 分钟 / IP |
触发限流返回 429。账号服务的全局限流会带 Retry-After: 30。
分页#
论坛列表类接口使用:
| 参数 | 默认 | 说明 |
|---|---|---|
| page | 1 | 页码,从 1 开始 |
| limit | 20 | 每页条数,最大 50 |
响应包含 page、limit、total、pages。
账号 API#
账号服务处理注册、登录、Token、设备、头像、应用备份与账号注销。以下路径均以 /api 开头。
注册与登录#
POST /api/register 注册账号
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 3–20 位字母、数字、下划线或中文 |
| password | string | 是 | 6–64 位 |
| string | 否 | 最长 100 字符 | |
| remember | boolean | 否 | true 返回 30 天令牌 |
| deviceId | string | 否 | 客户端持久化的设备标识,4–64 字符 |
| deviceName | string | 否 | 设备名称,最长 60 字符 |
| platform | string | 否 | 平台标识,最长 40 字符 |
请求:
{
"username": "lvx_user",
"password": "secret123",
"email": "[email protected]",
"remember": true,
"deviceId": "6f1c2a9e-device",
"deviceName": "Chrome / Windows",
"platform": "web"
}
响应 201:
{
"ok": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": 1200,
"username": "lvx_user",
"email": "[email protected]",
"createdAt": "2026-10-23 06:30:00",
"lastLoginAt": null,
"avatarAt": null
}
}
错误:400 用户名 / 密码不合法,409 用户名已存在,429 触发登录注册限流。
POST /api/login 登录
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| remember | boolean | 否 | true 返回 30 天令牌 |
| deviceId | string | 否 | 设备标识 |
| deviceName | string | 否 | 设备名称 |
| platform | string | 否 | 平台标识 |
响应 200 与注册相同。密码错误统一返回 401,不区分「用户不存在」与「密码错误」。
资料与设备#
GET /api/me 当前用户
响应:
{
"ok": true,
"user": {
"id": 1200,
"username": "lvx_user",
"email": "[email protected]",
"createdAt": "2026-10-23 06:30:00",
"lastLoginAt": "2026-10-23 06:31:00",
"avatarAt": null
}
}
POST /api/change-password 修改密码
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| oldPassword | string | 是 | 原密码 |
| newPassword | string | 是 | 新密码,6–64 位 |
成功返回 { "ok": true, "message": "密码修改成功" };原密码错误返回 401。
GET /api/devices 登录设备列表
响应:
{
"ok": true,
"current": 12,
"devices": [
{
"id": 12,
"deviceId": "6f1c2a9e-device",
"name": "Chrome / Windows",
"platform": "web",
"createdAt": "2026-10-23 06:30:00",
"lastSeenAt": "2026-10-23 06:35:00",
"current": true
}
]
}
每个账号最多保留 20 台设备,超出时自动移除最久未使用的一台。
POST /api/devices/bind 绑定当前设备并换发令牌
请求:{ "deviceId": "...", "deviceName": "...", "platform": "..." }
响应:{ "ok": true, "token": "...", "deviceId": 13 }
POST /api/devices/revoke 撤销设备
{ "id": 12 }撤销指定设备{ "all": true }撤销除当前设备外的全部设备
响应:{ "ok": true, "removed": 1 };撤销的是当前设备时额外带 "self": true。
POST /api/logout 退出当前设备
删除当前设备记录,令牌立即失效。响应 { "ok": true }。
头像 / 备份 / 账号#
POST /api/avatar 上传头像
请求:{ "dataUrl": "data:image/png;base64,..." }
- 支持 PNG / JPEG / WebP
- 解码后不超过 512KB
响应:{ "ok": true, "avatarAt": "2026-10-23T06:40:00.000Z" }
GET /api/avatar/:uid 读取头像
需要登录,且只能读取自己的头像;返回图片二进制,未设置时 404。
POST /api/upload 上传应用备份
- 请求体为原始二进制(
application/octet-stream),上限 4GB - 每个账号只保留 1 份,上传成功会替换旧备份
- 文件名由服务端生成:
momotalk_YYYYMMDDHHMMSS.zip
响应:
{
"ok": true,
"file": "momotalk_20261023064000.zip",
"size": 1048576,
"time": "2026-10-23T06:40:00.000Z",
"replaced": true
}
GET /api/uploads 列出备份
{
"ok": true,
"quota": 1,
"files": [
{ "name": "momotalk_20261023064000.zip", "size": 1048576, "time": "2026-10-23T06:40:00.000Z" }
]
}
POST /api/backup/delete 删除备份
请求:{ "name": "momotalk_20261023064000.zip" }
响应:{ "ok": true, "removed": "momotalk_20261023064000.zip" }
GET /api/download/:filename 下载备份
返回 application/octet-stream。文件名做了 basename 处理,不能穿越目录。
POST /api/account/delete 注销账号
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | string | 是 | 当前密码 |
| confirm | string | 是 | 原样输入用户名 |
会删除账号、设备记录、头像与备份,不可恢复。
GET /health 健康检查
无需登录,/health 不在 /api 前缀下:
{ "ok": true, "service": "momotalk-auth", "users": 1200, "time": "2026-10-23T06:40:00.000Z" }
论坛 API#
论坛接口统一前缀 /api/forum,复用账号服务的账号与 JWT。
帖子#
GET /api/forum/stats 站点统计
{
"ok": true,
"posts": 12,
"replies": 34,
"users": 1200,
"categories": [
{ "name": "综合", "count": 8 },
{ "name": "求助", "count": 2 },
{ "name": "创作", "count": 1 },
{ "name": "闲聊", "count": 1 },
{ "name": "公告", "count": 0 }
]
}
GET /api/forum/me 当前论坛身份
需要登录。返回账号、是否管理员、头衔:
{
"ok": true,
"user": { "id": 1001, "username": "lvx_admin" },
"isAdmin": true,
"title": { "name": "管理员", "color": "#dc2626" }
}
GET /api/forum/posts 帖子列表
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | number | 否 | 页码,默认 1 |
| limit | number | 否 | 每页条数,默认 20,最大 50 |
| q | string | 否 | 搜索标题或正文,最长 60 字符 |
| category | string | 否 | 综合 / 求助 / 创作 / 闲聊 / 公告 |
响应:
{
"ok": true,
"page": 1,
"limit": 20,
"total": 12,
"pages": 1,
"q": "",
"category": "",
"posts": [
{
"id": 12,
"title": "第一篇帖子",
"excerpt": "正文摘要…",
"image": "/forum/uploads/1690000000-abcd.webp",
"username": "lvx_user",
"userId": 1200,
"createdAt": "2026-10-23 06:30:00",
"replyCount": 3,
"likeCount": 5,
"category": "综合",
"tags": ["教程", "新手"],
"authorTitle": { "name": "创作者", "color": "#0d9488" },
"file": { "name": "note.txt", "kind": "txt", "size": 19 }
}
]
}
image、authorTitle、file 可能为 null;tags 始终是数组。列表里的 file 只有元数据,不含内容。
GET /api/forum/posts/:id 帖子详情
{
"ok": true,
"post": {
"id": 12,
"title": "第一篇帖子",
"body": "完整正文",
"meta": "{\"score\":42}",
"image": null,
"username": "lvx_user",
"userId": 1200,
"createdAt": "2026-10-23 06:30:00",
"replyCount": 1,
"likeCount": 5,
"category": "综合",
"tags": ["教程"],
"authorTitle": null,
"file": {
"name": "note.txt",
"kind": "txt",
"size": 19,
"content": "第一行\n第二行"
}
},
"replies": [
{
"id": 8,
"userId": 1201,
"username": "another_user",
"body": "一级回复",
"createdAt": "2026-10-23 06:31:00",
"parentId": null,
"parentUsername": null,
"authorTitle": null
},
{
"id": 9,
"userId": 1200,
"username": "lvx_user",
"body": "回复二级评论",
"createdAt": "2026-10-23 06:32:00",
"parentId": 8,
"parentUsername": "another_user",
"authorTitle": null
}
],
"liked": false,
"mine": true,
"canModerate": false
}
回复结构说明:
- 一级回复
parentId为null - 回复二级评论时,仍挂在同一个一级评论下(拍平),
parentId指向一级评论,parentUsername记录实际被回复的人 - 最多返回 500 条回复
POST /api/forum/posts 发帖
需要登录。请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 1–80 字符 |
| body | string | 是 | 1–5000 字符 |
| category | string | 否 | 默认「综合」,必须是预设分类 |
| tags | string | 否 | 逗号分隔,最多 5 个,每个 ≤12 字 |
| meta | string | 否 | 旧字段:附加 JSON 文本,≤1KB(新客户端请用 file) |
| file | object | 否 | 附件 {name, kind, content},见下方 |
| image | string | 否 | Data URL,≤3MB,PNG / JPEG / WebP |
{
"title": "第一篇帖子",
"body": "正文内容",
"category": "综合",
"tags": "教程, 新手",
"file": {
"name": "note.txt",
"kind": "txt",
"content": "第一行\n第二行"
}
}
图片会压缩为最长边 1600px 的 WebP(q82,去 EXIF)。响应 201,返回 post 对象。
限制:30 秒/条,30 条/天/用户;内容含屏蔽词返回 400;被禁言返回 403。
附件文件 file
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 文件名,1–80 字符;不能包含路径分隔符或特殊字符;缺少扩展名会自动补 .txt / .json |
| kind | string | 是 | txt 或 json |
| content | string | 是 | 文件内容,1–16KB;json 必须是合法 JSON |
- 每个帖子最多 1 个附件
- 列表接口只返回
{name, kind, size},详情接口额外返回content - 文件名与内容会做 HTML 转义;内容同样受屏蔽词限制
DELETE /api/forum/posts/:id 删除自己的帖子
软删除,同时隐藏该帖回复、删除相关通知、把举报标记为已处理。只能删除自己的帖子,否则 403。
POST /api/forum/posts/:id/like 点赞 / 取消点赞
切换当前用户对该帖的点赞状态。响应:
{ "ok": true, "liked": true, "likes": 6 }
回复 / 点赞#
POST /api/forum/posts/:id/replies 回复
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| body | string | 是 | 1–2000 字符 |
| parentId | number | 否 | 要回复的评论 id;不传为一级回复 |
响应 201:
{
"ok": true,
"reply": {
"id": 10,
"userId": 1200,
"username": "lvx_user",
"body": "回复内容",
"createdAt": "2026-10-23 06:33:00",
"parentId": 8,
"parentUsername": "another_user",
"authorTitle": null
}
}
限制:8 秒/条;被禁言返回 403。回复帖子作者会收到通知;回复某条评论时,该评论作者也会收到通知(不通知自己)。
DELETE /api/forum/replies/:id 删除自己的回复
软删除;如果删除的是一级评论,其下的二级回复一并隐藏,并重算帖子的回复数。
用户 / 通知 / 举报#
GET /api/forum/users/:id 用户主页
{
"ok": true,
"user": {
"id": 1001,
"username": "lvx_admin",
"joinedAt": "2026-10-21 09:49:12",
"avatarAt": null,
"title": { "name": "管理员", "color": "#dc2626" }
},
"postCount": 2,
"replyCount": 0,
"posts": [],
"replies": [
{
"id": 3,
"postId": 12,
"postTitle": "第一篇帖子",
"body": "回复内容",
"createdAt": "2026-10-23 06:33:00"
}
]
}
GET /api/forum/avatar/:uid 公开头像
返回图片二进制;未设置头像时 404。论坛展示用,不需要登录。
GET /api/forum/notifications 通知列表
需要登录。返回未读数和最近 30 条:
{
"ok": true,
"unread": 1,
"items": [
{
"id": 5,
"type": "reply",
"postId": 12,
"replyId": 10,
"from": "another_user",
"excerpt": "回复内容",
"postTitle": "第一篇帖子",
"read": false,
"createdAt": "2026-10-23 06:33:00"
}
]
}
type:post 表示回复了你的帖子,reply 表示回复了你的评论。
POST /api/forum/notifications/read 标记已读
{ "id": 5 }标记单条- 空 body / 不传 id 标记全部
响应 { "ok": true }。
POST /api/forum/reports 举报
需要登录。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| postId | number | 二选一 | 举报帖子 |
| replyId | number | 二选一 | 举报回复 |
| reason | string | 否 | 原因,最长 200 字符 |
响应 { "ok": true }。30 秒/次/用户。
管理 API#
管理接口前缀 /api/forum/admin,全部需要管理员权限;非管理员返回 403。
举报与内容#
GET /api/forum/admin/reports 未处理举报
返回最近 100 条:
{
"ok": true,
"reports": [
{
"id": 3,
"post_id": 12,
"reply_id": null,
"reporter_id": 1201,
"reporter_name": "another_user",
"reason": "广告",
"created_at": "2026-10-23 06:35:00",
"resolved": 0,
"post_title": "第一篇帖子",
"content": "被举报的正文",
"kind": "post",
"hidden": 0,
"target_post_id": 12
}
]
}
POST /api/forum/admin/reports/:id/resolve 标记举报已处理
响应 { "ok": true }。
POST /api/forum/admin/posts/:id/hide 隐藏帖子
软删除,可由管理员恢复;同时删除相关通知、把该帖及其回复的举报标记为已处理。
POST /api/forum/admin/posts/:id/restore 恢复帖子
把 deleted 置回 0。
POST /api/forum/admin/replies/:id/hide 隐藏回复
软删除并重算帖子的回复数,同时处理该回复的举报。
POST /api/forum/admin/replies/:id/restore 恢复回复
把 deleted 置回 0 并重算回复数。
用户 / 头衔#
GET /api/forum/admin/users?q= 搜索用户
按用户名或邮箱模糊搜索,最多 20 条。q 最长 60 字符。
{
"ok": true,
"users": [
{
"id": 1001,
"username": "lvx_admin",
"email": "[email protected]",
"joinedAt": "2026-10-21 09:49:12",
"role": "admin",
"title": { "name": "管理员", "color": "#dc2626" },
"banned": false,
"banReason": null
}
]
}
POST /api/forum/admin/users/:id/title 指派头衔
请求:{ "titleId": 3 };传 null 或空值清除头衔。
响应:{ "ok": true, "title": { "name": "创作者", "color": "#0d9488" } }。
POST /api/forum/admin/users/:id/role 设置角色
请求:{ "role": "admin" } 或 { "role": "user" }。
不能取消最后一位管理员,否则返回 400。
POST /api/forum/admin/users/:id/ban 禁言 / 解禁
请求:{ "banned": true, "reason": "广告" } 或 { "banned": false }。
管理员不能被禁言。禁言后不能发帖、回复、举报。
GET /api/forum/admin/titles 头衔列表
{
"ok": true,
"titles": [
{ "id": 1, "name": "管理员", "color": "#dc2626", "users": 1 },
{ "id": 2, "name": "版主", "color": "#ea580c", "users": 0 }
]
}
POST /api/forum/admin/titles 新建头衔
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 1–12 字,不能重名 |
| color | string | 是 | #RRGGBB |
最多 50 个头衔。响应 201。
DELETE /api/forum/admin/titles/:id 删除头衔
使用该头衔的用户会失去头衔。
商店与仓库#
商店索引#
GET /store.json 商店条目
Cache-Control: no-storeAccess-Control-Allow-Origin: *,允许跨域读取- 与
/store/页面同源
结构:
{
"store": "lvx",
"kind": "store",
"updated": "2026-11-03",
"apps": [
{
"id": "lvx-store",
"name": "lvx-store",
"title": "LVX Store",
"summary": "一句话简介",
"description": "详细描述",
"kind": "app",
"version": "1.0.0",
"package": "",
"packageUrl": null,
"source": "official",
"tags": ["应用"],
"media": null
}
]
}
tags 为字符串数组,用于商店页的标签筛选(如 示例 / 模型 / 推理 / 开发 / 应用 / Vulkan / 测试 / 工具 / CPU / MomoTalk-X/AI);仅展示与筛选,不影响安装。
插件仓库#
仓库根地址:https://lvx-office.com/repo/
GET /repo/manifest.json 包索引
{
"name": "lvx-official-repo",
"version": "3.0.0",
"packages": [
{
"name": "lvx-ai-dev",
"version": "1.0.0",
"desc": "包描述",
"dependencies": [],
"files": [
{
"file": "liblvx_importer_gguf.so",
"sha256": "9d567e1dc8fa...",
"size": 153344
}
]
}
]
}
GET /repo/<path> 下载包文件
- 支持
HEAD - 支持
Range: bytes=0-1023,返回206 Partial Content和Content-Range - 每个 IP 300 次/分钟
- 禁止目录列举;隐藏文件、
.py、.log、.db、.env、备份文件等不会对外提供
GET /lvx/1.0.0/... LVX 安装包
静态安装包与校验文件,链接自带内容版本参数;发布目录按版本管理。
商店发布 API#
面向第三方开发者的投稿接口。上传的 .lvx 先进入服务器私有待审区,不会立即出现在商店;管理员审核通过后,文件保留在待发布区,再由管理员执行上架。
- 前缀:
/api/store - 鉴权:MomoTalk 账号 JWT,
Authorization: Bearer - 上传格式:
multipart/form-data - 单文件上限:512 MB
- 提交频率:每用户 5 次/小时;每 IP 120 次/分钟
- 当前没有提交 UI,全部通过接口调用
可用标签#
GET /api/store/tags 公开
{"ok":true,"tags":["示例","模型","推理","开发","应用","测试","Vulkan","工具","CPU","MomoTalk-X/AI"]}
提交发布#
POST /api/store/publish 需要登录
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | file | 是 | .lvx 文件,≤512MB |
| name | string | 是 | 2–40 位小写字母/数字/点/下划线/短横线;规范化后必须与 LVX 清单里的 name 一致 |
| title | string | 否 | 显示名,1–80 字;默认取清单 name |
| version | string | 否 | x.y.z;默认取清单 version |
| summary | string | 否 | 一句话简介,1–200 字;默认取清单 desc |
| description | string | 否 | 详细描述,≤2000 字;默认同 summary |
| kind | string | 否 | app / plugin / model;默认取清单 kind 或 app |
| tags | string | 否 | 逗号分隔或 JSON 数组,最多 5 个,必须在可用标签内;默认「应用」 |
file 必须是合法的 LVX2 容器,且包含可读的 AppManifest(section type 13);否则返回 400。
示例:
TOKEN='登录后拿到的 token'
curl -X POST https://lvx-office.com/api/store/publish \
-H "Authorization: Bearer $TOKEN" \
-F "[email protected]" \
-F "name=myapp" \
-F "title=My App" \
-F "version=1.0.0" \
-F "summary=一句话介绍" \
-F "description=更详细的说明" \
-F "kind=app" \
-F "tags=应用"
响应 201:
{
"ok": true,
"submission": {
"id": "sub_1793707494027_cf9351bc",
"status": "pending",
"name": "myapp",
"title": "My App",
"version": "1.0.0",
"tags": ["应用"],
"size": 184,
"sha256": "b7c306...",
"createdAt": "2026-11-03 12:04:54",
"downloadUrl": "/api/store/publish/sub_1793707494027_cf9351bc/file"
}
}
错误:400 文件/字段/标签不合法,401 未登录,409 name 已存在或有同名待审,413 超过 512MB,429 提交过频,507 待审空间不足。
我的提交#
GET /api/store/publish/mine 需要登录
返回当前用户最近 50 条提交,含状态与拒绝原因。
GET /api/store/publish/:id 需要登录(本人或管理员)
GET /api/store/publish/:id/file 需要登录(本人或管理员)
下载原始 .lvx,application/octet-stream。
审核接口#
以下接口需要管理员权限(论坛 roles 中 role = admin)。
GET /api/store/admin/submissions?status=pending
status:pending(默认)/ approved / rejected / all;limit 最大 100。
GET /api/store/admin/submissions/:id/file 下载待审文件
POST /api/store/admin/submissions/:id/approve 通过
{"ok":true,"status":"approved","note":"已通过审核,文件保留在服务器待发布区;发布到商店索引需管理员后续执行"}
POST /api/store/admin/submissions/:id/reject 拒绝
{"reason":"缺少 AppManifest 或版本号不正确"}
DELETE /api/store/admin/submissions/:id 删除记录并清理文件
状态流转#
| 状态 | 含义 |
|---|---|
| pending | 已上传,等待审核 |
| approved | 审核通过,文件在待发布区 |
| rejected | 审核拒绝,用户可查看原因并重新提交 |
审核通过不会自动修改 store.json、仓库索引或商店页面;上架动作由管理员在审核后执行。这样可以在人工确认内容、许可证与包完整性后再发布。
数据模型#
Post#
| 字段 | 类型 | 说明 |
|---|---|---|
| id | number | 帖子 id |
| title | string | 标题 |
| body | string | 正文(列表接口为 excerpt) |
| meta | string/null | 旧字段:附加 JSON 文本 |
| file | object/null | 附件 {name, kind, size};详情额外含 content |
| image | string/null | 图片 URL |
| username | string | 作者用户名 |
| userId | number | 作者 id |
| createdAt | string | 创建时间(UTC) |
| replyCount | number | 回复数 |
| likeCount | number | 点赞数 |
| category | string | 分类 |
| tags | string[] | 标签 |
| authorTitle | object/null | 作者头衔 {name,color} |
Reply#
| 字段 | 类型 | 说明 |
|---|---|---|
| id | number | 回复 id |
| userId | number | 作者 id |
| username | string | 作者用户名 |
| body | string | 内容 |
| createdAt | string | 时间 |
| parentId | number/null | 一级回复为 null;二级回复指向一级评论 |
| parentUsername | string/null | 实际被回复的人 |
| authorTitle | object/null | 作者头衔 |
Notification#
| 字段 | 类型 | 说明 |
|---|---|---|
| id | number | 通知 id |
| type | string | post / reply |
| postId | number | 关联帖子 |
| replyId | number | 关联回复 |
| from | string | 触发者用户名 |
| excerpt | string | 回复摘要 |
| postTitle | string | 帖子标题 |
| read | boolean | 是否已读 |
| createdAt | string | 时间 |
调用示例#
注册并登录#
curl -s https://lvx-office.com/api/register \
-H 'Content-Type: application/json' \
-d '{"username":"lvx_user","password":"secret123","email":"[email protected]"}'
TOKEN=$(curl -s https://lvx-office.com/api/login \
-H 'Content-Type: application/json' \
-d '{"username":"lvx_user","password":"secret123","remember":true}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')
发帖与回复#
curl -s https://lvx-office.com/api/forum/posts \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"title":"你好","body":"第一帖","category":"综合","tags":"新手,测试"}'
curl -s https://lvx-office.com/api/forum/posts/12/replies \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"body":"回复一下","parentId":8}'
搜索与通知#
curl -s 'https://lvx-office.com/api/forum/posts?q=%E6%95%99%E7%A8%8B&category=%E7%BB%BC%E5%90%88&page=1'
curl -s https://lvx-office.com/api/forum/notifications \
-H "Authorization: Bearer $TOKEN"
前端 fetch#
const token = localStorage.getItem('lvx-token');
const res = await fetch('/api/forum/posts?limit=10', {
headers: { Authorization: `Bearer ${token}` }
});
const data = await res.json();
if (!data.ok) throw new Error(data.error);
管理员接口需要账号在roles表中为admin;普通用户调用会返回403。