Commit 80ffb92f authored by Junling Bu's avatar Junling Bu
Browse files

feat[litemall-db, litemall-wx-api]: 小商城后端支持优惠券

parent d5abf50c
package org.linlinjava.litemall.wx.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallCart;
import org.linlinjava.litemall.db.domain.LitemallCoupon;
import org.linlinjava.litemall.db.domain.LitemallCouponUser;
import org.linlinjava.litemall.db.domain.LitemallGrouponRules;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.CouponConstant;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.dao.CouponVo;
import org.linlinjava.litemall.wx.util.WxResponseCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 优惠券服务
*/
@RestController
@RequestMapping("/wx/coupon")
@Validated
public class WxCouponController {
private final Log logger = LogFactory.getLog(WxCouponController.class);
@Autowired
private LitemallCouponService couponService;
@Autowired
private LitemallCouponUserService couponUserService;
@Autowired
private LitemallGrouponRulesService grouponRulesService;
@Autowired
private LitemallCartService cartService;
@Autowired
private CouponVerifyService couponVerifyService;
/**
* 优惠券列表
*
* @param page
* @param size
* @param sort
* @param order
* @return
*/
@GetMapping("list")
public Object list(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<LitemallCoupon> couponList = couponService.queryList(page, size, sort, order);
int total = couponService.queryTotal();
Map<String, Object> data = new HashMap<String, Object>();
data.put("data", couponList);
data.put("count", total);
return ResponseUtil.ok(data);
}
/**
* 个人优惠券列表
*
* @param userId
* @param status
* @param page
* @param size
* @param sort
* @param order
* @return
*/
@GetMapping("mylist")
public Object mylist(@LoginUser Integer userId,
@NotNull Short status,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
if (userId == null) {
return ResponseUtil.unlogin();
}
List<LitemallCouponUser> couponUserList = couponUserService.queryList(userId, null, status, page, size, sort, order);
List<CouponVo> couponVoList = change(couponUserList);
int total = couponService.queryTotal();
Map<String, Object> data = new HashMap<String, Object>();
data.put("data", couponVoList);
data.put("count", total);
return ResponseUtil.ok(data);
}
private List<CouponVo> change(List<LitemallCouponUser> couponList) {
List<CouponVo> couponVoList = new ArrayList<>(couponList.size());
for(LitemallCouponUser couponUser : couponList){
Integer couponId = couponUser.getCouponId();
LitemallCoupon coupon = couponService.findById(couponId);
CouponVo couponVo = new CouponVo();
couponVo.setId(coupon.getId());
couponVo.setName(coupon.getName());
couponVo.setDesc(coupon.getDesc());
couponVo.setTag(coupon.getTag());
couponVo.setMin(coupon.getMin().toPlainString());
couponVo.setDiscount(coupon.getDiscount().toPlainString());
Short days = coupon.getDays();
if (days == 0) {
couponVo.setStartTime(coupon.getStartTime());
couponVo.setEndTime(coupon.getEndTime());
}
else{
couponVo.setStartTime(coupon.getAddTime());
couponVo.setEndTime(coupon.getAddTime().plusDays(days));
}
couponVoList.add(couponVo);
}
return couponVoList;
}
/**
* 当前购物车下单商品订单可用优惠券
*
* @param userId
* @param cartId
* @param grouponRulesId
* @return
*/
@GetMapping("selectlist")
public Object selectlist(@LoginUser Integer userId, Integer cartId, Integer grouponRulesId) {
if (userId == null) {
return ResponseUtil.unlogin();
}
// 团购优惠
BigDecimal grouponPrice = new BigDecimal(0.00);
LitemallGrouponRules grouponRules = grouponRulesService.queryById(grouponRulesId);
if (grouponRules != null) {
grouponPrice = grouponRules.getDiscount();
}
// 商品价格
List<LitemallCart> checkedGoodsList = null;
if (cartId == null || cartId.equals(0)) {
checkedGoodsList = cartService.queryByUidAndChecked(userId);
} else {
LitemallCart cart = cartService.findById(cartId);
if (cart == null) {
return ResponseUtil.badArgumentValue();
}
checkedGoodsList = new ArrayList<>(1);
checkedGoodsList.add(cart);
}
BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
for (LitemallCart cart : checkedGoodsList) {
// 只有当团购规格商品ID符合才进行团购优惠
if (grouponRules != null && grouponRules.getGoodsId().equals(cart.getGoodsId())) {
checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().subtract(grouponPrice).multiply(new BigDecimal(cart.getNumber())));
} else {
checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
}
}
// 计算优惠券可用情况
List<LitemallCouponUser> couponUserList = couponUserService.queryAll(userId);
List<LitemallCouponUser> availableCouponUserList = new ArrayList<>(couponUserList.size());
for (LitemallCouponUser couponUser : couponUserList) {
LitemallCoupon coupon = couponVerifyService.checkCoupon(userId, couponUser.getCouponId(), checkedGoodsPrice);
if (coupon == null) {
continue;
}
availableCouponUserList.add(couponUser);
}
List<CouponVo> couponVoList = change(availableCouponUserList);
return ResponseUtil.ok(couponVoList);
}
/**
* 优惠券领取
*
* @param userId 用户ID
* @param body 请求内容, { couponId: xxx }
* @return 操作结果
*/
@PostMapping("receive")
public Object receive(@LoginUser Integer userId, @RequestBody String body) {
if (userId == null) {
return ResponseUtil.unlogin();
}
Integer couponId = JacksonUtil.parseInteger(body, "couponId");
if(couponId == null){
return ResponseUtil.badArgument();
}
LitemallCoupon coupon = couponService.findById(couponId);
if(coupon == null){
return ResponseUtil.badArgumentValue();
}
// 当前已领取数量和总数量比较
Integer total = coupon.getTotal();
Integer totalCoupons = couponUserService.countCoupon(couponId);
if((total != 0) && (totalCoupons >= total)){
return ResponseUtil.fail(WxResponseCode.COUPON_EXCEED_LIMIT, "优惠券已领完");
}
// 当前用户已领取数量和用户限领数量比较
Integer limit = coupon.getLimit().intValue();
Integer userCounpons = couponUserService.countUserAndCoupon(userId, couponId);
if((limit != 0) && (userCounpons >= limit)){
return ResponseUtil.fail(WxResponseCode.COUPON_EXCEED_LIMIT, "优惠券已经领取过");
}
// 优惠券分发类型
// 例如注册赠券类型的优惠券不能领取
Short type = coupon.getType();
if(type.equals(CouponConstant.TYPE_REGISTER)){
return ResponseUtil.fail(WxResponseCode.COUPON_RECEIVE_FAIL, "新用户优惠券自动发送");
}
else if(!type.equals(CouponConstant.TYPE_COMMON)){
return ResponseUtil.fail(WxResponseCode.COUPON_RECEIVE_FAIL, "优惠券类型不支持");
}
// 优惠券状态,已下架或者过期不能领取
Short status = coupon.getStatus();
if(status.equals(CouponConstant.STATUS_OUT)){
return ResponseUtil.fail(WxResponseCode.COUPON_EXCEED_LIMIT, "优惠券已领完");
}
if(status.equals(CouponConstant.STATUS_EXPIRED)){
return ResponseUtil.fail(WxResponseCode.COUPON_RECEIVE_FAIL, "优惠券已经过期");
}
// 用户领券记录
LitemallCouponUser couponUser = new LitemallCouponUser();
couponUser.setCouponId(couponId);
couponUser.setUserId(userId);
couponUserService.add(couponUser);
return ResponseUtil.ok();
}
}
\ No newline at end of file
......@@ -40,7 +40,8 @@ public class WxHomeController {
private LitemallCategoryService categoryService;
@Autowired
private LitemallGrouponRulesService grouponRulesService;
@Autowired
private LitemallCouponService couponService;
@GetMapping("/cache")
public Object cache(@NotNull String key) {
......@@ -74,6 +75,9 @@ public class WxHomeController {
List<LitemallCategory> channel = categoryService.queryChannel();
data.put("channel", channel);
List<LitemallCoupon> couponList = couponService.queryList(0, 3);
data.put("couponList", couponList);
List<LitemallGoods> newGoods = goodsService.queryByNew(0, SystemConfig.getNewLimit());
data.put("newGoodsList", newGoods);
......
......@@ -21,6 +21,7 @@ import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.CouponUserConstant;
import org.linlinjava.litemall.db.util.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.wx.annotation.LoginUser;
......@@ -106,6 +107,12 @@ public class WxOrderController {
private ExpressService expressService;
@Autowired
private LitemallCommentService commentService;
@Autowired
private LitemallCouponService couponService;
@Autowired
private LitemallCouponUserService couponUserService;
@Autowired
private CouponVerifyService couponVerifyService;
private String detailedAddress(LitemallAddress litemallAddress) {
Integer provinceId = litemallAddress.getProvinceId();
......@@ -241,7 +248,7 @@ public class WxOrderController {
* <p>
* 1. 创建订单表项和订单商品表项;
* 2. 购物车清空;
* 3. TODO 优惠券设置已用;
* 3. 优惠券设置已用;
* 4. 商品货品库存减少;
* 5. 如果是团购商品,则创建团购活动表项。
*
......@@ -287,10 +294,6 @@ public class WxOrderController {
return ResponseUtil.badArgument();
}
// 获取可用的优惠券信息
// 使用优惠券减免的金额
BigDecimal couponPrice = new BigDecimal(0.00);
// 团购优惠
BigDecimal grouponPrice = new BigDecimal(0.00);
LitemallGrouponRules grouponRules = grouponRulesService.queryById(grouponRulesId);
......@@ -320,6 +323,19 @@ public class WxOrderController {
}
}
// 获取可用的优惠券信息
// 使用优惠券减免的金额
BigDecimal couponPrice = new BigDecimal(0.00);
// 如果couponId=0则没有优惠券,couponId=-1则不使用优惠券
if(couponId != 0 && couponId != -1){
LitemallCoupon coupon = couponVerifyService.checkCoupon(userId, couponId, checkedGoodsPrice);
if(coupon == null){
return ResponseUtil.badArgumentValue();
}
couponPrice = coupon.getDiscount();
}
// 根据订单商品总价计算运费,满足条件(例如88元)则免运费,否则需要支付运费(例如8元);
BigDecimal freightPrice = new BigDecimal(0.00);
if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
......@@ -331,6 +347,7 @@ public class WxOrderController {
// 订单费用
BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice);
// 最终支付费用
BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);
// 开启事务管理
......@@ -368,6 +385,7 @@ public class WxOrderController {
orderService.add(order);
orderId = order.getId();
// 添加订单商品表项
for (LitemallCart cartGoods : checkedGoodsList) {
// 订单商品
LitemallOrderGoods orderGoods = new LitemallOrderGoods();
......@@ -382,7 +400,6 @@ public class WxOrderController {
orderGoods.setSpecifications(cartGoods.getSpecifications());
orderGoods.setAddTime(LocalDateTime.now());
// 添加订单商品表项
orderGoodsService.add(orderGoods);
}
......@@ -403,6 +420,15 @@ public class WxOrderController {
}
}
// 如果使用了优惠券,设置优惠券使用状态
if(couponId != 0 && couponId != -1){
LitemallCouponUser couponUser = couponUserService.queryOne(userId, couponId);
couponUser.setStatus(CouponUserConstant.STATUS_USED);
couponUser.setUsedTime(LocalDateTime.now());
couponUser.setOrderId(orderId);
couponUserService.update(couponUser);
}
//如果是团购项目,添加团购信息
if (grouponRulesId != null && grouponRulesId > 0) {
LitemallGroupon groupon = new LitemallGroupon();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment