Browse Source

中台将商品添加到选品后,自动同步商品到企云商城(云悦生活的商城)

zhangwl 3 weeks ago
parent
commit
7a59c2de6a
24 changed files with 1582 additions and 370 deletions
  1. 18 0
      pom.xml
  2. 18 0
      src/main/java/zs/payment/config/MybatisPlusConfig.java
  3. 49 359
      src/main/java/zs/payment/controller/YxSupplyChannelManualController.java
  4. 1 0
      src/main/java/zs/payment/dto/OrderDetailDTO.java
  5. 1 1
      src/main/java/zs/payment/dto/SkuDTO.java
  6. 3 7
      src/main/java/zs/payment/entity/OrderCallback.java
  7. 70 0
      src/main/java/zs/payment/entity/mysql/ImsEweiShopCategory.java
  8. 509 0
      src/main/java/zs/payment/entity/mysql/ImsEweiShopGoods.java
  9. 10 0
      src/main/java/zs/payment/enums/ProductSupplyRedis.java
  10. 9 0
      src/main/java/zs/payment/mapper/ImsEweiShopCategoryMapper.java
  11. 9 0
      src/main/java/zs/payment/mapper/ImsEweiShopGoodsMapper.java
  12. 213 0
      src/main/java/zs/payment/messages/KafkaConsumer.java
  13. 28 0
      src/main/java/zs/payment/messages/KafkaProducer.java
  14. 7 0
      src/main/java/zs/payment/service/Imseweishopgoods/ImsEweiShopGoodsService.java
  15. 17 0
      src/main/java/zs/payment/service/Imseweishopgoods/impl/ImsEweiShopGoodsServiceImpl.java
  16. 9 0
      src/main/java/zs/payment/service/imseweishopcategory/ImsEweiShopCategoryService.java
  17. 33 0
      src/main/java/zs/payment/service/imseweishopcategory/impl/ImsEweiShopCategoryServiceImpl.java
  18. 1 1
      src/main/java/zs/payment/service/OrdersService.java
  19. 2 2
      src/main/java/zs/payment/service/impl/OrdersServiceImpl.java
  20. 33 0
      src/main/java/zs/payment/service/paysupply/PaySupplyService.java
  21. 383 0
      src/main/java/zs/payment/service/paysupply/impl/PaySupplyServiceImpl.java
  22. 4 0
      src/main/java/zs/payment/utils/RedisUtils.java
  23. 112 0
      src/main/java/zs/payment/utils/TimeUtils.java
  24. 43 0
      src/main/resources/application-pro.yml

+ 18 - 0
pom.xml

@@ -32,6 +32,11 @@
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
 
+        <!-- Kafka 依赖(关键) -->
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+        </dependency>
 
 
         <!-- commons -->
@@ -100,6 +105,19 @@
             <artifactId>spring-cloud-starter-config</artifactId>
         </dependency>
 
+        <!-- mysql -->
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>${mysql.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis.version}</version>
+        </dependency>
 
 
 

+ 18 - 0
src/main/java/zs/payment/config/MybatisPlusConfig.java

@@ -0,0 +1,18 @@
+package zs.payment.config;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@EnableTransactionManagement
+@Configuration
+public class MybatisPlusConfig {
+    /**
+     * mybatis-plus分页插件
+     */
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
+}

+ 49 - 359
src/main/java/zs/payment/controller/YxSupplyChannelManualController.java

@@ -2,8 +2,8 @@ package zs.payment.controller;
 
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.util.ObjectUtils;
+
+
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,20 +12,19 @@ import com.alibaba.fastjson.JSONObject;
 import zs.payment.dao.OrderCallbackDao;
 import zs.payment.entity.OrderCallback;
 import zs.payment.enums.CallbackMessageType;
+import zs.payment.messages.KafkaProducer;
 import zs.payment.req.*;
-import zs.payment.entity.Orders;
+
 import zs.payment.req.aftersales.AfterSalesOrderReq;
 import zs.payment.req.aftersales.AfterSalesOrderTypeReq;
 import zs.payment.req.storage.StoragePageReq;
 import zs.payment.resp.Result;
-import zs.payment.service.OrdersService;
-import zs.payment.utils.HttpUtil;
-import zs.payment.utils.RedisUtils;
-import zs.payment.dto.OrderDetailDTO;
+
+import zs.payment.service.paysupply.PaySupplyService;
 
 import javax.validation.Valid;
 import java.util.HashMap;
-import java.util.List;
+
 import java.util.Map;
 
 /**
@@ -36,313 +35,69 @@ import java.util.Map;
 @RequestMapping("/supply")
 public class YxSupplyChannelManualController {
 
-    @Value("${supply.demain}")
-    private String prefixUrl;
-
-    @Value("${supply.appKey}")
-    private String appKey;
-    @Value("${supply.appSecret}")
-    private String appSecret;
 
     @Autowired
-    private RedisUtils redisUtils;
+    private OrderCallbackDao callbackDao;
 
     @Autowired
-    private OrdersService ordersService;
+    private PaySupplyService paySupplyService;
 
     @Autowired
-    private OrderCallbackDao callbackDao;
-
-    public static final String SUPPLY_TOKEN = "supply:token";
+    private KafkaProducer kafkaProducer;
 
     /**
      * 获取token
      */
     @PostMapping("/getToken")
     public Result getToken() {
-        return fetchAndCacheToken();
+        return paySupplyService.fetchAndCacheToken();
     }
-
-    /**
-     * 请求上游获取token并缓存到Redis
-     * 成功返回 Result.success(token),失败返回 Result.fail(msg)
-     */
-    private Result fetchAndCacheToken() {
-        // 先判断TTL,剩余时间大于1小时才取缓存token直接返回
-        if (redisUtils.ttl(SUPPLY_TOKEN) > 3600) {
-            return Result.success(redisUtils.get(SUPPLY_TOKEN));
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("app_key", appKey);
-        params.put("app_secret", appSecret);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/application/getToken", params);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        JSONObject data = respJson.getJSONObject("data");
-        String token = data.getString("token");
-        long expiresAt = data.getLongValue("expiresAt");
-
-        long ttlSeconds = (expiresAt - System.currentTimeMillis()) / 1000;
-        if (ttlSeconds <= 0) ttlSeconds = 60;
-
-        redisUtils.set(SUPPLY_TOKEN, token, (int) ttlSeconds);
-
-        return Result.success(token);
-    }
-
     /**
      * 选品列表API
      */
     @PostMapping("/cursorList")
     public Result cursorList(@Valid @RequestBody ProductPageReq req) {
 
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("pageSize", req.getPageSize());
-        if (req.getCursor() != null) {
-            params.put("cursor", req.getCursor());
-        }
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/cursorList", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.cursorList(req);
     }
 
     //支持多个商品详情查看
     @PostMapping("/detailList")
     public Result detailList(@Valid @RequestBody ProductDetailReq req) {
+        return paySupplyService.detailList(req);
 
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("ids", req.getIds());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/detailList", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            log.info("查看商品详情失败,{}",req.getIds());
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        List<OrderDetailDTO> list = JSONObject.parseArray(
-                respJson.getJSONObject("data").getJSONArray("list").toJSONString(),
-                OrderDetailDTO.class
-        );
-
-        //todo  导入到企云商城
-
-
-
-
-        return Result.success(list);
     }
 
 
     // 订单验证
     @PostMapping("/beforeCheck")
     public Result beforeCheck(@Valid @RequestBody OrderCheckReq req) {
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("spu", req.getSpu());
-        params.put("address", req.getAddress());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/beforeCheck", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.beforeCheck(req);
     }
+
     //仅下单
     @PostMapping("/orderConfirmOnly")
     public Result orderConfirmOnly(@Valid @RequestBody OrderReq req){
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("spu", req.getSpu());
-        params.put("address", req.getAddress());
-        params.put("order_sn", req.getOrderSn());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/orderConfirmOnly", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        List<Orders> orders = JSONObject.parseArray(
-            respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
-            Orders.class
-        );
-        log.info("仅下单,存储订单");
-        ordersService.addBatchOrder(orders);
-
-        return Result.success(orders);
+        return paySupplyService.orderConfirmOnly(req);
     }
 
     //订单支付(单独下单之后使用这个支付)
     @PostMapping("/orderPayOnly")
     public Result orderPayOnly(@Valid @RequestBody OrderPayReq req){
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("order_sn", req.getOrderSn());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/orderPayOnly", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        List<Orders> orders = JSONObject.parseArray(
-            respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
-            Orders.class
-        );
-        return Result.success(orders);
+        return paySupplyService.orderPayOnly(req);
     }
 
 
     // 生成订单同时支付,如果已生成订单则是直接支付
     @PostMapping("/order")
     public Result order(@Valid @RequestBody OrderReq req) {
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("spu", req.getSpu());
-        params.put("address", req.getAddress());
-        params.put("order_sn", req.getOrderSn());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order", params, headers);
-
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        List<Orders> orders = JSONObject.parseArray(
-                respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
-                Orders.class
-        );
-        log.info("下单并支付,存储订单");
-        ordersService.addBatchOrder(orders);
-        return Result.success(orders);
+        return paySupplyService.order(req);
     }
 
     // 取消订单
     @PostMapping("/appCloseOrder")
     public Result appCloseOrder(@Valid @RequestBody CloseOrderReq req){
-
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("order_id", req.getOrderId());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/appCloseOrder", params, headers);
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-        //{
-        //    "body": {
-        //        "MSG": "SUCCESS",
-        //        "CODE": 200,
-        //        "data": {
-        //            "errorOrdersSNs": null,
-        //            "successOrdersSNs": [
-        //                195319850638
-        //            ]
-        //        }
-        //    },
-        //    "success": true
-        //}
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.appCloseOrder(req);
     }
 
     // =======================售后==========================================
