增加抢购货品接口
This commit is contained in:
@@ -132,21 +132,19 @@ public class LbGoodsController {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "抢购货品",
|
summary = "抢购货品",
|
||||||
description =
|
description =
|
||||||
"按 idList 查询 lb_goods,再使用 token 调用 hxrd POST /api/order/buy(body: id、seller_id);"
|
"从 lb_goods 按 total_money 从大到小选取货品,调用 hxrd POST /api/order/buy(body: id、seller_id);"
|
||||||
+ "成功笔数达到 maxBuyCount 后停止继续请求;需配置 hxr.admin.goods-api-app-str")
|
+ "成功笔数达到 maxBuyCount 后停止;token 可选,未传时使用 hxr.admin.goods-api-token")
|
||||||
public ResponseEntity<Map<String, Object>> rushBuy(
|
public ResponseEntity<Map<String, Object>> rushBuy(
|
||||||
@Parameter(description = "token、maxBuyCount、idList", required = true)
|
@Parameter(description = "maxBuyCount 必填,token 可选", required = true)
|
||||||
@RequestBody LbGoodsRushBuyRequest request) {
|
@RequestBody LbGoodsRushBuyRequest request) {
|
||||||
Map<String, Object> result = lbGoodsService.rushBuy(
|
Map<String, Object> result =
|
||||||
request.getToken(), request.getMaxBuyCount(), request.getIdList());
|
lbGoodsService.rushBuy(request.getToken(), request.getMaxBuyCount());
|
||||||
Boolean success = (Boolean) result.get("success");
|
Boolean success = (Boolean) result.get("success");
|
||||||
if (success != null && success) {
|
if (success != null && success) {
|
||||||
return ResponseEntity.ok(result);
|
return ResponseEntity.ok(result);
|
||||||
}
|
}
|
||||||
if (result.get("message") != null
|
if (result.get("message") != null
|
||||||
&& (result.get("message").toString().contains("不能为空")
|
&& result.get("message").toString().contains("必须大于0")) {
|
||||||
|| result.get("message").toString().contains("必须大于0")
|
|
||||||
|| result.get("message").toString().contains("无有效id"))) {
|
|
||||||
return ResponseEntity.badRequest().body(result);
|
return ResponseEntity.badRequest().body(result);
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(result);
|
return ResponseEntity.ok(result);
|
||||||
|
|||||||
@@ -3,21 +3,16 @@ package com.rj.dto;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抢购请求:按货品 id 列表查询 {@code lb_goods},再调用 hxrd {@code /api/order/buy}。
|
* 抢购请求:按 {@code total_money} 从大到小选取货品,调用 hxrd {@code /api/order/buy}。
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "LB 货品抢购请求")
|
@Schema(description = "LB 货品抢购请求")
|
||||||
public class LbGoodsRushBuyRequest {
|
public class LbGoodsRushBuyRequest {
|
||||||
|
|
||||||
@Schema(description = "hxrd 接口请求头 token", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "hxrd 接口请求头 token;未传时使用 hxr.admin.goods-api-token")
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
@Schema(description = "最多成功抢购笔数(达到后停止继续请求)", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "最多成功抢购笔数(达到后停止继续请求)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Integer maxBuyCount;
|
private Integer maxBuyCount;
|
||||||
|
|
||||||
@Schema(description = "货品 id 列表(对应 lb_goods.id)", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
private List<Long> idList;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ public class HxrAdminBuyService {
|
|||||||
* @return {@code apiCode} 为 -1 表示 HTTP 或解析失败
|
* @return {@code apiCode} 为 -1 表示 HTTP 或解析失败
|
||||||
*/
|
*/
|
||||||
public BuyApiResult buy(long goodsId, long sellerId, String token) throws Exception {
|
public BuyApiResult buy(long goodsId, long sellerId, String token) throws Exception {
|
||||||
if (token == null || token.isBlank()) {
|
String resolvedToken = resolveToken(token);
|
||||||
return BuyApiResult.failure(-1, "token不能为空");
|
if (resolvedToken == null) {
|
||||||
|
return BuyApiResult.failure(-1, "未提供 token 且未配置 hxr.admin.goods-api-token");
|
||||||
}
|
}
|
||||||
String appStr = properties.getGoodsApiAppStr();
|
String appStr = properties.getGoodsApiAppStr();
|
||||||
if (appStr == null || appStr.isBlank()) {
|
if (appStr == null || appStr.isBlank()) {
|
||||||
@@ -78,7 +79,7 @@ public class HxrAdminBuyService {
|
|||||||
.header("Origin", properties.getGoodsApiOrigin())
|
.header("Origin", properties.getGoodsApiOrigin())
|
||||||
.header("Referer", properties.getGoodsApiReferer())
|
.header("Referer", properties.getGoodsApiReferer())
|
||||||
.header("User-Agent", USER_AGENT)
|
.header("User-Agent", USER_AGENT)
|
||||||
.header("token", token.trim())
|
.header("token", resolvedToken)
|
||||||
.header("S", sign)
|
.header("S", sign)
|
||||||
.header("T", String.valueOf(timestamp))
|
.header("T", String.valueOf(timestamp))
|
||||||
.header("N", noncestr)
|
.header("N", noncestr)
|
||||||
@@ -108,6 +109,18 @@ public class HxrAdminBuyService {
|
|||||||
return new BuyApiResult(code == 0, code, msg);
|
return new BuyApiResult(code == 0, code, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 优先使用入参 token,否则回退到配置 {@code goods-api-token}。 */
|
||||||
|
private String resolveToken(String token) {
|
||||||
|
if (token != null && !token.isBlank()) {
|
||||||
|
return token.trim();
|
||||||
|
}
|
||||||
|
String configured = properties.getGoodsApiToken();
|
||||||
|
if (configured != null && !configured.isBlank()) {
|
||||||
|
return configured.trim();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public record BuyApiResult(boolean success, int apiCode, String apiMsg) {
|
public record BuyApiResult(boolean success, int apiCode, String apiMsg) {
|
||||||
|
|
||||||
public static BuyApiResult failure(int code, String msg) {
|
public static BuyApiResult failure(int code, String msg) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.rj.service;
|
|||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.rj.entity.LbGoods;
|
import com.rj.entity.LbGoods;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface ILbGoodsService extends IService<LbGoods> {
|
public interface ILbGoodsService extends IService<LbGoods> {
|
||||||
@@ -35,7 +34,7 @@ public interface ILbGoodsService extends IService<LbGoods> {
|
|||||||
Map<String, Object> syncFromHxrGoods(String tenantId);
|
Map<String, Object> syncFromHxrGoods(String tenantId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按 id 列表查询 {@code lb_goods},使用 token 调用 hxrd {@code /api/order/buy} 抢购。
|
* 按 {@code total_money} 从大到小选取 {@code lb_goods},调用 hxrd {@code /api/order/buy} 抢购。
|
||||||
*/
|
*/
|
||||||
Map<String, Object> rushBuy(String token, Integer maxBuyCount, List<Long> idList);
|
Map<String, Object> rushBuy(String token, Integer maxBuyCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,81 +375,50 @@ public class LbGoodsServiceImpl extends ServiceImpl<LbGoodsMapper, LbGoods> impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> rushBuy(String token, Integer maxBuyCount, List<Long> idList) {
|
public Map<String, Object> rushBuy(String token, Integer maxBuyCount) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
if (token == null || token.isBlank()) {
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "token不能为空");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (maxBuyCount == null || maxBuyCount <= 0) {
|
if (maxBuyCount == null || maxBuyCount <= 0) {
|
||||||
result.put("success", false);
|
result.put("success", false);
|
||||||
result.put("message", "maxBuyCount必须大于0");
|
result.put("message", "maxBuyCount必须大于0");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (idList == null || idList.isEmpty()) {
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "idList不能为空");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Long> distinctIds = idList.stream()
|
LambdaQueryWrapper<LbGoods> w = new LambdaQueryWrapper<>();
|
||||||
.filter(id -> id != null)
|
w.isNotNull(LbGoods::getSellerId);
|
||||||
.distinct()
|
w.orderByDesc(LbGoods::getTotalMoney).orderByDesc(LbGoods::getId);
|
||||||
.toList();
|
List<LbGoods> goodsList = this.list(w);
|
||||||
if (distinctIds.isEmpty()) {
|
if (goodsList.isEmpty()) {
|
||||||
result.put("success", false);
|
result.put("success", false);
|
||||||
result.put("message", "idList无有效id");
|
result.put("message", "lb_goods 中无可抢购货品");
|
||||||
|
result.put("successCount", 0);
|
||||||
|
result.put("failCount", 0);
|
||||||
|
result.put("details", List.of());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<LbGoods> found = this.listByIds(distinctIds);
|
|
||||||
Map<Long, LbGoods> goodsById = new LinkedHashMap<>();
|
|
||||||
for (LbGoods goods : found) {
|
|
||||||
if (goods.getId() != null) {
|
|
||||||
goodsById.put(goods.getId(), goods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Map<String, Object>> details = new ArrayList<>();
|
List<Map<String, Object>> details = new ArrayList<>();
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
int failCount = 0;
|
int failCount = 0;
|
||||||
boolean stoppedByMax = false;
|
boolean stoppedByMax = false;
|
||||||
|
|
||||||
for (Long goodsId : idList) {
|
for (LbGoods goods : goodsList) {
|
||||||
if (goodsId == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (successCount >= maxBuyCount) {
|
if (successCount >= maxBuyCount) {
|
||||||
stoppedByMax = true;
|
stoppedByMax = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (goods.getId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> item = new LinkedHashMap<>();
|
Map<String, Object> item = new LinkedHashMap<>();
|
||||||
item.put("id", goodsId);
|
item.put("id", goods.getId());
|
||||||
|
|
||||||
LbGoods goods = goodsById.get(goodsId);
|
|
||||||
if (goods == null) {
|
|
||||||
item.put("success", false);
|
|
||||||
item.put("message", "lb_goods中未找到该货品");
|
|
||||||
details.add(item);
|
|
||||||
failCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (goods.getSellerId() == null) {
|
|
||||||
item.put("success", false);
|
|
||||||
item.put("message", "seller_id为空,无法抢购");
|
|
||||||
details.add(item);
|
|
||||||
failCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.put("sellerId", goods.getSellerId());
|
item.put("sellerId", goods.getSellerId());
|
||||||
item.put("title", goods.getTitle());
|
item.put("title", goods.getTitle());
|
||||||
|
item.put("totalMoney", goods.getTotalMoney());
|
||||||
|
|
||||||
HxrAdminBuyService.BuyApiResult buyResult =
|
HxrAdminBuyService.BuyApiResult buyResult =
|
||||||
hxrAdminBuyService.buy(goodsId, goods.getSellerId(), token);
|
hxrAdminBuyService.buy(goods.getId(), goods.getSellerId(), token);
|
||||||
item.put("apiCode", buyResult.apiCode());
|
item.put("apiCode", buyResult.apiCode());
|
||||||
item.put("message", buyResult.apiMsg());
|
item.put("message", buyResult.apiMsg());
|
||||||
item.put("success", buyResult.success());
|
item.put("success", buyResult.success());
|
||||||
|
|||||||
Reference in New Issue
Block a user