新增购物车;新增购买限制策略;调整预生成订单

This commit is contained in:
DB 2023-11-06 17:55:25 +08:00
parent 212110afc8
commit 4ea49f82bb
24 changed files with 944 additions and 11 deletions

View File

@ -40,17 +40,17 @@ public class CpopGenerator {
/**
* 输出路径
*/
private static final String EXPORT_URL = "/Cpop-System";
private static final String EXPORT_URL = "/Cpop-Mall";
/**
* 模块
*/
private static final String EXPORT_ITEM = "system";
private static final String EXPORT_ITEM = "mall";
/**
* 表前缀
*/
private static final String TABLE_PREFIX = "cp_sys_";
private static final String TABLE_PREFIX = "cp_mall_";
/**
* 主入口

View File

@ -26,7 +26,8 @@ public class PlaceOrderBo implements Serializable {
/**
* 主键
*/
@ApiModelProperty("主键")
@NotBlank(message = "主键不能为空")
@ApiModelProperty(value = "主键",required = true)
private String id;
/**

View File

@ -0,0 +1,57 @@
package com.cpop.mall.business.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author DB
* @createTime 2023/11/06 14:12
* @description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "商城购物车新增对象")
public class ShoppingCartBo implements Serializable {
/**
* 商品记录id
*/
@NotBlank(message = "商品记录id不能为空")
@ApiModelProperty(value = "商品记录id",required = true)
private String productRecordId;
/**
* 校区id
*/
@NotBlank(message = "校区id不能为空")
@ApiModelProperty(value = "校区id",required = true)
private String storeId;
/**
* 金额
*/
@NotNull(message = "金额不能为空")
@ApiModelProperty(value = "金额",required = true)
private BigDecimal amount;
/**
* 积分
*/
@NotNull(message = "积分不能为空")
@ApiModelProperty(value = "积分",required = true)
private Integer point;
/**
* 数量
*/
@NotNull(message = "数量不能为空")
@ApiModelProperty(value = "数量",required = true)
private Integer number;
}

View File

@ -0,0 +1,25 @@
package com.cpop.mall.business.bo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author DB
* @createTime 2023/11/06 13:52
* @description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "商城购物车查询对象")
public class ShoppingCartPageBo implements Serializable {
/**
* 商品名
*/
@ApiModelProperty("商品名")
private String productName;
}

View File

@ -126,12 +126,24 @@ public class MiniOrderController {
* @param orderId 订单id
* @return: com.cpop.core.base.R<com.mybatisflex.core.paginate.Page<com.cpop.mall.business.vo.OrderPageVo>>
*/
@GetMapping("/rePayOrder/{orderId}")
@Deprecated
@PutMapping("/rePayOrder/{orderId}")
@ApiOperation("小程序-重新支付订单")
public R<Object> rePayOrder(@PathVariable @ApiParam(value = "订单id", required = true) String orderId) {
return R.ok(orderService.rePayOrder(orderId));
}
/**
* @descriptions 小程序-获取订单详情
* @author DB
* @date 2023/11/06 14:25
* @param orderId 订单id
* @return: com.cpop.core.base.R<java.lang.Object>
*/
@GetMapping("/getOrderInfo/{orderId}")
@ApiOperation("小程序-获取订单详情")
public R<OrderInfoVo> getOrderInfo(@PathVariable @ApiParam(value = "订单id", required = true) String orderId) {
return R.ok(orderService.getOrderInfo(orderId));
}
}

View File

@ -5,10 +5,7 @@ import com.cpop.core.base.R;
import com.cpop.core.utils.SpringUtils;
import com.cpop.mall.business.bo.ProductPageBo;
import com.cpop.mall.business.service.ProductService;
import com.cpop.mall.business.vo.MiniProductPageVo;
import com.cpop.mall.business.vo.ProductEvaluateVo;
import com.cpop.mall.business.vo.ProductPageVo;
import com.cpop.mall.business.vo.StoreListVo;
import com.cpop.mall.business.vo.*;
import com.cpop.system.business.entity.Store;
import com.cpop.system.business.service.StoreService;
import com.mybatisflex.core.paginate.Page;
@ -91,4 +88,18 @@ public class MiniProductController {
return R.ok(list);
}
/**
* @descriptions 获取商品详情
* @author DB
* @date 2023/11/06 11:55
* @param id 商品id
* @return: com.cpop.core.base.R<com.cpop.mall.business.vo.ProductInfoVo>
*/
@GetMapping("/getProductInfo/{id}")
@ApiOperation("获取商品详情")
public R<ProductInfoVo> getProductInfo(@PathVariable("id") @ApiParam(value = "商品id", required = true) String id) {
ProductInfoVo info = productService.getProductInfo(id);
return R.ok(info);
}
}

