Просмотр исходного кода

1.京东云仓 2.app角色会员等级

wjj 5 дней назад
Родитель
Сommit
374935e6db
48 измененных файлов с 1683 добавлено и 29 удалено
  1. 69 1
      fs-admin/src/main/java/com/fs/his/task/Task.java
  2. 3 0
      fs-service/src/main/java/com/fs/app/domain/FsAppRole.java
  3. 3 0
      fs-service/src/main/java/com/fs/app/vo/FsAppRoleVO.java
  4. 2 0
      fs-service/src/main/java/com/fs/erp/domain/ErpOrder.java
  5. 5 0
      fs-service/src/main/java/com/fs/erp/dto/CommonResponse.java
  6. 65 0
      fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java
  7. 22 0
      fs-service/src/main/java/com/fs/his/config/FsSysConfig.java
  8. 3 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  9. 6 0
      fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java
  10. 19 1
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java
  11. 2 2
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  12. 8 1
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  13. 44 23
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java
  14. 56 0
      fs-service/src/main/java/com/fs/jd/dto/AddServicesDTO.java
  15. 48 0
      fs-service/src/main/java/com/fs/jd/dto/BatchInfosDTO.java
  16. 75 0
      fs-service/src/main/java/com/fs/jd/dto/CargoInfoDTO.java
  17. 34 0
      fs-service/src/main/java/com/fs/jd/dto/CarrierInfoDTO.java
  18. 16 0
      fs-service/src/main/java/com/fs/jd/dto/ChannelInfoDTO.java
  19. 57 0
      fs-service/src/main/java/com/fs/jd/dto/ColdChainDTO.java
  20. 13 0
      fs-service/src/main/java/com/fs/jd/dto/CustomerInfoDTO.java
  21. 4 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryBatchItemDTO.java
  22. 4 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryBoxDTO.java
  23. 43 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryItemDTO.java
  24. 36 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryPackageDTO.java
  25. 42 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryProductInfoDTO.java
  26. 4 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryRejectItemDTO.java
  27. 26 0
      fs-service/src/main/java/com/fs/jd/dto/DeliveryStatusDTO.java
  28. 16 0
      fs-service/src/main/java/com/fs/jd/dto/GoodsSerialNoQueryResultDTO.java
  29. 9 0
      fs-service/src/main/java/com/fs/jd/dto/IndustryAttributesDTO.java
  30. 36 0
      fs-service/src/main/java/com/fs/jd/dto/InvoiceInfoDTO.java
  31. 30 0
      fs-service/src/main/java/com/fs/jd/dto/OrderCancelRequestDTO.java
  32. 12 0
      fs-service/src/main/java/com/fs/jd/dto/OrderCancelResponseDTO.java
  33. 17 0
      fs-service/src/main/java/com/fs/jd/dto/PackageItemDTO.java
  34. 15 0
      fs-service/src/main/java/com/fs/jd/dto/PackageMaterialDTO.java
  35. 18 0
      fs-service/src/main/java/com/fs/jd/dto/ProductAttrsDTO.java
  36. 12 0
      fs-service/src/main/java/com/fs/jd/dto/ProductDTO.java
  37. 45 0
      fs-service/src/main/java/com/fs/jd/dto/ReceiverInfoDTO.java
  38. 9 0
      fs-service/src/main/java/com/fs/jd/dto/RelatedOrdersDTO.java
  39. 51 0
      fs-service/src/main/java/com/fs/jd/dto/ShipmentInfoDTO.java
  40. 97 0
      fs-service/src/main/java/com/fs/jd/dto/SoCreateOrderRequestDTO.java
  41. 23 0
      fs-service/src/main/java/com/fs/jd/dto/SoCreateResponseDTO.java
  42. 111 0
      fs-service/src/main/java/com/fs/jd/dto/SoQueryRequestDTO.java
  43. 193 0
      fs-service/src/main/java/com/fs/jd/dto/SoQueryResponseDTO.java
  44. 36 0
      fs-service/src/main/java/com/fs/jd/dto/WarehouseOperationRuleDTO.java
  45. 18 0
      fs-service/src/main/java/com/fs/jd/http/IJdHttpService.java
  46. 220 0
      fs-service/src/main/java/com/fs/jd/http/JdHttpServiceImpl.java
  47. 5 1
      fs-service/src/main/resources/mapper/app/FsAppRoleMapper.xml
  48. 1 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml

+ 69 - 1
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -21,6 +21,10 @@ import com.fs.huifuPay.domain.HuifuOrderConfirmResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
 import com.fs.huifuPay.sdk.opps.core.utils.DateTools;
 import com.fs.huifuPay.service.HuiFuService;
+import com.fs.jd.dto.CarrierInfoDTO;
+import com.fs.jd.dto.SoQueryRequestDTO;
+import com.fs.jd.dto.SoQueryResponseDTO;
+import com.fs.jd.http.IJdHttpService;
 import com.fs.qw.mapper.FsSopCompanyUserTaskMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.sop.domain.QwSopTempVoice;
