Browse Source

供货/停止供货

zhangwl 1 month ago
parent
commit
4b0906f216

+ 14 - 1
src/main/java/zs/payment/controller/EweiShopGoodsController.java

@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import zs.payment.exception.ApiException;
 import zs.payment.req.CommodityProcureReq;
+import zs.payment.req.GoodsSupplyReq;
 import zs.payment.resp.Result;
 import zs.payment.service.commodity.CommodityProcureService;
 
@@ -20,7 +21,6 @@ public class EweiShopGoodsController {
 
     /**
      * 进货:把云商城(悦店管理)里的商品全进货到本地
-     *
      */
     @PostMapping("/fullAdd")
     public Result fullAdd(@Valid @RequestBody CommodityProcureReq req) {
@@ -31,4 +31,17 @@ public class EweiShopGoodsController {
         }
     }
 
+    /**
+     * 供货/停止供货:把本地商品推送到云商城,或停止供货
+     * issupply=1: 供货  issupply=0: 停止供货
+     */
+    @PostMapping("/fullOutput")
+    public Result fullOutput(@Valid @RequestBody GoodsSupplyReq req) {
+        try {
+            return commodityProcureService.fullOutput(req);
+        } catch (ApiException e) {
+            return Result.fail(e.getMsg());
+        }
+    }
+
 }

+ 5 - 5
src/main/java/zs/payment/messages/KafkaConsumer.java

