Merge branch 'Bulbasaur' of gitee.com:beijing_hongye_huicheng/lilishop into Bulbasaur

This commit is contained in:
Chopper 2021-05-31 11:34:47 +08:00
commit 78aee87b45
37 changed files with 725 additions and 350 deletions

View File

@ -1,13 +1,14 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.service.StudioService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -29,14 +30,18 @@ public class StudioController {
private StudioService studioService;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "recommend", value = "是否推荐", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
})
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO) {
return ResultUtil.data(studioService.page(PageUtil.initPage(pageVO)));
public ResultMessage<IPage<Studio>> page(PageVO pageVO, Integer recommend, String status) {
return ResultUtil.data(studioService.studioList(pageVO, recommend, status));
}
@ApiOperation(value = "获取店铺直播间回放地址")
@GetMapping("/getLiveInfo/{roomId}")
public ResultMessage<Object> getLiveInfo(Integer roomId){
public ResultMessage<Object> getLiveInfo(Integer roomId) {
return ResultUtil.data(studioService.getLiveInfo(roomId));
}

View File

@ -150,6 +150,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio
- /druid/**
- /swagger-ui.html
- /doc.html

View File

@ -147,6 +147,7 @@ ignored:
- /buyer/memberEvaluation/**/goodsEvaluation
- /buyer/memberEvaluation/**/evaluationNumber
- /buyer/appVersion/**
- /buyer/broadcast/studio/**
- /store/login/**
- /manager/user/login
- /manager/user/refresh/**

View File

@ -15,6 +15,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 分销订单入库
*
@ -28,7 +30,7 @@ public class DistributionOrderExecute implements OrderStatusChangeEvent, EveryDa
@Autowired
private DistributionOrderService distributionOrderService;
//分销订单持久层
@Autowired
@Resource
private DistributionOrderMapper distributionOrderMapper;

View File

@ -10,8 +10,6 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.entity.RefundLog;
import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.kit.enums.PaymentMethodEnum;
import cn.lili.modules.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -24,9 +22,6 @@ import org.springframework.stereotype.Service;
@Service
public class PaymentExecute implements OrderStatusChangeEvent {
//支付日志
@Autowired
private PaymentService paymentService;
//订单
@Autowired
private OrderService orderService;

View File

@ -52,7 +52,6 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
switch (orderMessage.getNewStatus()) {
case PAID: {
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
//库存key 扣减数量
List<String> keys = new ArrayList<>();
@ -78,7 +77,6 @@ public class StockUpdateExecute implements OrderStatusChangeEvent {
break;
}
case CANCELLED: {
OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn());
if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name())) {
for (OrderItem orderItem : order.getOrderItems()) {

View File

@ -0,0 +1,34 @@
package cn.lili.event.impl;
import cn.lili.common.utils.CommonUtil;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 虚拟商品
* @author Bulbasaur
* @date: 2021/5/29 9:17 上午
*
*/
@Component
public class VerificationOrderExecute implements OrderStatusChangeEvent {
@Autowired
private OrderService orderService;
@Override
public void orderChange(OrderMessage orderMessage) {
//订单状态为待核验添加订单添加核验码
if(orderMessage.getNewStatus().equals(OrderStatusEnum.TAKE)) {
String code = CommonUtil.getRandomNum();
orderService.update(new LambdaUpdateWrapper<Order>()
.set(Order::getVerificationCode, code)
.eq(Order::getSn, orderMessage.getOrderSn()));
}
}
}

View File

@ -88,4 +88,10 @@ public class Studio extends BaseEntity {
@ApiModelProperty(value = "直播间商品(最多展示两个商品name/goodsImage)")
private String roomGoodsList;
@ApiModelProperty(value = "推荐直播间")
private boolean recommend;
@ApiModelProperty(value = "直播间状态")
private String status;
}

View File

@ -1,7 +1,9 @@
package cn.lili.modules.broadcast.service;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.entity.vos.StudioVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
/**
@ -21,6 +23,14 @@ public interface StudioService extends IService<Studio> {
*/
Boolean create(Studio studio);
/**
* 修改直播间
* 直播间默认手机直播
* @param studio 直播间
* @return 修改状态
*/
Boolean edit(Studio studio);
/**
* 获取直播间信息
* @param id 直播间ID
@ -50,4 +60,13 @@ public interface StudioService extends IService<Studio> {
* @return 操作结果
*/
Boolean goodsDeleteInRoom(Integer roomId,Integer goodsId);
/**
* 获取直播间列表
* @param pageVO 分页
* @param recommend 是否推荐
* @param status 直播间状态
* @return 直播间分页
*/
IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status);
}

View File

@ -49,6 +49,9 @@ public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity
checkCommodity(commodity);
//添加直播商品
JSONObject json = wechatLivePlayerUtil.addGoods(commodity);
if(!json.getStr("errcode").equals("0")){
throw new ServiceException(json.getStr("errmsg"));
}
commodity.setLiveGoodsId(Convert.toInt(json.getStr("goodsId")));
commodity.setAuditId(json.getStr("auditId"));
commodity.setStoreId(UserContext.getCurrentUser().getStoreId());

View File

@ -5,6 +5,8 @@ import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.entity.dos.StudioCommodity;
import cn.lili.modules.broadcast.entity.vos.StudioVO;
@ -13,7 +15,9 @@ import cn.lili.modules.broadcast.mapper.StudioMapper;
import cn.lili.modules.broadcast.service.StudioCommodityService;
import cn.lili.modules.broadcast.service.StudioService;
import cn.lili.modules.broadcast.util.WechatLivePlayerUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -41,7 +45,7 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
public Boolean create(Studio studio) {
try {
//创建小程序直播
Map<String,String> roomMap=wechatLivePlayerUtil.create(studio);
Map<String, String> roomMap = wechatLivePlayerUtil.create(studio);
studio.setRoomId(Integer.parseInt(roomMap.get("roomId")));
studio.setQrCodeUrl(roomMap.get("qrcodeUrl"));
studio.setStoreId(UserContext.getCurrentUser().getStoreId());
@ -53,6 +57,12 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
}
@Override
public Boolean edit(Studio studio) {
wechatLivePlayerUtil.editRoom(studio);
return this.updateById(studio);
}
@Override
public StudioVO getStudioVO(String id) {
StudioVO studioVO = new StudioVO();
@ -86,8 +96,9 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
Studio studio = this.getByRoomId(roomId);
studio.setRoomGoodsNum(studio.getRoomGoodsNum() != null ? studio.getRoomGoodsNum() + 1 : 1);
//设置直播间默认的商品前台展示只展示两个
if(studio.getRoomGoodsNum()<3){
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));;
if (studio.getRoomGoodsNum() < 3) {
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));
;
}
return this.updateById(studio);
}
@ -103,14 +114,23 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
Studio studio = this.getByRoomId(roomId);
studio.setRoomGoodsNum(studio.getRoomGoodsNum() - 1);
//设置直播间默认的商品前台展示只展示两个
if(studio.getRoomGoodsNum()<3){
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));;
if (studio.getRoomGoodsNum() < 3) {
studio.setRoomGoodsList(JSONUtil.toJsonStr(commodityMapper.getSimpleCommodityByRoomId(roomId)));
;
}
return this.updateById(studio);
}
return false;
}
@Override
public IPage<Studio> studioList(PageVO pageVO, Integer recommend, String status) {
return this.page(PageUtil.initPage(pageVO), new QueryWrapper<Studio>()
.eq(recommend != null, "recommend", true)
.eq(status!=null,"status",status));
}
/**
* 根据直播间ID获取直播间
*
@ -118,6 +138,6 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
* @return 直播间
*/
private Studio getByRoomId(Integer roomId) {
return this.getOne(this.lambdaQuery().eq(Studio::getRoomId, roomId));
return this.getOne(new LambdaQueryWrapper<Studio>().eq(Studio::getRoomId, roomId));
}
}

