package com.ylx.massage.service.impl; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; import com.ylx.common.config.WechatAccountConfig; import com.ylx.massage.domain.TJs; import com.ylx.massage.domain.TOrder; import com.ylx.massage.domain.TXiangmu; import com.ylx.massage.service.OrderNotificationService; import com.ylx.massage.service.TJsService; import com.ylx.massage.utils.DateTimeUtils; import com.ylx.massage.utils.WeChatUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Date; import java.util.List; /** * 订单消息通知服务实现类 *

* 负责处理订单生命周期中各阶段的消息通知功能。 * 所有通知通过微信公众号模板消息推送给用户。 *

* * @author ylx * @version 1.0 * @since 2024 */ @Service @Slf4j public class OrderNotificationServiceImpl implements OrderNotificationService { @Resource private WeChatUtil weChatUtil; @Resource private WechatAccountConfig wxPayProperties; @Resource private TJsService jsService; /** * 订单待接单提醒(技师侧) * * @param order 订单信息 */ @Override public void sendPendingRemindNotification(TOrder order) { try { log.info("订单待接单提醒(技师侧)"); cn.hutool.json.JSONObject param = buildPendingRemindParams(order); //获取技师openid TJs js = jsService.getById(order.getcJsId()); weChatUtil.notification(js.getcOpenId(), wxPayProperties.getTechTemplate1(), param); log.info("订单待接单提醒发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { log.error("订单待接单提醒发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 订单已接单通知(用户侧) * * @param order 订单信息 */ @Override public void sendReceivedNotification(TOrder order) { try { cn.hutool.json.JSONObject param = buildReceivedNotificationParams(order); weChatUtil.notification(order.getcOpenId(), wxPayProperties.getUserTemplate1(), param); log.info("订单已接单通知发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { e.printStackTrace(); log.error("订单已接单通知发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 订单完成通知(用户侧) * * @param order 订单信息 */ @Override public void sendCompletedNotification(TOrder order) { try { cn.hutool.json.JSONObject param = buildCompletedNotificationParams(order); weChatUtil.notification(order.getcOpenId(), wxPayProperties.getUserTemplate2(), param); log.info("订单完成通知发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { log.error("订单完成通知发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 订单取消通知(用户侧) * * @param order 订单信息 */ @Override public void sendCancelledNotification(TOrder order) { try { cn.hutool.json.JSONObject param = buildCancelledNotificationParams(order); weChatUtil.notification(order.getcOpenId(), wxPayProperties.getUserTemplate3(), param); log.info("订单取消通知发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { log.error("订单取消通知发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 构建待接单提醒消息参数(技师侧) * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildPendingRemindParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单号 param.set("character_string9", JSONUtil.createObj().set("value", order.getOrderNo())); // 用户电话 param.set("phone_number3", JSONUtil.createObj().set("value", order.getcPhone())); // 项目 String projectNames = getProjectNames(order); param.set("thing10", JSONUtil.createObj().set("value", projectNames)); // 下单地址 param.set("thing13", JSONUtil.createObj().set("value", order.getAddress())); // 预约时间 LocalDateTime startTime = order.getStartTime(); if(startTime==null){ // 预约时间为空,设置默认值 startTime = LocalDateTime.now(); } Date date = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()); param.set("time6", JSONUtil.createObj().set("value", DateTimeUtils.formatDate(date, "yyyy-MM-dd HH:mm"))); return param; } /** * 构建已接单通知消息参数 * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildReceivedNotificationParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单号 param.set("character_string1", JSONUtil.createObj().set("value", order.getOrderNo())); // 项目名称 String projectNames = getProjectNames(order); param.set("thing4", JSONUtil.createObj().set("value", projectNames)); //根据技师ID查询技师姓名 TJs js = jsService.getById(order.getcJsId()); String jsName = js.getcName(); // 商家名称 param.set("thing9", JSONUtil.createObj().set("value", jsName)); // 联系电话 param.set("phone_number5", JSONUtil.createObj().set("value", js.getcPhone())); return param; } /** * 构建完成通知消息参数(用户侧) * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildCompletedNotificationParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单号 param.set("character_string8", JSONUtil.createObj().set("value", order.getOrderNo())); // 项目名称 String projectNames = getProjectNames(order); param.set("thing19", JSONUtil.createObj().set("value", projectNames)); // 完成时间 LocalDateTime completeTime = order.getEndTime(); Date date = Date.from(completeTime.atZone(ZoneId.systemDefault()).toInstant()); param.set("time18", JSONUtil.createObj().set("value", DateTimeUtils.formatDate(date, "yyyy-MM-dd HH:mm"))); return param; } /** * 构建取消通知消息参数 * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildCancelledNotificationParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单号 param.set("character_string2", JSONUtil.createObj().set("value", order.getOrderNo())); // 取消原因 param.set("thing5", JSONUtil.createObj().set("value", "用户个人原因")); // 项目名称 String projectNames = getProjectNames(order); param.set("thing25", JSONUtil.createObj().set("value", projectNames)); //订单金额 param.set("amount23", JSONUtil.createObj().set("value", order.getTotalPrice().toString())); return param; } /** * 从订单明细中提取项目名称 *

* 解析订单的商品列表,将多个项目名称用逗号连接 *

* * @param order 订单信息 * @return String 项目名称字符串,多个项目用逗号分隔 */ private String getProjectNames(TOrder order) { List list = JSONObject.parseArray(order.getcGoods().toJSONString(), TXiangmu.class); StringBuilder sb = new StringBuilder(); for (TXiangmu xiangmu : list) { sb.append(xiangmu.getcTitle()).append(","); } // 移除最后一个逗号 if (sb.length() > 0) { sb.setLength(sb.length() - 1); } return sb.toString(); } /** * 订单已接单通知(技师侧) * * @param order 订单信息 */ @Override public void sendTechnicianReceivedNotification(TOrder order) { try { // 获取技师信息 String jsOpenId = getTechnicianOpenId(order); log.info("技师的openId:{}", jsOpenId); if (jsOpenId == null) { log.warn("技师信息不存在,无法发送已接单通知,订单号:{}", order.getOrderNo()); return; } cn.hutool.json.JSONObject param = buildTechnicianReceivedNotificationParams(order); weChatUtil.notification(jsOpenId, wxPayProperties.getTechTemplate2(), param); log.info("技师侧已接单通知发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { log.error("技师侧已接单通知发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 订单取消通知(技师侧) * * @param order 订单信息 */ @Override public void sendTechnicianCancelledNotification(TOrder order) { try { // 获取技师的openId String jsOpenId = getTechnicianOpenId(order); log.info("技师的openId:{}", jsOpenId); if (jsOpenId == null) { log.warn("技师信息不存在,无法发送取消通知,订单号:{}", order.getOrderNo()); return; } cn.hutool.json.JSONObject param = buildTechnicianCancelledNotificationParams(order); weChatUtil.notification(jsOpenId, wxPayProperties.getTechTemplate3(), param); log.info("技师侧取消订单通知发送成功,订单号:{}", order.getOrderNo()); } catch (Exception e) { log.error("技师侧取消订单通知发送失败,订单号:{}", order.getOrderNo(), e); } } /** * 构建技师侧已接单通知消息参数 * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildTechnicianReceivedNotificationParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单编号 param.set("character_string1", JSONUtil.createObj().set("value", order.getOrderNo())); // 联系电话 param.set("phone_number5", JSONUtil.createObj().set("value", order.getcPhone())); // 项目名称 String projectNames = getProjectNames(order); param.set("thing4", JSONUtil.createObj().set("value", projectNames)); // 预约地址 param.set("thing14", JSONUtil.createObj().set("value", order.getAddress())); // 预约时间 LocalDateTime dtCreateTime = order.getDtCreateTime(); Date createTime = Date.from(dtCreateTime.atZone(ZoneId.systemDefault()).toInstant()); param.set("time3", JSONUtil.createObj().set("value", DateTimeUtils.formatDate(createTime, "yyyy-MM-dd HH:mm"))); return param; } /** * 构建技师侧取消通知消息参数 * * @param order 订单信息 * @return JSONObject 消息参数 */ private cn.hutool.json.JSONObject buildTechnicianCancelledNotificationParams(TOrder order) { cn.hutool.json.JSONObject param = JSONUtil.createObj(); // 订单号 param.set("character_string2", JSONUtil.createObj().set("value", order.getOrderNo())); // 取消原因 param.set("thing5", JSONUtil.createObj().set("value", getCancelReason(order))); // 订单金额 param.set("amount23", JSONUtil.createObj().set("value", order.getTotalPrice().toString())); return param; } /** * 获取技师的 OpenId * * @param order 订单信息 * @return String 技师 OpenId,如果技师不存在则返回 null */ private String getTechnicianOpenId(TOrder order) { if (order.getcJsId() == null) { return null; } try { return jsService.getById(order.getcJsId()).getcOpenId(); } catch (Exception e) { log.error("获取技师信息失败,技师ID:{}", order.getcJsId(), e); return null; } } /** * 获取订单取消原因 * * @param order 订单信息 * @return String 取消原因描述 */ private String getCancelReason(TOrder order) { // 如果订单中有具体的取消原因,使用订单中的原因 if (order.getReasonRefusal() != null && !order.getReasonRefusal().trim().isEmpty()) { return order.getReasonRefusal(); } // 默认取消原因 return "用户取消订单"; } }