yshop3.0-alpha版本
This commit is contained in:
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.builder;
|
||||
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Binary Wang(https://github.com/binarywang)
|
||||
*/
|
||||
public abstract class AbstractBuilder {
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public abstract WxMpXmlOutMessage build(String content,
|
||||
WxMpXmlMessage wxMessage, WxMpService service);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.builder;
|
||||
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
|
||||
/**
|
||||
* @author Binary Wang(https://github.com/binarywang)
|
||||
*/
|
||||
public class ImageBuilder extends AbstractBuilder {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
|
||||
WxMpService service) {
|
||||
|
||||
WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content)
|
||||
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
|
||||
.build();
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.builder;
|
||||
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage;
|
||||
|
||||
/**
|
||||
* @author Binary Wang(https://github.com/binarywang)
|
||||
*/
|
||||
public class TextBuilder extends AbstractBuilder {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
|
||||
WxMpService service) {
|
||||
WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content)
|
||||
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
|
||||
.build();
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.config;
|
||||
|
||||
import co.yixiang.mp.handler.*;
|
||||
import co.yixiang.utils.RedisUtil;
|
||||
import co.yixiang.utils.RedisUtils;
|
||||
import co.yixiang.utils.ShopKeyUtils;
|
||||
import com.google.common.collect.Maps;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
||||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
|
||||
import me.chanjar.weixin.mp.constant.WxMpEventConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.EventType;
|
||||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||
|
||||
/**
|
||||
* 公众号配置
|
||||
* @author hupeng
|
||||
* @date 2020/01/20
|
||||
*/
|
||||
@Configuration
|
||||
public class WxMpConfiguration {
|
||||
|
||||
private static Map<String, WxMpService> mpServices = Maps.newHashMap();
|
||||
private static Map<String, WxMpMessageRouter> routers = Maps.newHashMap();
|
||||
|
||||
private static LogHandler logHandler;
|
||||
private static NullHandler nullHandler;
|
||||
private static KfSessionHandler kfSessionHandler;
|
||||
private static StoreCheckNotifyHandler storeCheckNotifyHandler;
|
||||
private static LocationHandler locationHandler;
|
||||
private static MenuHandler menuHandler;
|
||||
private static MsgHandler msgHandler;
|
||||
private static UnsubscribeHandler unsubscribeHandler;
|
||||
private static SubscribeHandler subscribeHandler;
|
||||
private static ScanHandler scanHandler;
|
||||
private static RedisUtils redisUtils;
|
||||
|
||||
@Autowired
|
||||
public WxMpConfiguration(LogHandler logHandler,NullHandler nullHandler,KfSessionHandler kfSessionHandler,
|
||||
StoreCheckNotifyHandler storeCheckNotifyHandler,LocationHandler locationHandler,
|
||||
MenuHandler menuHandler,MsgHandler msgHandler,UnsubscribeHandler unsubscribeHandler,
|
||||
SubscribeHandler subscribeHandler,ScanHandler scanHandler,
|
||||
RedisUtils redisUtils){
|
||||
this.logHandler = logHandler;
|
||||
this.nullHandler = nullHandler;
|
||||
this.kfSessionHandler = kfSessionHandler;
|
||||
this.storeCheckNotifyHandler = storeCheckNotifyHandler;
|
||||
this.locationHandler = locationHandler;
|
||||
this.menuHandler = menuHandler;
|
||||
this.msgHandler = msgHandler;
|
||||
this.unsubscribeHandler = unsubscribeHandler;
|
||||
this.subscribeHandler = subscribeHandler;
|
||||
this.scanHandler = scanHandler;
|
||||
this.redisUtils = redisUtils;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取WxMpService
|
||||
* @return
|
||||
*/
|
||||
public static WxMpService getWxMpService() {
|
||||
|
||||
WxMpService wxMpService = mpServices.get(ShopKeyUtils.getYshopWeiXinMpSevice());
|
||||
//增加一个redis标识
|
||||
if(wxMpService == null || redisUtils.get(ShopKeyUtils.getYshopWeiXinMpSevice()) == null) {
|
||||
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
|
||||
configStorage.setAppId(RedisUtil.get(ShopKeyUtils.getWechatAppId()));
|
||||
configStorage.setSecret(RedisUtil.get(ShopKeyUtils.getWechatAppSecret()));
|
||||
configStorage.setToken(RedisUtil.get(ShopKeyUtils.getWechatToken()));
|
||||
configStorage.setAesKey(RedisUtil.get(ShopKeyUtils.getWechatEncodingAESKey()));
|
||||
wxMpService = new WxMpServiceImpl();
|
||||
wxMpService.setWxMpConfigStorage(configStorage);
|
||||
mpServices.put(ShopKeyUtils.getYshopWeiXinMpSevice(), wxMpService);
|
||||
routers.put(ShopKeyUtils.getYshopWeiXinMpSevice(), newRouter(wxMpService));
|
||||
|
||||
//增加标识
|
||||
redisUtils.set(ShopKeyUtils.getYshopWeiXinMpSevice(),"yshop");
|
||||
}
|
||||
return wxMpService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除WxMpService
|
||||
*/
|
||||
public static void removeWxMpService(){
|
||||
redisUtils.del(ShopKeyUtils.getYshopWeiXinMpSevice());
|
||||
mpServices.remove(ShopKeyUtils.getYshopWeiXinMpSevice());
|
||||
routers.remove(ShopKeyUtils.getYshopWeiXinMpSevice());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WxMpMessageRouter
|
||||
*/
|
||||
public static WxMpMessageRouter getWxMpMessageRouter() {
|
||||
WxMpMessageRouter wxMpMessageRouter = routers.get(ShopKeyUtils.getYshopWeiXinMpSevice());
|
||||
return wxMpMessageRouter;
|
||||
}
|
||||
|
||||
private static WxMpMessageRouter newRouter(WxMpService wxMpService) {
|
||||
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
|
||||
|
||||
// 记录所有事件的日志 (异步执行)
|
||||
newRouter.rule().handler(logHandler).next();
|
||||
|
||||
// 接收客服会话管理事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
|
||||
.handler(kfSessionHandler).end();
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
|
||||
.handler(kfSessionHandler)
|
||||
.end();
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
|
||||
.handler(kfSessionHandler).end();
|
||||
|
||||
// 门店审核事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxMpEventConstants.POI_CHECK_NOTIFY)
|
||||
.handler(storeCheckNotifyHandler).end();
|
||||
|
||||
// 自定义菜单事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end();
|
||||
|
||||
// 点击菜单连接事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(WxConsts.MenuButtonType.VIEW).handler(menuHandler).end();
|
||||
|
||||
// 扫码事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(EventType.SCANCODE_WAITMSG).handler(menuHandler).end();
|
||||
|
||||
// 关注事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(EventType.SUBSCRIBE).handler(subscribeHandler)
|
||||
.end();
|
||||
|
||||
// 取消关注事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(EventType.UNSUBSCRIBE)
|
||||
.handler(unsubscribeHandler).end();
|
||||
|
||||
// 上报地理位置事件
|
||||
newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
|
||||
.event(EventType.LOCATION).handler(locationHandler)
|
||||
.end();
|
||||
|
||||
|
||||
// 默认
|
||||
newRouter.rule().async(false).handler(msgHandler).end();
|
||||
|
||||
return newRouter;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.config;
|
||||
|
||||
import co.yixiang.enums.PayMethodEnum;
|
||||
import co.yixiang.utils.RedisUtil;
|
||||
import co.yixiang.utils.RedisUtils;
|
||||
import co.yixiang.utils.ShopKeyUtils;
|
||||
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付配置
|
||||
* @author hupeng
|
||||
* @date 2020/03/01
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class WxPayConfiguration {
|
||||
|
||||
private static Map<String, WxPayService> payServices = Maps.newHashMap();
|
||||
|
||||
private static RedisUtils redisUtils;
|
||||
|
||||
@Autowired
|
||||
public WxPayConfiguration(RedisUtils redisUtils) {
|
||||
this.redisUtils = redisUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WxPayService
|
||||
* @return
|
||||
*/
|
||||
public static WxPayService getPayService(PayMethodEnum payMethodEnum) {
|
||||
WxPayService wxPayService = payServices.get(ShopKeyUtils.getYshopWeiXinPayService());
|
||||
if(wxPayService == null || redisUtils.get(ShopKeyUtils.getYshopWeiXinPayService()) == null) {
|
||||
WxPayConfig payConfig = new WxPayConfig();
|
||||
switch (payMethodEnum){
|
||||
case WECHAT:
|
||||
payConfig.setAppId(redisUtils.getY(ShopKeyUtils.getWechatAppId()));
|
||||
break;
|
||||
case WXAPP:
|
||||
payConfig.setAppId(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
|
||||
break;
|
||||
case APP:
|
||||
payConfig.setAppId(RedisUtil.get(ShopKeyUtils.getWxNativeAppAppId()));
|
||||
break;
|
||||
}
|
||||
|
||||
payConfig.setMchId(redisUtils.getY(ShopKeyUtils.getWxPayMchId()));
|
||||
payConfig.setMchKey(redisUtils.getY(ShopKeyUtils.getWxPayMchKey()));
|
||||
payConfig.setKeyPath(redisUtils.getY(ShopKeyUtils.getWxPayKeyPath()));
|
||||
// 可以指定是否使用沙箱环境
|
||||
payConfig.setUseSandboxEnv(false);
|
||||
wxPayService = new WxPayServiceImpl();
|
||||
wxPayService.setConfig(payConfig);
|
||||
payServices.put(ShopKeyUtils.getYshopWeiXinPayService(), wxPayService);
|
||||
|
||||
//增加标识
|
||||
redisUtils.set(ShopKeyUtils.getYshopWeiXinPayService(),"yshop");
|
||||
}
|
||||
return wxPayService;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取小程序WxAppPayService
|
||||
// * @return
|
||||
// */
|
||||
// public static WxPayService getWxAppPayService() {
|
||||
// WxPayService wxPayService = payServices.get(ShopKeyUtils.getYshopWeiXinMiniPayService());
|
||||
// if(wxPayService == null || RedisUtil.get(ShopKeyUtils.getYshopWeiXinPayService()) == null) {
|
||||
// WxPayConfig payConfig = new WxPayConfig();
|
||||
// payConfig.setAppId(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
|
||||
// payConfig.setMchId(RedisUtil.get(ShopKeyUtils.getWxPayMchId()));
|
||||
// payConfig.setMchKey(RedisUtil.get(ShopKeyUtils.getWxPayMchKey()));
|
||||
// payConfig.setKeyPath(RedisUtil.get(ShopKeyUtils.getWxPayKeyPath()));
|
||||
// // 可以指定是否使用沙箱环境
|
||||
// payConfig.setUseSandboxEnv(false);
|
||||
// wxPayService = new WxPayServiceImpl();
|
||||
// wxPayService.setConfig(payConfig);
|
||||
// payServices.put(ShopKeyUtils.getYshopWeiXinMiniPayService(), wxPayService);
|
||||
//
|
||||
// //增加标识
|
||||
// RedisUtil.set(ShopKeyUtils.getYshopWeiXinPayService(),"yshop");
|
||||
// }
|
||||
// return wxPayService;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 获取APPPayService
|
||||
// * @return
|
||||
// */
|
||||
// public static WxPayService getAppPayService() {
|
||||
// WxPayService wxPayService = payServices.get(ShopKeyUtils.getYshopWeiXinAppPayService());
|
||||
// if(wxPayService == null || RedisUtil.get(ShopKeyUtils.getYshopWeiXinPayService()) == null) {
|
||||
// WxPayConfig payConfig = new WxPayConfig();
|
||||
// payConfig.setAppId(RedisUtil.get(ShopKeyUtils.getWxNativeAppAppId()));
|
||||
// payConfig.setMchId(RedisUtil.get(ShopKeyUtils.getWxPayMchId()));
|
||||
// payConfig.setMchKey(RedisUtil.get(ShopKeyUtils.getWxPayMchKey()));
|
||||
// payConfig.setKeyPath(RedisUtil.get(ShopKeyUtils.getWxPayKeyPath()));
|
||||
// // 可以指定是否使用沙箱环境
|
||||
// payConfig.setUseSandboxEnv(false);
|
||||
// wxPayService = new WxPayServiceImpl();
|
||||
// wxPayService.setConfig(payConfig);
|
||||
// payServices.put(ShopKeyUtils.getYshopWeiXinAppPayService(), wxPayService);
|
||||
//
|
||||
// //增加标识
|
||||
// RedisUtil.set(ShopKeyUtils.getYshopWeiXinPayService(),"yshop");
|
||||
// }
|
||||
// return wxPayService;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 移除WxPayService
|
||||
*/
|
||||
public static void removeWxPayService(){
|
||||
redisUtils.del(ShopKeyUtils.getYshopWeiXinPayService());
|
||||
payServices.remove(ShopKeyUtils.getYshopWeiXinPayService());
|
||||
//payServices.remove(ShopKeyUtils.getYshopWeiXinMiniPayService());
|
||||
//payServices.remove(ShopKeyUtils.getYshopWeiXinAppPayService());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.mp.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author hupeng
|
||||
* 微信公众号模板枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum WechatTempateEnum {
|
||||
PAY_SUCCESS("pay_success","支付成功通知"),
|
||||
DELIVERY_SUCCESS("delivery_success","发货成功通知"),
|
||||
REFUND_SUCCESS("refund_success","退款成功通知"),
|
||||
RECHARGE_SUCCESS("recharge_success","充值成功通知");
|
||||
|
||||
private String value; //模板编号
|
||||
private String desc; //模板id
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.error;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 出错页面控制器
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/error")
|
||||
public class ErrorController {
|
||||
|
||||
@GetMapping(value = "/404")
|
||||
public String error404() {
|
||||
return "error";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/500")
|
||||
public String error500() {
|
||||
return "error";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.error;
|
||||
|
||||
import org.springframework.boot.web.server.ErrorPage;
|
||||
import org.springframework.boot.web.server.ErrorPageRegistrar;
|
||||
import org.springframework.boot.web.server.ErrorPageRegistry;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Created by Binary Wang on 2018/8/25.
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class ErrorPageConfiguration implements ErrorPageRegistrar {
|
||||
@Override
|
||||
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
|
||||
errorPageRegistry.addErrorPages(
|
||||
new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"),
|
||||
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public abstract class AbstractHandler implements WxMpMessageHandler {
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
public class KfSessionHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
//TODO 对会话做处理
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import co.yixiang.mp.builder.TextBuilder;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||
|
||||
|
||||
@Component
|
||||
public class LocationHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) {
|
||||
//TODO 接收处理用户发送的地理位置消息
|
||||
try {
|
||||
String content = "感谢反馈,您的的地理位置已收到!";
|
||||
return new TextBuilder().build(content, wxMessage, null);
|
||||
} catch (Exception e) {
|
||||
this.logger.error("位置消息接收处理失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//上报地理位置事件
|
||||
this.logger.info("上报地理位置,纬度 : {},经度 : {},精度 : {}",
|
||||
wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision()));
|
||||
|
||||
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class LogHandler extends AbstractHandler {
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
//this.logger.info("\n接收到请求消息,内容:{}", JsonUtils.toJson(wxMessage));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
|
||||
|
||||
|
||||
@Component
|
||||
public class MenuHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService weixinService,
|
||||
WxSessionManager sessionManager) {
|
||||
|
||||
String msg = String.format("type:%s, event:%s, key:%s",
|
||||
wxMessage.getMsgType(), wxMessage.getEvent(),
|
||||
wxMessage.getEventKey());
|
||||
if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return WxMpXmlOutMessage.TEXT().content(msg)
|
||||
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import co.yixiang.mp.builder.TextBuilder;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||
|
||||
@Component
|
||||
public class MsgHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService weixinService,
|
||||
WxSessionManager sessionManager) {
|
||||
|
||||
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) {
|
||||
//TODO 可以选择将消息保存到本地
|
||||
}
|
||||
|
||||
//当用户输入关键词如“你好”,“客服”等,并且有客服在线时,把消息转发给在线客服
|
||||
try {
|
||||
if (StringUtils.startsWithAny(wxMessage.getContent(), "你好", "客服")
|
||||
&& weixinService.getKefuService().kfOnlineList()
|
||||
.getKfOnlineList().size() > 0) {
|
||||
return WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE()
|
||||
.fromUser(wxMessage.getToUser())
|
||||
.toUser(wxMessage.getFromUser()).build();
|
||||
}
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//TODO 组装回复消息
|
||||
String content = "yshop收到信息内容:" + wxMessage.getContent();
|
||||
|
||||
return new TextBuilder().build(content, wxMessage, weixinService);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class NullHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class RedisHandler{
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
public String getVal(String key) {
|
||||
try {
|
||||
String value = redisTemplate.opsForValue().get(key).toString();
|
||||
return value;
|
||||
}catch (Exception e){
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object getObj(String key) {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class ScanHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map,
|
||||
WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException {
|
||||
// 扫码事件处理
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门店审核事件处理
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class StoreCheckNotifyHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
// TODO 处理门店审核事件
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import co.yixiang.modules.wechat.domain.YxWechatReply;
|
||||
import co.yixiang.modules.wechat.service.YxWechatReplyService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
public class SubscribeHandler extends AbstractHandler {
|
||||
|
||||
@Autowired
|
||||
private YxWechatReplyService yxWechatReplyService;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService weixinService,
|
||||
WxSessionManager sessionManager) throws WxErrorException {
|
||||
|
||||
|
||||
String str = "你好,欢迎关注yshop!";
|
||||
YxWechatReply wechatReply = yxWechatReplyService.isExist("subscribe");
|
||||
if(!ObjectUtil.isNull(wechatReply)){
|
||||
str = JSONObject.parseObject(wechatReply.getData()).getString("content");
|
||||
}
|
||||
|
||||
try {
|
||||
WxMpXmlOutMessage msg= WxMpXmlOutMessage.TEXT()
|
||||
.content(str)
|
||||
.fromUser(wxMessage.getToUser())
|
||||
.toUser(wxMessage.getFromUser())
|
||||
.build();
|
||||
return msg;
|
||||
} catch (Exception e) {
|
||||
this.logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
public class UnsubscribeHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
String openId = wxMessage.getFromUser();
|
||||
this.logger.info("取消关注用户 OPENID: " + openId);
|
||||
// TODO 可以更新本地数据库为取消关注状态
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.mp.listener;
|
||||
|
||||
|
||||
import co.yixiang.event.TemplateBean;
|
||||
import co.yixiang.event.TemplateEvent;
|
||||
import co.yixiang.event.TemplateListenEnum;
|
||||
import co.yixiang.mp.service.WeixinPayService;
|
||||
import co.yixiang.mp.service.WeixinTemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.event.SmartApplicationListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author hupeng
|
||||
* 异步监听模板通知事件
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TemplateListener implements SmartApplicationListener {
|
||||
|
||||
@Autowired
|
||||
private WeixinTemplateService weixinTemplateService;
|
||||
@Autowired
|
||||
private WeixinPayService weixinPayService;
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> aClass) {
|
||||
return aClass == TemplateEvent.class;
|
||||
}
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||
//转换事件类型
|
||||
TemplateEvent templateEvent = (TemplateEvent) applicationEvent;
|
||||
//获取注册用户对象信息
|
||||
TemplateBean templateBean = templateEvent.getTemplateBean();
|
||||
log.info("模板事件类型:{}"+templateBean.getTemplateType());
|
||||
switch (TemplateListenEnum.toType(templateBean.getTemplateType())){
|
||||
case TYPE_1:
|
||||
weixinTemplateService.paySuccessNotice(templateBean.getOrderId()
|
||||
,templateBean.getPrice(),templateBean.getUid());
|
||||
break;
|
||||
case TYPE_2:
|
||||
//处理退款与消息
|
||||
BigDecimal bigDecimal = new BigDecimal("100");
|
||||
int payPrice = bigDecimal.multiply(new BigDecimal(templateBean.getPrice())).intValue();
|
||||
weixinPayService.refundOrder(templateBean.getOrderId(),payPrice);
|
||||
|
||||
weixinTemplateService.refundSuccessNotice(templateBean.getOrderId(),templateBean.getPrice(),
|
||||
templateBean.getUid(),templateBean.getTime());
|
||||
break;
|
||||
case TYPE_3:
|
||||
weixinTemplateService.deliverySuccessNotice(templateBean.getOrderId(),templateBean.getDeliveryName(),
|
||||
templateBean.getDeliveryId(),templateBean.getUid());
|
||||
break;
|
||||
case TYPE_4:
|
||||
weixinTemplateService.rechargeSuccessNotice(templateBean.getTime(),templateBean.getPrice(),
|
||||
templateBean.getUid());
|
||||
break;
|
||||
default:
|
||||
//todo
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.mp.service;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.api.BusinessException;
|
||||
import co.yixiang.api.YshopException;
|
||||
import co.yixiang.enums.*;
|
||||
import co.yixiang.modules.order.service.YxStoreOrderService;
|
||||
import co.yixiang.modules.order.vo.YxStoreOrderQueryVo;
|
||||
import co.yixiang.modules.user.domain.YxUser;
|
||||
import co.yixiang.modules.user.domain.YxUserRecharge;
|
||||
import co.yixiang.modules.user.service.YxUserRechargeService;
|
||||
import co.yixiang.modules.user.service.YxUserService;
|
||||
import co.yixiang.modules.user.service.dto.WechatUserDto;
|
||||
import co.yixiang.mp.config.WxPayConfiguration;
|
||||
import co.yixiang.mp.utils.YshopUtils;
|
||||
import co.yixiang.utils.RedisUtil;
|
||||
import co.yixiang.utils.RedisUtils;
|
||||
import co.yixiang.utils.ShopKeyUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @ClassName 微信支付WeixinPayService
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2020/6/27
|
||||
**/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WeixinPayService {
|
||||
|
||||
@Autowired
|
||||
private RedisUtils redisUtils;
|
||||
|
||||
@Autowired
|
||||
private YxUserService userService;
|
||||
@Autowired
|
||||
private YxStoreOrderService storeOrderService;
|
||||
@Autowired
|
||||
private YxUserRechargeService userRechargeService;
|
||||
|
||||
|
||||
/**
|
||||
* 统一支付入口
|
||||
* @param orderId 单号
|
||||
* @param from 来源
|
||||
* @param attach 备注 普通支付还是充值
|
||||
* @param body 内容
|
||||
* @return Object
|
||||
*/
|
||||
public Object unifyPay(String orderId, String from, String attach, String body) {
|
||||
long uid = 0;
|
||||
int payPrice = 0;
|
||||
BigDecimal bigDecimal = new BigDecimal(100);
|
||||
if(BillDetailEnum.TYPE_3.getValue().equals(attach)){ //普通支付
|
||||
YxStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(orderId,null);
|
||||
if(ObjectUtil.isNull(orderInfo)) throw new YshopException("订单不存在");
|
||||
if(orderInfo.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
|
||||
throw new YshopException("该订单已支付");
|
||||
}
|
||||
|
||||
if(orderInfo.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) throw new YshopException("该支付无需支付");
|
||||
|
||||
uid = orderInfo.getUid().intValue();
|
||||
payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();//计算分
|
||||
}else{ //充值
|
||||
YxUserRecharge userRecharge = userRechargeService.getOne(Wrappers.<YxUserRecharge>lambdaQuery()
|
||||
.eq(YxUserRecharge::getOrderId,orderId));
|
||||
if(userRecharge == null) throw new BusinessException("充值订单不存在");
|
||||
|
||||
if(userRecharge.getPaid().equals(OrderInfoEnum.PAY_STATUS_1.getValue())) {
|
||||
throw new YshopException("该订单已支付");
|
||||
}
|
||||
uid = userRecharge.getUid();
|
||||
payPrice = bigDecimal.multiply(userRecharge.getPrice()).intValue();
|
||||
}
|
||||
|
||||
|
||||
YxUser yxUser = userService.getById(uid);
|
||||
if(yxUser == null) throw new YshopException("用户错误");
|
||||
|
||||
|
||||
WechatUserDto wechatUserDto = YshopUtils.getWechtUser(yxUser.getWxProfile());
|
||||
|
||||
WxPayService wxPayService = null;
|
||||
if(AppFromEnum.ROUNTINE.getValue().equals(from)){
|
||||
wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WXAPP);
|
||||
}else if(AppFromEnum.APP.getValue().equals(from)){
|
||||
wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.APP);
|
||||
}else{
|
||||
wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
|
||||
}
|
||||
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
|
||||
orderRequest.setOutTradeNo(orderId);
|
||||
orderRequest.setTotalFee(payPrice);
|
||||
orderRequest.setSpbillCreateIp("127.0.0.1");
|
||||
orderRequest.setNotifyUrl(this.getApiUrl() + "/api/wechat/notify");
|
||||
orderRequest.setBody(body);
|
||||
orderRequest.setAttach(attach);
|
||||
|
||||
if(AppFromEnum.WEIXIN_H5.getValue().equals(from)){
|
||||
orderRequest.setTradeType("MWEB");
|
||||
}else if(AppFromEnum.APP.getValue().equals(from)){
|
||||
orderRequest.setTradeType("APP");
|
||||
} else{
|
||||
orderRequest.setTradeType("JSAPI");
|
||||
if(AppFromEnum.ROUNTINE.getValue().equals(from)){
|
||||
orderRequest.setOpenid(wechatUserDto.getRoutineOpenid());
|
||||
}else {
|
||||
orderRequest.setOpenid(wechatUserDto.getOpenid());
|
||||
}
|
||||
}
|
||||
try {
|
||||
return wxPayService.createOrder(orderRequest);
|
||||
}catch (WxPayException e) {
|
||||
log.info("支付错误信息:{}",e.getMessage());
|
||||
throw new BusinessException(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 退款
|
||||
* @param orderId orderId
|
||||
* @param totalFee totalFee 单位分
|
||||
*/
|
||||
public void refundOrder(String orderId, Integer totalFee) {
|
||||
|
||||
YxStoreOrderQueryVo orderInfo = storeOrderService.getOrderInfo(orderId,null);
|
||||
if(PayTypeEnum.YUE.getValue().equals(orderInfo.getPayType())) return;
|
||||
|
||||
WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
|
||||
WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
|
||||
|
||||
wxPayRefundRequest.setTotalFee(totalFee);//订单总金额
|
||||
wxPayRefundRequest.setOutTradeNo(orderId);
|
||||
wxPayRefundRequest.setOutRefundNo(orderId);
|
||||
wxPayRefundRequest.setRefundFee(totalFee);//退款金额
|
||||
wxPayRefundRequest.setNotifyUrl(this.getApiUrl() + "/api/notify/refund");
|
||||
|
||||
try {
|
||||
wxPayService.refund(wxPayRefundRequest);
|
||||
} catch (WxPayException e) {
|
||||
log.info("退款错误信息:{}",e.getMessage());
|
||||
throw new BusinessException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 企业打款
|
||||
* @param openid 微信openid
|
||||
* @param no 单号
|
||||
* @param userName 用户姓名
|
||||
* @param amount 金额
|
||||
* @throws WxPayException
|
||||
*/
|
||||
public void entPay(String openid,String no,String userName,Integer amount) throws WxPayException {
|
||||
WxPayService wxPayService = WxPayConfiguration.getPayService(PayMethodEnum.WECHAT);
|
||||
EntPayRequest entPayRequest = new EntPayRequest();
|
||||
|
||||
entPayRequest.setOpenid(openid);
|
||||
entPayRequest.setPartnerTradeNo(no);
|
||||
entPayRequest.setCheckName("FORCE_CHECK");
|
||||
entPayRequest.setReUserName(userName);
|
||||
entPayRequest.setAmount(amount);
|
||||
entPayRequest.setDescription("提现");
|
||||
entPayRequest.setSpbillCreateIp("127.0.0.1");
|
||||
wxPayService.getEntPayService().entPay(entPayRequest);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回H5 url
|
||||
* @return url
|
||||
*/
|
||||
private String getApiUrl(){
|
||||
String apiUrl = redisUtils.getY(ShopKeyUtils.getApiUrl());
|
||||
if(StrUtil.isBlank(apiUrl)){
|
||||
throw new YshopException("请配置移动端api地址");
|
||||
}
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.mp.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.api.YshopException;
|
||||
import co.yixiang.modules.user.domain.YxUser;
|
||||
import co.yixiang.modules.user.service.YxUserService;
|
||||
import co.yixiang.modules.user.service.dto.WechatUserDto;
|
||||
import co.yixiang.modules.wechat.domain.YxWechatTemplate;
|
||||
import co.yixiang.modules.wechat.service.YxWechatTemplateService;
|
||||
import co.yixiang.mp.config.WxMpConfiguration;
|
||||
import co.yixiang.mp.enums.WechatTempateEnum;
|
||||
import co.yixiang.mp.utils.YshopUtils;
|
||||
import co.yixiang.utils.RedisUtils;
|
||||
import co.yixiang.utils.ShopKeyUtils;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
|
||||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName 微信公众号模板通知
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2020/6/27
|
||||
**/
|
||||
@Service
|
||||
public class WeixinTemplateService {
|
||||
|
||||
@Autowired
|
||||
private RedisUtils redisUtils;
|
||||
|
||||
@Autowired
|
||||
private YxUserService userService;
|
||||
@Autowired
|
||||
private YxWechatTemplateService yxWechatTemplateService;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 充值成功通知
|
||||
* @param time 时间
|
||||
* @param price 金额
|
||||
* @param uid uid
|
||||
*/
|
||||
public void rechargeSuccessNotice(String time,String price,Long uid){
|
||||
String openid = this.getUserOpenid(uid);
|
||||
|
||||
if(StrUtil.isBlank(openid)) return;
|
||||
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("first","您的账户金币发生变动,详情如下:");
|
||||
map.put("keyword1","充值");
|
||||
map.put("keyword2",time);
|
||||
map.put("keyword3",price);
|
||||
map.put("remark","yshop为你服务!");
|
||||
String tempId = this.getTempId(WechatTempateEnum.RECHARGE_SUCCESS.getValue());
|
||||
this.sendWxMpTemplateMessage( openid, tempId, this.getSiteUrl()+"/user/account",map);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支付成功通知
|
||||
* @param orderId 订单号
|
||||
* @param price 金额
|
||||
* @param uid uid
|
||||
*/
|
||||
public void paySuccessNotice(String orderId,String price,Long uid){
|
||||
|
||||
String openid = this.getUserOpenid(uid);
|
||||
|
||||
if(StrUtil.isBlank(openid)) return;
|
||||
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("first","您的订单已支付成功,我们会尽快为您发货。");
|
||||
map.put("keyword1",orderId);//订单号
|
||||
map.put("keyword2",price);
|
||||
map.put("remark","yshop为你服务!");
|
||||
String tempId = this.getTempId(WechatTempateEnum.PAY_SUCCESS.getValue());
|
||||
this.sendWxMpTemplateMessage( openid,tempId, this.getSiteUrl()+"/order/detail/"+orderId,map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款成功通知
|
||||
* @param orderId 订单号
|
||||
* @param price 金额
|
||||
* @param uid uid
|
||||
* @param time 时间
|
||||
*/
|
||||
public void refundSuccessNotice(String orderId,String price,Long uid,String time){
|
||||
|
||||
String openid = this.getUserOpenid(uid);
|
||||
|
||||
if(StrUtil.isBlank(openid)) return;
|
||||
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("first","您的订单退款申请被通过,钱款将很快还至您的支付账户。");
|
||||
map.put("keyword1",orderId);//订单号
|
||||
map.put("keyword2",price);
|
||||
map.put("keyword3", time);
|
||||
map.put("remark","yshop为你服务!");
|
||||
String tempId = this.getTempId(WechatTempateEnum.REFUND_SUCCESS.getValue());
|
||||
this.sendWxMpTemplateMessage( openid,tempId, this.getSiteUrl()+"/order/detail/"+orderId,map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发货成功通知
|
||||
* @param orderId 单号
|
||||
* @param deliveryName 快递公司
|
||||
* @param deliveryId 快递单号
|
||||
* @param uid uid
|
||||
*/
|
||||
public void deliverySuccessNotice(String orderId,String deliveryName,
|
||||
String deliveryId,Long uid){
|
||||
|
||||
String openid = this.getUserOpenid(uid);
|
||||
|
||||
if(StrUtil.isEmpty(openid)) return;
|
||||
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("first","亲,宝贝已经启程了,好想快点来到你身边。");
|
||||
map.put("keyword2",deliveryName);
|
||||
map.put("keyword1",orderId);
|
||||
map.put("keyword3",deliveryId);
|
||||
map.put("remark","yshop为你服务!");
|
||||
String tempId = this.getTempId(WechatTempateEnum.DELIVERY_SUCCESS.getValue());
|
||||
this.sendWxMpTemplateMessage( openid,tempId, this.getSiteUrl()+"/order/detail/"+orderId,map);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建微信模板通知
|
||||
* @param openId 单号
|
||||
* @param templateId 模板id
|
||||
* @param url 跳转url
|
||||
* @param map map内容
|
||||
* @return String
|
||||
*/
|
||||
private String sendWxMpTemplateMessage(String openId, String templateId, String url, Map<String,String> map){
|
||||
WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
||||
.toUser(openId)
|
||||
.templateId(templateId)
|
||||
.url(url)
|
||||
.build();
|
||||
map.forEach( (k,v)-> { templateMessage.addData(new WxMpTemplateData(k, v, "#000000"));} );
|
||||
String msgId = null;
|
||||
WxMpService wxService = WxMpConfiguration.getWxMpService();
|
||||
try {
|
||||
msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return msgId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板消息id
|
||||
* @param key 模板key
|
||||
* @return string
|
||||
*/
|
||||
private String getTempId(String key){
|
||||
YxWechatTemplate yxWechatTemplate = yxWechatTemplateService.lambdaQuery()
|
||||
.eq(YxWechatTemplate::getTempkey,key)
|
||||
.one();
|
||||
if (yxWechatTemplate == null) throw new YshopException("请后台配置key:" + key + "模板消息id");
|
||||
|
||||
return yxWechatTemplate.getTempid();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回H5 url
|
||||
* @return url
|
||||
*/
|
||||
private String getSiteUrl(){
|
||||
String apiUrl = redisUtils.getY(ShopKeyUtils.getApiUrl());
|
||||
if(StrUtil.isBlank(apiUrl)){
|
||||
return "";
|
||||
}
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取openid
|
||||
* @param uid uid
|
||||
* @return String
|
||||
*/
|
||||
private String getUserOpenid(Long uid){
|
||||
YxUser yxUser = userService.getById(uid);
|
||||
if(yxUser == null) return "";
|
||||
if(StrUtil.isBlank(yxUser.getWxProfile())) return "";
|
||||
|
||||
WechatUserDto wechatUserDto = YshopUtils.getWechtUser(yxUser.getWxProfile());
|
||||
if(wechatUserDto == null) return "";
|
||||
if(StrUtil.isBlank(wechatUserDto.getOpenid())) return "";
|
||||
return wechatUserDto.getOpenid();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/**
|
||||
* @author Binary Wang(https://github.com/binarywang)
|
||||
*/
|
||||
public class JsonUtils {
|
||||
public static String toJson(Object obj) {
|
||||
Gson gson = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
}
|
81
yshop-weixin/src/main/java/co/yixiang/mp/utils/URLUtils.java
Normal file
81
yshop-weixin/src/main/java/co/yixiang/mp/utils/URLUtils.java
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.mp.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* URLUtils
|
||||
* @author Kevin
|
||||
* @date 2019-03-20 13:39
|
||||
*/
|
||||
public class URLUtils {
|
||||
|
||||
/**
|
||||
* 获取URL中的某个参数
|
||||
* @param url
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static String getParam(String url, String name) {
|
||||
return urlSplit(url).get( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉url中的路径,留下请求参数部分
|
||||
* @param strURL url地址
|
||||
* @return url请求参数部分
|
||||
*/
|
||||
private static String truncateUrlPage(String strURL){
|
||||
String strAllParam=null;
|
||||
String[] arrSplit=null;
|
||||
strURL=strURL.trim().toLowerCase();
|
||||
arrSplit=strURL.split("[?]");
|
||||
if(strURL.length()>1){
|
||||
if(arrSplit.length>1){
|
||||
for (int i=1;i<arrSplit.length;i++){
|
||||
strAllParam = arrSplit[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return strAllParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出url参数中的键值对
|
||||
* 如 "index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中
|
||||
* @param URL url地址
|
||||
* @return url请求参数部分
|
||||
*/
|
||||
public static Map<String, String> urlSplit(String URL){
|
||||
Map<String, String> mapRequest = new HashMap<String, String>();
|
||||
String[] arrSplit=null;
|
||||
String strUrlParam= truncateUrlPage(URL);
|
||||
if(strUrlParam==null){
|
||||
return mapRequest;
|
||||
}
|
||||
arrSplit=strUrlParam.split("[&]");
|
||||
for(String strSplit:arrSplit){
|
||||
String[] arrSplitEqual=null;
|
||||
arrSplitEqual= strSplit.split("[=]");
|
||||
//解析出键值
|
||||
if(arrSplitEqual.length>1){
|
||||
//正确解析
|
||||
mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
|
||||
}else{
|
||||
if(arrSplitEqual[0]!=""){
|
||||
//只有参数没有值,不加入
|
||||
mapRequest.put(arrSplitEqual[0], "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapRequest;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2020
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.mp.utils;
|
||||
|
||||
|
||||
import co.yixiang.modules.user.service.dto.WechatUserDto;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* @ClassName YshopUtils
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2020/6/27
|
||||
**/
|
||||
public class YshopUtils {
|
||||
public static WechatUserDto getWechtUser(String str) {
|
||||
return JSONObject.parseObject(str,WechatUserDto.class);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user