View File

@ -1,6 +1,7 @@
package cn.lili.modules.broadcast.util;
import cn.hutool.json.JSONObject;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.base.entity.enums.ClientTypeEnum;
import cn.lili.modules.broadcast.entity.dos.Commodity;
import cn.lili.modules.broadcast.entity.dos.Studio;
@ -36,49 +37,50 @@ public class WechatLivePlayerUtil {
* @param studio 小程序直播
* @return 房间ID
*/
public Map<String,String> create(Studio studio) throws Exception{
public Map<String, String> create(Studio studio) throws Exception {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/create?access_token=" + token;
Map<String, String> map = new HashMap<>();
// 背景图
map.put("coverImg", wechatMediaUtil.uploadMedia(token,"image",studio.getCoverImg()));
// 分享图
map.put("shareImg", wechatMediaUtil.uploadMedia(token,"image",studio.getShareImg()));
// 购物直播频道封面图
map.put("feedsImg", wechatMediaUtil.uploadMedia(token,"image",studio.getFeedsImg()));
// 直播间名字
map.put("name", studio.getName());
// 直播计划开始时间
map.put("startTime", studio.getStartTime());
// 直播计划结束时间
map.put("endTime", studio.getEndTime());
// 主播昵称
map.put("anchorName", studio.getAnchorName());
// 主播微信号
map.put("anchorWechat", studio.getAnchorWechat());
// 直播间类型
map.put("type", "0");
// 是否关闭点赞
map.put("closeLike", "0");
// 是否关闭货架
map.put("closeGoods", "0");
// 是否关闭评论
map.put("closeComment", "0");
// 直播间名字
map.put("closeReplay", "0");
//添加直播间
Map<String, String> map = this.mockRoom(token, studio);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间创建结果:" + content);
Map<String,String> roomMap=new HashMap<>();
roomMap.put("roomId",json.getStr("roomId"));
roomMap.put("qrcodeUrl",json.getStr("qrcode_url"));
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
Map<String, String> roomMap = new HashMap<>();
roomMap.put("roomId", json.getStr("roomId"));
roomMap.put("qrcodeUrl", json.getStr("qrcode_url"));
return roomMap;
}
/**
* 创建小程序直播间
*
* @param studio 小程序直播
* @return 房间ID
*/
public boolean editRoom(Studio studio) {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/editroom?access_token=" + token;
//修改直播间
Map<String, String> map = this.mockRoom(token, studio);
map.put("id", studio.getRoomId().toString());
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间修改结果:" + content);
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
return true;
}
/**
* 获取直播间回放
*
@ -118,16 +120,20 @@ public class WechatLivePlayerUtil {
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/push?access_token=" + token;
Map<String, Integer> map = new HashMap<>();
String url = "https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods?access_token=" + token;
Map<String, Object> map = new HashMap<>();
// 直播间回放
map.put("goodsId", goodsId);
Integer[] ids = {goodsId};
map.put("ids", ids);
// 商品ID
map.put("roomId", roomId);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间推送商品:" + content);
return json.getStr("errcode").equals("0");
log.info("直播间导入商品:" + content);
if (!json.getStr("errcode").equals("0")) {
throw new ServiceException(json.getStr("errmsg"));
}
return true;
}
/**
@ -167,10 +173,10 @@ public class WechatLivePlayerUtil {
//新建微信商品DTO
GoodsInfo goodsInfo = new GoodsInfo(commodity);
//上传微信临时图片
goodsInfo.setCoverImgUrl(wechatMediaUtil.uploadMedia(token,"image",commodity.getGoodsImage()));
Map<String,GoodsInfo> map=new HashMap<>();
goodsInfo.setCoverImgUrl(wechatMediaUtil.uploadMedia(token, "image", commodity.getGoodsImage()));
Map<String, GoodsInfo> map = new HashMap<>();
//调用新增直播商品接口
map.put("goodsInfo",goodsInfo);
map.put("goodsInfo", goodsInfo);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序添加直播商品结果:" + content);
@ -188,8 +194,8 @@ public class WechatLivePlayerUtil {
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxaapi/broadcast/goods/delete?access_token=" + token;
Map<String,Object> map=new HashMap<>();
map.put("goodsId",goodsId);
Map<String, Object> map = new HashMap<>();
map.put("goodsId", goodsId);
String content = HttpUtils.doPostWithJson(url, goodsId);
JSONObject json = new JSONObject(content);
log.info("微信小程序删除直播商品结果:" + content);
@ -207,12 +213,43 @@ public class WechatLivePlayerUtil {
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
String url = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse?access_token=" + token;
Map<String,Object> map=new HashMap<>();
map.put("goods_ids",goodsIdList);
Map<String, Object> map = new HashMap<>();
map.put("goods_ids", goodsIdList);
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序查询直播商品结果:" + content);
return json;
}
private Map<String, String> mockRoom(String token, Studio studio) {
Map<String, String> map = new HashMap<>();
// 背景图
map.put("coverImg", wechatMediaUtil.uploadMedia(token, "image", studio.getCoverImg()));
// 分享图
map.put("shareImg", wechatMediaUtil.uploadMedia(token, "image", studio.getShareImg()));
// 购物直播频道封面图
map.put("feedsImg", wechatMediaUtil.uploadMedia(token, "image", studio.getFeedsImg()));
// 直播间名字
map.put("name", studio.getName());
// 直播计划开始时间
map.put("startTime", studio.getStartTime());
// 直播计划结束时间
map.put("endTime", studio.getEndTime());
// 主播昵称
map.put("anchorName", studio.getAnchorName());
// 主播微信号
map.put("anchorWechat", studio.getAnchorWechat());
// 直播间类型
map.put("type", "0");
// 是否关闭点赞
map.put("closeLike", "0");
// 是否关闭货架
map.put("closeGoods", "0");
// 是否关闭评论
map.put("closeComment", "0");
// 直播间名字
map.put("closeReplay", "0");
return map;
}
}

View File

@ -182,6 +182,12 @@ public class Goods extends BaseEntity {
@ApiModelProperty(value = "销售模式", required = true)
private String salesModel;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型", required = true)
private String goodsType;
public Goods() {
}
@ -203,6 +209,6 @@ public class Goods extends BaseEntity {
this.cost = goodsOperationDTO.getCost();
//如果立即上架则
this.marketEnable = goodsOperationDTO.isRelease() ? GoodsStatusEnum.UPPER.name() : GoodsStatusEnum.DOWN.name();
this.goodsType=goodsOperationDTO.getGoodsType();
}
}

View File

@ -16,7 +16,7 @@ import java.util.List;
import java.util.Map;
/**
* 商品查询条件
* 商品编辑DTO
*
* @author pikachu
* @date 2020-02-24 19:27:20
@ -118,4 +118,10 @@ public class GoodsOperationDTO implements Serializable {
@ApiModelProperty(value = "是否重新生成sku数据")
private Boolean regeneratorSkuFlag = true;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
private String goodsType;
}

View File

@ -67,6 +67,12 @@ public class GoodsSearchParams extends PageVO {
@ApiModelProperty(value = "是否为推荐商品")
private Boolean recommend;
/**
* @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
*/
@ApiModelProperty(value = "商品类型")
private String goodsType;
public <T> QueryWrapper<T> queryWrapper() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotEmpty(goodsId)) {
@ -108,6 +114,10 @@ public class GoodsSearchParams extends PageVO {
if (recommend != null) {
queryWrapper.le("recommend", recommend);
}
if (goodsType != null) {
queryWrapper.eq("goods_type", goodsType);
}
queryWrapper.eq("delete_flag", false);
this.betweenWrapper(queryWrapper);
return queryWrapper;

View File

@ -1,28 +0,0 @@
package cn.lili.modules.goods.entity.enums;
/**
* 商品运费承担者
*
* @author pikachu
* @date 2020-02-26 23:24:13
*/
public enum GoodsFreightEnum {
/**
* 买家承担运费
*/
BUYER("买家承担运费"),
/**
* 卖家承担运费
*/
STORE("卖家承担运费");
private final String description;
GoodsFreightEnum(String description) {
this.description = description;
}
public String description() {
return description;
}
}

View File

@ -0,0 +1,29 @@
package cn.lili.modules.goods.entity.enums;
/**
* 商品类型
*
* @author Bulbasaur
* @date: 2021/5/28 4:23 下午
*/
public enum GoodsTypeEnum {
PHYSICAL_GOODS("实物商品"),
VIRTUAL_GOODS("虚拟商品"),
E_COUPON("电子卡券");
private final String description;
GoodsTypeEnum(String description) {
this.description = description;
}
public String description() {
return description;
}
}

View File

@ -101,41 +101,19 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Override
public void addGoods(GoodsOperationDTO goodsOperationDTO) {
Goods goods = new Goods(goodsOperationDTO);
//判定商品是否需要审核
this.checkNeedAuth(goods);
//检查商品
this.checkGoods(goods);
// 向goods加入图片
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
//商品添加卖家信息
StoreVO storeDetail = this.storeService.getStoreDetail();
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
// 评论次数
goods.setCommentNum(0);
// 购买次数
goods.setBuyCount(0);
// 购买次数
goods.setQuantity(0);
// 商品评分
goods.setGrade(100.0);
//添加商品
this.save(goods);
// 添加商品参数
if (goodsOperationDTO.getGoodsParamsList() != null && !goodsOperationDTO.getGoodsParamsList().isEmpty()) {
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
}
// 添加商品sku信息
this.goodsSkuService.add(goodsOperationDTO.getSkuList(), goods);
// 添加相册
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
@ -145,35 +123,25 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
@Override
public void editGoods(GoodsOperationDTO goodsOperationDTO, String goodsId) {
this.checkExist(goodsId);
Goods goods = new Goods(goodsOperationDTO);
goods.setId(goodsId);
//是否需要审核
this.checkNeedAuth(goods);
//检查商品信息
this.checkGoods(goods);
// 向goods加入图片
this.setGoodsGalleryParam(goodsOperationDTO.getGoodsGalleryList().get(0), goods);
//商品添加卖家信息
StoreVO storeDetail = this.storeService.getStoreDetail();
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
//修改商品
this.updateById(goods);
// 添加商品参数
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
//修改商品规格
if (goodsOperationDTO.getGoodsParamsList() != null && !goodsOperationDTO.getGoodsParamsList().isEmpty()) {
this.goodsParamsService.addParams(goodsOperationDTO.getGoodsParamsList(), goods.getId());
}
//修改商品sku信息
this.goodsSkuService.update(goodsOperationDTO.getSkuList(), goods, goodsOperationDTO.getRegeneratorSkuFlag());
// 添加相册
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
if (goodsOperationDTO.getGoodsGalleryList() != null && !goodsOperationDTO.getGoodsGalleryList().isEmpty()) {
this.goodsGalleryService.add(goodsOperationDTO.getGoodsGalleryList(), goods.getId());
}
}
@Override
@ -353,16 +321,62 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
}
/**
* 商品是否需要审核
* 检查商品信息
* 如果商品是虚拟商品则无需配置配送模板
* 如果商品是实物商品需要配置配送模板
* 判断商品是否存在
* 判断商品是否需要审核
* 判断当前用户是否为店铺
*
* @param goods 商品
*/
private void checkNeedAuth(Goods goods) {
private void checkGoods(Goods goods) {
//判断商品类型
switch (goods.getGoodsType()) {
case "PHYSICAL_GOODS":
if (goods.getTemplateId() == null) {
throw new ServiceException("实物商品需选择配送模板");
}
break;
case "VIRTUAL_GOODS":
if (goods.getTemplateId() != null) {
throw new ServiceException("虚拟商品不需要选择配送模板");
}
break;
default:
throw new ServiceException("需选择商品类型");
}
//检查商品是否存在--修改商品时使用
if (goods.getId() != null) {
this.checkExist(goods.getId());
} else {
// 评论次数
goods.setCommentNum(0);
// 购买次数
goods.setBuyCount(0);
// 购买次数
goods.setQuantity(0);
// 商品评分
goods.setGrade(100.0);
}
//获取商品系统配置决定是否审核
Setting setting = settingService.get(SettingEnum.GOODS_SETTING.name());
GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
//是否需要审核
goods.setIsAuth(Boolean.TRUE.equals(goodsSetting.getGoodsCheck()) ? GoodsAuthEnum.TOBEAUDITED.name() : GoodsAuthEnum.PASS.name());
//判断当前用户是否为店铺
if (UserContext.getCurrentUser().getRole().equals(UserEnums.STORE)) {
StoreVO storeDetail = this.storeService.getStoreDetail();
if (storeDetail.getSelfOperated() != null) {
goods.setSelfOperated(storeDetail.getSelfOperated());
}
goods.setStoreId(storeDetail.getId());
goods.setStoreName(storeDetail.getStoreName());
goods.setSelfOperated(storeDetail.getSelfOperated());
} else {
throw new ServiceException("当前未登录店铺");
}
}
/**

View File

@ -15,7 +15,7 @@ import java.io.Serializable;
public class StoreRemarkDTO implements Serializable {
private static final long serialVersionUID = -6793274046513576434L;
@ApiModelProperty(value = "商家id")
@ApiModelProperty(value = "店铺id")
private String storeId;
@ApiModelProperty(value = "备注")

View File

@ -65,14 +65,12 @@ public class TradeDTO implements Serializable {
/**
* key 为商家id
* value 为商家优惠券
* 商家优惠券
* 店铺优惠券
*/
private Map<String, MemberCouponDTO> storeCoupons;
/**
* key 为商家id
* value 为商家优惠券
* 商家优惠券
* 店铺备注
*/
private List<StoreRemarkDTO> storeRemark;

View File

@ -24,5 +24,9 @@ public enum CartTypeEnum {
* 积分
*/
POINTS,
/**
* 虚拟商品
*/
FICTITIOUS;
}

View File

@ -5,6 +5,7 @@ import cn.lili.modules.promotion.entity.dos.MemberCoupon;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.ArrayList;
@ -19,6 +20,7 @@ import java.util.List;
*/
@Data
@ApiModel(description = "购物车")
@NoArgsConstructor
public class CartVO extends CartBase implements Serializable {
private static final long serialVersionUID = -5651775413457562422L;
@ -44,7 +46,6 @@ public class CartVO extends CartBase implements Serializable {
@ApiModelProperty(value = "使用的优惠券列表")
private List<MemberCoupon> couponList;
@ApiModelProperty(value = "赠品列表")
private List<String> giftList;
@ -72,9 +73,6 @@ public class CartVO extends CartBase implements Serializable {
@ApiModelProperty(value = "已参与的的促销活动提示,直接展示给客户")
private String promotionNotice;
public CartVO() {
}
public CartVO(CartSkuVO cartSkuVO) {
this.setStoreId(cartSkuVO.getStoreId());
this.setStoreName(cartSkuVO.getStoreName());

View File

@ -4,27 +4,23 @@ import cn.hutool.json.JSONUtil;
import cn.lili.base.BaseEntity;
import cn.lili.common.utils.BeanUtil;
import cn.lili.modules.base.entity.enums.ClientTypeEnum;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.DeliverStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.enums.OrderTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.enums.PromotionTypeEnum;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.CartTypeEnum;
import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.order.order.entity.enums.*;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Date;
import java.util.Optional;
/**
* 订单
@ -37,6 +33,7 @@ import java.util.Optional;
@Table(name = "li_order")
@TableName("li_order")
@ApiModel(value = "订单")
@NoArgsConstructor
public class Order extends BaseEntity {
@ -176,6 +173,12 @@ public class Order extends BaseEntity {
@ApiModelProperty(value = "订单类型")
private String orderType;
/**
* @see OrderPromotionTypeEnum
*/
@ApiModelProperty(value = "订单促销类型")
private String orderPromotionType;
@Column(columnDefinition = "TEXT")
@ApiModelProperty(value = "价格详情")
private String priceDetail;
@ -184,7 +187,7 @@ public class Order extends BaseEntity {
private Boolean canReturn;
@ApiModelProperty(value = "提货码")
private String qrCode;
private String verificationCode;
@ApiModelProperty(value = "分销员ID")
private String distributionId;
@ -195,62 +198,38 @@ public class Order extends BaseEntity {
@ApiModelProperty(value = "使用的平台会员优惠券id")
private String usePlatformMemberCouponId;
public Order() {
}
/**
* 构建订单
*
* @param cartVO 购物车VO
* @param tradeDTO 交易DTO
*/
public Order(CartVO cartVO, TradeDTO tradeDTO) {
String oldId = this.getId();
String orderId = this.getId();
BeanUtil.copyProperties(tradeDTO, this);
BeanUtil.copyProperties(cartVO.getPriceDetailDTO(), this);
BeanUtil.copyProperties(cartVO, this);
this.setId(oldId);
//循环购物车列表判断是否为促销订单
this.setOrderType(OrderTypeEnum.NORMAL.name());
//促销信息填充
if (cartVO.getSkuList().get(0).getPromotions() != null) {
//判断是否为拼团订单
Optional<String> pintuanId = cartVO.getSkuList().get(0).getPromotions().stream().filter(i -> i.getPromotionType().equals(PromotionTypeEnum.PINTUAN.name())).map(PromotionGoods::getPromotionId).findFirst();
if (pintuanId.isPresent()) {
this.setOrderType(OrderTypeEnum.PINTUAN.name());
if (tradeDTO.getParentOrderSn() == null) {
this.setParentOrderSn("");
}
}
//判断是否为积分订单
Optional<String> pointGoodsId = cartVO.getSkuList().get(0).getPromotions().stream().filter(i -> i.getPromotionType().equals(PromotionTypeEnum.POINTS_GOODS.name())).map(PromotionGoods::getPromotionId).findFirst();
if (pointGoodsId.isPresent()) {
this.setOrderType(OrderTypeEnum.POINT.name());
if (tradeDTO.getParentOrderSn() == null) {
this.setParentOrderSn("");
}
}
}else{
//订单类型判断--普通订单活动订单
if (tradeDTO.getCartTypeEnum().equals(CartTypeEnum.CART) || tradeDTO.getCartTypeEnum().equals(CartTypeEnum.BUY_NOW)) {
this.setOrderType(OrderTypeEnum.NORMAL.name());
} else {
this.setOrderType(tradeDTO.getCartTypeEnum().name());
}
//设定订单默认状态
this.setId(orderId);
this.setOrderStatus(OrderStatusEnum.UNPAID.name());
this.setPayStatus(PayStatusEnum.UNPAID.name());
this.setDeliverStatus(DeliverStatusEnum.UNDELIVERED.name());
//填充订单收件人信息
this.setTradeSn(tradeDTO.getSn());
this.setRemark(cartVO.getRemark());
this.setFreightPrice(tradeDTO.getPriceDetailDTO().getFreightPrice());
//会员收件信息
this.setConsigneeAddressIdPath(tradeDTO.getMemberAddress().getConsigneeAddressIdPath());
this.setConsigneeAddressPath(tradeDTO.getMemberAddress().getConsigneeAddressPath());
this.setConsigneeDetail(tradeDTO.getMemberAddress().getDetail());
this.setConsigneeMobile(tradeDTO.getMemberAddress().getMobile());
this.setConsigneeName(tradeDTO.getMemberAddress().getName());
//判断是否使用平台优惠券
if (tradeDTO.getPlatformCoupon() != null) {
this.setUsePlatformMemberCouponId(tradeDTO.getPlatformCoupon().getMemberCoupon().getId());
}
//判断是否使用店铺优惠券
//如果有收货地址才记录收货地址
if (tradeDTO.getMemberAddress() != null) {
this.setConsigneeAddressIdPath(tradeDTO.getMemberAddress().getConsigneeAddressIdPath());
this.setConsigneeAddressPath(tradeDTO.getMemberAddress().getConsigneeAddressPath());
this.setConsigneeDetail(tradeDTO.getMemberAddress().getDetail());
this.setConsigneeMobile(tradeDTO.getMemberAddress().getMobile());
this.setConsigneeName(tradeDTO.getMemberAddress().getName());
}
//平台优惠券判定
if (tradeDTO.getPlatformCoupon() != null) {
this.setUsePlatformMemberCouponId(tradeDTO.getPlatformCoupon().getMemberCoupon().getId());
@ -263,18 +242,10 @@ public class Order extends BaseEntity {
}
this.setUseStoreMemberCouponIds(storeCouponIds.toString());
}
this.setTradeSn(tradeDTO.getSn());
this.setRemark(cartVO.getRemark());
this.setFreightPrice(tradeDTO.getPriceDetailDTO().getFreightPrice());
}
public PriceDetailDTO getPriceDetailDTO() {
try {
return JSONUtil.toBean(priceDetail, PriceDetailDTO.class);
} catch (Exception e) {
return null;
}
return JSONUtil.toBean(priceDetail, PriceDetailDTO.class);
}
public void setPriceDetailDTO(PriceDetailDTO priceDetail) {

View File

@ -56,27 +56,38 @@ public class OrderItem extends BaseEntity {
@ApiModelProperty(value = "商品ID")
private String goodsId;
@ApiModelProperty(value = "货品ID")
private String skuId;
@ApiModelProperty(value = "销售量")
private Integer num;
@ApiModelProperty(value = "交易编号")
private String tradeSn;
@ApiModelProperty(value = "图片")
private String image;
@ApiModelProperty(value = "商品名称")
private String goodsName;
@ApiModelProperty(value = "分类ID")
private String categoryId;
@ApiModelProperty(value = "快照id")
private String snapshotId;
@ApiModelProperty(value = "规格json")
@Column(columnDefinition = "TEXT")
private String specs;
@ApiModelProperty(value = "促销类型")
private String promotionType;
@ApiModelProperty(value = "促销id")
private String promotionId;
@ApiModelProperty(value = "销售金额")
private Double goodsPrice;

View File

@ -0,0 +1,24 @@
package cn.lili.modules.order.order.entity.enums;
/**
* 订单促销类型枚举
*
* @author Chopper
* @date 2020/11/17 7:28 下午
*/
public enum OrderPromotionTypeEnum {
/**
* 赠品订单
*/
GIFT,
/**
* 拼团订单
*/
PINTUAN,
/**
* 积分订单
*/
POINT
}

View File

@ -21,7 +21,7 @@ public enum OrderTypeEnum {
/**
* 虚拟订单
*/
FICTITIOUS,
VIRTUAL,
/**
* 拼团订单
*/

View File

@ -81,7 +81,7 @@ public class AllowOperation implements Serializable {
//是否允许查看物流信息
this.showLogistics = order.getDeliverStatus().equals(DeliverStatusEnum.DELIVERED.name()) && status.equals(OrderStatusEnum.DELIVERED.name());
this.take = order.getOrderType().equals(OrderTypeEnum.FICTITIOUS.name()) && order.getOrderStatus().equals(OrderStatusEnum.TAKE.name());
this.take = order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name()) && order.getOrderStatus().equals(OrderStatusEnum.TAKE.name());
}
/**
@ -119,7 +119,7 @@ public class AllowOperation implements Serializable {
//是否允许查看物流信息
this.showLogistics = order.getDeliverStatus().equals(DeliverStatusEnum.DELIVERED.name()) && status.equals(OrderStatusEnum.DELIVERED.name());
this.take = order.getOrderType().equals(OrderTypeEnum.FICTITIOUS.name()) && order.getOrderStatus().equals(OrderStatusEnum.TAKE.name());
this.take = order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name()) && order.getOrderStatus().equals(OrderStatusEnum.TAKE.name());
}

View File

@ -1,9 +1,11 @@
package cn.lili.modules.order.order.entity.vo;
import cn.hutool.core.bean.BeanUtil;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@ -14,6 +16,7 @@ import java.util.List;
* @date 2020/11/28 11:38
*/
@Data
@NoArgsConstructor
public class OrderVO extends Order {
@ -23,4 +26,8 @@ public class OrderVO extends Order {
private List<OrderItem> orderItems;
public OrderVO (Order order,List<OrderItem> orderItems){
BeanUtil.copyProperties(order, this);
this.setOrderItems(orderItems);
}
}

View File

@ -66,6 +66,8 @@ public interface OrderService extends IService<Order> {
/**
* 订单付款
* 修改订单付款信息
* 记录订单流水
*
* @param orderSn 订单编号
* @param paymentMethod 支付方法
@ -118,10 +120,16 @@ public interface OrderService extends IService<Order> {
/**
* 订单核验
*
* @param orderSn 订单编号
* @param qrCode 提货码
* @param verificationCode 验证码
*/
Order take(String orderSn, String qrCode);
Order take(String orderSn, String verificationCode);
/**
* 根据核验码获取订单信息
*
* @param verificationCode 验证码
*/
Order getOrderByVerificationCode(String verificationCode);
/**
* 订单完成
@ -180,8 +188,9 @@ public interface OrderService extends IService<Order> {
/**
* 获取待发货订单编号列表
*
* @param response
* @param orderIds 订单ID列表
* @param orderIds 订单ID列表
* @param logisticsName 店铺已选择物流公司列表
* @return 待发货订单编号列表
*/
@ -189,6 +198,7 @@ public interface OrderService extends IService<Order> {
/**
* 订单批量发货
*
* @param list 批量发货列表
*/
void batchDeliver(List<OrderBatchDeliverDTO> list);

View File

@ -21,7 +21,10 @@ import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.trigger.interfaces.TimeTrigger;
import cn.lili.common.trigger.model.TimeExecuteConstant;
import cn.lili.common.trigger.model.TimeTriggerMsg;
import cn.lili.common.utils.*;
import cn.lili.common.utils.OperationalJudgment;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.config.rocketmq.RocketmqCustomProperties;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@ -126,38 +129,40 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
@Override
public void intoDB(TradeDTO tradeDTO) {
//检查TradeDTO信息
checkTradeDTO(tradeDTO);
//订单列表
List<Order> orders = new ArrayList<>(tradeDTO.getCartList().size());
//订单日志
List<OrderLog> orderLogs = new ArrayList<>(tradeDTO.getCartList().size());
//订单VO列表
List<OrderVO> OrderVOList = new ArrayList<>(tradeDTO.getCartList().size());
//订单货物列表
List<OrderItem> orderItems = new ArrayList<>();
List<OrderLog> orderLogs = new ArrayList<>();
if (tradeDTO.getParentOrderSn() != null) {
Order parentOrder = this.getBySn(tradeDTO.getParentOrderSn());
if (parentOrder.getMemberId().equals(UserContext.getCurrentUser().getId())) {
throw new ServiceException("不能参与自己发起的拼团活动!");
}
}
List<OrderVO> list = new ArrayList<>();
//循环交易货物列表新增订单
tradeDTO.getCartList().forEach(item -> {
//构建订单
Order order = new Order(item, tradeDTO);
if (OrderTypeEnum.PINTUAN.name().equals(order.getOrderType())) {
Pintuan pintuan = pintuanService.getPintuanById(order.getPromotionId());
Integer limitNum = pintuan.getLimitNum();
if (limitNum != 0 && order.getGoodsNum() > limitNum) {
throw new ServiceException("购买数量超过拼团活动限制数量");
}
}
//构建orderVO对象
OrderVO orderVO = new OrderVO();
BeanUtil.copyProperties(order, orderVO);
//检查订单信息
checkOrder(order);
//新建订单
orders.add(order);
String message = "订单[" + item.getSn() + "]创建";
orderLogs.add(new OrderLog(item.getSn(), UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), message));
//记录订单日志
orderLogs.add(new OrderLog(item.getSn(),
UserContext.getCurrentUser().getId(),
UserContext.getCurrentUser().getRole().getRole(),
UserContext.getCurrentUser().getUsername(), "订单[" + item.getSn() + "]创建"));
//添加订单货物
item.getSkuList().forEach(
sku -> orderItems.add(new OrderItem(sku, item, tradeDTO))
);
orderVO.setOrderItems(orderItems);
list.add(orderVO);
//构建orderVO对象
OrderVO orderVO = new OrderVO(order, orderItems);
OrderVOList.add(orderVO);
});
tradeDTO.setOrderVO(list);
tradeDTO.setOrderVO(OrderVOList);
//批量保存订单
this.saveBatch(orders);
//批量保存 子订单
@ -165,6 +170,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
// 批量记录订单操作日志
orderLogService.saveBatch(orderLogs);
// 赠品根据店铺单独生成订单
//todo 优化赠品订单代码逻辑
this.generatorGiftOrder(tradeDTO);
}
@ -233,9 +239,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
*/
@Override
public Order getBySn(String orderSn) {
QueryWrapper<Order> orderWrapper = new QueryWrapper<>();
orderWrapper.eq("sn", orderSn);
return this.getOne(orderWrapper);
return this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getSn, orderSn));
}
@Override
@ -253,11 +257,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
order.setPayStatus(PayStatusEnum.PAID.name());
order.setOrderStatus(OrderStatusEnum.PAID.name());
order.setReceivableNo(receivableNo);
order.setCanReturn(!PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod()));
this.updateById(order);
//记录订单流水
storeFlowService.payOrder(orderSn);
//发送订单已付款消息
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOrderSn(order.getSn());
orderMessage.setPaymentMethod(paymentMethod);
@ -268,69 +274,24 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
OrderLog orderLog = new OrderLog(orderSn, "-1", UserEnums.SYSTEM.getRole(), "系统操作", message);
orderLogService.save(orderLog);
}
@Override
@OrderLogPoint(description = "'库存确认'", orderSn = "#orderSn")
public void afterOrderConfirm(String orderSn) {
Order order = this.getBySn(orderSn);
LambdaUpdateWrapper<Order> orderLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//如果为虚拟订单-修改订单状态为待核验
if (order.getOrderType().equals(OrderTypeEnum.FICTITIOUS.name())) {
//填写提货码
String code = CommonUtil.getRandomNum();
orderLambdaUpdateWrapper.eq(Order::getSn, orderSn);
orderLambdaUpdateWrapper.set(Order::getQrCode, code);
orderLambdaUpdateWrapper.set(Order::getOrderStatus, OrderStatusEnum.TAKE.name());
orderLambdaUpdateWrapper.set(Order::getCanReturn, !PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod()));
this.update(orderLambdaUpdateWrapper);
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.TAKE);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
}
//如果为商品订单-修改订单状态为待发货
else {
orderLambdaUpdateWrapper.eq(Order::getSn, orderSn);
//拼团订单
if (order.getOrderType().equals(OrderTypeEnum.PINTUAN.name()) && order.getPromotionId() != null) {
//校验拼团是否成团 对拼团结果进行处理
this.checkPintuanOrder(order.getPromotionId(), order.getParentOrderSn());
//判断是否为拼团订单进行特殊处理
//判断订单类型进行不同的订单确认操作
if (order.getOrderPromotionType().equals(OrderPromotionTypeEnum.PINTUAN.name())) {
this.checkPintuanOrder(order.getPromotionId(), order.getParentOrderSn());
} else {
//判断订单类型
if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name())) {
normalOrderConfirm(orderSn);
} else {
//普通订单直接修改为代发货状态
orderLambdaUpdateWrapper.set(Order::getOrderStatus, OrderStatusEnum.UNDELIVERED.name());
orderLambdaUpdateWrapper.set(Order::getCanReturn, !PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod()));
this.update(orderLambdaUpdateWrapper);
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.UNDELIVERED);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
virtualOrderConfirm(orderSn);
}
}
// 发送当前商品购买完成的信息用于更新商品数据
List<OrderItem> orderItems = orderItemService.getByOrderSn(orderSn);
List<GoodsCompleteMessage> goodsCompleteMessageList = new ArrayList<>();
for (OrderItem orderItem : orderItems) {
GoodsCompleteMessage goodsCompleteMessage = new GoodsCompleteMessage();
goodsCompleteMessage.setGoodsId(orderItem.getGoodsId());
goodsCompleteMessage.setSkuId(orderItem.getSkuId());
goodsCompleteMessage.setBuyNum(orderItem.getNum());
goodsCompleteMessage.setMemberId(order.getMemberId());
goodsCompleteMessageList.add(goodsCompleteMessage);
}
if (!goodsCompleteMessageList.isEmpty()) {
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.BUY_GOODS_COMPLETE.name();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsCompleteMessageList), RocketmqSendCallbackBuilder.commonCallback());
}
}
@ -395,30 +356,30 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
@Override
@OrderLogPoint(description = "'订单['+#orderSn+']核销,核销码['+#qrCode+']'", orderSn = "#orderSn")
public Order take(String orderSn, String qrCode) {
//是否可以查询到订单
Order order = OperationalJudgment.judgment(this.getBySn(orderSn));
//判断是否为虚拟订单
if (!order.getOrderType().equals(OrderTypeEnum.FICTITIOUS.name())) {
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
}
//判断虚拟订单状态
if (order.getOrderStatus().equals(OrderStatusEnum.TAKE.name())) {
//判断提货码是否正确\修改订单状态
if (order.getOrderStatus().equals(OrderStatusEnum.TAKE.name()) && qrCode.equals(order.getQrCode())) {
order.setOrderStatus(OrderStatusEnum.COMPLETED.name());
@OrderLogPoint(description = "'订单['+#orderSn+']核销,核销码['+#verificationCode+']'", orderSn = "#orderSn")
public Order take(String orderSn,String verificationCode) {
this.updateById(order);
//获取订单信息
Order order = this.getBySn(orderSn);
//检测虚拟订单信息
checkVerificationOrder(order,verificationCode);
order.setOrderStatus(OrderStatusEnum.COMPLETED.name());
//修改订单信息
this.updateById(order);
//发送订单完成消息
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.COMPLETED);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
return order;
}
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.COMPLETED);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
}
return order;
}
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
@Override
public Order getOrderByVerificationCode(String verificationCode) {
return this.getOne(new LambdaQueryWrapper<Order>()
.eq(Order::getOrderStatus, OrderStatusEnum.TAKE.name())
.eq(Order::getStoreId,UserContext.getCurrentUser().getStoreId())
.eq(Order::getVerificationCode, verificationCode));
}
@Override
@ -438,6 +399,25 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
orderMessage.setNewStatus(OrderStatusEnum.COMPLETED);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
// 发送当前商品购买完成的信息用于更新商品数据
List<OrderItem> orderItems = orderItemService.getByOrderSn(orderSn);
List<GoodsCompleteMessage> goodsCompleteMessageList = new ArrayList<>();
for (OrderItem orderItem : orderItems) {
GoodsCompleteMessage goodsCompleteMessage = new GoodsCompleteMessage();
goodsCompleteMessage.setGoodsId(orderItem.getGoodsId());
goodsCompleteMessage.setSkuId(orderItem.getSkuId());
goodsCompleteMessage.setBuyNum(orderItem.getNum());
goodsCompleteMessage.setMemberId(order.getMemberId());
goodsCompleteMessageList.add(goodsCompleteMessage);
}
//发送商品购买消息
if (!goodsCompleteMessageList.isEmpty()) {
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.BUY_GOODS_COMPLETE.name();
//发送订单变更mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsCompleteMessageList), RocketmqSendCallbackBuilder.commonCallback());
}
}
@Override
@ -609,6 +589,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
this.baseMapper.updateStatus(orderStatus.name(), orderSn);
}
/**
* 检测拼团订单内容
* 此方法用与订单确认
* 判断拼团是否达到人数进行下一步处理
*
* @param pintuanId 拼团活动ID
* @param parentOrderSn 拼团父订单编号
*/
private void checkPintuanOrder(String pintuanId, String parentOrderSn) {
//拼团有效参数判定
if (CharSequenceUtil.isEmpty(parentOrderSn)) {
@ -630,9 +618,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
DelayQueueTools.wrapperUniqueKey(DelayQueueType.PINTUAN_ORDER, (pintuanId + parentOrderSn)),
rocketmqCustomProperties.getPromotionTopic());
this.timeTrigger.addDelay(timeTriggerMsg, cn.lili.common.utils.DateUtil.getDelayTime(startTime));
}
//拼团所需人数小于等于 参团后的人数则说明成团所有订单成团
if (pintuan.getRequiredNum() <= count) {
} else if (pintuan.getRequiredNum() <= count) {
//拼团所需人数小于等于 参团后的人数则说明成团所有订单成团
this.pintuanOrderSuccess(list);
}
}
@ -659,17 +646,18 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
/**
* 根据提供的拼团订单列表更新拼团状态为拼团成功
* 循环订单列表根据不同的订单类型进行确认订单
*
* @param list 需要更新拼团状态为成功的拼团订单列表
*/
private void pintuanOrderSuccess(List<Order> list) {
for (Order order : list) {
LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Order::getId, order.getId());
updateWrapper.set(Order::getOrderStatus, OrderStatusEnum.UNDELIVERED.name());
updateWrapper.set(Order::getCanReturn, !PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod()));
this.update(updateWrapper);
}
list.stream().forEach(order -> {
if (order.getOrderType().equals(OrderTypeEnum.VIRTUAL)) {
this.virtualOrderConfirm(order.getSn());
} else if (order.getOrderType().equals(OrderTypeEnum.NORMAL)) {
this.normalOrderConfirm(order.getSn());
}
});
}
/**
@ -761,4 +749,96 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
/**
* 检查交易信息
*
* @param tradeDTO 交易DTO
*/
private void checkTradeDTO(TradeDTO tradeDTO) {
//检测是否为拼团订单
if (tradeDTO.getParentOrderSn() != null) {
//判断用户不能参与自己发起的拼团活动
Order parentOrder = this.getBySn(tradeDTO.getParentOrderSn());
if (parentOrder.getMemberId().equals(UserContext.getCurrentUser().getId())) {
throw new ServiceException("不能参与自己发起的拼团活动!");
}
}
}
/**
* 检查交易信息
*
* @param order 订单
*/
private void checkOrder(Order order) {
//订单类型为拼团订单检测购买数量是否超过了限购数量
if (OrderTypeEnum.PINTUAN.name().equals(order.getOrderType())) {
Pintuan pintuan = pintuanService.getPintuanById(order.getPromotionId());
Integer limitNum = pintuan.getLimitNum();
if (limitNum != 0 && order.getGoodsNum() > limitNum) {
throw new ServiceException("购买数量超过拼团活动限制数量");
}
}
}
/**
* 普通商品订单确认
* 修改订单状态为待发货
* 发送订单状态变更消息
*
* @param orderSn 订单编号
*/
private void normalOrderConfirm(String orderSn) {
//修改订单
this.update(new LambdaUpdateWrapper<Order>()
.eq(Order::getSn, orderSn)
.set(Order::getOrderStatus, OrderStatusEnum.UNDELIVERED.name()));
//修改订单
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.UNDELIVERED);
orderMessage.setOrderSn(orderSn);
this.sendUpdateStatusMessage(orderMessage);
}
/**
* 虚拟商品订单确认
* 修改订单状态为待核验
* 发送订单状态变更消息
*
* @param orderSn 订单编号
*/
private void virtualOrderConfirm(String orderSn) {
//修改订单
this.update(new LambdaUpdateWrapper<Order>()
.eq(Order::getSn, orderSn)
.set(Order::getOrderStatus, OrderStatusEnum.TAKE.name()));
OrderMessage orderMessage = new OrderMessage();
orderMessage.setNewStatus(OrderStatusEnum.TAKE);
orderMessage.setOrderSn(orderSn);
this.sendUpdateStatusMessage(orderMessage);
}
/**
* 检测虚拟订单信息
* @param order 订单
* @param verificationCode 验证码
*/
private void checkVerificationOrder(Order order,String verificationCode){
//判断查询是否可以查询到订单
if (order==null) {
throw new ServiceException(ResultCode.ORDER_NOT_EXIST);
}
//判断是否为虚拟订单
else if (!order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) {
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
}
//判断虚拟订单状态
else if (order.getOrderStatus().equals(OrderStatusEnum.TAKE.name())) {
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
}
//判断验证码是否正确
else if(!verificationCode.equals(order.getVerificationCode())){
throw new ServiceException(ResultCode.ORDER_TAKE_ERROR);
}
}
}

View File

@ -74,7 +74,9 @@ public class TradeServiceImpl extends ServiceImpl<TradeMapper, Trade> implements
pointPretreatment(tradeDTO);
//优惠券预处理
couponPretreatment(tradeDTO);
//添加交易
this.save(trade);
//添加订单
orderService.intoDB(tradeDTO);
//写入缓存给消费者调用
cache.put(key, tradeDTO);

View File

@ -14,7 +14,7 @@ import lombok.Data;
public class StoreBasicInfoVO {
@ApiModelProperty(value = "店铺ID")
private Long storeId;
private String storeId;
@ApiModelProperty(value = "店铺名称")
private String storeName;

View File

@ -0,0 +1,41 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.vos.CommodityVO;
import cn.lili.modules.broadcast.service.CommodityService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 管理端,直播间管理接口
*
* @author Bulbasaur
* @date: 2021/5/28 11:56 上午
*/
@RestController
@Api(tags = "店铺端,直播商品接口")
@RequestMapping("/manager/broadcast/commodity")
public class CommodityManagerController {
@Autowired
private CommodityService commodityService;
@ApiOperation(value = "获取店铺直播商品列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "商品名称", dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "auditStatus", value = "直播商品状态", dataType = "String", paramType = "query")
})
@GetMapping
public ResultMessage<IPage<CommodityVO>> page(String auditStatus, String name, PageVO pageVO) {
return ResultUtil.data(commodityService.commodityList(pageVO, name, auditStatus));
}
}

