修正项目
This commit is contained in:
42
xlcs-parent/common/common-util/pom.xml
Normal file
42
xlcs-parent/common/common-util/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common-util</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>model</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@@ -0,0 +1,126 @@
|
||||
package com.yovinchen.xlcs.common.utils;
|
||||
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* ClassName: DateUtil
|
||||
* Package: com.yovinchen.xlcs.common.utils
|
||||
* 日期操作工具类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/10/12 18:04
|
||||
*/
|
||||
public class DateUtil {
|
||||
|
||||
private static final String dateFormat = "yyyy-MM-dd";
|
||||
private static final String timeFormat = "HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String formatDate(Date date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
return sdf.format(date);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String formatTime(Date date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
|
||||
return sdf.format(date);
|
||||
|
||||
}
|
||||
|
||||
public static Date parseTime(String date) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
|
||||
try {
|
||||
return sdf.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取比较断两个日期对象的field处的值 。
|
||||
* 如果第一个日期小于、等于、大于第二个,则对应返回负整数、0、正整数
|
||||
*
|
||||
* @param date1 第一个日期对象,非null
|
||||
* @param date2 第二个日期对象,非null
|
||||
* @param field Calendar中的阈值
|
||||
* <p>
|
||||
* date1 > date2 返回:1
|
||||
* date1 = date2 返回:0
|
||||
* date1 < date2 返回:-1
|
||||
*/
|
||||
public static int truncatedCompareTo(final Date date1, final Date date2, final int field) {
|
||||
return DateUtils.truncatedCompareTo(date1, date2, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* 比对日期与时间大小
|
||||
*
|
||||
* @param beginDate
|
||||
* @param endDate
|
||||
* @return
|
||||
*/
|
||||
public static boolean dateCompare(Date beginDate, Date endDate) {
|
||||
// endDate > beginDate
|
||||
return DateUtil.truncatedCompareTo(beginDate, endDate, Calendar.SECOND) != 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 比对日期与时间大小
|
||||
*
|
||||
* @param beginDate
|
||||
* @param endDate
|
||||
* @return
|
||||
*/
|
||||
public static boolean timeCompare(Date beginDate, Date endDate) {
|
||||
Calendar instance1 = Calendar.getInstance();
|
||||
instance1.setTime(beginDate); //设置时间为当前时间
|
||||
instance1.set(Calendar.YEAR, 0);
|
||||
instance1.set(Calendar.MONTH, 0);
|
||||
instance1.set(Calendar.DAY_OF_MONTH, 0);
|
||||
|
||||
Calendar instance2 = Calendar.getInstance();
|
||||
instance2.setTime(endDate); //设置时间为当前时间
|
||||
instance2.set(Calendar.YEAR, 0);
|
||||
instance2.set(Calendar.MONTH, 0);
|
||||
instance2.set(Calendar.DAY_OF_MONTH, 0);
|
||||
// endDate > beginDate
|
||||
return DateUtil.truncatedCompareTo(instance1.getTime(), instance2.getTime(), Calendar.SECOND) != 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间到晚上23点59分59秒的时间间隔,单位:秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Long getCurrentExpireTimes() {
|
||||
//过期截止时间
|
||||
Calendar instance = Calendar.getInstance();
|
||||
instance.setTime(new Date()); //设置时间为当前时间
|
||||
instance.set(Calendar.HOUR_OF_DAY, 23);
|
||||
instance.set(Calendar.MINUTE, 59);
|
||||
instance.set(Calendar.SECOND, 59);
|
||||
Date endTime = instance.getTime();
|
||||
//当前时间与截止时间间隔,单位:秒
|
||||
long interval = (endTime.getTime() - new Date().getTime()) / 1000;
|
||||
return 100 * 60 * 60 * 24 * 365L;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,64 @@
|
||||
package com.yovinchen.xlcs.common.utils;
|
||||
|
||||
import io.jsonwebtoken.*;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* ClassName: JwtHelper
|
||||
* Package: com.yovinchen.xlcs.common.utils
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 15:50
|
||||
*/
|
||||
public class JwtHelper {
|
||||
|
||||
private static final long tokenExpiration = 365L * 24 * 60 * 60 * 1000;
|
||||
private static final String tokenSignKey = "xlcs";
|
||||
|
||||
public static String createToken(Long userId, String userName) {
|
||||
String token = Jwts.builder()
|
||||
.setSubject("xlcs-USER")
|
||||
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
|
||||
.claim("userId", userId)
|
||||
.claim("userName", userName)
|
||||
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
|
||||
.compressWith(CompressionCodecs.GZIP)
|
||||
.compact();
|
||||
return token;
|
||||
}
|
||||
|
||||
public static Long getUserId(String token) {
|
||||
if (StringUtils.isEmpty(token)) return null;
|
||||
|
||||
Jws<Claims> claimsJws = Jwts.parser()
|
||||
.setSigningKey(tokenSignKey)
|
||||
.parseClaimsJws(token);
|
||||
Claims claims = claimsJws.getBody();
|
||||
Integer userId = (Integer) claims.get("userId");
|
||||
return userId.longValue();
|
||||
// return 1L;
|
||||
}
|
||||
|
||||
public static String getUserName(String token) {
|
||||
if (StringUtils.isEmpty(token)) return "";
|
||||
|
||||
Jws<Claims> claimsJws = Jwts.parser()
|
||||
.setSigningKey(tokenSignKey)
|
||||
.parseClaimsJws(token);
|
||||
Claims claims = claimsJws.getBody();
|
||||
return (String) claims.get("userName");
|
||||
}
|
||||
|
||||
public static void removeToken(String token) {
|
||||
//jwttoken无需删除,客户端扔掉即可。
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String token = JwtHelper.createToken(7L, "admin");
|
||||
System.out.println(token);
|
||||
System.out.println(JwtHelper.getUserId(token));
|
||||
System.out.println(JwtHelper.getUserName(token));
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package com.yovinchen.xlcs.common.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
|
||||
public final class MD5 {
|
||||
|
||||
public static String encrypt(String strSrc) {
|
||||
try {
|
||||
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
byte[] bytes = strSrc.getBytes();
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(bytes);
|
||||
bytes = md.digest();
|
||||
int j = bytes.length;
|
||||
char[] chars = new char[j * 2];
|
||||
int k = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
byte b = bytes[i];
|
||||
chars[k++] = hexChars[b >>> 4 & 0xf];
|
||||
chars[k++] = hexChars[b & 0xf];
|
||||
}
|
||||
return new String(chars);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("MD5加密出错!!+" + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
60
xlcs-parent/common/pom.xml
Normal file
60
xlcs-parent/common/pom.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>xlcs-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>common-util</module>
|
||||
<module>service-util</module>
|
||||
<module>rabbit_util</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--lombok用来简化实体类:需要安装lombok插件-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<!-- https://doc.xiaominfo.com/knife4j/documentation/ -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--用来转换json使用 {JavaObject - json | json - JavaObject}-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 服务调用feign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
26
xlcs-parent/common/rabbit_util/pom.xml
Normal file
26
xlcs-parent/common/rabbit_util/pom.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>rabbit_util</artifactId>
|
||||
<dependencies>
|
||||
<!--rabbitmq消息队列-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@@ -0,0 +1,22 @@
|
||||
package com.yovinchen.xlcs.mq.config;
|
||||
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* ClassName: MQConfig
|
||||
* Package: com.yovinchen.xlcs.mq.config
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/16 23:32
|
||||
*/
|
||||
@Configuration
|
||||
public class MQConfig {
|
||||
|
||||
@Bean
|
||||
public MessageConverter messageConverter() {
|
||||
return new Jackson2JsonMessageConverter();
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
package com.yovinchen.xlcs.mq.config;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* ClassName: MQProducerAckConfig
|
||||
* Package: com.yovinchen.xlcs.mq.config
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/16 23:33
|
||||
*/
|
||||
@Component
|
||||
public class MQProducerAckConfig implements RabbitTemplate.ReturnCallback, RabbitTemplate.ConfirmCallback {
|
||||
|
||||
// 我们发送消息使用的是 private RabbitTemplate rabbitTemplate; 对象
|
||||
// 如果不做设置的话 当前的rabbitTemplate 与当前的配置类没有任何关系!
|
||||
@Autowired
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
// 设置 表示修饰一个非静态的void方法,在服务器加载Servlet的时候运行。并且只执行一次!
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
rabbitTemplate.setReturnCallback(this);
|
||||
rabbitTemplate.setConfirmCallback(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 表示消息是否正确发送到了交换机上
|
||||
*
|
||||
* @param correlationData 消息的载体
|
||||
* @param ack 判断是否发送到交换机上
|
||||
* @param cause 原因
|
||||
*/
|
||||
@Override
|
||||
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||
if (ack) {
|
||||
System.out.println("消息发送成功!");
|
||||
} else {
|
||||
System.out.println("消息发送失败!" + cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息如果没有正确发送到队列中,则会走这个方法!如果消息被正常处理,则这个方法不会走!
|
||||
*
|
||||
* @param message
|
||||
* @param replyCode
|
||||
* @param replyText
|
||||
* @param exchange
|
||||
* @param routingKey
|
||||
*/
|
||||
@Override
|
||||
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
|
||||
System.out.println("消息主体: " + new String(message.getBody()));
|
||||
System.out.println("应答码: " + replyCode);
|
||||
System.out.println("描述:" + replyText);
|
||||
System.out.println("消息使用的交换器 exchange : " + exchange);
|
||||
System.out.println("消息使用的路由键 routing : " + routingKey);
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package com.yovinchen.xlcs.mq.constant;
|
||||
|
||||
/**
|
||||
* ClassName: MqConst
|
||||
* Package: com.yovinchen.xlcs.mq.constant
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/16 23:34
|
||||
*/
|
||||
public class MqConst {
|
||||
/**
|
||||
* 消息补偿
|
||||
*/
|
||||
public static final String MQ_KEY_PREFIX = "xlcs.mq:list";
|
||||
public static final int RETRY_COUNT = 3;
|
||||
|
||||
/**
|
||||
* 商品上下架
|
||||
*/
|
||||
public static final String EXCHANGE_GOODS_DIRECT = "xlcs.goods.direct";
|
||||
public static final String ROUTING_GOODS_UPPER = "xlcs.goods.upper";
|
||||
public static final String ROUTING_GOODS_LOWER = "xlcs.goods.lower";
|
||||
//队列
|
||||
public static final String QUEUE_GOODS_UPPER = "xlcs.goods.upper";
|
||||
public static final String QUEUE_GOODS_LOWER = "xlcs.goods.lower";
|
||||
|
||||
/**
|
||||
* 团长上下线
|
||||
*/
|
||||
public static final String EXCHANGE_LEADER_DIRECT = "xlcs.leader.direct";
|
||||
public static final String ROUTING_LEADER_UPPER = "xlcs.leader.upper";
|
||||
public static final String ROUTING_LEADER_LOWER = "xlcs.leader.lower";
|
||||
//队列
|
||||
public static final String QUEUE_LEADER_UPPER = "xlcs.leader.upper";
|
||||
public static final String QUEUE_LEADER_LOWER = "xlcs.leader.lower";
|
||||
|
||||
//订单
|
||||
public static final String EXCHANGE_ORDER_DIRECT = "xlcs.order.direct";
|
||||
public static final String ROUTING_ROLLBACK_STOCK = "xlcs.rollback.stock";
|
||||
public static final String ROUTING_MINUS_STOCK = "xlcs.minus.stock";
|
||||
|
||||
public static final String ROUTING_DELETE_CART = "xlcs.delete.cart";
|
||||
//解锁普通商品库存
|
||||
public static final String QUEUE_ROLLBACK_STOCK = "xlcs.rollback.stock";
|
||||
public static final String QUEUE_SECKILL_ROLLBACK_STOCK = "xlcs.seckill.rollback.stock";
|
||||
public static final String QUEUE_MINUS_STOCK = "xlcs.minus.stock";
|
||||
public static final String QUEUE_DELETE_CART = "xlcs.delete.cart";
|
||||
|
||||
//支付
|
||||
public static final String EXCHANGE_PAY_DIRECT = "xlcs.pay.direct";
|
||||
public static final String ROUTING_PAY_SUCCESS = "xlcs.pay.success";
|
||||
public static final String QUEUE_ORDER_PAY = "xlcs.order.pay";
|
||||
public static final String QUEUE_LEADER_BILL = "xlcs.leader.bill";
|
||||
|
||||
//取消订单
|
||||
public static final String EXCHANGE_CANCEL_ORDER_DIRECT = "xlcs.cancel.order.direct";
|
||||
public static final String ROUTING_CANCEL_ORDER = "xlcs.cancel.order";
|
||||
//延迟取消订单队列
|
||||
public static final String QUEUE_CANCEL_ORDER = "xlcs.cancel.order";
|
||||
|
||||
/**
|
||||
* 定时任务
|
||||
*/
|
||||
public static final String EXCHANGE_DIRECT_TASK = "xlcs.exchange.direct.task";
|
||||
public static final String ROUTING_TASK_23 = "xlcs.task.23";
|
||||
//队列
|
||||
public static final String QUEUE_TASK_23 = "xlcs.queue.task.23";
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package com.yovinchen.xlcs.mq.service;
|
||||
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* ClassName: RabbitService
|
||||
* Package: com.yovinchen.xlcs.common.service
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/16 18:12
|
||||
*/
|
||||
@Service
|
||||
public class RabbitService {
|
||||
|
||||
// 引入操作rabbitmq 的模板
|
||||
@Autowired
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param exchange 交换机
|
||||
* @param routingKey 路由键
|
||||
* @param message 消息
|
||||
* @return
|
||||
*/
|
||||
public boolean sendMessage(String exchange, String routingKey, Object message) {
|
||||
// 调用发送数据的方法
|
||||
rabbitTemplate.convertAndSend(exchange, routingKey, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送延迟消息的方法
|
||||
*
|
||||
* @param exchange 交换机
|
||||
* @param routingKey 路由键
|
||||
* @param message 消息内容
|
||||
* @param delayTime 延迟时间
|
||||
* @return
|
||||
*/
|
||||
public boolean sendDelayMessage(String exchange, String routingKey, Object message, int delayTime) {
|
||||
|
||||
// 在发送消息的时候设置延迟时间
|
||||
rabbitTemplate.convertAndSend(exchange, routingKey, message, message1 -> {
|
||||
// 设置一个延迟时间
|
||||
message1
|
||||
.getMessageProperties()
|
||||
.setDelay(delayTime * 1000);
|
||||
return message1;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
74
xlcs-parent/common/service-util/pom.xml
Normal file
74
xlcs-parent/common/service-util/pom.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>service-util</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>common-util</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- redis -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- spring2.X集成redis所需common-pool2-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- redisson 分布式锁-->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.11.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--mybatis-plus-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yovinchen</groupId>
|
||||
<artifactId>model</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- 代码生成器-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@@ -0,0 +1,50 @@
|
||||
package com.yovinchen.xlcs.common.auth;
|
||||
|
||||
import com.yovinchen.xlcs.vo.user.UserLoginVo;
|
||||
|
||||
/**
|
||||
* ClassName: AuthContextHolder
|
||||
* Package: com.yovinchen.xlcs.common.auth
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 17:40
|
||||
*/
|
||||
//ThreadLocal工具类
|
||||
public class AuthContextHolder {
|
||||
|
||||
//用户id
|
||||
private static final ThreadLocal<Long> userId = new ThreadLocal<>();
|
||||
|
||||
//用户仓库id
|
||||
private static final ThreadLocal<Long> wareId = new ThreadLocal<>();
|
||||
|
||||
//用户信息对象
|
||||
private static final ThreadLocal<UserLoginVo> userLoginVo = new ThreadLocal<>();
|
||||
|
||||
public static Long getUserId() {
|
||||
return userId.get();
|
||||
}
|
||||
|
||||
//userId操作的方法
|
||||
public static void setUserId(Long _userId) {
|
||||
userId.set(_userId);
|
||||
}
|
||||
|
||||
public static Long getWareId() {
|
||||
return wareId.get();
|
||||
}
|
||||
|
||||
public static void setWareId(Long _wareId) {
|
||||
wareId.set(_wareId);
|
||||
}
|
||||
|
||||
public static UserLoginVo getUserLoginVo() {
|
||||
return userLoginVo.get();
|
||||
}
|
||||
|
||||
public static void setUserLoginVo(UserLoginVo _userLoginVo) {
|
||||
userLoginVo.set(_userLoginVo);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.yovinchen.xlcs.common.auth;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* ClassName: LoginMvcConfigurerAdapter
|
||||
* Package: com.yovinchen.xlcs.common.auth
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 23:58
|
||||
*/
|
||||
@Configuration
|
||||
public class LoginMvcConfigurerAdapter extends WebMvcConfigurationSupport {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new UserLoginInterceptor(redisTemplate))
|
||||
.addPathPatterns("/api/**")
|
||||
.excludePathPatterns("/api/user/weixin/wxLogin/*");
|
||||
super.addInterceptors(registry);
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package com.yovinchen.xlcs.common.auth;
|
||||
|
||||
import com.yovinchen.xlcs.common.constant.RedisConst;
|
||||
import com.yovinchen.xlcs.common.utils.JwtHelper;
|
||||
import com.yovinchen.xlcs.vo.user.UserLoginVo;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* ClassName: UserLoginInterceptor
|
||||
* Package: com.yovinchen.xlcs.common.auth
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 23:47
|
||||
*/
|
||||
public class UserLoginInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
public UserLoginInterceptor(RedisTemplate redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
this.getUserLoginVo(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void getUserLoginVo(HttpServletRequest request) {
|
||||
//从请求头获取token
|
||||
String token = request.getHeader("token");
|
||||
|
||||
//判断token不为空
|
||||
if (!StringUtils.isEmpty(token)) {
|
||||
//从token获取userId
|
||||
Long userId = JwtHelper.getUserId(token);
|
||||
//根据userId到Redis获取用户信息
|
||||
UserLoginVo userLoginVo = (UserLoginVo) redisTemplate.opsForValue()
|
||||
.get(RedisConst.USER_LOGIN_KEY_PREFIX + userId);
|
||||
//获取数据放到ThreadLocal里面
|
||||
if (userLoginVo != null) {
|
||||
AuthContextHolder.setUserId(userLoginVo.getUserId());
|
||||
AuthContextHolder.setWareId(userLoginVo.getWareId());
|
||||
AuthContextHolder.setUserLoginVo(userLoginVo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package com.yovinchen.xlcs.common.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* ClassName: MyBatisPlusConfig
|
||||
* Package: com.yovinchen.xlcs.common.config
|
||||
* MybatisPlus配置类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 12:56
|
||||
*/
|
||||
@EnableTransactionManagement
|
||||
@Configuration
|
||||
@MapperScan(value = {"com.yovinchen.xlcs.*.mapper"})
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* mp插件
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor optimisticLockerInnerInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
//向Mybatis过滤器链中添加分页拦截器
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
package com.yovinchen.xlcs.common.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
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;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* ClassName: RedisConfig
|
||||
* Package: com.yovinchen.xlcs.common.config
|
||||
* Redis配置类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 15:55
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class RedisConfig {
|
||||
|
||||
// 使用默认标签做缓存
|
||||
@Bean
|
||||
public KeyGenerator wiselyKeyGenerator() {
|
||||
return new KeyGenerator() {
|
||||
@Override
|
||||
public Object generate(Object target, Method method, Object... params) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(target.getClass()
|
||||
.getName());
|
||||
sb.append(method.getName());
|
||||
for (Object obj : params) {
|
||||
sb.append(obj.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 声明模板
|
||||
/*
|
||||
ref = 表示引用
|
||||
value = 具体的值
|
||||
<bean class="org.springframework.data.redis.core.RedisTemplate" >
|
||||
<property name="defaultSerializer" ref = "">
|
||||
</bean>
|
||||
*/
|
||||
// 工具类:
|
||||
@Bean
|
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
// 将Redis 中 string ,hash 数据类型,自动序列化!
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager(RedisConnectionFactory factory) {
|
||||
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
|
||||
//解决查询缓存转换异常的问题
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
|
||||
// 配置序列化(解决乱码的问题),过期时间600秒
|
||||
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
||||
.entryTtl(Duration.ofDays(365))
|
||||
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
|
||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
|
||||
.disableCachingNullValues();
|
||||
|
||||
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
|
||||
.cacheDefaults(config)
|
||||
.build();
|
||||
return cacheManager;
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package com.yovinchen.xlcs.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* ClassName: RedissonConfig
|
||||
* Package: com.yovinchen.xlcs.common.config
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/10/12 16:48
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties("spring.redis")
|
||||
public class RedissonConfig {
|
||||
|
||||
private static String ADDRESS_PREFIX = "redis://";
|
||||
private String host;
|
||||
private String addresses;
|
||||
private String password;
|
||||
private String port;
|
||||
private int timeout = 3000;
|
||||
private int connectionPoolSize = 64;
|
||||
private int connectionMinimumIdleSize = 10;
|
||||
private int pingConnectionInterval = 60000;
|
||||
|
||||
/**
|
||||
* 自动装配
|
||||
*/
|
||||
@Bean
|
||||
RedissonClient redissonSingle() {
|
||||
Config config = new Config();
|
||||
// 判断redis 的host是否为空
|
||||
if (StringUtils.isEmpty(host)) {
|
||||
throw new RuntimeException("host is empty");
|
||||
}
|
||||
// 配置host,port等参数
|
||||
SingleServerConfig serverConfig = config.useSingleServer()
|
||||
//redis://127.0.0.1:7181
|
||||
.setAddress(ADDRESS_PREFIX + this.host + ":" + port)
|
||||
.setTimeout(this.timeout)
|
||||
.setPingConnectionInterval(pingConnectionInterval)
|
||||
.setConnectionPoolSize(this.connectionPoolSize)
|
||||
.setConnectionMinimumIdleSize(this.connectionMinimumIdleSize);
|
||||
// 判断进入redis 是否密码
|
||||
if (!StringUtils.isEmpty(this.password)) {
|
||||
serverConfig.setPassword(this.password);
|
||||
}
|
||||
// RedissonClient redisson = Redisson.create(config);
|
||||
return Redisson.create(config);
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
package com.yovinchen.xlcs.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.service.Parameter;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ClassName: Swagger2Config
|
||||
* Package: com.yovinchen.xlcs.common.config
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 13:18
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2WebMvc
|
||||
public class Swagger2Config {
|
||||
|
||||
@Bean
|
||||
public Docket webApiConfig() {
|
||||
List<Parameter> pars = new ArrayList<>();
|
||||
ParameterBuilder tokenPar = new ParameterBuilder();
|
||||
tokenPar
|
||||
.name("userId")
|
||||
.description("用户token")
|
||||
//.defaultValue(JwtHelper.createToken(1L, "admin"))
|
||||
.defaultValue("1")
|
||||
.modelRef(new ModelRef("string"))
|
||||
.parameterType("header")
|
||||
.required(false)
|
||||
.build();
|
||||
pars.add(tokenPar.build());
|
||||
|
||||
Docket webApi = new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("webApi")
|
||||
.apiInfo(webApiInfo())
|
||||
.select()
|
||||
//只显示api路径下的页面
|
||||
.apis(RequestHandlerSelectors.basePackage("com.yovinchen.xlcs"))
|
||||
.paths(PathSelectors.regex("/api/.*"))
|
||||
.build()
|
||||
.globalOperationParameters(pars);
|
||||
return webApi;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket adminApiConfig() {
|
||||
List<Parameter> pars = new ArrayList<>();
|
||||
ParameterBuilder tokenPar = new ParameterBuilder();
|
||||
tokenPar
|
||||
.name("adminId")
|
||||
.description("用户token")
|
||||
.defaultValue("1")
|
||||
.modelRef(new ModelRef("string"))
|
||||
.parameterType("header")
|
||||
.required(false)
|
||||
.build();
|
||||
pars.add(tokenPar.build());
|
||||
|
||||
Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("adminApi")
|
||||
.apiInfo(adminApiInfo())
|
||||
.select()
|
||||
//只显示admin路径下的页面
|
||||
.apis(RequestHandlerSelectors.basePackage("com.yovinchen.xlcs"))
|
||||
.paths(PathSelectors.regex("/admin/.*"))
|
||||
.build()
|
||||
.globalOperationParameters(pars);
|
||||
return adminApi;
|
||||
}
|
||||
|
||||
private ApiInfo webApiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("网站-API文档")
|
||||
.description("本文档描述了尚上优选网站微服务接口定义")
|
||||
.version("1.0")
|
||||
.contact(new Contact("yovinchen", "http://yovinchen.com", "yovinchen"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private ApiInfo adminApiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("后台管理系统-API文档")
|
||||
.description("本文档描述了尚上优选后台系统服务接口定义")
|
||||
.version("1.0")
|
||||
.contact(new Contact("yovinchen", "http://yovinchen.com", "yovinchen"))
|
||||
.build();
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package com.yovinchen.xlcs.common.constant;
|
||||
|
||||
/**
|
||||
* ClassName: RedisConst
|
||||
* Package: com.yovinchen.xlcs.common.constant
|
||||
* Redis常量配置类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/22 15:57
|
||||
*/
|
||||
public class RedisConst {
|
||||
|
||||
public static final String SKUKEY_PREFIX = "sku:";
|
||||
public static final String SKUKEY_SUFFIX = ":info";
|
||||
//单位:秒
|
||||
public static final long SKUKEY_TIMEOUT = 24 * 60 * 60;
|
||||
// 定义变量,记录空对象的缓存过期时间 缓存穿透key的过期时间
|
||||
public static final long SKUKEY_TEMPORARY_TIMEOUT = 10 * 60;
|
||||
|
||||
//单位:秒 尝试获取锁的最大等待时间
|
||||
public static final long SKULOCK_EXPIRE_PX1 = 1;
|
||||
//单位:秒 锁的持有时间
|
||||
public static final long SKULOCK_EXPIRE_PX2 = 1;
|
||||
public static final String SKULOCK_SUFFIX = ":lock";
|
||||
|
||||
public static final String USER_KEY_PREFIX = "user:";
|
||||
public static final String USER_CART_KEY_SUFFIX = ":cart";
|
||||
public static final long USER_CART_EXPIRE = 60 * 60 * 24 * 7;
|
||||
public static final String SROCK_INFO = "stock:info:";
|
||||
public static final String ORDER_REPEAT = "order:repeat:";
|
||||
|
||||
//用户登录
|
||||
public static final String USER_LOGIN_KEY_PREFIX = "user:login:";
|
||||
public static final String ADMIN_LOGIN_KEY_PREFIX = "admin:login:";
|
||||
// public static final String userinfoKey_suffix = ":info";
|
||||
public static final int USERKEY_TIMEOUT = 365;
|
||||
public static final String ORDER_SKU_MAP = "order:sku:";
|
||||
|
||||
//秒杀商品前缀
|
||||
public static final String SECKILL_TIME_MAP = "seckill:time:map";
|
||||
public static final String SECKILL_SKU_MAP = "seckill:sku:map";
|
||||
public static final String SECKILL_SKU_LIST = "seckill:sku:list:";
|
||||
public static final String SECKILL_USER_MAP = "seckill:user:map:";
|
||||
public static final String SECKILL_ORDERS_USERS = "seckill:orders:users";
|
||||
public static final String SECKILL_STOCK_PREFIX = "seckill:stock:";
|
||||
public static final String SECKILL_USER = "seckill:user:";
|
||||
//用户锁定时间 单位:秒
|
||||
public static final int SECKILL__TIMEOUT = 60 * 60;
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package com.yovinchen.xlcs.common.exception;
|
||||
|
||||
import com.yovinchen.xlcs.common.result.Result;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* ClassName: GlobalExceptionHandler
|
||||
* Package: com.yovinchen.xlcs.common.exception
|
||||
* 统一异常处理类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 13:03
|
||||
*/
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public Result error(Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.fail(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义异常处理方法
|
||||
*
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(xlcsException.class)
|
||||
@ResponseBody
|
||||
public Result error(xlcsException e) {
|
||||
return Result.build(null, e.getCode(), e.getMessage());
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package com.yovinchen.xlcs.common.exception;
|
||||
|
||||
import com.yovinchen.xlcs.common.result.ResultCodeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* ClassName: xlcsException
|
||||
* Package: com.yovinchen.xlcs.common.exception
|
||||
* 自定义异常类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 13:05
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class xlcsException extends RuntimeException {
|
||||
|
||||
//异常状态码
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 通过状态码和错误消息创建异常对象
|
||||
*
|
||||
* @param message
|
||||
* @param code
|
||||
*/
|
||||
public xlcsException(String message, Integer code) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收枚举类型对象
|
||||
*
|
||||
* @param resultCodeEnum
|
||||
*/
|
||||
public xlcsException(ResultCodeEnum resultCodeEnum) {
|
||||
super(resultCodeEnum.getMessage());
|
||||
this.code = resultCodeEnum.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GuliException{" + "code=" + code + ", message=" + this.getMessage() + '}';
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package com.yovinchen.xlcs.common.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* ClassName: Result
|
||||
* Package: com.yovinchen.xlcs.common.result
|
||||
* 统一返回结果类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 13:01
|
||||
*/
|
||||
@Data
|
||||
public class Result<T> {
|
||||
|
||||
//状态码
|
||||
private Integer code;
|
||||
//信息
|
||||
private String message;
|
||||
//数据
|
||||
private T data;
|
||||
|
||||
//构造私有化
|
||||
private Result() {
|
||||
}
|
||||
|
||||
//设置数据,返回对象的方法
|
||||
public static <T> Result<T> build(T data, Integer code, String message) {
|
||||
//创建Resullt对象,设置值,返回对象
|
||||
Result<T> result = new Result<>();
|
||||
//判断返回结果中是否需要数据
|
||||
if (data != null) {
|
||||
//设置数据到result对象
|
||||
result.setData(data);
|
||||
}
|
||||
//设置其他值
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
//返回设置值之后的对象
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//设置数据,返回对象的方法
|
||||
public static <T> Result<T> build(T data, ResultCodeEnum resultCodeEnum) {
|
||||
//创建Resullt对象,设置值,返回对象
|
||||
Result<T> result = new Result<>();
|
||||
//判断返回结果中是否需要数据
|
||||
if (data != null) {
|
||||
//设置数据到result对象
|
||||
result.setData(data);
|
||||
}
|
||||
//设置其他值
|
||||
result.setCode(resultCodeEnum.getCode());
|
||||
result.setMessage(resultCodeEnum.getMessage());
|
||||
//返回设置值之后的对象
|
||||
return result;
|
||||
}
|
||||
|
||||
//成功的方法
|
||||
public static <T> Result<T> ok(T data) {
|
||||
Result<T> result = build(data, ResultCodeEnum.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
|
||||
//失败的方法
|
||||
public static <T> Result<T> fail(T data) {
|
||||
return build(data, ResultCodeEnum.FAIL);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package com.yovinchen.xlcs.common.result;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* ClassName: ResultCodeEnum
|
||||
* Package: com.yovinchen.xlcs.common.result
|
||||
* 统一返回结果状态信息类
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/13 12:59
|
||||
*/
|
||||
@Getter
|
||||
public enum ResultCodeEnum {
|
||||
|
||||
SUCCESS(200, "成功"),
|
||||
FAIL(201, "失败"),
|
||||
|
||||
SERVICE_ERROR(2012, "服务异常"),
|
||||
DATA_ERROR(204, "数据异常"),
|
||||
ILLEGAL_REQUEST(205, "非法请求"),
|
||||
REPEAT_SUBMIT(206, "重复提交"),
|
||||
|
||||
LOGIN_AUTH(208, "未登陆"),
|
||||
PERMISSION(209, "没有权限"),
|
||||
|
||||
ORDER_PRICE_ERROR(210, "订单商品价格变化"),
|
||||
ORDER_STOCK_FALL(204, "订单库存锁定失败"),
|
||||
CREATE_ORDER_FAIL(210, "创建订单失败"),
|
||||
|
||||
COUPON_GET(220, "优惠券已经领取"),
|
||||
COUPON_LIMIT_GET(221, "优惠券已发放完毕"),
|
||||
|
||||
URL_ENCODE_ERROR(216, "URL编码失败"),
|
||||
ILLEGAL_CALLBACK_REQUEST_ERROR(217, "非法回调请求"),
|
||||
FETCH_ACCESSTOKEN_FAILD(218, "获取accessToken失败"),
|
||||
FETCH_USERINFO_ERROR(219, "获取用户信息失败"),
|
||||
|
||||
|
||||
SKU_LIMIT_ERROR(230, "购买个数不能大于限购个数"),
|
||||
REGION_OPEN(240, "该区域已开通"),
|
||||
REGION_NO_OPEN(240, "该区域未开通"),
|
||||
PAYMENT_WAITING(242, "订单支付中"),
|
||||
PAYMENT_SUCCESS(241, "订单支付成功"),
|
||||
PAYMENT_FAIL(243, "订单支付失败"),
|
||||
;
|
||||
|
||||
private final Integer code;
|
||||
|
||||
private final String message;
|
||||
|
||||
ResultCodeEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package com.yovinchen.xlcs;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.PackageConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
|
||||
/**
|
||||
* ClassName: CodeGet
|
||||
* Package: com.yovinchen.xlcs
|
||||
*
|
||||
* @author yovinchen
|
||||
* @Create 2023/9/14 08:49
|
||||
*/
|
||||
public class CodeGet {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// 1、创建代码生成器
|
||||
AutoGenerator mpg = new AutoGenerator();
|
||||
|
||||
// 2、全局配置
|
||||
// 全局配置
|
||||
GlobalConfig gc = new GlobalConfig();
|
||||
gc.setOutputDir("yovinchen-xlcs-parent/service/service-order" + "/src/main/java");
|
||||
|
||||
gc.setServiceName("%sService"); //去掉Service接口的首字母I
|
||||
gc.setAuthor("yovinchen");
|
||||
gc.setOpen(false);
|
||||
mpg.setGlobalConfig(gc);
|
||||
|
||||
// 3、数据源配置
|
||||
DataSourceConfig dsc = new DataSourceConfig();
|
||||
dsc.setUrl("jdbc:mysql://82.157.68.223:3306/shequ-order?serverTimezone=GMT%2B8&useSSL=false");
|
||||
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
|
||||
dsc.setUsername("shequ-order");
|
||||
dsc.setPassword("shequ-order");
|
||||
dsc.setDbType(DbType.MYSQL);
|
||||
mpg.setDataSource(dsc);
|
||||
|
||||
// 4、包配置
|
||||
PackageConfig pc = new PackageConfig();
|
||||
pc.setParent("com.yovinchen.xlcs");
|
||||
pc.setModuleName("order"); //模块名
|
||||
pc.setController("controller");
|
||||
pc.setService("service");
|
||||
pc.setMapper("mapper");
|
||||
mpg.setPackageInfo(pc);
|
||||
|
||||
// 5、策略配置
|
||||
StrategyConfig strategy = new StrategyConfig();
|
||||
|
||||
strategy.setInclude("cart_info", "order_info", "order_deliver", "order_item", "order_log", "order_return_apply", "order_return_reason", "order_set", "payment_info", "refund_info");
|
||||
|
||||
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
|
||||
|
||||
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
|
||||
strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作
|
||||
|
||||
strategy.setRestControllerStyle(true); //restful api风格控制器
|
||||
strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
|
||||
|
||||
mpg.setStrategy(strategy);
|
||||
|
||||
// 6、执行
|
||||
mpg.execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user