|
@@ -12,9 +12,13 @@ import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
|
|
|
|
+import jakarta.servlet.http.HttpServletRequest;
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -55,13 +59,20 @@ public class CallbackController {
|
|
|
* 消息回调通知统一入口
|
|
* 消息回调通知统一入口
|
|
|
*
|
|
*
|
|
|
* 接收哈哈平台推送的所有类型通知,通过 notify_type 区分具体类型
|
|
* 接收哈哈平台推送的所有类型通知,通过 notify_type 区分具体类型
|
|
|
|
|
+ * 支持 application/json 和 application/x-www-form-urlencoded 两种格式
|
|
|
*
|
|
*
|
|
|
- * @param params 回调参数
|
|
|
|
|
|
|
+ * @param request HTTP请求对象
|
|
|
|
|
+ * @param requestParams form表单参数(用于application/x-www-form-urlencoded)
|
|
|
* @return 响应结果,必须返回 "success" 字符串
|
|
* @return 响应结果,必须返回 "success" 字符串
|
|
|
*/
|
|
*/
|
|
|
@PostMapping("/message")
|
|
@PostMapping("/message")
|
|
|
- public String handleMessageCallback(@RequestBody Map<String, Object> params) {
|
|
|
|
|
|
|
+ public String handleMessageCallback(
|
|
|
|
|
+ HttpServletRequest request,
|
|
|
|
|
+ @RequestParam(required = false) Map<String, String> requestParams) {
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // 解析请求参数(兼容JSON和表单两种格式)
|
|
|
|
|
+ Map<String, Object> params = parseRequestParams(request, requestParams);
|
|
|
|
|
+
|
|
|
// 记录回调日志
|
|
// 记录回调日志
|
|
|
log.info("收到消息回调通知: {}", JSON.toJSONString(params));
|
|
log.info("收到消息回调通知: {}", JSON.toJSONString(params));
|
|
|
|
|
|
|
@@ -308,13 +319,20 @@ public class CallbackController {
|
|
|
*
|
|
*
|
|
|
* 当AI识别完成并生成订单后,哈哈平台会推送订单信息到此接口
|
|
* 当AI识别完成并生成订单后,哈哈平台会推送订单信息到此接口
|
|
|
* 这是独立于消息回调的订单回调接口
|
|
* 这是独立于消息回调的订单回调接口
|
|
|
|
|
+ * 支持 application/json 和 application/x-www-form-urlencoded 两种格式
|
|
|
*
|
|
*
|
|
|
- * @param params 订单回调参数
|
|
|
|
|
|
|
+ * @param request HTTP请求对象
|
|
|
|
|
+ * @param requestParams form表单参数(用于application/x-www-form-urlencoded)
|
|
|
* @return 响应结果,必须返回 "success" 字符串
|
|
* @return 响应结果,必须返回 "success" 字符串
|
|
|
*/
|
|
*/
|
|
|
@PostMapping("/order")
|
|
@PostMapping("/order")
|
|
|
- public String handleOrderCallback(@RequestBody Map<String, Object> params) {
|
|
|
|
|
|
|
+ public String handleOrderCallback(
|
|
|
|
|
+ HttpServletRequest request,
|
|
|
|
|
+ @RequestParam(required = false) Map<String, String> requestParams) {
|
|
|
try {
|
|
try {
|
|
|
|
|
+ // 解析请求参数(兼容JSON和表单两种格式)
|
|
|
|
|
+ Map<String, Object> params = parseRequestParams(request, requestParams);
|
|
|
|
|
+
|
|
|
// 记录回调日志
|
|
// 记录回调日志
|
|
|
log.info("收到订单回调通知: {}", JSON.toJSONString(params));
|
|
log.info("收到订单回调通知: {}", JSON.toJSONString(params));
|
|
|
|
|
|
|
@@ -385,6 +403,49 @@ public class CallbackController {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 解析请求参数,支持 JSON 和 form-urlencoded 两种格式
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param request HTTP请求对象
|
|
|
|
|
+ * @param requestParams form表单参数
|
|
|
|
|
+ * @return 参数Map
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, Object> parseRequestParams(HttpServletRequest request, Map<String, String> requestParams) {
|
|
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ String contentType = request.getContentType();
|
|
|
|
|
+ log.debug("请求Content-Type: {}", contentType);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 判断 Content-Type
|
|
|
|
|
+ if (contentType != null && contentType.toLowerCase().contains("application/json")) {
|
|
|
|
|
+ // JSON 格式:从 request body 读取
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+ try (BufferedReader reader = request.getReader()) {
|
|
|
|
|
+ String line;
|
|
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
|
|
+ sb.append(line);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ String body = sb.toString();
|
|
|
|
|
+ if (body != null && !body.isEmpty()) {
|
|
|
|
|
+ params = JSON.parseObject(body, Map.class);
|
|
|
|
|
+ log.debug("解析JSON参数: {}", params.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // form-urlencoded 格式:使用 @RequestParam 捕获的参数
|
|
|
|
|
+ if (requestParams != null && !requestParams.isEmpty()) {
|
|
|
|
|
+ params.putAll(requestParams);
|
|
|
|
|
+ log.debug("解析表单参数: {}", params.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("解析请求参数失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return params;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 验证签名
|
|
* 验证签名
|
|
|
*
|
|
*
|