本仓库的原生微信小程序位于 miniprogram/。它不把 Vue 网页“硬打包”为小程序,而是使用微信原生的 WXML、WXSS、JavaScript 和 wx.request 重新实现移动端体验;Go 后端、资料库、AI Harness、版本保护和数据隔离继续复用。
| 小程序页面 | 能做什么 | 对应后端能力 |
|---|---|---|
| 登录 / 注册 | 使用现有学习空间账号登录、注册、刷新与退出当前设备 | 新增 /api/auth/mobile/* JSON 令牌接口。 |
| 学习 | 查看今日目标、本周汇总,记录专注分钟 | /api/dashboard/plan、/weekly-report、/focus-sessions。 |
| 资料库 | 浏览文件夹,新建文件夹或 Markdown 笔记 | /api/library/items。 |
| 笔记 | 阅读和保存 Markdown / TXT 笔记 | 内容版本检查、检查点保存,冲突时拒绝覆盖。 |
| 科目 / 错题 | 管理科目、录入错题、筛选、复习和删除 | 既有 /api/subjects、/api/errors。 |
| AI 助手 | 纯聊天、按资料库名称选择“整个资料库”或文件夹范围提问、轮询 Turn、取消、显示写入确认卡和实际引用资料;显示本轮模型名;长度截断时可手动继续生成,并在小程序回到前台后恢复未结束任务 | 既有 /api/ai/turns、确认接口和 Harness。 |
| 我的 | 修改模型、设置单次回答最大 token、配置 DeepSeek Key、修改服务器地址、退出 | 既有 settings API 与移动端登出。 |
小程序的 AI 使用 Turn 轮询而不是网页 SSE:它每约 1.2 秒读取一次任务状态,直到完成、失败、取消或等待写入确认。这样在微信网络环境中更稳定,也仍然复用了 Go 端的确认、引用和权限边界。若 Go 服务在任务中重启,后端会在小程序的下一次单项轮询中把没有运行器的旧活动 Turn 标为 failed;小程序立即停止轮询并提示重新发送,不会空等到自身的轮询超时。关闭“纯聊天”后,页面会加载你自己的资料文件夹并显示完整路径;你可以选择“整个资料库”或一个文件夹,不再需要记忆内部数字 ID。若资料夹列表暂时加载失败,页面会保留并明确显示之前已选的范围,绝不会悄悄显示“整个资料库”却仍提交旧的文件夹 ID。页面只保留服务端确认的可见答案、模型名和资料引用,不保存模型思考、工具参数或能力令牌。若服务端把本轮标记为 incomplete(DeepSeek 明确因输出长度结束),页面会保留前半段答案并提供“继续生成”;这会创建新的 Turn,只有用户点击后才会继续消耗额度。活动 Turn ID 会保存到小程序本地状态;用户从后台回到页面时会继续查询同一个 Turn。等待确认、运行或排队中的 Turn 会锁住“发送”和“新对话”,避免同一对话并发创建两项任务。本地 AI 状态会绑定当前用户 ID;退出登录、刷新令牌失效或换账号时都会清除,防止共享设备显示上一位用户的聊天。
网页端继续使用 HttpOnly Cookie,不受本次修改影响。小程序不能可靠依赖浏览器 Cookie,因此新增四个公开接口:
POST /api/auth/mobile/register
POST /api/auth/mobile/login
POST /api/auth/mobile/refresh
POST /api/auth/mobile/logout
登录和刷新成功返回:
{
"access_token": "短期 JWT",
"refresh_token": "轮换令牌",
"token_type": "Bearer",
"expires_in": 900,
"refresh_expires_in": 2592000,
"user": { "id": 1, "username": "knock" }
}后续小程序请求使用:
Authorization: Bearer <access_token>AuthRequired 会优先校验这个 Bearer Token;只有请求没有 Authorization 时才兼容原有 Cookie。令牌过期后,小程序只对同一个失败请求执行一次刷新并重试;若多个请求同时收到 401,它们会共用同一个刷新 Promise,只发送一次刷新令牌轮换请求,随后都用新 access token 重试。刷新失败才会清除本地会话并跳回登录页,避免无限重试或并发刷新把刚建立的新会话误清掉。
小程序本地存储适合保存登录会话,但不是服务器端秘密库。不要将 access token、refresh token、DeepSeek Key 或用户资料输出到日志、埋点、分享链接或错误提示中。
- 打开微信开发者工具,选择“导入项目”。
- 项目目录选择仓库中的
miniprogram。 - 开发阶段可使用
touristappid;真机预览和提交审核前,在project.config.json中填入你自己的小程序 AppID。 - 首次登录页填写 API 服务地址,例如
https://study.example.com。小程序会拒绝普通公网 HTTP 地址、带账号密码的地址和带 query/fragment 的地址,避免 Bearer 登录令牌被明文传输或误发给错误站点;只有http://localhost、http://127.0.0.1、http://[::1]可供开发者工具本地调试。 - 在微信公众平台的“开发管理 → 开发设置 → 服务器域名”中,把 API 域名加入 request 合法域名。
- 真机和正式版本必须使用公网 HTTPS;
http://127.0.0.1只能在开发者工具关闭域名校验时本地调试,不能作为生产地址。
当前电脑没有检测到微信开发者工具 CLI,因此本次自动验证覆盖了原生项目结构、JavaScript 请求行为和 Go 后端回归。安装微信开发者工具后,可用它打开 miniprogram 进行真机预览;小程序本身不依赖 npm 包或编译框架。
这个版本先支持现有学习空间账号(用户名 / 邮箱 + 密码),因此无需把微信 AppSecret 写进源码即可完整使用数据、资料库和 AI。
“使用微信身份一键登录”需要另行在微信开放平台 / 小程序后台申请 AppID、服务器端保管 AppSecret,并在 Go 后端用小程序临时 code 交换 openid 后绑定本地用户。它不能在没有 AppID、AppSecret 和正式域名的情况下伪造实现,也绝不能把 AppSecret 放在本小程序目录中。
无需安装依赖:
cd miniprogram
npm run check该命令会验证:
app.json、project.config.json、sitemap.json均为有效 JSON;- 所有注册页面都有
.js、.wxml、.wxss文件,WXML 标签也会检查闭合配对; - tabBar 路由确实已注册;
- 小程序源文件没有遗留
TODO、待实现、待补标记; - HTTPS/本机 HTTP 地址校验,令牌请求、单请求及并发
401下的单飞刷新轮换、退出时清理本地聊天、错误信息保留、接口路由契约、按资料夹名称选范围后正确传 ID、资料夹列表失败时范围仍一致、活动 AI Turn 防并发、服务端模型/资料引用显示、服务重启中断 Turn 后立即停止轮询、长度截断后的手动续写与换账号隔离等行为通过 Node 内置测试。
后端回归:
go test ./...小程序优先提供手机上最常用的学习流:浏览资料、写笔记、复习错题、专注记录和 AI 对话。网页版仍保留较适合桌面端的 OCR、复杂 Markdown / KaTeX 编辑、Office 文件预览、拖拽排序、资料回收站细节和可视化热力图。
差异不是数据分叉:两端请求同一个 Go API,登录到同一用户后看到的是同一套科目、错题、资料库、笔记版本、学习活动和 AI 配置(包括模型与单次回答最大 token)。