View File

@ -0,0 +1,78 @@
package com.cpop.mall.business.controller.mini;
import com.cpop.core.base.R;
import com.cpop.mall.business.bo.AdvanceOrderBo;
import com.cpop.mall.business.bo.ProductPageBo;
import com.cpop.mall.business.bo.ShoppingCartBo;
import com.cpop.mall.business.bo.ShoppingCartPageBo;
import com.cpop.mall.business.vo.MiniProductPageVo;
import com.cpop.mall.business.vo.MiniShoppingCartPageVo;
import com.mybatisflex.core.paginate.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.cpop.mall.business.entity.ShoppingCart;
import com.cpop.mall.business.service.ShoppingCartService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
/**
* 商城购物车表 控制层
*
* @author DB
* @since 2023-11-06
*/
@RestController
@Api(tags = "小程序-商城购物车接口")
@RequestMapping("/mini/shoppingCart")
public class MiniShoppingCartController {
@Autowired
private ShoppingCartService shoppingCartService;
/**
* @descriptions 分页查询小程序-商城-购物车分页
* @author DB
* @date 2023/11/06 14:10
* @param bo 请求参数
* @return: com.cpop.core.base.R<com.mybatisflex.core.paginate.Page<com.cpop.mall.business.vo.MiniShoppingCartPageVo>>
*/
@GetMapping("/getMiniShoppingCartPage")
@ApiOperation("分页查询小程序-商城-购物车分页")
public R<Page<MiniShoppingCartPageVo>> getMiniShoppingCartPage(@ApiParam("分页参数") ShoppingCartPageBo bo) {
Page<MiniShoppingCartPageVo> page = shoppingCartService.getMiniShoppingCartPage(bo);
return R.ok(page);
}
/**
* @descriptions 小程序-商城-购物车添加商品
* @author DB
* @date 2023/11/06 14:14
* @param bo 请求参数
* @return: com.cpop.core.base.R<java.lang.String>
*/
@PostMapping("/insertShoppingCart")
@ApiOperation("小程序-商城-购物车添加商品")
public R<String> insertShoppingCart(@RequestBody @Validated @ApiParam("商城-购物车新增参数") ShoppingCartBo bo) {
shoppingCartService.insertShoppingCart(bo);
return R.ok();
}
/**
* @descriptions 小程序-商城-购物车删除商
* @author DB
* @date 2023/11/06 14:14
* @param ids 主键
* @return: com.cpop.core.base.R<java.lang.String>
*/
@DeleteMapping("/removeShoppingCart")
@ApiOperation("小程序-商城-购物车删除商品")
public R<Void> removeShoppingCart(@RequestParam("ids") @ApiParam("商城-购物车新增参数") String[] ids) {
shoppingCartService.removeByIds(Arrays.asList(ids));
return R.ok();
}
}

View File

