# home-server-sys-app **Repository Path**: weh_coder/home-server-sys-app ## Basic Information - **Project Name**: home-server-sys-app - **Description**: 基于 Spring Boot 3 的家政服务平台后端,提供用户端、服务人员端(server)、管理员端(admin)以及 AI 智能助手(ai)等模块接口 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-21 - **Last Updated**: 2026-08-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: SpringAI, 家政服务, AI助手, Agent ## README # 家政服务系统后端(home_server_system) 基于 Spring Boot 3 的家政服务平台后端,提供用户端、服务人员端(server)、管理员端(admin)以及 AI 智能助手(ai)等模块接口。 > 微信公众号:weh程序猿 ## 一、技术栈 | 领域 | 技术选型 | | --- | --- | | 基础框架 | Spring Boot 3.2.5 | | 编程语言 | Java 17 | | Web 容器 | Undertow(已排除 Tomcat) | | 持久层 | MyBatis-Plus 3.5.7(spring-boot3 版) + PageHelper 2.1.1 | | 数据库 | MySQL(mysql-connector-j),连接池 HikariCP | | 缓存 | Redis(Jedis 连接池) | | 安全 | Spring Security + JWT(jjwt) | | 消息队列 | RabbitMQ(邮件异步发送:正常队列 + 死信队列 + 手动 ACK + 重试上限 + Confirm/Return 失败监控) | | 文件存储 | 阿里云 OSS / MinIO(可配置切换) | | 导入导出 | EasyExcel 4.0.3 | | AI 能力 | Spring AI 1.1.2(OpenAI 协议兼容,可接智谱/通义等大模型) | | 接口文档 | Knife4j OpenAPI3(jakarta 版) | | 实时通信 | WebSocket(`/ws/{userId}`,握手 token 鉴权,聊天/通知异步推送) | | 工具库 | Lombok、Hutool、Guava、Fastjson、commons-lang3、ip2region、UserAgentUtils、ZXing(二维码) | | 构建工具 | Maven | ## 二、环境要求 - **JDK 17** - **Maven 3.6+** - 可用的中间件/外部服务:**MySQL、Redis、RabbitMQ、SMTP 邮箱服务、MinIO 或 阿里云 OSS、高德天气 API、AI 大模型服务** ## 三、目录结构 ``` src/main/java/com/weh/homeserver/ ├── HomeServerApplication.java # 启动类 ├── controller/ # 控制器(按角色分包:admin / user / server / common / ai) ├── service/ # 业务接口 │ └── impl/ # 业务实现(含 WebSocketPushService:聊天/通知实时异步推送) ├── mapper/ # MyBatis Mapper 接口 ├── entity/ # 数据库实体(DO) ├── model/ # DTO / VO / 请求响应对象 ├── enums/ # 枚举 ├── config/ # 配置类(Security、Redis、RabbitMQ、MybatisPlus、WebSocket、Swagger、Ai 等) ├── constant/ # 常量 ├── utils/ # 工具类 ├── properties/ # 配置属性绑定类(@ConfigurationProperties) ├── exception/ # 全局异常与处理器 ├── filter/ / interceptor/ / handler/ # 过滤器、拦截器、处理器(interceptor/ 内含 WebSocket 握手鉴权 TokenEndpointConfigurator) ├── listener/ / mq/ # 消息监听与 MQ 配置 ├── strategy/ # 策略模式(如对象存储) ├── tool/ # AI Tool(供 Spring AI 调用) └── websocket/ # WebSocket 端点(WebSocketEndpoint,连接路径 /ws/{userId}) src/main/resources/ ├── application.yml # 主配置(含 ${...} 占位符) ├── application-dev.yml # dev 环境实际配置值 ├── mapper/ # MyBatis XML 映射文件 ├── templates/ # Thymeleaf 模板(邮件等) ├── ip/ # ip2region 数据库 └── META-INF/ ``` ## 四、配置说明 - 主配置 `application.yml` 使用占位符(如 `${mysql.host}`、`${ai.api-key}`),实际值写在 `application-dev.yml`。 - 默认激活 Profile:`dev`。 - 服务端口:默认 `19000`(可用环境变量 `SERVER_PORT` 覆盖)。 - 接口文档访问地址: - Knife4j:`http://localhost:19000/doc.html` - Swagger UI:`http://localhost:19000/swagger-ui.html` > ⚠️ 安全约定:`application-dev.yml` **不再包含明文**口令/AK/SK/API Key,全部改为**环境变量注入**(见文件头注释)。请勿往任何 yml 写真实凭据;本地开发复制 `.env.example` 为 `.env` 或用 `-D` 启动参数注入。生产使用 `application-prod.yml`(`--spring.profiles.active=prod`),同样仅读环境变量。 ## 五、本地运行 ```bash # 1. 准备中间件(MySQL / Redis / RabbitMQ 等),并修改 application-dev.yml 中的连接信息 # 2. 编译 mvn clean compile # 3. 运行 mvn spring-boot:run # 或打包后运行 mvn clean package -DskipTests java -jar target/home_server_system-0.0.1-SNAPSHOT.jar ``` 启动成功后访问 `http://localhost:19000/doc.html` 查看接口文档。 ## 六、WebSocket 实时通信 - **连接路径**:`/ws/{userId}`,通过 query 参数 `token` 握手鉴权(`Bearer xxx`,前端需 `encodeURIComponent` 编码)。 - **握手鉴权**:`interceptor/TokenEndpointConfigurator` 中校验 JWT(仅 access token 有效),失败时推送 `{type:"error"}` 并关闭连接。 - **实时推送**:聊天消息、系统通知/公告/订单通知经 `WebSocketPushService`(`@Async`)实时推送到在线用户。 - **推送协议**:JSON 含 `type` 字段:`chat`(新聊天)、`notice`(新通知)、`error`(鉴权失败)。 ## 七、前后端联调 - **前端工程**:`home-service-vue/home-service-user`(用户端,Vue3 + Vite + Vant)。 - **环境**:后端 `http://192.168.1.102:19000`,所有接口带 `/api/v1` 前缀(后端 `context-path` 统一生效)。前端 `config.js` 的 `baseURL`/`wsURL` 已统一拼接 `/api/v1`,直接访问后端 IP(Vite **未配置代理**),无需额外代理前缀。 - **登录链路**:`/api/v1/auth/userLogin` 获取 token → 携带 token 访问受保护接口 → 过期后 `/api/v1/access/refreshToken` 刷新。 - **聊天联调**:登录成功后前端 `connectWebSocket(userId)` 建立长连接;聊天页 `getMessageData(cb)` 注册回调实时刷新会话。 - **测试账号**:`test01` / `test02`(服务人员"小金"),密码均 `123456`。 ## 八、模块简介 - **user**:用户端接口(注册登录、订单、评价等) - **server**:服务人员端接口(接单、服务管理等) - **admin**:管理员后台接口(用户/订单/数据管理) - **common**:公共/通用接口(验证码、文件上传、天气等) - **ai**:AI 智能助手(基于 Spring AI,支持工具调用,如天气查询、时间查询) ## 九、安全与稳定性治理(已落地) > 以下为项目已实施的关键加固点,改动相关模块前请先知晓。 - **接口白名单最小权限**:`SecurityConfig` 仅放行确有 Controller/文档用途的路径;已移除 `/druid/**`、`/flowable/**`、`/common/download**`、`/api/contract|project|document|purchase|common/**` 等无对应实现/无依赖的预留式匿名放行,避免匿名访问后门与任意文件下载隐患。 - **AI 接口限流防刷**:`AiChatServiceImpl` 接入 `AiRateLimiter`,用户维度固定窗口限流(Redis,60s/10 次)+ 全局并发信号量(Semaphore,5 个在飞),防 token 账单被刷爆;超限返回友好文案。 - **邮件 MQ 可靠投递**:正常队列 + 死信队列 + 手动 ACK + 重试上限(`email.mq.max-retry`,默认 3);队列不再设 TTL(避免验证码有效期内被丢弃);`ConfirmCallback`/`ReturnsCallback` 将失败标记写入 Redis(`email:send:failed:count` / `email:send:failed:{messageId}`)做失败监控,解决"提交成功但投递失败"静默丢信。注意 `EmailUtil.sendHtmlMail` 不得加 `@Async`(消费者线程已是异步,否则返回值被代理为 Future 导致 ClassCastException)。 - **支付安全与事务**:`payBill` 账单查询强制按当前用户过滤(`Bill.userId`)并校验 Redis 预约订单归属,禁止使用他人订单号替他人支付;钱包转账与账单状态更新在同一事务(`@Transactional`)原子提交;账单状态使用条件更新(`WHERE status=未支付`),并发/重复支付时第二个请求被拒绝,避免重复扣款。 - **排期资源归属**:服务排期的创建强制归属当前登录服务人员(忽略请求体 `userId`),修改/上下架/删除均带 `userId` 条件过滤,防止越权操作他人排期。 - **并发安全(主键回填)**:新增排期/服务时间后直接使用 `insert` 自动回填的主键,不再按 `createTime` 回查,避免并发创建时抛 `TooManyResultsException`。 - **异步线程池**:`AsyncConfig` 提供 `@EnableAsync` + 业务线程池(核心 4 / 最大 16 / 队列 200,`CallerRunsPolicy` 兜底),确保 `@Async`(WebSocket 推送、邮件发送等)真正异步执行且不静默丢任务。 - **入参与异常规范**:全局异常统一返回,避免堆栈外泄;Controller 入参补齐 `@Valid` 校验。 - **API 版本前缀**:前后端统一 `/api/v1`(后端 `context-path`),前端 `config.js` 已拼接。 - **敏感信息**:所有凭据经环境变量注入,yml 不含明文。 ## 十、参与贡献 1. Fork 本仓库 2. 新建 `Feat_xxx` 分支 3. 提交代码 4. 新建 Pull Request 更多协作说明见 [AGENTS.md](./AGENTS.md)。