# 浠艾福 (XAF) - Project Knowledge Base **Branch:** cfclub **Updated:** 2026-06-19 ## OVERVIEW 三方平台型家庭教育服务平台。家长 + 孩子 + 服务商(成长规划师/供应商) + 平台运营。三端架构:Spring Boot 2.7.18 (Java 8) 后端 + uni-app Vue 2 微信小程序 + Vue 2 + Element UI Web 管理端。 **关键数字**:100+ Java 文件、~50 小程序页面、29 Web 管理页面、47+ 数据实体、60+ 控制器。 ## STRUCTURE ``` cfc/ ├── cfc-backend/ # Spring Boot 后端 (port 9082) │ └── src/main/java/com/etotem/cfc/ │ ├── controller/ # 60+ 控制器,按功能子包分组 │ ├── service/ # 业务逻辑层 │ ├── entity/ # MyBatis-Plus 实体 (@Data + @TableName) │ ├── mapper/ # MyBatis-Plus Mapper 接口 │ ├── dto/ # 数据传输对象 (~120 个) │ ├── config/ # JWT / 多数据源 / DatabaseInitializer / WebConfig │ ├── common/ # Result, ProductStatus │ └── task/ # 定时任务 (RepeatTaskGenerator, PointsExpireTask 等) │ ├── cfc-frontend/ # uni-app 微信小程序 │ ├── pages/ # ~50 页面 │ ├── components/ # 29 个可复用组件 │ ├── store/index.js # Vuex 角色状态管理 │ ├── utils/api.js # 1247 行 API 封装 │ ├── config.js # 环境感知 API 地址 │ └── pages.json # 5-Tab: 首页/身体/心智/关系/我的(TabBar 文案,非五维维度名) │ ├── cfc-web/ # Vue 2 + Element UI Web 管理端 │ └── src/ │ ├── views/ # admin/ + teacher/ │ ├── router/ # 角色权限守卫 │ └── store/ # 认证状态 │ ├── docs/ # 需求/设计/测试文档 ├── tests/ # unit/integration/e2e (基础设施不完整) └── .superpowers/ # superpowers 配置 ``` ## WHERE TO LOOK | Task | Location | Notes | |------|----------|-------| | REST API | `cfc-backend/.../controller/` | 按功能模块分组子目录 | | 业务逻辑 | `cfc-backend/.../service/` | 命名: `XxxService.java` | | 数据实体 | `cfc-backend/.../entity/` | MyBatis-Plus `@TableName` + `@Data` | | 配置 | `cfc-backend/.../config/` | JWT / 多数据源 / DatabaseInitializer / WebConfig | | 通用响应 | `cfc-backend/.../common/Result.java` | `Result` (code/message/data) | | 小程序页面 | `cfc-frontend/pages/` | 需在 `pages.json` 注册 | | 小程序 API | `cfc-frontend/utils/api.js` | 统一 `request()` 封装,含自定义 header | | 小程序配置 | `cfc-frontend/config.js` | 环境自动检测 (develop/trial/release) | | 小程序状态 | `cfc-frontend/store/index.js` | Vuex: token/role/currentRole/isSwitchedChild | | Web 前端 | `cfc-web/src/views/` + `router/index.js` | 角色权限路由 | | Web API | `cfc-web/src/api/` | axios 封装 | | 数据库配置 | `cfc-backend/src/main/resources/application.yml` | 主库 `zxyj` + sfms 源库 | | SQL 迁移 | `cfc-backend/src/main/resources/schema*.sql` + `DatabaseInitializer.java` | 启动时自动执行 | | 测试 | `tests/` | unit/integration/e2e | ## CRITICAL CONFIG (不查会错) - **后端端口:9082**(不是 8080) - **数据库名:`zxyj`**(不是 `cfc`),地址 `192.168.16.251:3306`,账号 `zxyj / zxyj@123` - **sfms 源库**:`bianwoyou.mysql.rds.aliyuncs.com:3305/sfms`,账号 `sfms / sfms@123` - **JWT secret**:`cfc-secret-key-2026-spring-boot-jwt-token`,过期 24h - **微信测试模式**:`wechat.test-mode: true`,使用 `13800138000` 模拟手机号 - **Dify AI**:`http://dify.bianwoyou.cn/v1` with API key - **小程序 AppID**:`wx5ba8038ef16fb245` - **Web 端口**:8082 ## COMMANDS ```bash # 后端 cd cfc-backend && mvn clean compile # 编译验证(必做) mvn spring-boot:run # 启动 localhost:9082 mvn test # 运行测试(目前只有1个测试类) # 小程序(需微信开发者工具) cd cfc-frontend && npm install && npm run dev:mp-weixin # Web 管理端 cd cfc-web && npm install && npm run serve # localhost:8082 # 数据迁移 curl -X POST http://localhost:9082/api/migration/run ``` ## CONVENTIONS ### 后端 - **分层**: Controller → Service → Mapper,禁止跨层调用 - **ORM**: MyBatis-Plus,`@TableName` + `@TableId(type = IdType.AUTO)` - **响应**: 统一 `Result`(code/message/data),成功 code=200,错误 code=500/400 - **认证**: JWT Bearer Token,`JwtInterceptor` 拦截 `/api/**`,约 15 个公开路径放行 - **异常处理**: 仅 `GlobalExceptionHandler` 处理 `IllegalArgumentException` → 400 - **DI**: `@Resource` 优先(180+ 处),`@Autowired` 仅 3 处(`AdminGuideController.java`) - **Lombok**: 全项目使用(实体 @Data, 日志 @Slf4j, 配置类等) - **Swagger**: 每个 Controller 类有 `@Tag`,62 个文件含 Swagger 注解 - **CORS**: `WebConfig` 全放通 - **上传**: `./uploads/` 目录,通过 `/uploads/**` 静态资源访问 - **定时任务**: `task/` 包下,含任务重复生成器、积分过期、连续签到重置 等 ### 接口方法 (重要 - 规则与实际有偏差) **声明的规则**:统一 `@PostMapping`,禁止 `@GetMapping/@PutMapping/@DeleteMapping`。 **实际情况**:9 个控制器违反此规则,主要分布在: - `DanAssessmentController` — 12 个 `@GetMapping`(测评结果查询) - `WishController` — 6 个 `@PutMapping/@DeleteMapping`(心愿状态变更) - `GuideManagementController`、`GuideFamilyTaskController` — PUT/DELETE - `TaskTemplatePackageController` — PUT/DELETE - 其他零星违反 **→ 新代码尽量用 `@PostMapping`,但改造已有 @GetMapping/@PutMapping/@DeleteMapping 前需确认。** ### 前端小程序 - **Vue 2 Options API**,生命周期 `onLoad`/`onShow`(非 mounted) - **禁止可选链 `?.`** — 仅 1 个文件违规(`teacher-profile.vue` 2 处),一律用 `&&` 替代 - **禁止 CSS Grid** — 用 flexbox - **API 调用**: `uni.request` + 自定义 header `X-User-Id` + `Authorization: Bearer` - **环境自动检测**: `uni.getAccountInfoSync().miniProgram.envVersion`(develop/trial/release) - **4 套 API Base URL**: localhost:9082 / cfc.iwintrue.com / cfc.etotem.com.cn + danshop 独立地址 - **DanShop 电商模块**: 独立服务(port 8081/8888),通过 `danshopRequest()` 调用 - **TabBar 5 标签**: 首页/身体/心智/关系/我的(TabBar 文案,非五维维度名),角色感知(家长/孩子/规划师展示不同内容) - **页面注册仅子包**: `pages.json` ### Web 管理端 - **Vue 2 + Element UI**,Options API - **Element UI 补丁**: `main.js` 中修补 `el-submenu` 的 `removeTabindex` null 错误 - **路由守卫**: `router.beforeEach` 验证 token → 调 `/api/admin-auth/info` → 角色分流 - **Layout 遮罩防御**: `v-modal { display: none !important }` - **路由错误抑制**: 覆盖 `VueRouter.prototype.push` 捕获 `Redirected` 导航错误 ## UNIQUE STYLES - **双角色系统**: 家长 `parent` ↔ 孩子 `child` 切换,`currentRole` 状态标记,切回需密码 - **教师角色**: `teacher` 独立角色,可登录规划师端,也可切回家长视角;`isSwitchedTeacher` 状态标记 - **角色字段**: 数据库 `role` ENUM + 多角色 `roles` 字段;`vendor_type` 次级角色 - **积分机制**: 任务完成加分、超时扣分,`PointsService` 处理 - **心愿审批**: 孩子创建 → 家长审批定价 → 扣减积分 → 确认收货 - **测评订单**: 家长申请 → 选规划师 → 孩子信息快照 → 支付 → 规划师录入结果 - **四级地址**: 省市区街道,回退匹配,`StreetController` 提供 API - **孩子快照**: 测评时保存身高/体重/学校到 `DanAssessmentResult` - **多数据源**: cfc 主库 + sfms 源库(只读迁移) - **五维能量**: 身(body)/心(mind)/智(wisdom)/行(behavior)/富(wealth),`EnergyService` - TabBar 第4标签显示为"关系",但五维维度名是"行"(行为决定关系) - **AI 聊天**: Dify 后端,`AIChatController` + 独立 `pages/ai/chat.vue` - **电商**: DanShop 独立服务,`danshopRequest()` 调用,含完整购物车/订单/物流 - **推广裂变**: 佣金/提现/团队,`CommissionController`/`WithdrawalController` ## ANTI-PATTERNS - **DO NOT** 在 Controller 中直接操作 Mapper - **DO NOT** 硬编码 API 地址(用 `config.js` 或 `application.yml`) - **DO NOT** 在前端存敏感信息(密码、密钥) - **NEVER** 使用 `@Resource(name="xxx")` 与字段名不一致 - **NEVER** 跳过 JWT 认证直接调用需登录接口 - **NEVER** 使用 `@GetMapping/@PutMapping/@DeleteMapping` — 统一 `@PostMapping`(除非确认改造范围) - **NEVER** 在小程序模板中用 `?.`(用 `&&`) - **NEVER** 对 Java 源文件用 `awk '!seen[$0]++'` 去重(会删合法重复行) - **NEVER** 直接 `new XxxMapper()` — 必须通过 `@Resource` 注入 ## VERIFICATION WORKFLOW 1. 改后端 → `mvn clean compile` 确认编译通过 2. `mvn spring-boot:run` 确认应用正常启动(显示 Started) 3. 测试相关 API 端点 4. 改前端 → `npm run dev:mp-weixin` 或 `npm run serve`(Web 端) 5. `lsp_diagnostics` 检查改过的文件 ## HIERARCHICAL DOCUMENTATION ``` cfc/ ├── AGENTS.md # 本文件 ├── cfc-backend/AGENTS.md # 后端详细文档 ├── cfc-frontend/AGENTS.md # 小程序前端文档 ├── cfc-web/AGENTS.md # Web管理端文档 ├── tests/AGENTS.md # 测试策略文档(基础设施不完整) └── docs/ # 需求/设计/测试文档 ```