@ -0,0 +1,68 @@
package com.cpop.mall.business.entity;
import com.cpop.core.base.entity.BaseEntity;
import com.cpop.core.base.entity.BaseInsertListener;
import com.cpop.core.base.entity.BaseUpdateListener;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
/**
* 商城购物车表 实体类
*
* @author DB
* @since 2023-11-06
*/
@Data
@EqualsAndHashCode(callSuper=false)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Table(value = "cp_mall_shopping_cart", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class ShoppingCart extends BaseEntity implements Serializable {
/**
* 主键
*/
@Id
private String id;
/**
* 用户id
*/
private String userId;
/**
* 商品记录id
*/
private String productRecordId;
/**
* 店铺/校区id
*/
private byte[] storeId;
/**
* 金额
*/
private BigDecimal amount;
/**
* 积分
*/
private Integer point;
/**
* 数量
*/
private Integer number;
}

View File

@ -0,0 +1,14 @@
package com.cpop.mall.business.mapper;
import com.mybatisflex.core.BaseMapper;
import com.cpop.mall.business.entity.ShoppingCart;
/**
* 商城购物车表 映射层
*
* @author DB
* @since 2023-11-06
*/
public interface ShoppingCartMapper extends BaseMapper<ShoppingCart> {
}

View File

@ -95,4 +95,12 @@ public interface OrderService extends IService<Order> {
*/
Object rePayOrder(String orderId);
/**
* @descriptions 小程序-获取订单详情
* @author DB
* @date 2023/11/06 14:26
* @param orderId 订单id
* @return: com.cpop.mall.business.vo.OrderInfoVo
*/
OrderInfoVo getOrderInfo(String orderId);
}

View File

@ -97,4 +97,12 @@ public interface ProductService extends IService<Product> {
*/
Page<ProductEvaluateVo> getOrderEvaluatePage(String productId);
/**
* @descriptions 获取商品详情
* @author DB
* @date 2023/11/06 11:56
* @param id 商品id
* @return: com.cpop.mall.business.vo.ProductInfoVo
*/
ProductInfoVo getProductInfo(String id);
}

View File

@ -0,0 +1,35 @@
package com.cpop.mall.business.service;
import com.cpop.mall.business.bo.ShoppingCartBo;
import com.cpop.mall.business.bo.ShoppingCartPageBo;
import com.cpop.mall.business.vo.MiniShoppingCartPageVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.cpop.mall.business.entity.ShoppingCart;
/**
* 商城购物车表 服务层
*
* @author DB
* @since 2023-11-06
*/
public interface ShoppingCartService extends IService<ShoppingCart> {
/**
* @descriptions 分页查询小程序-商城-购物车分页
* @author DB
* @date 2023/11/06 14:02
* @param bo 请求参数
* @return: com.mybatisflex.core.paginate.Page<com.cpop.mall.business.vo.MiniShoppingCartPageVo>
*/
Page<MiniShoppingCartPageVo> getMiniShoppingCartPage(ShoppingCartPageBo bo);
/**
* @descriptions 小程序-商城-购物车添加商品
* @author DB
* @date 2023/11/06 14:17
* @param bo 请求参数
* @return: void
*/
void insertShoppingCart(ShoppingCartBo bo);
}

View File

@ -21,9 +21,11 @@ import com.cpop.mall.business.service.*;
import com.cpop.mall.business.task.OrderOverTimeUnPayTask;
import com.cpop.mall.business.task.ProductRecordSyncStockTask;
import com.cpop.mall.business.task.WxPayAsyncTask;
import com.cpop.mall.business.vo.OrderDetailVo;
import com.cpop.mall.business.vo.OrderInfoVo;
import com.cpop.mall.business.vo.OrderPageVo;
import com.cpop.mall.framework.constant.MallRedisConstant;
import com.cpop.mall.framework.enums.BuyRestrictEnums;
import com.cpop.mall.framework.enums.QuartzEnums;
import com.cpop.mall.framework.handler.WxPayHandler;
import com.cpop.system.business.entity.Brand;
@ -54,6 +56,8 @@ import static com.cpop.mall.business.entity.table.ProductRecordTableDef.PRODUCT_
import static com.cpop.mall.business.entity.table.ProductTableDef.PRODUCT;
import static com.cpop.system.business.entity.table.ProfitSharingTableDef.PROFIT_SHARING;
import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
import static com.mybatisflex.core.query.QueryMethods.field;
import static com.mybatisflex.core.query.QueryMethods.select;
/**
@ -152,7 +156,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
try {
Order order = BeanUtils.mapToClass(bo, Order.class);
List<OrderDetail> orderDetails = BeanUtils.mapToList(bo.getOrderDetailList(), OrderDetail.class);
recordNumIsEnough= recordNumIsEnough(orderDetails);
//规格记录ids
Set<String> recordIds = orderDetails.stream().map(OrderDetail::getProductRecordId).collect(Collectors.toSet());
//获取涉及到的商品
@ -163,6 +166,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
.leftJoin(PRODUCT_RECORD).on(PRODUCT_RECORD.PRODUCT_ID.eq(PRODUCT.ID))
.where(PRODUCT_RECORD.ID.in(recordIds))
.list();
//检查库存
recordNumIsEnough= recordNumIsEnough(orderDetails);
//购买限制
buyRestrict(productList, recordNumIsEnough);
//设置待付款
order.setOrderStatus(0)
.setPreviousStatus(0)
@ -213,6 +220,17 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
private void buyRestrict(List<Product> productList, Map<String, Integer> recordNumIsEnough) {
//过滤出存在购买限制的商品
List<Product> filterProduct = productList.stream().filter(item -> item.getBuyRestrict() != null).collect(Collectors.toList());
//过滤之后不为空存在购买限制
if (!filterProduct.isEmpty()){
filterProduct.forEach(item->{
BuyRestrictEnums.getByCode(item.getBuyRestrict()).getBuyRestrictStrategy().buyRestrict(item, recordNumIsEnough);
});
}
}
/**
* @descriptions 商城-订单-下单
* @author DB
@ -551,4 +569,33 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
/**
* @descriptions 小程序-获取订单详情
* @author DB
* @date 2023/11/06 14:26
* @param orderId 订单id
* @return: com.cpop.mall.business.vo.OrderInfoVo
*/
@Override
public OrderInfoVo getOrderInfo(String orderId) {
OrderInfoVo orderInfoVo = this.mapper.selectOneWithRelationsByIdAs(orderId, OrderInfoVo.class);
//获取订单详情
List<OrderDetailVo> orderDetailVos = SpringUtils.getBean(OrderDetailService.class).listAs(QueryWrapper.create()
.select(PRODUCT.PRODUCT_NAME, PRODUCT.PIC_URL, PRODUCT.PIC_DETAIL_URL)
//订单详情
.select(ORDER_DETAIL.ORDER_ID, ORDER_DETAIL.PRODUCT_RECORD_ID, ORDER_DETAIL.AMOUNT, ORDER_DETAIL.POINT, ORDER_DETAIL.STORE_ID)
//规格
.select(PRODUCT_RECORD.RECORD_NAMES)
//校区
.select(STORE.STORE_NAME)
.from(ORDER_DETAIL)
.leftJoin(PRODUCT_RECORD).on(PRODUCT_RECORD.ID.eq(ORDER_DETAIL.PRODUCT_RECORD_ID))
.leftJoin(PRODUCT).on(PRODUCT.ID.eq(PRODUCT_RECORD.PRODUCT_ID))
.leftJoin(STORE).on(STORE.ID.eq(ORDER_DETAIL.STORE_ID))
.where(ORDER_DETAIL.ORDER_ID.eq(orderId)),
OrderDetailVo.class);
orderInfoVo.setDetailList(orderDetailVos);
return orderInfoVo;
}
}