@@ -66,7 +66,7 @@ public class KafkaConsumer {
      * @param messsage
      */
     @KafkaListener(
-        topics = "goods.undercarriage2",
+        topics = "goods.undercarriage",
         groupId = "pay2-group"
     )
     public void goodsUndercarriage(String messsage) {
@@ -90,7 +90,7 @@ public class KafkaConsumer {
      * @param messsage
      */
     @KafkaListener(
-        topics = "goods.on.sale2",
+        topics = "goods.on.sale",
         groupId = "pay2-group"
     )
     public void goodsOnSale(String messsage) {
@@ -114,7 +114,7 @@ public class KafkaConsumer {
      * @param messsage
      */
     @KafkaListener(
-        topics = "goods.delete2",
+        topics = "goods.delete",
         groupId = "pay2-group"
     )
     public void goodsDelete(String messsage) {
@@ -142,7 +142,7 @@ public class KafkaConsumer {
      * @param messsage
      */
     @KafkaListener(
-        topics = "goods.sync2",
+        topics = "goods.sync",
         groupId = "pay2-group"
     )
     @Transactional(rollbackFor = Exception.class)
@@ -364,7 +364,7 @@ public class KafkaConsumer {
      * @param messsage
      */
     @KafkaListener(
-        topics = "order.delivery2",
+        topics = "order.delivery",
         groupId = "pay2-group"
     )
     public void goodsDelivery(String orderSn) {

+ 37 - 0
src/main/java/zs/payment/req/GoodsSupplyReq.java

@@ -0,0 +1,37 @@
+package zs.payment.req;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 供货请求DTO
+ * 对应PHP goods.commodity.supply接口
+ */
+@Setter
+@Getter
+@NoArgsConstructor
+public class GoodsSupplyReq implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 商品ID列表 */
+    @NotEmpty(message = "商品ID不能为空")
+    private List<Long> goodsIds;
+
+    /** 品类ID(供货时必填) */
+    private Integer cate;
+
+    /** 1=供货 0=停止供货 */
+    @NotNull(message = "供货状态不能为空")
+    private Integer issupply;
+
+    /** 公众号ID */
+    @NotNull(message = "公众号ID不能为空")
+    private Integer uniacid;
+}

+ 7 - 0
src/main/java/zs/payment/service/commodity/CommodityProcureService.java

@@ -1,6 +1,7 @@
 package zs.payment.service.commodity;
 
 import zs.payment.req.CommodityProcureReq;
+import zs.payment.req.GoodsSupplyReq;
 import zs.payment.resp.Result;
 
 import java.util.List;
@@ -22,4 +23,10 @@ public interface CommodityProcureService {
      * 单商品进货(独立事务),传入cates列表自动解析分类
      */
     Result procureSingleGoods(Integer uniacid, Integer gdId, Integer mallid, List<Long> cates);
+
+    /**
+     * 供货/停止供货:把本地商品推到云商城,或从云商城停止供货
+     * 对应PHP goods.commodity.supply
+     */
+    Result fullOutput(GoodsSupplyReq req);
 }

+ 246 - 0
src/main/java/zs/payment/service/commodity/impl/CommodityProcureServiceImpl.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
@@ -23,7 +24,9 @@ import zs.payment.exception.ApiException;
 import zs.payment.mapper.primary.ImsEweiShopApplyMapper;
 import zs.payment.mapper.primary.ImsEweiShopGoodsMapper;
 import zs.payment.req.CommodityProcureReq;
+import zs.payment.req.GoodsSupplyReq;
 import zs.payment.resp.Result;
+import zs.payment.utils.HttpUtil;
 import zs.payment.service.Imseweishopgoods.ImsEweiShopGoodsService;
 import zs.payment.service.imseweishopcategory.ImsEweiShopCategoryService;
 import zs.payment.service.imseweishopgoodsoption.ImsEweiShopGoodsOptionService;
@@ -88,6 +91,9 @@ public class CommodityProcureServiceImpl implements CommodityProcureService {
     private static final BigDecimal COMMISSION_DEFAULT_RATE = new BigDecimal("0.01");
     private static final Integer JD_SHOP_ID = 11507;
 
+    @Value("${mall.host:}")
+    private String mallHost;
+
     @Override
     public Result procureGoods(CommodityProcureReq req) {
         Integer uniacid = req.getUniacid();
@@ -693,4 +699,244 @@ public class CommodityProcureServiceImpl implements CommodityProcureService {
         }
         return list.stream().map(String::valueOf).collect(Collectors.joining(","));
     }
+
+    // ==================== 供货 fullOutput ====================
+
+    @Override
+    public Result fullOutput(GoodsSupplyReq req) {
+        Integer uniacid = req.getUniacid();
+        Integer issupply = req.getIssupply();
+        Integer cate = req.getCate();
+        List<Long> goodsIds = req.getGoodsIds();
+
+        // 1. 查询在云商城中的店铺id(需要supplystatus=1)
+        ImsEweiShopApply apply = applyMapper.selectOne(new LambdaQueryWrapper<ImsEweiShopApply>()
+                .eq(ImsEweiShopApply::getUniacid, uniacid)
+                .eq(ImsEweiShopApply::getMerchid, 0)
+                .eq(ImsEweiShopApply::getMallStatus, 1)
+                .eq(ImsEweiShopApply::getShopStatus, 1)
+                .eq(ImsEweiShopApply::getSupplystatus, 1)
+                .last("LIMIT 1"));
+        if (apply == null) {
+            throw new ApiException("店铺不存在!");
+        }
+
+        // 2. 判断在云商城中是否有配送方式
+        String checkExpressUrl = mallHost + "/checkExpress?shop_id=" + apply.getStoreid();
+        try {
+            String expressResp = HttpUtil.restTemplateGet(checkExpressUrl, null);
+            log.info("配送方式查询 storeid={}, url={}, resp={}", apply.getStoreid(), checkExpressUrl, expressResp);
+            JSONObject expressJson = JSON.parseObject(expressResp);
+            if (expressJson == null || expressJson.getIntValue("head") != 200) {
+                throw new ApiException("配送方式查询失败!");
+            }
+            if (expressJson.getJSONObject("result") != null
+                    && expressJson.getJSONObject("result").getIntValue("hasExpress") == 2) {
+                throw new ApiException("请添加配送方式!");
+            }
+        } catch (ApiException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error("配送方式查询异常 storeid={}", apply.getStoreid(), e);
+            throw new ApiException("配送方式查询失败!");
+        }
+
+        // 3. 供货时品类必填
+        if (issupply == 1 && (cate == null || cate == 0)) {
+            throw new ApiException("请选择品类!");
+        }
+
+        // 4. 查询商品列表
+        List<ImsEweiShopGoods> items = new ArrayList<>(goodsService.listByIds(goodsIds));
+
+        for (ImsEweiShopGoods item : items) {
+            if (!issupply.equals(item.getIssupply())) {
+                if (issupply == 1) {
+                    // === 供货流程 ===
+                    supplyGoodsToMall(item, apply, cate, uniacid);
+                } else {
+                    // === 停止供货流程 ===
+                    stopSupplyFromMall(item, apply, uniacid);
+                }
+                // 更新供货状态
+                ImsEweiShopGoods update = new ImsEweiShopGoods();
+                update.setId(item.getId());
+                update.setIssupply(issupply);
+                goodsService.updateById(update);
+            }
+        }
+
+        return Result.success();
+    }
+
+    /**
+     * 供货:将本地商品推送到云商城
+     * 对应PHP supply()中issupply==1的逻辑(929-1014行)
+     */
+    private void supplyGoodsToMall(ImsEweiShopGoods item, ImsEweiShopApply apply, Integer cate, Integer uniacid) {
+        Long goodsId = item.getId();
+
+        // 多规格时取最大重量
+        if (item.getHasoption() != null && item.getHasoption() == 1) {
+            ImsEweiShopGoodsOption maxWeightOpt = optionService.getOne(new LambdaQueryWrapper<ImsEweiShopGoodsOption>()
+                    .eq(ImsEweiShopGoodsOption::getGoodsid, goodsId.intValue())
+                    .eq(ImsEweiShopGoodsOption::getUniacid, uniacid)
+                    .orderByDesc(ImsEweiShopGoodsOption::getWeight)
+                    .last("LIMIT 1"));
+            if (maxWeightOpt != null && maxWeightOpt.getWeight() != null) {
+                item.setWeight(maxWeightOpt.getWeight());
+            }
+        }
+
+        // 构建供货数据
+        Map<String, Object> addgoods = new LinkedHashMap<>();
+        addgoods.put("gd_name", item.getTitle());
+        addgoods.put("shop_id", apply.getStoreid());
+        addgoods.put("pt_id", cate);
+        addgoods.put("gd_weight", item.getWeight());
+        addgoods.put("gd_price", item.getMarketprice());         // 供货中心售价=商城售价
+        addgoods.put("mk_price", item.getProductprice());         // 市场价
+        addgoods.put("cost_price", item.getCostprice());          // 成本价/供货价
+        addgoods.put("gd_stock", item.getTotal());                // 库存
+        addgoods.put("msg1", item.getContent());                  // 商品详情
+        addgoods.put("uniacid", uniacid);
+        addgoods.put("merchid", 0);
+        addgoods.put("storeid", 0);
+        addgoods.put("goodsid", goodsId.intValue());
+
+        // 图片处理:thumb + thumb_url → imgsInfo数组
+        List<String> imgsInfo = new ArrayList<>();
+        if (item.getThumb() != null) {
+            imgsInfo.add(item.getThumb());  // 首图
+        }
+        if (item.getThumb_url() != null && !item.getThumb_url().isEmpty()) {
+            try {
+                List<String> extraImgs = JSON.parseArray(item.getThumb_url(), String.class);
+                if (extraImgs != null) {
+                    imgsInfo.addAll(extraImgs);
+                }
+            } catch (Exception e) {
+                log.warn("thumb_url解析失败 goodsId={}", goodsId, e);
+            }
+        }
+        addgoods.put("imgsInfo", JSON.toJSONString(imgsInfo));
+
+        // 规格列表
+        List<ImsEweiShopGoodsSpec> specs = specService.list(new LambdaQueryWrapper<ImsEweiShopGoodsSpec>()
+                .eq(ImsEweiShopGoodsSpec::getGoodsid, goodsId.intValue())
+                .eq(ImsEweiShopGoodsSpec::getUniacid, uniacid));
+
+        List<Map<String, Object>> specsList = new ArrayList<>();
+        for (ImsEweiShopGoodsSpec spec : specs) {
+            if (spec.getTitle() == null || spec.getTitle().isEmpty()) {
+                throw new ApiException("规格名称为空不能供货");
+            }
+            Map<String, Object> specMap = new LinkedHashMap<>();
+            specMap.put("id", spec.getId());
+            specMap.put("title", spec.getTitle());
+
+            List<ImsEweiShopGoodsSpecItem> speItems = specItemService.list(
+                    new LambdaQueryWrapper<ImsEweiShopGoodsSpecItem>()
+                            .eq(ImsEweiShopGoodsSpecItem::getSpecid, spec.getId().intValue())
+                            .eq(ImsEweiShopGoodsSpecItem::getUniacid, uniacid));
+
+            List<Map<String, Object>> valuesList = new ArrayList<>();
+            for (ImsEweiShopGoodsSpecItem speItem : speItems) {
+                Map<String, Object> valMap = new LinkedHashMap<>();
+                valMap.put("id", speItem.getId());
+                valMap.put("title", speItem.getTitle());
+                valMap.put("sku_img", speItem.getThumb() != null ? speItem.getThumb() : "");
+                valuesList.add(valMap);
+            }
+            specMap.put("values", valuesList);
+            specsList.add(specMap);
+        }
+        addgoods.put("specslist", JSON.toJSONString(specsList));
+
+        // SKU选项列表
+        List<ImsEweiShopGoodsOption> options = optionService.list(new LambdaQueryWrapper<ImsEweiShopGoodsOption>()
+                .eq(ImsEweiShopGoodsOption::getGoodsid, goodsId.intValue())
+                .eq(ImsEweiShopGoodsOption::getUniacid, uniacid));
+
+        List<Map<String, Object>> optionsList = new ArrayList<>();
+        for (ImsEweiShopGoodsOption opt : options) {
+            Map<String, Object> optMap = new LinkedHashMap<>();
+            optMap.put("id", opt.getId());
+            optMap.put("title", opt.getTitle());
+            optMap.put("gd_weight", opt.getWeight());
+            optMap.put("gd_price", opt.getMarketprice());             // 供货中心售价=商城售价
+            optMap.put("mk_price", opt.getProductprice());             // 市场价
+            optMap.put("cost_price", item.getCostprice());             // 供货价统一取商品级
+            optMap.put("gd_stock", opt.getStock());
+            optMap.put("specs", opt.getSpecs());
+            optionsList.add(optMap);
+        }
+        addgoods.put("optionslist", JSON.toJSONString(optionsList));
+
+        // 查重:是否已在云商城供货(通过gd_id判断)
+        if (item.getGd_id() != null && item.getGd_id() > 0) {
+            throw new ApiException("商品已经供货");
+        }
+
+        // 调用云商城接口创建商品
+        String addGoodsUrl = mallHost + "/addGoods";
+        String content;
+        try {
+            content = HttpUtil.restTemplatePost(addGoodsUrl, addgoods);
+        } catch (Exception e) {
+            log.error("云商城addGoods接口调用失败 goodsId={}", goodsId, e);
+            throw new ApiException("云商城接口调用失败: " + e.getMessage());
+        }
+
+        log.info("云商城插入商品 goodsId={}, uniacid={}, url={}, response={}", goodsId, uniacid, addGoodsUrl, content);
+
+        JSONObject result = JSON.parseObject(content);
+        if (result == null || result.getIntValue("head") != 200) {
+            String msg = result != null && result.getString("msg") != null ? result.getString("msg") : "供货失败!";
+            throw new ApiException(msg);
+        }
+
+        // 回写云商城商品ID
+        Integer gdId = result.getJSONObject("result") != null
+                ? result.getJSONObject("result").getInteger("goods_id") : null;
+        if (gdId != null) {
+            ImsEweiShopGoods update = new ImsEweiShopGoods();
+            update.setId(goodsId);
+            update.setGd_id(gdId);
+            goodsService.updateById(update);
+        }
+    }
+
+    /**
+     * 停止供货:通知云商城停止供货
+     * 对应PHP supply()中issupply==0的逻辑(1015-1034行)
+     */
+    private void stopSupplyFromMall(ImsEweiShopGoods item, ImsEweiShopApply apply, Integer uniacid) {
+        if (item.getGd_id() == null || item.getGd_id() == 0) {
+            throw new ApiException("该商品未在云商城供货,无法停止供货");
+        }
+
+        // 调用云商城接口通知停止供货
+        String changeStatusUrl = mallHost + "/changeStatus?shop_id=" + apply.getStoreid()
+                + "&gd_id=" + item.getGd_id() + "&status=2";
+        try {
+            String resp = HttpUtil.restTemplateGet(changeStatusUrl, null);
+            log.info("云商城停止供货 goodsId={}, gd_id={}, url={}, resp={}", item.getId(), item.getGd_id(), changeStatusUrl, resp);
+            JSONObject result = JSON.parseObject(resp);
+            if (result == null || result.getIntValue("head") != 200) {
+                throw new ApiException("停止供货失败!");
+            }
+        } catch (ApiException e) {
+            throw e;
+        } catch (Exception e) {
+            log.error("云商城停止供货接口异常 goodsId={}", item.getId(), e);
+            throw new ApiException("停止供货接口调用失败!");
+        }
+
+        // 停止供货时取消推荐状态
+        ImsEweiShopGoods update = new ImsEweiShopGoods();
+        update.setId(item.getId());
+        update.setIssupply_recommend(0);
+        goodsService.updateById(update);
+    }
 }

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

@@ -67,6 +67,10 @@ supply:
     appSecret: 80694edd4a7da03f3c35473f27603967
     demain: https://yx.gz.cn
 
+mall:
+    java-host: http://mall.zhongsou.com/ptmall/yuemall/qiyueapi/
+    host: http://mall.zhongsou.com/qiyueapi/api
+