# 知了数学 · 小程序 `math.client-pc` 的教师工作台小程序,使用 Taro 4、React 18、TypeScript、Vite 和 SCSS。此目录为独立 Git 仓库,使用 pnpm 管理依赖。 已按工作区「上传错题小程序.html」原型实现前端流程,所有环境使用本地模拟数据,不调用后端接口。可选择本地照片和 Word/PDF 文件,文件仅保存在当前设备;本地讲解视频可播放。退出/重新进入演示账号仅改变本地展示状态,不代表真实鉴权。 ## 原型功能 - 上传错题:跨班级多选学生、连续拍摄/相册多选、Word/PDF 导入、照片预览与删除、按页识别、题号/划动切换、标记错题、修改题干/选择题选项/答案/解析/年级/知识点/难度,提交所选错题。 - 上传试卷:必填名称、年份、类型、省份;多页采集与逐题编辑;提交后显示待审核,约 20 秒后本地模拟审核通过并产生通知。 - 上传答题卡:拍摄规范、相册多选、连续拍摄、逐张预览/删除/重拍、批量提交。成功后提示到 PC 客户端「批量解析」查看结果,当前版本不执行真实解析。 - 失败重试:确认页提供「体验上传失败与重试」入口;错题/试卷保留编辑结果,答题卡展示失败图片并支持仅重拍失败项,已成功图片不重复处理。 - 题目讲解:待查看/处理中筛选、关联学生与请求/预计/生成时间、完成通知、包内无声讲解示范、观看进度与已读状态。初始示例包含 3 条就绪讲解、1 条约 12 秒后完成的讲解。 - 消息:按视频讲解/试卷/题目/答题卡筛选、全部已读、上传与审核详情、试卷题目和原图分页查看。 - 题库与统计:保留题库页面,支持按年级、知识点、题干或学生筛选,展示本地题量、错题、关联学生和近 7 天趋势;包含 3 份多页示例卷。首页不显示题库管理和上传记录入口,消息仍可通过右上角铃铛查看。 - 我的:编辑姓名/手机号/邮箱并保存到本地、密码表单校验、关于与退出演示账号;不会保存或验证真实密码。 识别结果固定使用数学样例,每张照片/每个文档模拟 3 道题。Word/PDF 仅演示文件选择和识别流程,不解析实际文档内容或实际页数,也不提供文档原图预览。真实拍照需要微信相机权限,H5 拍照行为由浏览器与设备支持决定。 题库、通知、资料和观看进度使用 Taro 本地存储 `zhiliao-miniapp-workbench-v1`。微信端提交时将临时照片保存为本地文件;H5 保存为数据 URL,刷新后仍可查看。设备存储不足时显示失败并保留当前编辑供重试,未提交草稿不跨刷新保留。清除此项本地存储可恢复示例数据;不要使用真实敏感资料体验。 照片参考图及 4 段讲解视频由 `scripts/create-demo-media.mjs` 离线生成,拍摄示例页的试卷参考图由 `scripts/create-capture-reference.mjs` 绘制,已随源码提供。需要重新生成时运行对应的 `node scripts/…mjs`(使用本机 Chrome),普通构建无需运行。媒体资源输出为独立文件,避免微信端不支持的视频数据 URL。 上传错题页使用学生关联条、拍照区域和相册/文件双列入口;添加照片后显示数量与「识别全部照片」。「查看示例」页仅展示拍摄规范、完整试卷参考、三项拍摄提示和多页说明;拍照或导入照片请返回上传页操作。 上传试卷页使用浅紫色信息卡:名称独占一行、年份与类型并排、省份独占一行。下方为拍照区域、已添加照片入口和「识别全部照片」按钮;相册和 Word/PDF 导入入口位于后方,表单和已添加文件在查看示例或照片后保留。 上传答题卡页展示拍摄规范、浅紫色 A4 答题卡参考卡、三项提示,以及「从相册多选」「拍摄答题卡」双按钮。参考图片由 `scripts/create-answer-reference.mjs` 离线生成,包含姓名、班级、示意二维码和作答区域;首次选择照片后进入确认页。 关联学生使用居中弹窗,未关联学生时班级显示「请选择班级」,不默认选中班级;已有选择时重新打开弹窗,回显首位已选学生的班级及该班已选学生。先选择班级,再通过学生下拉多选。跨班级保留名单,已选学生以可删除标签展示。取消会丢弃本次选择,确认后才更新上传页名单。 关联名单仅用于本次上传,不保存为下次默认选择;重新进入、刷新页面或成功后「继续上传」均清空。查看照片和拍摄示例后返回,仍保留本次选择;已提交记录中的关联学生继续保留。 拍照、从相册选择和导入 Word/PDF 均不校验关联学生;点击「识别全部照片」时才校验,未关联学生则弹出选择框,取消后保留已添加的文件。 「已添加照片」按顺序展示照片缩略图、文件名、查看与删除入口;Word/PDF 使用文件图标。顶部可继续拍照,底部「完成」返回上传页,再统一识别。图片预览只包含照片,不包含文档。 ## 安装与预览 要求 Node.js 22.18+、pnpm 10.34.9(已在 `packageManager` 中固定)。React 18 为当前 Taro 官方插件支持的版本,未沿用 PC 端的 React 19。 ```powershell pnpm install --frozen-lockfile pnpm dev ``` 如果本机全局 pnpm 不是 10.34.9,可将命令前缀换成 `npx --yes pnpm@10.34.9`,例如 `npx --yes pnpm@10.34.9 dev`,无需改动全局安装。 先执行 `pnpm dev` 完成首次编译,再在微信开发者工具中直接导入 **`math.miniapp` 根目录**。根目录的 `project.config.json` 已将 `miniprogramRoot` 设为 `dist/`,修改源码后会自动重新编译。`pnpm build:dev` 可生成一次性的开发环境产物。 默认 `touristappid` 用于本地预览;需要真机或正式上传时,在微信开发者工具中使用自己的公开 AppID,不在本项目填写 AppSecret。也支持单独导入 `dist/`,该目录的工程配置可用进程环境变量覆盖 AppID: ```powershell $env:TARO_APP_ID = '你的小程序AppID' pnpm build:test ``` 浏览器辅助预览:`pnpm dev:h5`,访问 `http://127.0.0.1:10086`。H5 用于快速查看布局与交互,微信端效果仍需在开发者工具及真机上确认。构建命令只编译本地文件,不会上传或发布小程序。 ## 三套打包环境 | 环境 | 打包命令 | 产物目录 | | --- | --- | --- | | 开发 | `pnpm build:dev` | `dist/` | | 测试 | `pnpm build:test` | `dist/` | | 正式 | `pnpm build:production`(或 `pnpm build`) | `dist/` | `pnpm build:all` 依次构建开发、测试、正式环境,最终 `dist/` 保留正式环境产物。测试环境监听构建使用 `pnpm dev:test`。切换环境前请先停止正在运行的监听构建,避免不同命令同时写入 `dist/`。需要恢复开发环境时运行 `pnpm dev` 或 `pnpm build:dev`。 H5 开发环境静态打包使用 `pnpm build:h5`,产物单独保存到 `dist-h5/`,避免覆盖小程序产物。 业务环境由构建命令选择,脚本显式传递 `--mode development/test/production`,由 Taro 加载对应的 `.env.*` 文件,并设置 `APP_ENV`。所有一次性打包均使用 `NODE_ENV=production` 优化,避免将 React 的构建模式和业务测试环境混用。三个环境共用 `dist/`,后一次构建覆盖前一次,微信开发者工具运行的是最近一次构建的环境。 `dist/build-info.json` 包含当前产物的环境、平台、版本、数据来源和构建时间;单独导入 `dist/` 时微信工程名称也带环境后缀。所有环境的页面顶部均不显示环境标记;「关于」页可以查看环境和版本。三套环境目前都不含 API 地址,未来接接口时再分别添加公开配置,不能把密钥编译进前端。 根目录 `project.config.json` 用于直接导入仓库,同时作为产物工程配置的模板;构建生成的 `dist/project.config.json` 将 `miniprogramRoot` 设为 `./`,也可直接导入。`TARO_APP_ID` 仅覆盖产物工程配置,不改写根目录配置。不同 AppID 不是区分环境的必要条件,微信体验版/正式版发布状态与业务环境是两个概念。 ## 环境变量 | 文件 | 用途 | 提交 Git | | --- | --- | --- | | `.env.development` | 开发环境的公开值 | 是 | | `.env.test` | 测试环境的公开值 | 是 | | `.env.production` | 正式环境的公开值 | 是 | | `.env` / `.env.local` | 可选的公共默认值 / 个人默认值 | 否 | | `.env..local` | 某个环境的个人覆盖值 | 否 | 同名变量的优先级从高到低:进程环境变量 → `.env..local` → `.env.` → `.env.local` → `.env`。每个模式在独立构建进程中加载,`build:all` 不会沿用上一个环境文件的值。修改环境文件后需重启监听构建。 `.env` 文件格式本身不限制变量名前缀,但本项目使用 Taro 默认加载规则,自动加载并注入前端的自定义变量必须以完整的 `TARO_APP_` 开头,单独的 `TARO_` 前缀不够。任意名称的变量不会自动加载到业务代码;系统进程变量和框架内置变量另有用途。 例如,在本地 `.env` 中定义所有环境共用的公开变量(此文件不提交 Git): ```dotenv TARO_APP_APP_NAME=知了数学 ``` 在业务代码中可直接读取: ```ts const appName = process.env.TARO_APP_APP_NAME ``` 请使用完整的 `process.env.TARO_APP_XXX` 表达式,避免解构或动态键读取。同名值若存在于 `.env.development` 等优先级更高的文件中,将覆盖 `.env`,空字符串也会覆盖;需要使用公共默认值时,移除环境文件中的同名项。 三个环境文件已包含: ```dotenv TARO_APP_ENV_LABEL=开发环境 TARO_APP_API_BASE_URL= TARO_APP_ENABLE_DEBUG=true TARO_APP_ID=touristappid ``` 环境名称和调试开关分别按环境填写;接口地址目前留空,仍然只运行本地演示,不发请求。`TARO_APP_ENABLE_DEBUG` 必须为 `true` 或 `false`,不会自动打开调试工具。`TARO_APP_ID` 默认为游客 AppID;需要个人覆盖时在 `.env.development.local` 等文件中填写。 业务代码统一读取经过类型转换的配置: ```ts import { appConfig } from '@/config/environment' const apiBaseUrl = appConfig.apiBaseUrl const enableDebug = appConfig.enableDebug // boolean ``` 新增变量时,共用默认值放在本地 `.env`,不同环境的值放在对应 `.env.*`,并同步维护本节变量说明。需要统一暴露给业务代码的变量,更新 `types/global.d.ts` 的类型声明及 `src/config/environment.ts` 的读取/转换。需要构建时校验的变量同步维护 `config/environments.ts` 中的 `readPublicConfig`。不要在 TypeScript 中再硬编码三套环境值。Taro 以字符串注入环境变量,数字、布尔值需显式转换。 `src/config/environment.ts` 仍作为统一的类型化读取入口,「关于」页面正在使用它;它还负责将 `TARO_APP_ENABLE_DEBUG` 转换为布尔值。环境值来自 `.env.*`,这个文件不再维护三套配置。项目不保留额外的环境示例模板,变量说明直接维护在 README 和三套公开环境文件中。 `TARO_APP_` 变量会打进前端包,只存放公开配置,不包含密钥。`APP_ENV`、`NODE_ENV` 由脚本控制,不在环境文件中设置。 ## 验证 ```powershell pnpm typecheck pnpm lint pnpm test pnpm build:all pnpm test pnpm build:h5 pnpm test:e2e ``` 单元测试覆盖环境校验、模式文件加载、覆盖优先级、统一输出目录、产物配置,以及追加/删除照片时保留编辑、跨班级同名学生、表单校验、重复提交、审核回传和消息已读;可通过 `EXPECTED_APP_ENV` 指定产物应有的环境。E2E 使用本机 Chrome,覆盖 390px/320px 两种视口、错题编辑与重试、答题卡部分失败与重拍、试卷元信息/本地图片/PDF 选择/审核回传、刷新保留原图、视频播放、题库、个人页与无业务 API 请求。未安装 Chrome 时需先安装,或修改 Playwright 的浏览器配置。相机权限、微信文件选择器和原生视频播放仍需微信开发者工具及真机验证。 ## 目录约定 各页面保留自己的 `index.scss` 样式入口,确保微信端生成对应的 `index.wxss`。产物测试逐页检查 JS、JSON、WXML、WXSS,避免微信开发者工具因缺失页面样式而编译失败。 - `src/pages`:首页、个人页、上传、消息、讲解和题库;`src/components`:公共表单、题目卡片、学生选择、安全区与弹层。 - `src/data`:本地领域类型、模拟识别/回传、持久化状态、媒体适配及演示登录态;后续接接口可替换数据层。 - `config`、`scripts`:环境与跨平台构建入口。 - `tests`:环境回归与浏览器交互验证。 品牌 Logo 复用工作区 `math.client-pc/public/logo.png` 的副本;底部导航和通知铃铛 PNG 图标由本项目绘制,通知图标可运行 `scripts/create-notification-icon.ps1` 重新生成。未引入 PC 端的 Electron、Ant Design 或 API 依赖。