导出订单发货Excel,上传Excel订单批量发货

This commit is contained in:
lifenlong 2021-05-26 17:09:55 +08:00
parent 5f93ce3851
commit 99b9e8cf91
15 changed files with 226 additions and 37 deletions

View File

@ -45,6 +45,8 @@
<de.codecentric>2.3.1</de.codecentric>
<userAgentUtils>1.21</userAgentUtils>
<interceptor-api>1.2</interceptor-api>
<poi-version>5.0.0</poi-version>
<poi-ooxml-version>5.0.0</poi-ooxml-version>
</properties>
@ -81,11 +83,6 @@
<artifactId>xk-time</artifactId>
<version>2.2.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -356,23 +353,11 @@
<artifactId>simple-http</artifactId>
<version>${simple-http-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr4-runtime-version}</version>
</dependency>
<!-- http client -->
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents</groupId>-->
<!-- <artifactId>httpclient</artifactId>-->
<!-- <version>${httpclient-version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.squareup.okhttp3</groupId>-->
<!-- <artifactId>okhttp</artifactId>-->
<!-- <version>${okhttp-version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
@ -385,6 +370,16 @@
<artifactId>UserAgentUtils</artifactId>
<version>${userAgentUtils}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml-version}</version>
</dependency>
</dependencies>

View File

@ -138,6 +138,7 @@ public enum ResultCode {
ORDER_NOT_USER(31007, "非当前会员的订单"),
ORDER_TAKE_ERROR(31008, "当前订单无法核销"),
MEMBER_ADDRESS_NOT_EXIST(31009, "订单无收货地址,请先配置收货地址"),
ORDER_DELIVER_NUM_ERROR(31010, "没有待发货的订单"),
/**
* 支付

View File

@ -77,6 +77,9 @@ public class Studio extends BaseEntity {
@ApiModelProperty(value = "房间ID")
private Integer roomId;
@ApiModelProperty(value = "小程序直播码")
private String qrCodeUrl;
@ApiModelProperty(value = "店铺ID")
private String storeId;

View File

@ -58,7 +58,7 @@ public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity
private void checkCommodity(Commodity commodity){
//商品是否审核通过
GoodsSku goodsSku=goodsSkuService.getById(commodity.getSkuId());
if(!goodsSku.getIsAuth().equals(GoodsAuthEnum.PASS)){
if(!goodsSku.getIsAuth().equals(GoodsAuthEnum.PASS.name())){
throw new ServiceException(goodsSku.getGoodsName()+" 未审核通过,不能添加直播商品");
}
//是否已添加规格商品

View File

@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Map;
/**
* 小程序直播间业务层实现
@ -40,8 +41,9 @@ public class StudioServiceImpl extends ServiceImpl<StudioMapper, Studio> impleme
public Boolean create(Studio studio) {
try {
//创建小程序直播
Integer roomId = wechatLivePlayerUtil.create(studio);
studio.setRoomId(roomId);
Map<String,String> roomMap=wechatLivePlayerUtil.create(studio);
studio.setRoomId(Integer.parseInt(roomMap.get("roomId")));
studio.setQrCodeUrl(roomMap.get("qrcodeUrl"));
studio.setStoreId(UserContext.getCurrentUser().getStoreId());
return this.save(studio);
} catch (Exception e) {

View File

@ -1,6 +1,5 @@
package cn.lili.modules.broadcast.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONObject;
import cn.lili.modules.base.entity.enums.ClientTypeEnum;
import cn.lili.modules.broadcast.entity.dos.Commodity;
@ -37,7 +36,7 @@ public class WechatLivePlayerUtil {
* @param studio 小程序直播
* @return 房间ID
*/
public Integer create(Studio studio) throws Exception{
public Map<String,String> create(Studio studio) throws Exception{
//获取token
String token = wechatAccessTokenUtil.cgiAccessToken(ClientTypeEnum.WECHAT_MP);
//发送url
@ -74,7 +73,10 @@ public class WechatLivePlayerUtil {
String content = HttpUtils.doPostWithJson(url, map);
JSONObject json = new JSONObject(content);
log.info("微信小程序直播间创建结果:" + content);
return Convert.toInt(json.getStr("roomId"));
Map<String,String> roomMap=new HashMap<>();
roomMap.put("roomId",json.getStr("roomId"));
roomMap.put("qrcodeUrl",json.getStr("qrcode_url"));
return roomMap;
}
/**

View File

@ -115,6 +115,9 @@ public class WechatMediaUtil {
fileExt = ".png";
break;
case "image/jpeg":
fileExt = ".jpeg";
break;
case "image/jpg":
fileExt = ".jpg";
break;
}

View File

@ -0,0 +1,27 @@
package cn.lili.modules.order.order.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单批量发货DTO
* @author Bulbasaur
* @date: 2021/5/26 4:21 下午
*
*/
@Data
public class OrderBatchDeliverDTO {
@ApiModelProperty(value = "订单SN")
private String orderSn;
@ApiModelProperty(value = "物流公司ID")
private String logisticsId;
@ApiModelProperty(value = "物流公司名称")
private String logisticsName;
@ApiModelProperty(value = "发货单号")
private String logisticsNo;
}

View File

@ -11,6 +11,8 @@ import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* 订单数据处理层
*
@ -19,9 +21,6 @@ import org.apache.ibatis.annotations.Update;
*/
public interface OrderMapper extends BaseMapper<Order> {
@Update({"update li_order set order_status = #{status} where sn in #{orderSn}"})
void batchUpdateStatus(String status, String orderSns);
@Update({"update li_order set order_status = #{status} where sn = #{orderSn}"})
void updateStatus(String status, String orderSn);
@ -39,8 +38,9 @@ public interface OrderMapper extends BaseMapper<Order> {
" FROM li_order o INNER JOIN li_order_item AS oi on o.sn = oi.order_sn ${ew.customSqlSegment} ")
IPage<OrderSimpleVO> queryByParams(IPage<OrderSimpleVO> page, @Param(Constants.WRAPPER) Wrapper<OrderSimpleVO> queryWrapper);
@Select("select * from li_order ${ew.customSqlSegment} ")
IPage<PaymentLog> queryPaymentLogs(IPage<PaymentLog> page, @Param(Constants.WRAPPER) Wrapper<PaymentLog> queryWrapper);
@Select("SELECT sn FROM li_order o ${ew.customSqlSegment} ")
List<String> deliverSnList(@Param(Constants.WRAPPER) Wrapper<Order> queryWrapper);
}

View File

@ -4,6 +4,7 @@ import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderBatchDeliverDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
@ -13,6 +14,7 @@ import cn.lili.modules.system.entity.vo.Traces;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@ -176,4 +178,19 @@ public interface OrderService extends IService<Order> {
*/
void agglomeratePintuanOrder(String pintuanId, String parentOrderSn);
/**
* 获取待发货订单编号列表
* @param response
* @param orderIds 订单ID列表
* @param logisticsName 店铺已选择物流公司列表
* @return 待发货订单编号列表
*/
void getBatchDeliverList(HttpServletResponse response, List<String> orderIds, List<String> logisticsName);
/**
* 订单批量发货
* @param list 批量发货列表
*/
void batchDeliver(List<OrderBatchDeliverDTO> list);
}

View File

@ -2,8 +2,11 @@ package cn.lili.modules.order.order.serviceimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.lili.common.aop.syslog.annotation.SystemLogPoint;
import cn.lili.common.delayqueue.DelayQueueTools;
import cn.lili.common.delayqueue.DelayQueueType;
@ -31,6 +34,7 @@ import cn.lili.modules.order.order.aop.OrderLogPoint;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.Receipt;
import cn.lili.modules.order.order.entity.dto.OrderBatchDeliverDTO;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
@ -60,12 +64,16 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -78,7 +86,6 @@ import java.util.List;
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
private static final String ORDER_SN_COLUMN = "order_sn";
@ -364,8 +371,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
this.updateById(order);
//修改订单状态为已发送
this.updateStatus(orderSn, OrderStatusEnum.DELIVERED);
//修改订单货物可以进行售后投诉
orderItemService.update(new UpdateWrapper<OrderItem>().eq(ORDER_SN_COLUMN, orderSn)
.set("after_sale_status", OrderItemAfterSaleStatusEnum.NOT_APPLIED)
@ -375,8 +380,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
orderMessage.setNewStatus(OrderStatusEnum.DELIVERED);
orderMessage.setOrderSn(order.getSn());
this.sendUpdateStatusMessage(orderMessage);
} else {
throw new ServiceException(ResultCode.ORDER_DELIVER_ERROR);
}
@ -512,6 +515,77 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
}
}
@Override
public void getBatchDeliverList(HttpServletResponse response, List<String> orderIds, List<String> logisticsName) {
//获取待发货订单列表
List deliverList = this.baseMapper.deliverSnList(new LambdaQueryWrapper<Order>()
.eq(Order::getStoreId, UserContext.getCurrentUser().getStoreId())
.eq(Order::getOrderStatus, "'UNDELIVERED'")
.in(orderIds.size() > 0, Order::getId, orderIds));
//如果没有待发货的订单则返回
if (deliverList.size() < 1) {
throw new ServiceException(ResultCode.ORDER_DELIVER_NUM_ERROR);
}
ExcelWriter writer = ExcelUtil.getWriter();
writer.addHeaderAlias("sn", "订单号");
writer.addHeaderAlias("logisticsName", "物流公司");
writer.addHeaderAlias("logisticsNo", "物流单号");
//写入待发货的订单列表
writer.write(deliverList, true);
//存放下拉列表
String[] logiList = logisticsName.toArray(new String[]{});
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, deliverList.size(), 2, 3);
writer.addSelect(cellRangeAddressList, logiList);
response.setHeader("Content-Disposition", "attachment;filename=批量发货.xls");
ServletOutputStream out = null;
try {
out = response.getOutputStream();
writer.flush(out, true);
} catch (IOException e) {
e.printStackTrace();
} finally {
writer.close();
}
IoUtil.close(out);
}
@Override
public void batchDeliver(List<OrderBatchDeliverDTO> list) {
//循环检查是否符合规范
checkBatchDeliver(list);
//订单批量发货
for (OrderBatchDeliverDTO orderBatchDeliverDTO : list) {
this.delivery(orderBatchDeliverDTO.getOrderSn(), orderBatchDeliverDTO.getLogisticsNo(), orderBatchDeliverDTO.getLogisticsId());
}
}
/**
* 循环检查批量发货订单列表
*
* @param list 待发货订单列表
*/
private void checkBatchDeliver(List<OrderBatchDeliverDTO> list) {
for (OrderBatchDeliverDTO orderBatchDeliverDTO : list) {
//查看订单号是否存在-是否是当前店铺的订单
int count = this.count(new LambdaQueryWrapper<Order>()
.eq(Order::getStoreId, UserContext.getCurrentUser().getStoreId())
.eq(Order::getSn, orderBatchDeliverDTO.getOrderSn()));
if (count == 0) {
throw new ServiceException("订单编号:'" + orderBatchDeliverDTO.getOrderSn() + " '不存在");
}
//查看物流公司
Logistics logistics = logisticsService.getOne(new LambdaQueryWrapper<Logistics>().eq(Logistics::getName, orderBatchDeliverDTO.getLogisticsName()));
if (logistics == null) {
throw new ServiceException("物流公司:'" + orderBatchDeliverDTO.getLogisticsName() + " '不存在");
} else {
orderBatchDeliverDTO.setLogisticsId(logistics.getId());
}
}
}
/**
* 订单状态变更消息
*
@ -605,11 +679,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
*/
private void pintuanOrderFailed(List<Order> list) {
for (Order order : list) {
// LambdaUpdateWrapper<Order> updateWrapper = new LambdaUpdateWrapper<>();
// updateWrapper.eq(Order::getId, order.getId());
// updateWrapper.set(Order::getOrderStatus, OrderStatusEnum.CANCELLED.name());
// updateWrapper.set(Order::getCancelReason, "拼团人数不足,拼团失败!");
// this.update(updateWrapper);
try {
this.cancel(order.getSn(), "拼团人数不足,拼团失败!");
} catch (Exception e) {

View File

@ -18,6 +18,9 @@ public interface StoreLogisticsMapper extends BaseMapper<StoreLogistics> {
@Select("SELECT l.* FROM li_logistics l RIGHT JOIN li_store_logistics sl ON l.id=sl.logistics_id WHERE sl.store_id=#{storeId}")
List<StoreLogisticsVO> getSelectedStoreLogistics(String storeId);
@Select("SELECT l.name FROM li_logistics l RIGHT JOIN li_store_logistics sl ON l.id=sl.logistics_id WHERE sl.store_id=#{storeId}")
List<String> getSelectedStoreLogisticsName(String storeId);
@Select("SELECT *, ( SELECT sl.id FROM li_store_logistics sl WHERE l.id = sl.logistics_id AND sl.store_id=#{storeId} ) AS selected FROM li_logistics l;")
List<StoreLogisticsVO> getStoreLogistics(String storeId);

View File

@ -28,6 +28,13 @@ public interface StoreLogisticsService extends IService<StoreLogistics> {
*/
List<StoreLogisticsVO> getStoreSelectedLogistics();
/**
* 获取当前店铺已选择的物流公司名称列表
*
* @return 物流公司列表
*/
List<String> getStoreSelectedLogisticsName();
/**
* 添加店铺-物流公司
*

View File

@ -35,6 +35,11 @@ public class StoreLogisticsServiceImpl extends ServiceImpl<StoreLogisticsMapper,
}
@Override
public List<String> getStoreSelectedLogisticsName() {
return this.baseMapper.getSelectedStoreLogisticsName(UserContext.getCurrentUser().getStoreId());
}
@Override
public StoreLogistics add(String logisticsId) {
//判断是否已经选择过如果没有选择则进行添加

View File

@ -1,13 +1,18 @@
package cn.lili.controller.trade;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dto.MemberAddressDTO;
import cn.lili.modules.order.order.entity.dto.OrderBatchDeliverDTO;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
import cn.lili.modules.order.order.entity.vo.OrderSimpleVO;
import cn.lili.modules.order.order.service.OrderPriceService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.system.service.StoreLogisticsService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@ -15,10 +20,15 @@ import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 店铺端,订单接口
@ -42,6 +52,11 @@ public class OrderStoreController {
*/
@Autowired
private OrderPriceService orderPriceService;
/**
* 物流公司
*/
@Autowired
private StoreLogisticsService storeLogisticsService;
@ApiOperation(value = "查询订单列表")
@GetMapping
@ -121,4 +136,44 @@ public class OrderStoreController {
public ResultMessage<Object> getTraces(@NotBlank(message = "订单编号不能为空") @PathVariable String orderSn) {
return ResultUtil.data(orderService.getTraces(orderSn));
}
@ApiOperation(value = "下载待发货的订单列表")
@GetMapping(value = "/downLoadDeliverExcel")
public ResultMessage<Object> downLoadDeliverExcel(HttpServletResponse response, List<String> orderIds) {
//获取店铺已经选择物流公司列表
List<String> logisticsName = storeLogisticsService.getStoreSelectedLogisticsName();
//下载订单批量发货Excel
this.orderService.getBatchDeliverList(response,orderIds,logisticsName);
return ResultUtil.success(ResultCode.SUCCESS);
}
@ApiOperation(value = "上传文件进行订单批量发货")
@ApiImplicitParam(name = "file", value = "订单列表", required = true, dataType = "file", paramType = "query")
@PutMapping(value = "/batchDeliver")
public void batchDeliver(@RequestParam MultipartFile file) {
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
// 2.应用HUtool ExcelUtil获取ExcelReader指定输入流和sheet
ExcelReader excelReader = ExcelUtil.getReader(inputStream);
// 可以加上表头验证
// 3.读取第二行到最后一行数据
List<List<Object>> read = excelReader.read(1, excelReader.getRowCount());
List<OrderBatchDeliverDTO> orderBatchDeliverDTOList=new ArrayList<>();
for (List<Object> objects : read) {
OrderBatchDeliverDTO orderBatchDeliverDTO=new OrderBatchDeliverDTO();
orderBatchDeliverDTO.setOrderSn(objects.get(0).toString());
orderBatchDeliverDTO.setLogisticsName(objects.get(1).toString());
orderBatchDeliverDTO.setLogisticsNo(objects.get(2).toString());
orderBatchDeliverDTOList.add(orderBatchDeliverDTO);
}
orderService.batchDeliver(orderBatchDeliverDTOList);
} catch (Exception e) {
e.printStackTrace();
}
}
}