Explorar o código

物流异常 字段添加 对应前端页面修改

yuhongqi hai 1 semana
pai
achega
ba7ac6b9fb

+ 252 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreDeliveryAbnormalOrderController.java

@@ -0,0 +1,252 @@
+package com.fs.hisStore.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.utils.CloudHostUtils;
+import com.fs.common.utils.ParseUtils;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.company.service.ICompanyMoneyLogsService;
+import com.fs.company.vo.CompanyStoreOrderMoneyLogsVO;
+import com.fs.company.param.CompanyStoreOrderMoneyLogsListParam;
+import com.fs.framework.web.service.TokenService;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import com.fs.his.vo.FsStoreOrderListAndStatisticsVo;
+import com.fs.hisStore.domain.FsStoreAfterSalesScrm;
+import com.fs.hisStore.domain.FsStoreOrderItemScrm;
+import com.fs.hisStore.domain.FsStoreOrderScrm;
+import com.fs.hisStore.domain.FsStoreOrderStatusScrm;
+import com.fs.hisStore.domain.FsStorePaymentScrm;
+import com.fs.hisStore.param.FsStoreOrderDeliveryExceptionParam;
+import com.fs.hisStore.param.FsStoreOrderParam;
+import com.fs.hisStore.service.IFsStoreAfterSalesScrmService;
+import com.fs.hisStore.service.IFsStoreOrderAuditLogScrmService;
+import com.fs.hisStore.service.IFsStoreOrderItemScrmService;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
+import com.fs.hisStore.service.IFsStoreOrderStatusScrmService;
+import com.fs.hisStore.service.IFsStorePaymentScrmService;
+import com.fs.hisStore.vo.FsStoreOrderAuditLogVO;
+import com.fs.hisStore.vo.FsStoreOrderVO;
+import com.github.pagehelper.PageHelper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 物流异常订单 Controller
+ */
+@RestController
+@RequestMapping("/store/store/storeDeliveryAbnormalOrder")
+public class FsStoreDeliveryAbnormalOrderController extends BaseController {
+
+    @Autowired
+    private IFsStoreOrderScrmService fsStoreOrderService;
+
+    @Autowired
+    private IFsStoreOrderItemScrmService orderItemService;
+
+    @Autowired
+    private IFsStoreOrderStatusScrmService orderStatusService;
+
+    @Autowired
+    private IFsStorePaymentScrmService paymentService;
+
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    private ICompanyUserService companyUserService;
+
+    @Autowired
+    private ICompanyService companyService;
+
+    @Autowired
+    private ICompanyMoneyLogsService moneyLogsService;
+
+    @Autowired
+    private IFsStoreOrderAuditLogScrmService orderAuditLogService;
+
+    @Autowired
+    private IFsStoreAfterSalesScrmService fsStoreAfterSalesService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
+
+    /**
+     * 查询物流异常订单列表(默认 delivery_status = 4 问题件)
+     */
+    @PreAuthorize("@ss.hasPermi('store:storeDeliveryAbnormalOrder:list')")
+    @PostMapping("/list")
+    public FsStoreOrderListAndStatisticsVo list(@RequestBody FsStoreOrderParam param) {
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        normalizeTimeRange(param);
+        param.setDeliveryStatus(4);
+//        if ("北京卓美".equals(signProjectName)) {
+//            param.setIsHealth("1");
+//        }
+        List<FsStoreOrderVO> list = fsStoreOrderService.selectFsStoreOrderListVO(param);
+        com.fs.common.core.page.TableDataInfo dataTable = getDataTable(list);
+        if (CloudHostUtils.hasCloudHostName("康年堂")) {
+            dataTable.setMsg("knt");
+        }
+        maskSensitiveFields(list);
+        FsStoreOrderListAndStatisticsVo vo = new FsStoreOrderListAndStatisticsVo();
+        BeanUtils.copyProperties(dataTable, vo);
+        if (dataTable.getTotal() > 0) {
+            Map<String, BigDecimal> statistics = fsStoreOrderService.selectFsStoreOrderStatistics(param);
+            if (statistics != null && statistics.size() >= 3) {
+                vo.setPayPriceTotal(statistics.get("pay_price").toString());
+                vo.setPayMoneyTotal(statistics.get("pay_money").toString());
+                vo.setPayRemainTotal(statistics.get("pay_remain").toString());
+            } else {
+                vo.setPayPriceTotal("0");
+                vo.setPayMoneyTotal("0");
+                vo.setPayRemainTotal("0");
+            }
+            String productStatistics = fsStoreOrderService.selectFsStoreOrderProductStatistics(param);
+            vo.setProductInfo(StringUtils.isNotBlank(productStatistics) ? productStatistics : "");
+        }
+        return vo;
+    }
+
+    /**
+     * 获取物流异常订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('store:storeDeliveryAbnormalOrder:query')")
+    @GetMapping("/{id}")
+    public R getInfo(@PathVariable("id") Long id) {
+        FsStoreOrderScrm order = fsStoreOrderService.selectFsStoreOrderById(id);
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        if (order.getDeliveryStatus() == null || order.getDeliveryStatus() != 4) {
+            return R.error("该订单不是物流异常订单");
+        }
+        order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
+        order.setUserAddress(ParseUtils.parseAddress(order.getUserAddress()));
+        FsUser user = userService.selectFsUserById(order.getUserId());
+        if (user != null) {
+            user.setPhone(ParseUtils.parsePhone(user.getPhone()));
+        }
+        fillCompanyInfo(order);
+
+        FsStoreOrderItemScrm itemMap = new FsStoreOrderItemScrm();
+        itemMap.setOrderId(order.getId());
+        List<FsStoreOrderItemScrm> items = orderItemService.selectFsStoreOrderItemList(itemMap);
+        FsStoreOrderStatusScrm statusMap = new FsStoreOrderStatusScrm();
+        statusMap.setOrderId(order.getId());
+        List<FsStoreOrderStatusScrm> logs = orderStatusService.selectFsStoreOrderStatusList(statusMap);
+        List<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentByOrderId(order.getId());
+        List<CompanyStoreOrderMoneyLogsVO> tuiMoneyLogs = new ArrayList<>();
+        if (order.getCompanyId() != null) {
+            CompanyStoreOrderMoneyLogsListParam moneyLogsMap = new CompanyStoreOrderMoneyLogsListParam();
+            moneyLogsMap.setCompanyId(order.getCompanyId());
+            moneyLogsMap.setBusinessId(order.getId().toString());
+            tuiMoneyLogs = moneyLogsService.selectCompanyStoreOrderMoneyLogsList(moneyLogsMap);
+        }
+        List<FsStoreOrderAuditLogVO> auditLogs = orderAuditLogService.selectStoreOrderAuditLogVOByOrderId(order.getId());
+        FsStoreAfterSalesScrm afterSales = null;
+        if (order.getStatus() != null && (order.getStatus() == -1 || order.getStatus() == -2)) {
+            afterSales = fsStoreAfterSalesService.selectFsStoreAfterSalesByOrderCode(order.getOrderCode());
+        }
+        return R.ok().put("order", order).put("items", items).put("logs", logs).put("user", user)
+                .put("payments", payments).put("tuiMoneyLogs", tuiMoneyLogs)
+                .put("auditLogs", auditLogs).put("afterSales", afterSales);
+    }
+
+    /**
+     * 处理物流异常(标记为已处理并填写备注)
+     */
+    @PreAuthorize("@ss.hasPermi('store:storeDeliveryAbnormalOrder:handle')")
+    @PostMapping("/handle")
+    public R handle(@RequestBody FsStoreOrderDeliveryExceptionParam param) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setOperator(loginUser.getUser().getNickName());
+        if (param.getDeliveryExceptionStatus() == null) {
+            param.setDeliveryExceptionStatus(2);
+        }
+        return fsStoreOrderService.updateDeliveryExceptionStatus(param);
+    }
+
+    private void normalizeTimeRange(FsStoreOrderParam param) {
+        if (!StringUtils.isEmpty(param.getCreateTimeRange())) {
+            param.setCreateTimeList(param.getCreateTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getPayTimeRange())) {
+            param.setPayTimeList(param.getPayTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getDeliveryImportTimeRange())) {
+            param.setDeliveryImportTimeList(param.getDeliveryImportTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getDeliverySendTimeRange())) {
+            param.setDeliverySendTimeList(param.getDeliverySendTimeRange().split("--"));
+        }
+    }
+
+    private void maskSensitiveFields(List<FsStoreOrderVO> list) {
+        if (list == null) {
+            return;
+        }
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        boolean showFinance = loginUser.getPermissions().contains("his:storeAfterSales:finance")
+                || loginUser.getPermissions().contains("*:*:*");
+        for (FsStoreOrderVO vo : list) {
+            if (StringUtils.isNotEmpty(vo.getPhone())) {
+                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+            }
+            if (StringUtils.isNotEmpty(vo.getUserPhone())) {
+                vo.setUserPhone(vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+            }
+            if (!showFinance) {
+                vo.setPayPostage(BigDecimal.ZERO);
+                vo.setCost(BigDecimal.ZERO);
+                vo.setFPrice(BigDecimal.ZERO);
+                vo.setPayDelivery(BigDecimal.ZERO);
+                vo.setBarCode("");
+                vo.setCateName("");
+                vo.setBankTransactionId("");
+            } else if (vo.getCost() != null && vo.getTotalNum() != null) {
+                vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+            }
+        }
+    }
+
+    private void fillCompanyInfo(FsStoreOrderScrm order) {
+        if (order.getCompanyUserId() != null) {
+            CompanyUser companyUser = companyUserService.selectCompanyUserByUserId(order.getCompanyUserId());
+            if (companyUser != null) {
+                Company company = companyService.selectCompanyById(companyUser.getCompanyId());
+                order.setCompanyUserName(companyUser.getNickName());
+                if (company != null) {
+                    order.setCompanyName(company.getCompanyName());
+                }
+            }
+        } else if (order.getCompanyId() != null) {
+            Company company = companyService.selectCompanyById(order.getCompanyId());
+            if (company != null) {
+                order.setCompanyName(company.getCompanyName());
+            }
+        }
+    }
+}

