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 { ...@@ -40,7 +40,8 @@ public class WxHomeController {
private LitemallCategoryService categoryService; private LitemallCategoryService categoryService;
@Autowired @Autowired
private LitemallGrouponRulesService grouponRulesService; private LitemallGrouponRulesService grouponRulesService;
@Autowired
private LitemallCouponService couponService;
@GetMapping("/cache") @GetMapping("/cache")
public Object cache(@NotNull String key) { public Object cache(@NotNull String key) {
...@@ -74,6 +75,9 @@ public class WxHomeController { ...@@ -74,6 +75,9 @@ public class WxHomeController {
List<LitemallCategory> channel = categoryService.queryChannel(); List<LitemallCategory> channel = categoryService.queryChannel();
data.put("channel", channel); data.put("channel", channel);
List<LitemallCoupon> couponList = couponService.queryList(0, 3);
data.put("couponList", couponList);
List<LitemallGoods> newGoods = goodsService.queryByNew(0, SystemConfig.getNewLimit()); List<LitemallGoods> newGoods = goodsService.queryByNew(0, SystemConfig.getNewLimit());
data.put("newGoodsList", newGoods); data.put("newGoodsList", newGoods);
......
...@@ -21,6 +21,7 @@ import org.linlinjava.litemall.core.util.JacksonUtil; ...@@ -21,6 +21,7 @@ import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*; import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*; 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.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderUtil; import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.wx.annotation.LoginUser; import org.linlinjava.litemall.wx.annotation.LoginUser;
...@@ -106,6 +107,12 @@ public class WxOrderController { ...@@ -106,6 +107,12 @@ public class WxOrderController {
private ExpressService expressService; private ExpressService expressService;
@Autowired @Autowired
private LitemallCommentService commentService; private LitemallCommentService commentService;
@Autowired
private LitemallCouponService couponService;
@Autowired
private LitemallCouponUserService couponUserService;
@Autowired
private CouponVerifyService couponVerifyService;
private String detailedAddress(LitemallAddress litemallAddress) { private String detailedAddress(LitemallAddress litemallAddress) {
Integer provinceId = litemallAddress.getProvinceId(); Integer provinceId = litemallAddress.getProvinceId();
...@@ -241,7 +248,7 @@ public class WxOrderController { ...@@ -241,7 +248,7 @@ public class WxOrderController {
* <p> * <p>
* 1. 创建订单表项和订单商品表项; * 1. 创建订单表项和订单商品表项;
* 2. 购物车清空; * 2. 购物车清空;
* 3. TODO 优惠券设置已用; * 3. 优惠券设置已用;
* 4. 商品货品库存减少; * 4. 商品货品库存减少;
* 5. 如果是团购商品,则创建团购活动表项。 * 5. 如果是团购商品,则创建团购活动表项。
* *
...@@ -287,10 +294,6 @@ public class WxOrderController { ...@@ -287,10 +294,6 @@ public class WxOrderController {
return ResponseUtil.badArgument(); return ResponseUtil.badArgument();
} }
// 获取可用的优惠券信息
// 使用优惠券减免的金额
BigDecimal couponPrice = new BigDecimal(0.00);
// 团购优惠 // 团购优惠
BigDecimal grouponPrice = new BigDecimal(0.00); BigDecimal grouponPrice = new BigDecimal(0.00);
LitemallGrouponRules grouponRules = grouponRulesService.queryById(grouponRulesId); LitemallGrouponRules grouponRules = grouponRulesService.queryById(grouponRulesId);
...@@ -320,6 +323,19 @@ public class WxOrderController { ...@@ -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元); // 根据订单商品总价计算运费,满足条件(例如88元)则免运费,否则需要支付运费(例如8元);
BigDecimal freightPrice = new BigDecimal(0.00); BigDecimal freightPrice = new BigDecimal(0.00);
if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) { if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
...@@ -331,6 +347,7 @@ public class WxOrderController { ...@@ -331,6 +347,7 @@ public class WxOrderController {
// 订单费用 // 订单费用
BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice); BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice);
// 最终支付费用
BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice); BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);
// 开启事务管理 // 开启事务管理
...@@ -368,6 +385,7 @@ public class WxOrderController { ...@@ -368,6 +385,7 @@ public class WxOrderController {
orderService.add(order); orderService.add(order);
orderId = order.getId(); orderId = order.getId();
// 添加订单商品表项
for (LitemallCart cartGoods : checkedGoodsList) { for (LitemallCart cartGoods : checkedGoodsList) {
// 订单商品 // 订单商品
LitemallOrderGoods orderGoods = new LitemallOrderGoods(); LitemallOrderGoods orderGoods = new LitemallOrderGoods();
...@@ -382,7 +400,6 @@ public class WxOrderController { ...@@ -382,7 +400,6 @@ public class WxOrderController {
orderGoods.setSpecifications(cartGoods.getSpecifications()); orderGoods.setSpecifications(cartGoods.getSpecifications());
orderGoods.setAddTime(LocalDateTime.now()); orderGoods.setAddTime(LocalDateTime.now());
// 添加订单商品表项
orderGoodsService.add(orderGoods); orderGoodsService.add(orderGoods);
} }
...@@ -403,6 +420,15 @@ public class WxOrderController { ...@@ -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) { if (grouponRulesId != null && grouponRulesId > 0) {
LitemallGroupon groupon = new LitemallGroupon(); 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