Skip to content

Latest commit

 

History

History
97 lines (68 loc) · 7.5 KB

miniprogram.md

File metadata and controls

97 lines (68 loc) · 7.5 KB

微信小程序客户端

本仓库的原生微信小程序位于 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 或用户资料输出到日志、埋点、分享链接或错误提示中。

导入微信开发者工具

  1. 打开微信开发者工具,选择“导入项目”。
  2. 项目目录选择仓库中的 miniprogram。
  3. 开发阶段可使用 touristappid;真机预览和提交审核前,在 project.config.json 中填入你自己的小程序 AppID。
  4. 首次登录页填写 API 服务地址,例如 https://study.example.com。小程序会拒绝普通公网 HTTP 地址、带账号密码的地址和带 query/fragment 的地址,避免 Bearer 登录令牌被明文传输或误发给错误站点;只有 http://localhost、http://127.0.0.1、http://[::1] 可供开发者工具本地调试。
  5. 在微信公众平台的“开发管理 → 开发设置 → 服务器域名”中,把 API 域名加入 request 合法域名。
  6. 真机和正式版本必须使用公网 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)。