+ 64 - 4
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -65,6 +65,8 @@ public class WebSocketServer {
 
     // 上次点赞数缓存
     private final ConcurrentHashMap<Long, Integer> lastLikeCountCache = new ConcurrentHashMap<>();
+    /** 直播间在线人数峰值(广播只增不减) */
+    private final ConcurrentHashMap<Long, Integer> maxUserCountCache = new ConcurrentHashMap<>();
     // 直播间用户session
     private final static ConcurrentHashMap<Long, ConcurrentHashMap<Long, Session>> rooms = new ConcurrentHashMap<>();
     // 管理端连接
@@ -640,6 +642,11 @@ public class WebSocketServer {
                 case "deleteMsg":
                     deleteMsg(liveId,msg);
                     break;
+                case "replyUser":
+                    if (userType == 1) {
+                        sendReplyToUser(liveId, msg, session);
+                    }
+                    break;
                 case "red":
                     processRed(liveId, msg);
                     break;
@@ -966,6 +973,54 @@ public class WebSocketServer {
         }
     }
 
+    /**
+     * 管理端单独回复指定用户:从在线 map 定位 session,立即推送(不走广播队列,优先级最高)
+     */
+    private void sendReplyToUser(long liveId, SendMsgVo msg, Session adminSession) {
+        if (msg.getUserId() == null || StringUtils.isEmpty(msg.getMsg())) {
+            return;
+        }
+        msg.setMsg(productionWordFilter.filter(msg.getMsg()).getFilteredText());
+        if (StringUtils.isEmpty(msg.getMsg())) {
+            return;
+        }
+
+        Long targetUserId = msg.getUserId();
+        ConcurrentHashMap<Long, Session> room = getRoom(liveId);
+        Session targetSession = room.get(targetUserId);
+        if (targetSession == null || !targetSession.isOpen()) {
+            try {
+                sendMessage(adminSession, JSONObject.toJSONString(R.error("用户不在线,无法回复")));
+            } catch (IOException e) {
+                log.error("回复用户失败-通知管理员: liveId={}, targetUserId={}", liveId, targetUserId, e);
+            }
+            return;
+        }
+
+        SendMsgVo replyVo = new SendMsgVo();
+        replyVo.setLiveId(liveId);
+        replyVo.setUserId(targetUserId);
+        replyVo.setUserType(1L);
+        replyVo.setCmd("replyUser");
+        replyVo.setMsg(msg.getMsg());
+        replyVo.setNickName(msg.getNickName());
+        replyVo.setAvatar(msg.getAvatar());
+        replyVo.setOn(true);
+
+        String payload = JSONObject.toJSONString(R.ok().put("data", replyVo));
+        try {
+            sendMessage(targetSession, payload);
+            sendMessage(adminSession, JSONObject.toJSONString(R.ok().put("msg", "回复已发送")));
+        } catch (IOException e) {
+            log.error("发送单独回复失败: liveId={}, targetUserId={}, error={}", liveId, targetUserId, e.getMessage(), e);
+            try {
+                sendMessage(adminSession, JSONObject.toJSONString(R.error("回复发送失败")));
+            } catch (IOException ex) {
+                log.error("通知管理员回复失败: liveId={}, targetUserId={}", liveId, targetUserId, ex);
+            }
+        }
+    }
+
     /**
      * 广播消息
      * @param liveId   直播间ID
@@ -1033,6 +1088,7 @@ public class WebSocketServer {
 
     public void removeLikeCountCache(Long liveId) {
         lastLikeCountCache.remove(liveId);
+        maxUserCountCache.remove(liveId);
     }
     @Scheduled(fixedRate = 300)// 每分钟执行一次
     public void broadcastLikeMessage() {
@@ -1066,23 +1122,27 @@ public class WebSocketServer {
 
     @Scheduled(fixedRate = 2000)// 每2秒执行一次
     public void broadcastUserNumMessage() {
+        Set<Long> activeLiveIds = new HashSet<>();
         // 遍历每个直播间
         for (Map.Entry<Long, ConcurrentHashMap<Long, Session>> entry : rooms.entrySet()) {
             Long liveId = entry.getKey();
+            activeLiveIds.add(liveId);
             ConcurrentHashMap<Long, Session> room = entry.getValue();
 
-            // 统计当前直播间的在线人数
-            int onlineCount = room.size();
+            // 当前在线人数与历史峰值取较大值,保证广播数值只增不减
+            int currentOnline = room.size();
+            int displayCount = maxUserCountCache.merge(liveId, currentOnline, Math::max);
 
             // 构造消息
             SendMsgVo sendMsgVo = new SendMsgVo();
             sendMsgVo.setLiveId(liveId);
             sendMsgVo.setCmd("userCount");
-            sendMsgVo.setData(String.valueOf(onlineCount));
+            sendMsgVo.setData(String.valueOf(displayCount));
 
-            // 广播当前直播间的在线人数
+            // 广播当前直播间的在线人数(峰值)
             broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
         }
+        maxUserCountCache.keySet().removeIf(liveId -> !activeLiveIds.contains(liveId));
     }
 
 

+ 6 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -224,6 +224,12 @@ public class FsStoreOrderScrm extends BaseEntity
 
     private Integer deliveryStatus;
 
+    /** 物流异常备注 */
+    private String deliveryExceptionRemark;
+
+    /** 物流异常处理状态 1异常 2已处理 */
+    private Integer deliveryExceptionStatus;
+
     private Integer deliveryPayStatus;
 
     @Excel(name = "快递帐单日期")

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -152,6 +152,9 @@ public interface FsStoreAfterSalesScrmMapper
             "<if test = 'maps.deptId != null    '> " +
             "  AND (o.dept_id = #{maps.deptId} OR o.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{maps.deptId}, ancestors) )) " +
             "</if>" +
+            "<if test = 'maps.erpExceptionStatus != null    '> " +
+            "and s.erp_exception_status = #{maps.erpExceptionStatus} " +
+            "</if>" +
             " ${maps.params.dataScope} "+
             "order by s.create_time desc "+
             "</script>"})

