diff --git a/opush-server-sdk-1.1.0.jar b/opush-server-sdk-1.1.0.jar
new file mode 100644
index 0000000..81ac628
Binary files /dev/null and b/opush-server-sdk-1.1.0.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..120c905
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,85 @@
+
+
+ 4.0.0
+
+ com.oppo.push
+ oppo-push-server
+ 1.0.0
+ jar
+
+ OPPO Push Server
+ OPPO推送服务测试后台
+
+
+ 1.8
+ 1.8
+ 1.8
+ UTF-8
+ 2.7.0
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot.version}
+
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ ${spring-boot.version}
+ true
+
+
+
+
+ com.oppo.push
+ opush-server-sdk
+ 1.1.0
+ system
+ ${project.basedir}/opush-server-sdk-1.1.0.jar
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.83
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ true
+
+
+
+
+
+
diff --git a/src/main/java/com/oppo/push/OppoPushApplication.java b/src/main/java/com/oppo/push/OppoPushApplication.java
new file mode 100644
index 0000000..d57be47
--- /dev/null
+++ b/src/main/java/com/oppo/push/OppoPushApplication.java
@@ -0,0 +1,21 @@
+package com.oppo.push;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * OPPO推送服务主应用
+ */
+@SpringBootApplication
+public class OppoPushApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OppoPushApplication.class, args);
+ System.out.println("========================================");
+ System.out.println("OPPO推送服务已启动");
+ System.out.println("API地址: http://localhost:8080/api/push");
+ System.out.println("健康检查: http://localhost:8080/api/push/health");
+ System.out.println("========================================");
+ }
+}
+
diff --git a/src/main/java/com/oppo/push/config/OppoPushConfig.java b/src/main/java/com/oppo/push/config/OppoPushConfig.java
new file mode 100644
index 0000000..e319cd8
--- /dev/null
+++ b/src/main/java/com/oppo/push/config/OppoPushConfig.java
@@ -0,0 +1,44 @@
+package com.oppo.push.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * OPPO推送服务配置类
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "oppo.push")
+public class OppoPushConfig {
+ /**
+ * 应用Key
+ */
+ private String appKey;
+
+ /**
+ * 应用密钥
+ */
+ private String appSecret;
+
+ /**
+ * 主密钥
+ */
+ private String masterSecret;
+
+ /**
+ * API地址
+ */
+ private String apiUrl = "https://api.push.oppo.com";
+
+ /**
+ * 通讯与服务(原私信)频道ID
+ */
+ private String channelIdIm = "previte_message";
+
+ /**
+ * 通讯与服务(原私信)频道名称
+ */
+ private String channelNameIm = "消息推送";
+}
+
diff --git a/src/main/java/com/oppo/push/controller/PushController.java b/src/main/java/com/oppo/push/controller/PushController.java
new file mode 100644
index 0000000..607be3b
--- /dev/null
+++ b/src/main/java/com/oppo/push/controller/PushController.java
@@ -0,0 +1,75 @@
+package com.oppo.push.controller;
+
+import com.oppo.push.service.OppoPushService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 推送测试控制器
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/push")
+public class PushController {
+
+ @Autowired
+ private OppoPushService pushService;
+
+ /**
+ * 测试发送通讯与服务(原私信)类消息
+ *
+ * @param request 请求参数
+ * @return 推送结果
+ */
+ @PostMapping("/send")
+ public Map sendMessage(@RequestBody Map request) {
+ String targetValue = request.get("targetValue"); // registration_id或alias
+ String title = request.get("title");
+ String content = request.get("content");
+ String messageType = request.getOrDefault("messageType", "1"); // 1:通知栏消息, 2:透传消息
+
+ if (targetValue == null || title == null || content == null) {
+ Map error = new HashMap<>();
+ error.put("success", false);
+ error.put("message", "参数不完整:需要targetValue、title、content");
+ return error;
+ }
+
+ return pushService.sendMessage(targetValue, title, content, Integer.parseInt(messageType));
+ }
+
+ /**
+ * 获取Access Token(用于测试)
+ */
+ @GetMapping("/token")
+ public Map getToken() {
+ try {
+ String token = pushService.getAccessToken();
+ Map result = new HashMap<>();
+ result.put("success", true);
+ result.put("token", token);
+ return result;
+ } catch (Exception e) {
+ Map result = new HashMap<>();
+ result.put("success", false);
+ result.put("message", e.getMessage());
+ return result;
+ }
+ }
+
+ /**
+ * 健康检查
+ */
+ @GetMapping("/health")
+ public Map health() {
+ Map result = new HashMap<>();
+ result.put("status", "ok");
+ result.put("service", "OPPO Push Server");
+ return result;
+ }
+}
+
diff --git a/src/main/java/com/oppo/push/service/OppoPushService.java b/src/main/java/com/oppo/push/service/OppoPushService.java
new file mode 100644
index 0000000..1084ff2
--- /dev/null
+++ b/src/main/java/com/oppo/push/service/OppoPushService.java
@@ -0,0 +1,212 @@
+package com.oppo.push.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.oppo.push.config.OppoPushConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * OPPO推送服务类
+ */
+@Slf4j
+@Service
+public class OppoPushService {
+
+ @Autowired
+ private OppoPushConfig config;
+
+ private String accessToken;
+ private long tokenExpireTime;
+
+ /**
+ * 获取Access Token
+ */
+ public String getAccessToken() {
+ // 如果token未过期,直接返回
+ if (accessToken != null && System.currentTimeMillis() < tokenExpireTime) {
+ return accessToken;
+ }
+
+ try {
+ String url = config.getApiUrl() + "/v1/auth";
+
+ long timestamp = System.currentTimeMillis();
+ Map params = new HashMap<>();
+ params.put("app_key", config.getAppKey());
+ params.put("timestamp", timestamp);
+ params.put("sign", generateSign(config.getAppKey(), timestamp, config.getMasterSecret()));
+
+ String response = sendPostRequest(url, JSON.toJSONString(params));
+ JSONObject jsonResponse = JSON.parseObject(response);
+
+ if (jsonResponse.getInteger("code") == 0) {
+ accessToken = jsonResponse.getString("data");
+ // token有效期通常为24小时,这里设置为23小时,提前刷新
+ tokenExpireTime = System.currentTimeMillis() + 23 * 60 * 60 * 1000;
+ log.info("获取Access Token成功: {}", accessToken);
+ return accessToken;
+ } else {
+ log.error("获取Access Token失败: {}", response);
+ throw new RuntimeException("获取Access Token失败: " + jsonResponse.getString("message"));
+ }
+ } catch (Exception e) {
+ log.error("获取Access Token异常", e);
+ throw new RuntimeException("获取Access Token异常", e);
+ }
+ }
+
+ /**
+ * 发送通讯与服务(原私信)类消息
+ *
+ * @param targetValue 目标值(可以是token、registration_id等)
+ * @param title 消息标题
+ * @param content 消息内容
+ * @param messageType 消息类型(1:通知栏消息, 2:透传消息)
+ * @return 推送结果
+ */
+ public Map sendMessage(String targetValue, String title, String content, int messageType) {
+ try {
+ String token = getAccessToken();
+ String url = config.getApiUrl() + "/v1/message/notification/single";
+
+ // 构建消息体
+ Map message = new HashMap<>();
+ message.put("target_type", 1); // 1:registration_id, 2:alias, 3:tag
+ message.put("target_value", targetValue);
+
+ // 通知栏消息参数
+ Map notification = new HashMap<>();
+ notification.put("title", title);
+ notification.put("content", content);
+ notification.put("click_action_type", 1); // 1:打开应用首页, 2:打开应用内页, 3:打开网页, 4:打开应用内页(Intent)
+ notification.put("click_action_type_value", "");
+
+ // 通讯与服务(原私信)类消息特殊参数
+ // 根据OPPO官方文档,通讯与服务类消息需要设置channel_id和channel_name
+ notification.put("channel_id", config.getChannelIdIm()); // 通讯与服务频道ID: previte_message
+ notification.put("channel_name", config.getChannelNameIm()); // 频道名称: 消息推送
+
+ // extra参数(可选,用于传递额外信息)
+ Map extra = new HashMap<>();
+ extra.put("message_type", "chat"); // 标识为私信类消息
+ notification.put("extra", extra);
+
+ message.put("notification", notification);
+
+ // 请求头
+ Map headers = new HashMap<>();
+ headers.put("Content-Type", "application/json;charset=UTF-8");
+ headers.put("auth_token", token);
+
+ String response = sendPostRequestWithHeaders(url, JSON.toJSONString(message), headers);
+ JSONObject jsonResponse = JSON.parseObject(response);
+
+ Map result = new HashMap<>();
+ result.put("success", jsonResponse.getInteger("code") == 0);
+ result.put("code", jsonResponse.getInteger("code"));
+ result.put("message", jsonResponse.getString("message"));
+ result.put("data", jsonResponse.get("data"));
+
+ log.info("发送消息结果: {}", result);
+ return result;
+ } catch (Exception e) {
+ log.error("发送消息异常", e);
+ Map result = new HashMap<>();
+ result.put("success", false);
+ result.put("message", "发送消息异常: " + e.getMessage());
+ return result;
+ }
+ }
+
+ /**
+ * 发送单点推送(使用SDK方式)
+ */
+ public Map sendSinglePush(String registrationId, String title, String content) {
+ try {
+ // 这里使用OPPO SDK的方式发送
+ // 注意:需要根据实际的SDK API进行调整
+ return sendMessage(registrationId, title, content, 1);
+ } catch (Exception e) {
+ log.error("发送单点推送异常", e);
+ Map result = new HashMap<>();
+ result.put("success", false);
+ result.put("message", "发送单点推送异常: " + e.getMessage());
+ return result;
+ }
+ }
+
+ /**
+ * 生成签名
+ * 签名算法:MD5(app_key + timestamp + master_secret)
+ */
+ private String generateSign(String appKey, long timestamp, String masterSecret) {
+ try {
+ String signStr = appKey + timestamp + masterSecret;
+ java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
+ byte[] bytes = md.digest(signStr.getBytes(StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ throw new RuntimeException("生成签名失败", e);
+ }
+ }
+
+ /**
+ * 发送POST请求
+ */
+ private String sendPostRequest(String url, String jsonBody) throws Exception {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
+ httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));
+
+ try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+ HttpEntity entity = response.getEntity();
+ return EntityUtils.toString(entity, StandardCharsets.UTF_8);
+ } finally {
+ httpClient.close();
+ }
+ }
+
+ /**
+ * 发送带自定义请求头的POST请求
+ */
+ private String sendPostRequestWithHeaders(String url, String jsonBody, Map headers) throws Exception {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost(url);
+
+ // 设置默认请求头
+ httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
+
+ // 设置自定义请求头
+ if (headers != null) {
+ headers.forEach(httpPost::setHeader);
+ }
+
+ httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));
+
+ try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+ HttpEntity entity = response.getEntity();
+ return EntityUtils.toString(entity, StandardCharsets.UTF_8);
+ } finally {
+ httpClient.close();
+ }
+ }
+}
+
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..ccc2da8
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,16 @@
+# OPPO推送服务配置
+# 请在OPPO开放平台获取以下信息:https://open.oppomobile.com
+oppo.push.appKey=bb0819c889ae40cd8bde5a8ad4e670fe
+oppo.push.appSecret=9b5a0e6d560e406dbb70fbb4e0e38098
+oppo.push.masterSecret=9b5a0e6d560e406dbb70fbb4e0e38098
+
+# 通讯与服务(原私信)频道配置
+oppo.push.channel.id.im=previte_message
+oppo.push.channel.name.im=消息推送
+
+# 推送服务地址
+oppo.push.api.url=https://api.push.oppo.com
+
+# 服务器端口
+server.port=8080
+
diff --git a/target/classes/META-INF/spring-configuration-metadata.json b/target/classes/META-INF/spring-configuration-metadata.json
new file mode 100644
index 0000000..a1c24db
--- /dev/null
+++ b/target/classes/META-INF/spring-configuration-metadata.json
@@ -0,0 +1,48 @@
+{
+ "groups": [
+ {
+ "name": "oppo.push",
+ "type": "com.oppo.push.config.OppoPushConfig",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ }
+ ],
+ "properties": [
+ {
+ "name": "oppo.push.api-url",
+ "type": "java.lang.String",
+ "description": "API地址",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ },
+ {
+ "name": "oppo.push.app-key",
+ "type": "java.lang.String",
+ "description": "应用Key",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ },
+ {
+ "name": "oppo.push.app-secret",
+ "type": "java.lang.String",
+ "description": "应用密钥",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ },
+ {
+ "name": "oppo.push.channel-id-im",
+ "type": "java.lang.String",
+ "description": "通讯与服务(原私信)频道ID",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ },
+ {
+ "name": "oppo.push.channel-name-im",
+ "type": "java.lang.String",
+ "description": "通讯与服务(原私信)频道名称",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ },
+ {
+ "name": "oppo.push.master-secret",
+ "type": "java.lang.String",
+ "description": "主密钥",
+ "sourceType": "com.oppo.push.config.OppoPushConfig"
+ }
+ ],
+ "hints": []
+}
\ No newline at end of file
diff --git a/target/classes/application.properties b/target/classes/application.properties
new file mode 100644
index 0000000..ccc2da8
--- /dev/null
+++ b/target/classes/application.properties
@@ -0,0 +1,16 @@
+# OPPO推送服务配置
+# 请在OPPO开放平台获取以下信息:https://open.oppomobile.com
+oppo.push.appKey=bb0819c889ae40cd8bde5a8ad4e670fe
+oppo.push.appSecret=9b5a0e6d560e406dbb70fbb4e0e38098
+oppo.push.masterSecret=9b5a0e6d560e406dbb70fbb4e0e38098
+
+# 通讯与服务(原私信)频道配置
+oppo.push.channel.id.im=previte_message
+oppo.push.channel.name.im=消息推送
+
+# 推送服务地址
+oppo.push.api.url=https://api.push.oppo.com
+
+# 服务器端口
+server.port=8080
+
diff --git a/target/classes/com/oppo/push/OppoPushApplication.class b/target/classes/com/oppo/push/OppoPushApplication.class
new file mode 100644
index 0000000..63e6eff
Binary files /dev/null and b/target/classes/com/oppo/push/OppoPushApplication.class differ
diff --git a/target/classes/com/oppo/push/config/OppoPushConfig.class b/target/classes/com/oppo/push/config/OppoPushConfig.class
new file mode 100644
index 0000000..513f608
Binary files /dev/null and b/target/classes/com/oppo/push/config/OppoPushConfig.class differ
diff --git a/target/classes/com/oppo/push/controller/PushController.class b/target/classes/com/oppo/push/controller/PushController.class
new file mode 100644
index 0000000..710aa03
Binary files /dev/null and b/target/classes/com/oppo/push/controller/PushController.class differ
diff --git a/target/classes/com/oppo/push/service/OppoPushService.class b/target/classes/com/oppo/push/service/OppoPushService.class
new file mode 100644
index 0000000..71b37cc
Binary files /dev/null and b/target/classes/com/oppo/push/service/OppoPushService.class differ
diff --git a/test-request.json b/test-request.json
new file mode 100644
index 0000000..12a2419
--- /dev/null
+++ b/test-request.json
@@ -0,0 +1,7 @@
+{
+ "targetValue": "your_registration_id_here",
+ "title": "测试私信消息",
+ "content": "这是一条通讯与服务(原私信)类消息的测试内容",
+ "messageType": "1"
+}
+
diff --git a/调测使用说明.txt b/调测使用说明.txt
new file mode 100644
index 0000000..f638da2
--- /dev/null
+++ b/调测使用说明.txt
@@ -0,0 +1,388 @@
+================================================================================
+ OPPO推送服务 - 调测使用说明
+================================================================================
+
+一、环境准备
+================================================================================
+
+1. 系统要求
+ - JDK 1.8 或更高版本
+ - Maven 3.6 或更高版本
+ - Windows/Linux/Mac 操作系统
+
+2. 验证环境
+ - 打开命令行,执行:java -version
+ - 打开命令行,执行:mvn -version
+ - 确保两个命令都能正常显示版本信息
+
+3. 项目文件检查
+ 确保以下文件存在:
+ - pom.xml(Maven配置文件)
+ - opush-server-sdk-1.1.0.jar(OPPO推送SDK)
+ - src/main/resources/application.properties(配置文件)
+ - src/main/java/com/oppo/push/(源代码目录)
+
+
+二、配置说明
+================================================================================
+
+1. 配置文件位置
+ src/main/resources/application.properties
+
+2. 已配置的参数
+ - AppKey: bb0819c889ae40cd8bde5a8ad4e670fe
+ - AppSecret: 9b5a0e6d560e406dbb70fbb4e0e38098
+ - MasterSecret: 9b5a0e6d560e406dbb70fbb4e0e38098(默认与AppSecret相同)
+ - 频道ID: previte_message
+ - 频道名称: 消息推送
+ - 服务端口: 8080
+
+3. 配置修改(如需要)
+ 如果您的MasterSecret与AppSecret不同,请修改配置文件中的:
+ oppo.push.masterSecret=您的实际MasterSecret值
+
+
+三、启动服务
+================================================================================
+
+方式一:使用Maven直接运行(推荐)
+----------------------------------------
+1. 打开命令行(CMD或PowerShell)
+2. 进入项目目录:cd d:\oppo_push_server
+3. 执行启动命令:mvn spring-boot:run
+4. 等待启动完成,看到以下信息表示启动成功:
+ ========================================
+ OPPO推送服务已启动
+ API地址: http://localhost:8080/api/push
+ 健康检查: http://localhost:8080/api/push/health
+ ========================================
+
+方式二:打包后运行
+----------------------------------------
+1. 打包项目:mvn clean package
+2. 运行jar包:java -jar target/oppo-push-server-1.0.0.jar
+3. 启动成功后同上
+
+
+四、API接口说明
+================================================================================
+
+1. 健康检查接口
+ - 请求方式:GET
+ - 请求地址:http://localhost:8080/api/push/health
+ - 功能说明:检查服务是否正常运行
+ - 返回示例:
+ {
+ "status": "ok",
+ "service": "OPPO Push Server"
+ }
+
+2. 获取Access Token接口
+ - 请求方式:GET
+ - 请求地址:http://localhost:8080/api/push/token
+ - 功能说明:获取OPPO推送服务的访问令牌
+ - 返回示例(成功):
+ {
+ "success": true,
+ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+ }
+ - 返回示例(失败):
+ {
+ "success": false,
+ "message": "获取Access Token失败: 错误信息"
+ }
+
+3. 发送通讯与服务(原私信)类消息接口
+ - 请求方式:POST
+ - 请求地址:http://localhost:8080/api/push/send
+ - 请求头:Content-Type: application/json
+ - 请求体(JSON格式):
+ {
+ "targetValue": "设备的registration_id或alias",
+ "title": "消息标题",
+ "content": "消息内容",
+ "messageType": "1"
+ }
+ - 参数说明:
+ * targetValue(必填):目标设备的标识
+ - 可以是registration_id(设备注册ID)
+ - 可以是alias(别名)
+ - 可以是tag(标签)
+ * title(必填):消息标题
+ * content(必填):消息内容
+ * messageType(可选):消息类型
+ - "1":通知栏消息(默认)
+ - "2":透传消息
+ - 返回示例(成功):
+ {
+ "success": true,
+ "code": 0,
+ "message": "success",
+ "data": {
+ "messageId": "xxx",
+ "taskId": "xxx"
+ }
+ }
+ - 返回示例(失败):
+ {
+ "success": false,
+ "code": 1001,
+ "message": "错误信息",
+ "data": null
+ }
+
+
+五、测试步骤
+================================================================================
+
+步骤1:启动服务
+----------------------------------------
+执行:mvn spring-boot:run
+等待服务启动完成
+
+步骤2:健康检查
+----------------------------------------
+打开浏览器访问:http://localhost:8080/api/push/health
+或使用curl命令:
+ curl http://localhost:8080/api/push/health
+
+预期结果:返回 {"status":"ok","service":"OPPO Push Server"}
+
+步骤3:获取Token(测试认证)
+----------------------------------------
+使用curl命令:
+ curl http://localhost:8080/api/push/token
+
+或使用浏览器访问:http://localhost:8080/api/push/token
+
+预期结果:返回包含token的JSON,success为true
+
+步骤4:准备测试数据
+----------------------------------------
+1. 获取目标设备的registration_id
+ - 在您的移动应用中集成OPPO推送SDK
+ - 应用启动后,SDK会返回registration_id
+ - 记录下这个registration_id用于测试
+
+2. 修改test-request.json文件
+ 将文件中的 "your_registration_id_here" 替换为实际的registration_id
+
+步骤5:发送测试消息
+----------------------------------------
+使用curl命令(Windows PowerShell):
+ curl -X POST http://localhost:8080/api/push/send `
+ -H "Content-Type: application/json" `
+ -d @test-request.json
+
+使用curl命令(Linux/Mac):
+ curl -X POST http://localhost:8080/api/push/send \
+ -H "Content-Type: application/json" \
+ -d @test-request.json
+
+或使用Postman:
+ 1. 创建POST请求
+ 2. URL: http://localhost:8080/api/push/send
+ 3. Headers: Content-Type = application/json
+ 4. Body选择raw,格式选择JSON
+ 5. 输入以下内容:
+ {
+ "targetValue": "您的registration_id",
+ "title": "测试私信消息",
+ "content": "这是一条通讯与服务(原私信)类消息的测试内容",
+ "messageType": "1"
+ }
+ 6. 点击Send发送
+
+预期结果:
+ - 返回success为true
+ - 移动设备收到推送通知
+ - 通知显示在"消息推送"频道中
+
+
+六、使用Postman测试(推荐)
+================================================================================
+
+1. 导入请求集合
+ - 打开Postman
+ - 创建新的Collection:OPPO推送测试
+ - 添加以下三个请求:
+
+2. 健康检查请求
+ - 方法:GET
+ - URL:http://localhost:8080/api/push/health
+ - 点击Send,应该返回成功状态
+
+3. 获取Token请求
+ - 方法:GET
+ - URL:http://localhost:8080/api/push/token
+ - 点击Send,应该返回token
+
+4. 发送消息请求
+ - 方法:POST
+ - URL:http://localhost:8080/api/push/send
+ - Headers:
+ Key: Content-Type
+ Value: application/json
+ - Body(选择raw,格式JSON):
+ {
+ "targetValue": "替换为实际的registration_id",
+ "title": "测试标题",
+ "content": "测试内容",
+ "messageType": "1"
+ }
+ - 点击Send发送
+
+
+七、常见问题排查
+================================================================================
+
+问题1:服务启动失败
+----------------------------------------
+可能原因:
+ - 端口8080被占用
+ - JDK版本不兼容
+ - Maven依赖下载失败
+
+解决方法:
+ 1. 检查端口占用:netstat -ano | findstr :8080
+ 2. 修改端口:在application.properties中修改server.port=8081
+ 3. 检查JDK版本:java -version(需要1.8+)
+ 4. 清理Maven缓存:mvn clean
+
+问题2:获取Token失败
+----------------------------------------
+可能原因:
+ - AppKey或MasterSecret配置错误
+ - 网络连接问题
+ - OPPO服务端异常
+
+解决方法:
+ 1. 检查配置文件中的AppKey和MasterSecret是否正确
+ 2. 检查网络连接是否正常
+ 3. 查看控制台日志,确认具体错误信息
+ 4. 确认在OPPO开放平台已开通推送服务
+
+问题3:发送消息失败
+----------------------------------------
+可能原因:
+ - Token过期或无效
+ - targetValue(registration_id)无效
+ - 消息格式错误
+ - 设备未在线
+
+解决方法:
+ 1. 重新获取Token:访问 /api/push/token 接口
+ 2. 确认registration_id是否正确
+ 3. 检查请求体JSON格式是否正确
+ 4. 确认目标设备已连接网络且应用在运行
+ 5. 查看控制台日志获取详细错误信息
+
+问题4:设备收不到推送
+----------------------------------------
+可能原因:
+ - 设备未正确集成OPPO推送SDK
+ - 应用未获得通知权限
+ - 设备网络问题
+ - 频道配置不正确
+
+解决方法:
+ 1. 确认移动应用已正确集成OPPO推送SDK
+ 2. 检查应用的通知权限是否开启
+ 3. 确认设备网络连接正常
+ 4. 检查频道ID配置是否为"previte_message"
+ 5. 在OPPO开放平台查看推送统计,确认消息是否已发送
+
+问题5:编译错误
+----------------------------------------
+可能原因:
+ - 缺少依赖
+ - 代码语法错误
+
+解决方法:
+ 1. 执行:mvn clean install
+ 2. 检查IDE是否显示错误
+ 3. 确认opush-server-sdk-1.1.0.jar文件存在
+
+
+八、日志查看
+================================================================================
+
+1. 控制台日志
+ 服务启动后,所有日志会输出到控制台,包括:
+ - 服务启动信息
+ - Token获取日志
+ - 消息发送日志
+ - 错误信息
+
+2. 关键日志信息
+ - "获取Access Token成功":表示认证成功
+ - "发送消息结果":显示消息发送的详细结果
+ - "获取Access Token失败":表示认证失败,需要检查配置
+ - "发送消息异常":表示发送失败,查看具体错误信息
+
+
+九、调试技巧
+================================================================================
+
+1. 使用健康检查接口确认服务正常运行
+
+2. 先测试获取Token,确认认证配置正确
+
+3. 使用Postman等工具可以更方便地测试和查看响应
+
+4. 查看控制台日志,了解详细的执行过程
+
+5. 如果发送失败,先检查:
+ - Token是否有效
+ - registration_id是否正确
+ - 请求格式是否正确
+
+6. 建议测试流程:
+ 健康检查 → 获取Token → 发送消息
+
+
+十、注意事项
+================================================================================
+
+1. Token会自动缓存,有效期约24小时,无需频繁获取
+
+2. 确保在OPPO开放平台已正确配置应用信息
+
+3. registration_id需要从移动应用端获取,不能随意填写
+
+4. 通讯与服务类消息会自动使用配置的频道ID(previte_message)
+
+5. 测试时建议使用真实的设备registration_id
+
+6. 如果MasterSecret与AppSecret不同,务必更新配置文件
+
+7. 生产环境建议将敏感信息(AppKey、Secret等)配置为环境变量
+
+8. 通讯与服务类消息说明:
+ - 根据OPPO官方文档(https://open.oppomobile.com/documentation/page/info?id=13189)
+ - 必须设置 channel_id 为 "previte_message"
+ - 必须设置 channel_name 为 "消息推送"
+ - 这些参数已在代码中自动配置,无需手动设置
+ - 消息会显示在OPPO手机的"消息推送"频道中
+
+
+十一、技术支持
+================================================================================
+
+1. OPPO推送服务文档
+ - 通讯与服务类消息文档:https://open.oppomobile.com/documentation/page/info?id=13189
+ - 推送服务总文档:https://open.oppomobile.com/documentation/page/info?id=11233
+
+2. 查看项目文档
+ - README.md:项目总体说明
+ - 通讯与服务类消息说明.md:通讯与服务类消息详细说明
+
+3. 查看控制台日志获取详细错误信息
+
+4. 检查OPPO开放平台的推送统计,确认消息发送状态
+
+
+================================================================================
+ 祝您测试顺利!
+================================================================================
+
diff --git a/通讯与服务类消息说明.md b/通讯与服务类消息说明.md
new file mode 100644
index 0000000..c91fd06
--- /dev/null
+++ b/通讯与服务类消息说明.md
@@ -0,0 +1,136 @@
+# 通讯与服务类消息发送说明
+
+## 概述
+
+本文档说明如何使用本后台服务发送**通讯与服务(原私信)类消息**。
+
+根据 [OPPO推送服务官方文档](https://open.oppomobile.com/documentation/page/info?id=13189),通讯与服务类消息需要特殊的参数配置。
+
+## 关键配置参数
+
+### 1. 频道ID(channel_id)
+- **值**: `previte_message`
+- **位置**: `src/main/resources/application.properties`
+- **配置项**: `oppo.push.channel.id.im=previte_message`
+
+### 2. 频道名称(channel_name)
+- **值**: `消息推送`
+- **位置**: `src/main/resources/application.properties`
+- **配置项**: `oppo.push.channel.name.im=消息推送`
+
+## 代码实现
+
+在 `OppoPushService.java` 中,发送消息时会自动设置以下参数:
+
+```java
+// 通讯与服务(原私信)类消息特殊参数
+notification.put("channel_id", config.getChannelIdIm()); // previte_message
+notification.put("channel_name", config.getChannelNameIm()); // 消息推送
+
+// extra参数(可选)
+Map extra = new HashMap<>();
+extra.put("message_type", "chat"); // 标识为私信类消息
+notification.put("extra", extra);
+```
+
+## 消息体结构
+
+发送通讯与服务类消息时,完整的消息体结构如下:
+
+```json
+{
+ "target_type": 1,
+ "target_value": "设备的registration_id",
+ "notification": {
+ "title": "消息标题",
+ "content": "消息内容",
+ "click_action_type": 1,
+ "click_action_type_value": "",
+ "channel_id": "previte_message",
+ "channel_name": "消息推送",
+ "extra": {
+ "message_type": "chat"
+ }
+ }
+}
+```
+
+## 测试步骤
+
+### 1. 确保配置正确
+
+检查 `application.properties` 文件:
+```properties
+oppo.push.channel.id.im=previte_message
+oppo.push.channel.name.im=消息推送
+```
+
+### 2. 启动服务
+
+```bash
+mvn spring-boot:run
+```
+
+### 3. 发送测试消息
+
+使用 curl 命令:
+```bash
+curl -X POST http://localhost:8080/api/push/send \
+ -H "Content-Type: application/json" \
+ -d '{
+ "targetValue": "您的registration_id",
+ "title": "测试私信",
+ "content": "这是一条通讯与服务类消息",
+ "messageType": "1"
+ }'
+```
+
+### 4. 验证结果
+
+- 检查API返回:`success` 应为 `true`
+- 检查设备:消息应出现在OPPO手机的"消息推送"频道中
+- 检查日志:查看控制台输出的详细日志
+
+## 注意事项
+
+1. **频道ID必须正确**:`channel_id` 必须设置为 `previte_message`,否则消息不会被识别为普通通知
+
+2. **频道名称**:`channel_name` 设置为 `消息推送`,这是OPPO系统识别的标准名称
+
+3. **设备端配置**:确保移动应用已正确集成OPPO推送SDK,并且应用已获得通知权限
+
+4. **registration_id**:必须使用真实的设备registration_id,不能随意填写
+
+5. **消息分类**:通过设置 `channel_id` 为 `previte_message`,消息会被OPPO系统自动分类为"通讯与服务"类消息
+
+## 常见问题
+
+### Q1: 消息发送成功但设备收不到?
+**A**: 检查以下几点:
+- 设备是否在线
+- 应用是否已获得通知权限
+- registration_id是否正确
+- 应用是否已正确集成OPPO推送SDK
+
+### Q2: 消息收到了但不是通讯与服务类?
+**A**: 检查:
+- `channel_id` 是否正确设置为 `previte_message`
+- 查看日志确认消息体中的参数是否正确
+
+### Q3: 如何确认消息类型?
+**A**:
+- 在OPPO手机上,通讯与服务类消息会显示在"消息推送"频道中
+- 可以通过OPPO开放平台的推送统计查看消息分类
+
+## 相关文档
+
+- [OPPO推送服务文档 - 通讯与服务类消息](https://open.oppomobile.com/documentation/page/info?id=13189)
+- [OPPO开放平台](https://open.oppomobile.com)
+
+## 技术支持
+
+如有问题,请:
+1. 查看控制台日志获取详细错误信息
+2. 检查OPPO开放平台的推送统计
+3. 参考OPPO官方文档
+