|
@@ -0,0 +1,317 @@
|
|
|
+package com.qs.mp.web.controller.api.channel.mall;
|
|
|
+
|
|
|
+import cn.hutool.core.date.LocalDateTimeUtil;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.qs.mp.admin.domain.Goods;
|
|
|
+import com.qs.mp.admin.domain.vo.ShippingTemplateCalculateVO;
|
|
|
+import com.qs.mp.admin.service.IGoodsService;
|
|
|
+import com.qs.mp.channel.domain.Channel;
|
|
|
+import com.qs.mp.channel.domain.ChannelGoodsOrder;
|
|
|
+import com.qs.mp.channel.domain.ChannelGoodsOrderItem;
|
|
|
+import com.qs.mp.channel.domain.param.ChannelGoodsOrderParam;
|
|
|
+import com.qs.mp.channel.domain.param.OrderPayParam;
|
|
|
+import com.qs.mp.channel.domain.vo.ChannelGoodsOrderInfoVO;
|
|
|
+import com.qs.mp.channel.domain.vo.ChannelGoodsOrderItemVO;
|
|
|
+import com.qs.mp.channel.domain.vo.ChannelGoodsOrderSettleVO;
|
|
|
+import com.qs.mp.channel.domain.vo.ChannelGoodsOrderVO;
|
|
|
+import com.qs.mp.channel.service.IChannelGoodsOrderItemService;
|
|
|
+import com.qs.mp.channel.service.IChannelGoodsOrderService;
|
|
|
+import com.qs.mp.channel.service.IChannelService;
|
|
|
+import com.qs.mp.common.core.domain.AjaxResult;
|
|
|
+import com.qs.mp.common.core.page.TableDataInfo;
|
|
|
+import com.qs.mp.common.core.redis.RedisCache;
|
|
|
+import com.qs.mp.common.domain.DeliveryCompany;
|
|
|
+import com.qs.mp.common.enums.*;
|
|
|
+import com.qs.mp.common.exception.ServiceException;
|
|
|
+import com.qs.mp.common.service.IDeliveryCompanyService;
|
|
|
+import com.qs.mp.common.service.IShippingTemplateRuleService;
|
|
|
+import com.qs.mp.common.service.IShippingTemplateService;
|
|
|
+import com.qs.mp.common.utils.LogUtil;
|
|
|
+import com.qs.mp.common.utils.StringUtils;
|
|
|
+import com.qs.mp.framework.redis.RedisKey;
|
|
|
+import com.qs.mp.pay.service.IWalletService;
|
|
|
+import com.qs.mp.system.domain.SysUser;
|
|
|
+import com.qs.mp.system.service.ISysUserService;
|
|
|
+import com.qs.mp.user.domain.UserAddr;
|
|
|
+import com.qs.mp.user.service.IUserAddrService;
|
|
|
+import com.qs.mp.utils.SecurityUtils;
|
|
|
+import com.qs.mp.web.controller.common.BaseApiController;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import io.swagger.annotations.ApiResponse;
|
|
|
+import io.swagger.annotations.ApiResponses;
|
|
|
+import ma.glasnost.orika.MapperFacade;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.web.bind.annotation.RequestBody;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
+
|
|
|
+import javax.validation.Valid;
|
|
|
+import java.time.Duration;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author zhangkaikai
|
|
|
+ * @create 2023-06-02 3:08 PM
|
|
|
+ **/
|
|
|
+@Api("采购商品订单管理")
|
|
|
+@RestController
|
|
|
+@RequestMapping("/api/v1/mp/channel/mall")
|
|
|
+public class ChannelGoodsOrderController extends BaseApiController {
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IChannelGoodsOrderService channelGoodsOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IChannelGoodsOrderItemService channelGoodsOrderItemService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IChannelService channelService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IUserAddrService userAddrService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IShippingTemplateRuleService shippingTemplateRuleService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IShippingTemplateService shippingTemplateService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IGoodsService goodsService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IDeliveryCompanyService deliveryCompanyService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysUserService sysUserService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWalletService walletService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+
|
|
|
+ @Value("${shipping.channel}")
|
|
|
+ public Long shippingTemplateId;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MapperFacade mapperFacade;
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("采购商品订单列表")
|
|
|
+ @RequestMapping("/goods/order/list")
|
|
|
+ @ApiResponses(
|
|
|
+ @ApiResponse(code = 200, message = "成功", response = ChannelGoodsOrderVO.class)
|
|
|
+ )
|
|
|
+ public TableDataInfo goodsOrderList(@RequestBody JSONObject param) {
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ Integer status = param.getInteger("status");
|
|
|
+ startPage();
|
|
|
+ List<ChannelGoodsOrder> channelGoodsOrders = channelGoodsOrderService.list(
|
|
|
+ new LambdaQueryWrapper<ChannelGoodsOrder>().eq(ChannelGoodsOrder::getChannelId, channelId)
|
|
|
+ .eq(null != status, ChannelGoodsOrder::getStatus, status)
|
|
|
+ .orderByDesc(ChannelGoodsOrder::getCreatedTime));
|
|
|
+ List<ChannelGoodsOrderVO> channelGoodsOrderVOList = mapperFacade.mapAsList(channelGoodsOrders, ChannelGoodsOrderVO.class);
|
|
|
+ for (ChannelGoodsOrderVO channelGoodsOrderVO : channelGoodsOrderVOList) {
|
|
|
+ List<ChannelGoodsOrderItem> itemList = channelGoodsOrderItemService.list(new LambdaQueryWrapper<ChannelGoodsOrderItem>()
|
|
|
+ .eq(ChannelGoodsOrderItem::getOrderId, channelGoodsOrderVO.getOrderId()));
|
|
|
+
|
|
|
+ List<ChannelGoodsOrderItemVO> itemVOList = mapperFacade.mapAsList(itemList, ChannelGoodsOrderItemVO.class);
|
|
|
+ channelGoodsOrderVO.setItems(itemVOList);
|
|
|
+ }
|
|
|
+ TableDataInfo rspData = getDataTable(channelGoodsOrders);
|
|
|
+ rspData.setRows(channelGoodsOrderVOList);
|
|
|
+ return rspData;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("采购商品订单详情")
|
|
|
+ @RequestMapping("/goods/order/detail")
|
|
|
+ public AjaxResult goodsOrderDetail(@RequestBody ChannelGoodsOrder goodsOrder) {
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ ChannelGoodsOrder channelGoodsOrder = channelGoodsOrderService.getOne(new LambdaQueryWrapper<ChannelGoodsOrder>().eq(ChannelGoodsOrder::getChannelId, channelId)
|
|
|
+ .eq(ChannelGoodsOrder::getOrderId, goodsOrder.getOrderId()));
|
|
|
+ ChannelGoodsOrderInfoVO goodsOrderInfoVO = mapperFacade.map(channelGoodsOrder, ChannelGoodsOrderInfoVO.class);
|
|
|
+ // 设置自动确认收货的时间;
|
|
|
+ if (goodsOrderInfoVO != null && Objects.nonNull(goodsOrderInfoVO.getDeliveryTime())) {
|
|
|
+ Date deliveryTime = goodsOrderInfoVO.getDeliveryTime();
|
|
|
+ LocalDateTime autoConfirmTime = LocalDateTimeUtil.of(deliveryTime).plusDays(15);
|
|
|
+ Duration between = LocalDateTimeUtil.between(LocalDateTime.now(), autoConfirmTime);
|
|
|
+ long hours = between.toHours();
|
|
|
+ long day = hours / 24;
|
|
|
+ long hour = hours % 24;
|
|
|
+ goodsOrderInfoVO.setAutoConfirmTime(day + "天" + hour + "小时");
|
|
|
+ }
|
|
|
+
|
|
|
+ if(null != goodsOrderInfoVO && null != goodsOrderInfoVO.getDeliveryId()) {
|
|
|
+ DeliveryCompany deliveryCompany = deliveryCompanyService.getById(goodsOrderInfoVO.getDeliveryId());
|
|
|
+ goodsOrderInfoVO.setDeliveryCompany(deliveryCompany);
|
|
|
+ }
|
|
|
+
|
|
|
+ ChannelGoodsOrderItem goodsOrderItem = channelGoodsOrderItemService.getOne(new LambdaQueryWrapper<ChannelGoodsOrderItem>().eq(ChannelGoodsOrderItem::getOrderId, goodsOrder.getOrderId()));
|
|
|
+
|
|
|
+ goodsOrderInfoVO.setChannelGoodsOrderItem(goodsOrderItem);
|
|
|
+
|
|
|
+ return AjaxResult.success(goodsOrderInfoVO);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订单结算,每次更换地址时需重新请求此接口
|
|
|
+ */
|
|
|
+ @ApiOperation("采购商品订单结算")
|
|
|
+ @RequestMapping("/goods/order/settle")
|
|
|
+ @ApiResponses(
|
|
|
+ @ApiResponse(code = 200, message = "成功", response = ChannelGoodsOrderSettleVO.class)
|
|
|
+ )
|
|
|
+ public AjaxResult goodsOrderSettle(@Valid @RequestBody ChannelGoodsOrderParam param) {
|
|
|
+ Long userId = SecurityUtils.getLoginUser().getUserId();
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ Channel channel = channelService.getById(channelId);
|
|
|
+ if (channel.getStatus() == ChannelStatusEnum.OFF) {
|
|
|
+ return AjaxResult.error("账号异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ ChannelGoodsOrderSettleVO orderSettleVO = new ChannelGoodsOrderSettleVO();
|
|
|
+ // 收货地址,如果用户选了地址,则此处不做处理
|
|
|
+ if (null == param.getAddrId() || 0 == param.getAddrId()) {
|
|
|
+ //读取默认地址
|
|
|
+ UserAddr addr = userAddrService.getDefaultChannelAddr(userId);
|
|
|
+ if (null != addr) {
|
|
|
+ orderSettleVO.setAddr(addr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Goods goods = goodsService.getById(param.getGoodsId());
|
|
|
+
|
|
|
+ // 订单金额计算
|
|
|
+ orderSettleVO.setGoodsId(goods.getGoodsId());
|
|
|
+ orderSettleVO.setOrderNum(param.getOrderNum());
|
|
|
+ orderSettleVO.setOrderAmt(goods.getPurchasePrice() * param.getOrderNum());
|
|
|
+
|
|
|
+
|
|
|
+ // 运费计算
|
|
|
+ Integer freightAmt = 0;
|
|
|
+ // 计算运费
|
|
|
+ UserAddr userAddr = orderSettleVO.getAddr();
|
|
|
+ if (Objects.nonNull(userAddr)) {
|
|
|
+ // TODO: 4L上线需要调整,后期放开就是取的商品里配的运费模板id
|
|
|
+ ShippingTemplateCalculateVO shippingTemplateCalculateVO = shippingTemplateRuleService.getShippingTemplateRuleByTemplateIdAndAreaInfo(shippingTemplateId, userAddr.getProvinceId(), userAddr.getCityId());
|
|
|
+ // 无法查到运费模板则默认为0
|
|
|
+ if (Objects.nonNull(shippingTemplateCalculateVO)) {
|
|
|
+
|
|
|
+ orderSettleVO.setFreightRemark(shippingTemplateCalculateVO.getRemark());
|
|
|
+ orderSettleVO.setFreightType(shippingTemplateCalculateVO.getType());
|
|
|
+
|
|
|
+ if (ShippingTemplateRuleTypeEnum.SHIP.getValue().equals(shippingTemplateCalculateVO.getType())) {
|
|
|
+ // 运费计算
|
|
|
+ freightAmt = shippingTemplateService.calculateFreightAmt(param.getOrderNum(), shippingTemplateCalculateVO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ orderSettleVO.setFreightAmt(freightAmt);
|
|
|
+ orderSettleVO.setPayAmt(orderSettleVO.getOrderAmt() + freightAmt);
|
|
|
+
|
|
|
+ // 缓存商品订单
|
|
|
+ redisCache.setCacheObject(RedisKey.build(RedisKey.CHANNEL_GOODS_ORDER_KEY, channelId), orderSettleVO, 10,
|
|
|
+ TimeUnit.MINUTES);
|
|
|
+ return AjaxResult.success(orderSettleVO);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提交订单
|
|
|
+ */
|
|
|
+ @ApiOperation("采购商品订单提交")
|
|
|
+ @RequestMapping("/goods/order/submit")
|
|
|
+ public AjaxResult goodsOrderSubmit(@RequestBody ChannelGoodsOrder goodsOrder) {
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ Channel channel = channelService.getById(channelId);
|
|
|
+ if (channel.getCertifyStatus() != ChannelCertifyStatusEnum.CERTIFIED) {
|
|
|
+ LogUtil.info(logger, "账号未补充。channelId:{0}", channelId);
|
|
|
+ return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1016);
|
|
|
+ }
|
|
|
+ ChannelGoodsOrderSettleVO orderSettleVO = redisCache.getCacheObject(RedisKey.build(RedisKey.CHANNEL_GOODS_ORDER_KEY, channelId));
|
|
|
+ if (null == orderSettleVO) {
|
|
|
+ return AjaxResult.error("订单已过期,请重新下单");
|
|
|
+ }
|
|
|
+ if (null == orderSettleVO.getAddr()) {
|
|
|
+ return AjaxResult.error("收货地址缺失,请重新下单");
|
|
|
+ }
|
|
|
+ String orderId = channelGoodsOrderService.submitOrder(channelId, goodsOrder.getMemo(), orderSettleVO);
|
|
|
+
|
|
|
+ // 清除缓存的订单
|
|
|
+ redisCache.deleteObject(RedisKey.build(RedisKey.CHANNEL_GOODS_ORDER_KEY, channelId));
|
|
|
+
|
|
|
+ return AjaxResult.success(orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取消订单
|
|
|
+ */
|
|
|
+ @ApiOperation("采购商品订单取消")
|
|
|
+ @RequestMapping("/goods/order/cancel")
|
|
|
+ public AjaxResult goodsOrderCancel(@RequestBody ChannelGoodsOrder goodsOrder) {
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ channelGoodsOrderService.cancelOrder(channelId, goodsOrder.getOrderId());
|
|
|
+ return AjaxResult.success("取消成功");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("采购商品订单支付")
|
|
|
+ @RequestMapping("/goods/order/pay")
|
|
|
+ public AjaxResult goodsOrderPay(@Valid @RequestBody OrderPayParam param) {
|
|
|
+ Long userId = SecurityUtils.getLoginUser().getUserId();
|
|
|
+ SysUser sysUser = sysUserService.selectUserById(userId);
|
|
|
+ String channelOpenId = "";
|
|
|
+ if (StringUtils.isNotBlank(param.getOpenId())) {
|
|
|
+ channelOpenId = param.getOpenId();
|
|
|
+ } else {
|
|
|
+ channelOpenId = sysUser.getChannelOpenId();
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(channelOpenId)) {
|
|
|
+ return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1005);
|
|
|
+ }
|
|
|
+
|
|
|
+ ChannelGoodsOrder channelGoodsOrder = channelGoodsOrderService.getById(param.getOrderId());
|
|
|
+ JSONObject jsonObject;
|
|
|
+ try {
|
|
|
+ jsonObject = walletService.pay(BizTypeEnum.CHANNEL_GOODS_ORDER, param.getOrderId(), channelOpenId, channelGoodsOrder.getPayAmt(), channelGoodsOrder.getTitle(), AppSourceEnum.CHANNEL.getValue());
|
|
|
+ } catch (ServiceException e) {
|
|
|
+ LogUtil.error(logger, e, "门店采购商品订单创建支付单失败。userId:{0},orderId:{1}", new Object[]{userId, param.getOrderId()});
|
|
|
+ return AjaxResult.error(e.getMessage());
|
|
|
+ }
|
|
|
+ return AjaxResult.success(jsonObject);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("采购商品订单确认收货")
|
|
|
+ @RequestMapping("/goods/order/confirm")
|
|
|
+ public AjaxResult goodsOrderConfirm(@RequestBody ChannelGoodsOrder goodsOrder) {
|
|
|
+ Long channelId = SecurityUtils.getLoginUser().getChannelId();
|
|
|
+ ChannelGoodsOrder channelGoodsOrder = channelGoodsOrderService.getById(goodsOrder.getOrderId());
|
|
|
+ if (Objects.isNull(channelGoodsOrder)) {
|
|
|
+ return AjaxResult.error("订单不存在");
|
|
|
+ }
|
|
|
+ if (!ChannelGoodsOrderStatusEnum.NOT_CONFIRM.equals(channelGoodsOrder.getStatus())) {
|
|
|
+ return AjaxResult.error("订单状态不是待收货");
|
|
|
+ }
|
|
|
+ if (!channelId.equals(channelGoodsOrder.getChannelId())) {
|
|
|
+ return AjaxResult.error("非法操作他人订单");
|
|
|
+ }
|
|
|
+ channelGoodsOrderService.confirmOrder(channelGoodsOrder);
|
|
|
+ return AjaxResult.success("确认收藏成功");
|
|
|
+
|
|
|
+ }
|
|
|
+}
|