+ 20 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderDeliveryExceptionParam.java

@@ -0,0 +1,20 @@
+package com.fs.hisStore.param;
+
+import lombok.Data;
+
+/**
+ * 物流异常订单处理参数
+ */
+@Data
+public class FsStoreOrderDeliveryExceptionParam {
+
+    private Long orderId;
+
+    /** 物流异常处理状态 1异常 2已处理 */
+    private Integer deliveryExceptionStatus;
+
+    /** 物流异常备注 */
+    private String deliveryExceptionRemark;
+
+    private String operator;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderParam.java

@@ -61,6 +61,15 @@ public class FsStoreOrderParam extends BaseEntity implements Serializable
 
     private Integer deliveryStatus;
 
+    /** 物流异常处理状态 1待处理 2已处理 */
+    private Integer deliveryExceptionStatus;
+
+    /** 物流跟踪状态/异常状态 */
+    private String deliveryType;
+
+    /** 仅查询有物流异常标记的订单 */
+    private Integer onlyDeliveryAbnormal;
+
     private Integer deliveryPayStatus;
 
     private Long deptId;

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -346,6 +346,8 @@ public interface IFsStoreOrderScrmService
 
     String selectFsStoreOrderProductStatistics(FsStoreOrderParam param);
 
+    R updateDeliveryExceptionStatus(FsStoreOrderDeliveryExceptionParam param);
+
     int create(Long orderId, String type, String msg);
 
     R dfOrderResult(String body);

+ 51 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsExpressScrmServiceImpl.java

@@ -158,11 +158,13 @@ public class FsExpressScrmServiceImpl implements IFsExpressScrmService
 
             //根据公司业务处理返回的信息......
             ExpressInfoDTO dto=JSONUtil.toBean(result,ExpressInfoDTO.class);
-            if (!dto.isSuccess()) {
+            if (dto == null || !dto.isSuccess()) {
                 logger.error("查询快递信息失败:{}:{}", result, requestData);
+                afterExpressFailure(OrderCode, LogisticCode, dto != null ? dto.getReason() : "查询快递返回为空");
             }
             return dto;
         } catch (Exception e) {
+            afterExpressFailure(OrderCode, LogisticCode, e.getMessage());
             throw  new CustomException(e.getMessage());
         }
 
@@ -233,8 +235,14 @@ public class FsExpressScrmServiceImpl implements IFsExpressScrmService
             params.put("DataType", "2");
             String result = HttpUtil.post(sysConfig.getKdnSubscribeUrl().trim(), params);
             logger.info("订阅物流:"+result);
+            ExpressInfoDTO dto = JSONUtil.toBean(result, ExpressInfoDTO.class);
+            if (dto == null || !dto.isSuccess()) {
+                logger.error("订阅物流失败:{}:{}", result, requestData);
+                afterExpressFailure(orderCode, deliveryId, dto != null ? dto.getReason() : "订阅物流返回为空");
+            }
 
         } catch (Exception e) {
+            afterExpressFailure(orderCode, deliveryId, e.getMessage());
             throw  new CustomException(e.getMessage());
         }
     }
@@ -368,6 +376,48 @@ public class FsExpressScrmServiceImpl implements IFsExpressScrmService
         return lastFourNumber;
     }
 
+    /**
+     * 快递查询/订阅失败或异常时更新订单物流状态为问题件
+     */
+    private void afterExpressFailure(String orderCode, String logisticCode, String reason) {
+        try {
+            FsStoreOrderScrm order = findOrderForExpress(orderCode, logisticCode);
+            if (order == null) {
+                logger.warn("快递失败后置处理:未找到订单 orderCode={}, logisticCode={}, reason={}", orderCode, logisticCode, reason);
+                return;
+            }
+            if (order.getDeliveryStatus() != null && order.getDeliveryStatus() == 3) {
+                return;
+            }
+            FsStoreOrderScrm update = new FsStoreOrderScrm();
+            update.setId(order.getId());
+            update.setDeliveryStatus(4);
+            update.setDeliveryType("401");
+            update.setDeliveryExceptionStatus(1);
+            if (StringUtils.isNotBlank(reason)) {
+                update.setDeliveryExceptionRemark(reason);
+            }
+            fsStoreOrderMapper.updateFsStoreOrder(update);
+            logger.info("快递失败已更新订单物流状态为问题件 orderCode={}, orderId={}, reason={}",
+                    order.getOrderCode(), order.getId(), reason);
+        } catch (Exception e) {
+            logger.error("快递失败后置处理异常 orderCode={}, logisticCode={}", orderCode, logisticCode, e);
+        }
+    }
+
+    private FsStoreOrderScrm findOrderForExpress(String orderCode, String logisticCode) {
+        if (StringUtils.isNotBlank(orderCode)) {
+            FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
+            if (order != null) {
+                return order;
+            }
+        }
+        if (StringUtils.isNotBlank(logisticCode)) {
+            return fsStoreOrderMapper.selectFsStoreOrderByDeliveryId(logisticCode);
+        }
+        return null;
+    }
+
     /**
      * Sign签名生成
      *

+ 22 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -6299,6 +6299,28 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return fsStoreOrderMapper.selectFsStoreOrderProductStatistics(param);
     }
 
+    @Override
+    public R updateDeliveryExceptionStatus(FsStoreOrderDeliveryExceptionParam param) {
+        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
+        if (order == null) {
+            return R.error("订单不存在");
+        }
+        if (order.getDeliveryStatus() == null || order.getDeliveryStatus() != 4) {
+            return R.error("该订单不是物流异常订单");
+        }
+        if (order.getDeliveryExceptionStatus() != null && order.getDeliveryExceptionStatus() == 2) {
+            return R.error("该订单已处理");
+        }
+        FsStoreOrderScrm update = new FsStoreOrderScrm();
+        update.setId(param.getOrderId());
+        update.setDeliveryExceptionStatus(param.getDeliveryExceptionStatus() != null ? param.getDeliveryExceptionStatus() : 2);
+        if (StringUtils.isNotBlank(param.getDeliveryExceptionRemark())) {
+            update.setDeliveryExceptionRemark(param.getDeliveryExceptionRemark());
+        }
+        fsStoreOrderMapper.updateFsStoreOrder(update);
+        return R.ok();
+    }
+
     @Override
     public int create(Long orderId, String type, String msg) {
         FsStoreOrderLogsScrm logs=new FsStoreOrderLogsScrm();

+ 6 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java

@@ -245,6 +245,12 @@ public class FsStoreOrderVO implements Serializable
 
     private Integer deliveryStatus;
 
+    /** 物流异常备注 */
+    private String deliveryExceptionRemark;
+
+    /** 物流异常处理状态 1异常 2已处理 */
+    private Integer deliveryExceptionStatus;
+
     @Excel(name = "物流代收结算状态", dictType = "store_delivery_pay_status")
     private Integer deliveryPayStatus;
 

+ 60 - 2
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -69,6 +69,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="packageId"    column="package_id"    />
         <result property="finishTime"    column="finish_time"    />
         <result property="deliveryStatus"    column="delivery_status"    />
+        <result property="deliveryExceptionRemark"    column="delivery_exception_remark"    />
+        <result property="deliveryExceptionStatus"    column="delivery_exception_status"    />
         <result property="deliveryPayStatus"    column="delivery_pay_status"    />
         <result property="deliveryTime"    column="delivery_time"    />
         <result property="deliveryPayTime"    column="delivery_pay_time"    />
@@ -98,7 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsStoreOrderVo">
-        select id, order_code,outer_oi_id,service_fee, extend_order_id,pay_order_id,bank_order_id, user_id,order_visit, real_name, user_phone, user_address, cart_id, freight_price, total_num, total_price, total_postage, pay_price, pay_postage,pay_delivery,pay_money, deduction_price, coupon_id, coupon_price, paid, pay_time, pay_type, create_time, update_time, status, refund_status, refund_reason_wap_img, refund_reason_wap_explain, refund_reason_time, refund_reason_wap, refund_reason, refund_price, delivery_sn, delivery_name, delivery_type, delivery_id, gain_integral, use_integral, pay_integral, back_integral, mark, is_del, remark, cost, verify_code, store_id, shipping_type, is_channel, is_remind, is_sys_del,is_prescribe,prescribe_id ,company_id,company_user_id,is_package,package_json,item_json,order_type,package_id,finish_time,delivery_status,delivery_pay_status,delivery_time,delivery_pay_time,delivery_pay_money,tui_money,tui_money_status,delivery_import_time,tui_user_id,tui_user_money_status,order_create_type,store_house_code,dept_id,is_edit_money,customer_id,is_pay_remain,delivery_send_time,certificates,schedule_id,backend_edit_product_type,video_id,course_id,project_id,period_id,virtual_phone,group_buy_id,live_id from fs_store_order_scrm
+        select id, order_code,outer_oi_id,service_fee, extend_order_id,pay_order_id,bank_order_id, user_id,order_visit, real_name, user_phone, user_address, cart_id, freight_price, total_num, total_price, total_postage, pay_price, pay_postage,pay_delivery,pay_money, deduction_price, coupon_id, coupon_price, paid, pay_time, pay_type, create_time, update_time, status, refund_status, refund_reason_wap_img, refund_reason_wap_explain, refund_reason_time, refund_reason_wap, refund_reason, refund_price, delivery_sn, delivery_name, delivery_type, delivery_id, gain_integral, use_integral, pay_integral, back_integral, mark, is_del, remark, cost, verify_code, store_id, shipping_type, is_channel, is_remind, is_sys_del,is_prescribe,prescribe_id ,company_id,company_user_id,is_package,package_json,item_json,order_type,package_id,finish_time,delivery_status,delivery_exception_remark,delivery_exception_status,delivery_pay_status,delivery_time,delivery_pay_time,delivery_pay_money,tui_money,tui_money_status,delivery_import_time,tui_user_id,tui_user_money_status,order_create_type,store_house_code,dept_id,is_edit_money,customer_id,is_pay_remain,delivery_send_time,certificates,schedule_id,backend_edit_product_type,video_id,course_id,project_id,period_id,virtual_phone,group_buy_id,live_id from fs_store_order_scrm
     </sql>
 
     <select id="selectFsStoreOrderList" parameterType="FsStoreOrderScrm" resultMap="FsStoreOrderResult">
@@ -453,6 +455,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageId != null">package_id = #{packageId},</if>
             <if test="finishTime != null">finish_time = #{finishTime},</if>
             <if test="deliveryStatus != null">delivery_status = #{deliveryStatus},</if>
+            <if test="deliveryExceptionRemark != null">delivery_exception_remark = #{deliveryExceptionRemark},</if>
+            <if test="deliveryExceptionStatus != null">delivery_exception_status = #{deliveryExceptionStatus},</if>
             <if test="deliveryPayStatus != null">delivery_pay_status = #{deliveryPayStatus},</if>
             <if test="deliveryTime != null">delivery_time = #{deliveryTime},</if>
             <if test="deliveryPayTime != null">delivery_pay_time = #{deliveryPayTime},</if>
@@ -1302,6 +1306,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_exception_status is not null
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>
@@ -1481,6 +1494,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_exception_status is not null
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>
@@ -1637,6 +1659,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_exception_status is not null
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>
@@ -1797,6 +1828,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_exception_status is not null
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>
@@ -1874,7 +1914,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 <!--    商城订单查询接口-->
     <select id="selectFsStoreOrderListVO" resultType="com.fs.hisStore.vo.FsStoreOrderVO">
-        select DISTINCT o.id,o.order_code,o.extend_order_id,o.pay_order_id,o.bank_order_id,o.user_id,o.real_name,o.user_phone,o.user_address,o.cart_id,o.freight_price,o.total_num,o.total_price,o.total_postage,o.pay_price,o.pay_postage,o.pay_delivery,o.pay_money,o.deduction_price,o.coupon_id,o.coupon_price,o.paid,o.pay_time,o.pay_type,o.create_time,o.update_time,o.status,o.refund_status,o.refund_reason_wap_img,o.refund_reason_wap_explain,o.refund_reason_time,o.refund_reason_wap,o.refund_reason,o.refund_price,o.delivery_sn,o.delivery_name,o.delivery_type,o.delivery_id,o.gain_integral,o.use_integral,o.pay_integral,o.back_integral,o.mark,o.is_del,o.remark,o.verify_code,o.store_id,o.shipping_type,o.is_channel,o.is_remind,o.is_sys_del,o.is_prescribe,o.prescribe_id,o.company_id,o.company_user_id,o.is_package,o.package_json,o.order_type,o.package_id,o.finish_time,o.delivery_status,o.delivery_pay_status,o.delivery_time,o.delivery_pay_time,o.delivery_pay_money,o.tui_money,o.tui_money_status,o.delivery_import_time,o.tui_user_id,o.tui_user_money_status,o.order_create_type,o.store_house_code,o.dept_id,o.is_edit_money,o.customer_id,o.is_pay_remain,o.delivery_send_time,o.certificates,o.upload_time,o.item_json,o.schedule_id,o.delivery_pay_type,o.order_visit,o.service_fee,o.cycle,o.prescribe_price,o.follow_doctor_id,o.follow_time,o.user_coupon_id,o.order_medium,o.erp_phone,o.order_type
+        select DISTINCT o.id,o.order_code,o.extend_order_id,o.pay_order_id,o.bank_order_id,o.user_id,o.real_name,o.user_phone,o.user_address,o.cart_id,o.freight_price,o.total_num,o.total_price,o.total_postage,o.pay_price,o.pay_postage,o.pay_delivery,o.pay_money,o.deduction_price,o.coupon_id,o.coupon_price,o.paid,o.pay_time,o.pay_type,o.create_time,o.update_time,o.status,o.refund_status,o.refund_reason_wap_img,o.refund_reason_wap_explain,o.refund_reason_time,o.refund_reason_wap,o.refund_reason,o.refund_price,o.delivery_sn,o.delivery_name,o.delivery_type,o.delivery_id,o.gain_integral,o.use_integral,o.pay_integral,o.back_integral,o.mark,o.is_del,o.remark,o.verify_code,o.store_id,o.shipping_type,o.is_channel,o.is_remind,o.is_sys_del,o.is_prescribe,o.prescribe_id,o.company_id,o.company_user_id,o.is_package,o.package_json,o.order_type,o.package_id,o.finish_time,o.delivery_status,o.delivery_exception_remark,o.delivery_exception_status,o.delivery_pay_status,o.delivery_time,o.delivery_pay_time,o.delivery_pay_money,o.tui_money,o.tui_money_status,o.delivery_import_time,o.tui_user_id,o.tui_user_money_status,o.order_create_type,o.store_house_code,o.dept_id,o.is_edit_money,o.customer_id,o.is_pay_remain,o.delivery_send_time,o.certificates,o.upload_time,o.item_json,o.schedule_id,o.delivery_pay_type,o.order_visit,o.service_fee,o.cycle,o.prescribe_price,o.follow_doctor_id,o.follow_time,o.user_coupon_id,o.order_medium,o.erp_phone,o.order_type
         ,u.phone,u.register_code,u.register_date,u.source, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber
         , csc.name miniProgramName,fsp.cost, fspc.cate_name,spavs.bar_code, sp_latest.bank_transaction_id as bankTransactionId,sp_latest.app_id, o.is_audit, o.audit_time,u.nick_name AS userNickName,oi.json_info
         , aft.reason_level1_text as reasonValue1, aft.reason_level2_text as reasonValue2
@@ -1957,6 +1997,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_status like '%4%'
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>
@@ -2156,6 +2205,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.deliveryStatus != null     ">
                 and o.delivery_status =#{maps.deliveryStatus}
             </if>
+            <if test="maps.deliveryExceptionStatus != null">
+                and o.delivery_exception_status = #{maps.deliveryExceptionStatus}
+            </if>
+            <if test="maps.onlyDeliveryAbnormal != null and maps.onlyDeliveryAbnormal == 1">
+                and o.delivery_exception_status is not null
+            </if>
+            <if test="maps.deliveryType != null and maps.deliveryType != ''">
+                and o.delivery_type = #{maps.deliveryType}
+            </if>
             <if test="maps.deliveryPayStatus != null  ">
                 and o.delivery_pay_status =#{maps.deliveryPayStatus}
             </if>