# notify-server **Repository Path**: chmod/notify-server ## Basic Information - **Project Name**: notify-server - **Description**: 华润消息推送服务Server端 ## 项目概述 这是一个基于 Spring Boot 的 Java 应用程序,作为推送通知服务,支持多种移动设备制造商(Oppo、Vivo、小米和 Harmony/Huawei)。它提供 API 来向用户的设备发送推送通知,并管理这些通知的生命周期,包括重试和过期处理。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-04 - **Last Updated**: 2026-03-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 华润消息推送服务Server端 ## 项目概述 这是一个基于 Spring Boot 的 Java 应用程序,作为推送通知服务,支持多种移动设备制造商(Oppo、Vivo、小米和 Harmony/Huawei)。它提供 API 来向用户的设备发送推送通知,并管理这些通知的生命周期,包括重试和过期处理。 ## 架构和结构 ### 核心组件 1. **主应用程序入口点**:`NotifyServerApplication.java` 2. **配置文件**:`application.yml` 包含数据库和推送服务配置 3. **包结构**: - `controller/`:REST API 控制器,暴露推送通知端点 - `service/`:业务逻辑服务,实现推送通知功能 - `provider/`:供应商特定的推送服务提供商实现(Oppo、Vivo、小米、Harmony) - `dao/mapper/`:数据访问对象和 MyBatis XML 映射文件 - `entity/`:数据库实体,表示表结构 - `vo/`:API 请求和响应的值对象 - `config/`:配置类 - `constant/`:枚举和常量 ### 关键设计模式 - **工厂模式**:`PushServiceProviderFactory` 用于实例化特定供应商的服务实现 - **抽象基类**:`AbstractPushServiceProvider` 为所有供应商提供通用功能 - **计划任务**:失败通知的重试机制,使用阶梯递增的方式计算重试时间 - **分布式锁定**:在多节点环境中防止重复处理的机制 ### 技术栈 - Spring Boot 2.7.18 - MyBatis Plus 数据库操作 - MySQL 配合 Druid 连接池 - Hutool 工具库 - Knife4j/Swagger/OpenAPI API 文档 - Jackson JSON 处理 ## 构建和开发命令 ### 数据库账号及密码配置 本项目采用了Jasypt对敏感数据脱密的加密(如数据库账号密码),需要先配置密钥及加密原始账号和密码,然后配置到数据源上完成脱敏配置。 1. 加密密钥在`application-${profile}.yml`中配置(`jasypt.pwd`)。 2. 复制密钥到 `com.hr.service.notify.server.util.JasyptEncryptorUtil` 中完成对数据库账号及密码的加密。 3. 将加密后的数据库账号及密码密文配置到 `application-${profile}.yml` 中。 ### 构建应用程序 ```bash mvn clean install ``` ### 本地运行应用程序 ```bash # 手动启动(需要设置Jasypt加密密钥) java -jar ./target/notify-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev ``` ### 测试环境发布命令 ``` nohup java -jar notify-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=test & ``` ### 生产环境运行应用程序 ```bash # 手动启动(需要设置Jasypt加密密钥) java -jar ./target/notify-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=pro ``` ### 运行测试 ```bash mvn test ``` ### 运行单个测试 ```bash mvn test -Dtest=ClassName#methodName ``` ## 主要功能 1. **多供应商支持**:处理 Oppo、Vivo、小米和 Harmony 设备的推送通知 2. **重试机制**:失败的通知使用阶梯递增的方式计算重试时间重试(5分钟、1小时、4小时、12小时、1天) 3. **消息生命周期管理**:跟踪消息在 WAIT_SEND、FAIL、ERROR 和 EXPIRED 状态间的转换 4. **设备管理**:维护用户设备的注册信息,包括令牌和制造商信息 5. **分布式处理**:实现锁定机制,防止多节点环境中的重复处理 ## 重要端点 - `/device/registration` - 用户设备注册接口 - `/device/unRegistration` - 用户设备注销接口 - `/push/send` - 发送推送通知 - `/message/ack/page` - 查询消息确认记录 - `/message/log/page` - 获取消息日志 ### 业务端应用接入 #### API认证 业务端接入消息推送功能,主要接入 `/push/send` 接口,而Push接口需要API认证,详细对接指南参考 `sdk/华润推送消息服务 Push API 对接指南.md`。 ### 移动端应用接入 移动端应用负责接入设备注册与注销功能,主要接入 `/device/registration` 和 `/device/unRegistration` 接口,详细对接说明参考 `Apifox项目`。 ## 配置 供应商特定的 API 端点在 `application.yml` 中的 `push.provider` 部分进行配置。每个供应商都有其自己的认证和消息发送 API。 供应商特定的认证密钥等认证信息在 `config/{provider}_private_json` 部分进行配置。 ### 各个厂商的密钥配置说明 #### 1. 华为/鸿蒙 1.1 在华为 Developer [API服务](https://developer.huawei.com/consumer/cn/console/api/credentials/dev388421841221549139/0) 的凭证页面中获取到密钥JSON信息。 类似如下格式: ```json { "project_id": "[projectId]", "key_id": "[key_id]", "private_key": "-----BEGIN PRIVATE KEY-----[private_key]\n-----END PRIVATE KEY-----\n", "sub_account": "[subAccount]", "auth_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize", "token_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/token", "auth_provider_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/certs", "client_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/x509?client_id=" } ``` 1.2 在华为应用中心获取应用ID(appId) 1.3 然后将密钥与应用ID一起配置到 `config/ohos_private_json` 文件中, 类似如下格式: ```json { "default": "[default_app_id]", "configs": [ { "appId": "[appId]", "project_id": "[projectId]", "key_id": "[key_id]", "private_key": "-----BEGIN PRIVATE KEY-----[private_key]\n-----END PRIVATE KEY-----\n", "sub_account": "[subAccount]", "auth_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize", "token_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/token", "auth_provider_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/certs", "client_cert_uri": "https://oauth-login.cloud.huawei.com/oauth2/v3/x509?client_id=" } ] } ``` #### 2. Oppo 2.1 在Oppo 管理中心 -> [应用管理(全部)](https://open.oppomobile.com/new/mcom/app/list/all) -> xx应用页面中获取到密钥(appID/appKey/appSecret/appserversecret)信息。 类似如下格式: ```json { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]", "master_secret": "[appserversecret]" } ``` 2.2 然后将密钥与应用ID一起配置到 `config/oppo_private_json` 文件中, 类似如下格式: ```json { "default": "[default_app_id]", "configs": [ { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]", "master_secret": "[appserversecret]" } ] } ``` #### 3. Vivo 3.1 在Vivo 管理中心 -> 推送服务 -> [应用列表](https://vpush.vivo.com.cn/#/homePage/appDetail) -> xx应用信息页面中获取到密钥(appID/appKey/appSecret)信息。 类似如下格式: ```json { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]" } ``` 3.2 然后将密钥与应用ID一起配置到 `config/vivo_private_json` 文件中, 类似如下格式: ```json { "default": "[default_app_id]", "configs": [ { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]" } ] } ``` #### 4. Xiaomi 4.1 在Xiaomi 管理中心 -> [应用列表](https://dev.mi.com/xiaomihyperos/console/app-manage/mobile) -> xx应用信息页面中获取到密钥(appID/appKey/appSecret/应用包名)信息。 类似如下格式: ```json { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]", "package_name": "[package_name]" } ``` 4.2 然后将密钥与应用ID一起配置到 `config/vivo_private_json` 文件中, 类似如下格式: ```json { "default": "[default_app_id]", "configs": [ { "app_id": "[appId]", "app_key": "[appKey]", "app_secret": "[appSecret]", "package_name": "[package_name]" } ] } ``` ## 开发注意事项 1. **重试机制**:失败重试时间使用阶梯递增的方式计算时间(5分钟、1小时、4小时、12小时、1天) 2. **分布式锁定**:使用 `PushMessageAckLockService` 实现分布式锁定,防止多节点环境中的重复处理 3. **定时任务**:`ScheduledTasksConfig` 中的 `retryPushMessageScheduleTask` 负责重试失败的消息推送 4. **异步处理**:使用 `@EnableAsync` 和自定义线程池处理异步任务 5. **事务管理**:启用了事务管理 `@EnableTransactionManagement` 6. **缓存**:启用了缓存 `@EnableCaching` 7. **API 文档**:使用 Knife4j/Swagger 生成 API 文档,访问路径:`http://localhost:18000/notify-server/doc.html`