1.新增邮件,阿里,腾讯短信调用接口
2.新增微信模板通知,目前通知接口都是同步调用 3.添加redisson,延迟消息队列,超时订单自动取消
This commit is contained in:
5
pom.xml
5
pom.xml
@ -196,6 +196,11 @@
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.11.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -99,6 +99,21 @@
|
||||
<!-- <version>3.1.0</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
<version>4.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.qcloudsms</groupId>
|
||||
<artifactId>qcloudsms</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-miniapp</artifactId>
|
||||
<version>3.3.1.B</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -3,6 +3,11 @@ package co.yixiang.common.constant;
|
||||
|
||||
public interface CommonConstant {
|
||||
|
||||
|
||||
/**
|
||||
* 订单超时未支付时间 默认30分钟
|
||||
*/
|
||||
Long ORDER_OUTTIME_UNPAY = 1000* 1800L;
|
||||
/**
|
||||
* 默认页码为1
|
||||
*/
|
||||
|
||||
225
yshop-api/src/main/java/co/yixiang/config/NotifyProperties.java
Normal file
225
yshop-api/src/main/java/co/yixiang/config/NotifyProperties.java
Normal file
@ -0,0 +1,225 @@
|
||||
package co.yixiang.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ConfigurationProperties(prefix = "yshop.notify")
|
||||
public class NotifyProperties {
|
||||
private Mail mail;
|
||||
private Sms sms;
|
||||
private Wx wx;
|
||||
|
||||
public Mail getMail() {
|
||||
return mail;
|
||||
}
|
||||
|
||||
public void setMail(Mail mail) {
|
||||
this.mail = mail;
|
||||
}
|
||||
|
||||
public Sms getSms() {
|
||||
return sms;
|
||||
}
|
||||
|
||||
public void setSms(Sms sms) {
|
||||
this.sms = sms;
|
||||
}
|
||||
|
||||
public Wx getWx() {
|
||||
return wx;
|
||||
}
|
||||
|
||||
public void setWx(Wx wx) {
|
||||
this.wx = wx;
|
||||
}
|
||||
|
||||
public static class Mail {
|
||||
private boolean enable;
|
||||
private String host;
|
||||
private String username;
|
||||
private String password;
|
||||
private String sendfrom;
|
||||
private String sendto;
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getSendfrom() {
|
||||
return sendfrom;
|
||||
}
|
||||
|
||||
public void setSendfrom(String sendfrom) {
|
||||
this.sendfrom = sendfrom;
|
||||
}
|
||||
|
||||
public String getSendto() {
|
||||
return sendto;
|
||||
}
|
||||
|
||||
public void setSendto(String sendto) {
|
||||
this.sendto = sendto;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Sms {
|
||||
private boolean enable;
|
||||
private String active;
|
||||
private String sign;
|
||||
private Tencent tencent;
|
||||
private Aliyun aliyun;
|
||||
private List<Map<String, String>> template = new ArrayList<>();
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(List<Map<String, String>> template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public String getActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(String active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public Tencent getTencent() {
|
||||
return tencent;
|
||||
}
|
||||
|
||||
public void setTencent(Tencent tencent) {
|
||||
this.tencent = tencent;
|
||||
}
|
||||
|
||||
public Aliyun getAliyun() {
|
||||
return aliyun;
|
||||
}
|
||||
|
||||
public void setAliyun(Aliyun aliyun) {
|
||||
this.aliyun = aliyun;
|
||||
}
|
||||
|
||||
public static class Tencent {
|
||||
private int appid;
|
||||
private String appkey;
|
||||
|
||||
public int getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(int appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getAppkey() {
|
||||
return appkey;
|
||||
}
|
||||
|
||||
public void setAppkey(String appkey) {
|
||||
this.appkey = appkey;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Aliyun {
|
||||
private String regionId;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
|
||||
public String getRegionId() {
|
||||
return regionId;
|
||||
}
|
||||
|
||||
public void setRegionId(String regionId) {
|
||||
this.regionId = regionId;
|
||||
}
|
||||
|
||||
public String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
public void setAccessKeyId(String accessKeyId) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public String getAccessKeySecret() {
|
||||
return accessKeySecret;
|
||||
}
|
||||
|
||||
public void setAccessKeySecret(String accessKeySecret) {
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Wx {
|
||||
private boolean enable;
|
||||
private List<Map<String, String>> template = new ArrayList<>();
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(List<Map<String, String>> template) {
|
||||
this.template = template;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
import co.yixiang.utils.JacksonUtil;
|
||||
import com.aliyuncs.CommonRequest;
|
||||
import com.aliyuncs.CommonResponse;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.aliyuncs.exceptions.ServerException;
|
||||
import com.aliyuncs.http.MethodType;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* 阿里云短信服务
|
||||
*/
|
||||
public class AliyunSmsSender implements SmsSender {
|
||||
private final Log logger = LogFactory.getLog(AliyunSmsSender.class);
|
||||
|
||||
private String regionId;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String sign;
|
||||
|
||||
public String getRegionId() {
|
||||
return regionId;
|
||||
}
|
||||
|
||||
public void setRegionId(String regionId) {
|
||||
this.regionId = regionId;
|
||||
}
|
||||
|
||||
public String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
public void setAccessKeyId(String accessKeyId) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public String getAccessKeySecret() {
|
||||
return accessKeySecret;
|
||||
}
|
||||
|
||||
public void setAccessKeySecret(String accessKeySecret) {
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResult send(String phone, String content) {
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(false);
|
||||
return smsResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
|
||||
DefaultProfile profile = DefaultProfile.getProfile(this.regionId, this.accessKeyId, this.accessKeySecret);
|
||||
IAcsClient client = new DefaultAcsClient(profile);
|
||||
|
||||
CommonRequest request = new CommonRequest();
|
||||
request.setMethod(MethodType.POST);
|
||||
request.setDomain("dysmsapi.aliyuncs.com");
|
||||
request.setVersion("2017-05-25");
|
||||
request.setAction("SendSms");
|
||||
request.putQueryParameter("RegionId", this.regionId);
|
||||
request.putQueryParameter("PhoneNumbers", phone);
|
||||
request.putQueryParameter("SignName", this.sign);
|
||||
request.putQueryParameter("TemplateCode", templateId);
|
||||
/*
|
||||
NOTE:阿里云短信和腾讯云短信这里存在不一致
|
||||
腾讯云短信模板参数是数组,因此短信模板形式如 “短信参数{1}, 短信参数{2}”
|
||||
阿里云短信模板参数是JSON,因此短信模板形式如“短信参数{param1}, 短信参数{param2}”
|
||||
为了保持统一,我们假定阿里云短信里面的参数是code,code1,code2...
|
||||
|
||||
如果开发者在阿里云短信申请的模板参数是其他命名,请开发者自行调整这里的代码,或者直接写死。
|
||||
*/
|
||||
String templateParam = "{}";
|
||||
if(params.length == 1){
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("code", params[0]);
|
||||
templateParam = JacksonUtil.toJson(data);
|
||||
}
|
||||
else if(params.length > 1){
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("code", params[0]);
|
||||
for(int i = 1; i < params.length; i++){
|
||||
data.put("code" + i, params[i]);
|
||||
}
|
||||
templateParam = JacksonUtil.toJson(data);
|
||||
}
|
||||
request.putQueryParameter("TemplateParam", templateParam);
|
||||
|
||||
try {
|
||||
CommonResponse response = client.getCommonResponse(request);
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(true);
|
||||
smsResult.setResult(response);
|
||||
return smsResult;
|
||||
} catch (ServerException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClientException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(false);
|
||||
return smsResult;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
import org.springframework.mail.MailSender;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商城通知服务类
|
||||
*/
|
||||
public class NotifyService {
|
||||
private MailSender mailSender;
|
||||
private String sendFrom;
|
||||
private String sendTo;
|
||||
|
||||
private SmsSender smsSender;
|
||||
private List<Map<String, String>> smsTemplate = new ArrayList<>();
|
||||
|
||||
private List<Map<String, String>> wxTemplate = new ArrayList<>();
|
||||
|
||||
public boolean isMailEnable() {
|
||||
return mailSender != null;
|
||||
}
|
||||
|
||||
public boolean isSmsEnable() {
|
||||
return smsSender != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 短信消息通知
|
||||
*
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param message 短消息内容,这里短消息内容必须已经在短信平台审核通过
|
||||
*/
|
||||
@Async
|
||||
public void notifySms(String phoneNumber, String message) {
|
||||
if (smsSender == null)
|
||||
return;
|
||||
|
||||
smsSender.send(phoneNumber, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信模版消息通知
|
||||
*
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
*/
|
||||
@Async
|
||||
public void notifySmsTemplate(String phoneNumber, NotifyType notifyType, String[] params) {
|
||||
if (smsSender == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String templateIdStr = getTemplateId(notifyType, smsTemplate);
|
||||
if (templateIdStr == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
smsSender.sendWithTemplate(phoneNumber, templateIdStr, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以同步的方式发送短信模版消息通知
|
||||
*
|
||||
* @param phoneNumber 接收通知的电话号码
|
||||
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
* @return
|
||||
*/
|
||||
public SmsResult notifySmsTemplateSync(String phoneNumber, NotifyType notifyType, String[] params) {
|
||||
if (smsSender == null)
|
||||
return null;
|
||||
|
||||
return smsSender.sendWithTemplate(phoneNumber, getTemplateId(notifyType, smsTemplate), params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 邮件消息通知,
|
||||
* 接收者在spring.mail.sendto中指定
|
||||
*
|
||||
* @param subject 邮件标题
|
||||
* @param content 邮件内容
|
||||
*/
|
||||
@Async
|
||||
public void notifyMail(String subject, String content) {
|
||||
if (mailSender == null)
|
||||
return;
|
||||
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(sendFrom);
|
||||
message.setTo(sendTo);
|
||||
message.setSubject(subject);
|
||||
message.setText(content);
|
||||
mailSender.send(message);
|
||||
}
|
||||
|
||||
private String getTemplateId(NotifyType notifyType, List<Map<String, String>> values) {
|
||||
for (Map<String, String> item : values) {
|
||||
String notifyTypeStr = notifyType.getType();
|
||||
|
||||
if (item.get("name").equals(notifyTypeStr))
|
||||
return item.get("templateId");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setMailSender(MailSender mailSender) {
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
public void setSendFrom(String sendFrom) {
|
||||
this.sendFrom = sendFrom;
|
||||
}
|
||||
|
||||
public void setSendTo(String sendTo) {
|
||||
this.sendTo = sendTo;
|
||||
}
|
||||
|
||||
public void setSmsSender(SmsSender smsSender) {
|
||||
this.smsSender = smsSender;
|
||||
}
|
||||
|
||||
public void setSmsTemplate(List<Map<String, String>> smsTemplate) {
|
||||
this.smsTemplate = smsTemplate;
|
||||
}
|
||||
|
||||
public void setWxTemplate(List<Map<String, String>> wxTemplate) {
|
||||
this.wxTemplate = wxTemplate;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
public enum NotifyType {
|
||||
PAY_SUCCEED("paySucceed"),
|
||||
SHIP("ship"),
|
||||
REFUND("refund"),
|
||||
CAPTCHA("captcha");
|
||||
|
||||
private String type;
|
||||
|
||||
NotifyType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
/**
|
||||
* 发送短信的返回结果
|
||||
*/
|
||||
public class SmsResult {
|
||||
private boolean successful;
|
||||
private Object result;
|
||||
|
||||
/**
|
||||
* 短信是否发送成功
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSuccessful() {
|
||||
return successful;
|
||||
}
|
||||
|
||||
public void setSuccessful(boolean successful) {
|
||||
this.successful = successful;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
public interface SmsSender {
|
||||
|
||||
/**
|
||||
* 发送短信息
|
||||
*
|
||||
* @param phone 接收通知的电话号码
|
||||
* @param content 短消息内容
|
||||
*/
|
||||
SmsResult send(String phone, String content);
|
||||
|
||||
|
||||
/**
|
||||
* 通过短信模版发送短信息
|
||||
* @param phone 接收通知的电话号码
|
||||
* @param templateId 通知模板ID
|
||||
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
|
||||
*/
|
||||
SmsResult sendWithTemplate(String phone, String templateId, String[] params);
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package co.yixiang.modules.notify;
|
||||
|
||||
import com.github.qcloudsms.SmsSingleSender;
|
||||
import com.github.qcloudsms.SmsSingleSenderResult;
|
||||
import com.github.qcloudsms.httpclient.HTTPException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* 腾讯云短信服务
|
||||
*/
|
||||
public class TencentSmsSender implements SmsSender {
|
||||
private final Log logger = LogFactory.getLog(TencentSmsSender.class);
|
||||
|
||||
private SmsSingleSender sender;
|
||||
private String sign;
|
||||
|
||||
public SmsSingleSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(SmsSingleSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResult send(String phone, String content) {
|
||||
try {
|
||||
SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", "");
|
||||
logger.debug(result);
|
||||
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(true);
|
||||
smsResult.setResult(result);
|
||||
return smsResult;
|
||||
} catch (HTTPException | IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(false);
|
||||
return smsResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
|
||||
try {
|
||||
SmsSingleSenderResult result = sender.sendWithParam("86", phone, Integer.parseInt(templateId), params, this.sign, "", "");
|
||||
logger.debug(result);
|
||||
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(true);
|
||||
smsResult.setResult(result);
|
||||
return smsResult;
|
||||
} catch (HTTPException | IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
SmsResult smsResult = new SmsResult();
|
||||
smsResult.setSuccessful(false);
|
||||
return smsResult;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package co.yixiang.modules.notify.config;
|
||||
|
||||
import co.yixiang.config.NotifyProperties;
|
||||
import co.yixiang.modules.notify.AliyunSmsSender;
|
||||
import co.yixiang.modules.notify.NotifyService;
|
||||
import co.yixiang.modules.notify.TencentSmsSender;
|
||||
import com.github.qcloudsms.SmsSingleSender;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(NotifyProperties.class)
|
||||
public class NotifyAutoConfiguration {
|
||||
|
||||
private final NotifyProperties properties;
|
||||
|
||||
public NotifyAutoConfiguration(NotifyProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NotifyService notifyService() {
|
||||
NotifyService notifyService = new NotifyService();
|
||||
|
||||
NotifyProperties.Mail mailConfig = properties.getMail();
|
||||
if (mailConfig.isEnable()) {
|
||||
notifyService.setMailSender(mailSender());
|
||||
notifyService.setSendFrom(mailConfig.getSendfrom());
|
||||
notifyService.setSendTo(mailConfig.getSendto());
|
||||
}
|
||||
|
||||
NotifyProperties.Sms smsConfig = properties.getSms();
|
||||
if (smsConfig.isEnable()) {
|
||||
if(smsConfig.getActive().equals("tencent")) {
|
||||
notifyService.setSmsSender(tencentSmsSender());
|
||||
}
|
||||
else if(smsConfig.getActive().equals("aliyun")) {
|
||||
notifyService.setSmsSender(aliyunSmsSender());
|
||||
}
|
||||
|
||||
notifyService.setSmsTemplate(smsConfig.getTemplate());
|
||||
}
|
||||
|
||||
return notifyService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JavaMailSender mailSender() {
|
||||
NotifyProperties.Mail mailConfig = properties.getMail();
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setHost(mailConfig.getHost());
|
||||
mailSender.setUsername(mailConfig.getUsername());
|
||||
mailSender.setPassword(mailConfig.getPassword());
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public TencentSmsSender tencentSmsSender() {
|
||||
NotifyProperties.Sms smsConfig = properties.getSms();
|
||||
TencentSmsSender smsSender = new TencentSmsSender();
|
||||
NotifyProperties.Sms.Tencent tencent = smsConfig.getTencent();
|
||||
smsSender.setSender(new SmsSingleSender(tencent.getAppid(), tencent.getAppkey()));
|
||||
smsSender.setSign(smsConfig.getSign());
|
||||
return smsSender;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AliyunSmsSender aliyunSmsSender() {
|
||||
NotifyProperties.Sms smsConfig = properties.getSms();
|
||||
AliyunSmsSender smsSender = new AliyunSmsSender();
|
||||
NotifyProperties.Sms.Aliyun aliyun = smsConfig.getAliyun();
|
||||
smsSender.setSign(smsConfig.getSign());
|
||||
smsSender.setRegionId(aliyun.getRegionId());
|
||||
smsSender.setAccessKeyId(aliyun.getAccessKeyId());
|
||||
smsSender.setAccessKeySecret(aliyun.getAccessKeySecret());
|
||||
return smsSender;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package co.yixiang.modules.order.service.impl;
|
||||
|
||||
import cn.hutool.core.util.*;
|
||||
import co.yixiang.common.constant.CacheKey;
|
||||
import co.yixiang.common.constant.CommonConstant;
|
||||
import co.yixiang.exception.ErrorRequestException;
|
||||
import co.yixiang.modules.activity.service.YxStoreCombinationService;
|
||||
import co.yixiang.modules.activity.service.YxStorePinkService;
|
||||
@ -30,21 +31,18 @@ import co.yixiang.modules.shop.service.YxStoreProductService;
|
||||
import co.yixiang.modules.shop.service.YxSystemConfigService;
|
||||
import co.yixiang.modules.shop.web.vo.YxStoreCartQueryVo;
|
||||
//import co.yixiang.modules.task.CancelOrderService;
|
||||
import co.yixiang.modules.user.entity.YxUser;
|
||||
import co.yixiang.modules.user.entity.YxUserAddress;
|
||||
import co.yixiang.modules.user.entity.YxUserBill;
|
||||
import co.yixiang.modules.user.entity.YxWechatUser;
|
||||
import co.yixiang.modules.task.CancelOrderService;
|
||||
import co.yixiang.modules.user.entity.*;
|
||||
import co.yixiang.modules.user.mapper.YxUserMapper;
|
||||
import co.yixiang.modules.user.service.YxUserAddressService;
|
||||
import co.yixiang.modules.user.service.YxUserBillService;
|
||||
import co.yixiang.modules.user.service.YxUserService;
|
||||
import co.yixiang.modules.user.service.YxWechatUserService;
|
||||
import co.yixiang.modules.user.service.*;
|
||||
import co.yixiang.modules.user.web.controller.UserAddressController;
|
||||
import co.yixiang.modules.user.web.vo.YxUserAddressQueryVo;
|
||||
import co.yixiang.modules.user.web.vo.YxUserQueryVo;
|
||||
import co.yixiang.modules.user.web.vo.YxWechatUserQueryVo;
|
||||
//import co.yixiang.redisson.DelayJob;
|
||||
//import co.yixiang.redisson.DelayJobService;
|
||||
import co.yixiang.redisson.DelayJob;
|
||||
import co.yixiang.redisson.DelayJobService;
|
||||
import co.yixiang.utils.OrderUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -69,6 +67,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -137,15 +136,12 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
private YxStoreCouponUserMapper yxStoreCouponUserMapper;
|
||||
|
||||
@Autowired
|
||||
private DelayJobService delayJobService;
|
||||
private YxStoreCombinationService combinationService;
|
||||
|
||||
@Autowired
|
||||
private YxStorePinkService pinkService;
|
||||
|
||||
// @Autowired
|
||||
// private DelayJobService delayJobService;
|
||||
|
||||
|
||||
// @Value("${job.unpayorder}")
|
||||
// private String overtime;
|
||||
|
||||
@ -259,7 +255,7 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
public void cancelOrder(String orderId, int uid) {
|
||||
YxStoreOrderQueryVo order = getOrderInfo(orderId,uid);
|
||||
if(ObjectUtil.isNull(order)) throw new ErrorRequestException("订单不存在");
|
||||
|
||||
if(order.getIsDel() == 1)throw new ErrorRequestException("订单已取消");
|
||||
regressionIntegral(order);
|
||||
|
||||
regressionStock(order);
|
||||
@ -284,6 +280,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
|
||||
if(ObjectUtil.isNull(order)) throw new ErrorRequestException("订单不存在");
|
||||
|
||||
if(order.getIsDel() == 1)throw new ErrorRequestException("订单已取消");
|
||||
|
||||
regressionIntegral(order);
|
||||
|
||||
regressionStock(order);
|
||||
@ -638,11 +636,13 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
userService.incPayCount(orderInfo.getUid());
|
||||
//增加状态
|
||||
orderStatusService.create(orderInfo.getId(),"pay_success","用户付款成功");
|
||||
|
||||
|
||||
//支付成功后取消延时队列
|
||||
DelayJob delayJob = new DelayJob();
|
||||
delayJob.setOderId(storeOrder.getId());
|
||||
delayJob.setAClass(CancelOrderService.class);
|
||||
delayJobService.cancelJob(delayJob);
|
||||
//todo 拼团
|
||||
pinkService.createPink(orderInfo);
|
||||
|
||||
//todo 模板消息推送
|
||||
}
|
||||
|
||||
@ -909,18 +909,12 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
//增加状态
|
||||
orderStatusService.create(storeOrder.getId(),"cache_key_create_order","订单生成");
|
||||
|
||||
// 订单支付超期任务
|
||||
|
||||
//String overtimeStr = systemConfigService.getData("order_cancel_job_time");
|
||||
//没有配置不加入
|
||||
// if(StrUtil.isNotBlank(overtimeStr)){
|
||||
// // 订单支付超期任务
|
||||
// DelayJob delayJob = new DelayJob();
|
||||
// delayJob.setOrderId(storeOrder.getId());
|
||||
// delayJob.setAClass(CancelOrderService.class);
|
||||
// delayJobService.submitJob(delayJob,Long.valueOf(overtimeStr));
|
||||
// }
|
||||
|
||||
// 添加订单支付超期延时任务
|
||||
DelayJob delayJob = new DelayJob();
|
||||
delayJob.setOderId(storeOrder.getId());
|
||||
delayJob.setAClass(CancelOrderService.class);
|
||||
delayJobService.submitJob(delayJob, CommonConstant.ORDER_OUTTIME_UNPAY);
|
||||
return storeOrder;
|
||||
}
|
||||
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
//package co.yixiang.modules.task;
|
||||
//
|
||||
//import cn.hutool.core.util.ObjectUtil;
|
||||
//import co.yixiang.modules.order.entity.YxStoreOrder;
|
||||
//import co.yixiang.modules.order.service.YxStoreOrderService;
|
||||
//import co.yixiang.redisson.DelayJob;
|
||||
//import co.yixiang.redisson.ExecuteJob;
|
||||
//import co.yixiang.utils.SpringContextHolder;
|
||||
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//
|
||||
//@Component
|
||||
//@Slf4j
|
||||
//public class CancelOrderService implements ExecuteJob {
|
||||
// @Override
|
||||
// public void execute(DelayJob job) {
|
||||
// log.info("系统开始处理延时任务---订单超时未付款---" + job.getOrderId());
|
||||
//
|
||||
// YxStoreOrderService yxorderService = SpringContextHolder.getBean(YxStoreOrderService.class);
|
||||
//
|
||||
// YxStoreOrder order = null;
|
||||
// try {
|
||||
// order = yxorderService.getOne(new QueryWrapper<YxStoreOrder>().eq("id", job.getOrderId()).eq("is_del",0));
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if(ObjectUtil.isNull(order)) {
|
||||
// return;
|
||||
// }
|
||||
// if(order.getPaid() != 0){
|
||||
// return;
|
||||
// }
|
||||
// yxorderService.cancelOrderByTask(job.getOrderId());
|
||||
// log.info("系统结束处理延时任务---订单超时未付款取消---" + job.getOrderId());
|
||||
// }
|
||||
//}
|
||||
package co.yixiang.modules.task;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import co.yixiang.modules.order.entity.YxStoreOrder;
|
||||
import co.yixiang.modules.order.service.YxStoreOrderService;
|
||||
import co.yixiang.redisson.DelayJob;
|
||||
import co.yixiang.redisson.ExecuteJob;
|
||||
import co.yixiang.utils.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CancelOrderService implements ExecuteJob {
|
||||
@Override
|
||||
public void execute(DelayJob job) {
|
||||
log.info("系统开始处理延时任务---订单超时未付款---" + job.getOderId());
|
||||
|
||||
YxStoreOrderService yxorderService = BeanUtil.getBean(YxStoreOrderService.class);
|
||||
|
||||
YxStoreOrder order = null;
|
||||
try {
|
||||
order = yxorderService.getOne(new QueryWrapper<YxStoreOrder>().eq("id", job.getOderId()).eq("is_del",0));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(ObjectUtil.isNull(order)) {
|
||||
return;
|
||||
}
|
||||
if(order.getPaid() != 0){
|
||||
return;
|
||||
}
|
||||
yxorderService.cancelOrderByTask(job.getOderId());
|
||||
log.info("系统结束处理延时任务---订单超时未付款取消---" + job.getOderId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,10 +5,10 @@ spring:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
#driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
||||
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
|
||||
url: jdbc:p6spy:mysql://localhost:3306/yxshop?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
url: jdbc:p6spy:mysql://106.12.82.39:3306/yxshop?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
#url: jdbc:log4jdbc:mysql://localhost:3306/yxshop?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
username: root
|
||||
password: root
|
||||
password: Admin@123
|
||||
|
||||
# 初始化配置
|
||||
initial-size: 3
|
||||
@ -47,7 +47,7 @@ spring:
|
||||
database: 0
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
password:
|
||||
password: root
|
||||
#连接超时时间
|
||||
timeout: 5000
|
||||
|
||||
@ -78,4 +78,88 @@ file:
|
||||
# 文件大小 /M
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
localUrl: http://localhost:8000
|
||||
localUrl: http://localhost:8000
|
||||
yshop:
|
||||
#通知相关配置
|
||||
notify:
|
||||
mail:
|
||||
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
|
||||
enable: false
|
||||
host: smtp.exmail.qq.com
|
||||
username: ex@ex.com.cn
|
||||
password: XXXXXXXXXXXXX
|
||||
sendfrom: ex@ex.com.cn
|
||||
sendto: ex@qq.com
|
||||
|
||||
# 短消息模版通知配置
|
||||
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
sms:
|
||||
enable: false
|
||||
# 如果是腾讯云短信,则设置active的值tencent
|
||||
# 如果是阿里云短信,则设置active的值aliyun
|
||||
active: tencent
|
||||
sign: litemall
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: 156349
|
||||
- name: captcha
|
||||
templateId: 156433
|
||||
- name: ship
|
||||
templateId: 158002
|
||||
- name: refund
|
||||
templateId: 159447
|
||||
tencent:
|
||||
appid: 111111111
|
||||
appkey: xxxxxxxxxxxxxx
|
||||
aliyun:
|
||||
regionId: xxx
|
||||
accessKeyId: xxx
|
||||
accessKeySecret: xxx
|
||||
|
||||
|
||||
# 微信模版通知配置
|
||||
# 微信模版用于通知客户或者运营者,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
wx:
|
||||
enable: false
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: captcha
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: ship
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: refund
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# 快鸟物流查询配置
|
||||
express:
|
||||
enable: false
|
||||
appId: "XXXXXXXXX"
|
||||
appKey: "XXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
vendors:
|
||||
- code: "ZTO"
|
||||
name: "中通快递"
|
||||
- code: "YTO"
|
||||
name: "圆通速递"
|
||||
- code: "YD"
|
||||
name: "韵达速递"
|
||||
- code: "YZPY"
|
||||
name: "邮政快递包裹"
|
||||
- code: "EMS"
|
||||
name: "EMS"
|
||||
- code: "DBL"
|
||||
name: "德邦快递"
|
||||
- code: "FAST"
|
||||
name: "快捷快递"
|
||||
- code: "ZJS"
|
||||
name: "宅急送"
|
||||
- code: "TNT"
|
||||
name: "TNT快递"
|
||||
- code: "UPS"
|
||||
name: "UPS"
|
||||
- code: "DHL"
|
||||
name: "DHL"
|
||||
- code: "FEDEX"
|
||||
name: "FEDEX联邦(国内件)"
|
||||
- code: "FEDEX_GJ"
|
||||
name: "FEDEX联邦(国际件)"
|
||||
@ -86,4 +86,89 @@ file:
|
||||
# 文件大小 /M
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
localUrl: http://localhost:8000
|
||||
localUrl: http://localhost:8000
|
||||
|
||||
yshop:
|
||||
#通知相关配置
|
||||
notify:
|
||||
mail:
|
||||
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
|
||||
enable: false
|
||||
host: smtp.exmail.qq.com
|
||||
username: ex@ex.com.cn
|
||||
password: XXXXXXXXXXXXX
|
||||
sendfrom: ex@ex.com.cn
|
||||
sendto: ex@qq.com
|
||||
|
||||
# 短消息模版通知配置
|
||||
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
sms:
|
||||
enable: false
|
||||
# 如果是腾讯云短信,则设置active的值tencent
|
||||
# 如果是阿里云短信,则设置active的值aliyun
|
||||
active: tencent
|
||||
sign: litemall
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: 156349
|
||||
- name: captcha
|
||||
templateId: 156433
|
||||
- name: ship
|
||||
templateId: 158002
|
||||
- name: refund
|
||||
templateId: 159447
|
||||
tencent:
|
||||
appid: 111111111
|
||||
appkey: xxxxxxxxxxxxxx
|
||||
aliyun:
|
||||
regionId: xxx
|
||||
accessKeyId: xxx
|
||||
accessKeySecret: xxx
|
||||
|
||||
|
||||
# 微信模版通知配置
|
||||
# 微信模版用于通知客户或者运营者,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
wx:
|
||||
enable: false
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: captcha
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: ship
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
- name: refund
|
||||
templateId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# 快鸟物流查询配置
|
||||
express:
|
||||
enable: false
|
||||
appId: "XXXXXXXXX"
|
||||
appKey: "XXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
vendors:
|
||||
- code: "ZTO"
|
||||
name: "中通快递"
|
||||
- code: "YTO"
|
||||
name: "圆通速递"
|
||||
- code: "YD"
|
||||
name: "韵达速递"
|
||||
- code: "YZPY"
|
||||
name: "邮政快递包裹"
|
||||
- code: "EMS"
|
||||
name: "EMS"
|
||||
- code: "DBL"
|
||||
name: "德邦快递"
|
||||
- code: "FAST"
|
||||
name: "快捷快递"
|
||||
- code: "ZJS"
|
||||
name: "宅急送"
|
||||
- code: "TNT"
|
||||
name: "TNT快递"
|
||||
- code: "UPS"
|
||||
name: "UPS"
|
||||
- code: "DHL"
|
||||
name: "DHL"
|
||||
- code: "FEDEX"
|
||||
name: "FEDEX联邦(国内件)"
|
||||
- code: "FEDEX_GJ"
|
||||
name: "FEDEX联邦(国际件)"
|
||||
@ -23,9 +23,11 @@ import java.util.Map;
|
||||
public class CodeGenerator {
|
||||
|
||||
private static final String USER_NAME = "root";
|
||||
private static final String PASSWORD = "root";
|
||||
|
||||
private static final String PASSWORD = "Admin@123";
|
||||
private static final String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
|
||||
private static final String DRIVER_URL = "jdbc:mysql://127.0.0.1:3306/yxshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8";
|
||||
|
||||
private static final String DRIVER_URL = "jdbc:mysql://106.12.82.39:3306/yxshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8";
|
||||
|
||||
private static final String PARENT_PACKAGE = "co.yixiang";
|
||||
private static final String SUPER_ENTITY = PARENT_PACKAGE + ".common.entity.BaseEntity";
|
||||
@ -45,8 +47,7 @@ public class CodeGenerator {
|
||||
// 作者
|
||||
private static final String AUTHOR = "hupeng";
|
||||
// 生成的表名称
|
||||
private static final String TABLE_NAME = "yx_store_pink";
|
||||
// 主键数据库列名称
|
||||
private static final String TABLE_NAME = "yx_system_attachment"; // 主键数据库列名称
|
||||
private static final String PK_ID_COLUMN_NAME = "id";
|
||||
// 代码生成策略 true:All/false:SIMPLE
|
||||
private static final boolean GENERATOR_STRATEGY = true;
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
package co.yixiang.redis;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
@ -19,6 +14,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
@ -31,7 +27,7 @@ import java.time.Duration;
|
||||
// 自动配置
|
||||
@ConditionalOnClass(RedisOperations.class)
|
||||
@EnableConfigurationProperties(RedisProperties.class)
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
public class RedisConfig {
|
||||
|
||||
/**
|
||||
* 设置 redis 数据默认过期时间,默认1天
|
||||
@ -75,52 +71,5 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义缓存key生成策略,默认将使用该策略
|
||||
* 使用方法 @Cacheable
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return (target, method, params) -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(target.getClass().getName());
|
||||
sb.append(method.getName());
|
||||
for (Object obj : params) {
|
||||
sb.append(JSON.toJSONString(obj).hashCode());
|
||||
}
|
||||
return sb.toString();
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public CacheErrorHandler errorHandler() {
|
||||
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
|
||||
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
|
||||
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
|
||||
@Override
|
||||
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
|
||||
log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheClearError(RuntimeException e, Cache cache) {
|
||||
log.error("Redis occur handleCacheClearError:", e);
|
||||
}
|
||||
};
|
||||
return cacheErrorHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
16
yshop-common/src/main/java/co/yixiang/redisson/DelayJob.java
Normal file
16
yshop-common/src/main/java/co/yixiang/redisson/DelayJob.java
Normal file
@ -0,0 +1,16 @@
|
||||
package co.yixiang.redisson;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/7/20.
|
||||
* Content :延时job
|
||||
*/
|
||||
@Data
|
||||
public class DelayJob implements Serializable {
|
||||
private Integer oderId;//job执行参数
|
||||
private Class aClass;//具体执行实例实现
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package co.yixiang.redisson;
|
||||
|
||||
import org.redisson.api.RBlockingQueue;
|
||||
import org.redisson.api.RDelayedQueue;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/7/20.
|
||||
* Content :订单延时job服务
|
||||
*/
|
||||
@Component
|
||||
public class DelayJobService {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient client;
|
||||
|
||||
/**
|
||||
* 添加超时任务到redis队列
|
||||
* @param job 任务
|
||||
* @param delay 超时时间
|
||||
*/
|
||||
public void submitJob(DelayJob job, Long delay){
|
||||
RBlockingQueue blockingQueue = client.getBlockingQueue(JobTimer.CUSTOMER_JOB_TIMER_JOBS);
|
||||
RDelayedQueue delayedQueue = client.getDelayedQueue(blockingQueue);
|
||||
delayedQueue.offer(job,delay,TimeUnit.MILLISECONDS);
|
||||
delayedQueue.destroy();
|
||||
}
|
||||
/**
|
||||
* 用户付款后取消队列
|
||||
* @param job 任务
|
||||
*/
|
||||
public void cancelJob(DelayJob job){
|
||||
RBlockingQueue blockingQueue = client.getBlockingQueue(JobTimer.CUSTOMER_JOB_TIMER_JOBS);
|
||||
RDelayedQueue delayedQueue = client.getDelayedQueue(blockingQueue);
|
||||
delayedQueue.remove(job);
|
||||
delayedQueue.destroy();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package co.yixiang.redisson;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/7/20.
|
||||
* Content :延时job执行器接口
|
||||
*/
|
||||
public interface ExecuteJob {
|
||||
|
||||
void execute(DelayJob job);
|
||||
}
|
||||
68
yshop-common/src/main/java/co/yixiang/redisson/JobTimer.java
Normal file
68
yshop-common/src/main/java/co/yixiang/redisson/JobTimer.java
Normal file
@ -0,0 +1,68 @@
|
||||
package co.yixiang.redisson;
|
||||
|
||||
import org.redisson.api.RBlockingQueue;
|
||||
import org.redisson.api.RDelayedQueue;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 消费已经到点的延时job服务,通过job参数调用业务执行器实现
|
||||
*/
|
||||
@Component
|
||||
public class JobTimer {
|
||||
|
||||
static final String CUSTOMER_JOB_TIMER_JOBS = "customer_job_timer_jobs";
|
||||
@Autowired
|
||||
private RedissonClient client;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
|
||||
@PostConstruct
|
||||
public void startJobTimer() {
|
||||
RBlockingQueue blockingQueue = client.getBlockingQueue(CUSTOMER_JOB_TIMER_JOBS);
|
||||
RDelayedQueue delayedQueue = client.getDelayedQueue(blockingQueue);
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
DelayJob job = (DelayJob) blockingQueue.take();
|
||||
executorService.execute(new ExecutorTask(context, job));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(60);
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}finally {
|
||||
delayedQueue.destroy();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
class ExecutorTask implements Runnable {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
private DelayJob delayJob;
|
||||
|
||||
public ExecutorTask(ApplicationContext context, DelayJob delayJob) {
|
||||
this.context = context;
|
||||
this.delayJob = delayJob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ExecuteJob service = (ExecuteJob) context.getBean(delayJob.getAClass());
|
||||
service.execute(delayJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package co.yixiang.redisson;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.spring.cache.CacheConfig;
|
||||
import org.redisson.spring.cache.RedissonSpringCacheManager;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* redisson 配置类
|
||||
* Created on 2018/6/19
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
@Slf4j
|
||||
public class RedissonConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String host;
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private String port;
|
||||
|
||||
@Value("${spring.redis.password}")
|
||||
private String password;
|
||||
|
||||
@Bean
|
||||
public RedissonClient getRedisson(){
|
||||
|
||||
Config config = new Config();
|
||||
config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);
|
||||
//添加主从配置
|
||||
// config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
|
||||
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheManager cacheManager(RedissonClient redissonClient){
|
||||
Map<String, CacheConfig> config = new HashMap<>(16);
|
||||
// create "testMap" cache with ttl = 24 minutes and maxIdleTime = 12 minutes
|
||||
config.put("testMap",new CacheConfig(24*60*1000,12*60*1000));
|
||||
return new RedissonSpringCacheManager(redissonClient,config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义缓存key生成策略,默认将使用该策略
|
||||
* 使用方法 @Cacheable
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return (target, method, params) -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(target.getClass().getName());
|
||||
sb.append(method.getName());
|
||||
for (Object obj : params) {
|
||||
sb.append(JSON.toJSONString(obj).hashCode());
|
||||
}
|
||||
return sb.toString();
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public CacheErrorHandler errorHandler() {
|
||||
// 异常处理,当Redis发生异常时,打印日志,但是程序正常走
|
||||
log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
|
||||
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
|
||||
@Override
|
||||
public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
|
||||
log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
|
||||
log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCacheClearError(RuntimeException e, Cache cache) {
|
||||
log.error("Redis occur handleCacheClearError:", e);
|
||||
}
|
||||
};
|
||||
return cacheErrorHandler;
|
||||
}
|
||||
|
||||
}
|
||||
24
yshop-common/src/main/java/co/yixiang/utils/BeanUtil.java
Normal file
24
yshop-common/src/main/java/co/yixiang/utils/BeanUtil.java
Normal file
@ -0,0 +1,24 @@
|
||||
package co.yixiang.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class BeanUtil implements ApplicationContextAware {
|
||||
protected static ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
context = applicationContext;
|
||||
}
|
||||
|
||||
public static Object getBean(String name) {
|
||||
return context.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(Class<T> c){
|
||||
return context.getBean(c);
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,9 @@ spring:
|
||||
druid:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
||||
url: jdbc:log4jdbc:mysql://localhost:3306/yxshop?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
url: jdbc:log4jdbc:mysql://106.12.82.39:3306/yxshop?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
|
||||
username: root
|
||||
password: root
|
||||
password: Admin@123
|
||||
|
||||
# 初始化配置
|
||||
initial-size: 3
|
||||
@ -46,7 +46,7 @@ spring:
|
||||
database: 0
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
password:
|
||||
password: root
|
||||
#连接超时时间
|
||||
timeout: 5000
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
<artifactId>alipay-sdk-java</artifactId>
|
||||
<version>${alipay.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
|
||||
145
yshop-tools/src/main/java/co/yixiang/express/ExpressService.java
Normal file
145
yshop-tools/src/main/java/co/yixiang/express/ExpressService.java
Normal file
@ -0,0 +1,145 @@
|
||||
package co.yixiang.express;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import co.yixiang.express.config.ExpressProperties;
|
||||
import co.yixiang.express.dao.ExpressInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 物流查询服务
|
||||
* <p>
|
||||
* 快递鸟即时查询API http://www.kdniao.com/api-track
|
||||
*/
|
||||
public class ExpressService {
|
||||
|
||||
private final Log logger = LogFactory.getLog(ExpressService.class);
|
||||
//请求url
|
||||
private String ReqURL = "http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
|
||||
|
||||
private ExpressProperties properties;
|
||||
|
||||
public ExpressProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(ExpressProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流供应商名
|
||||
*
|
||||
* @param vendorCode
|
||||
* @return
|
||||
*/
|
||||
public String getVendorName(String vendorCode) {
|
||||
for (Map<String, String> item : properties.getVendors()) {
|
||||
if (item.get("code").equals(vendorCode))
|
||||
return item.get("name");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流信息
|
||||
*
|
||||
* @param expCode
|
||||
* @param expNo
|
||||
* @return
|
||||
*/
|
||||
public ExpressInfo getExpressInfo(String expCode, String expNo) {
|
||||
try {
|
||||
String result = getOrderTracesByJson(expCode, expNo);
|
||||
ObjectMapper objMap = new ObjectMapper();
|
||||
ExpressInfo ei = objMap.readValue(result, ExpressInfo.class);
|
||||
ei.setShipperName(getVendorName(expCode));
|
||||
return ei;
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Json方式 查询订单物流轨迹
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private String getOrderTracesByJson(String expCode, String expNo) throws Exception {
|
||||
if (!properties.isEnable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
|
||||
params.put("EBusinessID", properties.getAppId());
|
||||
params.put("RequestType", "1002");
|
||||
String dataSign = encrypt(requestData, properties.getAppKey(), "UTF-8");
|
||||
params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
|
||||
params.put("DataType", "2");
|
||||
|
||||
String result = HttpUtil.post(ReqURL, params);
|
||||
|
||||
//根据公司业务处理返回的信息......
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param str 内容
|
||||
* @param charset 编码方式
|
||||
* @throws Exception
|
||||
*/
|
||||
private String MD5(String str, String charset) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes(charset));
|
||||
byte[] result = md.digest();
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
int val = result[i] & 0xff;
|
||||
if (val <= 0xf) {
|
||||
sb.append("0");
|
||||
}
|
||||
sb.append(Integer.toHexString(val));
|
||||
}
|
||||
return sb.toString().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign签名生成
|
||||
*
|
||||
* @param content 内容
|
||||
* @param keyValue Appkey
|
||||
* @param charset 编码方式
|
||||
* @return DataSign签名
|
||||
*/
|
||||
private String encrypt(String content, String keyValue, String charset) {
|
||||
if (keyValue != null) {
|
||||
content = content + keyValue;
|
||||
}
|
||||
byte[] src;
|
||||
try {
|
||||
src = MD5(content, charset).getBytes(charset);
|
||||
return Base64Utils.encodeToString(src);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package co.yixiang.express.config;
|
||||
|
||||
import co.yixiang.express.ExpressService;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(ExpressProperties.class)
|
||||
public class ExpressAutoConfiguration {
|
||||
|
||||
private final ExpressProperties properties;
|
||||
|
||||
public ExpressAutoConfiguration(ExpressProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExpressService expressService() {
|
||||
ExpressService expressService = new ExpressService();
|
||||
expressService.setProperties(properties);
|
||||
return expressService;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package co.yixiang.express.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ConfigurationProperties(prefix = "yshop.express")
|
||||
public class ExpressProperties {
|
||||
private boolean enable;
|
||||
private String appId;
|
||||
private String appKey;
|
||||
private List<Map<String, String>> vendors = new ArrayList<>();
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getVendors() {
|
||||
return vendors;
|
||||
}
|
||||
|
||||
public void setVendors(List<Map<String, String>> vendors) {
|
||||
this.vendors = vendors;
|
||||
}
|
||||
|
||||
public String getAppKey() {
|
||||
return appKey;
|
||||
}
|
||||
|
||||
public void setAppKey(String appKey) {
|
||||
this.appKey = appKey;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright 2018 bejson.com
|
||||
*/
|
||||
package co.yixiang.express.dao;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2018-07-19 22:27:22
|
||||
*
|
||||
* @author bejson.com (i@bejson.com)
|
||||
* @website http://www.bejson.com/java2pojo/
|
||||
*/
|
||||
public class ExpressInfo {
|
||||
|
||||
@JsonProperty("LogisticCode")
|
||||
private String LogisticCode;
|
||||
@JsonProperty("ShipperCode")
|
||||
private String ShipperCode;
|
||||
@JsonProperty("Traces")
|
||||
private List<Traces> Traces;
|
||||
@JsonProperty("State")
|
||||
private String State;
|
||||
@JsonProperty("EBusinessID")
|
||||
private String EBusinessID;
|
||||
@JsonProperty("Success")
|
||||
private boolean Success;
|
||||
@JsonProperty("Reason")
|
||||
private String Reason;
|
||||
|
||||
private String ShipperName;
|
||||
|
||||
public String getLogisticCode() {
|
||||
return LogisticCode;
|
||||
}
|
||||
|
||||
public void setLogisticCode(String LogisticCode) {
|
||||
this.LogisticCode = LogisticCode;
|
||||
}
|
||||
|
||||
public String getShipperCode() {
|
||||
return ShipperCode;
|
||||
}
|
||||
|
||||
public void setShipperCode(String ShipperCode) {
|
||||
this.ShipperCode = ShipperCode;
|
||||
}
|
||||
|
||||
public List<Traces> getTraces() {
|
||||
return Traces;
|
||||
}
|
||||
|
||||
public void setTraces(List<Traces> Traces) {
|
||||
this.Traces = Traces;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return State;
|
||||
}
|
||||
|
||||
public void setState(String State) {
|
||||
this.State = State;
|
||||
}
|
||||
|
||||
public String getEBusinessID() {
|
||||
return EBusinessID;
|
||||
}
|
||||
|
||||
public void setEBusinessID(String EBusinessID) {
|
||||
this.EBusinessID = EBusinessID;
|
||||
}
|
||||
|
||||
public boolean getSuccess() {
|
||||
return Success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean Success) {
|
||||
this.Success = Success;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return Reason;
|
||||
}
|
||||
|
||||
public void setReason(String Reason) {
|
||||
this.Reason = Reason;
|
||||
}
|
||||
|
||||
public String getShipperName() {
|
||||
return ShipperName;
|
||||
}
|
||||
|
||||
public void setShipperName(String shipperName) {
|
||||
ShipperName = shipperName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExpressInfo{" +
|
||||
"LogisticCode='" + LogisticCode + '\'' +
|
||||
", ShipperCode='" + ShipperCode + '\'' +
|
||||
", Traces=" + Traces +
|
||||
", State='" + State + '\'' +
|
||||
", EBusinessID='" + EBusinessID + '\'' +
|
||||
", Success=" + Success +
|
||||
", Reason=" + Reason +
|
||||
", ShipperName='" + ShipperName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
37
yshop-tools/src/main/java/co/yixiang/express/dao/Traces.java
Normal file
37
yshop-tools/src/main/java/co/yixiang/express/dao/Traces.java
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright 2018 bejson.com
|
||||
*/
|
||||
package co.yixiang.express.dao;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2018-07-19 22:27:22
|
||||
*
|
||||
* @author bejson.com (i@bejson.com)
|
||||
* @website http://www.bejson.com/java2pojo/
|
||||
*/
|
||||
public class Traces {
|
||||
|
||||
@JsonProperty("AcceptStation")
|
||||
private String AcceptStation;
|
||||
@JsonProperty("AcceptTime")
|
||||
private String AcceptTime;
|
||||
|
||||
public String getAcceptStation() {
|
||||
return AcceptStation;
|
||||
}
|
||||
|
||||
public void setAcceptStation(String AcceptStation) {
|
||||
this.AcceptStation = AcceptStation;
|
||||
}
|
||||
|
||||
public String getAcceptTime() {
|
||||
return AcceptTime;
|
||||
}
|
||||
|
||||
public void setAcceptTime(String AcceptTime) {
|
||||
this.AcceptTime = AcceptTime;
|
||||
}
|
||||
|
||||
}
|
||||
174
yshop-tools/src/main/java/co/yixiang/utils/JacksonUtil.java
Normal file
174
yshop-tools/src/main/java/co/yixiang/utils/JacksonUtil.java
Normal file
@ -0,0 +1,174 @@
|
||||
package co.yixiang.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JacksonUtil {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JacksonUtil.class);
|
||||
|
||||
public static String parseString(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
if (leaf != null)
|
||||
return leaf.asText();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> parseStringList(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
|
||||
if (leaf != null)
|
||||
return mapper.convertValue(leaf, new TypeReference<List<String>>() {
|
||||
});
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer parseInteger(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
if (leaf != null)
|
||||
return leaf.asInt();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Integer> parseIntegerList(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
|
||||
if (leaf != null)
|
||||
return mapper.convertValue(leaf, new TypeReference<List<Integer>>() {
|
||||
});
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Boolean parseBoolean(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
if (leaf != null)
|
||||
return leaf.asBoolean();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Short parseShort(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
if (leaf != null) {
|
||||
Integer value = leaf.asInt();
|
||||
return value.shortValue();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Byte parseByte(String body, String field) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
JsonNode leaf = node.get(field);
|
||||
if (leaf != null) {
|
||||
Integer value = leaf.asInt();
|
||||
return value.byteValue();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String body, String field, Class<T> clazz) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode node;
|
||||
try {
|
||||
node = mapper.readTree(body);
|
||||
node = node.get(field);
|
||||
return mapper.treeToValue(node, clazz);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object toNode(String json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
|
||||
return mapper.readTree(json);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Map<String, String> toMap(String data) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
return objectMapper.readValue(data, new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String toJson(Object data) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
return objectMapper.writeValueAsString(data);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user