feat(pdd): 增加 latest-commit-status 外部接口转发 POP 审核状态查询
新增 POST /external/pdd/goods/latest-commit-status,调用 pdd.goods.latest.commit.status.get; 请求体含 pddGoodsIds 与 pddPopAuth,与 detail 接口鉴权形态一致。 Made-with: Cursor
This commit is contained in:
parent
e8565b4392
commit
29ccdd6ea0
|
|
@ -2,11 +2,13 @@ package cn.qihangerp.erp.controller;
|
||||||
|
|
||||||
import cn.qihangerp.common.AjaxResult;
|
import cn.qihangerp.common.AjaxResult;
|
||||||
import cn.qihangerp.model.request.ExternalPddGoodsDetailRequest;
|
import cn.qihangerp.model.request.ExternalPddGoodsDetailRequest;
|
||||||
|
import cn.qihangerp.model.request.ExternalPddGoodsLatestCommitStatusRequest;
|
||||||
import cn.qihangerp.model.vo.ExternalPddGoodsDetailResultVo;
|
import cn.qihangerp.model.vo.ExternalPddGoodsDetailResultVo;
|
||||||
import cn.qihangerp.security.common.BaseController;
|
import cn.qihangerp.security.common.BaseController;
|
||||||
import cn.qihangerp.erp.config.ExternalGoodsApiLogProperties;
|
import cn.qihangerp.erp.config.ExternalGoodsApiLogProperties;
|
||||||
import cn.qihangerp.erp.support.ExternalGoodsRequestLogSupport;
|
import cn.qihangerp.erp.support.ExternalGoodsRequestLogSupport;
|
||||||
import cn.qihangerp.service.external.ExternalPddGoodsDetailAppService;
|
import cn.qihangerp.service.external.ExternalPddGoodsDetailAppService;
|
||||||
|
import cn.qihangerp.service.external.ExternalPddGoodsLatestCommitStatusAppService;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
@ -19,6 +21,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
* 拼多多专用外部接口(与 {@code /external/goods/upsert} 编排解耦)。
|
* 拼多多专用外部接口(与 {@code /external/goods/upsert} 编排解耦)。
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code POST /external/pdd/goods/detail} — {@code pdd.goods.detail.get}</li>
|
* <li>{@code POST /external/pdd/goods/detail} — {@code pdd.goods.detail.get}</li>
|
||||||
|
* <li>{@code POST /external/pdd/goods/latest-commit-status} — {@code pdd.goods.latest.commit.status.get}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>改库存请使用 {@code POST /external/goods/pdd/quantity/update}(与 upsert 相同 out 键)。</p>
|
* <p>改库存请使用 {@code POST /external/goods/pdd/quantity/update}(与 upsert 相同 out 键)。</p>
|
||||||
*/
|
*/
|
||||||
|
|
@ -29,6 +32,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
public class ExternalPddGoodsController extends BaseController {
|
public class ExternalPddGoodsController extends BaseController {
|
||||||
|
|
||||||
private final ExternalPddGoodsDetailAppService externalPddGoodsDetailAppService;
|
private final ExternalPddGoodsDetailAppService externalPddGoodsDetailAppService;
|
||||||
|
private final ExternalPddGoodsLatestCommitStatusAppService externalPddGoodsLatestCommitStatusAppService;
|
||||||
private final ExternalGoodsApiLogProperties goodsApiLogProperties;
|
private final ExternalGoodsApiLogProperties goodsApiLogProperties;
|
||||||
|
|
||||||
@PostMapping("/detail")
|
@PostMapping("/detail")
|
||||||
|
|
@ -53,4 +57,28 @@ public class ExternalPddGoodsController extends BaseController {
|
||||||
}
|
}
|
||||||
return AjaxResult.success(vo);
|
return AjaxResult.success(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/latest-commit-status")
|
||||||
|
public AjaxResult latestCommitStatus(@RequestBody ExternalPddGoodsLatestCommitStatusRequest req) {
|
||||||
|
if (goodsApiLogProperties.isLogFullRequest()) {
|
||||||
|
log.info("[external/pdd/goods/latest-commit-status] goodsIdCount={}",
|
||||||
|
req != null && req.getPddGoodsIds() != null ? req.getPddGoodsIds().size() : 0);
|
||||||
|
}
|
||||||
|
if (req == null || req.getPddGoodsIds() == null || req.getPddGoodsIds().isEmpty()) {
|
||||||
|
return AjaxResult.error("参数错误:pddGoodsIds 不能为空");
|
||||||
|
}
|
||||||
|
if (req.getPddPopAuth() == null) {
|
||||||
|
return AjaxResult.error("参数错误:pddPopAuth 不能为空");
|
||||||
|
}
|
||||||
|
var auth = req.getPddPopAuth();
|
||||||
|
if (!StringUtils.hasText(auth.getAppKey()) || !StringUtils.hasText(auth.getAppSecret())
|
||||||
|
|| !StringUtils.hasText(auth.getAccessToken())) {
|
||||||
|
return AjaxResult.error("参数错误:pddPopAuth 需提供 appKey、appSecret、accessToken");
|
||||||
|
}
|
||||||
|
ExternalPddGoodsDetailResultVo vo = externalPddGoodsLatestCommitStatusAppService.fetchLatestCommitStatus(req);
|
||||||
|
if (!Boolean.TRUE.equals(vo.getPopBizSuccess())) {
|
||||||
|
return AjaxResult.error(StringUtils.hasText(vo.getMessage()) ? vo.getMessage() : "pdd.goods.latest.commit.status.get 失败");
|
||||||
|
}
|
||||||
|
return AjaxResult.success(vo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package cn.qihangerp.model.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code POST /external/pdd/goods/latest-commit-status}:转发 {@code pdd.goods.latest.commit.status.get}。
|
||||||
|
* <p>凭证形态与 {@link ExternalPddGoodsDetailRequest#getPddPopAuth()} 一致。</p>
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ExternalPddGoodsLatestCommitStatusRequest {
|
||||||
|
|
||||||
|
/** 待查询的拼多多 {@code goods_id} 列表(将序列化为 POP 顶层 {@code goods_id_list}) */
|
||||||
|
private List<Long> pddGoodsIds;
|
||||||
|
|
||||||
|
private ExternalGoodsUpsertRequest.PddPopAuth pddPopAuth;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cn.qihangerp.service.external;
|
||||||
|
|
||||||
|
import cn.qihangerp.model.request.ExternalPddGoodsLatestCommitStatusRequest;
|
||||||
|
import cn.qihangerp.model.vo.ExternalPddGoodsDetailResultVo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼多多商品最新提交审核状态({@code pdd.goods.latest.commit.status.get}),薄封装,不做业务状态机。
|
||||||
|
*/
|
||||||
|
public interface ExternalPddGoodsLatestCommitStatusAppService {
|
||||||
|
|
||||||
|
ExternalPddGoodsDetailResultVo fetchLatestCommitStatus(ExternalPddGoodsLatestCommitStatusRequest req);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
package cn.qihangerp.service.external.impl;
|
||||||
|
|
||||||
|
import cn.qihangerp.model.request.ExternalGoodsUpsertRequest;
|
||||||
|
import cn.qihangerp.model.request.ExternalPddGoodsLatestCommitStatusRequest;
|
||||||
|
import cn.qihangerp.model.vo.ExternalPddGoodsDetailResultVo;
|
||||||
|
import cn.qihangerp.service.external.ExternalPddGoodsLatestCommitStatusAppService;
|
||||||
|
import cn.qihangerp.service.external.pdd.ExternalPddProperties;
|
||||||
|
import cn.qihangerp.service.external.pdd.PddOpenApiSupport;
|
||||||
|
import cn.qihangerp.service.external.pdd.PddPopClient;
|
||||||
|
import cn.qihangerp.service.external.shop.PddShopCredential;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仅调用 POP,返回原始 JSON 供主数据解析 {@code goods_latest_commit_status_get_response}。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ExternalPddGoodsLatestCommitStatusAppServiceImpl implements ExternalPddGoodsLatestCommitStatusAppService {
|
||||||
|
|
||||||
|
private final ExternalPddProperties props;
|
||||||
|
private final PddPopClient pddPopClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExternalPddGoodsDetailResultVo fetchLatestCommitStatus(ExternalPddGoodsLatestCommitStatusRequest req) {
|
||||||
|
if (req == null || CollectionUtils.isEmpty(req.getPddGoodsIds())) {
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(false)
|
||||||
|
.message("pddGoodsIds 不能为空")
|
||||||
|
.popResponseBody(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
PddShopCredential cred = resolveCredential(req);
|
||||||
|
if (cred == null || !StringUtils.hasText(cred.getAppKey()) || !StringUtils.hasText(cred.getAppSecret())
|
||||||
|
|| !StringUtils.hasText(cred.getAccessToken())) {
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(false)
|
||||||
|
.message("pddPopAuth 不完整:需 appKey、appSecret、accessToken")
|
||||||
|
.popResponseBody(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
String gateway = StringUtils.hasText(cred.getGatewayUrl()) ? cred.getGatewayUrl() : props.getGatewayUrl();
|
||||||
|
if (!StringUtils.hasText(gateway)) {
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(false)
|
||||||
|
.message("未配置 POP gatewayUrl(请求体或 external.pdd.gateway-url)")
|
||||||
|
.popResponseBody(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
List<Long> ids = req.getPddGoodsIds().stream().filter(id -> id != null && id > 0).toList();
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(false)
|
||||||
|
.message("pddGoodsIds 无有效正数")
|
||||||
|
.popResponseBody(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String raw = pddPopClient.invokeTopLevelBiz(
|
||||||
|
gateway,
|
||||||
|
cred.getAppKey(),
|
||||||
|
cred.getAppSecret(),
|
||||||
|
cred.getAccessToken(),
|
||||||
|
"pdd.goods.latest.commit.status.get",
|
||||||
|
PddOpenApiSupport.goodsLatestCommitStatusGetTopLevelParams(ids));
|
||||||
|
boolean ok = !PddOpenApiSupport.isError(raw);
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(ok)
|
||||||
|
.message(ok ? "pdd.goods.latest.commit.status.get 调用成功" : ("pdd.goods.latest.commit.status.get 失败: " + PddOpenApiSupport.formatError(raw)))
|
||||||
|
.popResponseBody(raw)
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[PDD] pdd.goods.latest.commit.status.get exception err={}", e.getMessage(), e);
|
||||||
|
return ExternalPddGoodsDetailResultVo.builder()
|
||||||
|
.popBizSuccess(false)
|
||||||
|
.message(e.getMessage())
|
||||||
|
.popResponseBody(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PddShopCredential resolveCredential(ExternalPddGoodsLatestCommitStatusRequest req) {
|
||||||
|
if (req == null || req.getPddPopAuth() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ExternalGoodsUpsertRequest.PddPopAuth a = req.getPddPopAuth();
|
||||||
|
PddShopCredential c = new PddShopCredential();
|
||||||
|
c.setAppKey(trimToNull(a.getAppKey()));
|
||||||
|
c.setAppSecret(trimToNull(a.getAppSecret()));
|
||||||
|
c.setAccessToken(trimToNull(a.getAccessToken()));
|
||||||
|
if (StringUtils.hasText(a.getGatewayUrl())) {
|
||||||
|
c.setGatewayUrl(a.getGatewayUrl().trim());
|
||||||
|
}
|
||||||
|
c.setSource("REQUEST");
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String trimToNull(String s) {
|
||||||
|
if (!StringUtils.hasText(s)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return s.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -51,6 +51,27 @@ public final class PddOpenApiSupport {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code pdd.goods.latest.commit.status.get}:与官方 POP 一致,业务参数在表单顶层;{@code goods_id_list} 为 JSON 数组字符串(如 {@code [123,456]})。
|
||||||
|
*/
|
||||||
|
public static Map<String, String> goodsLatestCommitStatusGetTopLevelParams(List<Long> goodsIds) {
|
||||||
|
if (goodsIds == null || goodsIds.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("goods_id_list 不能为空");
|
||||||
|
}
|
||||||
|
List<Long> sanitized = new ArrayList<>();
|
||||||
|
for (Long id : goodsIds) {
|
||||||
|
if (id != null && id > 0) {
|
||||||
|
sanitized.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sanitized.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("goods_id_list 无有效 goods_id");
|
||||||
|
}
|
||||||
|
Map<String, String> m = new LinkedHashMap<>();
|
||||||
|
m.put("goods_id_list", JSON.toJSONString(sanitized));
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code pdd.goods.quantity.update} 表单顶层参数(与 POP 官方 curl / Java SDK 一致:{@code goods_id}、{@code sku_id}、{@code quantity}、
|
* {@code pdd.goods.quantity.update} 表单顶层参数(与 POP 官方 curl / Java SDK 一致:{@code goods_id}、{@code sku_id}、{@code quantity}、
|
||||||
* {@code update_type}、{@code force_update}、可选 {@code outer_id})。
|
* {@code update_type}、{@code force_update}、可选 {@code outer_id})。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue