|
|
@@ -7,12 +7,16 @@ import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
+import java.time.ZonedDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
+import cn.binarywang.wx.miniapp.api.WxMaService;
|
|
|
+import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
|
|
|
+import cn.binarywang.wx.miniapp.bean.shop.response.WxMaOrderShippingInfoGetResponse;
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
@@ -45,7 +49,10 @@ import com.fs.company.service.ICompanyDeptService;
|
|
|
import com.fs.company.service.ICompanyService;
|
|
|
import com.fs.company.service.ICompanyUserService;
|
|
|
import com.fs.config.cloud.CloudHostProper;
|
|
|
+import com.fs.core.config.WxMaConfiguration;
|
|
|
import com.fs.core.utils.OrderCodeUtils;
|
|
|
+import com.fs.course.dto.FsOrderDeliveryNoteDTO;
|
|
|
+import com.fs.course.dto.OrderOpenIdTransDTO;
|
|
|
import com.fs.erp.domain.*;
|
|
|
import com.fs.erp.dto.*;
|
|
|
import com.fs.erp.mapper.FsErpFinishPushMapper;
|
|
|
@@ -70,9 +77,7 @@ import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
|
|
|
import com.fs.hisStore.mapper.FsUserScrmMapper;
|
|
|
import com.fs.hisStore.param.*;
|
|
|
import com.fs.hisStore.service.*;
|
|
|
-import com.fs.hisStore.vo.FsMyStoreOrderListQueryVO;
|
|
|
-import com.fs.hisStore.vo.FsStoreOrderItemVO;
|
|
|
-import com.fs.hisStore.vo.FsStoreOrderVO;
|
|
|
+import com.fs.hisStore.vo.*;
|
|
|
import com.fs.huifuPay.domain.HuiFuCreateOrder;
|
|
|
import com.fs.huifuPay.domain.HuiFuRefundResult;
|
|
|
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
|
|
|
@@ -81,6 +86,7 @@ import com.fs.huifuPay.service.HuiFuService;
|
|
|
import com.fs.live.domain.*;
|
|
|
import com.fs.live.dto.LiveOrderComputeDTO;
|
|
|
import com.fs.live.dto.LiveOrderCustomerExportDTO;
|
|
|
+import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
|
|
|
import com.fs.live.dto.LiveOrderItemDTO;
|
|
|
import com.fs.live.mapper.*;
|
|
|
import com.fs.live.param.*;
|
|
|
@@ -97,6 +103,7 @@ import com.github.binarywang.wxpay.config.WxPayConfig;
|
|
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
|
|
import com.github.binarywang.wxpay.service.WxPayService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang.ObjectUtils;
|
|
|
import org.apache.http.util.Asserts;
|
|
|
@@ -674,6 +681,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
|
|
|
|
|
|
order.setStatus(OrderInfoEnum.STATUS_1.getValue());
|
|
|
order.setPayTime(LocalDateTime.now());
|
|
|
+ order.setIsPay("1");
|
|
|
baseMapper.updateLiveOrder(order);
|
|
|
return "SUCCESS";
|
|
|
}catch (Exception e){
|
|
|
@@ -1507,7 +1515,13 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
|
|
|
if (!StringUtils.isEmpty(order.getExtendOrderId()) && order.getStatus() != 1) {
|
|
|
return R.error("订单:" + order.getOrderCode() + ",已推送erp/订单状态不正确");
|
|
|
}
|
|
|
+ if(order.getUserName() == null || StringUtils.isEmpty(order.getUserName())) return R.error("用户信息为空");
|
|
|
ErpOrder erpOrder = getErpOrder(order);
|
|
|
+ if(erpOrder == null ){
|
|
|
+ log.info("组合码为空,订单ID:" + order.getOrderCode());
|
|
|
+ return R.error("组合码为空");
|
|
|
+ }
|
|
|
+
|
|
|
if (erpOrderService == jSTOrderService) {
|
|
|
erpOrder.setShop_code(erpConfig.getErpJstShopCode());
|
|
|
}
|
|
|
@@ -1616,6 +1630,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
|
|
|
for (LiveOrderItem orderItem : orderItems) {
|
|
|
FsStoreProduct cartDTO = JSONUtil.toBean(orderItem.getJsonInfo(), FsStoreProduct.class);
|
|
|
ErpOrderItem item = new ErpOrderItem();
|
|
|
+ if(cartDTO.getBarCode() == null) return null;
|
|
|
item.setItem_code(cartDTO.getBarCode() == null ? "" : cartDTO.getBarCode().trim());
|
|
|
item.setPrice(cartDTO.getPrice() == null ? "" : cartDTO.getPrice().toString());
|
|
|
// todo yhq 需要检查
|
|
|
@@ -2896,6 +2911,263 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
|
|
|
return baseMapper.selectLiveOrderItemJson();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
|
|
|
+ public void refreshOrderSettlementStatus() {
|
|
|
+ try {
|
|
|
+ // 判断是否对接微信发货
|
|
|
+ String json = configService.selectConfigByKey("store.config");
|
|
|
+ StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
|
|
|
+ log.info("进入微信结算订单定时任务--------------->{}", "start");
|
|
|
+ if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
|
|
|
+ // 获取未结算订单
|
|
|
+ List<LiveOrder> orderScrmList = liveOrderMapper.getUnsettledOrder();
|
|
|
+
|
|
|
+ String payConfig = configService.selectConfigByKey("store.pay");
|
|
|
+ JSONObject js = JSON.parseObject(payConfig);
|
|
|
+ String appId = js.getString("appId");
|
|
|
+
|
|
|
+ if (ObjectUtil.isNotNull(appId) && !appId.isEmpty()) {
|
|
|
+ final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
|
|
+
|
|
|
+ if (!orderScrmList.isEmpty()) {
|
|
|
+ for (LiveOrder order : orderScrmList) {
|
|
|
+ WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
|
|
|
+ request.setTransactionId(order.getBankTransactionId());
|
|
|
+ WxMaOrderShippingInfoGetResponse response;
|
|
|
+
|
|
|
+ try {
|
|
|
+ response = wxService.getWxMaOrderShippingService().get(request);
|
|
|
+
|
|
|
+ if (response.getErrCode().equals(0)) {
|
|
|
+ // 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
|
|
|
+ if (response.getOrder().getOrderState().equals(3) || response.getOrder().getOrderState().equals(4)) {
|
|
|
+ if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
|
|
|
+ this.finishOrder(order.getOrderId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("请求信息------------------------》{}", response);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (WxErrorException e) {
|
|
|
+ log.info("异常信息------------------------》{}", e.getMessage());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.getStackTrace();
|
|
|
+ } finally {
|
|
|
+ log.info("进入微信结算订单定时任务--------------->{}", "end");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R importDeliveryNoteExpress(List<LiveOrderDeliveryNoteDTO> dtoList,String appId) {
|
|
|
+ try {
|
|
|
+ StringBuilder builder = new StringBuilder();
|
|
|
+ //获取商城配置
|
|
|
+ String json = configService.selectConfigByKey("store.config");
|
|
|
+ StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
|
|
|
+
|
|
|
+ List<LiveOrderDeliveryNoteDTO> successList = new ArrayList<>(dtoList.size());
|
|
|
+ //提前获取所有必要数据
|
|
|
+ Map<String, String> expressDeliveryMap = buildExpressDeliveryMap();
|
|
|
+ //提取所有有效订单号
|
|
|
+ List<String> orderCodeList = new ArrayList<>(dtoList.size());
|
|
|
+ for (int i = 0; i < dtoList.size(); i++) {
|
|
|
+ LiveOrderDeliveryNoteDTO dto = dtoList.get(i);
|
|
|
+ if (StringUtils.isEmpty(dto.getOrderNumber())) {
|
|
|
+ builder.append("数据第").append(i + 2).append("行系统订单为空!").append(System.lineSeparator());
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
|
|
|
+ builder.append("数据第").append(i + 2).append("行物流公司为空!").append(System.lineSeparator());
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(dto.getDeliveryId())) {
|
|
|
+ builder.append("数据第").append(i + 2).append("行快递单号为空!").append(System.lineSeparator());
|
|
|
+ } else {
|
|
|
+ //处理订单ID信息
|
|
|
+ String originalOrderNumber = dto.getOrderNumber();
|
|
|
+ String processedOrderNumber = extractNumbers(originalOrderNumber);
|
|
|
+ dto.setOrderNumber(processedOrderNumber);
|
|
|
+ orderCodeList.add(dto.getOrderNumber());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //批量查询订单信息
|
|
|
+ if (orderCodeList.isEmpty()) {
|
|
|
+ return R.ok(builder.toString());
|
|
|
+ }
|
|
|
+ List<LiveOrderCodeOpenIdVo> orderCodeOpenIdVoList = baseMapper.selectLiveOrderCodeOpenIdInOrderCode(orderCodeList);
|
|
|
+ Map<String, OrderOpenIdTransDTO> orderMap = new HashMap<>(orderCodeOpenIdVoList.size());
|
|
|
+ Map<String, List<LiveOrderCodeOpenIdVo>> orderDetailsMap = new HashMap<>(orderCodeOpenIdVoList.size());
|
|
|
+
|
|
|
+ for (LiveOrderCodeOpenIdVo vo : orderCodeOpenIdVoList) {
|
|
|
+ orderMap.computeIfAbsent(vo.getId(), k -> {
|
|
|
+ OrderOpenIdTransDTO dto = new OrderOpenIdTransDTO();
|
|
|
+ dto.setOpenId(vo.getOpenId());
|
|
|
+ dto.setTransactionId(vo.getOutTransId());
|
|
|
+ return dto;
|
|
|
+ });
|
|
|
+
|
|
|
+ orderDetailsMap
|
|
|
+ .computeIfAbsent(vo.getId(), k -> new ArrayList<>())
|
|
|
+ .add(vo);
|
|
|
+ }
|
|
|
+ final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
|
|
+ String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
|
|
|
+ .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
|
|
+
|
|
|
+ for (int i = 0; i < dtoList.size(); i++) {
|
|
|
+ LiveOrderDeliveryNoteDTO dto = dtoList.get(i);
|
|
|
+ int rowNum = i + 2;
|
|
|
+ if (StringUtils.isEmpty(dto.getOrderNumber())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(dto.getDeliveryId())) {
|
|
|
+ builder.append("数据第").append(rowNum).append("行快递单号为空!")
|
|
|
+ .append(System.lineSeparator());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
|
|
|
+ builder.append("数据第").append(rowNum).append("行快递公司编号为空!")
|
|
|
+ .append(System.lineSeparator());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 验证快递公司
|
|
|
+ String deliverySn = expressDeliveryMap.get(dto.getLogisticsCompany());
|
|
|
+ if (deliverySn == null) {
|
|
|
+ builder.append("数据第").append(rowNum).append("行订单号为")
|
|
|
+ .append(dto.getOrderNumber()).append("物流公司名称异常")
|
|
|
+ .append(System.lineSeparator());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ dto.setDeliverySn(deliverySn);
|
|
|
+
|
|
|
+ // 检查订单是否存在
|
|
|
+ String orderNumber = dto.getOrderNumber();
|
|
|
+ OrderOpenIdTransDTO orderInfo = orderMap.get(orderNumber);
|
|
|
+ if (orderInfo == null) {
|
|
|
+ builder.append("数据第").append(rowNum).append("行订单号")
|
|
|
+ .append(orderNumber).append("不存在").append(System.lineSeparator());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //验证是否开启微信发货
|
|
|
+ if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
|
|
|
+ // 上传物流信息到微信
|
|
|
+ List<LiveOrderCodeOpenIdVo> orderDetails = orderDetailsMap.get(orderNumber);
|
|
|
+ if (uploadShippingInfoToWechat(wxService, orderInfo, orderDetails, dto, uploadTime)) {
|
|
|
+ successList.add(dto);
|
|
|
+ } else {
|
|
|
+ builder.append("数据第").append(rowNum).append("行订单号为")
|
|
|
+ .append(orderNumber).append("上传微信失败").append(System.lineSeparator());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ successList.add(dto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //批量更新数据
|
|
|
+ if (!successList.isEmpty()) {
|
|
|
+ batchUpdateDeliveryNotes(successList);
|
|
|
+ }
|
|
|
+
|
|
|
+ return R.ok(builder.toString().equals("") ? "操作成功!" : builder.toString());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("导入发货单快递信息失败", e);
|
|
|
+ return R.error("导入失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void batchUpdateDeliveryNotes(List<LiveOrderDeliveryNoteDTO> list) {
|
|
|
+ int batchSize = 500;
|
|
|
+ int total = list.size();
|
|
|
+ int batches = (total + batchSize - 1) / batchSize;
|
|
|
+ for (int i = 0; i < batches; i++) {
|
|
|
+ int start = i * batchSize;
|
|
|
+ int end = Math.min(start + batchSize, total);
|
|
|
+ List<LiveOrderDeliveryNoteDTO> subList = list.subList(start, end);
|
|
|
+ baseMapper.batchUpdateInOrderCode(subList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean uploadShippingInfoToWechat(WxMaService wxService,
|
|
|
+ OrderOpenIdTransDTO orderInfo,
|
|
|
+ List<LiveOrderCodeOpenIdVo> orderDetails,
|
|
|
+ LiveOrderDeliveryNoteDTO dto,
|
|
|
+ String uploadTime) {
|
|
|
+ try {
|
|
|
+ WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
|
|
|
+ OrderKeyBean orderKeyBean = new OrderKeyBean();
|
|
|
+ orderKeyBean.setOrderNumberType(2);
|
|
|
+ orderKeyBean.setTransactionId(orderInfo.getTransactionId());
|
|
|
+ request.setOrderKey(orderKeyBean);
|
|
|
+ request.setDeliveryMode(1);
|
|
|
+ request.setLogisticsType(1);
|
|
|
+ List<ShippingListBean> shippingList = new ArrayList<>(orderDetails.size());
|
|
|
+ ShippingListBean shippingListBean = null;
|
|
|
+ for (LiveOrderCodeOpenIdVo detail : orderDetails) {
|
|
|
+ if (shippingListBean == null) {
|
|
|
+ shippingListBean = new ShippingListBean();
|
|
|
+ shippingListBean.setTrackingNo(dto.getDeliveryId());
|
|
|
+ shippingListBean.setExpressCompany(dto.getDeliverySn());
|
|
|
+ JSONObject js = JSON.parseObject(detail.getJsonInfo());
|
|
|
+ shippingListBean.setItemDesc(js.getString("productName"));
|
|
|
+ ContactBean contactBean = new ContactBean();
|
|
|
+ contactBean.setReceiverContact(detail.getPhone());
|
|
|
+ shippingListBean.setContact(contactBean);
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ shippingList.add(shippingListBean);
|
|
|
+ request.setShippingList(shippingList);
|
|
|
+ request.setUploadTime(uploadTime);
|
|
|
+ // 设置支付者信息
|
|
|
+ PayerBean payerBean = new PayerBean();
|
|
|
+ payerBean.setOpenid(orderInfo.getOpenId());
|
|
|
+ request.setPayer(payerBean);
|
|
|
+
|
|
|
+ // 上传物流信息
|
|
|
+ return wxService.getWxMaOrderShippingService().upload(request).getErrCode() == 0;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("上传物流信息到微信失败,订单号: {}", dto.getOrderNumber(), e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Map<String, String> buildExpressDeliveryMap() {
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ map.put("SF", "顺丰");
|
|
|
+ map.put("EMS", "邮政");
|
|
|
+ map.put("ZTO", "中通");
|
|
|
+ map.put("JD", "京东");
|
|
|
+ map.put("DBL", "德邦");
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ //高性能截取订单ID
|
|
|
+ private static String extractNumbers(String str) {
|
|
|
+ if (str == null || str.isEmpty()) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ int start = 0;
|
|
|
+ int len = str.length();
|
|
|
+ while (start < len && !Character.isDigit(str.charAt(start))) {
|
|
|
+ start++;
|
|
|
+ }
|
|
|
+ return start < len ? str.substring(start) : "";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<LiveOrderDeliveryNoteExportVO> getDeliveryNote(LiveOrderParam param) {
|
|
|
+ return baseMapper.getDeliveryNote(param);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
|