完成订单 售后模块等
This commit is contained in:
66
yshop-module-mall/yshop-module-cart-biz/pom.xml
Normal file
66
yshop-module-mall/yshop-module-cart-biz/pom.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<?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>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-module-mall</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yshop-module-cart-biz</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
cart 模块,主要实现商品购物车相关功能
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-module-cart-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-module-product-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-biz-operatelog</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>co.yixiang.boot</groupId>
|
||||
<artifactId>yshop-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,102 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
import javax.validation.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
import co.yixiang.yshop.framework.common.pojo.CommonResult;
|
||||
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import co.yixiang.yshop.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import co.yixiang.yshop.framework.operatelog.core.annotations.OperateLog;
|
||||
import static co.yixiang.yshop.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import co.yixiang.yshop.module.cart.convert.storecart.StoreCartConvert;
|
||||
import co.yixiang.yshop.module.cart.service.storecart.StoreCartService;
|
||||
|
||||
@Tag(name = "管理后台 - 购物车")
|
||||
@RestController
|
||||
@RequestMapping("/cart/store-cart")
|
||||
@Validated
|
||||
public class StoreCartController {
|
||||
|
||||
@Resource
|
||||
private StoreCartService storeCartService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建购物车")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:create')")
|
||||
public CommonResult<Long> createStoreCart(@Valid @RequestBody StoreCartCreateReqVO createReqVO) {
|
||||
return success(storeCartService.createStoreCart(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新购物车")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:update')")
|
||||
public CommonResult<Boolean> updateStoreCart(@Valid @RequestBody StoreCartUpdateReqVO updateReqVO) {
|
||||
storeCartService.updateStoreCart(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除购物车")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:delete')")
|
||||
public CommonResult<Boolean> deleteStoreCart(@RequestParam("id") Long id) {
|
||||
storeCartService.deleteStoreCart(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得购物车")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:query')")
|
||||
public CommonResult<StoreCartRespVO> getStoreCart(@RequestParam("id") Long id) {
|
||||
StoreCartDO storeCart = storeCartService.getStoreCart(id);
|
||||
return success(StoreCartConvert.INSTANCE.convert(storeCart));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得购物车列表")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:query')")
|
||||
public CommonResult<List<StoreCartRespVO>> getStoreCartList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<StoreCartDO> list = storeCartService.getStoreCartList(ids);
|
||||
return success(StoreCartConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得购物车分页")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:query')")
|
||||
public CommonResult<PageResult<StoreCartRespVO>> getStoreCartPage(@Valid StoreCartPageReqVO pageVO) {
|
||||
PageResult<StoreCartDO> pageResult = storeCartService.getStoreCartPage(pageVO);
|
||||
return success(StoreCartConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出购物车 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('cart:store-cart:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportStoreCartExcel(@Valid StoreCartExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<StoreCartDO> list = storeCartService.getStoreCartList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<StoreCartExcelVO> datas = StoreCartConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "购物车.xls", "数据", StoreCartExcelVO.class, datas);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 购物车 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class StoreCartBaseVO {
|
||||
|
||||
@Schema(description = "用户ID", required = true, example = "10667")
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long uid;
|
||||
|
||||
@Schema(description = "类型", required = true, example = "1")
|
||||
@NotNull(message = "类型不能为空")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "商品ID", required = true, example = "1696")
|
||||
@NotNull(message = "商品ID不能为空")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "商品属性", required = true)
|
||||
@NotNull(message = "商品属性不能为空")
|
||||
private String productAttrUnique;
|
||||
|
||||
@Schema(description = "商品数量", required = true)
|
||||
@NotNull(message = "商品数量不能为空")
|
||||
private Short cartNum;
|
||||
|
||||
@Schema(description = "0 = 未购买 1 = 已购买", required = true)
|
||||
@NotNull(message = "0 = 未购买 1 = 已购买不能为空")
|
||||
private Integer isPay;
|
||||
|
||||
@Schema(description = "是否为立即购买", required = true)
|
||||
@NotNull(message = "是否为立即购买不能为空")
|
||||
private Integer isNew;
|
||||
|
||||
@Schema(description = "拼团id", example = "13847")
|
||||
private Integer combinationId;
|
||||
|
||||
@Schema(description = "秒杀产品ID", required = true, example = "8790")
|
||||
@NotNull(message = "秒杀产品ID不能为空")
|
||||
private Integer seckillId;
|
||||
|
||||
@Schema(description = "砍价id", required = true, example = "21581")
|
||||
@NotNull(message = "砍价id不能为空")
|
||||
private Integer bargainId;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@Schema(description = "管理后台 - 购物车创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class StoreCartCreateReqVO extends StoreCartBaseVO {
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
/**
|
||||
* 购物车 Excel VO
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Data
|
||||
public class StoreCartExcelVO {
|
||||
|
||||
@ExcelProperty("购物车表ID")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("用户ID")
|
||||
private Long uid;
|
||||
|
||||
@ExcelProperty("类型")
|
||||
private String type;
|
||||
|
||||
@ExcelProperty("商品ID")
|
||||
private Long productId;
|
||||
|
||||
@ExcelProperty("商品属性")
|
||||
private String productAttrUnique;
|
||||
|
||||
@ExcelProperty("商品数量")
|
||||
private Integer cartNum;
|
||||
|
||||
@ExcelProperty("0 = 未购买 1 = 已购买")
|
||||
private Integer isPay;
|
||||
|
||||
@ExcelProperty("是否为立即购买")
|
||||
private Integer isNew;
|
||||
|
||||
@ExcelProperty("拼团id")
|
||||
private Integer combinationId;
|
||||
|
||||
@ExcelProperty("秒杀产品ID")
|
||||
private Integer seckillId;
|
||||
|
||||
@ExcelProperty("砍价id")
|
||||
private Integer bargainId;
|
||||
|
||||
@ExcelProperty("添加时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageParam;
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 购物车 Excel 导出 Request VO,参数和 StoreCartPageReqVO 是一致的")
|
||||
@Data
|
||||
public class StoreCartExportReqVO {
|
||||
|
||||
@Schema(description = "用户ID", example = "10667")
|
||||
private Long uid;
|
||||
|
||||
@Schema(description = "类型", example = "1")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "商品ID", example = "1696")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "商品属性")
|
||||
private String productAttrUnique;
|
||||
|
||||
@Schema(description = "商品数量")
|
||||
private Short cartNum;
|
||||
|
||||
@Schema(description = "0 = 未购买 1 = 已购买")
|
||||
private Boolean isPay;
|
||||
|
||||
@Schema(description = "是否为立即购买")
|
||||
private Boolean isNew;
|
||||
|
||||
@Schema(description = "拼团id", example = "13847")
|
||||
private Integer combinationId;
|
||||
|
||||
@Schema(description = "秒杀产品ID", example = "8790")
|
||||
private Integer seckillId;
|
||||
|
||||
@Schema(description = "砍价id", example = "21581")
|
||||
private Integer bargainId;
|
||||
|
||||
@Schema(description = "添加时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 购物车分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class StoreCartPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "用户ID", example = "10667")
|
||||
private Long uid;
|
||||
|
||||
@Schema(description = "类型", example = "1")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "商品ID", example = "1696")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "商品属性")
|
||||
private String productAttrUnique;
|
||||
|
||||
@Schema(description = "商品数量")
|
||||
private Short cartNum;
|
||||
|
||||
@Schema(description = "0 = 未购买 1 = 已购买")
|
||||
private Boolean isPay;
|
||||
|
||||
@Schema(description = "是否为立即购买")
|
||||
private Boolean isNew;
|
||||
|
||||
@Schema(description = "拼团id", example = "13847")
|
||||
private Integer combinationId;
|
||||
|
||||
@Schema(description = "秒杀产品ID", example = "8790")
|
||||
private Integer seckillId;
|
||||
|
||||
@Schema(description = "砍价id", example = "21581")
|
||||
private Integer bargainId;
|
||||
|
||||
@Schema(description = "添加时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 购物车 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class StoreCartRespVO extends StoreCartBaseVO {
|
||||
|
||||
@Schema(description = "购物车表ID", required = true, example = "11256")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "添加时间", required = true)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package co.yixiang.yshop.module.cart.controller.admin.storecart.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@Schema(description = "管理后台 - 购物车更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class StoreCartUpdateReqVO extends StoreCartBaseVO {
|
||||
|
||||
@Schema(description = "购物车表ID", required = true, example = "11256")
|
||||
@NotNull(message = "购物车表ID不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
* 注意:
|
||||
* 本软件为www.yixiang.co开发研制,未经购买不得使用
|
||||
* 购买后可获得全部源代码(禁止转卖、分享、上传到码云、github等开源平台)
|
||||
* 一经发现盗用、分享等行为,将追究法律责任,后果自负
|
||||
*/
|
||||
package co.yixiang.yshop.module.cart.controller.app.cart;
|
||||
|
||||
import co.yixiang.yshop.framework.common.pojo.CommonResult;
|
||||
import co.yixiang.yshop.framework.security.core.annotations.PreAuthenticated;
|
||||
import co.yixiang.yshop.module.cart.controller.app.cart.param.AppCartIdsParm;
|
||||
import co.yixiang.yshop.module.cart.controller.app.cart.param.AppCartNumParam;
|
||||
import co.yixiang.yshop.module.cart.controller.app.cart.param.AppCartParam;
|
||||
import co.yixiang.yshop.module.cart.service.storecart.AppStoreCartService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
|
||||
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 购物车控制器
|
||||
* </p>
|
||||
*
|
||||
* @author hupeng
|
||||
* @since 2023-6-16
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@Tag(name = "用户 APP - 购物车")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
@RequestMapping("/cart")
|
||||
public class AppCartController {
|
||||
|
||||
private final AppStoreCartService appStoreCartService;
|
||||
|
||||
/**
|
||||
* 购物车 获取数量
|
||||
*/
|
||||
@PreAuthenticated
|
||||
@GetMapping("/count")
|
||||
@Operation(summary = "获取数量")
|
||||
public CommonResult<Map<String,Object>> count(){
|
||||
Map<String,Object> map = new LinkedHashMap<>();
|
||||
Long uid = getLoginUserId();
|
||||
map.put("count",appStoreCartService.getUserCartNum(uid));
|
||||
return success(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车 添加
|
||||
*/
|
||||
@PreAuthenticated
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "添加购物车")
|
||||
public CommonResult<Map<String,Object>> add(@Validated @RequestBody AppCartParam cartParam){
|
||||
Map<String,Object> map = new LinkedHashMap<>();
|
||||
Long uid = getLoginUserId();
|
||||
map.put("cartId",appStoreCartService.addCart(uid,cartParam.getProductId(),cartParam.getCartNum(),
|
||||
cartParam.getUniqueId(),cartParam.getIsNew(),cartParam.getCombinationId(),
|
||||
cartParam.getSecKillId(),cartParam.getBargainId()));
|
||||
return success(map);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 购物车列表
|
||||
*/
|
||||
@PreAuthenticated
|
||||
@GetMapping("/cart/list")
|
||||
@Operation(summary = "购物车列表")
|
||||
public CommonResult<Map<String,Object>> getList(){
|
||||
Long uid = getLoginUserId();
|
||||
return success(appStoreCartService.getUserProductCartList(uid,"",null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改产品数量
|
||||
*/
|
||||
@PreAuthenticated
|
||||
@PostMapping("/num")
|
||||
@Operation(summary = "修改产品数量")
|
||||
public CommonResult<Boolean> cartNum(@Validated @RequestBody AppCartNumParam param){
|
||||
Long uid = getLoginUserId();
|
||||
appStoreCartService.changeUserCartNum(param.getId(), param.getNumber(),uid);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 购物车删除产品
|
||||
*/
|
||||
@PreAuthenticated
|
||||
@PostMapping("/cart/del")
|
||||
@Operation(summary = "购物车删除产品")
|
||||
public CommonResult<Boolean> cartDel(@Validated @RequestBody AppCartIdsParm parm){
|
||||
Long uid = getLoginUserId();
|
||||
appStoreCartService.removeUserCart(uid, parm.getIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package co.yixiang.yshop.module.cart.controller.app.cart.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName CartIds
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2023/6/17
|
||||
**/
|
||||
@Data
|
||||
@Schema(description = "用户 APP - 购物车CartIds参数")
|
||||
public class AppCartIdsParm {
|
||||
|
||||
@NotNull(message = "参数有误")
|
||||
@Schema(description = "购物车ID,多个用,分隔开", required = true)
|
||||
List<String> ids;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package co.yixiang.yshop.module.cart.controller.app.cart.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @ClassName 购物车数量CartNumParam
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2023/6/17
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "用户 APP - 购物车数量参数")
|
||||
public class AppCartNumParam {
|
||||
|
||||
@Min(value = 1,message = "数量不在合法范围内")
|
||||
@Max(value = 9999,message = "数量不在合法范围内")
|
||||
@Schema(description = "购物车数量", required = true)
|
||||
private Integer number;
|
||||
|
||||
@NotNull(message = "参数有误")
|
||||
@Schema(description = "购物车ID", required = true)
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package co.yixiang.yshop.module.cart.controller.app.cart.param;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @ClassName 添加购物车CartParam
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2023/6/16
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "用户 APP - 添加购物车参数")
|
||||
public class AppCartParam {
|
||||
|
||||
@Min(value = 1,message = "数量不在合法范围内")
|
||||
@Max(value = 9999,message = "数量不在合法范围内")
|
||||
@Schema(description = "购物车数量", required = true)
|
||||
private Integer cartNum;
|
||||
|
||||
@JsonProperty(value = "new")
|
||||
@Schema(description = "是否立即购买1-是 0-否表示加入购物车列表", required = true)
|
||||
private Integer isNew = 0;
|
||||
|
||||
@NotNull(message = "参数有误")
|
||||
@Schema(description = "产品ID", required = true)
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "商品属性sku的unique值", required = true)
|
||||
private String uniqueId;
|
||||
|
||||
@Schema(description = "产品拼团ID", required = true)
|
||||
private Long combinationId = 0L;
|
||||
|
||||
@Schema(description = "产品秒杀ID", required = true)
|
||||
private Long secKillId = 0L;
|
||||
|
||||
@Schema(description = "产品砍价ID", required = true)
|
||||
private Long bargainId = 0L;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package co.yixiang.yshop.module.cart.convert.storecart;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
||||
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
|
||||
/**
|
||||
* 购物车 Convert
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Mapper
|
||||
public interface StoreCartConvert {
|
||||
|
||||
StoreCartConvert INSTANCE = Mappers.getMapper(StoreCartConvert.class);
|
||||
|
||||
StoreCartDO convert(StoreCartCreateReqVO bean);
|
||||
|
||||
StoreCartDO convert(StoreCartUpdateReqVO bean);
|
||||
|
||||
StoreCartRespVO convert(StoreCartDO bean);
|
||||
|
||||
AppStoreCartQueryVo convert01(StoreCartDO bean);
|
||||
|
||||
List<StoreCartRespVO> convertList(List<StoreCartDO> list);
|
||||
|
||||
PageResult<StoreCartRespVO> convertPage(PageResult<StoreCartDO> page);
|
||||
|
||||
List<StoreCartExcelVO> convertList02(List<StoreCartDO> list);
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package co.yixiang.yshop.module.cart.dal.dataobject.storecart;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import co.yixiang.yshop.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 购物车 DO
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@TableName("yshop_store_cart")
|
||||
@KeySequence("yshop_store_cart_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class StoreCartDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 购物车表ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long uid;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
private Long productId;
|
||||
/**
|
||||
* 商品属性
|
||||
*/
|
||||
private String productAttrUnique;
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer cartNum;
|
||||
/**
|
||||
* 0 = 未购买 1 = 已购买
|
||||
*/
|
||||
private Integer isPay;
|
||||
/**
|
||||
* 是否为立即购买
|
||||
*/
|
||||
private Integer isNew;
|
||||
/**
|
||||
* 拼团id
|
||||
*/
|
||||
private Long combinationId;
|
||||
/**
|
||||
* 秒杀产品ID
|
||||
*/
|
||||
private Long seckillId;
|
||||
/**
|
||||
* 砍价id
|
||||
*/
|
||||
private Long bargainId;
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package co.yixiang.yshop.module.cart.dal.mysql.storecart;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
import co.yixiang.yshop.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import co.yixiang.yshop.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
/**
|
||||
* 购物车 Mapper
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Mapper
|
||||
public interface StoreCartMapper extends BaseMapperX<StoreCartDO> {
|
||||
|
||||
default PageResult<StoreCartDO> selectPage(StoreCartPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<StoreCartDO>()
|
||||
.eqIfPresent(StoreCartDO::getUid, reqVO.getUid())
|
||||
.eqIfPresent(StoreCartDO::getType, reqVO.getType())
|
||||
.eqIfPresent(StoreCartDO::getProductId, reqVO.getProductId())
|
||||
.eqIfPresent(StoreCartDO::getProductAttrUnique, reqVO.getProductAttrUnique())
|
||||
.eqIfPresent(StoreCartDO::getCartNum, reqVO.getCartNum())
|
||||
.eqIfPresent(StoreCartDO::getIsPay, reqVO.getIsPay())
|
||||
.eqIfPresent(StoreCartDO::getIsNew, reqVO.getIsNew())
|
||||
.eqIfPresent(StoreCartDO::getCombinationId, reqVO.getCombinationId())
|
||||
.eqIfPresent(StoreCartDO::getSeckillId, reqVO.getSeckillId())
|
||||
.eqIfPresent(StoreCartDO::getBargainId, reqVO.getBargainId())
|
||||
.betweenIfPresent(StoreCartDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(StoreCartDO::getId));
|
||||
}
|
||||
|
||||
default List<StoreCartDO> selectList(StoreCartExportReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<StoreCartDO>()
|
||||
.eqIfPresent(StoreCartDO::getUid, reqVO.getUid())
|
||||
.eqIfPresent(StoreCartDO::getType, reqVO.getType())
|
||||
.eqIfPresent(StoreCartDO::getProductId, reqVO.getProductId())
|
||||
.eqIfPresent(StoreCartDO::getProductAttrUnique, reqVO.getProductAttrUnique())
|
||||
.eqIfPresent(StoreCartDO::getCartNum, reqVO.getCartNum())
|
||||
.eqIfPresent(StoreCartDO::getIsPay, reqVO.getIsPay())
|
||||
.eqIfPresent(StoreCartDO::getIsNew, reqVO.getIsNew())
|
||||
.eqIfPresent(StoreCartDO::getCombinationId, reqVO.getCombinationId())
|
||||
.eqIfPresent(StoreCartDO::getSeckillId, reqVO.getSeckillId())
|
||||
.eqIfPresent(StoreCartDO::getBargainId, reqVO.getBargainId())
|
||||
.betweenIfPresent(StoreCartDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(StoreCartDO::getId));
|
||||
}
|
||||
|
||||
@Select("select IFNULL(sum(cart_num),0) from yshop_store_cart " +
|
||||
"where is_pay=0 and deleted=0 and is_new=0 and uid=#{uid}")
|
||||
int cartSum(@Param("uid") Long uid);
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package co.yixiang.yshop.module.cart.service.storecart;
|
||||
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 购物车 Service 接口
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
public interface AppStoreCartService extends IService<StoreCartDO> {
|
||||
|
||||
|
||||
/**
|
||||
* 返回当前用户购物车总数量
|
||||
* @param uid 用户id
|
||||
* @return int
|
||||
*/
|
||||
int getUserCartNum(Long uid);
|
||||
|
||||
/**
|
||||
* 添加购物车
|
||||
* @param uid 用户id
|
||||
* @param productId 普通产品编号
|
||||
* @param cartNum 购物车数量
|
||||
* @param productAttrUnique 属性唯一值
|
||||
* @param isNew 1 加入购物车直接购买 0 加入购物车
|
||||
* @param combinationId 拼团id
|
||||
* @param seckillId 秒杀id
|
||||
* @param bargainId 砍价id
|
||||
* @return 购物车id
|
||||
*/
|
||||
long addCart(Long uid,Long productId,Integer cartNum, String productAttrUnique,
|
||||
Integer isNew,Long combinationId,Long seckillId,Long bargainId);
|
||||
|
||||
|
||||
/**
|
||||
* 检测商品/秒杀/砍价/拼团库存
|
||||
* @param uid 用户ID
|
||||
* @param productId 产品ID
|
||||
* @param cartNum 购买数量
|
||||
* @param productAttrUnique 商品属性Unique
|
||||
*/
|
||||
void checkProductStock(Long uid, Long productId, Integer cartNum, String productAttrUnique);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 购物车列表
|
||||
* @param uid 用户id
|
||||
* @param cartIds 购物车id,多个逗号隔开
|
||||
* @param status 0-购购物车列表
|
||||
* @return map valid-有效购物车 invalid-失效购物车
|
||||
*/
|
||||
Map<String,Object> getUserProductCartList(Long uid, String cartIds, Integer status);
|
||||
|
||||
/**
|
||||
* 改购物车数量
|
||||
* @param cartId 购物车id
|
||||
* @param cartNum 数量
|
||||
* @param uid uid
|
||||
*/
|
||||
void changeUserCartNum(Long cartId,int cartNum,Long uid);
|
||||
|
||||
/**
|
||||
* 删除购物车
|
||||
* @param uid uid
|
||||
* @param ids 购物车id集合
|
||||
*/
|
||||
void removeUserCart(Long uid, List<String> ids);
|
||||
|
||||
/**
|
||||
* 修改购物车支付状态
|
||||
* @param cartIds
|
||||
*/
|
||||
void updateCartPayStatus(List<String> cartIds);
|
||||
|
||||
}
|
@ -0,0 +1,285 @@
|
||||
package co.yixiang.yshop.module.cart.service.storecart;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
|
||||
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
|
||||
import co.yixiang.yshop.framework.common.exception.ErrorCode;
|
||||
import co.yixiang.yshop.module.cart.convert.storecart.StoreCartConvert;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import co.yixiang.yshop.module.cart.dal.mysql.storecart.StoreCartMapper;
|
||||
import co.yixiang.yshop.module.cart.enums.CartTypeEnum;
|
||||
import co.yixiang.yshop.module.product.api.product.ProductApi;
|
||||
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
|
||||
import co.yixiang.yshop.module.product.controller.app.product.vo.AppStoreProductRespVo;
|
||||
import co.yixiang.yshop.module.product.dal.dataobject.storeproduct.StoreProductDO;
|
||||
import co.yixiang.yshop.module.product.dal.dataobject.storeproductattrvalue.StoreProductAttrValueDO;
|
||||
import co.yixiang.yshop.module.product.enums.product.ProductTypeEnum;
|
||||
import co.yixiang.yshop.module.product.service.storeproduct.AppStoreProductService;
|
||||
import co.yixiang.yshop.module.product.service.storeproductattrvalue.StoreProductAttrValueService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.STORE_STOCK_ERROR;
|
||||
import static co.yixiang.yshop.module.product.enums.ErrorCodeConstants.STORE_PRODUCT_NOT_EXISTS;
|
||||
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.STORE_CART_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 购物车 Service 实现类
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCartDO> implements AppStoreCartService {
|
||||
|
||||
@Resource
|
||||
private StoreCartMapper storeCartMapper;
|
||||
@Resource
|
||||
private ProductApi productApi;
|
||||
@Resource
|
||||
private AppStoreProductService appStoreProductService;
|
||||
@Resource
|
||||
private StoreProductAttrValueService storeProductAttrValueService;
|
||||
|
||||
/**
|
||||
* 返回当前用户购物车总数量
|
||||
*
|
||||
* @param uid 用户id
|
||||
* @return int
|
||||
*/
|
||||
@Override
|
||||
public int getUserCartNum(Long uid) {
|
||||
return storeCartMapper.cartSum(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加购物车
|
||||
* @param uid 用户id
|
||||
* @param productId 普通产品编号
|
||||
* @param cartNum 购物车数量
|
||||
* @param productAttrUnique 属性唯一值
|
||||
* @param isNew 1 加入购物车直接购买 0 加入购物车
|
||||
* @param combinationId 拼团id
|
||||
* @param seckillId 秒杀id
|
||||
* @param bargainId 砍价id
|
||||
* @return 购物车id
|
||||
*/
|
||||
@Override
|
||||
public long addCart(Long uid, Long productId, Integer cartNum, String productAttrUnique,
|
||||
Integer isNew, Long combinationId, Long seckillId, Long bargainId) {
|
||||
|
||||
this.checkProductStock(uid, productId, cartNum, productAttrUnique);
|
||||
LambdaQueryWrapper<StoreCartDO> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(StoreCartDO::getUid, uid)
|
||||
.eq(StoreCartDO::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
|
||||
.eq(StoreCartDO::getProductId, productId)
|
||||
.eq(StoreCartDO::getIsNew, isNew)
|
||||
.eq(StoreCartDO::getProductAttrUnique, productAttrUnique)
|
||||
.eq(StoreCartDO::getBargainId, bargainId)
|
||||
.eq(StoreCartDO::getCombinationId, combinationId)
|
||||
.eq(StoreCartDO::getSeckillId, seckillId)
|
||||
.orderByDesc(StoreCartDO::getId)
|
||||
.last("limit 1");
|
||||
|
||||
StoreCartDO cart = storeCartMapper.selectOne(wrapper);
|
||||
|
||||
StoreCartDO storeCart = StoreCartDO.builder()
|
||||
.cartNum(cartNum)
|
||||
.productAttrUnique(productAttrUnique)
|
||||
.productId(productId)
|
||||
.bargainId(bargainId)
|
||||
.combinationId(combinationId)
|
||||
.seckillId(seckillId)
|
||||
.isNew(isNew)
|
||||
.uid(uid)
|
||||
.build();
|
||||
if (cart != null) {
|
||||
if (CartTypeEnum.NEW_0.getValue().equals(isNew)) {
|
||||
storeCart.setCartNum(cartNum + cart.getCartNum());
|
||||
}
|
||||
storeCart.setId(cart.getId());
|
||||
storeCartMapper.updateById(storeCart);
|
||||
} else {
|
||||
storeCartMapper.insert(storeCart);
|
||||
}
|
||||
|
||||
return storeCart.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测商品库存
|
||||
*
|
||||
* @param uid 用户ID
|
||||
* @param productId 产品ID
|
||||
* @param cartNum 购买数量
|
||||
* @param productAttrUnique 商品属性Unique
|
||||
*/
|
||||
@Override
|
||||
public void checkProductStock(Long uid, Long productId, Integer cartNum, String productAttrUnique) {
|
||||
StoreProductDO product = appStoreProductService
|
||||
.lambdaQuery().eq(StoreProductDO::getId, productId)
|
||||
.eq(StoreProductDO::getIsShow, ShopCommonEnum.SHOW_1.getValue())
|
||||
.one();
|
||||
if (product == null) {
|
||||
throw exception(STORE_PRODUCT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
int stock = appStoreProductService.getProductStock(productId, productAttrUnique, "");
|
||||
if (stock < cartNum) {
|
||||
throw exception(new ErrorCode(1008003010, product.getStoreName() + "库存不足" + cartNum));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 购物车列表
|
||||
*
|
||||
* @param uid 用户id
|
||||
* @param cartIds 购物车id,多个逗号隔开
|
||||
* @param status 0-购购物车列表
|
||||
* @return map valid-有效购物车 invalid-失效购物车
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getUserProductCartList(Long uid, String cartIds, Integer status) {
|
||||
LambdaQueryWrapper<StoreCartDO> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(StoreCartDO::getUid, uid)
|
||||
.eq(StoreCartDO::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
|
||||
.orderByDesc(StoreCartDO::getId);
|
||||
if (status == null) {
|
||||
wrapper.eq(StoreCartDO::getIsNew, CartTypeEnum.NEW_0.getValue());
|
||||
}
|
||||
if (StrUtil.isNotEmpty(cartIds)) {
|
||||
wrapper.in(StoreCartDO::getId, Arrays.asList(cartIds.split(",")));
|
||||
}
|
||||
List<StoreCartDO> carts = storeCartMapper.selectList(wrapper);
|
||||
|
||||
List<AppStoreCartQueryVo> valid = new ArrayList<>();
|
||||
List<AppStoreCartQueryVo> invalid = new ArrayList<>();
|
||||
|
||||
for (StoreCartDO storeCart : carts) {
|
||||
AppStoreProductRespVo storeProduct = appStoreProductService.getStoreProductById(storeCart.getProductId());
|
||||
AppStoreCartQueryVo storeCartQueryVo = StoreCartConvert.INSTANCE.convert01(storeCart);
|
||||
if (ObjectUtil.isNull(storeProduct)) {
|
||||
this.removeById(storeCart.getId());
|
||||
} else if (ShopCommonEnum.SHOW_0.getValue().equals(storeProduct.getIsShow()) || (storeProduct.getStock() == 0 && StrUtil.isEmpty(storeCart.getProductAttrUnique()))) {
|
||||
storeCartQueryVo.setProductInfo(storeProduct);
|
||||
invalid.add(storeCartQueryVo);
|
||||
} else {
|
||||
StoreProductAttrValueDO productAttrValue = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValueDO>lambdaQuery()
|
||||
.eq(StoreProductAttrValueDO::getUnique,storeCart.getProductAttrUnique()));
|
||||
if (ObjectUtil.isNull(productAttrValue) || productAttrValue.getStock() == 0) {
|
||||
storeCartQueryVo.setProductInfo(storeProduct);
|
||||
invalid.add(storeCartQueryVo);
|
||||
} else {
|
||||
storeProduct.setAttrInfo(productAttrValue);
|
||||
storeCartQueryVo.setProductInfo(storeProduct);
|
||||
//普通商品金额
|
||||
BigDecimal truePrice = storeProduct.getPrice();
|
||||
//设置拼团价格
|
||||
if(storeCart.getCombinationId() > 0 ){
|
||||
truePrice = productAttrValue.getPinkPrice();
|
||||
}
|
||||
//设置秒杀价格
|
||||
if( storeCart.getSeckillId() > 0){
|
||||
truePrice = productAttrValue.getSeckillPrice();
|
||||
}
|
||||
storeCartQueryVo.setTruePrice(truePrice);
|
||||
storeCartQueryVo.setTrueStock(productAttrValue.getStock());
|
||||
valid.add(storeCartQueryVo);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("valid", valid);
|
||||
map.put("invalid", invalid);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 改购物车数量
|
||||
*
|
||||
* @param cartId 购物车id
|
||||
* @param cartNum 数量
|
||||
* @param uid uid
|
||||
*/
|
||||
@Override
|
||||
public void changeUserCartNum(Long cartId, int cartNum, Long uid) {
|
||||
StoreCartDO cart = this.lambdaQuery()
|
||||
.eq(StoreCartDO::getUid, uid)
|
||||
.eq(StoreCartDO::getId, cartId)
|
||||
.one();
|
||||
if (cart == null) {
|
||||
throw exception(STORE_CART_NOT_EXISTS);
|
||||
}
|
||||
|
||||
if (cartNum <= 0) {
|
||||
throw exception(STORE_STOCK_ERROR);
|
||||
}
|
||||
|
||||
//普通商品库存
|
||||
int stock = appStoreProductService.getProductStock(cart.getProductId()
|
||||
, cart.getProductAttrUnique(), "");
|
||||
if (stock < cartNum) {
|
||||
throw exception(new ErrorCode(1008006002, "该产品库存不足" + cartNum));
|
||||
}
|
||||
|
||||
if (cartNum == cart.getCartNum()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StoreCartDO storeCart = new StoreCartDO();
|
||||
storeCart.setCartNum(cartNum);
|
||||
storeCart.setId(cartId);
|
||||
|
||||
storeCartMapper.updateById(storeCart);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除购物车
|
||||
*
|
||||
* @param uid uid
|
||||
* @param ids 购物车id集合
|
||||
*/
|
||||
@Override
|
||||
public void removeUserCart(Long uid, List<String> ids) {
|
||||
List<Long> newids = ids.stream().map(Long::new).collect(Collectors.toList());
|
||||
storeCartMapper.delete(Wrappers.<StoreCartDO>lambdaQuery()
|
||||
.eq(StoreCartDO::getUid, uid)
|
||||
.in(StoreCartDO::getId, newids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改购物车支付状态
|
||||
* @param cartIds
|
||||
*/
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
|
||||
public void updateCartPayStatus(List<String> cartIds) {
|
||||
StoreCartDO cartObj = new StoreCartDO();
|
||||
cartObj.setIsPay(OrderInfoEnum.PAY_STATUS_1.getValue());
|
||||
storeCartMapper.update(cartObj, Wrappers.<StoreCartDO>lambdaQuery()
|
||||
.in(StoreCartDO::getId, cartIds));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package co.yixiang.yshop.module.cart.service.storecart;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
||||
/**
|
||||
* 购物车 Service 接口
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
public interface StoreCartService {
|
||||
|
||||
/**
|
||||
* 创建购物车
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createStoreCart(@Valid StoreCartCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新购物车
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateStoreCart(@Valid StoreCartUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除购物车
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteStoreCart(Long id);
|
||||
|
||||
/**
|
||||
* 获得购物车
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 购物车
|
||||
*/
|
||||
StoreCartDO getStoreCart(Long id);
|
||||
|
||||
/**
|
||||
* 获得购物车列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 购物车列表
|
||||
*/
|
||||
List<StoreCartDO> getStoreCartList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得购物车分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 购物车分页
|
||||
*/
|
||||
PageResult<StoreCartDO> getStoreCartPage(StoreCartPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得购物车列表, 用于 Excel 导出
|
||||
*
|
||||
* @param exportReqVO 查询条件
|
||||
* @return 购物车列表
|
||||
*/
|
||||
List<StoreCartDO> getStoreCartList(StoreCartExportReqVO exportReqVO);
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package co.yixiang.yshop.module.cart.service.storecart;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.*;
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
||||
import co.yixiang.yshop.module.cart.convert.storecart.StoreCartConvert;
|
||||
import co.yixiang.yshop.module.cart.dal.mysql.storecart.StoreCartMapper;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 购物车 Service 实现类
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class StoreCartServiceImpl implements StoreCartService {
|
||||
|
||||
@Resource
|
||||
private StoreCartMapper storeCartMapper;
|
||||
|
||||
@Override
|
||||
public Long createStoreCart(StoreCartCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
StoreCartDO storeCart = StoreCartConvert.INSTANCE.convert(createReqVO);
|
||||
storeCartMapper.insert(storeCart);
|
||||
// 返回
|
||||
return storeCart.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStoreCart(StoreCartUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateStoreCartExists(updateReqVO.getId());
|
||||
// 更新
|
||||
StoreCartDO updateObj = StoreCartConvert.INSTANCE.convert(updateReqVO);
|
||||
storeCartMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteStoreCart(Long id) {
|
||||
// 校验存在
|
||||
validateStoreCartExists(id);
|
||||
// 删除
|
||||
storeCartMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateStoreCartExists(Long id) {
|
||||
if (storeCartMapper.selectById(id) == null) {
|
||||
throw exception(STORE_CART_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoreCartDO getStoreCart(Long id) {
|
||||
return storeCartMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreCartDO> getStoreCartList(Collection<Long> ids) {
|
||||
return storeCartMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<StoreCartDO> getStoreCartPage(StoreCartPageReqVO pageReqVO) {
|
||||
return storeCartMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoreCartDO> getStoreCartList(StoreCartExportReqVO exportReqVO) {
|
||||
return storeCartMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?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="co.yixiang.yshop.module.cart.dal.mysql.storecart.StoreCartMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
</mapper>
|
@ -0,0 +1,231 @@
|
||||
package co.yixiang.yshop.module.cart.service.storecart;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import co.yixiang.yshop.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
||||
import co.yixiang.yshop.module.cart.controller.admin.storecart.vo.*;
|
||||
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
|
||||
import co.yixiang.yshop.module.cart.dal.mysql.storecart.StoreCartMapper;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.*;
|
||||
import static co.yixiang.yshop.framework.test.core.util.AssertUtils.*;
|
||||
import static co.yixiang.yshop.framework.test.core.util.RandomUtils.*;
|
||||
import static co.yixiang.yshop.framework.common.util.date.LocalDateTimeUtils.*;
|
||||
import static co.yixiang.yshop.framework.common.util.object.ObjectUtils.*;
|
||||
import static co.yixiang.yshop.framework.common.util.date.DateUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link StoreCartServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author yshop
|
||||
*/
|
||||
@Import(StoreCartServiceImpl.class)
|
||||
public class StoreCartServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private StoreCartServiceImpl storeCartService;
|
||||
|
||||
@Resource
|
||||
private StoreCartMapper storeCartMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateStoreCart_success() {
|
||||
// 准备参数
|
||||
StoreCartCreateReqVO reqVO = randomPojo(StoreCartCreateReqVO.class);
|
||||
|
||||
// 调用
|
||||
Long storeCartId = storeCartService.createStoreCart(reqVO);
|
||||
// 断言
|
||||
assertNotNull(storeCartId);
|
||||
// 校验记录的属性是否正确
|
||||
StoreCartDO storeCart = storeCartMapper.selectById(storeCartId);
|
||||
assertPojoEquals(reqVO, storeCart);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStoreCart_success() {
|
||||
// mock 数据
|
||||
StoreCartDO dbStoreCart = randomPojo(StoreCartDO.class);
|
||||
storeCartMapper.insert(dbStoreCart);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
StoreCartUpdateReqVO reqVO = randomPojo(StoreCartUpdateReqVO.class, o -> {
|
||||
o.setId(dbStoreCart.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
storeCartService.updateStoreCart(reqVO);
|
||||
// 校验是否更新正确
|
||||
StoreCartDO storeCart = storeCartMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, storeCart);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStoreCart_notExists() {
|
||||
// 准备参数
|
||||
StoreCartUpdateReqVO reqVO = randomPojo(StoreCartUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> storeCartService.updateStoreCart(reqVO), STORE_CART_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStoreCart_success() {
|
||||
// mock 数据
|
||||
StoreCartDO dbStoreCart = randomPojo(StoreCartDO.class);
|
||||
storeCartMapper.insert(dbStoreCart);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbStoreCart.getId();
|
||||
|
||||
// 调用
|
||||
storeCartService.deleteStoreCart(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(storeCartMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteStoreCart_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> storeCartService.deleteStoreCart(id), STORE_CART_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStoreCartPage() {
|
||||
// mock 数据
|
||||
StoreCartDO dbStoreCart = randomPojo(StoreCartDO.class, o -> { // 等会查询到
|
||||
o.setUid(null);
|
||||
o.setType(null);
|
||||
o.setProductId(null);
|
||||
o.setProductAttrUnique(null);
|
||||
o.setCartNum(null);
|
||||
o.setIsPay(null);
|
||||
o.setIsNew(null);
|
||||
o.setCombinationId(null);
|
||||
o.setSeckillId(null);
|
||||
o.setBargainId(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
storeCartMapper.insert(dbStoreCart);
|
||||
// 测试 uid 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setUid(null)));
|
||||
// 测试 type 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setType(null)));
|
||||
// 测试 productId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setProductId(null)));
|
||||
// 测试 productAttrUnique 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setProductAttrUnique(null)));
|
||||
// 测试 cartNum 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCartNum(null)));
|
||||
// 测试 isPay 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setIsPay(null)));
|
||||
// 测试 isNew 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setIsNew(null)));
|
||||
// 测试 combinationId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCombinationId(null)));
|
||||
// 测试 seckillId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setSeckillId(null)));
|
||||
// 测试 bargainId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setBargainId(null)));
|
||||
// 测试 createTime 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
StoreCartPageReqVO reqVO = new StoreCartPageReqVO();
|
||||
reqVO.setUid(null);
|
||||
reqVO.setType(null);
|
||||
reqVO.setProductId(null);
|
||||
reqVO.setProductAttrUnique(null);
|
||||
reqVO.setCartNum(null);
|
||||
reqVO.setIsPay(null);
|
||||
reqVO.setIsNew(null);
|
||||
reqVO.setCombinationId(null);
|
||||
reqVO.setSeckillId(null);
|
||||
reqVO.setBargainId(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
PageResult<StoreCartDO> pageResult = storeCartService.getStoreCartPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbStoreCart, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetStoreCartList() {
|
||||
// mock 数据
|
||||
StoreCartDO dbStoreCart = randomPojo(StoreCartDO.class, o -> { // 等会查询到
|
||||
o.setUid(null);
|
||||
o.setType(null);
|
||||
o.setProductId(null);
|
||||
o.setProductAttrUnique(null);
|
||||
o.setCartNum(null);
|
||||
o.setIsPay(null);
|
||||
o.setIsNew(null);
|
||||
o.setCombinationId(null);
|
||||
o.setSeckillId(null);
|
||||
o.setBargainId(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
storeCartMapper.insert(dbStoreCart);
|
||||
// 测试 uid 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setUid(null)));
|
||||
// 测试 type 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setType(null)));
|
||||
// 测试 productId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setProductId(null)));
|
||||
// 测试 productAttrUnique 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setProductAttrUnique(null)));
|
||||
// 测试 cartNum 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCartNum(null)));
|
||||
// 测试 isPay 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setIsPay(null)));
|
||||
// 测试 isNew 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setIsNew(null)));
|
||||
// 测试 combinationId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCombinationId(null)));
|
||||
// 测试 seckillId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setSeckillId(null)));
|
||||
// 测试 bargainId 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setBargainId(null)));
|
||||
// 测试 createTime 不匹配
|
||||
storeCartMapper.insert(cloneIgnoreId(dbStoreCart, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
StoreCartExportReqVO reqVO = new StoreCartExportReqVO();
|
||||
reqVO.setUid(null);
|
||||
reqVO.setType(null);
|
||||
reqVO.setProductId(null);
|
||||
reqVO.setProductAttrUnique(null);
|
||||
reqVO.setCartNum(null);
|
||||
reqVO.setIsPay(null);
|
||||
reqVO.setIsNew(null);
|
||||
reqVO.setCombinationId(null);
|
||||
reqVO.setSeckillId(null);
|
||||
reqVO.setBargainId(null);
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||
|
||||
// 调用
|
||||
List<StoreCartDO> list = storeCartService.getStoreCartList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbStoreCart, list.get(0));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user