# 后端项目知识库 > 工程:UserHome | 技术栈:Spring Boot 2.7.18 / JDK 1.8 / Spring Data JPA(Hibernate) + MySQL 8.0.33 / Redis | 最近更新:2026-08-20 > 维护规则:发生重大功能变化、或收到"更新后端项目知识库"指令时更新。 ## 一、项目概览 - 定位:yh-platform 的**用户首页 / 应用门户**模块。负责用户首页应用聚合展示(分类 tab + 图标网格 + 搜索)、用户「常用应用」设置(≤8)、角色身份切换。应用元数据不落本地库,跨仓来自 UserBase。 - 技术栈与版本:Spring Boot 2.7.18(parent `spring-boot-starter-parent`);JDK 1.8;持久化 Spring Data JPA + Hibernate,MySQL 8.0.33;缓存 Redis(`spring-boot-starter-data-redis`);构建 Maven;统一依赖经 `yh-platform-dependencies` BOM 与 `spring-cloud-alibaba-dependencies 2021.0.5.0`(Nacos,适配 Boot 2.7)。 - 启动 / 运行方式:入口 `UserHomeApplication`;端口 **8070**,context-path `/`。默认 profile=`local`(不连 Nacos,纯走 application.yml);CI 注入 `SPRING_PROFILES_ACTIVE=prod` 启用 Nacos 配置中心覆盖。CAS 登录态用户以 `BoaUser` 注入 Controller。 ## 二、模块与包结构 - `controller.api`:接口层(`UserController`、`UsedAppController`),直接 return 对象,由 `yh-api-std` 包成 `{code:0,data}`。 - `service` / `service.impl`:业务层。远程应用(`AppRemoteService`,跨仓 UserBase)+ 本地常用应用(`UsedAppService`)+ 当前角色(`IUserCurrentRoleService`)。 - `repository`:数据访问(`UsedAppRepository`、`UserCurrentRoleRepository`,JPA)。 - `entity`:JPA 实体(`UsedApp`、`UserCurrentRole`)。 - `model`:枚举(`SetType`)。 - `config`:路径前缀约定(`Config` 枚举)。 - `common`:实体基类(`BaseEntity`)。 ## 三、核心领域模型与关系 - `UsedApp`(表 `used_app`):用户常用应用设置,**一行存一组**(`appIds` 逗号分隔),`set_type(0系统/1学校/2用户) + setId + roleType + schId` 四维唯一,覆盖式保存。**不冗余应用元数据**。 - 逻辑外键:`set_id/c_id → UserBase 用户`、`sch_id → UserBase sys_group.id`、appId → `UserBase application_info.id`。**无物理外键,靠业务字段关联**。 - 唯一索引 `idx_used_app_set(set_id,set_type,role_type,sch_id)`。 - `UserCurrentRole`(表 `user_current_role`):用户当前激活角色(会话态),`userId` 主键 + `roleId/roleName/schId/schName/childId/childName`,对齐旧 UserHome 同名表。 - `SetType`:常用设置级别 0=系统(超管)/1=学校/2=用户。 - `BaseEntity`(抽象 `@MappedSuperclass`):自增 `id` + `create_time` + `update_time`(与 UserBase/BasePlatform 约定一致)。 - 关系边界:**UserHome 只存「常用设置」与「当前角色」,应用元数据跨仓来自 UserBase**(`YschBaseOpenApi.getUserApp`)。 ## 四、关键业务流程 1. **获取用户应用**:`GET /{platform}/user/GetUserApp` → `AppRemoteService.getUserApps`(经 `YschBaseOpenApi.getUserApp(userId, PC_BROWSER)` 实时拉取)→ 返回 `List`(id/name/apps 分组)→ 前端渲染分类 tab(含「全部」)+ 图标网格 + 搜索。 2. **常用应用展示**:`GET /{platform}/usedapp/getUsedApp?roleType=&schId=&isSch=` → 本地 `used_app` 按「用户 > 学校 > 系统」多级取生效记录 → appIds 拆分 → 从跨仓全集过滤 → 返回 `List`(详情,保持顺序)。 3. **保存常用应用**:`POST /{platform}/usedapp/saveUsedApp`(body:appIds 逗号分隔 / type 0|1|2 / roleType / schId)→ 超管强制 type=0(系统级)→ `UsedAppService.save`:四维判重 upsert 覆盖保存。 4. **角色身份**:`getUserRole`(跨仓角色列表)、`findUserRole`(本地当前角色)、`savUserRole`(校验所选 学校+角色 属于角色列表后 upsert 本地表)。 5. **其它**:`GetUserInfo`(登录 BoaUser)、`GetAppInfoById?id=`(在全集中查找,免额外跨仓请求)、`getUsedAppById/saveUsedAppById`(用户级常用,roleType=-1)、`getAppByIds`(按 ids 取应用精简映射)。 ## 五、工程约定与模式 - 异常返回结构:Controller 直接 return 对象,`yh-api-std` 统一包成 `{code:0,data}`(HTTP 200);业务异常抛 `BizException(ErrorCode.FORBIDDEN/PARAM_ERROR, msg)`。 - 鉴权方式:CAS SSO(浏览器登录态,BoaUser 注入,作用于 `/{platform}` 普通接口);跨仓调用 UserBase 走 `yh-app-auth` 应用间签名(`yh.open` 配置 appKey/appSecret,`OpenApiHttpClient` 自动附加 `X-App-Key/X-Timestamp/X-Signature`)。 - 路径前缀约定:`Config` 枚举定义 `/{platform}` 普通、`/oapi/` 开放(与 UserBase 一致)。**注意 Boot 2.6+ 默认 PathPatternParser 不合并连续斜杠,路径末尾不要带斜杠,否则 404**。 - 缓存:已引入 Redis(host localhost:6379 db0),当前未实际用于业务。 - 事务边界:`UsedAppServiceImpl.save` 单表 upsert,未标 `@Transactional`(单条 save 自带事务)。 ## 六、集成点 - **MySQL(库 `bsch_userhome`)**:`used_app` + `user_current_role` 表;JPA `ddl-auto=update` 自动建表。凭据见 `application.yml`。 - **Redis(localhost:6379 db0)**:已配置,用途待核实。 - **Nacos 配置中心**:仅 `prod` profile 启用(`NACOS_CONFIG_ENABLED=true`),拉 `userhome.yaml`(group USERHOME)覆盖本地;本地 `local` 默认不连。详见 `bootstrap.yml`。 - **CAS SSO**:`https://sso.yunhaixingtong.com/cas`。 - **UserBase 跨仓开放接口**:经 `yh-openapi-spring-boot-starter` 自动装配 `YschBaseOpenApi` → `GET {yh.open.base-host}{base-path}/oapi/app/list?userId=&clientType=` 返回 `List`;`/oapi/user/roleList` 返回 `List`。 - **yh-platform starters**:`yh-auth-spring-boot-starter`(CAS)、`yh-app-auth-spring-boot-starter`(签名)、`yh-openapi-spring-boot-starter`(跨仓调用)、`yh-api-std`(统一响应)。 ## 七、重要设计决策与原因 - **本地只存「常用设置 + 当前角色」**,不冗余应用元数据 —— 元数据跨仓来自 UserBase,避免双写不一致。 - **一行存一组(appIds 逗号分隔)**而非逐应用一行 —— 对齐旧 UserHome 四维结构(系统/学校/用户 × 角色),支持超管设系统级、学校设角色级常用;`sortNo` 即逗号顺序。 - **多级生效(用户 > 学校 > 系统)** —— 个人未设置时回退学校/系统默认,`schId==uid` 直接取学校级(对齐旧逻辑)。 - **覆盖式保存(四维唯一 upsert)** —— 幂等,前端顺序即最终序。 - **跨仓调用仅替换实现** —— `AppRemoteService` 接口稳定,`OpenApiAppRemoteServiceImpl` 一行调用 `YschBaseOpenApi.getUserApp`,前端与 Controller 无需感知底层。 - **本地默认关闭 Nacos(profile=local)** —— CI 注入 prod 才连,避免本地 403 噪音;Nacos 不可达 `fail-fast=false` 回退本地配置兜底。 ## 八、待办与已知坑 - **appKey/appSecret 待填**:`yh.open` / `yh.app-auth` 的 app-key/app-secret 当前为占位(`100000` / `change-me-in-phase0`),需在 UserBase 完成 UserHome 应用注册后填入真实值,否则跨仓请求签名失败 401。 - **`yh.open.base-host` 指向**:本地默认 `http://localhost:8060`(UserBase),生产经 Nacos `userhome.yaml` 覆盖。 - **used_app 旧结构残留**:升级前若已有 `user_id/app_id/sort_no` 结构的旧表,`ddl-auto=update` 只加列不删列,建议按 `sql/userhome_init.sql` 备份后重建。 - **Redis 已引入但未实际使用**,待核实是否计划启用。 - **Nacos env 名陷阱**:`NACOS_NAMESPACE` 不生效,必须用 `SPRING_CLOUD_NACOS_CONFIG_NAMESPACE` 覆盖 namespace。 - **路径前缀尾斜杠**:Boot 2.6+ PathPatternParser 不合并连续斜杠,勿带尾斜杠(防 404)。 - **生产建表**:`ddl-auto=update` 自动建表;`sql/userhome_init.sql` 用于显式初始化 / 回滚参考,二者需保持字段一致。