You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pair_project/doc
Ryan 5ef350707c
修复登录bug
3 months ago
..
README.md 修复登录bug 3 months ago

README.md

本地离线测评客户端

一款无需网络、无需数据库、直接双击运行的本地教育测评桌面程序。支持邮箱/用户名登录与注册、密码生成与修改、题目生成与答题评分。


1. 项目定位与特性概览

  • 纯离线:不启动 HTTP 端口,不访问外网;所有逻辑在本地内存 + 文本文件。
  • 瘦前端 / 胖后端:前端仅负责 UI 渲染与输入;校验、题目生成、会话、计分全部在 Python 端。
  • 零构建链不依赖打包工具Vue 3 使用本地 ESM 运行时文件。
  • 明文数据存储:用户信息存放于 shared/users.txt;试卷存放于 shared/papers/ 文件夹下

2. 目录结构与职责

本项目采用典型的「前端轻量、后端负责业务逻辑」划分,前端负责 UI 渲染与用户交互,后端负责所有业务规则、题目生成、会话与持久化。下面以仓库当前文件名说明职责,便于开发与定位代码。

src/
  start.py                  # 应用入口:创建 PyWebView 窗口并绑定后端 API将 window.pywebview.api 暴露给前端)
  backend/                  # 后端业务模块(同步 Python 函数 / 类,均在本地运行,无外网依赖)
    api_bridge.py           # 与前端通信的绑定层Api 类):将前端请求路由到后端服务函数并做最小序列化/权限校验
    user_service.py         # 用户注册 / 登录 / 修改密码 / 文本存储(读写 shared/users.txt
    paper_gen.py            # 试卷/题目生成协调(组合不同题源、去重与分配)
    paper_act.py            # 会话管理session 创建、题目索引推进、临时答题记录(内存)
    paper_save.py           # 试卷持久化(保存已完成试卷到本地文件夹)
    paper_scoring.py        # 成绩计算与评分细则(百分制)
    question_fetch.py       # 外部/占位题库接口封装(实际项目可在此接入网络题库)
    question_filter.py      # 题目过滤、难度/知识点规则、去重等
    question_gen.py         # 内置题目生成器(数学题等)
    email_send.py           # 发送验证码或成绩通知的邮件逻辑
    interfaces.py           # 公共接口定义(供后端内部解耦使用)
  frontend/                 # 前端静态资源(单页面),使用本地 Vue ESM 运行时
    index.html
    src/
      api.js                # 前端对 window.pywebview.api 的封装promise 风格)
      main.js               # Vue 3 组件与状态管理(路由/视图/交互)
      style.css
      vendor/vue.esm-browser.js  # 本地化 Vue 运行时代码
  shared/
    users.txt               # 用户信息明文存储email|username|password仅用于教学示例