View File

@ -0,0 +1,64 @@
package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.service.StudioService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 管理端,直播间接口
*
* @author Bulbasaur
* @date: 2021/5/28 11:56 上午
*/
@RestController
@Api(tags = "店铺端,直播商品接口")
@RequestMapping("/manager/broadcast/studio")
public class StudioManagerController {
@Autowired
private StudioService studioService;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO, String status) {
return ResultUtil.data(studioService.studioList(pageVO, null, status));
}
@ApiOperation(value = "获取店铺直播间详情")
@ApiImplicitParam(name = "studioId", value = "直播间ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/studioInfo/{studioId}")
public ResultMessage<Studio> studioInfo(@PathVariable String studioId) {
return ResultUtil.data(studioService.getById(studioId));
}
@ApiOperation(value = "是否推荐直播间")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "Id", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "recommend", value = "是否推荐", required = true, dataType = "boolean", paramType = "path")
})
@GetMapping("/id/{studioId}")
public ResultMessage<Object> recommend(@PathVariable String id, @PathVariable boolean recommend) {
if (studioService.update(new UpdateWrapper<Studio>()
.eq("id", id)
.set("recommend", recommend))) {
return ResultUtil.success();
}
throw new ServiceException(ResultCode.ERROR);
}
}

View File

@ -27,7 +27,7 @@ import java.util.List;
@RestController
@Api(tags = "店铺端,直播商品接口")
@RequestMapping("/store/broadcast/commodity")
public class CommodityController {
public class CommodityStoreController {
@Autowired
private CommodityService commodityService;

View File

@ -3,12 +3,10 @@ package cn.lili.controller.other.broadcast;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.PageUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.broadcast.entity.dos.Studio;
import cn.lili.modules.broadcast.service.StudioService;
import cn.lili.modules.message.util.WechatAccessTokenUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@ -28,17 +26,16 @@ import org.springframework.web.bind.annotation.*;
@RestController
@Api(tags = "店铺端,直播间接口")
@RequestMapping("/store/broadcast/studio")
public class StudioController {
public class StudioStoreController {
@Autowired
private StudioService studioService;
@Autowired
private WechatAccessTokenUtil wechatAccessTokenUtil;
@ApiOperation(value = "获取店铺直播间列表")
@ApiImplicitParam(name = "status", value = "直播间状态", paramType = "query", dataType = "String")
@GetMapping
public ResultMessage<IPage<Studio>> page(PageVO pageVO) {
return ResultUtil.data(studioService.page(PageUtil.initPage(pageVO)));
public ResultMessage<IPage<Studio>> page(PageVO pageVO, String status) {
return ResultUtil.data(studioService.studioList(pageVO, null, status));
}
@ApiOperation(value = "获取店铺直播间详情")
@ -57,6 +54,15 @@ public class StudioController {
throw new ServiceException(ResultCode.ERROR);
}
@ApiOperation(value = "修改直播间")
@PutMapping("/edit")
public ResultMessage<Object> edit(@Validated Studio studio) {
if (studioService.edit(studio)) {
return ResultUtil.success(ResultCode.SUCCESS);
}
throw new ServiceException(ResultCode.ERROR);
}
@ApiOperation(value = "店铺直播间添加商品")
@ApiImplicitParams({
@ApiImplicitParam(name = "roomId", value = "房间ID", required = true, dataType = "Integer", paramType = "path"),

View File

@ -117,22 +117,23 @@ public class OrderStoreController {
return ResultUtil.data(orderService.cancel(orderSn, reason));
}
@ApiOperation(value = "根据核验码获取订单信息")
@ApiImplicitParam(name = "verificationCode", value = "核验码", required = true, paramType = "path")
@GetMapping(value = "/getOrderByVerificationCode/{verificationCode}")
public ResultMessage<Object> getOrderByVerificationCode(@PathVariable String verificationCode){
return ResultUtil.data(orderService.getOrderByVerificationCode(verificationCode));
}
@ApiOperation(value = "订单核验")
@ApiImplicitParams({
@ApiImplicitParam(name = "orderSn", value = "订单sn", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "qrCode", value = "发货单号", required = true, dataType = "String", paramType = "query")
})
@PostMapping(value = "/{orderSn}/take")
public ResultMessage<Object> take(@NotNull(message = "参数非法") @PathVariable String orderSn,
@NotNull(message = "核验码") String qrCode) {
return ResultUtil.data(orderService.take(orderSn, qrCode));
@ApiImplicitParam(name = "verificationCode", value = "核验码", required = true, paramType = "path")
@PutMapping(value = "/take/${order}/{verificationCode}")
public ResultMessage<Object> take(@PathVariable String orderSn,@PathVariable String verificationCode) {
return ResultUtil.data(orderService.take(orderSn,verificationCode));
}
@ApiOperation(value = "查询物流踪迹")
@ApiImplicitParams({
@ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path")
})
@PostMapping(value = "/getTraces/{orderSn}")
@ApiImplicitParam(name = "orderSn", value = "订单编号", required = true, dataType = "String", paramType = "path")
@GetMapping(value = "/getTraces/{orderSn}")
public ResultMessage<Object> getTraces(@NotBlank(message = "订单编号不能为空") @PathVariable String orderSn) {
return ResultUtil.data(orderService.getTraces(orderSn));
}