View File

@ -380,4 +380,16 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
.where(PRODUCT.ID.eq(productId)),
ProductEvaluateVo.class);
}
/**
* @descriptions 获取商品详情
* @author DB
* @date 2023/11/06 11:56
* @param id 商品id
* @return: com.cpop.mall.business.vo.ProductInfoVo
*/
@Override
public ProductInfoVo getProductInfo(String id) {
return this.mapper.selectOneWithRelationsByIdAs(id, ProductInfoVo.class);
}
}

View File

@ -0,0 +1,81 @@
package com.cpop.mall.business.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.mall.business.bo.ShoppingCartBo;
import com.cpop.mall.business.bo.ShoppingCartPageBo;
import com.cpop.mall.business.vo.MiniShoppingCartPageVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.cpop.mall.business.entity.ShoppingCart;
import com.cpop.mall.business.mapper.ShoppingCartMapper;
import com.cpop.mall.business.service.ShoppingCartService;
import org.springframework.stereotype.Service;
import static com.cpop.mall.business.entity.table.ProductRecordTableDef.PRODUCT_RECORD;
import static com.cpop.mall.business.entity.table.ProductTableDef.PRODUCT;
import static com.cpop.mall.business.entity.table.ShoppingCartTableDef.SHOPPING_CART;
import static com.cpop.system.business.entity.table.StoreTableDef.STORE;
/**
* 商城购物车表 服务层实现
*
* @author DB
* @since 2023-11-06
*/
@Service("shoppingCartService")
public class ShoppingCartServiceImpl extends ServiceImpl<ShoppingCartMapper, ShoppingCart> implements ShoppingCartService {
/**
* @descriptions 分页查询小程序-商城-购物车分页
* @author DB
* @date 2023/11/06 14:02
* @param bo 请求参数
* @return: com.mybatisflex.core.paginate.Page<com.cpop.mall.business.vo.MiniShoppingCartPageVo>
*/
@Override
public Page<MiniShoppingCartPageVo> getMiniShoppingCartPage(ShoppingCartPageBo bo) {
//获取当前用户信息
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
QueryWrapper queryWrapper = QueryWrapper.create();
if (StringUtils.isNotBlank(bo.getProductName())) {
queryWrapper.and(PRODUCT.PRODUCT_NAME.like(bo.getProductName()));
}
return this.mapper.paginateAs(pageDomain.getPageNum(), pageDomain.getPageSize(),
queryWrapper.select(SHOPPING_CART.ALL_COLUMNS)
//记录
.select(PRODUCT_RECORD.RECORD_NAMES)
//商品
.select(PRODUCT.PRODUCT_NAME)
//校区
.select(STORE.STORE_NAME)
.from(SHOPPING_CART)
.leftJoin(PRODUCT_RECORD).on(PRODUCT_RECORD.ID.eq(SHOPPING_CART.PRODUCT_RECORD_ID))
.leftJoin(PRODUCT).on(PRODUCT.ID.eq(PRODUCT_RECORD.PRODUCT_ID))
.leftJoin(STORE).on(STORE.ID.eq(SHOPPING_CART.STORE_ID))
.where(SHOPPING_CART.USER_ID.eq(loginUserInfo.getString("userId"))),
MiniShoppingCartPageVo.class);
}
/**
* @descriptions 小程序-商城-购物车添加商品
* @author DB
* @date 2023/11/06 14:17
* @param bo 请求参数
* @return: void
*/
@Override
public void insertShoppingCart(ShoppingCartBo bo) {
//获取当前用户信息
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
ShoppingCart shoppingCart = BeanUtils.mapToClass(bo, ShoppingCart.class);
shoppingCart.setUserId(loginUserInfo.getString("userId"));
this.save(shoppingCart);
}
}