职责要点(简短):

  • 前端(frontend/src:

    • 只负责视图渲染、表单校验(输入格式、必填项)与用户交互反馈;
    • 通过 src/api.js 调用 window.pywebview.api 发起请求;
    • 不保存敏感业务逻辑(如题目生成、评分、账号存储)到客户端 JS 中。
  • 后端(backend/:

    • 负责所有业务逻辑:用户管理、试卷生成、会话维护、评分与持久化;
    • api_bridge.py 暴露给前端的 API 是同步的 Python 方法PyWebView 会序列化返回值);
    • 数据以文本文件为主(shared/users.txt、本地试卷文件夹),不依赖数据库或外网服务(默认行为)。

3. 运行原理与数据流

3.1 前端调用链(更详尽)

  1. 用户在 UI 触发操作(登录 / 注册 / 选择题量与年级 / 答题等)。
  2. 前端通过 frontend/src/api.js 提供的封装函数发起调用;该封装返回 Promise内部调用 window.pywebview.api.<method>(args)
  3. PyWebView 将调用映射到 backend/api_bridge.py 中绑定的 Api 类方法。api_bridge.py 负责:参数验格式、简单权限检查、将请求路由到后端对应服务模块(如 user_service.pypaper_gen.pypaper_act.py 等)。
  4. 后端服务执行逻辑并返回可序列化的 Python 类型dict / list / str / int / boolapi_bridge 会把结果直接返回给前端;如遇异常,会返回统一格式的错误对象 { ok: false, error: 'msg' }(前端约定按此格式处理错误提示)。
  5. 前端在 Promise 里处理返回:成功更新 Vue 响应式状态,失败展示错误提示或重试按钮。

交互契约(约定):

  • 所有 API 返回值遵循 { ok: true, data: ... } 或 { ok: false, error: '错误消息' } 的形态;这是 api.jsapi_bridge.py 之间的轻量约束。
  • 大型耗时操作(例如从外部题库拉取)在后端保持同步实现,但 api.js 会把调用封装为 Promise使得前端可以使用 async/await 风格并展示加载状态。
  • 前端只接收已去敏的题目对象(题干 + 选项 + id正确答案仅保留在后端内存/评分流程中,不会在前端暴露。

3.2 会话与答题流程(映射到实际模块)

  • 生成试卷:前端调用 api.generate_test(params) -> api_bridge 调用 paper_gen.py/paper_act.py 进行试卷生成 -> 返回 { ok: true, data: { session_id, total } }。
  • 拉取题目:前端调用 api.get_next_question(session_id) -> paper_act.py 从会话内存队列取出下一个题目并返回(题目对象不包含正确答案)。
  • 提交答案:前端调用 api.submit_answer(session_id, question_id, answer) -> paper_act.py 在会话记录中写入用户答案并推进索引(返回当前进度)。
  • 结束并评分:前端调用 api.finalize_quiz(session_id) -> paper_scoring.py 根据会话内答题记录计算分数并返回成绩摘要;同时 paper_save.py 可将试卷与成绩持久化到本地文件。

后备/题源策略:

  • 题目首先由 question_fetch.py 负责从“外部题库接口”或配置的题源读取;若外部题源不可用或返回不足,则转由 question_gen.py(内置题目生成器)补足;若仍不足则走占位回退(简单选择题、全部答案为 A以保证试卷长度。题源组合与去重由 paper_gen.py/question_filter.py 协调。

3.3 用户与认证(映射到实际模块)

  • 注册:前端调用 api.request_register(email) -> user_service.py 可生成验证码(或使用 email_send.py 发送);前端提交验证码与密码后调用 api.register 完成写入 shared/users.txt
  • 登录:前端调用 api.login(identifier, password)identifier 可为 email 或 username-> user_service.py 校验并返回用户信息的最小视图(不返回密码)。
  • 修改密码:前端提交原密码与新密码 -> user_service.py 校验后写回 shared/users.txt
  • 存储格式:shared/users.txt 使用明文管道分隔形式email|username|password仅作示例教学用途生产请勿明文存储

4. 环境与依赖要求

要求
操作系统 Windows 11 64位
Python 版本 3.10 及以上(推荐 3.11+/64 位)
浏览器 Edge浏览器内置或可安装 Edge WebView2 Runtime大多数 Win10/11 用户已默认配好)
权限 需可读写当前目录下 shared文件夹,不需要管理员权限

5. 快速启动(源码方式)

  1. 进入项目目录(包含 start.py
  2. 安装依赖(首次):
pip install pywebview
  1. 运行:
python start.py
  1. 窗口出现后:    - 直接使用已存在账户(若 users.txt 已含默认管理员)    - 或输入新邮箱 -> 按提示完成注册 -> 登录 -> 选择年级与题量 -> 开始答题。

6. 打包为独立 exeWindows

本项目 ./dist 路径下已打包好可执行的 .exe 单文件,方便直接在其他电脑上运行。而以下为手动打包流程:

采用单文件模式onefile包含所有必要依赖确保在其他 Windows 电脑上无需额外安装即可运行。

6.1 准备虚拟环境

cd src
python -m venv .venv
.venv\Scripts\activate
pip install --upgrade pip
pip install pywebview pyinstaller

6.2 打包命令

cd ..  # 返回项目根目
pyinstaller --noconfirm --clean .\QuizClient.spec  # 运行 PyInstaller使用已有的 spec 文件进行打包

6.3 生成文件

dist/
  QuizClient.exe  # 单文件可执行程序,包含所有依赖

6.4 在其他电脑上运行

直接双击 QuizClient.exe 运行,无需安装任何额外软件(除 Windows 自带的 WebView2 Runtime

若运行目录无 shared 文件夹,程序会自动创建并写入默认管理员账号。

6.5 打包说明

  • 使用虚拟环境而非系统 Python确保依赖隔离
  • 只打包必要的依赖,文件体积紧凑
  • 生成单文件 exe方便分发和运行

7. 许可与使用

  • 内置的 Vue 运行时代码遵循其自身许可证(见 frontend/src/vendor/VUE_LICENSE.txt)。
  • 本项目其余代码可按内部教学 / 演示自由使用。

祝使用愉快!