mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2024-12-23 05:00:25 +08:00
feat:订单项目结构调整
This commit is contained in:
parent
ec223bbf1e
commit
0b223cb31e
168
mall-oms/oms-boot/pom.xml
Normal file
168
mall-oms/oms-boot/pom.xml
Normal file
@ -0,0 +1,168 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>mall-oms</artifactId>
|
||||
<groupId>com.youlai</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>oms-boot</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>oms-api</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>pms-api</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>common-mybatis</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>common-web</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>common-redis</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.youlai</groupId>
|
||||
<artifactId>common-rabbitmq</artifactId>
|
||||
<version>${youlai.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- nacos 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
<exclusions>
|
||||
<!-- 排除依赖 指定版本和服务器端一致 -->
|
||||
<exclusion>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-all</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<!--执行mvn package,即执行 mvn clean package docker:build-->
|
||||
<!-- <execution>
|
||||
<id>build-image</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>-->
|
||||
</executions>
|
||||
|
||||
<configuration>
|
||||
<!-- 镜像名称 -->
|
||||
<imageName>${project.artifactId}</imageName>
|
||||
<!-- 指定标签 -->
|
||||
<imageTags>
|
||||
<imageTag>latest</imageTag>
|
||||
</imageTags>
|
||||
<!-- 基础镜像-->
|
||||
<baseImage>openjdk:8-jdk-alpine</baseImage>
|
||||
|
||||
<!-- 切换到容器工作目录-->
|
||||
<workdir>/</workdir>
|
||||
|
||||
<entryPoint>["java","-jar","${project.build.finalName}.jar"]</entryPoint>
|
||||
|
||||
<!-- 指定远程 Docker API地址 -->
|
||||
<dockerHost>https://b.youlai.store:2376</dockerHost>
|
||||
<!-- 指定tls证书的目录 -->
|
||||
<dockerCertPath>C:\cert\docker\b.youlai.store</dockerCertPath>
|
||||
|
||||
<!-- 复制 jar包到docker容器指定目录-->
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>/</targetPath>
|
||||
<!-- 用于指定需要复制的根目录,${project.build.directory}表示target目录 -->
|
||||
<directory>${project.build.directory}</directory>
|
||||
<!-- 用于指定需要复制的文件,${project.build.finalName}.jar就是打包后的target目录下的jar包名称 -->
|
||||
<include>${project.build.finalName}.jar</include>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,24 @@
|
||||
package com.youlai.mall;
|
||||
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients
|
||||
//@EnableConfigurationProperties({ThreadPoolProperties.class})
|
||||
@MapperScan({"com.youlai.mall.oms.mapper", "com.youlai.mall.oms.dao"})
|
||||
@EnableRabbit
|
||||
public class OmsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OmsApplication.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.youlai.common.redis.constant;
|
||||
package com.youlai.mall.oms.common;
|
||||
|
||||
public interface RedisKeyConstants {
|
||||
public interface RedisConstants {
|
||||
|
||||
Long REDIS_KEY_TIME_OUT = 3600 * 24L;
|
||||
|
@ -0,0 +1,78 @@
|
||||
package com.youlai.mall.oms.config;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.OAuthBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author haoxr
|
||||
* @Date 2021-02-25 15:36
|
||||
* @Version 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2WebMvc
|
||||
@Import(BeanValidatorPluginsConfiguration.class)
|
||||
public class SwaggerConfiguration {
|
||||
|
||||
@Bean
|
||||
public Docket restApi() {
|
||||
//schema
|
||||
List<GrantType> grantTypes=new ArrayList<>();
|
||||
//密码模式
|
||||
String passwordTokenUrl="http://localhost:9999/youlai-auth/oauth/token";
|
||||
ResourceOwnerPasswordCredentialsGrant resourceOwnerPasswordCredentialsGrant=new ResourceOwnerPasswordCredentialsGrant(passwordTokenUrl);
|
||||
grantTypes.add(resourceOwnerPasswordCredentialsGrant);
|
||||
OAuth oAuth=new OAuthBuilder().name("oauth2")
|
||||
.grantTypes(grantTypes).build();
|
||||
//context
|
||||
//scope方位
|
||||
List<AuthorizationScope> scopes=new ArrayList<>();
|
||||
scopes.add(new AuthorizationScope("read","read resources"));
|
||||
scopes.add(new AuthorizationScope("write","write resources"));
|
||||
scopes.add(new AuthorizationScope("reads","read all resources"));
|
||||
scopes.add(new AuthorizationScope("writes","write all resources"));
|
||||
|
||||
SecurityReference securityReference=new SecurityReference("oauth2",scopes.toArray(new AuthorizationScope[]{}));
|
||||
SecurityContext securityContext=new SecurityContext(Lists.newArrayList(securityReference),PathSelectors.ant("/**"));
|
||||
//schemas
|
||||
List<SecurityScheme> securitySchemes=Lists.newArrayList(oAuth);
|
||||
//securyContext
|
||||
List<SecurityContext> securityContexts=Lists.newArrayList(securityContext);
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.youlai.mall.oms.controller"))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.securityContexts(securityContexts)
|
||||
.securitySchemes(securitySchemes)
|
||||
.apiInfo(apiInfo());
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("订单中心REST接口")
|
||||
.description("<div style='font-size:14px;color:red;'>订单提交、秒杀接口</div>")
|
||||
.termsOfServiceUrl("https://www.youlai.store")
|
||||
.contact(new Contact("yl", "https://github.com/hxrui", "1490493387@qq.com"))
|
||||
.license("Open Source")
|
||||
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
|
||||
.version("1.0.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package com.youlai.mall.oms.config.rabbitmq;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc rabbitmq 业务相关配置类
|
||||
* 订单相关业务统一使用 order-event-exchange 交换机
|
||||
* order.delay.queue 队列,用于存放需要延时多长时间处理的订单,不需要被消费
|
||||
* order.release.queue 队列,用于真正执行处理订单,需要被业务消费,如果订单还没有付款需要自动关闭订单并释放库存
|
||||
* <p>
|
||||
* order.create.order 建立交换机与 order.delay.queue 队列的绑定关系,目的是将新创建的订单放入延时队列中
|
||||
* order.release.order 建立交换机与 order.release.queue 队列的绑定关系,目的是将延时队列中到达延时时间的订单执行释放操作
|
||||
* <p>
|
||||
* 自动创建相关 交换机,队列,路由键
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/17
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class OmsRabbitConfig {
|
||||
|
||||
@Autowired
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
/**
|
||||
* 订单死信-延时队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue orderDelayQueue() {
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
args.put("x-dead-letter-exchange", OmsRabbitConstants.ORDER_EVENT_EXCHANGE);
|
||||
args.put("x-dead-letter-routing-key", OmsRabbitConstants.ORDER_RELEASE_ORDER_KEY);
|
||||
args.put("x-message-ttl", 60000);
|
||||
Queue queue = new Queue(OmsRabbitConstants.ORDER_DELAY_QUEUE, true, false, false, args);
|
||||
|
||||
return queue;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放订单队列
|
||||
* 订单系统从该队列中取出订单order,判断是否超时未支付
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue orderReleaseQueue() {
|
||||
return new Queue(OmsRabbitConstants.ORDER_RELEASE_QUEUE, true, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Topic类型 订单交换机
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Exchange orderEventExchange() {
|
||||
return new TopicExchange(OmsRabbitConstants.ORDER_EVENT_EXCHANGE, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立 order.delay.queue 队列与交换机绑定
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding orderCreateOrderBinding() {
|
||||
//String destination, DestinationType destinationType, String exchange, String routingKey,
|
||||
// @Nullable Map<String, Object> arguments
|
||||
return new Binding(OmsRabbitConstants.ORDER_DELAY_QUEUE, Binding.DestinationType.QUEUE, OmsRabbitConstants.ORDER_EVENT_EXCHANGE, OmsRabbitConstants.ORDER_CREATE_ORDER_KEY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立 order.release.queue 与交换机绑定
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding orderReleaseOrderBinding() {
|
||||
return new Binding(OmsRabbitConstants.ORDER_RELEASE_QUEUE, Binding.DestinationType.QUEUE, OmsRabbitConstants.ORDER_EVENT_EXCHANGE, OmsRabbitConstants.ORDER_RELEASE_ORDER_KEY, null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产者投递消息后,如果Broker收到消息后,会给生产者一个ACK。生产者通过ACK,可以确认这条消息是否正常发送到Broker,这种方式是消息可靠性投递的核心
|
||||
* 步骤1:yaml文件中添加配置 spring.rabbitmq.publisher-confirm-type: correlated
|
||||
* 步骤2:编写代码
|
||||
*/
|
||||
@PostConstruct
|
||||
public void setConfirmCallback() {
|
||||
|
||||
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
|
||||
|
||||
/**
|
||||
* @param correlationData 发送消息时指定的唯一关联数据(消息id)
|
||||
* @param ack 投递结果
|
||||
* @param cause 失败原因
|
||||
*/
|
||||
@Override
|
||||
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||
if (ack) {
|
||||
log.info("消息投递到交换机成功:[correlationData={}]", correlationData);
|
||||
} else {
|
||||
log.error("消息投递到交换机成功:[correlationData={},原因={}]", correlationData, cause);
|
||||
}
|
||||
|
||||
//TODO 根据ACK状态做对应的消息更新操作
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 注意下面两项必须同时配置
|
||||
* # 开启阶段二(消息从E->Q)的确认回调 Exchange --> Queue returnCallback
|
||||
* spring.rabbitmq.publisher-returns=true
|
||||
*
|
||||
* #为true,则交换机处理消息到路由失败,则会返回给生产者
|
||||
* spring.rabbitmq.template.mandatory=true
|
||||
*/
|
||||
@PostConstruct
|
||||
public void setQueueCallback() {
|
||||
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
|
||||
|
||||
@Override
|
||||
public void returnedMessage(ReturnedMessage returnedMessage) {
|
||||
log.error("路由到队列失败,[消息内容:{},交换机:{},路由件:{},回复码:{},回复文本:{}]",
|
||||
returnedMessage.getMessage(), returnedMessage.getExchange(),
|
||||
returnedMessage.getRoutingKey(), returnedMessage.getReplyCode(), returnedMessage.getReplyText());
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.youlai.mall.oms.config.rabbitmq;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc RabbitMQ 相关常量
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/17
|
||||
*/
|
||||
public class OmsRabbitConstants {
|
||||
|
||||
public static final String ORDER_EVENT_EXCHANGE = "order_event_exchange";
|
||||
|
||||
public static final String ORDER_DELAY_QUEUE = "order.delay.queue";
|
||||
|
||||
public static final String ORDER_RELEASE_QUEUE = "order.release.queue";
|
||||
|
||||
public static final String ORDER_CREATE_ORDER_KEY = "order.create.order";
|
||||
|
||||
public static final String ORDER_RELEASE_ORDER_KEY = "order.release.order";
|
||||
|
||||
public static final Integer ORDER_RELEASE_TTL = 60000;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//package com.youlai.mall.oms.config.thread;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.core.task.AsyncTaskExecutor;
|
||||
//import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
//
|
||||
//import java.util.concurrent.ThreadPoolExecutor;
|
||||
//
|
||||
///**
|
||||
// * @author huawei
|
||||
// * @desc 异步任务线程配置
|
||||
// * @email huawei_code@163.com
|
||||
// * @date 2021/1/16
|
||||
// */
|
||||
//@Configuration
|
||||
//@Slf4j
|
||||
//public class AsyncConfig {
|
||||
//
|
||||
// @Bean("asyncTaskExecutor")
|
||||
// public AsyncTaskExecutor asyncTaskExecutor(ThreadPoolProperties properties) {
|
||||
// log.info("loading asyncTaskExecutor ...");
|
||||
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
// //配置核心线程数
|
||||
// executor.setCorePoolSize(properties.getCorePoolSize());
|
||||
// //配置最大线程数
|
||||
// executor.setMaxPoolSize(properties.getMaxPoolSize());
|
||||
// //配置队列大小
|
||||
// executor.setQueueCapacity(properties.getQueueCapacity());
|
||||
// executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());
|
||||
// //配置线程池中的线程的名称前缀
|
||||
// executor.setThreadNamePrefix("async-service-");
|
||||
//
|
||||
// // 设置拒绝策略:当pool已经达到max size的时候,如何处理新任务
|
||||
// // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
|
||||
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// //执行初始化
|
||||
// executor.initialize();
|
||||
// return executor;
|
||||
// }
|
||||
//}
|
@ -0,0 +1,23 @@
|
||||
//package com.youlai.mall.oms.config.thread;
|
||||
//
|
||||
//import lombok.Data;
|
||||
//import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
//
|
||||
///**
|
||||
// * @author huawei
|
||||
// * @desc 线程池配置属性类
|
||||
// * @email huawei_code@163.com
|
||||
// * @date 2021/1/16
|
||||
// */
|
||||
//@Data
|
||||
//@ConfigurationProperties(prefix = "task.pool")
|
||||
//public class ThreadPoolProperties {
|
||||
//
|
||||
// private Integer corePoolSize;
|
||||
//
|
||||
// private Integer maxPoolSize;
|
||||
//
|
||||
// private Integer queueCapacity;
|
||||
//
|
||||
// private Integer keepAliveSeconds;
|
||||
//}
|
@ -0,0 +1,31 @@
|
||||
package com.youlai.mall.oms.config.token;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc Token 幂等性校验接口注解
|
||||
* 幂等性方案:注解 + 拦截器
|
||||
* 注解:@TokenVerify 注解,该注解有两个属性,generate 和 clean
|
||||
* generate:属性为true是表示请求该方法会生成一个uuid token,同时放入redis中和用户请求中,用于用户下一次请求校验,默认为false
|
||||
* clean:如果属性为true表示请求该方法需要校验token唯一性,并且在校验通过后清除redis中的token
|
||||
* 拦截器:TokenVerifyHandler
|
||||
* 实现原理:拦截所有的请求,如果该请求被 @TokenVerify 注解标识:首先判断该注解属性 generate 是否为true,然后校验属性 clean 是否为true
|
||||
* 最后,在 WebMvcConfig 配置中配置拦截器
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/21
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TokenVerify {
|
||||
|
||||
// 是否生成校验token
|
||||
boolean generate() default false;
|
||||
|
||||
// 是否校验token
|
||||
boolean verify() default false;
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.youlai.mall.oms.config.token;
|
||||
|
||||
import com.youlai.mall.oms.service.TokenService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/21
|
||||
*/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class TokenVerifyHandler extends HandlerInterceptorAdapter {
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HandlerMethod method = (HandlerMethod) handler;
|
||||
TokenVerify tokenVerify = method.getMethodAnnotation(TokenVerify.class);
|
||||
if (tokenVerify != null) {
|
||||
log.debug("请求:{} 使用 @TokenVerify 注解,被拦截器拦截", request.getRequestURI());
|
||||
// 校验token,判断是否重复提交
|
||||
tokenService.checkToken(request);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package com.youlai.mall.oms.controller.admin;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.youlai.common.enums.BusinessTypeEnum;
|
||||
import com.youlai.common.enums.QueryModeEnum;
|
||||
import com.youlai.common.redis.component.BusinessNoGenerator;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.mall.oms.bo.OrderBO;
|
||||
import com.youlai.mall.oms.service.IOmsOrderService;
|
||||
import com.youlai.mall.oms.pojo.OmsOrder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Api(tags = "【系统管理】订单服务")
|
||||
@RestController("")
|
||||
@RequestMapping("/api.admin/v1/orders")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class OrderController {
|
||||
|
||||
private IOmsOrderService iOmsOrderService;
|
||||
|
||||
@ApiOperation(value = "列表分页", httpMethod = "GET")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "queryMode", value = "查询模式", paramType = "query", dataType = "QueryModeEnum"),
|
||||
@ApiImplicitParam(name = "page", value = "页码", paramType = "query", dataType = "Long"),
|
||||
@ApiImplicitParam(name = "limit", value = "每页数量", paramType = "query", dataType = "Long"),
|
||||
@ApiImplicitParam(name = "orderSn", value = "订单编号", paramType = "query", dataType = "String"),
|
||||
@ApiImplicitParam(name = "status", value = "订单状态", paramType = "query", dataType = "Integer"),
|
||||
@ApiImplicitParam(name = "startDate", value = "开始日期", paramType = "query", dataType = "String"),
|
||||
@ApiImplicitParam(name = "endDate", value = "结束日期", paramType = "query", dataType = "String"),
|
||||
})
|
||||
@GetMapping
|
||||
public Result list(
|
||||
String queryMode,
|
||||
Integer page,
|
||||
Integer limit,
|
||||
String orderSn,
|
||||
Integer status,
|
||||
String startDate,
|
||||
String endDate
|
||||
) {
|
||||
QueryModeEnum queryModeEnum = QueryModeEnum.getValue(queryMode);
|
||||
switch (queryModeEnum) {
|
||||
case PAGE:
|
||||
LambdaQueryWrapper<OmsOrder> queryWrapper = new LambdaQueryWrapper<OmsOrder>()
|
||||
.like(StrUtil.isNotBlank(orderSn), OmsOrder::getOrderSn, orderSn)
|
||||
.eq(status != null, OmsOrder::getStatus, status)
|
||||
.apply(StrUtil.isNotBlank(startDate),
|
||||
"date_format (gmt_crate,'%Y-%m-%d') >= date_format('" + startDate + "','%Y-%m-%d')")
|
||||
.apply(StrUtil.isNotBlank(endDate),
|
||||
"date_format (gmt_crate,'%Y-%m-%d') <= date_format('" + endDate + "','%Y-%m-%d')")
|
||||
.orderByDesc(OmsOrder::getGmtModified)
|
||||
.orderByDesc(OmsOrder::getGmtCreate);
|
||||
|
||||
Page<OmsOrder> result = iOmsOrderService.page(new Page<>(page, limit), queryWrapper);
|
||||
|
||||
return Result.success(result.getRecords(), result.getTotal());
|
||||
default:
|
||||
return Result.failed(ResultCode.QUERY_MODE_IS_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "订单详情", httpMethod = "GET")
|
||||
@ApiImplicitParam(name = "id", value = "订单id", required = true, paramType = "path", dataType = "Long")
|
||||
@GetMapping("/{id}")
|
||||
public Result detail(@PathVariable Long id) {
|
||||
OrderBO order = iOmsOrderService.getByOrderId(id);
|
||||
return Result.success(order);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "订单提交", httpMethod = "POST")
|
||||
@ApiImplicitParam(name = "orderBO", value = "实体JSON对象", required = true, paramType = "body", dataType = "OrderBO")
|
||||
@PostMapping
|
||||
public Result add(@RequestBody OrderBO orderBO) {
|
||||
boolean status = iOmsOrderService.save(orderBO);
|
||||
return Result.judge(status);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改订单", httpMethod = "PUT")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "订单id", required = true, paramType = "path", dataType = "Long"),
|
||||
@ApiImplicitParam(name = "order", value = "实体JSON对象", required = true, paramType = "body", dataType = "OmsOrder")
|
||||
})
|
||||
@PutMapping(value = "/{id}")
|
||||
public Result update(
|
||||
@PathVariable Long id,
|
||||
@RequestBody OmsOrder order) {
|
||||
boolean status = iOmsOrderService.updateById(order);
|
||||
return Result.judge(status);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "订单提交", httpMethod = "POST")
|
||||
@PostMapping("/submit")
|
||||
public Result submit(Boolean openTransaction) {
|
||||
boolean status;
|
||||
if (openTransaction) {
|
||||
status = iOmsOrderService.submitWithGlobalTransactional();
|
||||
} else {
|
||||
status = iOmsOrderService.submit();
|
||||
}
|
||||
return Result.judge(status);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "订单详情", httpMethod = "GET")
|
||||
@ApiImplicitParam(name = "id", value = "订单id", required = true, paramType = "path", dataType = "Long")
|
||||
@GetMapping("/{id}/detail")
|
||||
public Result orderDetail(@PathVariable Long id) {
|
||||
OmsOrder order = iOmsOrderService.getById(id);
|
||||
return Result.success(order);
|
||||
}
|
||||
|
||||
private BusinessNoGenerator businessNoGenerator;
|
||||
|
||||
@PostMapping("/order_sn")
|
||||
public Result generateOrderSn() {
|
||||
String orderSn = businessNoGenerator.generate(BusinessTypeEnum.ORDER);
|
||||
log.info("订单编号:{}", orderSn);
|
||||
return Result.success(orderSn);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.mall.oms.bo.CartItemBo;
|
||||
import com.youlai.mall.oms.bo.CartItemCheckBo;
|
||||
import com.youlai.mall.oms.pojo.vo.CartVo;
|
||||
import com.youlai.mall.oms.service.CartService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* 购物车
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
|
||||
@Api(tags = "购物车接口")
|
||||
@RestController
|
||||
@RequestMapping("/api.app/v1/carts")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class CartController {
|
||||
|
||||
private CartService cartService;
|
||||
|
||||
@ApiOperation(value = "查询购物车", httpMethod = "GET")
|
||||
@GetMapping
|
||||
public Result<CartVo> detail() {
|
||||
CartVo cart = cartService.detail();
|
||||
return Result.success(cart);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "添加购物车", httpMethod = "POST")
|
||||
@ApiImplicitParam(name = "skuId", value = "商品SKU Id", required = true, paramType = "param", dataType = "String")
|
||||
@PostMapping
|
||||
public Result<Object> save(@RequestParam("skuId") String skuId) throws ExecutionException, InterruptedException {
|
||||
cartService.save(skuId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改购物车商品数量", httpMethod = "PUT")
|
||||
@ApiImplicitParam(name = "cartItemBo", value = "实体JSON对象", required = true, paramType = "body", dataType = "CartItemBo")
|
||||
@PutMapping
|
||||
public Result<Object> update(@Validated @RequestBody CartItemBo cartItemBo) {
|
||||
cartService.update(cartItemBo);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "是否选择购物车中商品", httpMethod = "PUT")
|
||||
@ApiImplicitParam(name = "cartItemChooseBo", value = "实体JSON对象", required = true, paramType = "body", dataType = "CartItemChooseBo")
|
||||
@PutMapping("/check")
|
||||
public Result<Object> check(@Validated @RequestBody CartItemCheckBo cartItemCheckBo) {
|
||||
cartService.check(cartItemCheckBo);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "全选/全不选择购物车", httpMethod = "PUT")
|
||||
@ApiImplicitParam(name = "check", value = "全选/全不选", required = true, paramType = "param", dataType = "Long")
|
||||
@PutMapping("/checkAll")
|
||||
public Result<Object> checkAll(@RequestParam("check") Integer check) {
|
||||
cartService.checkAll(check);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "批量删除购物车", httpMethod = "DELETE")
|
||||
@ApiImplicitParam(name = "skuIds", value = "商品sku id集合", required = true, paramType = "param", dataType = "List")
|
||||
@DeleteMapping
|
||||
public Result<Boolean> delete(@RequestParam("skuIds") List<String> skuIds) {
|
||||
cartService.deleteBatch(skuIds);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "清空购物车", httpMethod = "GET")
|
||||
@GetMapping("/clear")
|
||||
public Result<Boolean> clear() {
|
||||
cartService.clear();
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderListVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderSubmitResultVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderSubmitVO;
|
||||
import com.youlai.mall.oms.service.OrderService;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import io.swagger.annotations.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
||||
/**
|
||||
* 订单详情表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Api(tags = "APP订单详情接口")
|
||||
@RestController
|
||||
@RequestMapping("/api.app/v1/orders")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class OrderController {
|
||||
|
||||
private OrderService orderService;
|
||||
|
||||
/**
|
||||
* 订单确认信息,生成订单
|
||||
* 如果入参传了skuId,则以当前skuId为准,商品数量默认为1
|
||||
* 如果没有传,则从购物车中获取数据
|
||||
* 如果购物车中没有数据,则返回为空
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value = "订单确认信息", httpMethod = "POST")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "skuId", value = "商品ID", required = true, paramType = "param", dataType = "String"),
|
||||
@ApiImplicitParam(name = "number", value = "商品数量", required = true, defaultValue = "1", paramType = "param", dataType = "Integer")
|
||||
|
||||
})
|
||||
@PostMapping("/confirm")
|
||||
public Result<OrderConfirmVO> confirm(@RequestParam(value = "skuId", required = false) String skuId,
|
||||
@RequestParam(value = "number", defaultValue = "1") Integer number) {
|
||||
return Result.success(orderService.confirm(skuId, number));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "提交订单", httpMethod = "POST")
|
||||
@ApiImplicitParam(name = "submit", value = "提交订单参数", required = true, paramType = "body", dataType = "OrderSubmitVO")
|
||||
@PostMapping("/submit")
|
||||
public Result<OrderSubmitResultVO> submit(@Valid @RequestBody OrderSubmitVO submit) throws ExecutionException, InterruptedException {
|
||||
log.info("提交订单:{}", submit);
|
||||
return Result.success(orderService.submit(submit));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据订单状态查询订单列表
|
||||
* 步骤:
|
||||
* 1、入参 status 表示订单状态
|
||||
* 2、status = 0 表示查询所有订单
|
||||
* 3、已删除订单无法查询
|
||||
*/
|
||||
@ApiOperation("订单列表查询")
|
||||
@GetMapping("/list")
|
||||
public Result<List<OrderListVO>> list(@ApiParam(name = "status",value = "订单状态",required = true,defaultValue = "0")
|
||||
@RequestParam(value = "status",required = true,defaultValue = "0") Integer status) {
|
||||
List<OrderListVO> orderList = orderService.list(status);
|
||||
|
||||
return Result.success(orderList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
@GlobalTransactional
|
||||
//@RequiresPermissions("oms:order:info")
|
||||
public Result<OrderEntity> info(@PathVariable("id") Long id) {
|
||||
OrderEntity order = orderService.getById(id);
|
||||
|
||||
return Result.success(order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:order:save")
|
||||
public Result<Object> save(@RequestBody OrderEntity order) {
|
||||
orderService.save(order);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:order:update")
|
||||
public Result<Object> update(@RequestBody OrderEntity order) {
|
||||
orderService.updateById(order);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
*/
|
||||
@PutMapping("/cancel")
|
||||
@ApiImplicitParam(name = "id", value = "订单ID", required = true, paramType = "param", dataType = "String")
|
||||
public Result<Object> cancelOrder(@RequestParam("id") String id) {
|
||||
orderService.cancelOrder(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@DeleteMapping
|
||||
@ApiImplicitParam(name = "id", value = "订单ID", required = true, paramType = "param", dataType = "String")
|
||||
public Result<Object> delete(@RequestParam("id") String id) {
|
||||
orderService.deleteOrder(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity;
|
||||
import com.youlai.mall.oms.service.OrderDeliveryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单物流记录表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("oms/orderdelivery")
|
||||
public class OrderDeliveryController {
|
||||
@Autowired
|
||||
private OrderDeliveryService orderDeliveryService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermissions("oms:orderdelivery:list")
|
||||
public Result<PageUtils> list(@RequestParam Map<String, Object> params){
|
||||
PageUtils page = orderDeliveryService.queryPage(params);
|
||||
|
||||
return Result.success(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
//@RequiresPermissions("oms:orderdelivery:info")
|
||||
public Result<OrderDeliveryEntity> info(@PathVariable("id") Long id){
|
||||
OrderDeliveryEntity orderDelivery = orderDeliveryService.getById(id);
|
||||
|
||||
return Result.success(orderDelivery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:orderdelivery:save")
|
||||
public Result<Object> save(@RequestBody OrderDeliveryEntity orderDelivery){
|
||||
orderDeliveryService.save(orderDelivery);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:orderdelivery:update")
|
||||
public Result<Object> update(@RequestBody OrderDeliveryEntity orderDelivery){
|
||||
orderDeliveryService.updateById(orderDelivery);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermissions("oms:orderdelivery:delete")
|
||||
public Result<Object> delete(@RequestBody Long[] ids){
|
||||
orderDeliveryService.removeByIds(Arrays.asList(ids));
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
import com.youlai.mall.oms.service.OrderGoodsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单商品信息表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("oms/ordergoods")
|
||||
public class OrderGoodsController {
|
||||
@Autowired
|
||||
private OrderGoodsService orderGoodsService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermissions("oms:ordergoods:list")
|
||||
public Result<PageUtils> list(@RequestParam Map<String, Object> params){
|
||||
PageUtils page = orderGoodsService.queryPage(params);
|
||||
|
||||
return Result.success(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
//@RequiresPermissions("oms:ordergoods:info")
|
||||
public Result<OrderGoodsEntity> info(@PathVariable("id") Long id){
|
||||
OrderGoodsEntity orderGoods = orderGoodsService.getById(id);
|
||||
|
||||
return Result.success(orderGoods);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:ordergoods:save")
|
||||
public Result<Object> save(@RequestBody OrderGoodsEntity orderGoods){
|
||||
orderGoodsService.save(orderGoods);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:ordergoods:update")
|
||||
public Result<Object> update(@RequestBody OrderGoodsEntity orderGoods){
|
||||
orderGoodsService.updateById(orderGoods);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermissions("oms:ordergoods:delete")
|
||||
public Result<Object> delete(@RequestBody Long[] ids){
|
||||
orderGoodsService.removeByIds(Arrays.asList(ids));
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderLogsEntity;
|
||||
import com.youlai.mall.oms.service.OrderLogsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单操作历史记录
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("oms/order/logs")
|
||||
public class OrderLogsController {
|
||||
@Autowired
|
||||
private OrderLogsService orderLogsService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermissions("oms:orderlogs:list")
|
||||
public Result<PageUtils> list(@RequestParam Map<String, Object> params){
|
||||
PageUtils page = orderLogsService.queryPage(params);
|
||||
|
||||
return Result.success(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
//@RequiresPermissions("oms:orderlogs:info")
|
||||
public Result<OrderLogsEntity> info(@PathVariable("id") Long id){
|
||||
OrderLogsEntity orderLogs = orderLogsService.getById(id);
|
||||
|
||||
return Result.success(orderLogs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:orderlogs:save")
|
||||
public Result<Object> save(@RequestBody OrderLogsEntity orderLogs){
|
||||
orderLogsService.save(orderLogs);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:orderlogs:update")
|
||||
public Result<Object> update(@RequestBody OrderLogsEntity orderLogs){
|
||||
orderLogsService.updateById(orderLogs);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermissions("oms:orderlogs:delete")
|
||||
public Result<Object> delete(@RequestBody Long[] ids){
|
||||
orderLogsService.removeByIds(Arrays.asList(ids));
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.utils.EnumUtils;
|
||||
import com.youlai.mall.oms.enums.OrderPayTypeEnum;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderPayEntity;
|
||||
import com.youlai.mall.oms.pojo.form.OrderPayForm;
|
||||
import com.youlai.mall.oms.pojo.vo.PayInfoVO;
|
||||
import com.youlai.mall.oms.service.OrderPayService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 订单支付服务
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Api(tags = "订单支付服务")
|
||||
@RestController
|
||||
@RequestMapping("/api.app/v1/order/pay")
|
||||
@Slf4j
|
||||
public class OrderPayController {
|
||||
@Autowired
|
||||
private OrderPayService orderPayService;
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
* 1、根据支付类型选择正确支付方式(1:微信支付;2:支付宝支付;3:余额支付)
|
||||
* 2、根据订单id查询订单价格,进行支付(在整个支付的过程中进行事务控制,保证整个操作的原子性)
|
||||
* 3、将支付结果记录日志并返回给前端
|
||||
*
|
||||
* @param orderPayForm 订单支付表单
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation("订单支付")
|
||||
@PostMapping
|
||||
public Result doPay(@Validated @RequestBody OrderPayForm orderPayForm) {
|
||||
OrderPayTypeEnum payTypeEnum = EnumUtils.getByCode(orderPayForm.getPayType(), OrderPayTypeEnum.class);
|
||||
if (payTypeEnum == null) {
|
||||
return Result.failed("请选择正确的支付方式");
|
||||
}
|
||||
log.info("订单支付,orderId={},支付方式={}", orderPayForm.getOrderId(), payTypeEnum.desc);
|
||||
if (payTypeEnum == OrderPayTypeEnum.BALANCE) {
|
||||
orderPayService.balancePay(orderPayForm.getOrderId());
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取订单支付详情")
|
||||
@GetMapping("/info")
|
||||
public Result<PayInfoVO> info(@ApiParam(name = "orderId", value = "订单ID", required = true, defaultValue = "1") @RequestParam("orderId") String orderId) {
|
||||
return Result.success(orderPayService.info(orderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
public Result<PageUtils> list(@RequestParam Map<String, Object> params) {
|
||||
PageUtils page = orderPayService.queryPage(params);
|
||||
|
||||
return Result.success(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
//@RequiresPermissions("oms:orderpay:info")
|
||||
public Result<OrderPayEntity> info(@PathVariable("id") Long id) {
|
||||
OrderPayEntity orderPay = orderPayService.getById(id);
|
||||
|
||||
return Result.success(orderPay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:orderpay:save")
|
||||
public Result<Object> save(@RequestBody OrderPayEntity orderPay) {
|
||||
orderPayService.save(orderPay);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:orderpay:update")
|
||||
public Result<Object> update(@RequestBody OrderPayEntity orderPay) {
|
||||
orderPayService.updateById(orderPay);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermissions("oms:orderpay:delete")
|
||||
public Result<Object> delete(@RequestBody Long[] ids) {
|
||||
orderPayService.removeByIds(Arrays.asList(ids));
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.youlai.mall.oms.controller.app;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderSettingEntity;
|
||||
import com.youlai.mall.oms.service.OrderSettingService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 订单配置信息
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("oms/ordersetting")
|
||||
public class OrderSettingController {
|
||||
@Autowired
|
||||
private OrderSettingService orderSettingService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermissions("oms:ordersetting:list")
|
||||
public Result<PageUtils> list(@RequestParam Map<String, Object> params){
|
||||
PageUtils page = orderSettingService.queryPage(params);
|
||||
|
||||
return Result.success(page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
//@RequiresPermissions("oms:ordersetting:info")
|
||||
public Result<OrderSettingEntity> info(@PathVariable("id") Long id){
|
||||
OrderSettingEntity orderSetting = orderSettingService.getById(id);
|
||||
|
||||
return Result.success(orderSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("oms:ordersetting:save")
|
||||
public Result<Object> save(@RequestBody OrderSettingEntity orderSetting){
|
||||
orderSettingService.save(orderSetting);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("oms:ordersetting:update")
|
||||
public Result<Object> update(@RequestBody OrderSettingEntity orderSetting){
|
||||
orderSettingService.updateById(orderSetting);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermissions("oms:ordersetting:delete")
|
||||
public Result<Object> delete(@RequestBody Long[] ids){
|
||||
orderSettingService.removeByIds(Arrays.asList(ids));
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 订单详情表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderDao extends BaseMapper<OrderEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 订单物流记录表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderDeliveryDao extends BaseMapper<OrderDeliveryEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 订单商品信息表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderGoodsDao extends BaseMapper<OrderGoodsEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderLogsEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 订单操作历史记录
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderLogsDao extends BaseMapper<OrderLogsEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderPayEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 支付信息表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderPayDao extends BaseMapper<OrderPayEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.youlai.mall.oms.dao;
|
||||
|
||||
import com.youlai.mall.oms.pojo.entity.OrderSettingEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 订单配置信息
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderSettingDao extends BaseMapper<OrderSettingEntity> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.youlai.mall.oms.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.youlai.mall.oms.pojo.OmsOrderItem;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface OmsOrderItemMapper extends BaseMapper<OmsOrderItem> {
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.youlai.mall.oms.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.youlai.mall.oms.pojo.OmsOrder;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface OmsOrderMapper extends BaseMapper<OmsOrder> {
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.youlai.mall.oms.bo.CartItemBo;
|
||||
import com.youlai.mall.oms.bo.CartItemCheckBo;
|
||||
import com.youlai.mall.oms.pojo.vo.CartVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* 购物车业务接口
|
||||
*/
|
||||
public interface CartService {
|
||||
|
||||
/**
|
||||
* 添加商品到购物车
|
||||
* @param skuId 商品模型
|
||||
*/
|
||||
void save(String skuId) throws ExecutionException, InterruptedException;
|
||||
|
||||
/**
|
||||
* 修改购物车商品数量
|
||||
* @param cartItemBo
|
||||
*/
|
||||
void update(CartItemBo cartItemBo);
|
||||
|
||||
/**
|
||||
* 修改购物车中商品是否选中状态
|
||||
* @param cartItemCheckBo
|
||||
*/
|
||||
void check(CartItemCheckBo cartItemCheckBo);
|
||||
|
||||
/**
|
||||
* 全选/全不选购物车
|
||||
* @param check
|
||||
*/
|
||||
void checkAll(Integer check);
|
||||
|
||||
/**
|
||||
* 删除购物车中的商品
|
||||
* @param skuId 商品id
|
||||
*/
|
||||
void delete(Long skuId);
|
||||
|
||||
/**
|
||||
* 批量删除购物车中的商品
|
||||
* @param skuIds 商品id集合
|
||||
*/
|
||||
void deleteBatch(List<String> skuIds);
|
||||
|
||||
/**
|
||||
* 查询购物车详情
|
||||
* @return
|
||||
*/
|
||||
CartVo detail();
|
||||
|
||||
/**
|
||||
* 清空购物车
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* 清空购物车中已选择商品
|
||||
*/
|
||||
void cleanSelected();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.mall.oms.pojo.OmsOrderItem;
|
||||
|
||||
public interface IOmsOrderItemService extends IService<OmsOrderItem> {
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.mall.oms.bo.OrderBO;
|
||||
import com.youlai.mall.oms.pojo.OmsOrder;
|
||||
|
||||
public interface IOmsOrderService extends IService<OmsOrder> {
|
||||
|
||||
boolean save(OrderBO orderBO);
|
||||
|
||||
OrderBO getByOrderId(Long id);
|
||||
|
||||
boolean submit();
|
||||
|
||||
boolean submitWithGlobalTransactional();
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单物流记录表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderDeliveryService extends IService<OrderDeliveryEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单商品信息表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderGoodsService extends IService<OrderGoodsEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
List<OrderGoodsEntity> getByOrderId(Long orderId);
|
||||
|
||||
Map<Long,List<OrderGoodsEntity>> getByOrderIds(List<Long> orderIds);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderLogsEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单操作历史记录
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderLogsService extends IService<OrderLogsEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 添加订单操作日志记录
|
||||
* @param orderId 订单id
|
||||
* @param orderStatus 订单状态
|
||||
* @param user 操作人员
|
||||
* @param detail 描述信息
|
||||
*/
|
||||
void addOrderLogs(Long orderId, Integer orderStatus, String user, String detail);
|
||||
|
||||
/**
|
||||
* 添加订单操作日志记录
|
||||
* @param orderId 订单id
|
||||
* @param orderStatus 订单状态
|
||||
* @param detail 描述
|
||||
*/
|
||||
void addOrderLogs(Long orderId, Integer orderStatus, String detail);
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderPayEntity;
|
||||
import com.youlai.mall.oms.pojo.vo.PayInfoVO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付信息表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderPayService extends IService<OrderPayEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 获取订单支付详情
|
||||
* @param orderId 订单id
|
||||
* @return
|
||||
*/
|
||||
PayInfoVO info(String orderId);
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
* @param orderId 订单ID
|
||||
*/
|
||||
void balancePay(String orderId);
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.rabbitmq.client.Channel;
|
||||
import org.springframework.amqp.core.Message;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc Order RabbitMQ 业务类
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/2/4
|
||||
*/
|
||||
public interface OrderRabbitService {
|
||||
|
||||
/**
|
||||
* 订单超时释放
|
||||
*
|
||||
* @param orderSn
|
||||
* @param message
|
||||
* @param channel
|
||||
*/
|
||||
void releaseOrder(String orderSn, Message message, Channel channel);
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderListVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderSubmitResultVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderSubmitVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* 订单详情表
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderService extends IService<OrderEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 订单确认页信息
|
||||
*
|
||||
* @param skuId 商品id,非必填参数
|
||||
* @param number 商品数量
|
||||
* @return
|
||||
*/
|
||||
OrderConfirmVO confirm(String skuId, Integer number);
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
*
|
||||
* @param submit 订单提交参数
|
||||
*/
|
||||
OrderSubmitResultVO submit(OrderSubmitVO submit) throws ExecutionException, InterruptedException;
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单详情
|
||||
*
|
||||
* @param orderSn 订单号
|
||||
* @return
|
||||
*/
|
||||
OrderEntity getByOrderSn(String orderSn);
|
||||
|
||||
/**
|
||||
* 系统关闭订单
|
||||
*
|
||||
* @param orderSn 订单号
|
||||
*/
|
||||
boolean closeOrderBySystem(String orderSn);
|
||||
|
||||
/**
|
||||
* 取消订单接口
|
||||
*
|
||||
* @param id 订单id
|
||||
* @return 是否取消成功
|
||||
*/
|
||||
boolean cancelOrder(String id);
|
||||
|
||||
/**
|
||||
* 删除订单
|
||||
*
|
||||
* @param id 订单id
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
boolean deleteOrder(String id);
|
||||
|
||||
/**
|
||||
* 订单列表查询
|
||||
*
|
||||
* @param status 订单状态
|
||||
* @return 订单列表
|
||||
*/
|
||||
List<OrderListVO> list(Integer status);
|
||||
|
||||
/**
|
||||
* 根据订单id获取订单信息
|
||||
*
|
||||
* @param id 订单id
|
||||
* @return 订单信息
|
||||
*/
|
||||
OrderEntity getByOrderId(String id);
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderSettingEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单配置信息
|
||||
*
|
||||
* @author huawei
|
||||
* @email huawei_code@163.com
|
||||
* @date 2020-12-30 22:31:10
|
||||
*/
|
||||
public interface OrderSettingService extends IService<OrderSettingEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/21
|
||||
*/
|
||||
public interface TokenService {
|
||||
|
||||
/**
|
||||
* 为当前用户请求生成Token
|
||||
*
|
||||
* @return token
|
||||
*/
|
||||
String generateToken();
|
||||
|
||||
/**
|
||||
* 校验 Token 是否正确
|
||||
* @param request 当前请求
|
||||
*/
|
||||
void checkToken(HttpServletRequest request);
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.web.util.RequestUtils;
|
||||
import com.youlai.mall.pms.api.ProductFeignService;
|
||||
import com.youlai.mall.oms.bo.CartItemBo;
|
||||
import com.youlai.mall.oms.bo.CartItemCheckBo;
|
||||
import com.youlai.mall.pms.pojo.dto.SkuDTO;
|
||||
import com.youlai.mall.oms.pojo.vo.CartItemVo;
|
||||
import com.youlai.mall.oms.pojo.vo.CartVo;
|
||||
import com.youlai.mall.oms.service.CartService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.BoundHashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.youlai.common.redis.constant.RedisKeyConstants.MALL_CART_KEY;
|
||||
|
||||
/**
|
||||
* 购物车模块搭建步骤
|
||||
* 1、用户登录后才能操作购物车
|
||||
* *********添加购物车*************
|
||||
* 1、获取当前登录用户
|
||||
* 2、添加商品到购物车
|
||||
* 2.1、如果购物车中已经有该商品的相关数据
|
||||
* 2.1.1、修改购物车商品数量
|
||||
* 2.2、如果购物车中没有该商品,新增该商品
|
||||
* 2.2.1、调用商品服务查询商品sku详情
|
||||
* 2.2.2、封装CartItem实体类
|
||||
* *********修改购物车*************
|
||||
* *********删除购物车*************
|
||||
* *********查询购物车*************
|
||||
*/
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class CartServiceImpl implements CartService {
|
||||
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
private ProductFeignService productFeignService;
|
||||
|
||||
|
||||
@Override
|
||||
public void save(String skuId) throws ExecutionException, InterruptedException {
|
||||
log.info("添加商品到购物车,form:{}", skuId);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
if (cartOps.get(skuId) != null) {
|
||||
CartItemVo cartItem = (CartItemVo) cartOps.get(skuId);
|
||||
Integer number = cartItem.getNumber() + 1;
|
||||
cartItem.setNumber(number);
|
||||
cartOps.put(skuId, cartItem);
|
||||
return;
|
||||
}
|
||||
|
||||
CartItemVo cartItem = new CartItemVo();
|
||||
// 添加新商品到购物车
|
||||
CompletableFuture<Void> skuInfoFuture = CompletableFuture.runAsync(() -> {
|
||||
//1、远程查询商品详情
|
||||
Result<SkuDTO> skuInfo = productFeignService.getSkuById(Long.parseLong(skuId));
|
||||
SkuDTO data = skuInfo.getData();
|
||||
cartItem.setSkuId(Long.parseLong(skuId));
|
||||
cartItem.setChecked(true);
|
||||
cartItem.setSkuName(data.getName());
|
||||
cartItem.setSkuImg(data.getPicUrl());
|
||||
cartItem.setNumber(1);
|
||||
cartItem.setPrice(data.getPrice());
|
||||
cartItem.setStock(data.getStock());
|
||||
|
||||
});
|
||||
//2、远程查询商品属性
|
||||
//3、远程查询库存
|
||||
CompletableFuture<Void> allOf = CompletableFuture.allOf(skuInfoFuture);
|
||||
allOf.get();
|
||||
cartOps.put(skuId, cartItem);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CartItemBo cartItemBo) {
|
||||
log.info("修改购物车商品数量,form:{}", cartItemBo);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
CartItemVo cartItem = (CartItemVo) cartOps.get(cartItemBo.getSkuId().toString());
|
||||
if (cartItem == null) {
|
||||
return;
|
||||
}
|
||||
cartItem.setNumber(cartItemBo.getNumber());
|
||||
cartOps.put(cartItemBo.getSkuId().toString(), cartItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(CartItemCheckBo cartItemCheckBo) {
|
||||
log.info("修改购物车商品选中状态,form:{}", cartItemCheckBo);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
CartItemVo cartItem = (CartItemVo) cartOps.get(cartItemCheckBo.getSkuId().toString());
|
||||
if (cartItem == null) {
|
||||
return;
|
||||
}
|
||||
cartItem.setChecked(cartItemCheckBo.getCheck() == 1);
|
||||
cartOps.put(cartItemCheckBo.getSkuId().toString(), cartItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAll(Integer check) {
|
||||
log.info("全选/全不选购物车商品状态,check:{}", check);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
for (Object value : cartOps.values()) {
|
||||
CartItemVo cartItem = (CartItemVo) value;
|
||||
cartItem.setChecked(check == 1);
|
||||
cartOps.put(cartItem.getSkuId().toString(), cartItem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long skuId) {
|
||||
log.info("删除购物车,商品id:{}", skuId);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
cartOps.delete(skuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBatch(List<String> skuIds) {
|
||||
log.info("批量删除购物车,商品id集合:{}", skuIds);
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
for (String skuId : skuIds) {
|
||||
cartOps.delete(skuId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CartVo detail() {
|
||||
log.info("查询购物车详情");
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
List<CartItemVo> items = cartOps.values();
|
||||
CartVo cartVo = new CartVo();
|
||||
cartVo.setItems(items);
|
||||
return cartVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
log.info("清空购物车");
|
||||
Long userId = RequestUtils.getUserId();
|
||||
String cartKey = MALL_CART_KEY + userId;
|
||||
redisTemplate.delete(cartKey);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanSelected() {
|
||||
log.info("清空购物车中已选择商品");
|
||||
BoundHashOperations cartOps = getCartOps();
|
||||
for (Object value : cartOps.values()) {
|
||||
CartItemVo cartItem = (CartItemVo) value;
|
||||
if (cartItem.isChecked()) {
|
||||
log.info("清空购物车中商品,商品id:{} | 名称:{}", cartItem.getSkuId(), cartItem.getSkuName());
|
||||
cartOps.delete(cartItem.getSkuId().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BoundHashOperations getCartOps() {
|
||||
Long userId = RequestUtils.getUserId();
|
||||
String cartKey = MALL_CART_KEY + userId;
|
||||
BoundHashOperations operations = redisTemplate.boundHashOps(cartKey);
|
||||
return operations;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.mall.oms.mapper.OmsOrderItemMapper;
|
||||
import com.youlai.mall.oms.pojo.OmsOrderItem;
|
||||
import com.youlai.mall.oms.service.IOmsOrderItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class OmsOrderItemServiceImpl extends ServiceImpl<OmsOrderItemMapper, OmsOrderItem> implements IOmsOrderItemService {
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.mall.oms.bo.OrderBO;
|
||||
import com.youlai.mall.oms.mapper.OmsOrderMapper;
|
||||
import com.youlai.mall.oms.pojo.OmsOrder;
|
||||
import com.youlai.mall.oms.pojo.OmsOrderItem;
|
||||
import com.youlai.mall.oms.service.IOmsOrderItemService;
|
||||
import com.youlai.mall.oms.service.IOmsOrderService;
|
||||
import com.youlai.mall.pms.api.ProductFeignService;
|
||||
import com.youlai.mall.ums.api.MemberFeignService;
|
||||
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> implements IOmsOrderService {
|
||||
|
||||
private IOmsOrderItemService iOmsOrderItemService;
|
||||
|
||||
private MemberFeignService memberFeignService;
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
*
|
||||
* @param orderBO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean save(OrderBO orderBO) {
|
||||
// 订单
|
||||
OmsOrder order = orderBO.getOrder();
|
||||
String orderSn = IdUtil.createSnowflake(1, 1).nextIdStr();
|
||||
order.setOrderSn(orderSn);
|
||||
this.save(order);
|
||||
|
||||
// 订单明细
|
||||
List<OmsOrderItem> orderItems = orderBO.getOrderItems();
|
||||
if (CollectionUtil.isEmpty(orderItems)) {
|
||||
throw new BizException("订单明细不能为空");
|
||||
}
|
||||
orderItems.forEach(item -> {
|
||||
item.setOrderId(order.getId());
|
||||
});
|
||||
iOmsOrderItemService.saveBatch(orderItems);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderBO getByOrderId(Long orderId) {
|
||||
OrderBO orderBO = new OrderBO();
|
||||
// 订单
|
||||
OmsOrder order = this.getById(orderId);
|
||||
if (order == null) {
|
||||
throw new BizException("订单不存在");
|
||||
}
|
||||
// 订单明细
|
||||
List<OmsOrderItem> orderItems = iOmsOrderItemService.list(
|
||||
new LambdaQueryWrapper<OmsOrderItem>().eq(OmsOrderItem::getOrderId, orderId)
|
||||
);
|
||||
orderItems = Optional.ofNullable(orderItems).orElse(new ArrayList<>());
|
||||
|
||||
// 会员明细
|
||||
Result<MemberDTO> result = memberFeignService.getUserById(order.getUserId());
|
||||
MemberDTO member = result.getData();
|
||||
orderBO.setOrder(order).setOrderItems(orderItems).setMember(member);
|
||||
return orderBO;
|
||||
}
|
||||
|
||||
private ProductFeignService productFeignService;
|
||||
|
||||
@Override
|
||||
public boolean submit() {
|
||||
log.info("扣减库存----begin");
|
||||
productFeignService.updateStock(1l, -1);
|
||||
log.info("扣减库存----end");
|
||||
|
||||
log.info("增加积分----begin");
|
||||
memberFeignService.updatePoint(1l, 10);
|
||||
log.info("增加积分----end");
|
||||
|
||||
log.info("修改订单状态----begin");
|
||||
boolean result = this.update(new LambdaUpdateWrapper<OmsOrder>().eq(OmsOrder::getId, 1l).set(OmsOrder::getStatus, 901));
|
||||
log.info("修改订单状态----end");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@GlobalTransactional(rollbackFor = Exception.class)
|
||||
public boolean submitWithGlobalTransactional() {
|
||||
log.info("扣减库存----begin");
|
||||
productFeignService.updateStock(1l, -1);
|
||||
log.info("扣减库存----end");
|
||||
|
||||
log.info("增加积分----begin");
|
||||
memberFeignService.updatePoint(1l, 10);
|
||||
log.info("增加积分----end");
|
||||
|
||||
log.info("修改订单状态----begin");
|
||||
boolean result = this.update(new LambdaUpdateWrapper<OmsOrder>().eq(OmsOrder::getId, 1l).set(OmsOrder::getStatus, 901));
|
||||
log.info("修改订单状态----end");
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.dao.OrderDeliveryDao;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity;
|
||||
import com.youlai.mall.oms.service.OrderDeliveryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service("orderDeliveryService")
|
||||
public class OrderDeliveryServiceImpl extends ServiceImpl<OrderDeliveryDao, OrderDeliveryEntity> implements OrderDeliveryService {
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderDeliveryEntity> page = this.page(
|
||||
new Query<OrderDeliveryEntity>().getPage(params),
|
||||
new QueryWrapper<OrderDeliveryEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.dao.OrderGoodsDao;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
import com.youlai.mall.oms.service.OrderGoodsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service("orderGoodsService")
|
||||
@Slf4j
|
||||
public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsDao, OrderGoodsEntity> implements OrderGoodsService {
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderGoodsEntity> page = this.page(
|
||||
new Query<OrderGoodsEntity>().getPage(params),
|
||||
new QueryWrapper<OrderGoodsEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OrderGoodsEntity> getByOrderId(Long orderId) {
|
||||
log.info("根据订单id,查询订单商品列表,orderId={}", orderId);
|
||||
QueryWrapper<OrderGoodsEntity> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.ge("order_id", orderId);
|
||||
return baseMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, List<OrderGoodsEntity>> getByOrderIds(List<Long> orderIds) {
|
||||
QueryWrapper<OrderGoodsEntity> orderGoodsQuery = new QueryWrapper<>();
|
||||
orderGoodsQuery.in("order_id", orderIds).orderByDesc("order_id", "id");
|
||||
List<OrderGoodsEntity> orderGoods = this.list(orderGoodsQuery);
|
||||
if (orderGoods == null || orderGoods.size() == 0) {
|
||||
log.info("根据订单ID列表查询商品为空,orderIds={}", orderIds);
|
||||
return new HashMap<>(8);
|
||||
}
|
||||
Map<Long, List<OrderGoodsEntity>> orderGoodsMap = orderGoods.stream()
|
||||
.collect(Collectors.groupingBy(OrderGoodsEntity::getOrderId));
|
||||
return orderGoodsMap;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.common.web.util.RequestUtils;
|
||||
import com.youlai.mall.oms.dao.OrderLogsDao;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderLogsEntity;
|
||||
import com.youlai.mall.oms.service.OrderLogsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service("orderLogsService")
|
||||
@Slf4j
|
||||
public class OrderLogsServiceImpl extends ServiceImpl<OrderLogsDao, OrderLogsEntity> implements OrderLogsService {
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderLogsEntity> page = this.page(
|
||||
new Query<OrderLogsEntity>().getPage(params),
|
||||
new QueryWrapper<OrderLogsEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOrderLogs(Long orderId, Integer orderStatus, String user, String detail) {
|
||||
try {
|
||||
log.info("添加订单操作日志,orderId={},detail={}", orderId, detail);
|
||||
OrderLogsEntity orderLogs = new OrderLogsEntity();
|
||||
orderLogs.setDetail(detail);
|
||||
orderLogs.setOrderId(orderId);
|
||||
orderLogs.setOrderStatus(orderStatus);
|
||||
orderLogs.setUser(user);
|
||||
baseMapper.insert(orderLogs);
|
||||
} catch (Exception e) {
|
||||
log.error("添加订单操作日志失败,orderId={}", orderId, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOrderLogs(Long orderId, Integer orderStatus, String detail) {
|
||||
Long userId = RequestUtils.getUserId();
|
||||
addOrderLogs(orderId, orderStatus, userId.toString(), detail);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.common.utils.EnumUtils;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.common.web.util.RequestUtils;
|
||||
import com.youlai.mall.oms.dao.OrderPayDao;
|
||||
import com.youlai.mall.oms.enums.OrderPayTypeEnum;
|
||||
import com.youlai.mall.oms.enums.OrderStatusEnum;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderPayEntity;
|
||||
import com.youlai.mall.oms.pojo.vo.PayInfoVO;
|
||||
import com.youlai.mall.oms.service.OrderLogsService;
|
||||
import com.youlai.mall.oms.service.OrderPayService;
|
||||
import com.youlai.mall.oms.service.OrderService;
|
||||
import com.youlai.mall.ums.api.MemberFeignService;
|
||||
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@Service("orderPayService")
|
||||
public class OrderPayServiceImpl extends ServiceImpl<OrderPayDao, OrderPayEntity> implements OrderPayService {
|
||||
|
||||
private OrderService orderService;
|
||||
|
||||
private OrderLogsService orderLogsService;
|
||||
|
||||
private MemberFeignService memberFeignService;
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderPayEntity> page = this.page(
|
||||
new Query<OrderPayEntity>().getPage(params),
|
||||
new QueryWrapper<OrderPayEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayInfoVO info(String orderId) {
|
||||
Long userId = RequestUtils.getUserId();
|
||||
PayInfoVO payInfoVO = new PayInfoVO();
|
||||
// 1、获取订单应支付金额
|
||||
OrderEntity orderEntity = orderService.getByOrderId(orderId);
|
||||
payInfoVO.setPayPrice(orderEntity.getPayAmount());
|
||||
|
||||
// 2、获取会员余额
|
||||
try {
|
||||
Result<MemberDTO> memberInfo = memberFeignService.getUserById(RequestUtils.getUserId());
|
||||
if (memberInfo != null && memberInfo.getCode().equals(ResultCode.SUCCESS.getCode())) {
|
||||
MemberDTO data = memberInfo.getData();
|
||||
if (data != null) {
|
||||
payInfoVO.setBalance(data.getBalance());
|
||||
} else {
|
||||
log.error("获取会员信息失败,userId={}", userId);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取会员余额失败,userId={}", userId, e);
|
||||
}
|
||||
|
||||
return payInfoVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@GlobalTransactional(rollbackFor = Exception.class)
|
||||
public void balancePay(String orderId) {
|
||||
// 1、查询订单详情,判断订单状态是否是待支付状态
|
||||
log.info("订单进入支付流程,orderId:{}", orderId);
|
||||
OrderEntity order = orderService.getByOrderId(orderId);
|
||||
OrderStatusEnum orderStatusEnum = EnumUtils.getByCode(order.getStatus(), OrderStatusEnum.class);
|
||||
if (orderStatusEnum != OrderStatusEnum.NEED_PAY) {
|
||||
log.error("订单状态异常无法支付,orderStatus={}", orderStatusEnum.desc);
|
||||
throw new BizException("订单" + orderStatusEnum.desc);
|
||||
}
|
||||
|
||||
// 2、查询用户信息,判断用户余额是否足够
|
||||
Long userId = RequestUtils.getUserId();
|
||||
Result<MemberDTO> memberInfo = memberFeignService.getUserById(userId);
|
||||
MemberDTO memberInfoData = memberInfo.getData();
|
||||
if (memberInfo == null || !memberInfo.getCode().equals(ResultCode.SUCCESS.getCode()) || memberInfoData == null) {
|
||||
log.error("会员信息异常,无法支付");
|
||||
throw new BizException("会员信息异常,无法支付");
|
||||
}
|
||||
if (memberInfoData.getBalance() < order.getPayAmount()) {
|
||||
log.error("会员余额不足,无法支付,请先充值");
|
||||
throw new BizException("会员余额不足,无法支付,请先充值");
|
||||
}
|
||||
|
||||
// 3、更新用户余额
|
||||
memberFeignService.updateBalance(userId, order.getPayAmount());
|
||||
|
||||
// 4、更新订单状态、添加订单支付记录、添加订单操作记录
|
||||
order.setStatus(OrderStatusEnum.IS_PAY.code);
|
||||
order.setPayTime(new Date());
|
||||
order.setPayType(OrderPayTypeEnum.BALANCE.code);
|
||||
orderService.updateById(order);
|
||||
this.save(createOrderPay(order, OrderPayTypeEnum.BALANCE.code));
|
||||
orderLogsService.addOrderLogs(order.getId(), OrderStatusEnum.IS_PAY.code, userId.toString(), "支付订单");
|
||||
}
|
||||
|
||||
private OrderPayEntity createOrderPay(OrderEntity order, Integer payType) {
|
||||
OrderPayEntity payEntity = new OrderPayEntity();
|
||||
payEntity.setOrderId(order.getId());
|
||||
payEntity.setPayAmount(order.getPayAmount());
|
||||
payEntity.setPayTime(new Date());
|
||||
payEntity.setPayType(payType);
|
||||
return payEntity;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.mall.oms.config.rabbitmq.OmsRabbitConstants;
|
||||
import com.youlai.mall.oms.enums.OrderStatusEnum;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
import com.youlai.mall.oms.service.OrderGoodsService;
|
||||
import com.youlai.mall.oms.service.OrderRabbitService;
|
||||
import com.youlai.mall.oms.service.OrderService;
|
||||
import com.youlai.mall.pms.api.ProductFeignService;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuStockVO;
|
||||
import com.youlai.mall.pms.pojo.vo.WareSkuStockVO;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RabbitListener(queues = OmsRabbitConstants.ORDER_RELEASE_QUEUE)
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class OrderRabbitServiceImpl implements OrderRabbitService {
|
||||
|
||||
private OrderService orderService;
|
||||
|
||||
private OrderGoodsService orderGoodsService;
|
||||
|
||||
private ProductFeignService productFeignService;
|
||||
|
||||
/**
|
||||
* 接收超时订单消息
|
||||
* 订单已支付 - 确认接收消息
|
||||
* 订单未支付 - 关闭订单,释放库存
|
||||
* 出现异常,消费消息失败,将数据重新放入队列,等待下次消费
|
||||
*
|
||||
* @param orderSn
|
||||
*/
|
||||
@Override
|
||||
@RabbitHandler
|
||||
@GlobalTransactional(rollbackFor = Exception.class)
|
||||
public void releaseOrder(String orderSn, Message message, Channel channel) {
|
||||
long msgTag = message.getMessageProperties().getDeliveryTag();
|
||||
log.info("获取到消息,msgTag={},message={},body={}", msgTag, message.toString(), orderSn);
|
||||
|
||||
try {
|
||||
OrderEntity order = orderService.getByOrderSn(orderSn);
|
||||
if (order.getStatus().equals(OrderStatusEnum.NEED_PAY.code)) {
|
||||
if (orderService.closeOrderBySystem(orderSn)){
|
||||
releaseStock(order.getId());
|
||||
}
|
||||
}
|
||||
channel.basicAck(msgTag, false);
|
||||
} catch (Exception e) {
|
||||
log.error("关闭订单失败,orderSn={}", orderSn);
|
||||
throw new BizException("关闭订单失败,orderSn=" + orderSn);
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseStock(Long orderId) {
|
||||
List<OrderGoodsEntity> orderGoods = orderGoodsService.getByOrderId(orderId);
|
||||
List<SkuStockVO> items = orderGoods.stream().map(good -> {
|
||||
SkuStockVO itemVO = new SkuStockVO();
|
||||
itemVO.setSkuId(good.getSkuId());
|
||||
itemVO.setNumber(good.getSkuQuantity());
|
||||
return itemVO;
|
||||
}).collect(Collectors.toList());
|
||||
WareSkuStockVO wareSkuStock = new WareSkuStockVO();
|
||||
wareSkuStock.setItems(items);
|
||||
Result result = productFeignService.releaseStock(wareSkuStock);
|
||||
if (result == null || !StrUtil.equals(result.getCode(), ResultCode.SUCCESS.getCode())) {
|
||||
log.error("释放库存异常,商品列表={}", items);
|
||||
throw new BizException("关闭订单失败,释放库存错误");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,451 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.common.utils.EnumUtils;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.common.web.util.BeanMapperUtils;
|
||||
import com.youlai.common.web.util.RequestUtils;
|
||||
import com.youlai.mall.oms.config.rabbitmq.OmsRabbitConstants;
|
||||
import com.youlai.mall.oms.dao.OrderDao;
|
||||
import com.youlai.mall.oms.dao.OrderDeliveryDao;
|
||||
import com.youlai.mall.oms.dao.OrderGoodsDao;
|
||||
import com.youlai.mall.oms.enums.OrderStatusEnum;
|
||||
import com.youlai.mall.oms.enums.OrderTypeEnum;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderEntity;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderGoodsEntity;
|
||||
import com.youlai.mall.oms.pojo.vo.*;
|
||||
import com.youlai.mall.oms.service.CartService;
|
||||
import com.youlai.mall.oms.service.OrderGoodsService;
|
||||
import com.youlai.mall.oms.service.OrderLogsService;
|
||||
import com.youlai.mall.oms.service.OrderService;
|
||||
import com.youlai.mall.pms.api.ProductFeignService;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuInfoVO;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuStockVO;
|
||||
import com.youlai.mall.pms.pojo.vo.WareSkuStockVO;
|
||||
import com.youlai.mall.ums.api.MemberFeignService;
|
||||
import com.youlai.mall.ums.pojo.dto.UmsAddressDTO;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
@Service("orderService")
|
||||
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
|
||||
|
||||
private static final ThreadLocal<OrderSubmitVO> threadOrderSubmit = new ThreadLocal<>();
|
||||
|
||||
private CartService cartService;
|
||||
|
||||
private ProductFeignService productFeignService;
|
||||
|
||||
private MemberFeignService memberFeignService;
|
||||
|
||||
private AsyncTaskExecutor executor;
|
||||
|
||||
private OrderDao orderDao;
|
||||
|
||||
private OrderGoodsDao orderGoodsDao;
|
||||
|
||||
private OrderDeliveryDao orderDeliveryDao;
|
||||
|
||||
private OrderLogsService orderLogsService;
|
||||
|
||||
private OrderGoodsService orderGoodsService;
|
||||
|
||||
private RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderEntity> page = this.page(
|
||||
new Query<OrderEntity>().getPage(params),
|
||||
new QueryWrapper<OrderEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderConfirmVO confirm(String skuId, Integer number) {
|
||||
List<OrderItemVO> items = getOrderItemFromCart(skuId, number);
|
||||
if (CollectionUtil.isEmpty(items)) {
|
||||
log.info("订单商品列表为空,无法创建订单确认信息");
|
||||
return new OrderConfirmVO();
|
||||
}
|
||||
|
||||
// feign调用商品接口,获取商品信息
|
||||
Map<Long, SkuInfoVO> skuMap = new HashMap<>(items.size());
|
||||
List<String> skuIds = items.stream().map(item -> item.getSkuId().toString()).collect(Collectors.toList());
|
||||
List<SkuInfoVO> skuInfos = productFeignService.infos(skuIds).getData();
|
||||
if (!CollectionUtil.isEmpty(skuInfos)) {
|
||||
skuMap = skuInfos.stream().collect(Collectors.toMap(SkuInfoVO::getSkuId, Function.identity()));
|
||||
}
|
||||
|
||||
for (OrderItemVO item : items) {
|
||||
SkuInfoVO info = skuMap.get(item.getSkuId());
|
||||
if (info != null) {
|
||||
item.setPrice(info.getSkuPrice());
|
||||
item.setSkuImg(info.getSkuPic());
|
||||
item.setSkuName(info.getSkuName());
|
||||
}
|
||||
}
|
||||
|
||||
OrderConfirmVO confirm = new OrderConfirmVO();
|
||||
confirm.setItems(items);
|
||||
return confirm;
|
||||
}
|
||||
|
||||
@Override
|
||||
@GlobalTransactional
|
||||
public OrderSubmitResultVO submit(OrderSubmitVO submit) throws ExecutionException, InterruptedException {
|
||||
log.info("开始创建订单:{}", submit);
|
||||
threadOrderSubmit.set(submit);
|
||||
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
|
||||
OrderVO orderVO = new OrderVO();
|
||||
CompletableFuture<Void> orderFuture = CompletableFuture.runAsync(() -> {
|
||||
RequestContextHolder.setRequestAttributes(attributes);
|
||||
threadOrderSubmit.set(submit);
|
||||
OrderEntity order = createOrder();
|
||||
orderVO.setOrderEntity(order);
|
||||
}, executor);
|
||||
|
||||
CompletableFuture<Void> orderGoodsFuture = CompletableFuture.runAsync(() -> {
|
||||
// 生成订单商品信息
|
||||
RequestContextHolder.setRequestAttributes(attributes);
|
||||
threadOrderSubmit.set(submit);
|
||||
List<OrderGoodsEntity> orderGoods = createOrderGoods();
|
||||
orderVO.setOrderGoods(orderGoods);
|
||||
}, executor);
|
||||
|
||||
CompletableFuture<Void> orderDeliveryFuture = CompletableFuture.runAsync(() -> {
|
||||
threadOrderSubmit.set(submit);
|
||||
RequestContextHolder.setRequestAttributes(attributes);
|
||||
// 生成订单地址信息
|
||||
OrderDeliveryEntity orderDelivery = createOrderDelivery();
|
||||
if (orderDelivery == null) {
|
||||
throw new BizException("提交订单失败,无法获取用户地址信息");
|
||||
}
|
||||
orderVO.setOrderDeliveryEntity(orderDelivery);
|
||||
}, executor);
|
||||
|
||||
CompletableFuture<Void> future = CompletableFuture.allOf(orderFuture, orderGoodsFuture, orderDeliveryFuture);
|
||||
future.get();
|
||||
|
||||
// 订单验价
|
||||
computePrice(orderVO.getOrderEntity(), orderVO.getOrderGoods());
|
||||
|
||||
// 扣减库存
|
||||
lockStock(orderVO.getOrderGoods());
|
||||
|
||||
// 保存订单
|
||||
this.baseMapper.insert(orderVO.getOrderEntity());
|
||||
Long orderId = orderVO.getOrderEntity().getId();
|
||||
|
||||
// 保存订单商品
|
||||
for (OrderGoodsEntity orderGood : orderVO.getOrderGoods()) {
|
||||
orderGood.setOrderId(orderId);
|
||||
orderGoodsDao.insert(orderGood);
|
||||
}
|
||||
|
||||
// 保存订单发货信息
|
||||
orderVO.getOrderDeliveryEntity().setOrderId(orderId);
|
||||
orderDeliveryDao.insert(orderVO.getOrderDeliveryEntity());
|
||||
|
||||
// 保存订单日志
|
||||
// 清空购物车
|
||||
if (ObjectUtil.isNull(submit.getSkuId())) {
|
||||
cartService.cleanSelected();
|
||||
}
|
||||
|
||||
// 将订单放入定时队列中,超时未支付系统自动关单,是否库存
|
||||
rabbitTemplate.convertAndSend(OmsRabbitConstants.ORDER_EVENT_EXCHANGE,
|
||||
OmsRabbitConstants.ORDER_CREATE_ORDER_KEY, orderVO.getOrderEntity().getOrderSn());
|
||||
|
||||
orderLogsService.addOrderLogs(orderVO.getOrderEntity().getId(), orderVO.getOrderEntity().getStatus(), RequestUtils.getUserId().toString(), "创建订单");
|
||||
|
||||
OrderSubmitResultVO result = new OrderSubmitResultVO();
|
||||
result.setId(orderId);
|
||||
result.setOrderSn(orderVO.getOrderEntity().getOrderSn());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderEntity getByOrderSn(String orderSn) {
|
||||
log.info("根据订单号查询订单详情,orderSn={}", orderSn);
|
||||
QueryWrapper<OrderEntity> query = new QueryWrapper<>();
|
||||
query.eq("order_sn", orderSn);
|
||||
return baseMapper.selectOne(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closeOrderBySystem(String orderSn) {
|
||||
log.info("订单超时未支付,系统自动关闭,orderSn={}", orderSn);
|
||||
OrderEntity order = getByOrderSn(orderSn);
|
||||
if (!order.getStatus().equals(OrderStatusEnum.NEED_PAY.code)) {
|
||||
log.info("订单状态异常,系统无法自动关闭,orderSn={},orderStatus={}", orderSn, order.getStatus());
|
||||
return false;
|
||||
}
|
||||
order.setStatus(OrderStatusEnum.SYS_CANCEL.code);
|
||||
baseMapper.updateById(order);
|
||||
// 添加订单操作日志
|
||||
orderLogsService.addOrderLogs(order.getId(), order.getStatus(),
|
||||
"系统操作", OrderStatusEnum.SYS_CANCEL.desc);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancelOrder(String id) {
|
||||
log.info("会员取消订单,orderId={}", id);
|
||||
OrderEntity order = getByOrderId(id);
|
||||
if (!order.getStatus().equals(OrderStatusEnum.NEED_PAY.code)) {
|
||||
log.info("订单状态异常,会员无法取消,orderId={},orderStatus={}", id, order.getStatus());
|
||||
return false;
|
||||
}
|
||||
order.setStatus(OrderStatusEnum.USER_CANCEL.code);
|
||||
baseMapper.updateById(order);
|
||||
// 添加订单操作日志
|
||||
orderLogsService.addOrderLogs(order.getId(), order.getStatus(), OrderStatusEnum.USER_CANCEL.desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteOrder(String id) {
|
||||
// 查询订单,校验订单状态
|
||||
OrderEntity order = this.getByOrderId(id);
|
||||
if (!order.getStatus().equals(OrderStatusEnum.SYS_CANCEL.code) &&
|
||||
order.getStatus().equals(OrderStatusEnum.USER_CANCEL.code)) {
|
||||
throw new BizException(StrUtil.format("订单无法删除,订单状态【{}】", Objects.requireNonNull(EnumUtils.getByCode(order.getStatus(), OrderStatusEnum.class)).desc));
|
||||
}
|
||||
|
||||
orderDao.deleteById(id);
|
||||
orderLogsService.addOrderLogs(order.getId(), order.getStatus(), "会员删除订单");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OrderListVO> list(Integer status) {
|
||||
log.info("订单列表查询,status={}", status);
|
||||
QueryWrapper<OrderEntity> orderQuery = new QueryWrapper<>();
|
||||
if (status != 0) {
|
||||
orderQuery.eq("status", status);
|
||||
}
|
||||
orderQuery.orderByDesc("id");
|
||||
List<OrderEntity> orderList = this.list(orderQuery);
|
||||
if (orderList == null || orderList.size() <= 0) {
|
||||
log.info("订单列表查询结果为空,status={}", status);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Long> orderIds = orderList.stream().map(orderEntity -> orderEntity.getId()).collect(Collectors.toList());
|
||||
Map<Long, List<OrderGoodsEntity>> orderGoodsMap = orderGoodsService.getByOrderIds(orderIds);
|
||||
List<OrderListVO> result = orderList.stream().map(orderEntity -> {
|
||||
OrderListVO orderListVO = BeanMapperUtils.map(orderEntity, OrderListVO.class);
|
||||
orderListVO.setStatusDesc(EnumUtils.getByCode(orderListVO.getStatus(), OrderStatusEnum.class).desc);
|
||||
List<OrderGoodsEntity> orderGoodsEntities = orderGoodsMap.get(orderListVO.getId());
|
||||
if (orderGoodsEntities != null && orderGoodsEntities.size() > 0) {
|
||||
List<OrderListVO.GoodsListBean> goodsListBeans = orderGoodsEntities.stream().map(orderGoodsEntity -> BeanMapperUtils.map(orderGoodsEntity, OrderListVO.GoodsListBean.class)).collect(Collectors.toList());
|
||||
orderListVO.setGoodsList(goodsListBeans);
|
||||
}
|
||||
return orderListVO;
|
||||
}).collect(Collectors.toList());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderEntity getByOrderId(String id) {
|
||||
Long userId = RequestUtils.getUserId();
|
||||
QueryWrapper<OrderEntity> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("member_id", userId).eq("id", id);
|
||||
OrderEntity orderEntity = this.getOne(queryWrapper);
|
||||
if (orderEntity == null) {
|
||||
throw new BizException("订单不存在,订单id非法");
|
||||
}
|
||||
return orderEntity;
|
||||
}
|
||||
|
||||
private void lockStock(List<OrderGoodsEntity> orderGoods) {
|
||||
List<SkuStockVO> items = orderGoods.stream().map(good -> {
|
||||
SkuStockVO itemVO = new SkuStockVO();
|
||||
itemVO.setSkuId(good.getSkuId());
|
||||
itemVO.setNumber(good.getSkuQuantity());
|
||||
return itemVO;
|
||||
}).collect(Collectors.toList());
|
||||
WareSkuStockVO wareSkuStock = new WareSkuStockVO();
|
||||
wareSkuStock.setItems(items);
|
||||
Result result = productFeignService.lockStock(wareSkuStock);
|
||||
if (result == null || !StrUtil.equals(result.getCode(), ResultCode.SUCCESS.getCode())) {
|
||||
log.error("锁定库存异常,商品列表={}", items);
|
||||
throw new BizException("下单失败,锁定库存错误");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算订单商品价格
|
||||
*
|
||||
* @param order
|
||||
* @param orderGoods
|
||||
* @return
|
||||
*/
|
||||
private Long computePrice(OrderEntity order, List<OrderGoodsEntity> orderGoods) {
|
||||
log.info("计算订单价格:order:{},orderGoods:{}", order, orderGoods);
|
||||
if (order == null || CollectionUtil.isEmpty(orderGoods)) {
|
||||
throw new BizException("订单或订单商品列表为空,订单创建失败");
|
||||
}
|
||||
Long totalAmount = orderGoods.stream().mapToLong(OrderGoodsEntity::getSkuTotalPrice).sum();
|
||||
int totalQuantity = orderGoods.stream().mapToInt(OrderGoodsEntity::getSkuQuantity).sum();
|
||||
Long payAmount = totalAmount;
|
||||
if (order.getCouponAmount() != null) {
|
||||
payAmount -= order.getCouponAmount();
|
||||
}
|
||||
if (order.getFreightAmount() != null) {
|
||||
payAmount -= order.getFreightAmount();
|
||||
}
|
||||
order.setTotalAmount(totalAmount);
|
||||
order.setTotalQuantity(totalQuantity);
|
||||
order.setPayAmount(payAmount);
|
||||
|
||||
OrderSubmitVO submit = threadOrderSubmit.get();
|
||||
if (!StrUtil.equals(submit.getPayAmount().toString(), payAmount.toString())) {
|
||||
throw new BizException("订单价格变化,请重新提交");
|
||||
}
|
||||
return payAmount;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建订单商品集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<OrderGoodsEntity> createOrderGoods() {
|
||||
OrderSubmitVO submit = threadOrderSubmit.get();
|
||||
log.info("创建订单商品实体类,submit:{}", submit);
|
||||
List<OrderGoodsEntity> orderGoods = null;
|
||||
if (ObjectUtil.isNull(submit.getSkuId())) {
|
||||
CartVo detail = cartService.detail();
|
||||
log.info("从购物车中获取已选择商品信息:{}", detail);
|
||||
orderGoods = detail.getItems().stream().map(item -> {
|
||||
OrderGoodsEntity good = new OrderGoodsEntity();
|
||||
good.setSkuId(item.getSkuId());
|
||||
good.setSkuQuantity(item.getNumber());
|
||||
return good;
|
||||
}).collect(Collectors.toList());
|
||||
} else {
|
||||
log.info("会员选择商品直接下单,商品id:{}", submit.getSkuId());
|
||||
orderGoods = new ArrayList<>();
|
||||
OrderGoodsEntity good = new OrderGoodsEntity();
|
||||
good.setSkuId(Long.valueOf(submit.getSkuId()));
|
||||
good.setSkuQuantity(submit.getSkuNumber());
|
||||
orderGoods.add(good);
|
||||
}
|
||||
|
||||
List<String> skuIds = orderGoods.stream().map(vo -> vo.getSkuId().toString()).collect(Collectors.toList());
|
||||
Result<List<SkuInfoVO>> response = productFeignService.infos(skuIds);
|
||||
List<SkuInfoVO> skuInfos = response.getData();
|
||||
if (skuInfos == null) {
|
||||
return null;
|
||||
}
|
||||
Map<Long, SkuInfoVO> skuMap = skuInfos.stream().collect(Collectors.toMap(SkuInfoVO::getSkuId, Function.identity(), (o1, o2) -> o2));
|
||||
for (OrderGoodsEntity good : orderGoods) {
|
||||
SkuInfoVO skuInfo = skuMap.get(good.getSkuId());
|
||||
if (skuInfo == null) {
|
||||
throw new BizException("订单商品库存为空");
|
||||
}
|
||||
BeanMapperUtils.copy(skuInfo, good);
|
||||
Long goodTotalPrice = good.getSkuPrice() * good.getSkuQuantity();
|
||||
good.setSkuTotalPrice(goodTotalPrice);
|
||||
}
|
||||
return orderGoods;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成订单数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private OrderEntity createOrder() {
|
||||
OrderSubmitVO submit = threadOrderSubmit.get();
|
||||
log.info("创建订单实体类,submit:{}", submit);
|
||||
OrderEntity order = new OrderEntity();
|
||||
order.setOrderSn(IdWorker.getTimeId());
|
||||
order.setRemark(submit.getRemark());
|
||||
order.setStatus(OrderStatusEnum.NEED_PAY.code);
|
||||
order.setSourceType(OrderTypeEnum.APP.code);
|
||||
order.setMemberId(RequestUtils.getUserId());
|
||||
return order;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单地址信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private OrderDeliveryEntity createOrderDelivery() {
|
||||
String addressId = threadOrderSubmit.get().getAddressId();
|
||||
log.info("获取订单地址信息,addressId:{}", addressId);
|
||||
try {
|
||||
Result<UmsAddressDTO> response = memberFeignService.getAddressById(addressId);
|
||||
UmsAddressDTO addressInfo = response.getData();
|
||||
if (addressInfo != null) {
|
||||
OrderDeliveryEntity delivery = new OrderDeliveryEntity();
|
||||
delivery.setReceiverProvince(addressInfo.getProvince());
|
||||
delivery.setReceiverCity(addressInfo.getCity());
|
||||
delivery.setReceiverRegion(addressInfo.getArea());
|
||||
delivery.setReceiverDetailAddress(addressInfo.getAddress());
|
||||
delivery.setReceiverName(addressInfo.getName());
|
||||
delivery.setReceiverPostCode(addressInfo.getZipCode());
|
||||
delivery.setReceiverPhone(addressInfo.getMobile());
|
||||
return delivery;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取订单地址信息失败,addressId:{}", addressId, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从购物车中获取订单商品列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<OrderItemVO> getOrderItemFromCart(String skuId, Integer number) {
|
||||
if (!StrUtil.isEmpty(skuId)) {
|
||||
log.info("请求携带商品id:{},数量:{},订单类型为用户直接购买", skuId, number);
|
||||
OrderItemVO itemVO = OrderItemVO.builder().skuId(Long.parseLong(skuId)).number(number).build();
|
||||
return Arrays.asList(itemVO);
|
||||
|
||||
}
|
||||
CartVo cartVo = cartService.detail();
|
||||
List<OrderItemVO> items = cartVo.getItems().stream().filter(CartItemVo::isChecked).map(cart -> OrderItemVO.builder().skuId(cart.getSkuId()).number(cart.getNumber()).build()).collect(Collectors.toList());
|
||||
return items;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.base.Query;
|
||||
import com.youlai.common.mybatis.utils.PageUtils;
|
||||
import com.youlai.mall.oms.dao.OrderSettingDao;
|
||||
import com.youlai.mall.oms.pojo.entity.OrderSettingEntity;
|
||||
import com.youlai.mall.oms.service.OrderSettingService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service("orderSettingService")
|
||||
public class OrderSettingServiceImpl extends ServiceImpl<OrderSettingDao, OrderSettingEntity> implements OrderSettingService {
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<OrderSettingEntity> page = this.page(
|
||||
new Query<OrderSettingEntity>().getPage(params),
|
||||
new QueryWrapper<OrderSettingEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.common.web.util.RequestUtils;
|
||||
import com.youlai.mall.oms.service.TokenService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static com.youlai.common.redis.constant.RedisKeyConstants.REDIS_KEY_TIME_OUT;
|
||||
import static com.youlai.common.redis.constant.RedisKeyConstants.TOKEN_VERIFY;
|
||||
|
||||
/**
|
||||
* @author huawei
|
||||
* @desc Token 服务
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/21
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class TokenServiceImpl implements TokenService {
|
||||
|
||||
private static final String TOKEN = "token";
|
||||
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public String generateToken() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String userId = RequestUtils.getUserId().toString();
|
||||
//生成UUID
|
||||
String token = IdUtil.randomUUID();
|
||||
//前缀 + 用户id + UUID组成 token
|
||||
String key = sb.append(TOKEN_VERIFY).append(userId).append(':').append(token).toString();
|
||||
//将token写入redis并设置过期时间
|
||||
redisTemplate.opsForValue().set(key, key, REDIS_KEY_TIME_OUT);
|
||||
//redis写入成功则设置token成功
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkToken(HttpServletRequest request) {
|
||||
String token = request.getHeader(TOKEN);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
token = request.getParameter(TOKEN);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new BizException("请勿重复提交");
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String userId = RequestUtils.getUserId().toString();
|
||||
String key = sb.append(TOKEN_VERIFY).append(userId).append(':').append(token).toString();
|
||||
|
||||
// 2、校验token是否存在
|
||||
if (!StrUtil.equals(redisTemplate.opsForValue().get(key).toString(), key)) {
|
||||
log.debug("请求:{} 使用 token:{} 校验幂等性,缓存中不存在", request.getRequestURI(), token);
|
||||
throw new BizException("请勿重复提交");
|
||||
}
|
||||
// 3、校验token是否删除成功
|
||||
if (!redisTemplate.delete(key)) {
|
||||
log.debug("请求:{} 使用 token:{} 校验幂等性,删除缓存数据失败", request.getRequestURI(), token);
|
||||
throw new BizException("请勿重复提交");
|
||||
}
|
||||
}
|
||||
}
|
23
mall-oms/oms-boot/src/main/resources/banner.txt
Normal file
23
mall-oms/oms-boot/src/main/resources/banner.txt
Normal file
@ -0,0 +1,23 @@
|
||||
${AnsiColor.BRIGHT_RED} 升职加薪
|
||||
钱 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀
|
||||
多 ⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 身
|
||||
事 ⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢙⢂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 强
|
||||
少 ⢸⣱⢄⣀⣀⣀⣀⣀ ⢀⣀⣠⢀⡀⣤⠤⣚⣼⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 体
|
||||
干 ⠀⠒⠿⣊⣇⣧⣾⣟⣝⣝⣿⣿⣜⡵⠵⢼⣊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 健
|
||||
的 ⠀⠀⠀⠐⠺⠿⣿⠻⢟⣿⢍⢍⢻⣿⣿⣧⡞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 进
|
||||
爽 ⠀⠀⠀⠀⠀⠀⣿⢠⣿⣿ ⣿⣴⣿⣿⣟⢷⣦⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 步
|
||||
⠀⠀⠀⠀⠀⢸⢿⡿⢿⣿⣿⣿ ⢫⣿⠏⢤⣿⠩⣝⣷⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⣠⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 快
|
||||
⠀⠀⠀⠀⠀⣏⡃⣘⣃⣿⠿⢛⣡⣿⠿⢶⣿⣿⣷⣬⣍⣼⡟⢻⣟⢟⠿⣿⠿⢛⣿⠿⣿⠿⢳⣶⣿⡿⠛⠛⠿⣷⣄⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠈⠉⠛⠛⠻⡿⡻⡉⠡⡀⣿⣿⣿⣿⣿⣿⣿⣷⣾⣬⣥⣴⣿⣗⣿⠡⣷⡗⣼⡷⠛⡻⣷⡀⠀⠀⠈⠻⣦⣀⠀⡔⠒⠲⡇
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⡷⣷⡷⡿⣿⣿⣿⣿⣿⣿⣿⡍⠛⢛⢍⣽⠏⣼⠻⣜⣻⢟⣵⣷⠿⣿⢜⣧⠀⠀⠀⠀⠀⠉⠉⠑⠒⠊⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣮⣠⣠⣴⠿⣿⣿⣿⣿⣿⣿⣿⣾⣼⣾⡿⢧⣽⣎⠿⠻⣻⡵⢻⣿⠏⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣸⡟⢹⣗⣽⠿⣿⣿⣿⣿⣿⣿⡿⣆⣌⠐⣰⣿⣄⣛⣿⣻⠛⢍⣼⣋⣵⠣⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⡤⡲⣴⢄⣯⣬⣿⣷⣄⣹⠅⣱⣿⣿⣿⣿⣿⣿⠌⢽⣿⡟⠛⡋⣹⡝⣷⣉⣻⣏⣉⣲⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⢨⡪⡭⢸⣿⠃⠀⠉⠙⠛⠳⢼⣿⣿⣿⣿⢻⢊⣢⣽⣋⣿⣾⠾⣟⣯⣷⣿⡻⢿⣿⣿⣿⣿⣿⣦⡀⢠⣀⣤⠀⠀⠀⡀⠀⠀
|
||||
⠀⠛⣠⣃⣬⣿⣁⠀⣿⣗⣤⠀⡀⠀⠀⣜⢿⣿⠏⠉⠋⠉⠉⠉⠉⠀⠀⠀⠙⠿⣿⣿⣧⠀⠈⠙⠛⠿⣿⣯⣼⠀⡃⣣⣧⣤⣾⣇⠀⠀
|
||||
⢀⣀⣴⡿⣺⡏⢻⣆⡈⠓⠻⠃⡐⠀⠀⣷⣿⠋⠀⠀⠀⠀⠀⣼⣵⠇⡀⠀⠀⠀⣸⣿⡭⠃⠀⠀⠀⠀⠈⠻⣿⡄⠀⠿⣯⣖⡽⠃⠀⠀
|
||||
⢨⣵⣭⣽⡗⡟⢿⣶⣿⡄⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠙⡒⣥⣄⡘⠍⠀⢀⣠⣼⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⢹⣷⡀⠠⢵⠸⣤⣀⠀⠀
|
||||
⠀⠉⢈⣋⣦⣴⡄⢉⣰⣲⡂⠀⠀⢰⣭⡽⠂⠀⠀⠀⠈⠀⠐⠻⢽⠿⡳⠶⡾⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣯⣵⠣⣟⣆⡃⠧⣾⡅⠀
|
||||
⠀⠀⠙⠻⠿⠛⠉⠑⠋⠉⠀⠀⠪⣀⣉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠚⠀⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣱⣀⡁⠀⠀⠃
|
||||
${AnsiColor.BRIGHT_YELLOW}Spring Boot 版本:${spring-boot.version}
|
||||
${AnsiColor.BRIGHT_YELLOW}项目名称:${spring.application.name} | 端口号:${server.port}
|
41
mall-oms/oms-boot/src/main/resources/bootstrap-dev.yml
Normal file
41
mall-oms/oms-boot/src/main/resources/bootstrap-dev.yml
Normal file
@ -0,0 +1,41 @@
|
||||
server:
|
||||
port: 8603
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: mall-oms
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: http://localhost:8848
|
||||
config:
|
||||
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||
file-extension: yaml
|
||||
|
||||
|
||||
|
||||
# 全局参数设置
|
||||
ribbon:
|
||||
ReadTimeout: 10000
|
||||
ConnectTimeout: 10000
|
||||
SocketTimeout: 10000
|
||||
MaxAutoRetries: 0
|
||||
MaxAutoRetriesNextServer: 1
|
||||
|
||||
# 分布式事务配置
|
||||
seata:
|
||||
tx-service-group: mall_tx_group
|
||||
enable-auto-data-source-proxy: true
|
||||
registry:
|
||||
type: nacos
|
||||
nacos:
|
||||
server-addr: c.youlai.store:8848
|
||||
namespace: seata_namespace_id
|
||||
group: SEATA_GROUP
|
||||
config:
|
||||
type: nacos
|
||||
nacos:
|
||||
server-addr: c.youlai.store:8848
|
||||
namespace: seata_namespace_id
|
||||
group: SEATA_GROUP
|
||||
|
51
mall-oms/oms-boot/src/main/resources/bootstrap-prod.yml
Normal file
51
mall-oms/oms-boot/src/main/resources/bootstrap-prod.yml
Normal file
@ -0,0 +1,51 @@
|
||||
server:
|
||||
port: 8603
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: mall-oms
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: http://c.youlai.store:8848
|
||||
namespace: prod_namespace_id
|
||||
config:
|
||||
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||
file-extension: yaml
|
||||
namespace: prod_namespace_id
|
||||
|
||||
|
||||
# 分布式事务配置
|
||||
seata:
|
||||
tx-service-group: mall_tx_group
|
||||
enable-auto-data-source-proxy: true
|
||||
registry:
|
||||
type: nacos
|
||||
nacos:
|
||||
server-addr: c.youlai.store:8848
|
||||
namespace: seata_namespace_id
|
||||
group: SEATA_GROUP
|
||||
config:
|
||||
type: nacos
|
||||
nacos:
|
||||
server-addr: c.youlai.store:8848
|
||||
namespace: seata_namespace_id
|
||||
group: SEATA_GROUP
|
||||
|
||||
|
||||
|
||||
# 全局参数设置
|
||||
ribbon:
|
||||
ReadTimeout: 10000
|
||||
ConnectTimeout: 10000
|
||||
SocketTimeout: 10000
|
||||
MaxAutoRetries: 0
|
||||
MaxAutoRetriesNextServer: 1
|
||||
|
||||
|
||||
# 站长支付API配置
|
||||
zzf:
|
||||
AppKey: c35332f4d84646f7
|
||||
AppSecret: 1c93baadf7544f5faa5b5c6e02ef4307
|
||||
CreateOrderURL: https://admin.zhanzhangfu.com/order/createOrder
|
||||
FindOrderURL: https://admin.zhanzhangfu.com/order/onlinePayFindResult
|
3
mall-oms/oms-boot/src/main/resources/bootstrap.yml
Normal file
3
mall-oms/oms-boot/src/main/resources/bootstrap.yml
Normal file
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
31
mall-oms/oms-boot/src/main/resources/mapper/oms/OrderDao.xml
Normal file
31
mall-oms/oms-boot/src/main/resources/mapper/oms/OrderDao.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderEntity" id="orderMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderSn" column="order_sn"/>
|
||||
<result property="totalAmount" column="total_amount"/>
|
||||
<result property="totalQuantity" column="total_quantity"/>
|
||||
<result property="sourceType" column="source_type"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="memberId" column="member_id"/>
|
||||
<result property="couponId" column="coupon_id"/>
|
||||
<result property="couponAmount" column="coupon_amount"/>
|
||||
<result property="freightAmount" column="freight_amount"/>
|
||||
<result property="payAmount" column="pay_amount"/>
|
||||
<result property="payTime" column="pay_time"/>
|
||||
<result property="payType" column="pay_type"/>
|
||||
<result property="deliveryTime" column="delivery_time"/>
|
||||
<result property="receiveTime" column="receive_time"/>
|
||||
<result property="commentTime" column="comment_time"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderDeliveryDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderDeliveryEntity" id="orderDeliveryMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderId" column="order_id"/>
|
||||
<result property="deliveryCompany" column="delivery_company"/>
|
||||
<result property="deliverySn" column="delivery_sn"/>
|
||||
<result property="receiverName" column="receiver_name"/>
|
||||
<result property="receiverPhone" column="receiver_phone"/>
|
||||
<result property="receiverPostCode" column="receiver_post_code"/>
|
||||
<result property="receiverProvince" column="receiver_province"/>
|
||||
<result property="receiverCity" column="receiver_city"/>
|
||||
<result property="receiverRegion" column="receiver_region"/>
|
||||
<result property="receiverDetailAddress" column="receiver_detail_address"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="deliveryStatus" column="delivery_status"/>
|
||||
<result property="deliveryTime" column="delivery_time"/>
|
||||
<result property="receiveTime" column="receive_time"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderGoodsDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderGoodsEntity" id="orderGoodsMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderId" column="order_id"/>
|
||||
<result property="skuId" column="sku_id"/>
|
||||
<result property="skuCode" column="sku_code"/>
|
||||
<result property="skuName" column="sku_name"/>
|
||||
<result property="skuPic" column="sku_pic"/>
|
||||
<result property="skuPrice" column="sku_price"/>
|
||||
<result property="skuQuantity" column="sku_quantity"/>
|
||||
<result property="skuTotalPrice" column="sku_total_price"/>
|
||||
<result property="spuId" column="spu_id"/>
|
||||
<result property="spuName" column="spu_name"/>
|
||||
<result property="spuPic" column="spu_pic"/>
|
||||
<result property="brandId" column="brand_id"/>
|
||||
<result property="brandName" column="brand_name"/>
|
||||
<result property="categoryId" column="category_id"/>
|
||||
<result property="categoryName" column="category_name"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderLogsDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderLogsEntity" id="orderLogsMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderId" column="order_id"/>
|
||||
<result property="user" column="user"/>
|
||||
<result property="detail" column="detail"/>
|
||||
<result property="orderStatus" column="order_status"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderPayDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderPayEntity" id="orderPayMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderId" column="order_id"/>
|
||||
<result property="paySn" column="pay_sn"/>
|
||||
<result property="payAmount" column="pay_amount"/>
|
||||
<result property="payTime" column="pay_time"/>
|
||||
<result property="payType" column="pay_type"/>
|
||||
<result property="payStatus" column="pay_status"/>
|
||||
<result property="confirmTime" column="confirm_time"/>
|
||||
<result property="callbackContent" column="callback_content"/>
|
||||
<result property="callbackTime" column="callback_time"/>
|
||||
<result property="paySubject" column="pay_subject"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.youlai.mall.oms.dao.OrderSettingDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<resultMap type="com.youlai.mall.oms.pojo.entity.OrderSettingEntity" id="orderSettingMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="flashOrderOvertime" column="flash_order_overtime"/>
|
||||
<result property="normalOrderOvertime" column="normal_order_overtime"/>
|
||||
<result property="confirmOvertime" column="confirm_overtime"/>
|
||||
<result property="finishOvertime" column="finish_overtime"/>
|
||||
<result property="commentOvertime" column="comment_overtime"/>
|
||||
<result property="memberLevel" column="member_level"/>
|
||||
<result property="deleted" column="deleted"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
<result property="gmtModified" column="gmt_modified"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
@ -0,0 +1,78 @@
|
||||
package com.youlai.mall.oms.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.mall.oms.controller.admin.OrderController;
|
||||
import com.youlai.mall.oms.pojo.OmsOrder;
|
||||
import com.youlai.mall.oms.service.IOmsOrderService;
|
||||
import com.youlai.mall.pms.api.ProductFeignService;
|
||||
import com.youlai.mall.ums.api.MemberFeignService;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
|
||||
|
||||
@AutoConfigureMockMvc
|
||||
@SpringBootTest
|
||||
@Slf4j
|
||||
public class OrderControllerTest {
|
||||
|
||||
@Autowired
|
||||
public MockMvc mockMvc;
|
||||
@Autowired
|
||||
public OrderController orderController;
|
||||
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void saveOrder() throws Exception {
|
||||
|
||||
String goods = "{\"order\":{\"userId\":0,\"status\":10,\"source\":0,\"consignee\":\"str\",\"mobile\":\"str\",\"postcode\":\"str\",\"address\":\"str\",\"couponId\":0,\"skuPrice\":0,\"freightPrice\":0,\"couponPrice\":0,\"orderPrice\":0,\"integrationPrice\":0,\"payPrice\":0,\"payId\":\"str\",\"payType\":0,\"payTime\":1606379283562,\"shipSn\":\"str\",\"shipChannel\":\"str\"},\n" +
|
||||
" \"orderItems\":[{\"spuId\":0,\"spuName\":\"str\",\"skuId\":\"0\",\"skuBarCode\":\"str\",\"skuSpecifications\":\"str\",\"skuPrice\":0,\"skuQuantity\":0,\"pic\":\"str\"}]}";
|
||||
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/orders")
|
||||
.contentType("application/json")
|
||||
.content(goods))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResultCode.SUCCESS.getCode()))
|
||||
.andDo(print())
|
||||
.andReturn();
|
||||
|
||||
log.info(result.getResponse().getContentAsString());
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private ProductFeignService productFeignService;
|
||||
|
||||
@Autowired
|
||||
private MemberFeignService memberFeignService;
|
||||
|
||||
@Autowired
|
||||
private IOmsOrderService iOmsOrderService;
|
||||
|
||||
|
||||
@Test
|
||||
@GlobalTransactional(rollbackFor = Exception.class)
|
||||
public void submitOrder() {
|
||||
// 扣减库存
|
||||
productFeignService.updateStock(151l, -1);
|
||||
// 增加积分
|
||||
memberFeignService.updatePoint(1l, 10);
|
||||
// 修改订单状态
|
||||
iOmsOrderService.update(new LambdaUpdateWrapper<OmsOrder>().eq(OmsOrder::getId, 1l).set(OmsOrder::getStatus, 901));
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>oms-api</module>
|
||||
<module>oms-biz</module>
|
||||
<module>oms-boot</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.youlai.mall.pms.common;
|
||||
|
||||
/**
|
||||
* @author haoxr
|
||||
* @date 2021-02-28 20:10
|
||||
*/
|
||||
public interface RedisConstants {
|
||||
|
||||
String PRODUCT_INVENTORY_PREFIX = "product:inventory:";
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.youlai.mall.pms.controller.app;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.mall.pms.pojo.domain.PmsSku;
|
||||
import com.youlai.mall.pms.pojo.dto.SkuDTO;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuInfoVO;
|
||||
import com.youlai.mall.pms.pojo.vo.WareSkuStockVO;
|
||||
import com.youlai.mall.pms.service.IPmsSkuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "【移动端】商品库存")
|
||||
@RestController("AppInventoryController")
|
||||
@RequestMapping("/api.app/v1/inventories")
|
||||
@AllArgsConstructor
|
||||
public class InventoryController {
|
||||
|
||||
private IPmsSkuService iPmsSkuService;
|
||||
|
||||
|
||||
@ApiOperation(value = "商品库存详情", httpMethod = "GET")
|
||||
@ApiImplicitParam(name = "id", value = "商品SkuId", required = true, paramType = "path", dataType = "Long")
|
||||
@GetMapping("/{id}")
|
||||
public Result<SkuDTO> detail(@PathVariable Long id) {
|
||||
PmsSku sku = iPmsSkuService.getById(id);
|
||||
SkuDTO skuDTO = new SkuDTO();
|
||||
BeanUtil.copyProperties(sku, skuDTO);
|
||||
return Result.success(skuDTO);
|
||||
}
|
||||
|
||||
|
||||
@ApiImplicitParam(name = "id", value = "商品SkuId", required = true, paramType = "path", dataType = "Long")
|
||||
@GetMapping("/{skuId}/inventory")
|
||||
public Result<Integer> getInventoryBySkuId(@PathVariable Long skuId) {
|
||||
Integer inventory = iPmsSkuService.getInventoryBySkuId(skuId);
|
||||
return Result.success(inventory);
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "【移动端】商品库存")
|
||||
@RestController("AppInventoryController")
|
||||
@RestController("AppSkuController")
|
||||
@RequestMapping("/api.app/v1/sku")
|
||||
@AllArgsConstructor
|
||||
public class SkuController {
|
||||
|
@ -29,4 +29,12 @@ public interface IPmsSkuService extends IService<PmsSku> {
|
||||
* @return 释放库存结果
|
||||
*/
|
||||
boolean releaseStock(WareSkuStockVO skuStockVO);
|
||||
|
||||
|
||||
/**
|
||||
* 获取商品库存
|
||||
* @param skuId
|
||||
* @return
|
||||
*/
|
||||
Integer getInventoryBySkuId(Long skuId);
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
package com.youlai.mall.pms.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.mall.pms.common.RedisConstants;
|
||||
import com.youlai.mall.pms.mapper.PmsSkuMapper;
|
||||
import com.youlai.mall.pms.pojo.domain.PmsSku;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuInfoVO;
|
||||
import com.youlai.mall.pms.pojo.vo.SkuStockVO;
|
||||
import com.youlai.mall.pms.pojo.vo.WareSkuStockVO;
|
||||
import com.youlai.mall.pms.service.IPmsSkuService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -16,8 +21,12 @@ import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> implements IPmsSkuService {
|
||||
|
||||
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public List<SkuInfoVO> getSkuInfoByIds(List<String> skuIds) {
|
||||
log.info("批量获取商品详情,skuIds:{}", skuIds);
|
||||
@ -50,4 +59,37 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cache-Aside pattern 缓存、数据库读写模式
|
||||
* 1. 读取数据,先读缓存,没有就去读数据库,然后将结果写入缓存
|
||||
* 2. 写入数据,先更新数据库,再删除缓存
|
||||
* @param skuId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Integer getInventoryBySkuId(Long skuId) {
|
||||
Integer inventory = 0;
|
||||
// 读->缓存
|
||||
Object cacheVal = redisTemplate.opsForValue().get(RedisConstants.PRODUCT_INVENTORY_PREFIX + skuId);
|
||||
if (cacheVal != null) {
|
||||
inventory = Convert.toInt(cacheVal);
|
||||
return inventory;
|
||||
}
|
||||
|
||||
// 读->数据库
|
||||
PmsSku pmsInventory = this.getOne(new LambdaQueryWrapper<PmsSku>()
|
||||
.eq(PmsSku::getId, skuId)
|
||||
.select(PmsSku::getStock));
|
||||
|
||||
if (pmsInventory != null) {
|
||||
inventory = pmsInventory.getStock();
|
||||
// 写->缓存
|
||||
redisTemplate.opsForValue().set(RedisConstants.PRODUCT_INVENTORY_PREFIX + skuId, inventory);
|
||||
}
|
||||
|
||||
return inventory;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.youlai.common.constant;
|
||||
|
||||
public interface RedisConstants {
|
||||
|
||||
String BUSINESS_NO_PREFIX = "business_no:";
|
||||
|
||||
}
|
@ -4,26 +4,29 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2021-02-17 13:13
|
||||
*
|
||||
*/
|
||||
public enum BusinessTypeEnum {
|
||||
|
||||
USER("100", "用户类型编号"),
|
||||
MEMBER("200", "会员类型编号"),
|
||||
ORDER("300", "订单类型编号");
|
||||
USER("user", 100),
|
||||
MEMBER("member", 200),
|
||||
ORDER("order", 300);
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String code;
|
||||
|
||||
BusinessTypeEnum(String code, String desc) {
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer value;
|
||||
|
||||
BusinessTypeEnum(String code, Integer value) {
|
||||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static BusinessTypeEnum getValue(String code){
|
||||
public static BusinessTypeEnum getValue(String code) {
|
||||
for (BusinessTypeEnum value : values()) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.youlai.common.redis.component;
|
||||
|
||||
import com.youlai.common.constant.RedisConstants;
|
||||
import com.youlai.common.enums.BusinessTypeEnum;
|
||||
import com.youlai.common.redis.constant.RedisKeyConstants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@ -20,22 +20,22 @@ public class BusinessNoGenerator {
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* @param businessCode 业务类型编号
|
||||
* @param businessType 业务类型枚举
|
||||
* @param digit 业务序号位数
|
||||
* @return
|
||||
*/
|
||||
public String generate(String businessCode, Integer digit) {
|
||||
public String generate(BusinessTypeEnum businessType, Integer digit) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
String date = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
|
||||
String key = RedisKeyConstants.BUSINESS_NO_PREFIX + BusinessTypeEnum.getValue(businessCode).toString().toLowerCase() + ":" + date;
|
||||
String key = RedisConstants.BUSINESS_NO_PREFIX +businessType.getCode() + ":" + date;
|
||||
Long increment = redisTemplate.opsForValue().increment(key);
|
||||
return date + businessCode + String.format("%0" + digit + "d", increment);
|
||||
return date + businessType.getValue() + String.format("%0" + digit + "d", increment);
|
||||
}
|
||||
|
||||
|
||||
public String generate(String businessCode) {
|
||||
public String generate(BusinessTypeEnum businessType) {
|
||||
Integer defaultDigit = 6;
|
||||
return generate(businessCode, defaultDigit);
|
||||
return generate(businessType, defaultDigit);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user