Compare commits

...

6 Commits

Author SHA1 Message Date
Leo
f89ed66bcc 1 2025-12-08 15:27:52 +08:00
Leo
a893f3cd61 1 2025-12-05 23:02:02 +08:00
Leo
c2be15e3f5 1 2025-12-05 23:01:41 +08:00
Leo
8445b500ae 1 2025-12-05 22:35:51 +08:00
Leo
ee67d1ae8f Merge branch 'master' of https://git.van333.cn/CC/Jarvis_java 2025-12-04 15:47:42 +08:00
Leo
a20e92d7bf 1 2025-12-04 15:47:39 +08:00
7 changed files with 125 additions and 17 deletions

View File

@@ -58,7 +58,7 @@ public class SocialMediaPromptController {
templateInfo.put("key", key);
templateInfo.put("description", TEMPLATE_DESCRIPTIONS.get(key));
String template = getTemplate(key);
String template = getTemplateFromRedis(key);
templateInfo.put("template", template);
templateInfo.put("isDefault", template == null);
@@ -92,7 +92,7 @@ public class SocialMediaPromptController {
return response;
}
String template = getTemplate(key);
String template = getTemplateFromRedis(key);
Map<String, Object> data = new HashMap<>();
data.put("key", key);
data.put("description", TEMPLATE_DESCRIPTIONS.get(key));
@@ -202,7 +202,7 @@ public class SocialMediaPromptController {
/**
* 从 Redis 获取模板
*/
private String getTemplate(String key) {
private String getTemplateFromRedis(String key) {
if (redisTemplate == null) {
return null;
}

View File

@@ -61,6 +61,12 @@ public class SuperAdmin {
@Column(name = "is_active", nullable = false)
private Integer isActive = 1;
/**
* 接收人企业微信用户ID多个用逗号分隔
*/
@Column(name = "touser", length = 500)
private String touser;
/**
* 创建时间
*/

View File

@@ -61,8 +61,9 @@ public class MessageConsumerService implements RocketMQListener<JSONObject> {
Integer msgType = data.getInteger("msgType");
String fromWxid = data.getString("fromWxid");
Boolean hiddenTime = data.getBoolean("hiddenTime");
String touser = data.getString("touser"); // 获取接收人参数
wxtsUtil.sendWxTextMessage(wxid, content, msgType, fromWxid, hiddenTime);
wxtsUtil.sendWxTextMessage(wxid, content, msgType, fromWxid, hiddenTime, touser);

View File

@@ -2048,7 +2048,7 @@ public class JDUtil {
/**
* 提供给对外API使用根据商品类型选择一条评论
* 优先返回未使用的京东评论;若无则尝试淘宝映射;仍无则从已使用中随机一条。
* 优先返回未使用的京东评论;若无则尝试淘宝映射;仍无则从已使用中随机一条(京东和淘宝随机选择)
* 返回的 Comment 可能不是持久化实体(如淘宝生成),调用方需自行处理 images 解析。
*/
public synchronized cn.van.business.model.pl.Comment selectCommentForProductType(String productType) {
@@ -2079,18 +2079,55 @@ public class JDUtil {
return chosen;
}
// 无可用京东评论时,尝试淘宝映射生成
// 无可用京东评论时,尝试淘宝映射生成(未使用的淘宝评论)
cn.van.business.model.pl.Comment taobao = null;
try {
cn.van.business.model.pl.Comment taobao = generateTaobaoComment(productType);
taobao = generateTaobaoComment(productType);
if (taobao != null) {
return taobao; // 注意:此处返回的对象未必持久化
}
} catch (Exception ignore) {}
// 兜底:从已使用京东评论里取一条
// 兜底:当京东和淘宝的未使用评论都用完了,在京东已使用和淘宝已使用之间随机选择
java.util.List<cn.van.business.model.pl.Comment> allUsedComments = new java.util.ArrayList<>();
// 添加已使用的京东评论
if (usedComments != null && !usedComments.isEmpty()) {
java.util.Collections.shuffle(usedComments);
return usedComments.get(0);
allUsedComments.addAll(usedComments);
}
// 添加已使用的淘宝评论
try {
getProductTypeMapForTB();
String taobaoProductId = productTypeMapTB.getOrDefault(productId, productId);
java.util.List<TaobaoComment> usedTbComments = taobaoCommentRepository
.findByProductIdAndIsUseNotAndPictureUrlsIsNotNull(taobaoProductId, 0);
if (usedTbComments != null && !usedTbComments.isEmpty()) {
// 将淘宝评论转换为京东评论格式
for (TaobaoComment tbComment : usedTbComments) {
cn.van.business.model.pl.Comment converted = new cn.van.business.model.pl.Comment();
converted.setCommentText(tbComment.getCommentText());
String pictureUrls = tbComment.getPictureUrls();
if (pictureUrls != null) {
pictureUrls = pictureUrls.replace("//img.", "https://img.");
}
converted.setPictureUrls(pictureUrls);
converted.setCommentId(tbComment.getCommentId());
converted.setProductId(productId);
converted.setUserName(tbComment.getUserName());
converted.setCreatedAt(tbComment.getCreatedAt());
allUsedComments.add(converted);
}
}
} catch (Exception e) {
logger.warn("获取已使用的淘宝评论失败", e);
}
// 从所有已使用的评论(京东+淘宝)中随机选择一条
if (!allUsedComments.isEmpty()) {
java.util.Collections.shuffle(allUsedComments);
return allUsedComments.get(0);
}
} catch (Exception e) {
logger.error("selectCommentForProductType error", e);

View File

@@ -68,9 +68,13 @@ public class OrderUtil {
if (!isAutoFlush || !lastValidCode.equals(newValidCode)) {
String content = getFormattedOrderInfo(orderRow);
String wxId = getWxidFromJdid(orderRow.getUnionId().toString());
// 根据unionId获取接收人列表
String unionIdStr = orderRow.getUnionId().toString();
String touser = WXUtil.getTouserByUnionId(unionIdStr);
logger.info("京粉订单推送 - unionId={}, wxId={}, touser={}", unionIdStr, wxId, touser);
if (Util.isNotEmpty(wxId)) {
wxUtil.sendTextMessage(wxId, content, 1, wxId, true);
wxUtil.sendTextMessage(wxId, content, 1, wxId, true, touser);
// 不是已完成,不是违规的才发送
if (newValidCode != 17 && newValidCode != 25 && newValidCode != 26 && newValidCode != 27 && newValidCode != 28) {
// 发送今日统计信息
@@ -98,13 +102,15 @@ public class OrderUtil {
}
if (shouldNotify) {
String wxId = getWxidFromJdid(orderRow.getUnionId().toString());
// 根据unionId获取接收人列表
String touser = WXUtil.getTouserByUnionId(orderRow.getUnionId().toString());
if (Util.isNotEmpty(wxId)) {
String content = getFormattedOrderInfoForJB(orderRow);
String alertMsg = "[爱心] 价保/赔付 " + newProPriceAmount + " [爱心] \n" + content;
try {
// 先发送通知
wxUtil.sendTextMessage(wxId, alertMsg, 1, wxId, true);
wxUtil.sendTextMessage(wxId, alertMsg, 1, wxId, true, touser);
// 通知成功后更新Redis格式为 "金额:true"
if (!isAutoFlushJB) {
@@ -176,6 +182,8 @@ public class OrderUtil {
if (!orderRowList.isEmpty()) {
int i = 1;
String wxId = getWxidFromJdid(orderRowList.get(0).getUnionId().toString());
// 根据unionId获取接收人列表
String touser = WXUtil.getTouserByUnionId(orderRowList.get(0).getUnionId().toString());
StringBuilder content = new StringBuilder();
content.append("批量订单:\n\r ").append("").append(orderRowList.size()).append("\r");
List<OrderRow> filterList = orderRowList.stream().filter(orderRow -> orderRow.getValidCode() != 2 && orderRow.getValidCode() != 3).toList();
@@ -187,7 +195,7 @@ public class OrderUtil {
}
if (Util.isNotEmpty(wxId)) {
wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId, false);
wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId, false, touser);
}
}
@@ -247,6 +255,8 @@ public class OrderUtil {
if (!orderRowList.isEmpty()) {
int i = 1;
String wxId = getWxidFromJdid(orderRowList.get(0).getUnionId().toString());
// 根据unionId获取接收人列表
String touser = WXUtil.getTouserByUnionId(orderRowList.get(0).getUnionId().toString());
StringBuilder content = new StringBuilder();
content.append("批量订单:\n\r ").append("").append(orderRowList.size()).append("\r");
List<OrderRow> filterList = orderRowList.stream().filter(orderRow -> orderRow.getValidCode() != 2 && orderRow.getValidCode() != 3).toList();
@@ -258,7 +268,7 @@ public class OrderUtil {
}
if (Util.isNotEmpty(wxId)) {
wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId, false);
wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId, false, touser);
}
}

View File

@@ -133,6 +133,33 @@ public class WXUtil {
return result;
}
/**
* 根据unionId获取SuperAdmin的接收人列表
* @param unionId 联盟ID
* @return 接收人列表企业微信用户ID多个用逗号分隔如果未配置则返回null
*/
public static String getTouserByUnionId(String unionId) {
if (unionId == null || unionId.trim().isEmpty()) {
logger.debug("getTouserByUnionId: unionId为空");
return null;
}
logger.debug("getTouserByUnionId: 查找unionId={}, super_admins数量={}", unionId, super_admins.size());
for (SuperAdmin admin : super_admins.values()) {
if (unionId.equals(admin.getUnionId())) {
String touser = admin.getTouser();
logger.debug("getTouserByUnionId: 找到匹配的SuperAdmin, unionId={}, name={}, touser={}",
admin.getUnionId(), admin.getName(), touser);
if (touser != null && !touser.trim().isEmpty()) {
return touser.trim();
} else {
logger.debug("getTouserByUnionId: SuperAdmin的touser字段为空或未配置");
}
}
}
logger.debug("getTouserByUnionId: 未找到匹配的SuperAdmin, unionId={}", unionId);
return null;
}
public static List<String> splitStringByLength(String input, int length) {
List<String> result = new ArrayList<>();
@@ -158,7 +185,8 @@ public class WXUtil {
jdidToWxidMap.put(superAdmin.getUnionId(), superAdmin.getWxid());
jdidToRemarkMap.put(superAdmin.getUnionId(), superAdmin.getName());
}
logger.info("超级管理员:{} {}", superAdmin.getName(), superAdmin.getWxid());
logger.info("超级管理员:{} {}, unionId={}, touser={}",
superAdmin.getName(), superAdmin.getWxid(), superAdmin.getUnionId(), superAdmin.getTouser());
}
/* 内部管理群 */
@@ -218,6 +246,10 @@ public class WXUtil {
}
public void sendTextMessage(String wxid, String content, Integer msgType, String fromwxid, Boolean hiddenTime) {
sendTextMessage(wxid, content, msgType, fromwxid, hiddenTime, null);
}
public void sendTextMessage(String wxid, String content, Integer msgType, String fromwxid, Boolean hiddenTime, String touser) {
// 全部打印
//logger.info("发送文本消息 msgType: {} wxid: {} fromwxid: {} content: {}", msgType, wxid, fromwxid, content);
// 先在content顶部插入时间戳
@@ -264,6 +296,10 @@ public class WXUtil {
data.put("msgType", msgType);
data.put("fromWxid", fromwxid);
data.put("hiddenTime", hiddenTime);
// 如果提供了接收人列表,添加到数据中
if (touser != null && !touser.trim().isEmpty()) {
data.put("touser", touser.trim());
}
wxReqDate.setData(data);
// wxReqDate 转成 JSONObject
JSONObject message = JSON.parseObject(JSON.toJSONString(wxReqDate));

View File

@@ -59,11 +59,29 @@ public class WxtsUtil {
* @param hiddenTime 是否隐藏时间戳
*/
public void sendWxTextMessage(String wxid, String content, Integer msgType, String fromWxid, Boolean hiddenTime) {
sendWxTextMessage(wxid, content, msgType, fromWxid, hiddenTime, null);
}
/**
* 发送微信文本消息到wxts接口带接收人参数
* @param wxid 接收者微信ID
* @param content 消息内容
* @param msgType 消息类型
* @param fromWxid 发送者微信ID
* @param hiddenTime 是否隐藏时间戳
* @param touser 接收人列表企业微信用户ID多个用逗号分隔
*/
public void sendWxTextMessage(String wxid, String content, Integer msgType, String fromWxid, Boolean hiddenTime, String touser) {
try {
String url = SERVER_URL + "/wx/send/jd";
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("text", content);
// 如果提供了接收人列表,添加到参数中
if (touser != null && !touser.trim().isEmpty()) {
paramMap.put("touser", touser.trim());
logger.info("企业微信推送设置接收人 - 接收人: {}", touser);
}
HttpResponse execute = HttpRequest.post(url)
.header("vanToken", TOKEN)
@@ -72,7 +90,7 @@ public class WxtsUtil {
.execute();
if (execute.getStatus() == 200) {
logger.info("微信文本消息发送成功wxid={}, content={}", wxid, content);
logger.info("微信文本消息发送成功wxid={}, content={}, touser={}", wxid, content, touser);
} else {
logger.error("微信文本消息发送失败status={}, response={}", execute.getStatus(), execute.body());
}