@@ -355,76 +110,14 @@ public class YxSupplyChannelManualController {
     @PostMapping("/getAfterSalesTypeNameMap")
     public Result getAfterSalesTypeNameMap(@Valid @RequestBody AfterSalesOrderTypeReq req){
 
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("order_id", req.getOrderId());
-        params.put("order_item_id",req.getOrderItemId());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplateGet(prefixUrl + "/supplyapi/app/afterSales/getAfterSalesTypeNameMap", params, headers);
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.getAfterSalesTypeNameMap(req);
     }
 
 
     //申请售后
     @PostMapping("/afterSalesCreate")
     public Result afterSalesCreate(@Valid @RequestBody AfterSalesOrderReq req){
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("order_id", req.getOrderId());
-        params.put("is_received",req.getIsReceived());
-        params.put("order_item_id",req.getOrderItemId());
-        if (!ObjectUtils.isEmpty(req.getAmount())){
-            //退款总额不为空
-            params.put("amount",req.getAmount());
-        }
-        if (!ObjectUtils.isEmpty(req.getRefundType())){
-            // 退款方式: "0": "退款",  "1": "退货退款"
-            params.put("refund_type",req.getRefundType());
-        }
-        if (!ObjectUtils.isEmpty(req.getTechnicalServicesFee())){
-            //技术服务费
-            params.put("technical_services_fee",req.getTechnicalServicesFee());
-        }
-
-        if (!ObjectUtils.isEmpty(req.getFreight())){
-            //运费
-            params.put("freight",req.getFreight());
-        }
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/afterSales/create", params, headers);
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.afterSalesCreate(req);
     }
 
 
@@ -436,18 +129,39 @@ public class YxSupplyChannelManualController {
 
         JSONObject reqJson = JSONObject.parseObject(JSONObject.toJSONString(req));
         String messageType = reqJson.getString("message_type");
+        OrderCallback callback = new OrderCallback();
+        callback.setMessage_type(messageType);
+        callback.setMessage(req);
         //当 message_type == 商品类的事件 时跳过保存,其他类型才入库
-//        if (CallbackMessageType.GOODS_ALTER.equalsIgnoreCase(messageType) || CallbackMessageType.GOODS_UNDERCARRIAGE.equalsIgnoreCase(messageType)
-//        || CallbackMessageType.GOODS_ON_SALE.equalsIgnoreCase(messageType) ||  CallbackMessageType.GOODS_DELETE.equalsIgnoreCase(messageType)) {
-//            return result;
-//        }
+        if (CallbackMessageType.GOODS_ALTER.equalsIgnoreCase(messageType) || CallbackMessageType.GOODS_UNDERCARRIAGE.equalsIgnoreCase(messageType)
+        || CallbackMessageType.GOODS_ON_SALE.equalsIgnoreCase(messageType) ||  CallbackMessageType.GOODS_DELETE.equalsIgnoreCase(messageType)) {
+            int productId = reqJson.getIntValue("product_id");
+            callback.setProduct_id(productId);
+            // 若product_id =0 ,则为无效数据,直接跳过
+            if (0== productId){
+                return result;
+            }
+            JSONObject json=new JSONObject();
+            json.put("product_id", productId);
+            // 商品变更,有可能是加入到选品库了
+            if (CallbackMessageType.GOODS_ALTER.equalsIgnoreCase(messageType)){
+
+                //添加商品
+                kafkaProducer.sendMessage(CallbackMessageType.GOODS_ALTER, json.toJSONString());
+            }
+            // 当商品下架的时候,更新商品为下架
+            if (CallbackMessageType.GOODS_UNDERCARRIAGE.equalsIgnoreCase(messageType)){
+                //更新商品下架,状态变更,
+                kafkaProducer.sendMessage(CallbackMessageType.GOODS_UNDERCARRIAGE, json.toJSONString());
+            }
+
+        }
 
         //售后通过
         if (CallbackMessageType.AFTER_SALES_PASS.equalsIgnoreCase(messageType)) {
 
         }
-        OrderCallback callback = new OrderCallback();
-        callback.setMessage(req);
+
         callbackDao.save(callback);
 
         return result;
@@ -458,31 +172,7 @@ public class YxSupplyChannelManualController {
     //我的选品库
     @PostMapping("/getMyStorageIdsList")
     public Result getMyStorageIdsList(@Valid @RequestBody StoragePageReq req){
-        String token = redisUtils.get(SUPPLY_TOKEN);
-        if (token == null || token.isEmpty()) {
-            Result tokenResult = fetchAndCacheToken();
-            if (!tokenResult.isSuccess()) {
-                return tokenResult;
-            }
-            token = (String) tokenResult.getBody().get("token");
-        }
-
-        Map<String, Object> params = new HashMap<>();
-        params.put("page", req.getPage());
-        params.put("pageSize",req.getPageSize());
-        params.put("create_sort",req.getCreateSort());
-
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-token", token);
-
-        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/getMyStorageIdsList", params, headers);
-        JSONObject respJson = JSONObject.parseObject(resp);
-        if (respJson.getIntValue("code") != 0) {
-            return Result.fail(respJson.getString("msg"));
-        }
-
-
-        return Result.success(respJson.getJSONObject("data"));
+        return paySupplyService.getMyStorageIdsList(req);
     }
 
 

+ 1 - 0
src/main/java/zs/payment/dto/OrderDetailDTO.java

@@ -15,6 +15,7 @@ import java.util.List;
 @NoArgsConstructor
 public class OrderDetailDTO {
 
+    //中台商品id
     private Long id;
     private Long created_at;
     private Long updated_at;

+ 1 - 1
src/main/java/zs/payment/dto/SkuDTO.java

@@ -11,7 +11,7 @@ import java.util.List;
 @NoArgsConstructor
 public class SkuDTO {
 
-    // sku id
+    // sku id =规格id
     private Integer id;
     // 创建时间
     private String created_at;

+ 3 - 7
src/main/java/zs/payment/entity/OrderCallback.java

@@ -16,14 +16,10 @@ public class OrderCallback {
     // 消息类型
     private String message_type;
 
-    // 订单编号
-//    @NotBlank(message = "order_sn不能为空")
-    private String order_sn;
-
-    // 签名
-//    @NotBlank(message = "member_sign不能为空")
-    private String member_sign;
+    // 商品编号
+    private Integer product_id;
 
+    //原始消息
     private Object message;
 
 }

+ 70 - 0
src/main/java/zs/payment/entity/mysql/ImsEweiShopCategory.java

@@ -0,0 +1,70 @@
+package zs.payment.entity.mysql;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Setter
+@Getter
+@NoArgsConstructor
+@TableName("ims_ewei_shop_category")
+public class ImsEweiShopCategory {
+
+    //create table ims_ewei_shop_category
+    //(
+    //    id           int auto_increment
+    //        primary key,
+    //    uniacid      int              default 0  null,
+    //    name         varchar(50)                 null,
+    //    thumb        varchar(255)                null,
+    //    parentid     int              default 0  null,
+    //    isrecommand  int(10)          default 0  null,
+    //    description  varchar(500)                null,
+    //    displayorder tinyint unsigned default 0  null,
+    //    enabled      tinyint(1)       default 1  null,
+    //    ishome       tinyint(3)       default 0  null,
+    //    level        tinyint(3)                  null,
+    //    advimg       varchar(255)     default '' null,
+    //    advurl       varchar(500)     default '' null,
+    //    src_id       int                         null comment '源分类ID',
+    //    iswater      tinyint(1)       default 0  null comment '久猪 是否是茗水会分类 1是'
+    //)
+    //    row_format = DYNAMIC;
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    @TableField("uniacid")
+    private Integer uniacId;
+    //名称
+    private String name;
+    private String thumb;
+    //父类
+    @TableField("parentid")
+    private Integer parentId;
+    //是否推荐,默认0
+    @TableField("isrecommand")
+    private Integer isRecommand;
+    private String description;
+    private Integer displayorder;
+    //启用,默认为1 , 0=未启用
+    private Integer enabled;
+    @TableField("ishome")
+    private Integer isHome;
+    //分类 1=顶级 2=第二类 3=第三类
+    private Integer level;
+    private String advimg;
+    private String advurl;
+    //源分类ID
+    @TableField("src_id")
+    private Integer srcId;
+    //久猪 是否是茗水会分类 1是
+    @TableField("iswater")
+    private Integer isWater;
+
+
+
+
+}

+ 509 - 0
src/main/java/zs/payment/entity/mysql/ImsEweiShopGoods.java

@@ -0,0 +1,509 @@
+package zs.payment.entity.mysql;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 企云商城的商品
+ */
+@Setter
+@Getter
+@NoArgsConstructor
+@TableName("ims_ewei_shop_goods")
+public class ImsEweiShopGoods {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    // 公众号id
+    private Integer uniacid;
+    // 一级分类ID
+    private Long pcate;
+    // 二级分类ID
+    private Long ccate;
+    // 三级分类ID
+    private Long tcate;
+    // 1 实体商品 2 虚拟商品 3 虚拟物品(卡密) 4 批发商品 5 记次/时商品 9 周期购商品 20 租赁商品 21 定金购商品 22拍卖 23易拍即得拍卖品24易拍即得拼拍 25盲盒 26盲盒商品 27久猪租赁
+    private Integer type;
+    // 多商户id
+    private Integer merchid;
+    // 状态 0 下架 1 上架 2 赠品上架
+    private Integer status;
+    // 排序
+    private Integer displayorder;
+    // 商品名称
+    private String title;
+    // 商品图(首图)
+    private String thumb;
+    // 商品单位
+    private String unit;
+    // 分享描述
+    private String description;
+    // 商品详情
+    private String content;
+    // 商品编号
+    private String goodssn;
+    // 商品条码
+    private String productsn;
+    // 商品原价
+    private BigDecimal productprice;
+    // 普通商品现价/拍卖保证金
+    private BigDecimal marketprice;
+    // 租赁中押金/拍卖保留价/久猪租赁押金
+    private BigDecimal costprice;
+    // 成本价
+    private BigDecimal cost_of_price;
+    // 原价
+    private BigDecimal originalprice;
+    // 商品库存
+    private Integer total;
+    // 0 拍下减库存 1 付款减库存 2 永久不减
+    private Integer totalcnf;
+    // 已出售数
+    private Integer sales;
+    // 实际售出数
+    private Integer salesreal;
+    // 商品规格设置
+    private String spec;
+    // 建立时间
+    private Long createtime;
+    // 重量
+    private BigDecimal weight;
+    // 购买赠送积分,如果带%号,则为按成交价比例计算
+    private String credit;
+    // 单次最多购买量
+    private Integer maxbuy;
+    // 用户最多购买量
+    private Integer usermaxbuy;
+    // 启用商品规则 0 不启用 1 启用
+    private Integer hasoption;
+    // 配送
+    private Integer dispatch;
+    // 缩略图地址
+    private String thumb_url;
+    // 新上
+    private Integer isnew;
+    // 热卖
+    private Integer ishot;
+    // 促销
+    private Integer isdiscount;
+    // 促销标题
+    private String isdiscount_title;
+    // 促销时间
+    private Integer isdiscount_time;
+    // 促销描述
+    private String isdiscount_discounts;
+    // 推荐 1是 0否
+    private Integer isrecommand;
+    // 包邮 1是 0否
+    private Integer issendfree;
+    // 限时卖
+    private Integer istime;
+    // 允许评价 1是 0否
+    private Integer iscomment;
+    // 限卖开始时间/拼拍开始倒计时分钟
+    private Integer timestart;
+    // 限卖结束时间/拼拍结束倒计时分钟
+    private Integer timeend;
+    // 查看次数
+    private Integer viewcount;
+    // 是否删除 1是 0否
+    private Integer deleted;
+    // 是否有分销 1是 0否
+    private Integer hascommission;
+    // 一级分销比率
+    private BigDecimal commission1_rate;
+    // 一级分销固定佣金
+    private BigDecimal commission1_pay;
+    // 二级分销比率
+    private BigDecimal commission2_rate;
+    // 二级分销固定佣金
+    private BigDecimal commission2_pay;
+    // 三级分销比率
+    private BigDecimal commission3_rate;
+    // 三级分销固定佣金
+    private BigDecimal commission3_pay;
+    // 分销
+    private String commission;
+    // 得分
+    private BigDecimal score;
+    // 抓取产品信息ID/星链导入商品spuid,共富商城第三方商品id
+    private String catch_id;
+    // 抓取产品地址/共富商城第三方商品链接
+    private String catch_url;
+    // 抓取产品来源/来源星链xinglian、淘宝助手taobao,共富商城第三方商品(拼多多gfPDD,京东gfJD,淘宝gfTaobao),芸信yunxin
+    private String catch_source;
+    // 更新时间
+    private Long updatetime;
+    // 分享标题
+    private String share_title;
+    // 分享图标
+    private String share_icon;
+    // 货到付款 1 不支持 2 支持
+    private Integer cash;
+    // 海报图片
+    private String commission_thumb;
+    // 不参与会员折扣
+    private Integer isnodiscount;
+    // 会员等级浏览权限
+    private String showlevels;
+    // 会员组购买权限
+    private String buylevels;
+    // 会员组浏览权限
+    private String showgroups;
+    // 会员组购买权限
+    private String buygroups;
+    // 支持线下核销 Null 0 1 不支持 2 支持
+    private Integer isverify;
+    // 核销:支持门店ID
+    private String storeids;
+    // 商家通知
+    private String noticeopenid;
+    // 提醒类型
+    private String noticetype;
+    // 需要关注
+    private Integer needfollow;
+    // 关注地址
+    private String followurl;
+    // 关注事项
+    private String followtip;
+    // 积分抵扣 0 不支持积分抵扣 >0 最多抵扣 元
+    private BigDecimal deduct;
+    // 短名称 打印需要
+    private String shorttitle;
+    // 虚拟商品模板ID 0 多规格虚拟商品
+    @TableField("virtual")
+    private Integer virtualVar;
+    // 一级多重分类
+    private String ccates;
+    // 折扣
+    private String discounts;
+    // 不执行分销
+    private Integer nocommission;
+    // 隐藏分销按钮
+    private Integer hidecommission;
+    // 二级多重分类
+    private String pcates;
+    // 三级多重分类
+    private String tcates;
+    // 店铺LOGO
+    private String detail_logo;
+    // 店铺名称
+    private String detail_shopname;
+    // 全部宝贝x个
+    private String detail_totaltitle;
+    // 按钮1名称
+    private String detail_btntext1;
+    // 按钮1链接 默认"查看所有商品"及"默认的全部商品连接"
+    private String detail_btnurl1;
+    // 按钮2名称
+    private String detail_btntext2;
+    // 按钮2链接 默认"进店逛逛"及"默认的小店或商城连接"
+    private String detail_btnurl2;
+    // 多重分类数据集
+    private String cates;
+    // 营销文章ID
+    private Integer artid;
+    // 余额抵扣 0 支持全额抵扣 -1 不支持余额抵扣 >0 最多抵扣 元
+    private BigDecimal deduct2;
+    // 单品满件包邮 0 : 不支持满件包邮
+    private Integer ednum;
+    // 不参加满包邮的地区 ,0 : 不支持满件包邮
+    private String edareas;
+    // 单品满额包邮 0 : 不支持满额包邮
+    private BigDecimal edmoney;
+    // 自定义表单形式
+    private Integer diyformtype;
+    // 自定义表单ID
+    private Integer diyformid;
+    // 订单模式
+    private Integer diymode;
+    // 配送类型 0 运费模板 1 统一邮费
+    private Integer dispatchtype;
+    // 配送ID
+    private Integer dispatchid;
+    // 统一邮费
+    private BigDecimal dispatchprice;
+    // 多件累计抵扣积分
+    private Integer manydeduct;
+    // 销售更新
+    private Integer saleupdate;
+    // 商户ID
+    private Integer shopid;
+    // 商品分类集合
+    private String allcates;
+    // 用户单次必须购买数量
+    private Integer minbuy;
+    // 提供发票
+    private Integer invoice;
+    // 保修
+    private Integer repair;
+    // 7天无理由退换
+    private Integer seven;
+    // 余额返现
+    private String money;
+    // 多规格中最小价格,无规格时显示销售价
+    private BigDecimal minprice;
+    // 多规格中最大价格,无规格时显示销售价
+    private BigDecimal maxprice;
+    // 商品所在省 如为空则显示商城所在
+    private String province;
+    // 商品所在城市 如为空则显示商城所在
+    private String city;
+    // 是否购买后显示
+    private Integer buyshow;
+    // 购买后显示的内容
+    private String buycontent;
+    private Integer saleupdate37975;
+    private Integer saleupdate51117;
+    // 是否自动发货 1是 0否
+    private Integer virtualsend;
+    // 自动发货内容
+    private String virtualsendcontent;
+    // 0按订单核销1按消费码核销2按次核销
+    private Integer verifytype;
+    // 商品自定义的表单结构
+    private String diyfields;
+    // 存为模板时记录的id
+    private Integer diysaveid;
+    // 模板更新
+    private Integer diysave;
+    // 正品保证
+    private Integer quality;
+    // 是否加入团购 1是 0否(必填)
+    private Integer groupstype;
+    // 显示库存(必填)
+    private Integer showtotal;
+    // 子标题
+    private String subtitle;
+    // 详情页 分享按钮 0 弹出层 1跳转海报(必填)
+    private Integer sharebtn;
+    private Integer checked;
+    // 详情页面显示首图 0 不显示 1 显示 注:首图为列表页使用,尺寸较小
+    private Integer thumb_first;
+    // 机端使用的价格 0 当前设置促销价格 1 商户设置促销价格
+    private Integer merchsale;
+    // 商品关键字
+    private String keywords;
+    // 商品标签
+    private String labelname;
+    // 自动收货 0 系统设置 -1 不自动收货 >0 天数
+    private Integer autoreceive;
+    // 不允许退货
+    private Integer cannotrefund;
+    // 砍价
+    private Integer bargain;
+    // 二次购买几折
+    private BigDecimal buyagain;
+    // 是否持续使用
+    private Integer buyagain_islong;
+    // 使用条件,0是付款后,1是完成后
+    private Integer buyagain_condition;
+    // 可以使用优惠 默认是 0 不能使用其他优惠,1是可以使用
+    private Integer buyagain_sale;
+    // 关于重复购买的佣金
+    private String buyagain_commission;
+    // 再次购买价格
+    private BigDecimal buyagain_price;
+    // 自定义页面ID
+    private Integer diypage;
+    // 是否 支持收银台
+    private Integer cashier;
+    // 核销:是否指定时间兑换(必填)
+    private Integer isendtime;
+    // 核销:自动使用期限(必填)
+    private Integer usetime;
+    // 核销:使用有效期至(必填)
+    private Integer endtime;
+    // 多商户排序(必填)
+    private Integer merchdisplayorder;
+    // 兑换库存
+    private Integer exchange_stock;
+    // 兑换邮费(必填)
+    private BigDecimal exchange_postage;
+    // 是否开启预售(必填)
+    private Integer ispresell;
+    // 预售价格(必填)
+    private BigDecimal presellprice;
+    // 预售商品结束设置(必填)
+    private Integer presellover;
+    // 预售商品结束X天后,商品转为正常销售(必填)
+    private Integer presellovertime;
+    // 是否设置预售开始时间(必填)
+    private Integer presellstart;
+    // 预售开始时间(必填)
+    private Integer preselltimestart;
+    // 是否设置预售结束时间(必填)
+    private Integer presellend;
+    // 预售结束时间(必填)
+    private Integer preselltimeend;
+    // 预售发货时间类型 0设置时间 1购买后X天(必填)
+    private Integer presellsendtype;
+    //(必填)
+    private Integer presellsendstatrttime;
+    // 预售购买后X天后发货(必填)
+    private Integer presellsendtime;
+    // 地区code
+    private String edareas_code;
+    // 总库存(必填)
+    private Integer unite_total;
+    // 3N营销会员
+    private String threen;
+    // 批发价格
+    private Integer intervalfloor;
+    // 批发单价
+    private String intervalprice;
+    // 是否为全返商品(必填)
+    private Integer isfullback;
+    // 是否开启上架时间(必填)
+    private Integer isstatustime;
+    // 上架开始时间(必填)
+    private Integer statustimestart;
+    // 上架结束时间(必填)
+    private Integer statustimeend;
+    // 主商城搜索结果中是否显示该商品 1隐藏 0显示(必填)
+    private Integer nosearch;
+    // 显示销量(必填)
+    private Integer showsales;
+    // 是否为直播商品(必填)
+    private Integer islive;
+    // 直播间价格(必填)
+    private BigDecimal liveprice;
+    // 是否开启微信卡片 0关闭 1开启
+    private Integer opencard;
+    // 微信卡片id
+    private String cardid;
+    // 可核销次数
+    private Integer verifygoodsnum;
+    // 可核销天数
+    private Integer verifygoodsdays;
+    // 核销时间类型
+    private Integer verifygoodslimittype;
+    // 核销过期时间
+    private Integer verifygoodslimitdate;
+    // 最小直播价(必填)
+    private BigDecimal minliveprice;
+    // 最大直播价(必填)
+    private BigDecimal maxliveprice;
+    // 订金(必填)
+    private BigDecimal dowpayment;
+    // 行业模板id(必填)
+    private Integer tempid;
+    // 允许门店设置价格 1允许 0禁止(必填)
+    private Integer isstoreprice;
+    // 定金退还设置 0退还 -1不退还 1-12多少小时退还(必填)
+    private Integer beforehours;
+    // 新商品(必填)
+    private Integer newgoods;
+    // 视频
+    private String video;
+    private String officthumb;
+    // 是否初始化分类信息 1是 0否
+    private String catesinit3;
+    // 是否调整过显示库存 1是 0否
+    private Integer showtotaladd;
+    //(必填)
+    private Integer verifygoodstype;
+    //(必填)
+    private Integer isforceverifystore;
+    // 是否是进货 1
+    private Integer commoditytype;
+    // 云商城商品id
+    private Integer gd_id;
+    // 是否是供货 1是
+    private Integer issupply;
+    // 机器人是否支持自提(0支持 1不支持)
+    private Integer ispickup;
+    // 云商城店铺名称
+    private String ysh_merchname;
+    // 是否京东商品0:否1是
+    private Integer isjingdong;
+    // 本币抵扣金额/久猪金猪豆(本币)最高可抵扣
+    private BigDecimal benbi_money;
+    // 联盟币抵扣金额
+    private BigDecimal lmb_money;
+    // 联盟币抵扣上限
+    private Integer lmb_num;
+    // 积分币抵扣
+    private Integer benbi_num;
+    // 接入人
+    private String jieruren;
+    // 推荐人
+    private String tuijianren;
+    // 分佣策略 1 按固定金额分账 2 按利润百分比分账(必填)
+    private Integer fenyong_tactics;
+    // 分佣联盟币(关系和交易)同时是定金购定金分佣金额「分佣策略=2时,该值是通过fenyong_profit_per计算得出的」
+    private BigDecimal fenyonglmb;
+    // 利润百分比
+    private BigDecimal fenyong_profit_per;
+    // 满多少返联盟币
+    private BigDecimal man_saleprice;
+    // 返联盟币
+    private Integer fan_lmb;
+    // 奖励积分币
+    private Integer reward_jfb;
+    // 奖励积分币-允许多件累计 0 不允许 1 允许
+    private Integer allow_more;
+    // 是否是订单全返商品
+    private Integer isordersign;
+    // 定金购定金可支付开始时间/拍卖开始时间/拼拍开始时间
+    private Integer deposittimestart;
+    // 定金购定金可支付结束时间/拍卖结束时间/拼拍结束时间
+    private Integer deposittimeend;
+    // 定金购尾款开始时间
+    private Integer remainingtimestart;
+    // 定金购尾款结束时间
+    private Integer remainingtimeend;
+    // 定金购尾款/拍卖起拍价
+    private BigDecimal remainingprice;
+    // 定金购全额支付价格/拍卖参考价
+    private BigDecimal fullprice;
+    // 定金购每期天数
+    private Integer cycleday;
+    // 定金购期数
+    private Integer cyclenum;
+    // 分佣联盟币(关系和交易)定金购尾款分佣金额
+    private BigDecimal fenyonglmb_r;
+    // 分佣联盟币(关系和交易)定金全额支付分佣金额
+    private BigDecimal fenyonglmb_f;
+    // 拍卖加价幅度
+    private BigDecimal rangeprice;
+    // 拍卖加价延迟分钟/易拍记得 竞拍限时秒
+    private Integer pricemin;
+    // 拍卖关联得商品id/拼拍关联拍卡id
+    private Integer relevanceid;
+    // 拍卖商品状态1流拍 (易拍记得 拍卖状态0未知1已结束)/拼拍(0未开始或进行中或成团等待开始1报名中2已结束)
+    private Integer auctionstatus;
+    // 拍卖商品1未开始/拼拍1成团等待开始
+    private Integer isauctiontime;
+    // 拍卖送派人userid
+    private String souyue_userid;
+    // 是否是供货推荐商品
+    private Integer issupply_recommend;
+    // 拍卖奖励比例
+    private BigDecimal rewardratio;
+    // 易拍记得拍卖房间人数
+    private Integer auctionnum;
+    // 费用详情
+    private String costcontent;
+    // 行程路线/久猪扩展字段
+    private String itinerary;
+    // 是否是旅游产品 1是
+    private Integer isitinerary;
+    // 共富分佣
+    private BigDecimal fenyong_rich;
+    // 共富广告收益抵扣上限
+    private BigDecimal adv_money;
+    // 商品属性0无1汽车订购(717项目专用)
+    private Integer attribute;
+    // 会员等级奖励积分币
+    private String level_reward_jfb;
+    // 商品类别:0线上商品 1线下商品
+    private Integer kind;
+}

+ 10 - 0
src/main/java/zs/payment/enums/ProductSupplyRedis.java

@@ -0,0 +1,10 @@
+package zs.payment.enums;
+
+public interface ProductSupplyRedis {
+
+    // 芸信 供应链的token
+    String SUPPLY_TOKEN = "supply:token";
+    //
+    String SYNC_SUPPLY_ID = "sync:supply:ids";
+
+}

+ 9 - 0
src/main/java/zs/payment/mapper/ImsEweiShopCategoryMapper.java

@@ -0,0 +1,9 @@
+package zs.payment.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import zs.payment.entity.mysql.ImsEweiShopCategory;
+
+@Mapper
+public interface ImsEweiShopCategoryMapper extends BaseMapper<ImsEweiShopCategory> {
+}

+ 9 - 0
src/main/java/zs/payment/mapper/ImsEweiShopGoodsMapper.java

@@ -0,0 +1,9 @@
+package zs.payment.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import zs.payment.entity.mysql.ImsEweiShopGoods;
+
+@Mapper
+public interface ImsEweiShopGoodsMapper extends BaseMapper<ImsEweiShopGoods> {
+}

+ 213 - 0
src/main/java/zs/payment/messages/KafkaConsumer.java

@@ -0,0 +1,213 @@
+package zs.payment.messages;
+
+import com.alibaba.fastjson.JSONObject;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+import zs.payment.dto.OrderDetailDTO;
+import zs.payment.entity.mysql.ImsEweiShopCategory;
+import zs.payment.entity.mysql.ImsEweiShopGoods;
+import zs.payment.enums.ProductSupplyRedis;
+import zs.payment.req.ProductDetailReq;
+import zs.payment.resp.Result;
+import zs.payment.service.Imseweishopgoods.ImsEweiShopGoodsService;
+import zs.payment.service.imseweishopcategory.ImsEweiShopCategoryService;
+import zs.payment.service.paysupply.PaySupplyService;
+import zs.payment.utils.RedisUtils;
+import zs.payment.utils.TimeUtils;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+
+@Slf4j
+@Component
+@RefreshScope
+public class KafkaConsumer {
+
+    @Autowired
+    private PaySupplyService paySupplyService;
+
+    @Autowired
+    private RedisUtils redisUtils;
+
+    @Autowired
+    private ImsEweiShopCategoryService imsEweiShopCategoryService;
+    @Autowired
+    private ImsEweiShopGoodsService imsEweiShopGoodsService;
+
+
+    /**
+     * 商品下架
+     * @param messsage
+     */
+    @KafkaListener(
+        topics = "goods.undercarriage",
+        groupId = "pay2-group"
+    )
+    public void goodsUndercarriage(String messsage) {
+        JSONObject jsonObject = JSONObject.parseObject(messsage);
+        int productId = jsonObject.getIntValue("product_id");
+
+        // 更新商品状态为下架   update ims_ewei_shop_goods set  status = 0 where catch_id=productId
+
+        boolean b = imsEweiShopGoodsService.update(
+            new LambdaUpdateWrapper<ImsEweiShopGoods>()
+                .set(ImsEweiShopGoods::getStatus, 0)
+                .eq(ImsEweiShopGoods::getCatch_id, String.valueOf(productId))
+        );
+        if (!b){
+            log.error("--------商品{}下架状态修改失败--------", productId);
+        }
+
+    }
+
+
+
+    /**
+     * 商品添加
+     *
+     * @param messsage
+     */
+    @KafkaListener(
+        topics = "goods.after",
+        groupId = "pay2-group"
+    )
+    public void goodsAfter(String messsage) {
+
+        JSONObject jsonObject = JSONObject.parseObject(messsage);
+        int productId = jsonObject.getIntValue("product_id");
+        ProductDetailReq req=new ProductDetailReq();
+        List<Integer>  ids=new ArrayList<>();
+        ids.add(productId);
+        req.setIds(ids);
+        Result result = paySupplyService.detailList(req);
+
+        if (result.isSuccess()) {
+
+            List<OrderDetailDTO> list = JSONObject.parseArray(
+                result.getBody().get("data").toString(),
+                OrderDetailDTO.class
+            );
+            //todo  导入到企云商城
+            list.forEach(dto -> {
+                //todo 先查看该商品编号是否已同步企云商城。若没同步,则判断商品分类是否存在。不存在则创建
+
+                Boolean b = redisUtils.sismember(ProductSupplyRedis.SYNC_SUPPLY_ID, dto.getId().toString());
+                if (!b){
+
+                    //第一级
+                    Long pcate=0L;
+                    //第二级
+                    Long ccate=0L;
+                    //第三级
+                    Long tcate=0L;
+
+                    //未同步,则判断商品分类
+                    ImsEweiShopCategory category1 = imsEweiShopCategoryService.selectByName(dto.getCategory_1().getName(), dto.getCategory_1().getLevel(),0L);
+                    if (!Optional.ofNullable(category1).isPresent()){
+                        //创建新的商品分类
+                        category1=new ImsEweiShopCategory();
+                        category1.setLevel(1);
+                        category1.setName(dto.getCategory_1().getName());
+                        imsEweiShopCategoryService.save(category1);
+                    }
+                    pcate=category1.getId();
+                    // 存在,再查询商品分类第二级
+                    ImsEweiShopCategory category2 = imsEweiShopCategoryService.selectByName(dto.getCategory_2().getName(), dto.getCategory_2().getLevel(),pcate);
+                    if (!Optional.ofNullable(category2).isPresent()){
+                        category2=new ImsEweiShopCategory();
+                        category2.setLevel(2);
+                        category2.setName(dto.getCategory_2().getName());
+                        imsEweiShopCategoryService.save(category2);
+                    }
+                    ccate=category2.getId();
+
+                    // 再查询商品分类第三级
+                    ImsEweiShopCategory category3 = imsEweiShopCategoryService.selectByName(dto.getCategory_3().getName(), dto.getCategory_3().getLevel(),ccate);
+                    if (!Optional.ofNullable(category3).isPresent()){
+                        category3 = new ImsEweiShopCategory();
+                        category3.setLevel(3);
+                        category3.setName(dto.getCategory_3().getName());
+                        imsEweiShopCategoryService.save(category3);
+                    }
+                    tcate=category3.getId();
+
+
+                    //todo 创建商品
+
+                    ImsEweiShopGoods goods=new  ImsEweiShopGoods();
+                    goods.setPcate(pcate);
+                    goods.setCcate(ccate);
+                    goods.setTcate(tcate);
+                    goods.setType(1);
+                    //状态  1=上架
+                    goods.setStatus(1);
+                    goods.setDisplayorder(0);
+                    goods.setTitle(dto.getTitle());
+                    //商品图
+                    goods.setThumb(dto.getImage_url());
+                    //商品单位: 件
+                    goods.setUnit(dto.getUnit());
+                    goods.setContent(dto.getDetail_images());
+                    //================价格====================
+                    goods.setProductprice(new BigDecimal(dto.getGuide_price()/100));
+                    goods.setMarketprice(new BigDecimal(dto.getMarket_price()/100));
+                    goods.setCostprice(new BigDecimal(0));
+                    goods.setCost_of_price(new BigDecimal(dto.getCost_price()/100));
+
+                    goods.setTotal(dto.getStock());
+                    // 0 拍下减库存 1 付款减库存 2 永久不减
+                    goods.setTotalcnf(0);
+                    goods.setSales(dto.getSales());
+                    goods.setSalesreal(dto.getSales());
+                    goods.setIsnew(0);
+                    goods.setIshot(0);
+                    goods.setIsdiscount(0);
+                    //商品来源
+                    goods.setCatch_source("yunxin");
+                    //芸信商城的商品主键
+                    goods.setCatch_id(dto.getId().toString());
+//                    goods.setCates("");
+                    //数据库里的时间戳是秒级
+                    goods.setCreatetime(TimeUtils.getLongFromCurrentTime()/1000);
+                    goods.setUpdatetime(TimeUtils.getLongFromCurrentTime()/1000);
+                    goods.setHasoption(0);
+                    goods.setDeleted(0);
+                    //多商户id
+                    goods.setMerchid(0);
+                    // merchid==0?0:1
+                    goods.setMerchsale(1);
+//                    goods.setShorttitle();
+                    //商品编号
+                    goods.setGoodssn(dto.getSn());
+                    //商品条码
+                    goods.setProductsn(dto.getBarcode());
+                    //默认发布给云悦生活
+                    goods.setUniacid(463);
+                    imsEweiShopGoodsService.save(goods);
+
+                }
+
+
+            });
+            log.info("=======productId:{} feed pool refill end=======",ids);
+        }else {
+            log.error("kafka consumer goods.after 商品详情查询失败");
+        }
+
+
+
+
+
+    }
+
+
+
+}

+ 28 - 0
src/main/java/zs/payment/messages/KafkaProducer.java

@@ -0,0 +1,28 @@
+package zs.payment.messages;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Service;
+
+/**
+ * 生产者组件
+ */
+@Service
+public class KafkaProducer {
+    @Autowired
+    private KafkaTemplate<String, String> kafkaTemplate;
+
+
+    /**
+     * 不指定topic
+     * @param topicName
+     * @param message
+     */
+    public void sendMessage(String topicName,String message) {
+        // 发送到默认分区(轮询)
+        kafkaTemplate.send(topicName, message);
+        System.out.println(">>> 生产者发送消息: " + message);
+    }
+}

+ 7 - 0
src/main/java/zs/payment/service/Imseweishopgoods/ImsEweiShopGoodsService.java

@@ -0,0 +1,7 @@
+package zs.payment.service.Imseweishopgoods;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import zs.payment.entity.mysql.ImsEweiShopGoods;
+
+public interface ImsEweiShopGoodsService extends IService<ImsEweiShopGoods> {
+}

+ 17 - 0
src/main/java/zs/payment/service/Imseweishopgoods/impl/ImsEweiShopGoodsServiceImpl.java

@@ -0,0 +1,17 @@
+package zs.payment.service.Imseweishopgoods.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import zs.payment.entity.mysql.ImsEweiShopGoods;
+import zs.payment.mapper.ImsEweiShopGoodsMapper;
+import zs.payment.service.Imseweishopgoods.ImsEweiShopGoodsService;
+
+@Service
+@Slf4j
+public class ImsEweiShopGoodsServiceImpl  extends ServiceImpl<ImsEweiShopGoodsMapper, ImsEweiShopGoods> implements ImsEweiShopGoodsService {
+
+
+
+}

+ 9 - 0
src/main/java/zs/payment/service/imseweishopcategory/ImsEweiShopCategoryService.java

@@ -0,0 +1,9 @@
+package zs.payment.service.imseweishopcategory;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import zs.payment.entity.mysql.ImsEweiShopCategory;
+
+public interface ImsEweiShopCategoryService extends IService<ImsEweiShopCategory> {
+
+    ImsEweiShopCategory selectByName(String name,Integer level,Long parentId);
+}

+ 33 - 0
src/main/java/zs/payment/service/imseweishopcategory/impl/ImsEweiShopCategoryServiceImpl.java

@@ -0,0 +1,33 @@
+package zs.payment.service.imseweishopcategory.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import zs.payment.entity.mysql.ImsEweiShopCategory;
+import zs.payment.mapper.ImsEweiShopCategoryMapper;
+import zs.payment.service.imseweishopcategory.ImsEweiShopCategoryService;
+
+import java.util.Optional;
+
+@Slf4j
+@Service
+public class ImsEweiShopCategoryServiceImpl extends ServiceImpl<ImsEweiShopCategoryMapper, ImsEweiShopCategory> implements ImsEweiShopCategoryService {
+
+
+    @Override
+    public ImsEweiShopCategory selectByName(String name, Integer level, Long parentId) {
+        LambdaQueryWrapper<ImsEweiShopCategory> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(ImsEweiShopCategory::getName, name);
+        queryWrapper.eq(ImsEweiShopCategory::getLevel, level);
+        queryWrapper.eq(ImsEweiShopCategory::getParentId, parentId);
+        //已启用
+        queryWrapper.eq(ImsEweiShopCategory::getEnabled, 1);
+
+        return baseMapper.selectOne(queryWrapper);
+    }
+
+
+}

+ 1 - 1
src/main/java/zs/payment/service/OrdersService.java

@@ -1,4 +1,4 @@
-package zs.payment.service;
+package zs.payment.service.order;
 
 import zs.payment.entity.Orders;
 

+ 2 - 2
src/main/java/zs/payment/service/impl/OrdersServiceImpl.java

@@ -1,10 +1,10 @@
-package zs.payment.service.impl;
+package zs.payment.service.order.impl;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import zs.payment.dao.OrderDao;
 import zs.payment.entity.Orders;
-import zs.payment.service.OrdersService;
+import zs.payment.service.order.OrdersService;
 
 import java.util.List;
 

+ 33 - 0
src/main/java/zs/payment/service/paysupply/PaySupplyService.java

@@ -0,0 +1,33 @@
+package zs.payment.service.paysupply;
+
+import org.springframework.web.bind.annotation.RequestBody;
+import zs.payment.req.*;
+import zs.payment.req.aftersales.AfterSalesOrderReq;
+import zs.payment.req.aftersales.AfterSalesOrderTypeReq;
+import zs.payment.req.storage.StoragePageReq;
+import zs.payment.resp.Result;
+
+import javax.validation.Valid;
+
+public interface PaySupplyService {
+
+    Result detailList(ProductDetailReq req);
+    Result fetchAndCacheToken();
+
+    Result cursorList(ProductPageReq req);
+
+    Result beforeCheck(OrderCheckReq req);
+
+    Result orderConfirmOnly(OrderReq req);
+    Result orderPayOnly(OrderPayReq req);
+
+    Result order(OrderReq req);
+
+    Result appCloseOrder(CloseOrderReq req);
+
+    Result getAfterSalesTypeNameMap(AfterSalesOrderTypeReq req);
+
+    Result afterSalesCreate(AfterSalesOrderReq req);
+
+    Result getMyStorageIdsList(StoragePageReq req);
+}

+ 383 - 0
src/main/java/zs/payment/service/paysupply/impl/PaySupplyServiceImpl.java

@@ -0,0 +1,383 @@
+package zs.payment.service.paysupply.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import zs.payment.dto.OrderDetailDTO;
+import zs.payment.entity.Orders;
+import zs.payment.enums.ProductSupplyRedis;
+import zs.payment.req.*;
+import zs.payment.req.aftersales.AfterSalesOrderReq;
+import zs.payment.req.aftersales.AfterSalesOrderTypeReq;
+import zs.payment.req.storage.StoragePageReq;
+import zs.payment.resp.Result;
+
+import zs.payment.service.order.OrdersService;
+import zs.payment.service.paysupply.PaySupplyService;
+import zs.payment.utils.HttpUtil;
+import zs.payment.utils.RedisUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static zs.payment.enums.ProductSupplyRedis.SUPPLY_TOKEN;
+
+@Service
+@Slf4j
+public class PaySupplyServiceImpl implements PaySupplyService {
+
+
+    @Value("${supply.demain}")
+    private String prefixUrl;
+
+    @Value("${supply.appKey}")
+    private String appKey;
+    @Value("${supply.appSecret}")
+    private String appSecret;
+
+    @Autowired
+    private OrdersService ordersService;
+
+    @Autowired
+    private RedisUtils redisUtils;
+
+
+
+    @Override
+    public Result detailList(ProductDetailReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("ids", req.getIds());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/detailList", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            log.info("查看商品详情失败,{}", req.getIds());
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        return Result.success(respJson.getJSONObject("data").getJSONArray("list"));
+    }
+
+    /**
+     * 请求上游获取token并缓存到Redis
+     * 成功返回 Result.success(token),失败返回 Result.fail(msg)
+     */
+    @Override
+    public Result fetchAndCacheToken() {
+        // 先判断TTL,剩余时间大于1小时才取缓存token直接返回
+        if (redisUtils.ttl(SUPPLY_TOKEN) > 3600) {
+            return Result.success(redisUtils.get(SUPPLY_TOKEN));
+        }
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("app_key", appKey);
+        params.put("app_secret", appSecret);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/application/getToken", params);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        JSONObject data = respJson.getJSONObject("data");
+        String token = data.getString("token");
+        long expiresAt = data.getLongValue("expiresAt");
+
+        long ttlSeconds = (expiresAt - System.currentTimeMillis()) / 1000;
+        if (ttlSeconds <= 0) ttlSeconds = 60;
+
+        redisUtils.set(SUPPLY_TOKEN, token, (int) ttlSeconds);
+
+        return Result.success(token);
+    }
+
+
+    @Override
+    public Result cursorList(ProductPageReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("pageSize", req.getPageSize());
+        if (req.getCursor() != null) {
+            params.put("cursor", req.getCursor());
+        }
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/cursorList", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        return Result.success(respJson.getJSONObject("data"));
+    }
+
+
+    @Override
+    public Result beforeCheck(OrderCheckReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("spu", req.getSpu());
+        params.put("address", req.getAddress());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/beforeCheck", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        return Result.success(respJson.getJSONObject("data"));
+    }
+
+    @Override
+    public Result orderConfirmOnly(OrderReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("spu", req.getSpu());
+        params.put("address", req.getAddress());
+        params.put("order_sn", req.getOrderSn());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/orderConfirmOnly", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        List<Orders> orders = JSONObject.parseArray(
+            respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
+            Orders.class
+        );
+        log.info("仅下单,存储订单");
+        ordersService.addBatchOrder(orders);
+
+        return Result.success(orders);
+    }
+
+    @Override
+    public Result orderPayOnly(OrderPayReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("order_sn", req.getOrderSn());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/orderPayOnly", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        List<Orders> orders = JSONObject.parseArray(
+            respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
+            Orders.class
+        );
+        return Result.success(orders);
+    }
+
+    @Override
+    public Result order(OrderReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("spu", req.getSpu());
+        params.put("address", req.getAddress());
+        params.put("order_sn", req.getOrderSn());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order", params, headers);
+
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        List<Orders> orders = JSONObject.parseArray(
+            respJson.getJSONObject("data").getJSONArray("Orders").toJSONString(),
+            Orders.class
+        );
+        log.info("下单并支付,存储订单");
+        ordersService.addBatchOrder(orders);
+        return Result.success(orders);
+    }
+
+    @Override
+    public Result appCloseOrder(CloseOrderReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("order_id", req.getOrderId());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/order/appCloseOrder", params, headers);
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+        //{
+        //    "body": {
+        //        "MSG": "SUCCESS",
+        //        "CODE": 200,
+        //        "data": {
+        //            "errorOrdersSNs": null,
+        //            "successOrdersSNs": [
+        //                195319850638
+        //            ]
+        //        }
+        //    },
+        //    "success": true
+        //}
+        return Result.success(respJson.getJSONObject("data"));
+    }
+
+    @Override
+    public Result getAfterSalesTypeNameMap(AfterSalesOrderTypeReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("order_id", req.getOrderId());
+        params.put("order_item_id",req.getOrderItemId());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplateGet(prefixUrl + "/supplyapi/app/afterSales/getAfterSalesTypeNameMap", params, headers);
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        return Result.success(respJson.getJSONObject("data"));
+    }
+
+    @Override
+    public Result afterSalesCreate(AfterSalesOrderReq req) {
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("order_id", req.getOrderId());
+        params.put("is_received",req.getIsReceived());
+        params.put("order_item_id",req.getOrderItemId());
+        if (!ObjectUtils.isEmpty(req.getAmount())){
+            //退款总额不为空
+            params.put("amount",req.getAmount());
+        }
+        if (!ObjectUtils.isEmpty(req.getRefundType())){
+            // 退款方式: "0": "退款",  "1": "退货退款"
+            params.put("refund_type",req.getRefundType());
+        }
+        if (!ObjectUtils.isEmpty(req.getTechnicalServicesFee())){
+            //技术服务费
+            params.put("technical_services_fee",req.getTechnicalServicesFee());
+        }
+
+        if (!ObjectUtils.isEmpty(req.getFreight())){
+            //运费
+            params.put("freight",req.getFreight());
+        }
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/afterSales/create", params, headers);
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+        return Result.success(respJson.getJSONObject("data"));
+    }
+
+    @Override
+    public Result getMyStorageIdsList(StoragePageReq req) {
+
+        Result tokenResult = fetchAndCacheToken();
+        if (!tokenResult.isSuccess()) {
+            return tokenResult;
+        }
+        String  token = (String) tokenResult.getBody().get("token");
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("page", req.getPage());
+        params.put("pageSize",req.getPageSize());
+        params.put("create_sort",req.getCreateSort());
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("x-token", token);
+
+        String resp = HttpUtil.restTemplatePost(prefixUrl + "/supplyapi/app/product/storage/getMyStorageIdsList", params, headers);
+        JSONObject respJson = JSONObject.parseObject(resp);
+        if (respJson.getIntValue("code") != 0) {
+            return Result.fail(respJson.getString("msg"));
+        }
+
+
+        return Result.success(respJson.getJSONObject("data"));
+    }
+}

+ 4 - 0
src/main/java/zs/payment/utils/RedisUtils.java

@@ -128,6 +128,10 @@ public class RedisUtils {
         return  Redis.withCluster(ecoCluster, jedis -> jedis.smembers(key));
     }
 
+    public Boolean sismember(String key,String value){
+        return Redis.withCluster(ecoCluster,jedis -> jedis.sismember(key,value));
+    }
+
     public long zadd(String key, double score, String member) {
         return Redis.withCluster(ecoCluster, jedis -> jedis.zadd(key, score, member));
     }

+ 112 - 0
src/main/java/zs/payment/utils/TimeUtils.java

@@ -0,0 +1,112 @@
+package zs.payment.utils;
+
+
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+
+/**
+ *时间处理工具
+ */
+@Slf4j
+@UtilityClass
+public class TimeUtils {
+    /**
+     * NO_LINE
+     **/
+    public final static String DATE_TIME_NO_LINE_PATTERN = "yyyyMMddHHmmss";
+
+    public final static String DATE_TIME_WITH_LINE_PATTERN = "yyyy-MM-dd HH:mm:ss";
+
+    /**
+     * 毫秒级  13位
+     * @param localDateTime
+     * @return
+     */
+    public long getLongFromLocalDateTime(LocalDateTime localDateTime) {
+        return localDateTime.atZone(ZoneId.of("CTT", ZoneId.SHORT_IDS)).toInstant().toEpochMilli();
+    }
+
+    public long getLongFromLocalDate(LocalDate localDate) {
+        return getLongFromLocalDateTime(localDate.atStartOfDay());
+    }
+
+    public LocalDateTime genLocalDataTimeFromInstant(Instant instant) {
+        return LocalDateTime.parse(instant.toString().substring(0, instant.toString().length() - 1));
+    }
+
+    public LocalDateTime genLocalDataTimeFromStr(String dateStr) {
+        return LocalDateTime.parse(dateStr);
+    }
+
+    public LocalDate getLocalDateFromLong(long milliSeconds) {
+        return Instant.ofEpochMilli((milliSeconds)).atZone(ZoneId.of("CTT", ZoneId.SHORT_IDS)).toLocalDate();
+    }
+
+    public LocalDateTime getLocalDateTimeFromLong(long milliSeconds) {
+        return LocalDateTime.ofInstant(Instant.ofEpochMilli((milliSeconds)), ZoneId.of("CTT", ZoneId.SHORT_IDS));
+    }
+
+    public long getLongFromCurrentTime() {
+        return getLongFromLocalDateTime(LocalDateTime.now());
+    }
+
+    public String format_no_line(LocalDateTime date) {
+        return date.format(DateTimeFormatter.ofPattern(DATE_TIME_NO_LINE_PATTERN));
+    }
+
+    public String getDateTimeWithLineFromLong(long milliSeconds) {
+        return getLocalDateTimeFromLong(milliSeconds).format(DateTimeFormatter.ofPattern(DATE_TIME_WITH_LINE_PATTERN));
+    }
+
+    public String format_line(LocalDateTime date) {
+        return date.format(DateTimeFormatter.ofPattern(DATE_TIME_WITH_LINE_PATTERN));
+    }
+
+    /**
+     * yyyy-MM-dd HH:mm:ss格式转Date
+     * @param dateStr
+     * @return
+     * @throws ParseException
+     */
+    public Date getDateFromString(String dateStr) {
+        Date date = null;
+        try {
+            date =  new SimpleDateFormat(DATE_TIME_WITH_LINE_PATTERN).parse(dateStr);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return date;
+    }
+
+
+    /**
+     * 获取日期时间格式化器
+     */
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_WITH_LINE_PATTERN);
+
+    /**
+     * 将字符串日期转换为 LocalDateTime
+     */
+    public LocalDateTime parseUpdateTime(String updateTimeStr) {
+        return LocalDateTime.parse(updateTimeStr, DATE_TIME_FORMATTER);
+    }
+
+    /**
+     * 比较两个日期字符串, 返回从小到大排序
+     * @return 负数表示 a < b,0 表示 a = b,正数表示 a > b
+     */
+    public int compareUpdateTime(String a, String b) {
+        return parseUpdateTime(a).compareTo(parseUpdateTime(b));
+    }
+
+}

+ 43 - 0
src/main/resources/application-pro.yml

@@ -1,9 +1,46 @@
 spring:
+    kafka:
+        # ============== 生产者配置 ==============
+        producer:
+            bootstrap-servers: 172.17.240.140:9092,172.17.240.141:9092  # Kafka 3.1.2 KRaft地址
+            key-serializer: org.apache.kafka.common.serialization.StringSerializer
+            value-serializer: org.apache.kafka.common.serialization.StringSerializer
+            # 可选:提高可靠性
+            acks: all
+            retries: 3
+
+        # ============== 消费者配置 ==============
+        #172.17.240.132:9092,172.17.240.140:9092,172.17.240.141:9092
+        consumer:
+            bootstrap-servers: 172.17.240.140:9092,172.17.240.141:9092  # 同上
+            key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+            value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+            #            group-id: store-group  # 消费者组,同一组内负载均衡
+            auto-offset-reset: earliest  # 无偏移量时从最早开始
+            enable-auto-commit: true  # 自动提交偏移量
+
+        # ============== 监听器容器配置 ==============
+        listener:
+            # 当使用批量消费时改为 BATCH
+            type: single
     data:
         mongodb:
             uri: mongodb://pay:pay2026@dds-2zedd8d70bde6e541.mongodb.rds.aliyuncs.com:3717,dds-2zedd8d70bde6e542.mongodb.rds.aliyuncs.com:3717/pay_supply
 
 
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver #数据源配置
+        url: jdbc:mysql://fefvp9lglp7e7w6hwzlp-rw4rm.rwlb.rds.aliyuncs.com:3306/qiyun?characterEncoding=UTF-8&autoReconnect=true
+        username: weitest
+        password: wei@2@22
+        hikari:
+            maximum-pool-size: 20      # 适合中等并发量的应用,既保证了响应速度,又不会过度占用数据库资源
+            minimum-idle: 10            # 通常设置为maximum-pool-size的一半
+            connection-timeout: 30000   # 30秒等待时间足够
+            idle-timeout: 600000        # 10分钟空闲可接受
+            max-lifetime: 1800000       # 30分钟防止连接泄露
+
+
 pay:
     redis:
         master: r-2zeitjlg0gdypzb4v6.redis.rds.aliyuncs.com:6379
@@ -13,3 +50,9 @@ supply:
     appKey: application519
     appSecret: 80694edd4a7da03f3c35473f27603967
     demain: https://yx.gz.cn
+
+
+
+
+
+