模板消息推送
一、微信推送模板消息
1、首先需要在公众号中添加消息模板,记住在白名单添加IP:
2、代码实现,使用第三方SDK
@Service
@Slf4j
public class PushMessageServiceImpl implements PushMessageService{
@Autowired
private WxMpService wxMpService;
@Autowired
private WechatAccountConfig accountConfig;
@Override
public void orderStatus(OrderDTO orderDTO) {
WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
//设置模板id
templateMessage.setTemplateId(accountConfig.getTemplateId().get("orderStatus"));
templateMessage.setToUser(orderDTO.getBuyerOpenid());//opneid
List<WxMpTemplateData> data = Arrays.asList(new WxMpTemplateData(
"first","亲,记得收货"),
new WxMpTemplateData("keyword1","微信点餐"),
new WxMpTemplateData("keyword2","18766666666"),
new WxMpTemplateData("keyword3",orderDTO.getOrderId()),
new WxMpTemplateData("keyword4",orderDTO.getOrderStatusEnum().getMessage()),
new WxMpTemplateData("keyword5","¥"+orderDTO.getOrderAmount()),
new WxMpTemplateData("remark","欢迎再次光临"));
templateMessage.setData(data);
try {
wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
e.printStackTrace();
log.error("【微信模板消息推送】{}",e);
}
}
}
3、然后在其他业务代码中选择推送模板消息,在此项目中选择在完结订单时推送:
@Override
@Transactional
public OrderDTO finish(OrderDTO orderDTO) {
//判断订单状态
if (!orderDTO.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {
log.error("【完结订单】,订单状态不正确 orderId={},orderStatus={}",orderDTO.getOrderId(),orderDTO.getOrderStatus());
throw new SellException(ResultEums.ORDER_STATUS_ERROR);
}
//修改订单状态
OrderMaster orderMaster = new OrderMaster();
orderDTO.setOrderStatus(OrderStatusEnum.FINISH.getCode());
BeanUtils.copyProperties(orderDTO,orderMaster);
OrderMaster result = orderMasterRepository.save(orderMaster);
if (result==null) {
log.error("【完结订单】订单状态更新失败 orderId={},orderStatus={}",orderMaster.getOrderId(),orderMaster.getOrderStatus());
}
//推送模板消息
pushMessageService.orderStatus(orderDTO);
return orderDTO;
}
注意:在推送模板消息中,如果模板消息推送失败,只是捕获异常,没有抛出,因为推送模板消息与其他业务相比,并不算是多重要的功能,就是推送失败,也是可以接受的范围之内,不能影响其他的业务实现。
二、webSocket实现消息提醒
1、前台页面的处理:在订单列表页面,当有新的订单生成的弹窗提醒,并伴有提示音
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| <html> <#include "../common/head.ftl"> <body> <div id="wrapper" class="toggled"> <#-- 边栏--> <#include "../common/nav.ftl">
<#--主要内容--> <div id="page-content-wrapper"> .... </div>
<!--弹窗--> <div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel"> 提醒 </h4> </div> <div class="modal-body"> 您有新的订单 </div> <div class="modal-footer"> <!--点击关闭,关闭音乐播放--> <button onclick="javascript:document.getElementById('notice').pause()" type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button onclick="location.reload()" type="button" class="btn btn-primary">查看新的订单</button> </div> </div>
</div>
</div> <#--b播放音乐--> <audio id="notice" loop="loop"> <source src="/sell/mp3.notify.mp3" > </audio> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <!--websocket--> <script> var websocket = null; if ('WebSocket' in window) { websocket = new WebSocket('ws://wxorder.natapp1.cc/sell/webSocket');
}else { alert('该浏览器不支持webSocket!'); } websocket.onopen = function (event) { console.log('建立连接'); }
websocket.onclose = function (event) { console.log('连接关闭'); }
websocket.onmessage = function (event) { console.log('收到消息'+event.data); //弹出提醒,播放音乐 $('#myModal').modal('show'); document.getElementById('notice').play();
} window.onbeforeunload = function () { websocket.close(); } </script> </body> </html>
|
2、后台消息的发送:
配置:
@Component
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this);
log.info("【websocket消息】有新的连接,总数:{}",webSocketSet.size());
}
@OnClose
public void onClose() {
webSocketSet.remove(this);
log.info("【webSocket消息】 连接断开,总数:{}",webSocketSet.size());
}
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】 收到客户端发来的消息",message);
}
public void sendMessage(String message) {
for (WebSocket webSocket:webSocketSet) {
log.info("【websocket消息】 广播消息,message={}",message);
try {
webSocket.session.getBasicRemote().sendText(message);
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
3、在创建订单时发送消息:
@Override
@Transactional
public OrderDTO create(OrderDTO orderDTO) {
String orderId = KeyUtils.genUniqueKey();
BigDecimal ordrAmount = new BigDecimal(BigInteger.ZERO);
//查询商品,从前台传来得OrderDTO中获取商品详细列表,遍历列表得中得所有OrderDetail,
for (OrderDetail orderDetail:orderDTO.getOrderDetailList()) {
//计算订单总价:(1)、从orderDetail中获取商品Id,查出商品信息,主要是为了获取ProducePrie和ProductQuantity
ProductInfo productInfo = productInfoService.findOne(orderDetail.getProductId());
if (productInfo==null) {
throw new SellException(ResultEums.PRODUCT_NOT_EXIST);
}
//(2)、根据获取得到得ProducePrie和ProductQuantity计算商品总价ordrAmount
ordrAmount = productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity()))
.add(ordrAmount);
//订单详情入库:要将从数据库中查出得productInfo复制到orderDetail,productInfo必须从数据库获取,
// 并且设置detailId与orderId
BeanUtils.copyProperties(productInfo,orderDetail);
orderDetail.setDetailId(KeyUtils.genUniqueKey());
orderDetail.setOrderId(orderId);
orderDetailRepository.save(orderDetail);
}
//写入订单数据库:将订单信息,即OrderMaster信息入库,要将OrderDTO中的信息复制到OrderMaster对象中
// ,同时设置orderId,总金额ordrAmount,支付状态,订单状态,并保存入库
OrderMaster orderMaster = new OrderMaster();
orderDTO.setOrderId(orderId);
BeanUtils.copyProperties(orderDTO,orderMaster);
orderMaster.setOrderAmount(ordrAmount);
orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
orderMasterRepository.save(orderMaster);
//扣库存
List<Cart> cartList = orderDTO.getOrderDetailList().stream()
.map(e ->new Cart(e.getProductId(),e.getProductQuantity()))
.collect(Collectors.toList());
productInfoService.decreStock(cartList);
//发送websocket消息
webSocket.sendMessage(orderDTO.getOrderId());
return orderDTO;
}