parent
022dafec0b
commit
3658dce209
|
|
@ -1,20 +1,25 @@
|
||||||
package com.czg.controller;
|
package com.czg.controller;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.czg.account.entity.UserInfo;
|
import com.czg.account.entity.UserInfo;
|
||||||
import com.czg.account.service.UserInfoService;
|
import com.czg.account.service.UserInfoService;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.Element;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公众号 通知
|
* 公众号 通知
|
||||||
|
|
@ -52,18 +57,31 @@ public class NotifyController {
|
||||||
else if ("POST".equals(request.getMethod())) {
|
else if ("POST".equals(request.getMethod())) {
|
||||||
log.info("接收到微信 POST 消息请求 - signature: {}, timestamp: {}, nonce: {}",
|
log.info("接收到微信 POST 消息请求 - signature: {}, timestamp: {}, nonce: {}",
|
||||||
signature, timestamp, nonce);
|
signature, timestamp, nonce);
|
||||||
// 读取 POST 请求体中的 XML 数据(微信推送的消息格式为 XML)
|
// 1. 读取请求体中的 XML 数据
|
||||||
String xmlData = readPostXml(request);
|
String xmlData = readPostXml(request);
|
||||||
JSONObject jsonObject = JSON.parseObject(xmlData);
|
if (xmlData.isEmpty()) {
|
||||||
log.info("微信 POST 消息内容: {}", jsonObject);
|
log.error("微信 POST 消息体为空");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
log.info("微信 POST 消息 XML 原始内容: {}", xmlData);
|
||||||
|
|
||||||
|
// 2. 解析 XML 为 Map(便于获取字段)
|
||||||
|
Map<String, String> messageMap;
|
||||||
|
try {
|
||||||
|
messageMap = parseXmlToMap(xmlData);
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
log.error("XML 解析失败,原始内容: {}", xmlData, e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
log.info("微信 POST 消息内容: {}", messageMap);
|
||||||
// 获取消息类型(如 event)
|
// 获取消息类型(如 event)
|
||||||
String msgType = jsonObject.getString("MsgType");
|
String msgType = messageMap.get("MsgType");
|
||||||
// 获取事件类型(如 unsubscribe:用户取消关注 subscribe:用户关注)
|
// 获取事件类型(如 unsubscribe:用户取消关注 subscribe:用户关注)
|
||||||
String event = jsonObject.getString("Event");
|
String event = messageMap.get("Event");
|
||||||
// 获取用户 OpenID
|
// 获取用户 OpenID
|
||||||
String openId = jsonObject.getString("FromUserName");
|
String openId = messageMap.get("FromUserName");
|
||||||
//携带参数
|
//携带参数
|
||||||
String eventKey = jsonObject.getString("EventKey");
|
String eventKey = messageMap.get("EventKey");
|
||||||
Long userId = null;
|
Long userId = null;
|
||||||
log.info("解析结果 - 消息类型: {}, 事件类型: {}, 用户 OpenID: {} 携带参数: {}", msgType, event, openId, eventKey);
|
log.info("解析结果 - 消息类型: {}, 事件类型: {}, 用户 OpenID: {} 携带参数: {}", msgType, event, openId, eventKey);
|
||||||
if (eventKey != null && eventKey.startsWith("qrscene_")) {
|
if (eventKey != null && eventKey.startsWith("qrscene_")) {
|
||||||
|
|
@ -114,4 +132,47 @@ public class NotifyController {
|
||||||
return xmlSb.toString();
|
return xmlSb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 将 XML 字符串解析为 Map<String, String>
|
||||||
|
private static Map<String, String> parseXmlToMap(String xmlData) throws DocumentException {
|
||||||
|
Map<String, String> resultMap = new HashMap<>(16);
|
||||||
|
Document document = DocumentHelper.parseText(xmlData);
|
||||||
|
Element rootElement = document.getRootElement();
|
||||||
|
|
||||||
|
// 遍历所有子节点,将节点名和文本值存入 Map
|
||||||
|
Iterator<Element> elementIterator = rootElement.elementIterator();
|
||||||
|
while (elementIterator.hasNext()) {
|
||||||
|
Element childElement = elementIterator.next();
|
||||||
|
resultMap.put(childElement.getName(), childElement.getTextTrim());
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String str = "<xml><ToUserName><![CDATA[gh_11fc27b7ef34]]></ToUserName><FromUserName><![CDATA[owWHW7Tzeh2gx3WmFsFSxBq2JUTk]]></FromUserName><CreateTime>1761095747</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[subscribe]]></Event><EventKey><![CDATA[qrscene_275]]></EventKey><Ticket><![CDATA[gQGF8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUTZDVHRTMXhmbUoxYUlYdk5GY2sAAgSsLvhoAwQAjScA]]></Ticket></xml>";
|
||||||
|
// 2. 解析 XML 为 Map(便于获取字段)
|
||||||
|
Map<String, String> messageMap = new HashMap<>();
|
||||||
|
try {
|
||||||
|
messageMap = parseXmlToMap(str);
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
log.error("XML 解析失败,", e);
|
||||||
|
}
|
||||||
|
log.info("微信 POST 消息内容: {}", messageMap);
|
||||||
|
//携带参数
|
||||||
|
String eventKey = messageMap.get("EventKey");
|
||||||
|
Long userId = null;
|
||||||
|
if (eventKey != null && eventKey.startsWith("qrscene_")) {
|
||||||
|
try {
|
||||||
|
// 截取 "qrscene_" 前缀后的字符串(长度为 8),并转为 Long
|
||||||
|
String numberStr = eventKey.substring("qrscene_".length());
|
||||||
|
userId = Long.parseLong(numberStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.error("EventKey 后缀不是有效数字,eventKey: {}", eventKey, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("userId: " + userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,13 @@ public class AAMarketTasks {
|
||||||
memberTask.task();
|
memberTask.task();
|
||||||
}
|
}
|
||||||
|
|
||||||
//满减活动定时任务
|
//满减活动/限时折扣 处理任务状态 定时任务
|
||||||
@Resource
|
@Resource
|
||||||
private DiscountActivityTask discountActivityTask;
|
private ActivityStatusTask activityStatusTask;
|
||||||
//每天0点 0分 1秒 执行
|
//每天0点 0分 1秒 执行
|
||||||
@Scheduled(cron = "1 0 0 * * ? ")
|
@Scheduled(cron = "1 0 0 * * ? ")
|
||||||
public void discountActivityTask() {
|
public void activityStatusTask() {
|
||||||
discountActivityTask.task();
|
activityStatusTask.task();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.czg.task;
|
package com.czg.task;
|
||||||
|
|
||||||
import com.czg.market.entity.MkDiscountActivity;
|
import com.czg.market.entity.MkDiscountActivity;
|
||||||
|
import com.czg.market.entity.MkLimitTimeDiscount;
|
||||||
import com.czg.market.service.MkDiscountActivityService;
|
import com.czg.market.service.MkDiscountActivityService;
|
||||||
|
import com.czg.market.service.MkLimitTimeDiscountService;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -17,14 +19,17 @@ import java.time.LocalDateTime;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class DiscountActivityTask {
|
public class ActivityStatusTask {
|
||||||
@Resource
|
@Resource
|
||||||
private MkDiscountActivityService discountActivityService;
|
private MkDiscountActivityService discountActivityService;
|
||||||
|
@Resource
|
||||||
|
private MkLimitTimeDiscountService limitTimeDiscountService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 满减活动 过期
|
* 满减活动/限时折扣 任务状态更新任务
|
||||||
*/
|
*/
|
||||||
public void task() {
|
public void task() {
|
||||||
|
//满减活动
|
||||||
discountActivityService.update(new MkDiscountActivity().setStatus(2),
|
discountActivityService.update(new MkDiscountActivity().setStatus(2),
|
||||||
new QueryWrapper()
|
new QueryWrapper()
|
||||||
.eq(MkDiscountActivity::getStatus, 1)
|
.eq(MkDiscountActivity::getStatus, 1)
|
||||||
|
|
@ -34,5 +39,17 @@ public class DiscountActivityTask {
|
||||||
discountActivityService.update(new MkDiscountActivity().setStatus(3),
|
discountActivityService.update(new MkDiscountActivity().setStatus(3),
|
||||||
new QueryWrapper().le(MkDiscountActivity::getValidEndTime, LocalDateTime.now())
|
new QueryWrapper().le(MkDiscountActivity::getValidEndTime, LocalDateTime.now())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//限时折扣
|
||||||
|
limitTimeDiscountService.update(new MkLimitTimeDiscount().setStatus(2),
|
||||||
|
new QueryWrapper()
|
||||||
|
.eq(MkLimitTimeDiscount::getStatus, 1)
|
||||||
|
.le(MkLimitTimeDiscount::getValidStartTime, LocalDateTime.now())
|
||||||
|
.gt(MkLimitTimeDiscount::getValidEndTime, LocalDateTime.now())
|
||||||
|
);
|
||||||
|
|
||||||
|
limitTimeDiscountService.update(new MkLimitTimeDiscount().setStatus(3),
|
||||||
|
new QueryWrapper().le(MkLimitTimeDiscount::getValidEndTime, LocalDateTime.now())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
@ -27,6 +28,7 @@ import java.time.LocalTime;
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Table("mk_limit_time_discount")
|
@Table("mk_limit_time_discount")
|
||||||
|
@Accessors(chain = true)
|
||||||
public class MkLimitTimeDiscount implements Serializable {
|
public class MkLimitTimeDiscount implements Serializable {
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue