@@ -31,10 +31,24 @@
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>javax.mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.qcloudsms</groupId>
|
||||
<artifactId>qcloudsms</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 异步线程池,用于异步发送通知
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
@EnableAsync
|
||||
class ExecutorConfig {
|
||||
|
||||
@Value("${spring.notify.corePoolSize}")
|
||||
private int corePoolSize;
|
||||
@Value("${spring.notify.maxPoolSize}")
|
||||
private int maxPoolSize;
|
||||
@Value("${spring.notify.queueCapacity}")
|
||||
private int queueCapacity;
|
||||
|
||||
@Bean(name = "nofityAsync")
|
||||
public Executor nofityAsync() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(corePoolSize);
|
||||
executor.setMaxPoolSize(maxPoolSize);
|
||||
executor.setQueueCapacity(queueCapacity);
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
executor.setThreadNamePrefix("NotifyExecutor-");
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Litemall商城通知服务类
|
||||
*/
|
||||
@PropertySource(value = "classpath:notify.properties")
|
||||
@Service("litemallNotifyService")
|
||||
public class LitemallNotifyService {
|
||||
@Autowired
|
||||
MailSendService mailSendService;
|
||||
@Autowired
|
||||
SMSSendService smsSendService;
|
||||
@Autowired
|
||||
Environment environment;
|
||||
|
||||
@Value("${sprint.mail.enable}")
|
||||
private boolean sendMailEnable;
|
||||
@Value("${spring.sms.enable}")
|
||||
private boolean sendSMSEnable;
|
||||
|
||||
public void notifySMSMessage(String phoneNumber,String message) {
|
||||
if (!sendSMSEnable)
|
||||
return;
|
||||
|
||||
smsSendService.sendSMS(phoneNumber, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信模版通知
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
|
||||
*/
|
||||
public void notifySMSTemplate(String phoneNumber, String[] params, NotifyUtils.NotifyType notifyType) {
|
||||
if (!sendSMSEnable)
|
||||
return;
|
||||
|
||||
int templateId = -1;
|
||||
switch (notifyType) {
|
||||
case PAY_COMPLATED:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.pay.complated"));
|
||||
break;
|
||||
case VERIFICATIONCODE:
|
||||
templateId = Integer.parseInt(environment.getProperty("spring.sms.template.verificationcode"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (templateId != -1)
|
||||
smsSendService.sendSMSWithTemplate(phoneNumber, templateId, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件通知,接收者在spring.mail.sendto中指定
|
||||
* @param setSubject 邮件标题
|
||||
* @param setText 邮件内容
|
||||
*/
|
||||
public void notifyMailMessage(String setSubject, String setText) {
|
||||
if(!sendMailEnable)
|
||||
return;
|
||||
|
||||
mailSendService.sendEmail(setSubject, setText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
@PropertySource(value = "classpath:notify.properties")
|
||||
@Service("mailSendService")
|
||||
class MailSendService {
|
||||
@Resource
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@Value("${spring.mail.username}")
|
||||
private String from;
|
||||
|
||||
@Value("${spring.mail.sendto}")
|
||||
private String sendto;
|
||||
|
||||
/**
|
||||
* 异步发送邮件通知
|
||||
* @param setSubject 邮件标题
|
||||
* @param setText 邮件内容
|
||||
*/
|
||||
@Async("nofityAsync")
|
||||
public void sendEmail(String setSubject, String setText) {
|
||||
try {
|
||||
final MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
|
||||
|
||||
message.setFrom(from);
|
||||
message.setTo(sendto);
|
||||
message.setSubject(setSubject);
|
||||
message.setText(setText);
|
||||
mailSender.send(mimeMessage);
|
||||
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
public class NotifyUtils {
|
||||
/**
|
||||
* 该枚举定义了所有的需要通知的事件,调用通知时作为参数
|
||||
*/
|
||||
public enum NotifyType {
|
||||
PAY_COMPLATED, REGISTER, VERIFICATIONCODE,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
import com.github.qcloudsms.SmsSingleSender;
|
||||
import com.github.qcloudsms.SmsSingleSenderResult;
|
||||
import com.github.qcloudsms.httpclient.HTTPException;
|
||||
import org.json.JSONException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@PropertySource(value = "classpath:notify.properties")
|
||||
@Service("smsSendService")
|
||||
class SMSSendService {
|
||||
@Value("${spring.sms.appid}")
|
||||
private int appid;
|
||||
|
||||
@Value("${spring.sms.appkey}")
|
||||
private String appkey;
|
||||
|
||||
@Value("${spring.sms.sign}")
|
||||
private String smsSign;
|
||||
|
||||
@Async("nofityAsync")
|
||||
public void sendSMS(String phoneNumber, String content) {
|
||||
try {
|
||||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
|
||||
SmsSingleSenderResult result = ssender.send(0, "86", phoneNumber,
|
||||
content, "", "");
|
||||
|
||||
System.out.println(result);
|
||||
} catch (HTTPException e) {
|
||||
// HTTP响应码错误
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
// json解析错误
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// 网络IO错误
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Async("nofityAsync")
|
||||
public void sendSMSWithTemplate(String phoneNumber, int templateId, String[] params) {
|
||||
try {
|
||||
SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
|
||||
SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber,
|
||||
templateId, params, smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
|
||||
System.out.println(result);
|
||||
} catch (HTTPException e) {
|
||||
// HTTP响应码错误
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
// json解析错误
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// 网络IO错误
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package org.linlinjava.litemall.core.notify;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ConnectException;
|
||||
import java.net.URL;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* 微信模版消息通知,未完成
|
||||
*/
|
||||
@PropertySource(value = "classpath:notify.properties")
|
||||
@Service("wxTemplateMsgSendService")
|
||||
public class WXTemplateMsgSendService {
|
||||
/**
|
||||
* 发送微信消息(模板消息)
|
||||
*
|
||||
* @param touser 用户 OpenID
|
||||
* @param templatId 模板消息ID
|
||||
* @param formId payId或者表单ID
|
||||
* @param clickurl URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
|
||||
* @param topcolor 标题颜色
|
||||
* @param data 详细内容
|
||||
* @return
|
||||
*/
|
||||
public String sendWechatMsgToUser(String token, String touser, String templatId, String formId, String clickurl, String topcolor, JSONObject data) {
|
||||
String tmpurl = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + token;
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("touser", touser);
|
||||
json.put("template_id", templatId);
|
||||
json.put("form_id", formId);
|
||||
json.put("url", clickurl);
|
||||
json.put("topcolor", topcolor);
|
||||
json.put("data", data);
|
||||
try {
|
||||
JSONObject result = httpsRequest(tmpurl, "POST", json.toString());
|
||||
// log.info("发送微信消息返回信息:" + resultJson.get("errcode"));
|
||||
String errmsg = (String) result.get("errmsg");
|
||||
if (!"ok".equals(errmsg)) { //如果为errmsg为ok,则代表发送成功,公众号推送信息给用户了。
|
||||
return "error";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "error";
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送https请求
|
||||
*
|
||||
* @param requestUrl 请求地址
|
||||
* @param requestMethod 请求方式(GET、POST)
|
||||
* @param outputStr 提交的数据
|
||||
* @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)
|
||||
*/
|
||||
private JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
|
||||
JSONObject jsonObject = null;
|
||||
try {
|
||||
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
|
||||
TrustManager[] tm = {new MyX509TrustManager()};
|
||||
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
|
||||
sslContext.init(null, tm, new SecureRandom());
|
||||
// 从上述SSLContext对象中得到SSLSocketFactory对象
|
||||
SSLSocketFactory ssf = sslContext.getSocketFactory();
|
||||
URL url = new URL(requestUrl);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||
conn.setSSLSocketFactory(ssf);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setUseCaches(false);
|
||||
// 设置请求方式(GET/POST)
|
||||
conn.setRequestMethod(requestMethod);
|
||||
// 当outputStr不为null时向输出流写数据
|
||||
if (null != outputStr) {
|
||||
OutputStream outputStream = conn.getOutputStream();
|
||||
// 注意编码格式
|
||||
outputStream.write(outputStr.getBytes("UTF-8"));
|
||||
outputStream.close();
|
||||
}
|
||||
// 从输入流读取返回内容
|
||||
InputStream inputStream = conn.getInputStream();
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
|
||||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
|
||||
String str = null;
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
while ((str = bufferedReader.readLine()) != null) {
|
||||
buffer.append(str);
|
||||
}
|
||||
// 释放资源
|
||||
bufferedReader.close();
|
||||
inputStreamReader.close();
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
conn.disconnect();
|
||||
jsonObject = new JSONObject(buffer.toString());
|
||||
} catch (ConnectException ce) {
|
||||
// log.error("连接超时:{}", ce);
|
||||
} catch (Exception e) {
|
||||
// log.error("https请求异常:{}", e);
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信请求 - 信任管理器
|
||||
*/
|
||||
private class MyX509TrustManager implements X509TrustManager {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
// return new X509Certificate[0];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.linlinjava.litemall.core.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class MailUtils {
|
||||
private static final Log logger = LogFactory.getLog(MailUtils.class);
|
||||
private static MailUtils mailUtils;
|
||||
|
||||
private JavaMailSenderImpl mailSender;
|
||||
|
||||
// TODO 邮箱相关后置后续应移到数据库,在后台配置完成,暂时先完成功能
|
||||
// 通知邮件送达地址
|
||||
private static final String SEND_TO = "ex@qq.com";
|
||||
|
||||
private MailUtils() {
|
||||
mailSender = new JavaMailSenderImpl();
|
||||
// 配置发送邮箱设置,请按照自己邮箱填写
|
||||
mailSender.setHost("smtp.exmail.qq.com");
|
||||
mailSender.setUsername("ex@ex.com.cn");
|
||||
mailSender.setPassword("ex");
|
||||
mailSender.setDefaultEncoding("UTF-8");
|
||||
}
|
||||
|
||||
public static MailUtils getMailUtils() {
|
||||
if (mailUtils == null)
|
||||
mailUtils = new MailUtils();
|
||||
|
||||
return mailUtils;
|
||||
}
|
||||
|
||||
public boolean sendEmail(String setSubject, String setText) {
|
||||
try {
|
||||
final MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
|
||||
message.setFrom(mailSender.getUsername());
|
||||
message.setTo(SEND_TO);
|
||||
message.setSubject(setSubject);
|
||||
message.setText(setText);
|
||||
mailSender.send(mimeMessage);
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
logger.error("通知邮件发送出错" + ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
spring.profiles.active=dev
|
||||
spring.profiles.active=dev
|
||||
spring.message.encoding = UTF-8
|
||||
22
litemall-core/src/main/resources/notify.properties
Normal file
22
litemall-core/src/main/resources/notify.properties
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
#\u90AE\u4EF6\u53D1\u9001\u914D\u7F6E
|
||||
sprint.mail.enable=false
|
||||
spring.mail.host=smtp.exmail.qq.com
|
||||
spring.mail.username=ex@ex.com.cn
|
||||
spring.mail.password=
|
||||
spring.mail.sendto=ex@qq.com
|
||||
|
||||
#\u77ED\u4FE1\u53D1\u9001\u914D\u7F6E
|
||||
spring.sms.enable=false
|
||||
spring.sms.appid=
|
||||
spring.sms.appkey=
|
||||
spring.sms.sign=
|
||||
|
||||
#\u77ED\u4FE1\u6A21\u7248\u6D88\u606F\u914D\u7F6E\uFF0C\u8BF7\u5728\u817E\u8BAF\u77ED\u4FE1\u5E73\u53F0\u914D\u7F6E\u597D\u5404\u4E2A\u901A\u77E5\u6D88\u606F\u7684\u6A21\u7248\uFF0C\u7136\u540E\u5C06\u6A21\u7248ID\u4E00\u4E00\u8D4B\u503C,LitemallNotifyService,NotifyType\u679A\u4E3E\u4E2D\u4E0E\u8FD9\u91CC\u4E00\u4E00\u5BF9\u5E94
|
||||
spring.sms.template.pay.complated=156349
|
||||
spring.sms.template.verificationcode=156433
|
||||
|
||||
#\u53D1\u9001\u7EBF\u7A0B\u6C60\u914D\u7F6E
|
||||
spring.notify.corePoolSize=5
|
||||
spring.notify.maxPoolSize=100
|
||||
spring.notify.queueCapacity=50
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.linlinjava</groupId>
|
||||
<artifactId>litemall-core</artifactId>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.linlinjava.litemall.wx.util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class IpUtil {
|
||||
public static String client(HttpServletRequest request) {
|
||||
@@ -10,4 +12,42 @@ public class IpUtil {
|
||||
}
|
||||
return xff;
|
||||
}
|
||||
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ipAddress = null;
|
||||
try {
|
||||
ipAddress = request.getHeader("x-forwarded-for");
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getRemoteAddr();
|
||||
if (ipAddress.equals("127.0.0.1")) {
|
||||
// 根据网卡取本机配置的IP
|
||||
InetAddress inet = null;
|
||||
try {
|
||||
inet = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ipAddress = inet.getHostAddress();
|
||||
}
|
||||
}
|
||||
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
|
||||
if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
|
||||
// = 15
|
||||
if (ipAddress.indexOf(",") > 0) {
|
||||
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ipAddress="";
|
||||
}
|
||||
// ipAddress = this.getRequest().getRemoteAddr();
|
||||
|
||||
return ipAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,24 @@ package org.linlinjava.litemall.wx.web;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
|
||||
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
|
||||
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
|
||||
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
|
||||
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
|
||||
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
|
||||
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.linlinjava.litemall.core.notify.LitemallNotifyService;
|
||||
import org.linlinjava.litemall.core.notify.NotifyUtils;
|
||||
import org.linlinjava.litemall.core.util.JacksonUtil;
|
||||
import org.linlinjava.litemall.core.util.ResponseUtil;
|
||||
import org.linlinjava.litemall.db.domain.*;
|
||||
import org.linlinjava.litemall.db.service.*;
|
||||
import org.linlinjava.litemall.db.util.OrderHandleOption;
|
||||
import org.linlinjava.litemall.db.util.OrderUtil;
|
||||
import org.linlinjava.litemall.core.util.JacksonUtil;
|
||||
import org.linlinjava.litemall.core.util.ResponseUtil;
|
||||
import org.linlinjava.litemall.wx.annotation.LoginUser;
|
||||
import org.linlinjava.litemall.wx.util.IpUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
@@ -81,6 +81,9 @@ public class WxOrderController {
|
||||
@Autowired
|
||||
private WxPayService wxPayService;
|
||||
|
||||
@Autowired
|
||||
private LitemallNotifyService litemallNotifyService;
|
||||
|
||||
public WxOrderController() {
|
||||
}
|
||||
|
||||
@@ -290,7 +293,7 @@ public class WxOrderController {
|
||||
// 根据订单商品总价计算运费,满88则免运费,否则8元;
|
||||
BigDecimal freightPrice = new BigDecimal(0.00);
|
||||
if (checkedGoodsPrice.compareTo(new BigDecimal(88.00)) < 0) {
|
||||
freightPrice = new BigDecimal(8.00);
|
||||
freightPrice = new BigDecimal(0.00);
|
||||
}
|
||||
|
||||
// 可以使用的其他钱,例如用户积分
|
||||
@@ -440,7 +443,7 @@ public class WxOrderController {
|
||||
|
||||
/**
|
||||
* 付款订单的预支付会话标识
|
||||
*
|
||||
* <p>
|
||||
* 1. 检测当前订单是否能够付款
|
||||
* 2. 微信支付平台返回支付订单ID
|
||||
* 3. 设置订单付款状态
|
||||
@@ -452,8 +455,8 @@ public class WxOrderController {
|
||||
* 失败则 { errno: XXX, errmsg: XXX }
|
||||
*/
|
||||
@PostMapping("prepay")
|
||||
public Object prepay(@LoginUser Integer userId, @RequestBody String body) {
|
||||
if(userId == null){
|
||||
public Object prepay(@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) {
|
||||
if (userId == null) {
|
||||
return ResponseUtil.unlogin();
|
||||
}
|
||||
Integer orderId = JacksonUtil.parseInteger(body, "orderId");
|
||||
@@ -477,7 +480,7 @@ public class WxOrderController {
|
||||
|
||||
LitemallUser user = userService.findById(userId);
|
||||
String openid = user.getWeixinOpenid();
|
||||
if(openid == null){
|
||||
if (openid == null) {
|
||||
return ResponseUtil.fail(403, "订单不能支付");
|
||||
}
|
||||
WxPayMpOrderResult result = null;
|
||||
@@ -486,16 +489,16 @@ public class WxOrderController {
|
||||
orderRequest.setOutTradeNo(order.getOrderSn());
|
||||
orderRequest.setOpenid(openid);
|
||||
// TODO 更有意义的显示名称
|
||||
orderRequest.setBody("litemall小商场-订单测试支付");
|
||||
orderRequest.setBody("订单:" + order.getOrderSn());
|
||||
// 元转成分
|
||||
Integer fee = 1;
|
||||
Integer fee = 0;
|
||||
// 这里演示仅支付1分
|
||||
// 实际项目取消下面两行注释
|
||||
// BigDecimal actualPrice = order.getActualPrice();
|
||||
// fee = actualPrice.multiply(new BigDecimal(100)).intValue();
|
||||
BigDecimal actualPrice = order.getActualPrice();
|
||||
fee = actualPrice.multiply(new BigDecimal(100)).intValue();
|
||||
orderRequest.setTotalFee(fee);
|
||||
// TODO 用户IP地址
|
||||
orderRequest.setSpbillCreateIp("123.12.12.123");
|
||||
orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));
|
||||
|
||||
result = wxPayService.createOrder(orderRequest);
|
||||
} catch (Exception e) {
|
||||
@@ -518,7 +521,7 @@ public class WxOrderController {
|
||||
* @return 订单操作结果
|
||||
* 成功则 WxPayNotifyResponse.success的XML内容
|
||||
* 失败则 WxPayNotifyResponse.fail的XML内容
|
||||
*
|
||||
* <p>
|
||||
* 注意,这里pay-notify是示例地址,开发者应该设立一个隐蔽的回调地址
|
||||
*/
|
||||
@PostMapping("pay-notify")
|
||||
@@ -533,19 +536,19 @@ public class WxOrderController {
|
||||
String totalFee = BaseWxPayResult.feeToYuan(result.getTotalFee());
|
||||
|
||||
LitemallOrder order = orderService.findBySn(orderSn);
|
||||
if(order == null){
|
||||
if (order == null) {
|
||||
throw new Exception("订单不存在 sn=" + orderSn);
|
||||
}
|
||||
|
||||
// 检查这个订单是否已经处理过
|
||||
if(OrderUtil.isPayStatus(order) && order.getPayId() != null){
|
||||
if (OrderUtil.isPayStatus(order) && order.getPayId() != null) {
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
}
|
||||
|
||||
// 检查支付订单金额
|
||||
// TODO 这里1分钱需要改成实际订单金额
|
||||
if(!totalFee.equals("0.01")){
|
||||
throw new Exception("支付金额不符合 totalFee=" + totalFee);
|
||||
if (!totalFee.equals(order.getActualPrice().toString())) {
|
||||
throw new Exception(order.getOrderSn() + " : 支付金额不符合 totalFee=" + totalFee);
|
||||
}
|
||||
|
||||
order.setPayId(payId);
|
||||
@@ -553,6 +556,10 @@ public class WxOrderController {
|
||||
order.setOrderStatus(OrderUtil.STATUS_PAY);
|
||||
orderService.updateById(order);
|
||||
|
||||
//TODO 发送邮件和短信通知,这里采用异步发送
|
||||
litemallNotifyService.notifyMailMessage("订单通知", order.toString());
|
||||
litemallNotifyService.notifySMSTemplate(order.getMobile(), new String[]{""}, NotifyUtils.NotifyType.PAY_COMPLATED);
|
||||
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
} catch (Exception e) {
|
||||
logger.error("微信回调结果异常,异常原因 " + e.getMessage());
|
||||
@@ -560,7 +567,6 @@ public class WxOrderController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 订单申请退款
|
||||
* 1. 检测当前订单是否能够退款
|
||||
@@ -714,5 +720,4 @@ public class WxOrderController {
|
||||
LitemallOrderGoods orderGoods = orderGoodsList.get(0);
|
||||
return ResponseUtil.ok(orderGoods);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user