# LexiGo **Repository Path**: AchieveMiniMax/lexi-go ## Basic Information - **Project Name**: LexiGo - **Description**: 本项目是主打极简学习+进度可视化的微信背单词小程序,启动直入学习页,点击「已掌握」即更新进度条、加载下一个单词,标记单词同步生词本。学习页展示单词全信息,支持发音、收藏、分享,配套生词本、统计、个人设置功能,适配碎片化学习,以流畅的进度反馈提升用户学习意愿与留存。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-03-28 - **Last Updated**: 2026-03-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LexiGo - 背单词微信小程序 > 轻量背单词微信小程序,核心是极简单词学习+进度可视化,打开即学,操作零成本。 ## 📋 项目概述 **项目周期:** 6周(2026-03-28 至 2026-05-09) **核心价值:** - **对用户**:打开即学,操作零成本;进度实时变化,直观感知学习成果 - **对产品**:降低使用门槛,提升启动率与日活;通过进度反馈提升留存 **目标用户:** - 碎片化时间学习者(通勤、课间) - 追求极简学习体验的用户 - 需要明确进度反馈来维持动力的用户 **📌 当前状态:** ✅ 后端开发完成,所有模块已实现并通过单元测试 --- ## 🏗️ 技术架构 ### 后端技术栈 | 技术类型 | 选型 | 版本 | 说明 | |---------|------|------|------| | 核心框架 | Spring Boot | 2.7.18 | 轻量无冗余,快速开发 | | Web框架 | Spring MVC | - | RESTful接口设计 | | 持久层 | MyBatis-Plus | 3.5.3.1 | 简化CRUD操作 | | 数据库 | MySQL | 8.0+ | 关系型数据库 | | 缓存 | Redis | 6.x | 高性能内存数据库 | | 接口文档 | Swagger3 | 3.0 | 在线API调试 | | 身份认证 | JWT | 0.11.5 | 无状态认证 | | 工具库 | Hutool | 5.8.23 | Java基础工具集 | | 部署容器 | Tomcat | 9.x | Spring Boot内置 | | JDK | Java | 17 | 编译版本 | ### 前端技术栈 | 技术类型 | 选型 | 说明 | |---------|------|------| | 基础框架 | 微信小程序原生框架 | WXML/WXSS/JS | | 网络请求 | wx.request | 封装请求拦截/响应拦截 | | 状态管理 | App对象 + Storage | 轻量全局状态 | | 音频播放 | wx.createInnerAudioContext | 适配iOS/Android | --- ## 📁 项目结构 ``` LexiGo/ ├── backend/ # 后端项目 (Spring Boot) │ ├── src/main/java/com/wordlearn │ │ ├── common/ # 通用模块 │ │ │ ├── constant/ # 常量定义 │ │ │ ├── controller/ # 通用控制器 │ │ │ ├── dto/ # 数据传输对象 │ │ │ ├── exception/ # 异常处理 │ │ │ ├── response/ # 统一响应封装 │ │ │ ├── util/ # 工具类 │ │ │ └── vo/ # 视图对象 │ │ ├── config/ # 配置类 │ │ │ ├── AsyncConfig # 异步配置 │ │ │ ├── MyBatisPlusConfig # MyBatis-Plus配置 │ │ │ ├── RedisConfig # Redis配置 │ │ │ ├── RestTemplateConfig # HTTP客户端配置 │ │ │ ├── SwaggerConfig # Swagger文档配置 │ │ │ ├── WebMvcConfig # Web MVC配置 │ │ │ └── WxConfig # 微信配置 │ │ ├── dao/ # 数据访问层 │ │ │ ├── UserMapper # 用户数据访问 │ │ │ ├── WordMapper # 单词数据访问 │ │ │ ├── UserStudyProgressMapper # 学习进度访问 │ │ │ └── UserWordStatusMapper # 单词状态访问 │ │ ├── entity/ # 实体类 │ │ │ ├── User # 用户实体 │ │ │ ├── Word # 单词实体 │ │ │ ├── UserStudyProgress # 学习进度实体 │ │ │ └── UserWordStatus # 单词状态实体 │ │ ├── filter/ # 过滤器/拦截器 │ │ │ └── LoginInterceptor # 登录拦截器 │ │ ├── user/ # 用户管理模块 │ │ │ ├── controller/ # 用户控制器 │ │ │ ├── dto/ # 用户DTO/VO │ │ │ └── service/ # 用户服务接口与实现 │ │ ├── study/ # 单词学习模块 [核心] │ │ │ ├── controller/ # 学习控制器 │ │ │ ├── dto/ # 学习DTO │ │ │ ├── service/ # 学习服务接口与实现 │ │ │ └── vo/ # 学习VO │ │ ├── collection/ # 单词收藏模块 │ │ │ ├── controller/ # 收藏控制器 │ │ │ ├── dto/ # 收藏DTO │ │ │ ├── service/ # 收藏服务接口与实现 │ │ │ └── vo/ # 收藏VO │ │ └── stat/ # 统计分析模块 │ │ ├── controller/ # 统计控制器 │ │ ├── service/ # 统计服务接口与实现 │ │ └── vo/ # 统计VO │ ├── src/test/java/ # 测试代码 │ │ └── com/wordlearn/ │ │ ├── collection/service/ # 收藏服务测试 │ │ └── user/service/ # 用户服务测试 │ ├── src/main/resources/ │ │ └── application.yml # 应用配置文件 │ └── pom.xml # Maven项目配置 │ ├── 前端 (微信小程序) [待开发] │ ├── pages/ │ │ ├── study/ # 学习页 │ │ ├── collection/ # 生词本 │ │ ├── stat/ # 统计 │ │ └── mine/ # 我的 │ ├── utils/ │ │ ├── request.js # 网络请求封装 │ │ └── cache.js # 本地缓存工具 │ └── app.js # 全局App实例 │ └── 文档/ ├── 产品经理-需求文档.md ├── 架构师-架构设计文档.md ├── 架构师-接口契约结构.md ├── DBA数据库设计师-数据库设计文档.md ├── DBA数据库设计师-数据库初始化 SQL 脚本.md ├── 项目经理-WBS 文档.md ├── Plan.md # 实施方案 └── 文档一致性检查报告.md ``` --- ## 🔌 API接口概览 ### 基础配置 - **接口根路径:** `http://localhost:8080/word-api/v1` - **请求格式:** JSON - **必传请求头:** `token`(登录后获取) - **测试文档:** Swagger UI `http://localhost:8080/word-api/swagger-ui/index.html` ### ✅ 用户管理模块 (/user) | 接口 | 方法 | 说明 | 认证 | |-----|------|------|------| | `/user/login` | POST | 微信登录,获取token | ❌ | | `/user/config/get` | GET | 获取学习配置 | ✅ | | `/user/config/update` | PUT | 修改每日计划数 | ✅ | **登录请求示例:** ```json POST /word-api/v1/user/login Content-Type: application/json { "code": "081XXXXXXXXXXXXXXX" } ``` **登录响应示例:** ```json { "code": 200, "msg": "操作成功", "data": { "token": "eyJhbGciOiJIUzI1NiJ9...", "userId": "123456789", "planNum": 50 } } ``` ### ✅ 单词学习模块 (/study) ⭐核心 | 接口 | 方法 | 说明 | 认证 | |-----|------|------|------| | `/study/first` | GET | 获取今日首个未学习单词 | ✅ | | `/study/markMaster` | POST | 标记单词已掌握 | ✅ | **获取首个单词响应示例:** ```json { "code": 200, "msg": "操作成功", "data": { "progress": { "finishNum": 0, "planNum": 50 }, "word": { "wordId": "1", "word": "apple", "partOfSpeech": "n.", "phonetic": "[ˈæpl]", "meaning": "苹果", "example": "I eat an apple every day. 我每天吃一个苹果。", "audioUrl": "https://cdn.example.com/audio/apple.mp3" } } } ``` ### ✅ 单词收藏模块 (/collection) | 接口 | 方法 | 说明 | 认证 | |-----|------|------|------| | `/collection/add` | POST | 收藏单词 | ✅ | | `/collection/remove` | DELETE | 取消收藏 | ✅ | | `/collection/list` | GET | 获取收藏列表(分页) | ✅ | | `/collection/masterList` | GET | 获取已掌握列表(分页) | ✅ | **收藏请求示例:** ```json POST /word-api/v1/collection/add Content-Type: application/json token: eyJhbGciOiJIUzI1NiJ9... { "wordId": "1" } ``` ### ✅ 统计分析模块 (/stat) | 接口 | 方法 | 说明 | 认证 | |-----|------|------|------| | `/stat/overview` | GET | 获取学习概览统计 | ✅ | **统计响应示例:** ```json { "code": 200, "msg": "操作成功", "data": { "totalWord": 500, "continueDays": 30, "todayFinish": 50, "collectNum": 120 } } ``` --- ## 🗄️ 数据库设计 ### 核心表结构 #### user 用户表 | 字段 | 类型 | 说明 | 约束 | |-----|------|------|------| | id | BIGINT | 用户ID | PRIMARY KEY, AUTO_INCREMENT | | openid | VARCHAR(64) | 微信唯一标识 | UNIQUE INDEX | | nickname | VARCHAR(100) | 昵称 | - | | avatar_url | VARCHAR(255) | 头像URL | - | | daily_plan_count | INT | 每日计划数 | DEFAULT 50 | | created_at | DATETIME | 创建时间 | - | | updated_at | DATETIME | 更新时间 | - | #### word 单词库表 | 字段 | 类型 | 说明 | 约束 | |-----|------|------|------| | id | BIGINT | 单词ID | PRIMARY KEY, AUTO_INCREMENT | | word | VARCHAR(100) | 单词 | - | | part_of_speech | VARCHAR(50) | 词性 | - | | phonetic | VARCHAR(100) | 音标 | - | | meaning | TEXT | 中文释义 | - | | example_en | TEXT | 英文例句 | - | | example_cn | TEXT | 中文例句 | - | | audio_url | VARCHAR(255) | 发音地址 | - | | created_at | DATETIME | 创建时间 | - | #### user_study_progress 用户学习进度表 | 字段 | 类型 | 说明 | 约束 | |-----|------|------|------| | id | BIGINT | 进度ID | PRIMARY KEY, AUTO_INCREMENT | | user_id | BIGINT | 用户ID | INDEX | | study_date | DATE | 学习日期 | - | | plan_count | INT | 计划数 | - | | completed_count | INT | 已完成数 | - | | is_completed | TINYINT | 是否完成 | DEFAULT 0 | | created_at | DATETIME | 创建时间 | - | | updated_at | DATETIME | 更新时间 | - | #### user_word_status 用户单词状态表 | 字段 | 类型 | 说明 | 约束 | |-----|------|------|------| | id | BIGINT | 状态ID | PRIMARY KEY, AUTO_INCREMENT | | user_id | BIGINT | 用户ID | INDEX | | word_id | BIGINT | 单词ID | INDEX | | study_date | DATE | 学习日期 | - | | is_mastered | TINYINT | 已掌握 | DEFAULT 0 | | is_collected | TINYINT | 已收藏 | DEFAULT 0 | | created_at | DATETIME | 创建时间 | - | | updated_at | DATETIME | 更新时间 | - | ### Redis缓存设计 | Key规则 | 类型 | 说明 | |--------|------|------| | `study:progress:{userId}:{date}` | String | 学习进度 | | `study:queue:{userId}:{date}` | List | 今日学习队列 | | `study:mastered:{userId}:{date}` | Set | 今日已掌握单词 | | `word:info:{wordId}` | Hash | 单词信息缓存 | | `word:collection:{userId}` | Set | 用户收藏列表 | | `token:{userId}` | String | 用户Token缓存 | | `idempotent:*` | String | 幂等校验键 | --- ## 🚀 核心业务流程 ### 1. 启动直入学习页 ``` 小程序启动 → App.onLaunch() → switchTab学习页 → onLoad() → GET /study/first → 后端查Redis获取进度+首个单词 → 前端渲染骨架屏 → 展示单词数据 ``` ### 2. 点击"已掌握"【核心流程】 ``` 用户点击"已掌握" ↓ 【前端本地先行】进度+1,按钮动画 ↓ POST /study/markMaster { wordId } ↓ 后端幂等校验 (Redis SET NX) ↓ 更新Redis进度 + 标记已掌握 ↓ 异步更新数据库 ↓ 加载下一个单词 ↓ 返回 { newProgress, nextWord, isFinish } ↓ 前端渲染 → 完成页跳转 or 新单词 ``` ### 3. 收藏/取消收藏 ``` 用户点击收藏按钮 ↓ 切换按钮状态 (空心→实心) ↓ POST /collection/add { wordId } ↓ 后端更新Redis + 异步落库 ↓ 返回成功 ``` --- ## ⚙️ 环境配置 ### 后端配置 (application.yml) ```yaml server: port: 8080 servlet: context-path: /word-api/v1 spring: datasource: url: jdbc:mysql://localhost:3306/word_study username: root password: ${DB_PASSWORD:123456} redis: host: localhost port: 6379 database: 0 timeout: 5000ms jwt: secret: ${JWT_SECRET:your-secret-key} expiration: 604800000 # 7天 wx: appid: ${WX_APPID} secret: ${WX_SECRET} ``` ### 环境变量要求 | 变量名 | 说明 | 示例 | |-------|------|------| | `JWT_SECRET` | JWT签名密钥 | 64位十六进制字符串 | | `WX_APPID` | 微信小程序AppID | wx1234567890abcdef | | `WX_SECRET` | 微信小程序AppSecret | abcdef1234567890... | | `DB_PASSWORD` | 数据库密码 | your_db_password | --- ## 🔐 安全机制 1. **JWT Token认证** - Payload包含userId和openid - 7天过期时间 - HS256算法签名 2. **接口幂等性** - 已掌握:userId + wordId + studyDate - 收藏:userId + wordId - Redis SET NX EX 1小时 3. **前端防抖** - 按钮500ms内禁止重复点击 - 本地先行 + 失败回滚 4. **微信配置校验** - 启动时校验配置完整性 - 运行时异常捕获,不影响主流程 5. **Redis容错** - Redis操作失败不影响登录和学习流程 - 仅记录警告日志 --- ## 🧪 测试状态 ### ✅ 单元测试覆盖 **总测试数:** 25 **通过率:** 100% ✅ #### CollectionServiceTest (15个测试) - ✅ 获取已掌握列表 - ✅ 获取收藏列表 - ✅ 收藏单词 - ✅ 取消收藏 - ✅ 异常场景(重复操作、单词不存在) #### UserServiceTest (10个测试) - ✅ 新用户微信登录 - ✅ 老用户登录 - ✅ 获取用户配置 - ✅ 修改学习计划数(正常值、边界值) ### 运行测试 ```bash cd backend mvn clean test ``` --- ## 🗂️ 项目里程碑 | 阶段 | 时间 | 状态 | 关键任务 | |-----|------|------|---------| | 准备阶段 | 03-28~30 | ✅ 完成 | 项目启动、接口契约冻结 | | 后端开发 | 03-31~04-16 | ✅ 完成 | 基础框架、核心模块开发 | | 前端开发 | 04-01~04-17 | ⏳ 待开发 | 小程序页面与交互开发 | | 前后端联调 | 04-18~04-22 | ⏳ 待开始 | 全流程联调测试 | | 测试阶段 | 04-15~05-01 | ⏳ 待开始 | 功能、性能、安全测试 | | 上线准备 | 05-02~05-04 | ⏳ 待开始 | 代码冻结、部署、提审 | | 正式上线 | 05-05~05-06 | ⏳ 待开始 | 上线与监控 | --- ## 📝 开发指南 ### 后端开发(Java/Spring Boot) #### 1. 项目启动 ```bash # 进入后端目录 cd backend # 安装依赖并启动 mvn spring-boot:run # 或打包后运行 mvn clean package java -jar target/lexigo-backend-1.0.0.jar ``` #### 2. API文档访问 - Swagger UI: http://localhost:8080/word-api/swagger-ui/index.html - API Docs: http://localhost:8080/word-api/v3/api-docs #### 3. 核心实现要点 - **Redis缓存优先**:学习进度和单词队列存储在Redis - **@Async异步落库**:数据库操作异步执行,提升响应速度 - **幂等校验防重**:使用Redis SET NX防止重复操作 - **JWT Token认证**:统一身份验证和拦截 - **统一响应封装**:所有接口返回Result格式 - **全局异常处理**:BusinessException统一处理业务异常 #### 4. 模块开发顺序 - ✅ T1.1 基础框架(统一响应、异常处理、JWT工具) - ✅ T1.2 用户管理(微信登录、JWT认证) - ✅ T1.3 单词学习(核心模块)⭐ - ✅ T1.4 生词本(收藏功能) - ✅ T1.5 统计分析 ### 前端开发(微信小程序) #### 1. 项目初始化 ```javascript // app.js App({ globalData: { baseUrl: 'https://your-domain.com/word-api/v1', token: null, userId: null, todayPlanNum: 50, todayFinishNum: 0 } }) ``` #### 2. 页面开发顺序 - ⏳ T2.1 基础框架 - ⏳ T2.2 学习页 ⭐核心 - ⏳ T2.3 生词本&统计页 - ⏳ T2.4 我的页&底部导航 #### 3. 关键实现点 - 本地先行UI更新 - 按钮防抖机制 - 音频预加载 - 骨架屏优化体验 --- ## 📊 性能指标 | 指标 | 目标 | 当前状态 | |-----|------|---------| | 页面加载时间 | ≤ 2s | ⏳ 待测试 | | 已掌握点击响应 | ≤ 500ms | ⏳ 待测试 | | 音频加载时间 | ≤ 1s | ⏳ 待测试 | | 缓存命中时间 | ≤ 100ms | ⏳ 待测试 | | 后端API响应时间 | ≤ 200ms | ⏳ 待测试 | --- ## 📚 相关文档 | 文档 | 角色 | 说明 | |-----|------|------| | [产品经理-需求文档.md](产品经理-需求文档.md) | 产品经理 | 产品需求与验收标准 | | [架构师-架构设计文档.md](架构师-架构设计文档md.md) | 架构师 | 技术架构与核心方案 | | [架构师-接口契约结构.md](架构师-接口契约结构.md) | 架构师 | API接口详细定义 | | [DBA数据库设计师-数据库设计文档.md](DBA数据库设计师-数据库设计文档.md) | DBA | 数据库表结构设计 | | [DBA数据库设计师-数据库初始化 SQL 脚本.md](DBA数据库设计师-数据库初始化%20SQL%20脚本.md) | DBA | 建表SQL脚本 | | [项目经理-WBS 文档.md](项目经理-WBS%20文档.md) | 项目经理 | 任务分解与排期 | | [Plan.md](Plan.md) | 实施工程师 | 代码级实施方案 | | [文档一致性检查报告.md](文档一致性检查报告.md) | 质量保障 | 文档一致性验证 | --- ## 👥 项目团队 | 角色 | 职责 | |-----|------| | 产品经理 | 需求定义、验收标准 | | 架构师 | 技术架构、接口设计 | | DBA | 数据库设计 | | 后端工程师 | Java/Spring Boot开发 | | 前端工程师 | 微信小程序开发 | | QA工程师 | 测试方案与执行 | | 项目经理 | 项目规划与协调 | --- ## 🐛 Bug修复记录 ### v1.0.1 (2026-03-29) #### 已修复的测试Bug 1. **Mockito doNothing() 使用错误** (影响3个测试) - 文件: `UserServiceTest.java` - 问题: `updateById()` 返回 int,不能使用 `doNothing()` - 修复: 改用 `when().thenReturn(1)` 模拟返回值 2. **新用户登录 Token 为 null** - 文件: `UserServiceTest.java` - 问题: mock `insert()` 未设置用户ID - 修复: 使用 `thenAnswer()` 模拟ID自动填充 --- ## 📈 版本历史 - **v1.0.0** (2026-03-29) - 初始版本,后端核心功能完成 - **v1.0.1** (2026-03-29) - 修复测试Bug,测试覆盖率100% --- **项目状态:** ✅ 后端开发完成,前端开发待启动 **文档版本:** V1.0.1 **最后更新:** 2026-03-29