@@ -284,6 +288,9 @@ public class Task {
     @Autowired
     private IFsUserService fsUserService;
 
+    @Autowired
+    private IJdHttpService jdHttpService;
+
     public static final String SOP_TEMP_VOICE_KEY = "sop:tempVoice";
 
     // sop升单客户类型
@@ -1015,6 +1022,68 @@ public class Task {
 
     }
 
+    //京东发货-互医
+    public void jdDeliveryOp(){
+        List<FsStoreOrder> storeOrders = fsStoreOrderMapper.selectJDOmsOrderDeliveryOp();
+        if (CollectionUtils.isNotEmpty(storeOrders)) {
+            for (FsStoreOrder order : storeOrders) {
+                SoQueryRequestDTO dto = new SoQueryRequestDTO();
+                dto.setPin("YSY2026");
+                dto.setOwnerNo("EBU4418057579814");
+                dto.setErpDeliveryNo(order.getOrderCode());
+                dto.setDeliveryNo(order.getExtendOrderId());
+                SoQueryResponseDTO soQueryResponseDTO = null;
+                try {
+                    //查询京东物流信息
+                   soQueryResponseDTO  = jdHttpService.queryDelivery(dto);
+                   Thread.sleep(2000); // 1000毫秒 = 1秒
+                } catch (Exception e) {
+                    logger.info("查询京东出库信息失败,订单号:{},失败原因:{}",order.getOrderCode(),e.getMessage());
+                }
+                if (soQueryResponseDTO != null) {
+                    //物流信息
+                    CarrierInfoDTO carrierInfo = soQueryResponseDTO.getCarrierInfo();
+                    if (carrierInfo != null) {
+                        if (StringUtils.isNotEmpty(carrierInfo.getWaybillNo())){
+                            fsStoreOrderService.deliveryOrder(order.getOrderCode(),carrierInfo.getWaybillNo(),carrierInfo.getCarrierNo(),carrierInfo.getCarrierName(),carrierInfo.getExpectDate());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    //京东发货-商城
+    public void jdDeliveryOpScrm(){
+        List<FsStoreOrderScrm> storeOrders = fsStoreOrderMapper.selectJDOmsOrderDeliveryOpScrm();
+        if (CollectionUtils.isNotEmpty(storeOrders)) {
+            for (FsStoreOrderScrm order : storeOrders) {
+                SoQueryRequestDTO dto = new SoQueryRequestDTO();
+                dto.setPin("YSY2026");
+                dto.setOwnerNo("EBU4418057579814");
+                dto.setErpDeliveryNo(order.getOrderCode());
+                dto.setDeliveryNo(order.getExtendOrderId());
+                SoQueryResponseDTO soQueryResponseDTO = null;
+                try {
+                    //查询京东物流信息
+                    soQueryResponseDTO  = jdHttpService.queryDelivery(dto);
+                    Thread.sleep(2000); // 1000毫秒 = 1秒
+                } catch (Exception e) {
+                    logger.info("查询京东出库信息失败,订单号:{},失败原因:{}",order.getOrderCode(),e.getMessage());
+                }
+                if (soQueryResponseDTO != null) {
+                    //物流信息
+                    CarrierInfoDTO carrierInfo = soQueryResponseDTO.getCarrierInfo();
+                    if (carrierInfo != null) {
+                        if (StringUtils.isNotEmpty(carrierInfo.getWaybillNo())){
+                            fsStoreOrderService.deliveryOrderScrm(order.getOrderCode(),carrierInfo.getWaybillNo(),carrierInfo.getCarrierNo(),carrierInfo.getCarrierName(),carrierInfo.getExpectDate());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public void deliveryOp() {
         IErpOrderService erpOrderService = getErpService();
         List<FsStoreOrder> orders = null;
@@ -2384,7 +2453,6 @@ public class Task {
                     Thread.sleep(1000);
                 } catch (Exception e) {
                     logger.info("添加用户角色信息失败,原因:{},用户id:{}",e.getMessage(),userId);
-                    continue;
                 }
             }
         }

+ 3 - 0
fs-service/src/main/java/com/fs/app/domain/FsAppRole.java

@@ -112,4 +112,7 @@ public class FsAppRole extends BaseEntity{
     /** 是否显示 true:显示,false:隐藏*/
     @TableField(exist = false)
     private boolean isShow=false;
+
+    /** 角色关联的会员等级 */
+    private Integer roleVipLevel;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/app/vo/FsAppRoleVO.java

@@ -77,6 +77,9 @@ public class FsAppRoleVO {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
+    /** 角色关联的会员等级 */
+    private Integer roleVipLevel;
+
     @Data
     public static class Options implements Serializable {
         private String day;

+ 2 - 0
fs-service/src/main/java/com/fs/erp/domain/ErpOrder.java

@@ -37,4 +37,6 @@ public class ErpOrder {
 
     // 1-聚水潭 2-兔零
     Integer erpType;
+
+    String town;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/erp/dto/CommonResponse.java

@@ -32,4 +32,9 @@ public class CommonResponse<T> implements Serializable {
      * 响应数据
      */
     private T data;
+
+    /**
+     * 京东错误描述
+     */
+    private String message;
 }

+ 65 - 0
fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java

@@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.erp.constant.AfterSalesOrderStatusEnum;
@@ -15,6 +16,7 @@ import com.fs.erp.constant.OrderStatusEnum;
 import com.fs.erp.constant.TaskStatusEnum;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
+import com.fs.erp.dto.OrderCancelRequestDTO;
 import com.fs.erp.dto.tl.TlCreateOrderRequest;
 import com.fs.erp.dto.tl.TlOptions;
 import com.fs.erp.http.JstErpHttpService;
@@ -44,6 +46,8 @@ import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.hisStore.service.impl.FsStoreProductScrmServiceImpl;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.huifuPay.sdk.opps.core.utils.StringUtil;
+import com.fs.jd.dto.*;
+import com.fs.jd.http.IJdHttpService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.http.util.Asserts;
@@ -100,6 +104,9 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
     @Autowired
     private CompanyUserMapper companyUserMapper;
 
+    @Autowired
+    private IJdHttpService jdHttpService;
+
     @Override
     public ErpOrderResponse addOrder(ErpOrder order) {
         FsStoreOrder fsStoreOrder = fsStoreOrderService.selectFsStoreOrderByOrderCode(order.getPlatform_code());
@@ -257,6 +264,8 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
             }
             //HttpResponse response = tlErpOrderService.syncOrderToJst(request);
             //upload = parseResponse(response,  new TypeReference<CommonResponse<ErpOrderResponseDTO>>() {});
+        } else if (order.getErpType() == 3) {
+            pushJDOrder(order, itemDTOList, erpOrderResponse);
         }
         return erpOrderResponse;
     }
@@ -434,10 +443,66 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
             }
             //HttpResponse response = tlErpOrderService.syncOrderToJst(request);
             //upload = parseResponse(response,  new TypeReference<CommonResponse<ErpOrderResponseDTO>>() {});
+        }  else if (order.getErpType() == 3) {
+            pushJDOrder(order, itemDTOList, erpOrderResponse);
         }
         return erpOrderResponse;
     }
 
+    private void pushJDOrder(ErpOrder order, List<OrderItemDTO> itemDTOList, ErpOrderResponse erpOrderResponse) {
+         SoCreateOrderRequestDTO requestDTO = new SoCreateOrderRequestDTO();
+         requestDTO.setSourceNo("ISV0020008045424");
+         //订单号
+         requestDTO.setErpDeliveryNo(order.getPlatform_code());
+         requestDTO.setWarehouseNo("118075105");
+         requestDTO.setOrderMark("00000000000000000000000000000000000000000000000000");
+         requestDTO.setPin("YSY2026");
+         //渠道信息
+         ChannelInfoDTO channelInfoDTO = new ChannelInfoDTO();
+         channelInfoDTO.setSalesPlatformSource("6");
+         requestDTO.setChannelInfo(channelInfoDTO);
+         //客户信息
+         CustomerInfoDTO customerInfoDTO = new CustomerInfoDTO();
+         customerInfoDTO.setOwnerNo("EBU4418057579814");
+         customerInfoDTO.setShopNo("ESP0020010430525");
+         requestDTO.setCustomerInfo(customerInfoDTO);
+         //承运信息
+         CarrierInfoDTO carrierInfoDTO = new CarrierInfoDTO();
+         carrierInfoDTO.setCarrierNo("CYS4418046511167");
+         requestDTO.setCarrierInfo(carrierInfoDTO);
+         List<CargoInfoDTO> cargoInfoDTOList = new ArrayList<>();
+         //商品信息
+         if (!CollectionUtils.isEmpty(itemDTOList)) {
+             for (OrderItemDTO orderItemDTO : itemDTOList) {
+                 CargoInfoDTO cargoInfoDTO = new CargoInfoDTO();
+                 cargoInfoDTO.setGoodsNo(orderItemDTO.getSkuId());
+                 cargoInfoDTO.setPlanQuantity(orderItemDTO.getQty());
+                 cargoInfoDTOList.add(cargoInfoDTO);
+             }
+         }
+         requestDTO.setCargoInfos(cargoInfoDTOList);
+
+         //收件人信息
+         ReceiverInfoDTO receiverInfoDTO = new ReceiverInfoDTO();
+         //收件人电话
+         receiverInfoDTO.setMobile(order.getReceiver_mobile());
+         //收件人姓名
+         receiverInfoDTO.setName(order.getReceiver_name());
+         //省
+         receiverInfoDTO.setProvince(order.getReceiver_province());
+         //市
+         receiverInfoDTO.setCity(order.getReceiver_city());
+         //区
+         receiverInfoDTO.setCounty(order.getReceiver_district());
+         receiverInfoDTO.setTown(order.getReceiver_address());
+         receiverInfoDTO.setDetailAddress(order.getReceiver_address());
+         requestDTO.setReceiverInfo(receiverInfoDTO);
+         SoCreateResponseDTO dto = jdHttpService.deliveryCreate(requestDTO);
+         if (!StringUtils.isEmpty(dto.getDeliveryNo())) {
+             erpOrderResponse.setSuccess(true);
+             erpOrderResponse.setCode(dto.getDeliveryNo());
+         }
+    }
 
 
     @Override

+ 22 - 0
fs-service/src/main/java/com/fs/his/config/FsSysConfig.java

@@ -81,4 +81,26 @@ public class FsSysConfig {
 
     //物流代收定金比例
     private BigDecimal rate;
+
+
+    //京东APPkey
+    private String jdAppKey;
+    //京东AppSecret
+    private String jdAppSecret;
+    //京东token
+    private String jdAccessToken;
+    //京东token
+    private String jdRefreshToken;
+    //京东pin
+    private String pin;
+    //京东K码
+    private String kNo;
+    //京东店铺
+    private String shopNo;
+    //京东库房编码
+    private String warehouseNo;
+    //京东承运码
+    private String carrierNo;
+    //京东EBU码
+    private String ownerNo;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -166,6 +166,9 @@ public class FsUser extends BaseEntity
     /** app奖励实际观看天数 */
     private Integer appRewardsViewedDays;
 
+    /** 角色关联的会员等级 */
+    private Integer roleVipLevel;
+
     /** app登录后不为null(表示是否下载app) */
     private String historyApp;
 

+ 6 - 0
fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java

@@ -1157,9 +1157,15 @@ public interface FsStoreOrderMapper
     @Select("select * from fs_store_order where  `status`=2 and extend_order_id is not null and extend_order_id != '' and (erp_type = 1 or erp_type is null) ")
     List<FsStoreOrder> selectWdtOmsOrderdeliveryOp();
 
+    @Select("select * from fs_store_order where  `status`=2 and extend_order_id is not null and extend_order_id != '' and erp_type = 3")
+    List<FsStoreOrder> selectJDOmsOrderDeliveryOp();
+
     @Select("select * from fs_store_order_scrm where  `status`=1 and extend_order_id is not null and extend_order_id != '' and (erp_type = 1 or erp_type is null) ")
     List<FsStoreOrderScrm> selectWdtOmsOrderdeliveryOpScrm();
 
+    @Select("select * from fs_store_order_scrm where  `status`=1 and extend_order_id is not null and extend_order_id != '' and erp_type = 3")
+    List<FsStoreOrderScrm> selectJDOmsOrderDeliveryOpScrm();
+
     @Select("select * from fs_store_order where  `status`=2 and extend_order_id is not null and `is_merge` = 0 and extend_order_id != '' ")
     List<FsStoreOrder> selectNoMergeOrder();
 

+ 19 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java

@@ -46,6 +46,9 @@ import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.im.dto.*;
 import com.fs.im.service.IImService;
+import com.fs.jd.dto.OrderCancelRequestDTO;
+import com.fs.jd.dto.OrderCancelResponseDTO;
+import com.fs.jd.http.IJdHttpService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.ybPay.dto.RefundDTO;
@@ -158,6 +161,9 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
     @Autowired
     private IFsStoreOrderLogsService fsStoreOrderLogsService;
 
+    @Autowired
+    private IJdHttpService jdHttpService;
+
     /**
      * 查询售后记录
      *
@@ -563,7 +569,7 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
             }
         }
 
-        //erpType== null 兼容之前订单没有设值 erpType==2人工在兔灵作废
+        //erpType== null 兼容之前订单没有设值 erpType==2人工在兔灵作废 erpType==3 取消京东出库
         if (fsStoreOrder.getErpType() == null || fsStoreOrder.getErpType() == 1) {
             try {
                 //管易作废
@@ -596,6 +602,18 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
             } catch (Exception e) {
 //                throw new RuntimeException(e);
             }
+        } else if (fsStoreOrder.getErpType() == 3) {
+            OrderCancelRequestDTO requestDTO = new OrderCancelRequestDTO();
+            requestDTO.setOwnerNo("EBU4418057579814");
+            requestDTO.setPin("YSY2026");
+            requestDTO.setOrderType("XSCK");
+            requestDTO.setOrderNo(fsStoreOrder.getExtendOrderId());
+            requestDTO.setErpOrderNo(fsStoreOrder.getOrderCode());
+            try {
+                jdHttpService.orderCancel(requestDTO);
+            } catch (Exception e) {
+                logger.info("取消京东出库失败,订单号:{},失败原因:{}",fsStoreOrder.getOrderCode(),e.getMessage());
+            }
         }
 
 

+ 2 - 2
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -2569,7 +2569,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 //        }
 //        FsPackage fsPackage = JSONUtil.toBean(fsPackageOrder.getPackageJson(), FsPackage.class);
 
-        //获取ERP类型 1-聚水潭 2-兔灵
+        //获取ERP类型 1-聚水潭 2-兔灵 3-京东云仓
         erpOrder.setErpType(order.getErpType());
 
         if (order.getCompanyId() != null) {
@@ -2756,7 +2756,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         log.info("ErpCreate:" + order.getOrderCode() + ":" + JSONUtil.toJsonStr(response));
         if (Boolean.TRUE.equals(response.getSuccess())) {
             //写入外部订单号
-            if (order.getErpType() == 2) {
+            if (order.getErpType() == 2 || order.getErpType() == 3) {
                 order.setExtendOrderId(response.getCode());
             } else {
                 //支付成功后 将订单号写入待发货的REDIS中

+ 8 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -1538,7 +1538,7 @@ public class FsUserServiceImpl implements IFsUserService {
         //标签+商城商品
         if (CollectionUtils.isNotEmpty(tagAndMallRoleList)) {
             if (CollectionUtils.isNotEmpty(userTags) && CollectionUtils.isNotEmpty(userProductIds)) {
-                tagAndPackageRoleList.forEach(tagAndMallRole -> {
+                tagAndMallRoleList.forEach(tagAndMallRole -> {
                     boolean tagMatch = false;
                     boolean productMatch = false;
                     if (StringUtils.isNotEmpty(tagAndMallRole.getRoleTags())) {
@@ -1593,9 +1593,16 @@ public class FsUserServiceImpl implements IFsUserService {
         }
         //3.更新用户角色信息
         if (CollectionUtils.isNotEmpty(addRoleList)) {
+            HashSet<Long> idSet = new HashSet<>(addRoleList);
+            List<FsAppRole> addAppRoleList = appRoleList.stream()
+                    .filter(fsAppRole -> idSet.contains(fsAppRole.getId()))
+                    .sorted(Comparator.comparingInt(FsAppRole::getRoleVipLevel))
+                    .collect(Collectors.toList());
+            logger.info("addAppRoleList:{}",addAppRoleList);
             FsUser map = new FsUser();
             map.setUserId(userId);
             map.setAppRoles(StringUtils.join(addRoleList, ","));
+            map.setRoleVipLevel(addAppRoleList.get(0).getRoleVipLevel());
             fsUserMapper.updateFsUser(map);
         }
     }

+ 44 - 23
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -43,6 +43,8 @@ import com.fs.huifuPay.domain.HuifuConfirmrefundResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentDelaytransConfirmrefundRequest;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
 import com.fs.huifuPay.service.HuiFuService;
+import com.fs.jd.dto.OrderCancelRequestDTO;
+import com.fs.jd.http.IJdHttpService;
 import com.fs.pay.service.IPayService;
 import com.fs.hisStore.config.StoreConfig;
 import com.fs.hisStore.domain.*;
@@ -198,6 +200,9 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
     @Autowired
     private CloudHostProper cloudHostProper;
 
+    @Autowired
+    private IJdHttpService jdHttpService;
+
     /**
      * 查询售后记录
      *
@@ -1602,31 +1607,47 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
             }
             //管易作废
             if (StringUtils.isNotEmpty(fsStoreOrder.getExtendOrderId())) {
-                if (!fsStoreOrder.getExtendOrderId().equals("HIS")) {
-                    ErpRefundUpdateRequest request = new ErpRefundUpdateRequest();
-                    request.setTid(fsStoreOrder.getOrderCode());
-                    request.setOid(fsStoreOrder.getOrderCode());
-                    request.setRefund_state(1);
-                    request.setStoreAfterSalesId(fsStoreAfterSales.getId());
-                    FsSysConfig sysConfig = configUtil.getSysConfig();
-                    Integer erpType = sysConfig.getErpType();
-                    IErpOrderService erpOrderService = getErpService();
-                    if (erpType == 1) {
-                        erpOrderService.refundUpdate(request);
-                    }else if (erpType == 2) {
-                        //旺店通
-                        wdtErpOrderService.refundUpdate(request);
-                    } else if (erpType == 3) {
-                        //瀚智
-                        hzOMSerpOrderService.refundUpdate(request);
-                    }  else if (erpType == 4) {
-                        dfOrderService.refundUpdate(request);
-                    }else if(erpType == 5){
-                        jSTOrderService.refundUpdate(request);
-                    }else if(erpType == 6){
-                        k9OrderService.refundUpdate(request);
+                //erpType== null 兼容之前订单没有设值 erpType==2人工在兔灵作废 erpType==3 取消京东出库
+                if (fsStoreOrder.getErpType() == null || fsStoreOrder.getErpType() == 1) {
+                    if (!fsStoreOrder.getExtendOrderId().equals("HIS")) {
+                        ErpRefundUpdateRequest request = new ErpRefundUpdateRequest();
+                        request.setTid(fsStoreOrder.getOrderCode());
+                        request.setOid(fsStoreOrder.getOrderCode());
+                        request.setRefund_state(1);
+                        request.setStoreAfterSalesId(fsStoreAfterSales.getId());
+                        FsSysConfig sysConfig = configUtil.getSysConfig();
+                        Integer erpType = sysConfig.getErpType();
+                        IErpOrderService erpOrderService = getErpService();
+                        if (erpType == 1) {
+                            erpOrderService.refundUpdate(request);
+                        }else if (erpType == 2) {
+                            //旺店通
+                            wdtErpOrderService.refundUpdate(request);
+                        } else if (erpType == 3) {
+                            //瀚智
+                            hzOMSerpOrderService.refundUpdate(request);
+                        }  else if (erpType == 4) {
+                            dfOrderService.refundUpdate(request);
+                        }else if(erpType == 5){
+                            jSTOrderService.refundUpdate(request);
+                        }else if(erpType == 6){
+                            k9OrderService.refundUpdate(request);
+                        }
+                    }
+                } else if (fsStoreOrder.getErpType() == 3) {
+                    OrderCancelRequestDTO requestDTO = new OrderCancelRequestDTO();
+                    requestDTO.setOwnerNo("EBU4418057579814");
+                    requestDTO.setPin("YSY2026");
+                    requestDTO.setOrderType("XSCK");
+                    requestDTO.setOrderNo(fsStoreOrder.getExtendOrderId());
+                    requestDTO.setErpOrderNo(fsStoreOrder.getOrderCode());
+                    try {
+                        jdHttpService.orderCancel(requestDTO);
+                    } catch (Exception e) {
+                        logger.info("取消京东出库失败,订单号:{},失败原因:{}",fsStoreOrder.getOrderCode(),e.getMessage());
                     }
                 }
+
             }
         } else {
             if (order.getRefundAmount().compareTo(BigDecimal.ZERO) == 0) {

+ 56 - 0
fs-service/src/main/java/com/fs/jd/dto/AddServicesDTO.java

@@ -0,0 +1,56 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AddServicesDTO {
+    /** 代收货款金额,单位:元,精确到2位小数 */
+    private Double receivable;
+
+    /** 是否保价,枚举:1:是,0:否,长度:1字符 */
+    private Integer isInsuredPrice;
+
+    /** 保价声明价值,单位:元,精确到2位小数 */
+    private Double insuredValue;
+
+    /** 是否特殊签收,枚举:0:不需要此服务 2:短信验证 3:指定验证码;长度:1字符 */
+    private Integer signType;
+
+    /** 指定验证码,signType=3时必填,6位的数字字母 */
+    private String signIDCode;
+
+    /** 签单返还收件人名称,当大件订单纸质签单必填,长度:1-20字符 */
+    private String signReturnName;
+
+    /** 签单返还收件人电话,长度:1-15字符 */
+    private String signReturnPhone;
+
+    /** 签单返还收件人手机,当大件订单纸质签单必填,长度:11-15字符 */
+    private String signReturnMobile;
+
+    /** 签单返还收件人地址,大件订单纸质签单必填,1-200字符 */
+    private String signReturnAddress;
+
+    /** 中小件开箱验货方式,枚举:0:未开通,1:随心验(收费),2:开商品包装验货,3:开物流包装验货,4:不支持开箱验货,长度:1字符 */
+    private Integer unPack;
+
+    /** 是否安心,枚举:0:否;1:是,长度:1字符 */
+    private Integer peaceMindReceive;
+
+    /** 院内增值服务,枚举:0:否,1:是,长度:1字符 */
+    private Integer yardInner;
+
+    /** 是否卸车,枚举:0:否,1:是,长度:1字符 */
+    private String isUnload;
+
+    /** 大件是否SN码拍照。枚举值。0:否,1:是 */
+    private String lasSnPhotoTaken;
+
+    /** 预约派送。枚举值:0-不需要此服务;1-预约派送 */
+    private Integer appointmentDelivery;
+
+    /** 预约派送时间 */
+    private List<ProductDTO> appointmentDeliveryTime;
+}

+ 48 - 0
fs-service/src/main/java/com/fs/jd/dto/BatchInfosDTO.java

@@ -0,0 +1,48 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class BatchInfosDTO {
+    /** 采购单号,长度:1-50字符 */
+    private String purchaseNo;
+
+    /** 生产日期,格式:yyyy-MM-dd,长度:1-100字符 */
+    private String productDate;
+
+    /** 到期日期,格式:yyyy-MM-dd,长度:1-100字符 */
+    private String expireDate;
+
+    /** 收货日期,长度:1-50字符 */
+    private String receiptDate;
+
+    /** 包装批号,长度:1-50字符 */
+    private String packageLot;
+
+    /** 生产批号,长度:1-50字符 */
+    private String lot;
+
+    /** 供应商,长度:1-50字符 */
+    private String supplier;
+
+    /** plu管理,长度:1-100字符 */
+    private String plu;
+
+    /** 物流公司,长度:1-100字符 */
+    private String logisticCompany;
+
+    /** 原产地,长度:1-100字符 */
+    private String origin;
+
+    /** 制造商,长度:1-100字符 */
+    private String manufacturer;
+
+    /** 箱号,长度:1-100字符 */
+    private String boxNo;
+
+    /** 不可售,长度:1-100字符 */
+    private String noSale;
+
+    /** 门店,长度:1-100字符 */
+    private String store;
+}

+ 75 - 0
fs-service/src/main/java/com/fs/jd/dto/CargoInfoDTO.java

@@ -0,0 +1,75 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class CargoInfoDTO {
+    /** ECLP商品编号,与商家商品编号二选一必填,长度:16字符 */
+    private String goodsNo;
+
+    /** 商家商品编号,与ECLP商品编号二选一必填,长度:1-50字符 */
+    private String erpGoodsNo;
+
+    /** 商品的出库数量,必须大于0,长度:1-11字符 */
+    private Integer planQuantity;
+
+    /** 明细商品等级,枚举:良品:100;残品:200,如不指定默认良品出库,长度:1-10字符 */
+    private String goodsLevel;
+
+    /** 行号,长度:1-50字符 */
+    private String orderLine;
+
+    /** 商品名称,长度:1-500字符 */
+    private String goodsName;
+
+    /** 计量单位,长度:1-10字符 */
+    private String unit;
+
+    /** 发票备注,长度:1-20字符 */
+    private String remark;
+
+    /** 商品金额,单位:元,精确到4位小数,整数最多13位 */
+    private Double price;
+
+    /** 金额,单位:元,长度:1-10字符 */
+    private String amount;
+
+    /** 结算金额,单位:元,精确到2位小数,整数最多12位 */
+    private Double payAmount;
+
+    /** 商品备注,无长度限制 */
+    private String sellerGoodsRemark;
+
+    /** 发票税率,无长度限制 */
+    private String taxRate;
+
+    /** 规格型号,发票使用,无长度限制 */
+    private String type;
+
+    /** 安维标识,枚举:0:不需要安装,1:京东安装,2:厂家安装,长度:1字符 */
+    private String installVenderId;
+
+    /** 包装类型,无长度限制 */
+    private String packageType;
+
+    /** 保质期剩余百分比,0到1之间 */
+    private Double leftExpirationPercent;
+
+    /** 保质期剩余百分比运算规则,1:等于 2:大于 3:小于 4:大于等于 5:小于等于 6:不等于 ,默认=1,长度:1字符 */
+    private Integer leftExpirationPercentOperate;
+
+    /** 商品折扣价格,单位:元,精确到2位小数 */
+    private String goodsDiscountPrice;
+
+    /** 批属性信息 */
+    private BatchInfosDTO batchInfos;
+
+    /** 序列号编码列表 */
+    private List<String> serialNos;
+
+    /** 即时配送商品扩展信息 */
+    private Map<String, Object> instantFulfillmentGoodsExtendProps;
+}

+ 34 - 0
fs-service/src/main/java/com/fs/jd/dto/CarrierInfoDTO.java

@@ -0,0 +1,34 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class CarrierInfoDTO {
+    /** 承运商编号,默认为京东快递(CYS0000010),长度:1-50字符 */
+    private String carrierNo;
+
+    /**
+     * 期望发货时间,格式为:yyyy-mm-dd HH:mm:ss,未指定默认京东接单时间,长度:19字符
+     */
+    private String expectDate;
+
+    /**
+     * 三方配送信息
+     */
+    private ShipmentInfoDTO shipmentInfo;
+
+    /**
+     * 承运商名称
+     */
+    private String carrierName;
+
+    /**
+     * 快递单号
+     */
+    private String waybillNo;
+
+    /**
+     * 众邮运单号
+     */
+    private String tpWaybillNo;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/jd/dto/ChannelInfoDTO.java

@@ -0,0 +1,16 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ChannelInfoDTO {
+
+    //商家店铺编号,长度:1-100字符
+    private String erpShopNo;
+    //销售平台订单号,如果销售平台来源为京东平台(salePlatformSource=1),则该字段不能为空,长度:1-200字符
+    private String salesPlatformDeliveryNo;
+    //销售平台来源(1-京东 6-其他),常用平台枚举详见:https://cloud.jdl.com/#/open-business-document/access-guide/367/54604
+    private String salesPlatformSource;
+    //销售平台下单时间,格式为:yyyy-mm-dd HH:mm:ss,未指定默认京东接单时间,长度:19字符
+    private String salesPlatformCreateTime;
+}

+ 57 - 0
fs-service/src/main/java/com/fs/jd/dto/ColdChainDTO.java

@@ -0,0 +1,57 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ColdChainDTO {
+    /** 车型 */
+    private String vehicleType;
+
+    /** 流通监管码,长度:1-50字符 */
+    private String supervisionCode;
+
+    /** 开票员,长度:1-50字符 */
+    private String invoiceChecker;
+
+    /** 付款方式,长度:1-20字符 */
+    private String paymentType;
+
+    /** 销售类型,长度:1-10字符 */
+    private String saleType;
+
+    /** 是否抽检单,枚举:0:否,1:是,长度:1字符 */
+    private Integer randomInspection;
+
+    /** 冷链产品编码 */
+    private String productCode;
+
+    /** 有无动物检疫证,枚举:1:有,2:无,长度:1字符 */
+    private Integer quarantineCert;
+
+    /** 是否送货入仓,枚举:1:是;2:否,长度:1字符 */
+    private Integer deliveryIntoWarehouse;
+
+    /** 送仓类型,枚举:1:送京仓;2:送外仓,长度:1字符 */
+    private Integer deliveryWarehouseType;
+
+    /** 进仓预约号,长度:1-30字符 */
+    private String inStorageNo;
+
+    /** 进仓时间,格式为:yyyy-MM-dd HH:mm:ss,长度:19字符 */
+    private String inStorageTime;
+
+    /** 进仓备注,长度:1-100字符 */
+    private String inStorageRemark;
+
+    /** 派送服务,是否需要京东进行上门派送,枚举:1:京东派送:2:非京东派送,长度:1字符 */
+    private Integer deliveryService;
+
+    /** 自提点Id,长度: 1-10字符 */
+    private Integer selfDeliverySiteId;
+
+    /** 集单批量号,长度:1-100字符 */
+    private String orderBatchNo;
+
+    /** 集单总单数,长度:1-100 */
+    private Integer orderBatchQty;
+}

+ 13 - 0
fs-service/src/main/java/com/fs/jd/dto/CustomerInfoDTO.java

@@ -0,0 +1,13 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class CustomerInfoDTO {
+    //青龙业主号,格式:010K开头,长度:1-50字符
+    private String customerCode;
+    //开放平台事业部编码,商家与京东物流签约后生成的商家的唯一编码,格式:EBU开头,长度:1-50字符
+    private String ownerNo;
+    //店铺编码,当orderType=1时必填,orderType=2时非必填,长度:1-100字符
+    private String shopNo;
+}

+ 4 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryBatchItemDTO.java

@@ -0,0 +1,4 @@
+package com.fs.jd.dto;
+
+public class DeliveryBatchItemDTO {
+}

+ 4 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryBoxDTO.java

@@ -0,0 +1,4 @@
+package com.fs.jd.dto;
+
+public class DeliveryBoxDTO {
+}

+ 43 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryItemDTO.java

@@ -0,0 +1,43 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class DeliveryItemDTO {
+
+    /**
+     * 开放平台事业部商品编号,长度:16字符
+     */
+    private String goodsNo;
+
+    /**
+     * 商品金额,单位:元,精确到4位小数,整数最多13位
+     */
+    private Double price;
+
+    /**
+     * 下单数量,长度:1-11字符
+     */
+    private Integer planQuantity;
+
+
+    /**
+     * 实际出库数量,长度:1-11字符
+     */
+    private Integer realQuantity;
+
+    /**
+     * 商家商品编码,长度:1-50字符
+     */
+    private String erpGoodsNo;
+
+    /**
+     * 行号,长度:1-50字符
+     */
+    private String orderLine;
+
+    /**
+     * 仓实际出库批属性,当商品是批次管理的商品时会返回
+     */
+    private BatchInfosDTO batchInfos;
+}

+ 36 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryPackageDTO.java

@@ -0,0 +1,36 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DeliveryPackageDTO {
+
+    /**
+     * 包裹号
+     * 长度:1-200字符
+     */
+    private String packageNo;
+
+    /**
+     * 包裹重量,单位:Kg,精确到小数后四位
+     */
+    private Double packageWeight;
+
+    /**
+     * 包裹箱唯一码,多个逗号相隔
+     * 无长度限制
+     */
+    private String packageUniqueCodes;
+
+    /**
+     * 商品明细列表
+     */
+    private List<PackageItemDTO> packageItemList;
+
+    /**
+     * 耗材明细列表
+     */
+    private List<PackageMaterialDTO> packageMaterialList;
+}

+ 42 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryProductInfoDTO.java

@@ -0,0 +1,42 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class DeliveryProductInfoDTO {
+    /**
+     * 产品编码
+     * 长度:1-10字符
+     */
+    private String productCode;
+
+    /**
+     * 产品名称
+     * 长度:1-20字符
+     */
+    private String productName;
+
+    /**
+     * 计费模式
+     * 长度:1-20字符
+     */
+    private String billingMode;
+
+    /**
+     * 计费模式名称
+     * 长度:1-50字符
+     */
+    private String billingModeName;
+
+    /**
+     * 产品分类编码
+     * 长度无限制
+     */
+    private String categoryCode;
+
+    /**
+     * 产品分类名称
+     * 长度:1-50字符
+     */
+    private String categoryName;
+}

+ 4 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryRejectItemDTO.java

@@ -0,0 +1,4 @@
+package com.fs.jd.dto;
+
+public class DeliveryRejectItemDTO {
+}

+ 26 - 0
fs-service/src/main/java/com/fs/jd/dto/DeliveryStatusDTO.java

@@ -0,0 +1,26 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class DeliveryStatusDTO {
+    /**
+     * 出库单状态编号,状态枚举详见:https://cloud.jdl.com/#/open-business-document/access-guide/367/54597,长度:1-10字符
+     */
+    private Integer statusCode;
+
+    /**
+     * 出库单状态名称,状态名称详见:https://cloud.jdl.com/#/open-business-document/access-guide/367/54597,长度:1-10字符
+     */
+    private String statusName;
+
+    /**
+     * 操作时间,格式:yyyy-MM-dd HH:mm:ss,长度:19字符
+     */
+    private String operateTime;
+
+    /**
+     * 操作人,长度:1-200字符
+     */
+    private String operateUser;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/jd/dto/GoodsSerialNoQueryResultDTO.java

@@ -0,0 +1,16 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class GoodsSerialNoQueryResultDTO {
+    /**
+     * 开放平台商品编码
+     */
+    private String goodsNo;
+
+    /**
+     * 序列号
+     */
+    private String serialNo;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/jd/dto/IndustryAttributesDTO.java

@@ -0,0 +1,9 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class IndustryAttributesDTO {
+    /** 医药冷链行业属性 */
+    private ColdChainDTO coldChain;
+}

+ 36 - 0
fs-service/src/main/java/com/fs/jd/dto/InvoiceInfoDTO.java

@@ -0,0 +1,36 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class InvoiceInfoDTO {
+    /** 发票抬头,无长度限制 */
+    private String invoiceTitle;
+
+    /** 发票内容,无长度限制 */
+    private String invoiceContent;
+
+    /** 是否需要开具发票,枚举:0,1:需要开发票,2,3:不需要开发票,长度:1字符 */
+    private String invoiceState;
+
+    /** 发票类型 ,枚举:1:普通发票, 2:电子发票,3:增值税发票,长度:1字符 */
+    private String invoiceType;
+
+    /** 发票号,无长度限制 */
+    private String invoiceNo;
+
+    /** 购方税号(税务识别号),无长度限制 */
+    private String invoiceTax;
+
+    /** 开户银行名称,无长度限制 */
+    private String bankName;
+
+    /** 开户银行账户,无长度限制 */
+    private String bankAccount;
+
+    /** 购货单位地址,无长度限制 */
+    private String address;
+
+    /** 购货单位电话,无长度限制 */
+    private String phone;
+}

+ 30 - 0
fs-service/src/main/java/com/fs/jd/dto/OrderCancelRequestDTO.java

@@ -0,0 +1,30 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class OrderCancelRequestDTO {
+
+    /**
+     * 货主编码,当仓储系统单据编码为空时必填
+     */
+    private String ownerNo;
+
+    /**
+     * 商家单号
+     */
+    private String  erpOrderNo;
+
+    /**
+     * 仓储系统单据编码
+     */
+    private String orderNo;
+    /**
+     * 单据类型(CGRK=采购入库单;XSCK=销售出库单;THRK=退货入库;TGCK=退供出库单;ZKTZ=在库调整单;ZTJG=组套加工单;BFCK=报废出库单),长度:1-50字符
+     */
+    private String orderType;
+    /**
+     * pin鉴权,长度:1-50字符
+     */
+    private String pin;
+}

+ 12 - 0
fs-service/src/main/java/com/fs/jd/dto/OrderCancelResponseDTO.java

@@ -0,0 +1,12 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OrderCancelResponseDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String orderNo;
+}

+ 17 - 0
fs-service/src/main/java/com/fs/jd/dto/PackageItemDTO.java

@@ -0,0 +1,17 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class PackageItemDTO {
+    /**
+     * 开放平台商品编码,长度:16字符
+     */
+    private String goodsNo;
+
+    /**
+     * 商品数量,长度:1-11字符
+     */
+    private Integer quantity;
+
+}

+ 15 - 0
fs-service/src/main/java/com/fs/jd/dto/PackageMaterialDTO.java

@@ -0,0 +1,15 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class PackageMaterialDTO {
+    /**
+     * 耗材名称,长度:1-100字符
+     */
+    private String materialName;
+    /**
+     *型号,长度:1-11字符
+     */
+    private String model;
+}

+ 18 - 0
fs-service/src/main/java/com/fs/jd/dto/ProductAttrsDTO.java

@@ -0,0 +1,18 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductAttrsDTO {
+    /** 预约日期 */
+    private String calendar;
+
+    /** 派送开始时间,格式:HH:mm */
+    private String receiveStartTime;
+
+    /** 派送结束时间,格式:HH:mm */
+    private String receiveEndTime;
+
+    /** 派送类型,定时派送=timingDelivery */
+    private String deliveryType;
+}

+ 12 - 0
fs-service/src/main/java/com/fs/jd/dto/ProductDTO.java

@@ -0,0 +1,12 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductDTO {
+    /** 增值服务编码, 枚举:预约派送增值服务=ed-a-0053 */
+    private String productCode;
+
+    /** 增值服务参数 */
+    private ProductAttrsDTO productAttrs;
+}

+ 45 - 0
fs-service/src/main/java/com/fs/jd/dto/ReceiverInfoDTO.java

@@ -0,0 +1,45 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ReceiverInfoDTO {
+    /** 收货人姓名,长度:1-20字符 */
+    private String name;
+
+    /** 收货人手机(收货人电话、手机至少有一个不为空),长度:1-30字符 */
+    private String mobile;
+
+    /** 收货人电话(收货人电话、手机至少有一个不为空),长度:1-30字符 */
+    private String phone;
+
+    /** 收货人邮箱,长度:1-100字符 */
+    private String email;
+
+    /** 收货人邮编,长度:1-20字符 */
+    private String postCode;
+
+    /** 收件人省,长度:1-100字符 */
+    private String province;
+
+    /** 收件人市,长度:1-100字符 */
+    private String city;
+
+    /** 收件人县,长度:1-100字符 */
+    private String county;
+
+    /** 收件人镇,长度:1-100字符 */
+    private String town;
+
+    /** 收件人地址,当customerNo为空时必填,长度:1-100字符 */
+    private String detailAddress;
+
+    /** 是否地址解析,枚举 0:不解析、1:通过客户门店编码解析四级地址、2:通过收件人地址解析四级地址,长度:1字符 */
+    private Integer addressAnalysis;
+
+    /** 客户门店编码,开启地址解析时(addrAnalysis=1)必填,长度:1-100字符 */
+    private String customerNo;
+
+    /** 收件人公司 长度:1-50字符 */
+    private String receiveCompany;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/jd/dto/RelatedOrdersDTO.java

@@ -0,0 +1,9 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class RelatedOrdersDTO {
+    /** 提货单号 ,长度 1-100字符 */
+    private String relationNo;
+}

+ 51 - 0
fs-service/src/main/java/com/fs/jd/dto/ShipmentInfoDTO.java

@@ -0,0 +1,51 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class ShipmentInfoDTO {
+    /** 三方运单号,长度:1-200字符 */
+    private String thirdWaybillNo;
+
+    /** 顺丰E标,长度:1-50字符 */
+    private String packageMark;
+
+    /** 业务类型,长度:1-50字符 */
+    private String businessType;
+
+    /** 目的地代码,长度:1-50字符 */
+    private String destinationCode;
+
+    /** 目的地名称,长度:1-200字符 */
+    private String destinationName;
+
+    /** 发件网点代码,长度:1-50字符 */
+    private String sendWebsiteCode;
+
+    /** 发件网点名称,长度:1-200字符 */
+    private String sendWebsiteName;
+
+    /** 寄件方式,三方承运使用,枚举值(1.自寄2.其它),长度:1-4字符 */
+    private Integer sendMode;
+
+    /** 收件方式,三方承运使用,枚举值(1.自寄2.其它),长度:1-4字符 */
+    private Integer receiveMode;
+
+    /** 预约配送时间,三方承运使用,格式YYYY-MM-DD HH:MM:SS,长度:1-50字符 */
+    private String appointDeliveryTime;
+
+    /** 运费支付方式,三方承运使用,枚举值:(1.寄方付2.收方付3.寄付月结),长度:1-4字符 */
+    private Integer payment;
+
+    /** 月结账号,三方承运使用,长度:1-50字符 */
+    private String monthlyAccount;
+
+    /** 寄托物,三方承运使用,长度:1-100字符 */
+    private String shipment;
+
+    /** 模板备注,三方承运使用,长度:1-500字符 */
+    private String sellerRemark;
+
+    /** 大头笔,三方承运使用,长度:1-500字符 */
+    private String markDestination;
+}

+ 97 - 0
fs-service/src/main/java/com/fs/jd/dto/SoCreateOrderRequestDTO.java

@@ -0,0 +1,97 @@
+package com.fs.jd.dto;
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class SoCreateOrderRequestDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /** 来源编号,固定填写:ISV0020008045424 */
+    private String sourceNo;
+
+    /** 商家单号,事业部下需保证唯一,长度:1-125字符 */
+    private String erpDeliveryNo;
+
+    /** 订单类型,枚举:1:B2C订单, 2:B2B订单,不指定默认=1,长度:1字符 */
+    private String orderType;
+
+    /** 库房编号,事业部开启寻源拆分服务可不填;否则必填,长度:9字符 */
+    private String warehouseNo;
+
+    /** 商家仓编码,商家仓编码与warehouseNo二选一,长度:1-50字符 */
+    private String erpWarehouseNo;
+
+    /** 调拨入库库房,当调拨业务场景下使用,长度:9字符 */
+    private String intoWarehouseNo;
+
+    /** 订单标记位,不同标记位代表不同服务,首位为1代表货到付款,长度:1-500字符 */
+    private String orderMark;
+
+    /** 逻辑库存因子,长度:1-50字符 */
+    private String logicalInventoryFactor;
+
+    /** 客户留言,长度:1-500字符 */
+    private String customerRemark;
+
+    /** 商家备注,长度:1-200字符 */
+    private String erpRemark;
+
+    /** 外部订单类型,长度:1-20字符 */
+    private String erpOrderType;
+
+    /** 外部订单类型名称,长度:1-20字符 */
+    private String erpOrderTypeName;
+
+    /** 京东pin,长度:1-50字符 */
+    private String pin;
+
+    /** 渠道信息 */
+    private ChannelInfoDTO channelInfo;
+
+    /** 客户信息 */
+    private CustomerInfoDTO customerInfo;
+
+    /** 收件人信息 */
+    private ReceiverInfoDTO receiverInfo;
+
+    /** 承运信息 */
+    private CarrierInfoDTO carrierInfo;
+
+    /** 增值服务信息 */
+    private AddServicesDTO addServices;
+
+    /** 行业属性信息 */
+    private IndustryAttributesDTO industryAttributes;
+
+    /** 库房操作规则 */
+    private WarehouseOperationRuleDTO warehouseOperationRule;
+
+    /** 发票信息 */
+    private InvoiceInfoDTO invoiceInfo;
+
+    /** 商品明细信息 */
+    private List<CargoInfoDTO> cargoInfos;
+    /** 扩展信息 */
+    private Map<String, String> extendProps;
+    /** 相关扩展信息 */
+    private Map<String, String> printExtendInfo;
+
+    /** 关联单号 */
+    private RelatedOrdersDTO relatedOrders;
+
+    /** 商家关联单号,用于商家单号在与其它业务单号有关联时使用。字段的长度不超过50 */
+    private String erpRelatedOrderNo;
+
+
+    /** 订单金额(单位:元,限制2位小数,字段长度10) */
+    private Double orderPrice;
+
+    /** 即时履约扩展字段 */
+    private Map<String, Object> instantFulfillmentExtendProps;
+
+}

+ 23 - 0
fs-service/src/main/java/com/fs/jd/dto/SoCreateResponseDTO.java

@@ -0,0 +1,23 @@
+package com.fs.jd.dto;
+
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class SoCreateResponseDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 京东开放平台销售出库单单号
+     */
+    private String deliveryNo;
+
+    /**
+     * 商家单号
+     */
+    private String erpDeliveryNo;
+}

+ 111 - 0
fs-service/src/main/java/com/fs/jd/dto/SoQueryRequestDTO.java

@@ -0,0 +1,111 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class SoQueryRequestDTO {
+    /**
+     * 开放平台出库单号
+     * 与erpDeliveryNo、salesPlatformDeliveryNo三选一必填
+     * 长度:1-50字符
+     */
+    private String deliveryNo;
+
+    /**
+     * 销售平台单号
+     * 与deliveryNo、erpDeliveryNo三选一必填
+     * 长度:200字符
+     */
+    private String salesPlatformDeliveryNo;
+
+    /**
+     * 商家出库单号
+     * 与deliveryNo、salesPlatformDeliveryNo三选一必填
+     * 长度:1-125字符
+     */
+    private String erpDeliveryNo;
+
+    /**
+     * 开放平台事业部编码(货主编码)
+     * 商家与京东物流签约后生成的商家的唯一编码
+     * 如填写erpDeliveryNo时,必填
+     * 格式:EBU开头,长度:1-50字符
+     */
+    private String ownerNo;
+
+    /**
+     * 是否查询销售出库明细
+     * 0:否;1:是,默认=1
+     * 长度:1字符
+     */
+    private Integer deliveryItemFlag;
+
+    /**
+     * 是否查询销售出库包裹信息
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryPackageFlag;
+
+    /**
+     * 是否查询销售出库单状态流水明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryStatusFlag;
+
+    /**
+     * 是否查询销售出库批次明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryBatchItemFlag;
+
+    /**
+     * 是否查询销售出库产品明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryProductInfoFlag;
+
+    /**
+     * 是否查询销售出库拒收明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryRejectItemFlag;
+
+    /**
+     * 是否查询销售出库拒收图片明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryRejectPictureUrlFlag;
+
+    /**
+     * 是否查询销售出库箱明细
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliveryBoxFlag;
+
+    /**
+     * 是否查询销售出库序列号信息
+     * 0:否;1:是,默认=0
+     * 长度:1字符
+     */
+    private Integer deliverySerialNoFlag;
+
+    /**
+     * 京东pin
+     * 必填
+     * 长度:1-50字符
+     */
+    private String pin;
+
+    /**
+     * 地址类型
+     * 0:京标四级地址 1:国标四级地址,不传默认0
+     */
+    private Integer addressType;
+}

+ 193 - 0
fs-service/src/main/java/com/fs/jd/dto/SoQueryResponseDTO.java

@@ -0,0 +1,193 @@
+package com.fs.jd.dto;
+
+import com.fs.erp.dto.AfterSaleResponseDTO;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SoQueryResponseDTO {
+    /**
+     * 开放平台销售出库单单号
+     * 长度:1-50字符
+     */
+    private String deliveryNo;
+
+    /**
+     * 商家单号,事业部下需保证唯一
+     * 长度:1-125字符
+     */
+    private String erpDeliveryNo;
+
+    /**
+     * 客户信息,此节点一定返回
+     */
+    private CustomerInfoDTO customerInfo;
+
+    /**
+     * 库房编号
+     * 长度:9字符
+     */
+    private String warehouseNo;
+
+    /**
+     * 商家仓编码
+     * 长度:1-50字符
+     */
+    private String erpWarehouseNo;
+
+    /**
+     * 承运商信息,此节点一定返回
+     */
+    private CarrierInfoDTO carrierInfo;
+
+    /**
+     * 渠道信息,此节点一定返回
+     */
+    private ChannelInfoDTO channelInfo;
+
+    /**
+     * 收货信息,此节点一定返回
+     */
+    private ReceiverInfoDTO receiverInfo;
+
+    /**
+     * 增值服务信息,当代收货款订单才返回
+     */
+    private AddServicesDTO addServices;
+
+    /**
+     * 商家留言
+     * 长度:1-500字符
+     */
+    private String customerRemark;
+
+    /**
+     * 订单标记位
+     * 长度:1-500字符
+     */
+    private String orderMark;
+
+    /**
+     * 退货信息,如下单店铺在京东店铺管理中维护了售后信息,则返回
+     */
+    private AfterSaleResponseDTO afterSalesInfo;
+
+    /**
+     * 下单人(操作人)
+     * 长度:1-100字符
+     */
+    private String pinAccount;
+
+    /**
+     * 是否拆单(1:已拆单;0:未拆单)
+     * 长度:1字符
+     */
+    private String isSplit;
+
+    /**
+     * 出库单当前状态
+     * 状态枚举详见:https://cloud.jdl.com/#/open-business-document/access-guide/367/54597
+     * 长度:1-10字符
+     */
+    private String status;
+
+    /**
+     * 子单订单号集合,多个以逗号隔开
+     * 无长度限制
+     */
+    private String splitDeliveryNos;
+
+    /**
+     * 配送方式
+     * 长度:1字符
+     */
+    private String transType;
+
+    /**
+     * 预计送达时间
+     * 格式:yyyy-MM-dd HH:mm:ss
+     * 长度:19字符
+     */
+    private String expectDeliveryDate;
+
+    /**
+     * 订单重量,单位:Kg,精确到小数点后3位
+     * 长度:1-20字符
+     */
+    private String orderWeight;
+
+    /**
+     * 送仓类型,枚举:1:送京仓;2:送外仓
+     * 长度:1字符
+     */
+    private String warehouseType;
+
+    /**
+     * 逻辑因子
+     * 长度:1-50字符
+     */
+    private String logicalInventoryFactor;
+
+    /**
+     * 是否签署免赔函
+     * 长度:1字符
+     */
+    private String isSignDisclaimer;
+
+    /**
+     * 出库商品明细列表,此节点一定返回
+     * 如果订单未出库,则不会返回实际出库数量realQuantity字段
+     */
+    private List<DeliveryItemDTO> deliveryItemList;
+
+    /**
+     * 包裹数量,无长度限制
+     */
+    private Integer packCount;
+
+    /**
+     * 发货包裹明细列表,当仓进行包裹采集后才会返回
+     */
+    private List<DeliveryPackageDTO> deliveryPackageList;
+
+    /**
+     * 状态流水列表,此节点一定返回
+     */
+    private List<DeliveryStatusDTO> deliveryStatusList;
+
+    /**
+     * 批次出库商品明细列表,当商品是批次管理的商品时会返回
+     */
+    private List<DeliveryBatchItemDTO> deliveryBatchItemList;
+
+    /**
+     * 产品信息列表,此节点一定返回
+     */
+    private List<DeliveryProductInfoDTO> deliveryProductInfoList;
+
+    /**
+     * 医药拒收明细列表,当医药订单且单据状态为"部分签收、整单签收"时返回
+     */
+    private List<DeliveryRejectItemDTO> deliveryRejectItemList;
+
+    /**
+     * 拒收图片URL列表,当医药订单且单据状态为"部分签收、整单签收"时返回
+     */
+    private List<String> deliveryRejectPictureUrlList;
+
+    /**
+     * 总箱数,无长度限制
+     */
+    private Integer boxQuantity;
+
+    /**
+     * 箱实体列表,当按箱出库时会返回
+     */
+    private List<DeliveryBoxDTO> deliveryBoxList;
+
+    /**
+     * 出库序列号信息
+     */
+    private List<GoodsSerialNoQueryResultDTO> serialNoList;
+}

+ 36 - 0
fs-service/src/main/java/com/fs/jd/dto/WarehouseOperationRuleDTO.java

@@ -0,0 +1,36 @@
+package com.fs.jd.dto;
+
+import lombok.Data;
+
+@Data
+public class WarehouseOperationRuleDTO {
+    /** 订单优先级,特殊商家使用,可填写1-9的整数,长度: 1字符 */
+    private String orderPriority;
+
+    /** 越库优先级,长度:1字符 */
+    private String crossDockPriority;
+
+    /** 超区检查,枚举:1:需要超区检查; 其他值:不需要超区检查,长度:1字符 */
+    private String checkDelivery;
+
+    /** 商家通过京东获取三方运单号,特殊场景使用,枚举:1:是,0:否长度:1字符 */
+    private String inDependent;
+
+    /** 运输方式是否加急,枚举:1:加急;其他值不加急,长度:1字符 */
+    private Integer urgency;
+
+    /** WMS出库前等待指令,枚举:0:wms直接出库,1:wms出库前等待指令运单,长度:1字符 */
+    private Integer deliveryBeforeCommand;
+
+    /** 商家指定的产品编码,长度:1-20字符 */
+    private String deliveryProductCode;
+
+    /** 商家包装类型编码 长度:1-30字符 */
+    private String erpPackTypeNo;
+
+    /** 激活卡业务 枚举:1:是,0:否长度:1字符 */
+    private String activationService;
+
+    /** 1:支持自提码校验,0:不支持自提码校验;默认0,长度:1字符 */
+    private String selfPickupCode;
+}

+ 18 - 0
fs-service/src/main/java/com/fs/jd/http/IJdHttpService.java

@@ -0,0 +1,18 @@
+package com.fs.jd.http;
+
+import com.fs.jd.dto.*;
+
+/**
+ * 京东云仓 服务类
+ */
+public interface IJdHttpService {
+
+    //销售出库单创建
+    SoCreateResponseDTO deliveryCreate(SoCreateOrderRequestDTO dto);
+
+    //订单取消
+    OrderCancelResponseDTO orderCancel(OrderCancelRequestDTO dto);
+
+    //查询单个销售出库单详情
+    SoQueryResponseDTO queryDelivery(SoQueryRequestDTO dto);
+}

+ 220 - 0
fs-service/src/main/java/com/fs/jd/http/JdHttpServiceImpl.java

@@ -0,0 +1,220 @@
+package com.fs.jd.http;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.PropertyNamingStrategy;
+import com.alibaba.fastjson.TypeReference;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.fs.common.utils.DateUtils;
+import com.fs.erp.dto.CommonResponse;
+import com.fs.erp.dto.ErpOrderResponseDTO;
+import com.fs.erp.utils.SignUtil;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.utils.ConfigUtil;
+import com.fs.jd.dto.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+import static com.fs.common.core.text.CharsetKit.UTF_8;
+
+@Slf4j
+@Service
+public class JdHttpServiceImpl implements IJdHttpService{
+
+    //正式
+    private static final String BASE_URL = "https://api.jdl.com";
+    private static final String HEX_CHARACTERS = "0123456789ABCDEF";
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    private static final String DELIVERY_CREATE_METHOD = "/integratedsupplychain/order/delivery/create/v1";
+    private static final String ORDER_CANCEL_METHOD = "/integratedsupplychain/order/cancel/v1";
+    private static final String QUERY_DELIVERY_METHOD = "/integratedsupplychain/order/delivery/query/v1";
+
+    @Autowired
+    private ConfigUtil configUtil;
+
+    @Override
+    public SoCreateResponseDTO deliveryCreate(SoCreateOrderRequestDTO dto) {
+        String method = DELIVERY_CREATE_METHOD;
+        String url = BASE_URL + method;
+        log.info("京东-销售出库单创建 - URL: {}, 请求体: {}", url, JSON.toJSONString(dto));
+        HttpResponse response;
+        try {
+            response = executeJsonPost(url, Arrays.asList(dto), method);
+        } catch (GeneralSecurityException | UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        return parseResponse(response, new TypeReference<CommonResponse<SoCreateResponseDTO>>() {});
+    }
+
+    @Override
+    public OrderCancelResponseDTO orderCancel(OrderCancelRequestDTO dto) {
+        String method = ORDER_CANCEL_METHOD;
+        String url = BASE_URL + method;
+        log.info("京东-销售出库单取消 - URL: {}, 请求体: {}", url, JSON.toJSONString(dto));
+        HttpResponse response;
+        try {
+            response = executeJsonPost(url, Arrays.asList(dto), method);
+        } catch (GeneralSecurityException | UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        return parseResponse(response, new TypeReference<CommonResponse<OrderCancelResponseDTO>>() {});
+    }
+
+    @Override
+    public SoQueryResponseDTO queryDelivery(SoQueryRequestDTO dto) {
+        String method = QUERY_DELIVERY_METHOD;
+        String url = BASE_URL + method;
+        log.info("京东-销售出库单查询 - URL: {}, 请求体: {}", url, JSON.toJSONString(dto));
+        HttpResponse response;
+        try {
+            response = executeJsonPost(url, Arrays.asList(dto), method);
+        } catch (GeneralSecurityException | UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        return parseResponse(response, new TypeReference<CommonResponse<SoQueryResponseDTO>>() {});
+    }
+
+    /**
+     * 执行JSON格式的POST请求
+     *
+     * @param url 请求URL
+     * @param dto 请求对象
+     * @return HttpResponse响应
+     */
+    private HttpResponse executeJsonPost(String url, Object dto,String method) throws GeneralSecurityException, UnsupportedEncodingException {
+        String appKey = "38b123c8d2084beabe21be14549a9749";
+        String appSecret = "b088b97cc2924bfc9ec5d09310d17f73";
+        String accessToken = "144d2076bf7c4bcdaf1a2c0452eeb021";
+//        FsSysConfig sysConfig = configUtil.getSysConfig();
+//
+//        String appKey = sysConfig.getJdAppKey();
+//        String appSecret = sysConfig.getJdAppSecret();
+//        String accessToken = sysConfig.getJdAccessToken();
+
+        String algorithm = "md5-salt";
+        String domain = "IntegratedSupplyChain";
+        String timestamp = DATE_TIME_FORMATTER.format(LocalDateTime.now());
+        String jsonBody = JSON.toJSONString(dto);
+
+        log.info("timestamp: {}, jsonBody: {}", timestamp, jsonBody);
+
+        //生成签名字符拼接
+        String content = String.join("", new String[]{
+                appSecret,
+                "access_token", accessToken,
+                "app_key", appKey,
+                "method", method,
+                "param_json", jsonBody,
+                "timestamp", timestamp,
+                "v", "2.0",
+                appSecret});
+        String sign = sign(algorithm, content.getBytes(StandardCharsets.UTF_8), appSecret.getBytes(StandardCharsets.UTF_8)).toLowerCase();
+        Map<String,String> query  = new HashMap<>();
+        query.put("LOP-DN", domain);
+        query.put("app_key", appKey);
+        query.put("access_token", accessToken);
+        query.put("timestamp", timestamp);
+        query.put("v", "2.0");
+        query.put("sign", URLEncoder.encode(sign, StandardCharsets.UTF_8.toString()));
+        String uri = url + "?" + httpBuildQuery(query);
+        Map<String, String> headers = MapUtil.builder(new HashMap<String, String>())
+                .put("Content-Type", "application/json;charset=utf-8")
+                .build();
+
+
+        log.debug("发送JSON请求 - URL: {}, Headers: {}, Body: {}", uri, headers, jsonBody);
+
+        return HttpRequest.post(uri)
+                .headerMap(headers, true)
+                .body(jsonBody)
+                .execute();
+    }
+
+    /**
+     * 解析带有泛型的HTTP响应
+     *
+     * @param response HTTP响应
+     * @param typeReference 响应类型引用
+     * @param <T> 期望的响应数据类型
+     * @return 解析后的数据
+     */
+    private <T> T parseResponse(HttpResponse response, TypeReference<CommonResponse<T>> typeReference) {
+        String body = response.body();
+        log.debug("解析响应体: {}", body);
+
+
+        CommonResponse<T> commonResponse = JSON.parseObject(body, typeReference);
+
+        if (!Integer.valueOf(1000).equals(commonResponse.getCode())) {
+            log.error("API请求失败 - 错误码: {}, 错误信息: {}", commonResponse.getCode(), commonResponse.getMessage());
+            throw new RuntimeException("请求接口失败!原因:" + commonResponse.getMessage());
+        }
+        log.info("response: {}", commonResponse);
+        T result = commonResponse.getData();
+        log.info("API请求成功 - 结果: {}", JSON.toJSONString(result));
+        return result;
+    }
+
+    private static String httpBuildQuery(Map<String, String> query) throws UnsupportedEncodingException {
+        StringBuilder stringBuilder = new StringBuilder();
+        boolean first = true;
+        for (Map.Entry<String, String> entry : query.entrySet()) {
+            if (!first) {
+                stringBuilder.append("&");
+            } else {
+                first = false;
+            }
+            stringBuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), UTF_8));
+        }
+        return stringBuilder.toString();
+    }
+
+    private  String sign(String algorithm, byte[] data, byte[] secret) throws GeneralSecurityException {
+        if (Objects.equals(algorithm, "md5-salt")) {
+            return bytesToHex(MessageDigest.getInstance("md5").digest(data));
+        } else if (Objects.equals(algorithm, "HMacMD5")) {
+            Mac mac = Mac.getInstance(algorithm);
+            mac.init(new SecretKeySpec(secret, algorithm));
+            return Base64.getEncoder().encodeToString(mac.doFinal(data));
+        } else if (Objects.equals(algorithm, "HMacSHA1")) {
+            Mac mac = Mac.getInstance(algorithm);
+            mac.init(new SecretKeySpec(secret, algorithm));
+            return Base64.getEncoder().encodeToString(mac.doFinal(data));
+        } else if (Objects.equals(algorithm, "HMacSHA256")) {
+            Mac mac = Mac.getInstance(algorithm);
+            mac.init(new SecretKeySpec(secret, algorithm));
+            return Base64.getEncoder().encodeToString(mac.doFinal(data));
+        } else if (Objects.equals(algorithm, "HMacSHA512")) {
+            Mac mac = Mac.getInstance(algorithm);
+            mac.init(new SecretKeySpec(secret, algorithm));
+            return Base64.getEncoder().encodeToString(mac.doFinal(data));
+        }
+        throw new GeneralSecurityException("Algorithm " + algorithm + " not supported yet");
+    }
+
+    private static String bytesToHex(byte[] bytes) {
+        StringBuilder stringBuilder = new StringBuilder(bytes.length * 2);
+        for (byte b : bytes) {
+            stringBuilder.append(HEX_CHARACTERS.charAt((b >>> 4) & 0x0F));
+            stringBuilder.append(HEX_CHARACTERS.charAt(b & 0x0F));
+        }
+        return stringBuilder.toString();
+    }
+}

+ 5 - 1
fs-service/src/main/resources/mapper/app/FsAppRoleMapper.xml

@@ -28,10 +28,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="roleStoreProductIds"    column="role_store_product_ids"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
+        <result property="roleVipLevel"    column="role_vip_level"    />
     </resultMap>
 
     <sql id="selectFsAppRoleVo">
-        select id, role_name, role_type, register_reward_type, register_red_packet, register_product_id, register_product_type, register_integral, course_day, course_reward_type, course_red_packet, course_integral, course_product_type, course_product_id, course_need_day, course_reward_rule_type, course_reward_rule, role_level, role_tags, role_package_product_ids, role_store_product_ids, create_time, update_time from fs_app_role
+        select id, role_name, role_type, register_reward_type, register_red_packet, register_product_id, register_product_type, register_integral, course_day, course_reward_type, course_red_packet, course_integral, course_product_type, course_product_id, course_need_day, course_reward_rule_type, course_reward_rule, role_level, role_tags, role_package_product_ids, role_store_product_ids, create_time, update_time,role_vip_level from fs_app_role
     </sql>
 
     <select id="selectFsAppRoleList" parameterType="FsAppRole" resultMap="FsAppRoleResult">
@@ -183,6 +184,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="roleStoreProductIds != null">role_store_product_ids,</if>
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
+            <if test="roleVipLevel != null">role_vip_level,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="roleName != null">#{roleName},</if>
@@ -207,6 +209,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="roleStoreProductIds != null">#{roleStoreProductIds},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
+            <if test="roleVipLevel != null">#{roleVipLevel},</if>
          </trim>
     </insert>
 
@@ -235,6 +238,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="roleStoreProductIds != null">role_store_product_ids = #{roleStoreProductIds},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="roleVipLevel != null">role_vip_level = #{roleVipLevel},</if>
         </trim>
         where id = #{id}
     </update>

+ 1 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -729,6 +729,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="appRoles != null">app_roles = #{appRoles},</if>
             <if test="appRewardsViewedDays != null">app_rewards_viewed_days = #{appRewardsViewedDays},</if>
             <if test="userSource != null">user_source = #{userSource},</if>
+            <if test="roleVipLevel != null">role_vip_level = #{roleVipLevel},</if>
         </trim>
         where user_id = #{userId}
     </update>