View File

@ -0,0 +1,91 @@
package com.cpop.mall.business.vo;
import com.cpop.core.annontation.StringArrayConvert;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author DB
* @createTime 2023/11/06 13:53
* @description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "小程序-商城-购物车分页返回对象")
public class MiniShoppingCartPageVo implements Serializable {
/**
* 主键
*/
@ApiModelProperty("主键")
private String id;
/**
* 用户id
*/
@ApiModelProperty("用户id")
private String userId;
/**
* 商品名
*/
@ApiModelProperty("商品名")
private String productName;
/**
* 规格名
*/
@StringArrayConvert
@ApiModelProperty("规格名")
private String recordNames;
/**
* 商品记录id
*/
@ApiModelProperty("商品记录id")
private String productRecordId;
/**
* 店铺/校区id
*/
@ApiModelProperty("店铺/校区id")
private String storeId;
/**
* 店铺/校区名
*/
@ApiModelProperty("店铺/校区名")
private String storeName;
/**
* 金额
*/
@ApiModelProperty("金额")
private BigDecimal amount;
/**
* 积分
*/
@ApiModelProperty("积分")
private Integer point;
/**
* 数量
*/
@ApiModelProperty("数量")
private Integer number;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -1,6 +1,7 @@
package com.cpop.mall.business.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.RelationOneToMany;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

View File

@ -0,0 +1,111 @@
package com.cpop.mall.business.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.RelationOneToMany;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author DB
* @createTime 2023/11/06 11:55
* @description
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "商城商品详情返回对象")
public class ProductInfoVo implements Serializable {
/**
* 主键
*/
@ApiModelProperty("主键")
private String id;
/**
* 商品名
*/
@ApiModelProperty("商品名")
private String productName;
/**
* 产品类型(0:课卡;1:周边;2:优惠卷:3:其他)
*/
@ApiModelProperty("产品类型(0:课卡;1:周边;2:优惠卷:3:其他)")
private Integer productType;
/**
* 商店(校区)集合
*/
@ApiModelProperty("商店(校区)集合")
private String storeIds;
/**
* 描述
*/
@ApiModelProperty("描述")
private String description;
/**
* 商品图地址
*/
@ApiModelProperty("商品图地址")
private String picUrl;
/**
* 商品详情图地址
*/
@ApiModelProperty("商品详情图地址")
private String picDetailUrl;
/**
* 购买限制(0:会员限制;1:新客限定;2:用户限购)
*/
@ApiModelProperty("购买限制(0:会员限制;1:新客限定;2:用户限购)")
private Integer buyRestrict;
/**
* 最高价
*/
@ApiModelProperty("最高价")
private BigDecimal maxPrice;
/**
* 最低价
*/
@ApiModelProperty("最低价")
private BigDecimal minPrice;
/**
* 支付方式(微信支付:0;积分支付:1)
*/
@ApiModelProperty("支付方式(微信支付:0;积分支付:1)")
private Integer payType;
/**
* 产品规格
*/
@RelationOneToMany(selfField = "id", targetField = "productId",targetTable = "cp_mall_product_specification")
@ApiModelProperty("产品规格")
private List<ProductSpecificationVo> productSpecificationVos;
/**
* 产品规格记录
*/
@RelationOneToMany(selfField = "id", targetField = "productId",targetTable = "cp_mall_product_record")
@ApiModelProperty("产品规格记录")
private List<ProductRecordVo> productRecordVos;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,75 @@
package com.cpop.mall.framework.enums;
import com.cpop.core.utils.SpringUtils;
import com.cpop.mall.framework.strategy.buyRestrict.BuyRestrictStrategy;
import com.cpop.mall.framework.strategy.buyRestrict.MemberRestrictStrategy;
import com.cpop.mall.framework.strategy.buyRestrict.NewCustomerRestrictStrategy;
import com.cpop.mall.framework.strategy.buyRestrict.UserRestrictStrategy;
import lombok.Getter;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author DB
* @createTime 2023/11/06 15:21
* @description 购买限制枚举
*/
@Getter
public enum BuyRestrictEnums {
/**
* 会员限制
*/
MEMBER_RESTRICT(0, "会员限制", SpringUtils.getBean(MemberRestrictStrategy.class)),
/**
* 新客限定
*/
NEW_CUSTOMER_RESTRICT(1, "新客限定", SpringUtils.getBean(NewCustomerRestrictStrategy.class)),
/**
* 用户限购
*/
USER_RESTRICT(2, "用户限购", SpringUtils.getBean(UserRestrictStrategy.class))
;
private Integer code;
private String name;
private BuyRestrictStrategy buyRestrictStrategy;
BuyRestrictEnums(Integer code, String name, BuyRestrictStrategy buyRestrictStrategy) {
this.code = code;
this.name = name;
this.buyRestrictStrategy = buyRestrictStrategy;
}
public void setCode(Integer code) {
this.code = code;
}
public void setName(String name) {
this.name = name;
}
/**
* 放入map中通过键取值
*/
private static Map<Integer, BuyRestrictEnums> buyRestrictMap = new HashMap<>();
static {
for (BuyRestrictEnums value : BuyRestrictEnums.values()) {
buyRestrictMap.put(value.getCode(), value);
}
}
/**
* 根据code获取枚举
* @param code
* @return
*/
public static BuyRestrictEnums getByCode(Integer code) {
return buyRestrictMap.get(code);
}
}

View File

@ -0,0 +1,19 @@
package com.cpop.mall.framework.strategy.buyRestrict;
import com.cpop.mall.business.entity.Product;
import java.util.Map;
/**
* 购买策略接口
*/
public interface BuyRestrictStrategy {
/**
* @descriptions 购买限制
* @author DB
* @date 2023/11/06 15:21
* @return: void
*/
void buyRestrict(Product product, Map<String, Integer> recordNumIsEnough);
}

View File

@ -0,0 +1,61 @@
package com.cpop.mall.framework.strategy.buyRestrict;
import com.alibaba.fastjson.JSONObject;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.jambox.business.entity.BrandExtend;
import com.cpop.jambox.business.service.BrandExtendService;
import com.cpop.mall.business.entity.Product;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.Map;
import static com.cpop.jambox.business.entity.table.BrandExtendTableDef.BRAND_EXTEND;
/**
* @author DB
* @createTime 2023/11/06 15:26
* @description
*/
@Component
public class MemberRestrictStrategy implements BuyRestrictStrategy{
/**
* @descriptions 会员购买策略
* @author DB
* @date 2023/11/06 15:47
* @param product 商品
* @return: void
*/
@Override
public void buyRestrict(Product product, Map<String, Integer> recordNumIsEnough) {
// 获取当前用户信息
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
//获取品牌信息
BrandExtend brandExtend = SpringUtils.getBean(BrandExtendService.class).queryChain()
.where(BRAND_EXTEND.BRAND_ID.eq(loginUserInfo.getString("brandId")))
.one();
//查询当前用户是否是会员
DataSourceKey.use("jambox");
long count = Db.selectCountByQuery("j_membership", QueryWrapper.create()
.select()
.leftJoin("t_brand_info").on("t_brand_info.brand_id = j_membership.brand_id")
//手机号
.where("j_membership.phone = ?", loginUserInfo.getString("phoneNumber"))
//品牌id
.and("t_brand_info.brand_id = ?", brandExtend.getBrandCloudId())
//会员时间未过期
.and("j_membership.end_time >= ?", LocalDate.now())
.and("j_membership.deleted = 1"));
DataSourceKey.clear();
//没有会员
if (count == 0) {
throw new ServiceException("你尚未成为会员,无法购买商品:" + product.getProductName());
}
}
}

View File

@ -0,0 +1,45 @@
package com.cpop.mall.framework.strategy.buyRestrict;
import com.alibaba.fastjson.JSONObject;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.mall.business.entity.Product;
import com.cpop.mall.business.service.OrderService;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import org.springframework.stereotype.Component;
import java.util.Map;
import static com.cpop.mall.business.entity.table.OrderTableDef.ORDER;
/**
* @author DB
* @createTime 2023/11/06 16:16
* @description 新客限定策略
*/
@Component
public class NewCustomerRestrictStrategy implements BuyRestrictStrategy{
/**
* 购买限制
* @param product 产品
*/
@Override
public void buyRestrict(Product product, Map<String, Integer> recordNumIsEnough) {
//查询当前用户是否有购买记录
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
OrderService orderService = SpringUtils.getBean(OrderService.class);
//跳过逻辑删除
LogicDeleteManager.execWithoutLogicDelete(() -> {
long count = orderService.queryChain()
.where(ORDER.PAY_USER_ID.eq(loginUserInfo.getString("userId")))
.count();
if (count > 0) {
//存在过购买记录
throw new ServiceException("您已不是新客,无法购买商品" + product.getProductName());
}
});
}
}

View File

@ -0,0 +1,66 @@
package com.cpop.mall.framework.strategy.buyRestrict;
import com.alibaba.fastjson.JSONObject;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.mall.business.entity.Product;
import com.cpop.mall.business.entity.ProductRecord;
import com.cpop.mall.business.service.OrderDetailService;
import com.cpop.mall.business.service.ProductRecordService;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.cpop.mall.business.entity.table.OrderDetailTableDef.ORDER_DETAIL;
import static com.cpop.mall.business.entity.table.OrderTableDef.ORDER;
import static com.cpop.mall.business.entity.table.ProductRecordTableDef.PRODUCT_RECORD;
import static com.cpop.mall.business.entity.table.ProductTableDef.PRODUCT;
/**
* @author DB
* @createTime 2023/11/06 16:42
* @description 用户限购
*/
@Component
public class UserRestrictStrategy implements BuyRestrictStrategy{
@Override
public void buyRestrict(Product product, Map<String, Integer> recordNumIsEnough) {
//查询用户已购买的数量
JSONObject loginUserInfo = SecurityUtils.getInstance().getLoginUserInfo();
OrderDetailService orderDetailService = SpringUtils.getBean(OrderDetailService.class);
ProductRecordService productRecordService = SpringUtils.getBean(ProductRecordService.class);
//产品记录
List<ProductRecord> productRecordList = productRecordService.queryChain().where(PRODUCT_RECORD.PRODUCT_ID.eq(product.getId())).list();
Set<String> recordSet = productRecordList.stream().map(ProductRecord::getId).collect(Collectors.toSet());
//跳过逻辑删除
LogicDeleteManager.execWithoutLogicDelete(() -> {
//已存在订单数
long count = orderDetailService.queryChain()
.leftJoin(ORDER).on(ORDER.ID.eq(ORDER_DETAIL.ORDER_ID))
.leftJoin(PRODUCT_RECORD).on(PRODUCT_RECORD.ID.eq(ORDER_DETAIL.PRODUCT_RECORD_ID))
.leftJoin(PRODUCT).on(PRODUCT.ID.eq(PRODUCT_RECORD.PRODUCT_ID))
.where(ORDER.PAY_USER_ID.eq(loginUserInfo.getString("userId")))
.and(PRODUCT.ID.eq(product.getId()))
.count();
//产品购买数量
AtomicInteger num = new AtomicInteger();
recordNumIsEnough.forEach((key, value) -> {
if (recordSet.contains(key)) {
num.addAndGet(value);
}
});
if (product.getLimitNum() - count > num.get()) {
//存在过购买记录
throw new ServiceException("您购买的商品已超出限制,无法购买商品" + product.getProductName());
}
});
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cpop.mall.business.mapper.ShoppingCartMapper">
</mapper>