引入sql文件,新建springboot工程,添加web依赖,修改springboot版本
增加依赖
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.9version>
<relativePath/>
parent>
<groupId>com.hillkygroupId>
<artifactId>imocc_mallartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>imocc_mallname>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocityartifactId>
<version>1.7version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>
使用mybatis-plus生成代码
package com.hillky.imocc_mall;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.hillky.imooc_mall.ImoccMallApplication;
import javafx.application.Application;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Collections;
@SpringBootTest(classes = ImoccMallApplication.class)
class ImoccMallApplicationTests {
@Test
void contextLoads() {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/imooc_mall", "root", "root")
.globalConfig(builder -> {
builder.author("hillky") // 设置作者
.fileOverride() // 覆盖已生成文件
.outputDir("E:\\IdeaProjects\\imocc_mall\\src\\main\\java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.hillky.imooc_mall") // 设置父包名
.moduleName("") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "E:\\IdeaProjects\\imocc_mall\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("imooc_mall_category","imooc_mall_order","imooc_mall_order_item","imooc_mall_product","imooc_mall_user") // 设置需要生成的表名
.addTablePrefix("imooc_mall"); // 设置过滤表前缀
})
.templateEngine(new VelocityTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
配置文件编写
server:
port: 9090
ip: localhost
# ip: 39.108.128.26
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/imooc_mall?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&useSSL=false
# url: jdbc:mysql://39.108.128.26:3306/bishe?serverTimezone=GMT%2b8
username: root
password: root
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
mybatis:
mapper-locations: classpath:mapper/*.xml #扫描所有mybatis的xml文件
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
在maven配置的spring-boot-starter-web排去,然后加入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
新建log4j2的配置文件
<Configuration status="fatal">
<Properties>
<Property name="baseDir" value="${sys:user.dir}/logs"/>
Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="info" onMatch="ACCEPT"
onMismatch="DENY"/>
<PatternLayout
pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
Console>
<RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="debug"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
RollingFile>
<RollingFile name="info_appender" fileName="${baseDir}/info.log"
filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="info"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
RollingFile>
<RollingFile name="error_appender" fileName="${baseDir}/error.log"
filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
<Filters>
<ThresholdFilter level="error"/>
Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
Policies>
RollingFile>
Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="debug_appender"/>
<AppenderRef ref="info_appender"/>
<AppenderRef ref="error_appender"/>
Root>
Loggers>
Configuration>
新建logs目录
maven配置加入aop依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
新建过滤器
package com.hillky.imooc_mall.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* 打印请求和响应信息
*/
@Aspect
@Component
public class WebLogAspect {
//拿到日志对象
private final Logger log = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.hillky.imooc_mall.controller.*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
//收到请求,记录请求内容
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
//记录请求url
log.info("URL: " + request.getRequestURL().toString());
//记录请求方法
log.info("HTTP_METHOD: " + request.getMethod());
//记录请求IP
log.info("IP: " + request.getRemoteAddr());
//获取类的信息
log.info("CLASS_METHOD: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
//参数信息
log.info("ARGS: " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "res", pointcut = "webLog()")
public void doAfterReturning(Object res) throws JsonProcessingException {
//处理完请求,返回内容
log.info("RESPONSE : " + new ObjectMapper().writeValueAsString(res));
}
}
返回结果封装
package com.hillky.imooc_mall.common;
import com.hillky.imooc_mall.exception.ImoocMallExceptionEnum;
/**
* 描述: 通用返回对象
*/
public class ApiRestResponse<T> {
private Integer status;
private String msg;
private T data;
private static final int OK_CODE = 10000;
private static final String OK_MSG = "SUCCESS";
public ApiRestResponse(Integer status, String msg, T data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public ApiRestResponse(Integer status, String msg) {
this.status = status;
this.msg = msg;
}
public ApiRestResponse() {
this(OK_CODE, OK_MSG);
}
public static <T> ApiRestResponse<T> success() {
return new ApiRestResponse<>();
}
public static <T> ApiRestResponse<T> success(T result) {
ApiRestResponse<T> response = new ApiRestResponse<>();
response.setData(result);
return response;
}
public static <T> ApiRestResponse<T> error(Integer code, String msg) {
return new ApiRestResponse<>(code, msg);
}
public static <T> ApiRestResponse<T> error(ImoocMallExceptionEnum ex) {
return new ApiRestResponse<>(ex.getCode(), ex.getMsg());
}
@Override
public String toString() {
return "ApiRestResponse{" +
"status=" + status +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static int getOkCode() {
return OK_CODE;
}
public static String getOkMsg() {
return OK_MSG;
}
}
异常枚举
package com.hillky.imooc_mall.exception;
/**
* 描述: 异常枚举
*/
public enum ImoocMallExceptionEnum {
NEED_USER_NAME(10001, "用户名不能为空"),
NEED_PASSWORD(10002, "密码不能为空"),
PASSWORD_TOO_SHORT(10003, "密码长度不能小于8位"),
NAME_EXISTED(10004, "不允许重名"),
INSERT_FAILED(10005, "插入失败,请重试"),
WRONG_PASSWORD(10006, "密码错误"),
NEED_LOGIN(10007, "用户未登录"),
UPDATE_FAILED(10008, "更新失败"),
NEED_ADMIN(10009, "无管理员权限"),
PARA_NOT_NULL(10010, "参数不能为空"),
CREATE_FAILED(10011, "新增失败"),
REQUEST_PARAM_ERROR(10012, "参数错误"),
DELETE_FAILED(10013, "删除失败"),
MKDIR_FAILED(10014, "文件夹创建失败"),
UPLOAD_FAILED(10015, "图片上传失败"),
NOT_SALE(10016, "商品状态不可售"),
NOT_ENOUGH(10017, "商品库存不足"),
CART_EMPTY(10018, "购物车已勾选的商品为空"),
NO_ENUM(10019, "未找到对应的枚举"),
NO_ORDER(10020, "订单不存在"),
NOT_YOUR_ORDER(10021, "订单不属于你"),
WRONG_ORDER_STATUS(10022, "订单状态不符"),
SYSTEM_ERROR(20000, "系统异常,请从控制台或日志中查看具体错误信息");
/**
* 异常码
*/
Integer code;
/**
* 异常信息
*/
String msg;
ImoocMallExceptionEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
service层编写
@Override
public void register(String username,String password) throws ImoocMallException {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.eq("username",username);
User user = getOne(userQueryWrapper);
if(!ObjectUtil.isNull(user)){
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
User registerUser = new User();
registerUser.setUsername(username);
registerUser.setPassword(SecureUtil.md5(password));
if(!this.save(registerUser)){
throw new ImoocMallException(ImoocMallExceptionEnum.INSERT_FAILED);
}
}
controller层编写
@PostMapping("/register")
public ApiRestResponse register(@RequestParam("username")String username,@RequestParam("password")String password) throws ImoocMallException {
if(StrUtil.isEmpty(username)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_USER_NAME);
}
if(StrUtil.isEmpty(password)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_PASSWORD);
}
if(password.length()<8){
return ApiRestResponse.error(ImoocMallExceptionEnum.PASSWORD_TOO_SHORT);
}
userService.register(username, password);
return ApiRestResponse.success();
}
统一异常
package com.hillky.imooc_mall.exception;
import lombok.Data;
@Data
public class ImoocMallException extends Exception{
private Integer code;
private String message;
public ImoocMallException(ImoocMallExceptionEnum ex){
this(ex.getCode(),ex.getMsg());
}
public ImoocMallException(Integer code, String msg) {
this.code=code;
this.message=msg;
}
}
统一异常处理
package com.hillky.imooc_mall.exception;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.hillky.imooc_mall.common.ApiRestResponse;
import com.sun.org.slf4j.internal.LoggerFactory;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Log log = LogFactory.get();
@ResponseBody
@ExceptionHandler(Exception.class)
public Object handleException(Exception e){
log.error("Default Exception",e);
return ApiRestResponse.error(ImoocMallExceptionEnum.SYSTEM_ERROR);
}
@ResponseBody
@ExceptionHandler(ImoocMallException.class)
public Object handleImoocMallException(ImoocMallException e){
log.error("ImoocMallException",e);
return ApiRestResponse.error(e.getCode(),e.getMessage());
}
}
service层
@Override
public User login(String username, String password) throws ImoocMallException {
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.eq("username",username);
User user = getOne(userQueryWrapper);
if(!user.getPassword().equals(SecureUtil.md5(password))){
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_PASSWORD);
}
return user;
}
controller层
@PostMapping("/login")
public ApiRestResponse login(@RequestParam("username")String username,@RequestParam("password")String password) throws ImoocMallException {
if(StrUtil.isEmpty(username)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_USER_NAME);
}
if(StrUtil.isEmpty(password)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_PASSWORD);
}
User user = userService.login(username, password);
return ApiRestResponse.success(user);
}
service层
@Override
public void updateSign(User user, String signature) {
user.setPersonalizedSignature(signature);
this.updateById(user);
}
controller层
@PostMapping("/user/update")
public ApiRestResponse updateSign(@RequestParam("signature")String signature, HttpSession session) throws ImoocMallException {
User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(currentUser)){
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_LOGIN);
}
this.userService.updateSign(currentUser,signature);
return ApiRestResponse.success();
}
controller层
@PostMapping("/user/logout")
public ApiRestResponse logout(HttpSession session) throws ImoocMallException {
User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(currentUser)){
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_LOGIN);
}
session.removeAttribute(Constant.IMOOC_MALL_USER);
return ApiRestResponse.success();
}
service层
@Override
public boolean checkAdmin(User user) {
return user.getRole().equals(2);
}
controller层
@PostMapping("/adminLogin")
public ApiRestResponse adminLogin(@RequestParam("username")String username, @RequestParam("password")String password, HttpSession session) throws ImoocMallException {
if(StrUtil.isEmpty(username)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_USER_NAME);
}
if(StrUtil.isEmpty(password)){
return ApiRestResponse.error(ImoocMallExceptionEnum.NEED_PASSWORD);
}
User user = userService.login(username, password);
if(userService.checkAdmin(user)){
user.setPassword(null);
session.setAttribute(Constant.IMOOC_MALL_USER,user);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_ADMIN);
}
return ApiRestResponse.success();
}
请求参数封装
package com.hillky.imooc_mall.entity.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AddCategoryReq {
private String name;
private Integer type;
private Integer parentId;
private Integer orderNum;
}
service层编写
@Override
public void addCategory(AddCategoryReq addCategoryReq) throws ImoocMallException {
Category category = new Category();
BeanUtils.copyProperties(addCategoryReq,category);
QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",category.getName());
Category dbCategory = this.getOne(queryWrapper);
if(!ObjectUtil.isEmpty(dbCategory)){
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
boolean save = this.save(category);
if(!save){
throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
}
}
controller层编写
@PostMapping("admin/category/add")
public ApiRestResponse addCategory(HttpSession session, @RequestBody AddCategoryReq addCategoryReq) throws ImoocMallException {
User user = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(user)){
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_LOGIN);
}
if(userService.checkAdmin(user)){
categoryService.addCategory(addCategoryReq);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_ADMIN);
}
return ApiRestResponse.success();
}
添加依赖,在springboot在2.3之后,spring-boot-starter-web的依赖项已经去除了validate依赖,推荐导入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
统一异常处理处理参数valid异常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ApiRestResponse handleMethodArgumentNotValidException(
MethodArgumentNotValidException e) {
log.error("MethodArgumentNotValidException: ", e);
return handleBindingResult(e.getBindingResult());
}
private ApiRestResponse handleBindingResult(BindingResult result) {
//把异常处理为对外暴露的提示
List<String> list = new ArrayList<>();
if (result.hasErrors()) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError objectError : allErrors) {
String message = objectError.getDefaultMessage();
list.add(message);
}
}
if (list.size() == 0) {
return ApiRestResponse.error(ImoocMallExceptionEnum.REQUEST_PARAM_ERROR);
}
return ApiRestResponse.error(ImoocMallExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
}
对实体类中加入注解规则
package com.hillky.imooc_mall.entity.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AddCategoryReq {
@NotNull
@Size(min = 3, max = 5,message = "name个数必须在3-5之间")
private String name;
@NotNull
@Max(3)
private Integer type;
@NotNull(message = "parentId不能为空")
private Integer parentId;
@NotNull
private Integer orderNum;
}
在controller层加入@valid
@PostMapping("admin/category/add")
public ApiRestResponse addCategory(HttpSession session, @RequestBody @Validated AddCategoryReq addCategoryReq) throws ImoocMallException {
User user = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(user)){
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_LOGIN);
}
if(userService.checkAdmin(user)){
categoryService.addCategory(addCategoryReq);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_ADMIN);
}
return ApiRestResponse.success();
}
添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
配置
package com.hillky.imooc_mall.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
1. swagger配置类
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//是否开启 (true 开启 false隐藏。生产环境建议隐藏)
//.enable(false)
.select()
//扫描的路径包,设置basePackage会将包下的所有被@Api标记类的所有方法作为api
.apis(RequestHandlerSelectors.basePackage("com.hillky.imooc_mall.controller"))
//指定路径处理PathSelectors.any()代表所有的路径
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//设置文档标题(API名称)
.title("慕慕生鲜")
//文档描述
.description("接口说明")
//服务条款URL
.termsOfServiceUrl("http://localhost:9090/")
//版本号
.version("1.0.0")
.build();
}
}
注解配置
@Api(value = "测试接口", tags = "用户管理相关的接口", description = "用户测试接口")
public class UserController {}
@ApiOperation(value = "用户注册")
public ApiRestResponse register(@RequestParam()...
访问http://localhost:9090/swagger-ui.html
更新实体类请求
package com.hillky.imooc_mall.entity.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UpdateCategoryReq {
@NotNull
private Integer id;
@NotNull
@Size(min = 2, max = 5,message = "name个数必须在2-5之间")
private String name;
@NotNull
@Max(3)
private Integer type;
@NotNull(message = "parentId不能为空")
private Integer parentId;
@NotNull
private Integer orderNum;
}
service层
@Override
public void updateCategory(Category category) throws ImoocMallException {
if (category.getName() != null) {
Category categoryOld = this.selectByName(category.getName());
if (categoryOld != null && !categoryOld.getId().equals(category.getId())) {
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
}
boolean b = this.updateById(category);
if (!b) {
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}
}
controller层
@PostMapping("admin/category/update")
public ApiRestResponse updateCategory(HttpSession session, @RequestBody @Validated UpdateCategoryReq updateCategoryReq) throws ImoocMallException {
User user = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(user)){
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_LOGIN);
}
if(userService.checkAdmin(user)){
Category category = new Category();
BeanUtils.copyProperties(updateCategoryReq,category);
categoryService.updateCategory(category);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.NEED_ADMIN);
}
return ApiRestResponse.success();
}
管理员校验过滤器
package com.hillky.imooc_mall.filter;
import cn.hutool.core.util.ObjectUtil;
import com.hillky.imooc_mall.common.ApiRestResponse;
import com.hillky.imooc_mall.common.Constant;
import com.hillky.imooc_mall.entity.Category;
import com.hillky.imooc_mall.entity.User;
import com.hillky.imooc_mall.exception.ImoocMallException;
import com.hillky.imooc_mall.exception.ImoocMallExceptionEnum;
import com.hillky.imooc_mall.service.IUserService;
import com.sun.deploy.net.HttpResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@Component
public class AdminFilter implements Filter {
@Autowired
private IUserService userService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response= (HttpServletResponse) servletResponse;
response.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
User user = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(user)){
response.getWriter().write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"用户未登录\",\n" +
" \"data\": null\n" +
"}");
return;
}
if(userService.checkAdmin(user)){
filterChain.doFilter(servletRequest, servletResponse);
}else{
response.getWriter().write("{\n" +
" \"status\": 10009,\n" +
" \"msg\": \"无管理员权限\",\n" +
" \"data\": null\n" +
"}");
return;
}
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
配置过滤器
package com.hillky.imooc_mall.config;
import com.hillky.imooc_mall.filter.AdminFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Autowired
private AdminFilter adminFilter;
@Bean
public FilterRegistrationBean addFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(adminFilter);
registration.addUrlPatterns("/admin/category/*","/admin/product/*","/admin/order/*");
registration.setName("adminFilter");
//设置优先级别
registration.setOrder(1);
return registration;
}
}
controller层
@GetMapping("admin/category/delete")
@ApiOperation(value = "后台删除目录")
public ApiRestResponse deleteCategory(@RequestParam("id")Integer id) throws ImoocMallException {
boolean b = this.categoryService.removeById(id);
if(!b){
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
return ApiRestResponse.success();
}
添加分页插件的配置
package com.hillky.imooc_mall.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.hillky.imooc_mall.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
controller层
@GetMapping("admin/category/list")
@ApiOperation(value = "后台查询目录")
public ApiRestResponse listCategory(@RequestParam("pageNum")Integer pageNum,@RequestParam("pageSize")Integer pageSize) throws ImoocMallException {
if(pageNum==null){
pageNum=1;
}
if(pageSize==null){
pageSize=10;
}
Page<Category>page=new Page<>(pageNum,pageSize);
Page<Category> pageObject = this.categoryService.page(page);
return ApiRestResponse.success(pageObject);
}
categoryVo对象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CategoryVO implements Serializable {
private Integer id;
private String name;
private Integer type;
private Integer parentId;
private Integer orderNum;
private Date updateTime;
private List<CategoryVO> childCategory = new ArrayList<>();
}
controller层
@GetMapping("category/list")
@ApiOperation(value = "后台查询目录")
public ApiRestResponse frontListCategory() {
List<CategoryVO> result = this.categoryService.frontListCategory();
return ApiRestResponse.success(result);
}
service层
@Override
public List<CategoryVO> frontListCategory() {
ArrayList<CategoryVO> categoryVOList = new ArrayList<>();
findChildList(categoryVOList, 0);
return categoryVOList;
}
public void findChildList(List<CategoryVO> categoryVOList,Integer parentId){
QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
categoryQueryWrapper.eq("parent_id",parentId);
List<Category> categoryList = this.list(categoryQueryWrapper);
//递归获取所有子类别,并组合成为一个“目录树”
if (!CollectionUtils.isEmpty(categoryList)) {
for (int i = 0; i < categoryList.size(); i++) {
Category category = categoryList.get(i);
CategoryVO categoryVO = new CategoryVO();
BeanUtils.copyProperties(category, categoryVO);
categoryVOList.add(categoryVO);
findChildList(categoryVO.getChildCategory(), categoryVO.getId());
}
}
}
添加依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
开启注解,添加
@SpringBootApplication
@MapperScan("com.hillky.imooc_mall.mapper")
@EnableCaching
public class ImoccMallApplication {
public static void main(String[] args) {
SpringApplication.run(ImoccMallApplication.class, args);
}
}
@GetMapping("category/list")
@Cacheable("frontListCategory")
@ApiOperation(value = "后台查询目录")
public ApiRestResponse frontListCategory() {
List<CategoryVO> result = this.categoryService.frontListCategory();
return ApiRestResponse.success(result);
}
addproductReq实体类,添加参数校验
package com.hillky.imooc_mall.entity.request;
import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.mapstruct.MapperConfig;
public class AddProductReq {
@NotNull(message = "商品名称不能为null")
private String name;
@NotNull(message = "商品图片不能为null")
private String image;
private String detail;
@NotNull(message = "商品分类不能为null")
private Integer categoryId;
@NotNull(message = "商品价格不能为null")
@Min(value = 1, message = "价格不能小于1分")
private Integer price;
@NotNull(message = "商品库存不能为null")
@Max(value = 10000, message = "库存不能大于10000")
private Integer stock;
private Integer status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image == null ? null : image.trim();
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail == null ? null : detail.trim();
}
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "AddProductReq{" +
"name='" + name + '\'' +
", image='" + image + '\'' +
", detail='" + detail + '\'' +
", categoryId=" + categoryId +
", price=" + price +
", stock=" + stock +
", status=" + status +
'}';
}
}
controller层编写
@PostMapping("/admin/product/add")
public ApiRestResponse addProduct(@RequestBody @Validated AddProductReq addProductReq) throws ImoocMallException {
Product product = new Product();
BeanUtils.copyProperties(addProductReq,product);
Product dbProduct = productService.findProductByName(product.getName());
if(!ObjectUtil.isNull(dbProduct)){
throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
}
productService.save(product);
return ApiRestResponse.success();
}
service层编写
@Override
public Product findProductByName(String name) {
QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",name);
return this.getOne(queryWrapper);
}
controller层
@PostMapping("/admin/upload/file")
public ApiRestResponse uploadFile(MultipartFile file) throws ImoocMallException, IOException {
String originalFilename = file.getOriginalFilename();
String type = FileUtil.extName(originalFilename);
String newFileName= IdUtil.fastSimpleUUID()+ StrUtil.DOT +type;
File destFile = new File(fileUploadPath+newFileName);
File parentFile = destFile.getParentFile();
if(!parentFile.exists()){
boolean b = parentFile.mkdirs();
if(!b){
throw new ImoocMallException(ImoocMallExceptionEnum.MKDIR_FAILED);
}
}
file.transferTo(destFile);
String result="http://"+serverIp+":9090/images/"+newFileName;
return ApiRestResponse.success(result);
}
@Value("${file.upload.dir}")
private String fileUploadPath;
@Value(("${server.ip}"))
private String serverIp;
配置静态资源映射
package com.hillky.imooc_mall.config;
import com.hillky.imooc_mall.common.Constant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MallWebConfig implements WebMvcConfigurer {
@Value("${file.upload.dir}")
private String fileUploadPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/images/**").addResourceLocations("file:"+ fileUploadPath);
}
}
UpdateProductReq实体类
package com.hillky.imooc_mall.entity.request;
import lombok.Data;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@Data
public class UpdateProductReq {
@NotNull(message = "id不能为null")
private Integer id;
@NotNull(message = "商品名称不能为null")
private String name;
@NotNull(message = "商品图片不能为null")
private String image;
private String detail;
@NotNull(message = "商品分类不能为null")
private Integer categoryId;
@NotNull(message = "商品价格不能为null")
@Min(value = 1, message = "价格不能小于1分")
private Integer price;
@NotNull(message = "商品库存不能为null")
@Max(value = 10000, message = "库存不能大于10000")
private Integer stock;
private Integer status;
}
controller层
@PostMapping("/admin/product/update")
public ApiRestResponse updateProduct(@RequestBody @Validated UpdateProductReq updateProductReq) throws ImoocMallException {
Product product = new Product();
BeanUtils.copyProperties(updateProductReq,product);
Product dbProduct = productService.getById(updateProductReq.getId());
if(ObjectUtil.isNull(dbProduct)){
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}
productService.updateById(product);
return ApiRestResponse.success();
}
controller层开发
@GetMapping("/admin/product/delete")
public ApiRestResponse deleteProduct(@RequestParam("id")Integer id) throws ImoocMallException {
boolean b = this.productService.removeById(id);
if(!b){
throw new ImoocMallException(ImoocMallExceptionEnum.DELETE_FAILED);
}
return ApiRestResponse.success();
}
controller层
@PostMapping("/admin/product/batchUpdateSellStatus")
public ApiRestResponse batchUpdateSellStatus(@RequestParam("ids")Integer[] ids,
@RequestParam("sellStatus") Integer sellStatus) {
this.productService.batchUpdateSellStatus(ids, sellStatus);
return ApiRestResponse.success();
}
service层
@Override
public void batchUpdateSellStatus(Integer[] ids, Integer sellStatus) {
for (Integer id : ids) {
this.productMapper.updateSellStatus(id,sellStatus);
}
}
mapper层
@Update("update imooc_mall_product set status=#{sellStatus} where id=#{id}")
void updateSellStatus(Integer id, Integer sellStatus);
ProductListReq封装
package com.hillky.imooc_mall.entity.request;
import lombok.Data;
import java.util.Date;
@Data
public class ProductListReq {
private String keyword;
private Integer categoryId;
private String orderBy;
private Integer pageNum = 1;
private Integer pageSize = 10;
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
controller层
@GetMapping("/product/list")
public ApiRestResponse frontListProduct(ProductListReq productListReq) throws ImoocMallException {
IPage<Product> pageObject = this.productService.frontListProduct(productListReq);
return ApiRestResponse.success(pageObject);
}
service层
@Override
public IPage<Product> frontListProduct(ProductListReq productListReq) {
QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
// if(productListReq.getOrderBy().equalsIgnoreCase("price desc")){
// queryWrapper.orderByDesc("price");
// }
// if(productListReq.getOrderBy().equalsIgnoreCase("price asc")){
// queryWrapper.orderByAsc("price");
// }
if(Constant.ProductListOrderBy.PRICE_ASC_DESC.contains(productListReq.getOrderBy())){
queryWrapper.last("order by "+productListReq.getOrderBy());
}
//查找目录要把子目录同样查出来
ArrayList<Integer> ids = new ArrayList<>();
if(!ObjectUtil.isNull(productListReq.getCategoryId())){
List<CategoryVO> categoryVOList = categoryService.frontListCategory(productListReq.getCategoryId());
ids.add(productListReq.getCategoryId());
this.getCategoryIds(categoryVOList,ids);
}
if(ids.size()>0){
queryWrapper.in("category_id",ids);
}
if(StrUtil.isNotBlank(productListReq.getKeyword())){
queryWrapper.like("name",productListReq.getKeyword());
}
Page<Product> page=new Page<>(productListReq.getPageNum(),productListReq.getPageSize());
Page<Product> pageObject = this.page(page,queryWrapper);
return pageObject;
}
public void getCategoryIds(List<CategoryVO> categoryVOList,ArrayList<Integer> categoryIds){
for (CategoryVO categoryVO : categoryVOList) {
if(categoryVO!=null){
categoryIds.add(categoryVO.getId());
this.getCategoryIds(categoryVO.getChildCategory(),categoryIds);
}
}
}
controller层
@GetMapping("/product/detail")
public ApiRestResponse productDetail(@RequestParam("id")Integer id){
Product result = this.productService.getById(id);
return ApiRestResponse.success(result);
}
用户过滤器
package com.hillky.imooc_mall.filter;
import cn.hutool.core.util.ObjectUtil;
import com.hillky.imooc_mall.common.Constant;
import com.hillky.imooc_mall.entity.User;
import com.hillky.imooc_mall.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Component
public class UserFilter implements Filter {
@Autowired
private IUserService userService;
public static User currentUser;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) servletRequest;
HttpServletResponse response= (HttpServletResponse) servletResponse;
response.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
User user = (User) session.getAttribute(Constant.IMOOC_MALL_USER);
if(ObjectUtil.isNull(user)){
response.getWriter().write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"用户未登录\",\n" +
" \"data\": null\n" +
"}");
return;
}
currentUser=user;
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
配置过滤器
@Bean
public FilterRegistrationBean addUserFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(userFilter);
registration.addUrlPatterns("/cart/*","/order/*");
registration.setName("userFilter");
//设置优先级别 数字越小优先级越高
registration.setOrder(1);
return registration;
}
CartVo对象
package com.hillky.imooc_mall.entity.vo;
import lombok.Data;
@Data
public class CartVO {
private Integer id;
private Integer productId;
private Integer userId;
private Integer quantity;
private Integer selected;
private Integer price;
private Integer totalPrice;
private String productName;
private String productImage;
}
controller层编写
@GetMapping("/add")
public ApiRestResponse cartAdd(@RequestParam Integer productId, @RequestParam Integer count) throws ImoocMallException {
Integer userId = UserFilter.currentUser.getId();
List<CartVO> cartVOList = this.cartService.cartAdd(productId,userId,count);
return ApiRestResponse.success(cartVOList);
}
service层编写
@Override
public List<CartVO> cartAdd(Integer productId, Integer userId, Integer count) throws ImoocMallException {
validAddCart(productId,count);
Cart cartDB = this.findCartByProductIdAndUserId(productId, userId);
if(ObjectUtil.isNull(cartDB)){
//没有记录则新增
Cart cart = new Cart();
cart.setProductId(productId);
cart.setUserId(userId);
cart.setQuantity(count);
cart.setSelected(Constant.Cart.CHECKED);
this.save(cart);
}else{
//有记录则更新,数量加count
cartDB.setQuantity(cartDB.getQuantity()+count);
cartDB.setSelected(Constant.Cart.CHECKED);
this.updateById(cartDB);
}
return this.cartList(userId);
}
controller层
@GetMapping("/list")
public ApiRestResponse cartList(){
Integer userId = UserFilter.currentUser.getId();
List<CartVO> result = this.cartService.cartList(userId);
return ApiRestResponse.success(result);
}
service层
@Override
public List<CartVO> cartList(Integer userId) {
//这个方法也可用多表查询语句进行封装
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id",userId);
List<Cart> cartList = this.list(queryWrapper);
List<CartVO> cartVOList=new ArrayList<>();
for (Cart cart : cartList) {
CartVO cartVO = new CartVO();
BeanUtils.copyProperties(cart,cartVO);
Product product = this.productService.getById(cartVO.getProductId());
cartVO.setPrice(product.getPrice());
cartVO.setProductName(product.getName());
cartVO.setProductImage(product.getImage());
cartVO.setTotalPrice(cartVO.getPrice()*cartVO.getQuantity());
cartVOList.add(cartVO);
}
return cartVOList;
}
controller层
@PostMapping("/update")
public ApiRestResponse cartUpdate(@RequestParam("productId") Integer productId,@RequestParam("count") Integer count) throws ImoocMallException {
Integer userId = UserFilter.currentUser.getId();
List<CartVO> result = this.cartService.cartUpdate(userId,productId,count);
return ApiRestResponse.success(result);
}
service层
@Override
public List<CartVO> cartUpdate(Integer userId,Integer productId,Integer count) throws ImoocMallException {
validAddCart(productId,count);
Cart cart = this.findCartByProductIdAndUserId(productId, userId);
cart.setQuantity(count);
this.updateById(cart);
return this.cartList(userId);
}
controller层
@PostMapping("/delete")
public ApiRestResponse cartDeletee(@RequestParam("productId") Integer productId){
Integer userId = UserFilter.currentUser.getId();
List<CartVO> result = this.cartService.cartDelete(userId,productId);
return ApiRestResponse.success(result);
}
service层
@Override
public List<CartVO> cartDelete(Integer userId, Integer productId) {
Cart cart = findCartByProductIdAndUserId(productId, userId);
this.removeById(cart);
return this.cartList(userId);
}
controller层
@PostMapping("/select")
public ApiRestResponse cartSelect(@RequestParam("productId") Integer productId,@RequestParam("selected")Integer selected) throws ImoocMallException {
Integer userId = UserFilter.currentUser.getId();
List<CartVO> result = this.cartService.cartSelect(userId,productId,selected);
return ApiRestResponse.success(result);
}
service层
@Override
public List<CartVO> cartSelect(Integer userId, Integer productId, Integer selected) throws ImoocMallException {
Cart cart = this.findCartByProductIdAndUserId(productId, userId);
if(ObjectUtil.isNull(cart)){
throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
}else{
cart.setSelected(selected);
this.updateById(cart);
}
return this.cartList(userId);
}
controller层
@PostMapping("/selectAll")
public ApiRestResponse cartSelectAll(@RequestParam("selected")Integer selected) throws ImoocMallException {
Integer userId = UserFilter.currentUser.getId();
List<CartVO> result = this.cartService.cartSelectAll(userId,selected);
return ApiRestResponse.success(result);
}
service层
@Override
public List<CartVO> cartSelectAll(Integer userId, Integer selected) throws ImoocMallException {
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id",userId);
List<Cart> cartList = this.list(queryWrapper);
for (Cart cart : cartList) {
this.cartSelect(userId,cart.getProductId(),selected);
}
return this.cartList(userId);
}
请求类
@Data
public class CreateOrderReq {
@NotNull
private String receiverName;
@NotNull
private String receiverMobile;
@NotNull
private String receiverAddress;
private Integer postage=0;
private Integer payType=1;
}
controller层编写
@PostMapping("/create")
public ApiRestResponse createOrder(@RequestBody CreateOrderReq createOrderReq) throws ImoocMallException {
String orderNo=orderService.createOrder(createOrderReq);
return ApiRestResponse.success(orderNo);
}
service层编写 添加数据库事务
@Override
@Transactional
public String createOrder(CreateOrderReq createOrderReq) throws ImoocMallException {
//获取用户id
Integer userId = UserFilter.currentUser.getId();
//根据用户id查询购物车勾选商品的信息
List<CartVO> cartVOList = cartService.cartList(userId);
if (ObjectUtil.isNull(cartVOList)){
throw new ImoocMallException(ImoocMallExceptionEnum.CART_EMPTY);
}
//校验已选商品的购买是否属于可买阶段
for (CartVO cartVO : cartVOList) {
validBuy(cartVO.getProductId(),cartVO.getQuantity());
}
//生成订单号
long id = IdUtil.getSnowflakeNextId();
String orderNo = String.valueOf(id);
//将购物车对象转换为orderItem对象,并保存到order_item表中
ArrayList<OrderItem> orderItemList = new ArrayList<>();
for (CartVO cartVO : cartVOList) {
OrderItem orderItem = new OrderItem();
BeanUtils.copyProperties(cartVO,orderItem);
orderItem.setOrderNo(orderNo);
orderItem.setUnitPrice(cartVO.getPrice());
orderItem.setProductImg(cartVO.getProductImage());
orderItemList.add(orderItem);
}
//将orderItemList存入数据库中
this.orderItemService.saveBatch(orderItemList);
//对商品数量进行更新
for (OrderItem orderItem : orderItemList) {
Product product = productService.getById(orderItem.getProductId());
product.setStock(product.getStock()-orderItem.getQuantity());
this.productService.updateById(product);
}
//对购物车列表进行删除
for (CartVO cartVO : cartVOList) {
this.cartService.removeById(cartVO.getId());
}
//,新增订单
Order order = new Order();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalPrice(getTotalPrice(orderItemList));
order.setReceiverAddress(createOrderReq.getReceiverAddress());
order.setReceiverMobile(createOrderReq.getReceiverMobile());
order.setReceiverName(createOrderReq.getReceiverName());
order.setPaymentType(createOrderReq.getPayType());
order.setPostage(createOrderReq.getPostage());
order.setOrderStatus(Constant.OrderStatusEnum.NOT_PAID.getCode());
this.save(order);
//返回订单号
return orderNo;
}
private Integer getTotalPrice(ArrayList<OrderItem> orderItems) {
Integer totalPrice=0;
for (OrderItem orderItem : orderItems) {
totalPrice+=orderItem.getTotalPrice();
}
return totalPrice;
}
private void validBuy(Integer productId, Integer count) throws ImoocMallException {
Product product = this.productService.getById(productId);
if(ObjectUtil.isNull(product)||product.getStatus().equals(Constant.SaleStatus.NOT_SALE)){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_SALE);
}
if(count>product.getStock()){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_ENOUGH);
}
}
OrderVO实体类
package com.hillky.imooc_mall.entity.vo;
import com.hillky.imooc_mall.entity.OrderItem;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class OrderVO {
/**
* 订单号(非主键id)
*/
private String orderNo;
/**
* 用户id
*/
private Integer userId;
/**
* 订单总价格
*/
private Integer totalPrice;
/**
* 收货人姓名快照
*/
private String receiverName;
/**
* 收货人手机号快照
*/
private String receiverMobile;
/**
* 收货地址快照
*/
private String receiverAddress;
/**
* 订单状态: 0用户已取消,10未付款(初始状态),20已付款,30已发货,40交易完成
*/
private Integer orderStatus;
/**
* 运费,默认为0
*/
private Integer postage;
/**
* 支付类型,1-在线支付
*/
private Integer paymentType;
/**
* 发货时间
*/
private Date deliveryTime;
/**
* 支付时间
*/
private Date payTime;
/**
* 交易完成时间
*/
private Date endTime;
private String orderStatusName;
private List<OrderItemVO> orderItemVOList;
}
OrderItemVO实体类
package com.hillky.imooc_mall.entity.vo;
import lombok.Data;
import java.util.Date;
@Data
public class OrderItemVO {
/**
* 归属订单id
*/
private String orderNo;
/**
* 商品名称
*/
private String productName;
/**
* 商品图片
*/
private String productImg;
/**
* 单价(下单时的快照)
*/
private Integer unitPrice;
/**
* 商品数量
*/
private Integer quantity;
/**
* 商品总价
*/
private Integer totalPrice;
}
controller层
@GetMapping("/detail")
public ApiRestResponse orderDetail(@RequestParam String orderNo) throws ImoocMallException {
OrderVO orderVo=orderService.orderDetail(orderNo);
return ApiRestResponse.success(orderVo);
}
service层
@Override
public OrderVO orderDetail(String orderNo) throws ImoocMallException {
//根据orderNo查询order对象
QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
orderQueryWrapper.eq("order_no",orderNo);
Order order = this.getOne(orderQueryWrapper);
if(ObjectUtil.isNull(order)){
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
if(order.getUserId()!=UserFilter.currentUser.getId()){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
//oderVO值与order赋予
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(order,orderVO);
//orderVO对象中statusName的封装
orderVO.setOrderStatusName(Constant.OrderStatusEnum.codeOf(order.getOrderStatus()).getValue());
//orderVO OrderItemVoList
ArrayList<OrderItemVO> orderItemVOList = new ArrayList<>();
QueryWrapper<OrderItem> orderItemQueryWrapper = new QueryWrapper<>();
orderItemQueryWrapper.eq("order_no",orderNo);
List<OrderItem> orderItemList = this.orderItemService.list(orderItemQueryWrapper);
for (OrderItem orderItem : orderItemList) {
OrderItemVO orderItemVO = new OrderItemVO();
BeanUtils.copyProperties(orderItem,orderItemVO);
orderItemVOList.add(orderItemVO);
}
orderVO.setOrderItemVOList(orderItemVOList);
return orderVO;
}
controller层
@GetMapping("/list")
public ApiRestResponse orderFrontList(@RequestParam Integer pageNum,@RequestParam Integer pageSize) throws ImoocMallException {
Page<Order> orderPage = orderService.orderFrontList(pageNum, pageSize);
return ApiRestResponse.success(orderPage);
}
service层,mybatisplus分页泛型转换
@Override
public Page<Order> orderFrontList(Integer pageNum, Integer pageSize) throws ImoocMallException {
Page<Order> page = new Page<Order>(pageNum,pageSize);
Integer userId = UserFilter.currentUser.getId();
QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
orderQueryWrapper.eq("user_id",userId);
Page<Order> orderPage = this.page(page, orderQueryWrapper);
orderPage.convert(order -> {
OrderVO orderVO = new OrderVO();
try {
orderVO=getOrderVo(order);
} catch (ImoocMallException e) {
e.printStackTrace();
}
return orderVO;
});
return orderPage;
}
controller层
@GetMapping("/cancel")
public ApiRestResponse orderCancel(@RequestParam String orderNo) throws ImoocMallException {
orderService.orderCancel(orderNo);
return ApiRestResponse.success();
}
service层
@Override
public void orderCancel(String orderNo) throws ImoocMallException {
//判断订单是否存在
QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
orderQueryWrapper.eq("order_no",orderNo);
Order order = this.getOne(orderQueryWrapper);
if(ObjectUtil.isNull(order)){
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//判读订单身份归属
Integer userId = UserFilter.currentUser.getId();
if(!order.getUserId().equals(userId)){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
//更改订单状态,要在订单状态为未支付状态下更改
if(order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
order.setOrderStatus(Constant.OrderStatusEnum.CANCELED.getCode());
//更改订单的结束时间
order.setEndTime(new Date());
//更新数据
this.updateById(order);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
引入依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
controller层
@PostMapping("/qrcode")
public ApiRestResponse orderQrcode(@RequestParam String orderNo) throws ImoocMallException {
String payUrl=orderService.orderQrcode(orderNo);
return ApiRestResponse.success(payUrl);
}
service层
@Override
public String orderQrcode(String orderNo) {
//解码结果:支付的url拼接
String payUrl="http://"+ip+":"+port+"/pay?orderNo="+orderNo;
//图片存放的文件
String fileName=orderNo+".png";
File file = new File(fileUploadPath + fileName);
QrCodeUtil.generate(payUrl, 300, 300,file);
//返回图片url
String imgUrl="http://"+ip+":"+port+"/images/"+fileName;
return imgUrl;
}
controller层
@GetMapping("/pay")
public ApiRestResponse orderPay(@RequestParam String orderNo) throws ImoocMallException {
orderService.orderPay(orderNo);
return ApiRestResponse.success();
}
service层
@Override
public void orderPay(String orderNo) throws ImoocMallException {
//查询订单是否合法
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_no", orderNo);
Order order = this.getOne(queryWrapper);
if(ObjectUtil.isNull(order)){
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//更改订单状态(要在初始状态下进行,取消的不能进行)
if(order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
order.setOrderStatus(Constant.OrderStatusEnum.PAID.getCode());
//更改订单付款时间
order.setPayTime(new Date());
this.updateById(order);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
controller层
@GetMapping("/admin/order/list")
public ApiRestResponse orderAdminList(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {
return ApiRestResponse.success(orderService.orderAdminList(pageNum,pageSize));
}
service层
@Override
public IPage<Order> orderAdminList(Integer pageNum, Integer pageSize) {
//构建page对象,进行分页查询
IPage<Order> orderIPage = new Page<Order>(pageNum,pageSize);
IPage<Order> page = this.page(orderIPage);
//convert order类型的转换
page.convert(order -> {
OrderVO orderVo = new OrderVO();
try {
orderVo=getOrderVo(order);
} catch (ImoocMallException e) {
e.printStackTrace();
}
return orderVo;
});
return page;
}
controller层
@PostMapping("/admin/order/delivered")
public ApiRestResponse orderDeliver(@RequestParam String orderNo) throws ImoocMallException {
orderService.orderDeliver(orderNo);
return ApiRestResponse.success();
}
service层
@Override
public void orderDeliver(String orderNo) throws ImoocMallException {
//查找订单,校验合法
Order order = getOrderByOrderNo(orderNo);
if(ObjectUtil.isNull(order)){
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//修改订单状态(只在付款状态后),设置发货时间,更新操作
if(order.getOrderStatus().equals(Constant.OrderStatusEnum.PAID.getCode())){
order.setOrderStatus(Constant.OrderStatusEnum.DELIVERED.getCode());
order.setDeliveryTime(new Date());
this.updateById(order);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}
controller层
@PostMapping("/order/finish")
public ApiRestResponse orderFinish(@RequestParam String orderNo) throws ImoocMallException {
orderService.orderFinish(orderNo);
return ApiRestResponse.success();
}
service层
@Override
public void orderFinish(String orderNo) throws ImoocMallException {
//查询订单,校验合法性
Order order = this.getOrderByOrderNo(orderNo);
if(ObjectUtil.isNull(order)){
throw new ImoocMallException(ImoocMallExceptionEnum.NO_ORDER);
}
//校验订单所属,用户只能对自己的订单进行完结,管理员能对所有订单完结
User user = UserFilter.currentUser;
if(!order.getUserId().equals(user.getId())&&!user.getRole().equals(2)){
throw new ImoocMallException(ImoocMallExceptionEnum.NOT_YOUR_ORDER);
}
//订单在发货状态下更新状态,更新时间,更新操作
if(order.getOrderStatus().equals(Constant.OrderStatusEnum.DELIVERED.getCode())){
order.setOrderStatus(Constant.OrderStatusEnum.FINISHED.getCode());
order.setEndTime(new Date());
this.updateById(order);
}else{
throw new ImoocMallException(ImoocMallExceptionEnum.WRONG_ORDER_STATUS);
}
}