refactor(pdd): 发品/更新成功后不再自动拉 detail.get,由主数据发起
Made-with: Cursor
This commit is contained in:
parent
29ccdd6ea0
commit
03a45c3eb4
|
|
@ -3,12 +3,9 @@ package cn.qihangerp.service.external.pdd;
|
||||||
import cn.qihangerp.model.entity.OGoods;
|
import cn.qihangerp.model.entity.OGoods;
|
||||||
import cn.qihangerp.model.entity.OGoodsSku;
|
import cn.qihangerp.model.entity.OGoodsSku;
|
||||||
import cn.qihangerp.model.request.ExternalGoodsUpsertRequest;
|
import cn.qihangerp.model.request.ExternalGoodsUpsertRequest;
|
||||||
import cn.qihangerp.model.request.ExternalPddGoodsDetailRequest;
|
|
||||||
import cn.qihangerp.model.vo.ExternalGoodsUpsertResultVo;
|
import cn.qihangerp.model.vo.ExternalGoodsUpsertResultVo;
|
||||||
import cn.qihangerp.model.vo.ExternalPddGoodsDetailResultVo;
|
|
||||||
import cn.qihangerp.module.service.OGoodsService;
|
import cn.qihangerp.module.service.OGoodsService;
|
||||||
import cn.qihangerp.module.service.OGoodsSkuService;
|
import cn.qihangerp.module.service.OGoodsSkuService;
|
||||||
import cn.qihangerp.service.external.ExternalPddGoodsDetailAppService;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
|
@ -27,8 +24,9 @@ import java.util.Map;
|
||||||
* 各渠道在 {@code o_goods}/{@code o_goods_sku}.{@code canonicalExt} 使用<strong>独立键名</strong>(拼多多为 {@value #CANONICAL_PDD_GOODS_ID}、{@value #CANONICAL_PDD_SKU_ID}),
|
* 各渠道在 {@code o_goods}/{@code o_goods_sku}.{@code canonicalExt} 使用<strong>独立键名</strong>(拼多多为 {@value #CANONICAL_PDD_GOODS_ID}、{@value #CANONICAL_PDD_SKU_ID}),
|
||||||
* 未来京东/天猫可并行增加 {@code jdSkuId} 等,改库存接口按平台从本库解析后再调 POP。</p>
|
* 未来京东/天猫可并行增加 {@code jdSkuId} 等,改库存接口按平台从本库解析后再调 POP。</p>
|
||||||
*
|
*
|
||||||
* <p>拼多多:{@code pdd.goods.add} 响应可解析 SKU 映射;{@code pdd.goods.information.update} 往往不带 {@code sku_list},
|
* <p>拼多多:仅根据 {@code pdd.goods.add} 成功响应中的 {@code sku_list} 回填 {@value #CANONICAL_PDD_SKU_ID};<strong>不在本服务内</strong>调用
|
||||||
* 因此在 upsert 成功后若仍有 SKU 未写入 {@value #CANONICAL_PDD_SKU_ID},将自动补调 {@code pdd.goods.detail.get} 回填。</p>
|
* {@code pdd.goods.detail.get}。{@code pdd.goods.information.update} 若未带 {@code sku_list},则 {@code pddSkuId} 须由主数据在适当时机
|
||||||
|
* 调 {@code POST /external/pdd/goods/detail} 后自行落库或后续扩展同步接口写回 ERP(当前 detail 接口仅返回 JSON 给调用方)。</p>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
|
@ -40,12 +38,12 @@ public class OGoodsPddMappingPersistence {
|
||||||
|
|
||||||
private final OGoodsService goodsService;
|
private final OGoodsService goodsService;
|
||||||
private final OGoodsSkuService skuService;
|
private final OGoodsSkuService skuService;
|
||||||
private final ExternalPddGoodsDetailAppService externalPddGoodsDetailAppService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在 upsert 拼多多链路成功({@link ExternalGoodsUpsertResultVo#getPddPublishSuccess()}==true)后调用。
|
* 在 upsert 拼多多链路成功({@link ExternalGoodsUpsertResultVo#getPddPublishSuccess()}==true)后调用。
|
||||||
|
* <p>只落 {@code pddGoodsId},以及 {@code GOODS_ADD} 响应片段中能解析到的 SKU 映射;不发起 {@code detail.get}。</p>
|
||||||
*
|
*
|
||||||
* @param req 用于携带 {@code pddPopAuth},在需补拉 {@code pdd.goods.detail.get} 时使用;可为 {@code null}(则无法补全 SKU 映射)
|
* @param req 保留入参供调用方兼容;本方法不再使用 {@code pddPopAuth} 拉 detail
|
||||||
*/
|
*/
|
||||||
public void persistAfterPddPublishSuccess(Long erpGoodsId, ExternalGoodsUpsertRequest req,
|
public void persistAfterPddPublishSuccess(Long erpGoodsId, ExternalGoodsUpsertRequest req,
|
||||||
ExternalGoodsUpsertResultVo vo) {
|
ExternalGoodsUpsertResultVo vo) {
|
||||||
|
|
@ -75,38 +73,9 @@ public class OGoodsPddMappingPersistence {
|
||||||
log.info("[PDD] persisted pddGoodsId + sku from GOODS_ADD snippet erpGoodsId={} lane={} skuRowsUpdated={}",
|
log.info("[PDD] persisted pddGoodsId + sku from GOODS_ADD snippet erpGoodsId={} lane={} skuRowsUpdated={}",
|
||||||
erpGoodsId, lane, fromAdd);
|
erpGoodsId, lane, fromAdd);
|
||||||
} else {
|
} else {
|
||||||
log.info("[PDD] persisted pddGoodsId on o_goods (no GOODS_ADD sku_list) erpGoodsId={} lane={}",
|
log.info("[PDD] persisted pddGoodsId on o_goods (no GOODS_ADD sku_list; no ERP-side detail.get) erpGoodsId={} lane={}",
|
||||||
erpGoodsId, lane);
|
erpGoodsId, lane);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!anySkuMissingPddSkuId(erpGoodsId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (req == null || req.getPddPopAuth() == null) {
|
|
||||||
log.warn("[PDD] skip detail.get backfill: missing pddPopAuth erpGoodsId={} lane={}",
|
|
||||||
erpGoodsId, lane);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalPddGoodsDetailRequest dreq = new ExternalPddGoodsDetailRequest();
|
|
||||||
dreq.setPddGoodsId(pddGoodsId);
|
|
||||||
dreq.setPddPopAuth(req.getPddPopAuth());
|
|
||||||
ExternalPddGoodsDetailResultVo detailVo = externalPddGoodsDetailAppService.fetchGoodsDetail(dreq);
|
|
||||||
if (!Boolean.TRUE.equals(detailVo.getPopBizSuccess()) || !StringUtils.hasText(detailVo.getPopResponseBody())) {
|
|
||||||
log.warn("[PDD] detail.get backfill failed erpGoodsId={} pddGoodsId={} msg={}",
|
|
||||||
erpGoodsId, pddGoodsId, detailVo.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Map<String, Long> fromDetail =
|
|
||||||
PddOpenApiSupport.parseOuterKeyToPddSkuIdFromGoodsDetailGetResponse(detailVo.getPopResponseBody());
|
|
||||||
int fromDetailCount = applyPddSkuMappings(erpGoodsId, fromDetail);
|
|
||||||
if (fromDetailCount > 0) {
|
|
||||||
log.info("[PDD] detail.get backfill applied erpGoodsId={} pddGoodsId={} skuRowsUpdated={}",
|
|
||||||
erpGoodsId, pddGoodsId, fromDetailCount);
|
|
||||||
} else if (anySkuMissingPddSkuId(erpGoodsId)) {
|
|
||||||
log.warn("[PDD] detail.get ok but no sku_id matched outer_erp_sku_id erpGoodsId={} pddGoodsId={}",
|
|
||||||
erpGoodsId, pddGoodsId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -140,39 +109,6 @@ public class OGoodsPddMappingPersistence {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean anySkuMissingPddSkuId(Long erpGoodsId) {
|
|
||||||
List<OGoodsSku> rows = skuService.list(new LambdaQueryWrapper<OGoodsSku>()
|
|
||||||
.eq(OGoodsSku::getGoodsId, erpGoodsId));
|
|
||||||
if (rows == null || rows.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (OGoodsSku row : rows) {
|
|
||||||
if (row == null || !StringUtils.hasText(row.getOuterErpSkuId())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Long v = readCanonicalLong(row.getCanonicalExt(), CANONICAL_PDD_SKU_ID);
|
|
||||||
if (v == null || v <= 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Long readCanonicalLong(String json, String key) {
|
|
||||||
if (!StringUtils.hasText(json) || !StringUtils.hasText(key)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
JSONObject o = JSON.parseObject(json);
|
|
||||||
if (o == null || !o.containsKey(key)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return o.getLong(key);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String mergeJsonLongField(String existingJson, String field, long value) {
|
private static String mergeJsonLongField(String existingJson, String field, long value) {
|
||||||
JSONObject o;
|
JSONObject o;
|
||||||
if (StringUtils.hasText(existingJson)) {
|
if (StringUtils.hasText(existingJson)) {
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ public final class PddOpenApiSupport {
|
||||||
/**
|
/**
|
||||||
* 从 {@code pdd.goods.detail.get} 成功响应中解析 {@code goods_detail_get_response.sku_list[]},
|
* 从 {@code pdd.goods.detail.get} 成功响应中解析 {@code goods_detail_get_response.sku_list[]},
|
||||||
* 与 {@link #parseOuterKeyToPddSkuIdFromGoodsAddResponse} 对齐:按 {@code out_sku_sn}/{@code outer_id}/{@code out_sku_id} 映射拼多多 {@code sku_id}。
|
* 与 {@link #parseOuterKeyToPddSkuIdFromGoodsAddResponse} 对齐:按 {@code out_sku_sn}/{@code outer_id}/{@code out_sku_id} 映射拼多多 {@code sku_id}。
|
||||||
* <p>用于 {@code INFORMATION_UPDATE} 等未返回 {@code goods_add_response.sku_list} 的发品路径之后,在 ERP 本地补全 {@code o_goods_sku.canonicalExt.pddSkuId}。</p>
|
* <p>供调用方(如主数据在拉 {@code /external/pdd/goods/detail} 后)解析 SKU 映射;ERP-Open 发品/更新成功后<strong>不再</strong>自动调 detail 写 {@code o_goods_sku}。</p>
|
||||||
*/
|
*/
|
||||||
public static Map<String, Long> parseOuterKeyToPddSkuIdFromGoodsDetailGetResponse(String raw) {
|
public static Map<String, Long> parseOuterKeyToPddSkuIdFromGoodsDetailGetResponse(String raw) {
|
||||||
Map<String, Long> out = new LinkedHashMap<>();
|
Map<String, Long> out = new LinkedHashMap<>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue