8.17 测试接口更新

This commit is contained in:
zhangsan 2025-08-17 17:04:37 +08:00
parent a5d523eefb
commit 9af9601129
9 changed files with 91 additions and 16 deletions

View File

@ -41,6 +41,12 @@ services:
max-file: '3'
networks:
- group-buy-network
# 资源限制(重点在这里)
deploy:
resources:
limits:
cpus: "2.0" # 限制最大使用 2 核 CPU
memory: 4g # 限制最大使用 4GB 内存
mysql:
image: mysql:8.0

View File

@ -38,11 +38,6 @@ public class DCCValueBeanFactory implements BeanPostProcessor {
/** 记录「配置 Key → 注入了该 Key 的 Bean 实例」的映射,用于收到变更后反射刷新字段值 */
private final Map<String, Object> dccObjGroup = new HashMap<>();
/**
* 通过构造器注入 RedissonClient便于单元测试 Mock
* @param redissonClient Spring 上下文提供的 RedissonClient
*/
/**
* 定义一个 {@link RTopic} Bean 并注册监听器用于接收
* 其他节点发布的配置变更消息
@ -138,8 +133,10 @@ public class DCCValueBeanFactory implements BeanPostProcessor {
// 1. Redis 同步若不存在则写默认值若已存在则取最新值
RBucket<String> bucket = redissonClient.getBucket(key);
String injectedValue = bucket.isExists() ? bucket.get() : defaultVal;
if (!bucket.isExists()) { bucket.set(defaultVal); }
// 如果 Redis 里本来没有这个 key就把默认值写进去
if (!bucket.isExists()) {
bucket.set(defaultVal);
}
// 2. 反射注入字段
try {
field.setAccessible(true);

View File

@ -30,7 +30,7 @@ public class RedisClientConfig {
public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
Config config = new Config();
// 根据需要可以设定编解码器https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
config.setCodec(JsonJacksonCodec.INSTANCE);
config.setCodec(JsonJacksonCodec.INSTANCE); // Jackson 进行序列化
config.useSingleServer()
.setAddress("redis://" + properties.getHost() + ":" + properties.getPort())

View File

@ -95,5 +95,5 @@ redis:
# ---------- 日志 ----------
logging:
level:
root: info
root: WARN
config: classpath:logback-spring.xml

View File

@ -81,21 +81,29 @@ public class GroupBuyActivityDiscountVO {
private String tagScope;
/**
* 可见限制可以看见不等于能参加拼团
* 只要存在这样一个值那么首次获得的默认值就是 falsefalse代表有限制
* 可见限制根据 tagScope 判断是否可见
* 如果 tagScope 的第一个值为 "1"表示有限制不可见
* 如果 tagScope 为空默认允许可见
*/
public boolean isVisible() {
if(StringUtils.isBlank(this.tagScope)) return TagScopeEnumVO.VISIBLE.getAllow(); //等价于return true,放行
// 如果 tagScope 为空默认返回允许可见 true
if(StringUtils.isBlank(this.tagScope)) return TagScopeEnumVO.VISIBLE.getAllow();
// tagScope 按照 Constants.SPLIT 进行分割
String[] split = this.tagScope.split(Constants.SPLIT);
// 如果 split 数组的第一个元素是 "1" 并且不为空则返回不允许可见 false
if (split.length > 0 && Objects.equals(split[0], "1") && StringUtils.isNotBlank(split[0])) {
return TagScopeEnumVO.VISIBLE.getRefuse(); //等价于return false待后续校验
}
// 默认返回允许可见 true
return TagScopeEnumVO.VISIBLE.getAllow();
}
/**
* 参与限制
* 只要存在这样一个值那么首次获得的默认值就是 false
* 参与限制根据 tagScope 判断是否允许参与拼团
* 如果 tagScope 的第二个值为 "2"表示有限制不能参与
* 如果 tagScope 为空默认允许参与
*/
public boolean isEnable() {
if(StringUtils.isBlank(this.tagScope)) return TagScopeEnumVO.VISIBLE.getAllow();

View File

@ -23,7 +23,7 @@ public abstract class AbstractDiscountCalculateService implements IDiscountCalcu
if (DiscountTypeEnum.TAG.equals(groupBuyDiscount.getDiscountType())){
boolean isCrowdRange = filterTagId(userId, groupBuyDiscount.getTagId());
if (!isCrowdRange) {
log.info("折扣优惠计算拦截,用户不优惠人群标签范围内 userId:{}", userId);
log.info("折扣优惠计算拦截,用户不优惠人群标签范围内 userId:{}", userId);
return originalPrice;
}
}

View File

@ -27,6 +27,7 @@ public class TagNode extends AbstractGroupBuyMarketSupport<MarketProductEntity,
GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = dynamicContext.getGroupBuyActivityDiscountVO();
String tagId = groupBuyActivityDiscountVO.getTagId();
// 活动是否配置了可见性
boolean visible = groupBuyActivityDiscountVO.isVisible();
boolean enable = groupBuyActivityDiscountVO.isEnable();

View File

@ -106,7 +106,7 @@ public class MarketTradeService implements IMarketTradeService {
.activityId(activityId)
.build());
// 人群限定非目人群不允许参与活动
// 人群限定非目人群不允许参与活动
if (!trialBalance.getIsVisible() || !trialBalance.getIsEnable()){
return Response.<LockMarketPayOrderResponseDTO>builder()
.code(ResponseCode.E0007.getCode())

View File

@ -0,0 +1,63 @@
package edu.whut.trigger.http;
import com.alibaba.fastjson.JSON;
import edu.whut.api.IMarketTradeService;
import edu.whut.api.dto.LockMarketPayOrderRequestDTO;
import edu.whut.api.dto.LockMarketPayOrderResponseDTO;
import edu.whut.api.response.Response;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/gbm/test/")
public class MarketTestController {
private final IMarketTradeService marketTradeService;
/**
* 一键生成测试拼团订单
* @param prefix 用户名前缀比如 "smile2"默认 "testUser"
* @param count 模拟人数默认 3
*/
@GetMapping("market/lockOrders")
public String generateTestOrders(
@RequestParam(defaultValue = "testUser") String prefix,
@RequestParam(defaultValue = "3") int count
) {
String teamId = null;
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= count; i++) {
LockMarketPayOrderRequestDTO req = new LockMarketPayOrderRequestDTO();
req.setUserId(prefix + i); // 这里拼接参数前缀
req.setTeamId(teamId);
req.setActivityId(100123L);
req.setGoodsId("9890001");
req.setSource("s01");
req.setChannel("c01");
req.setNotifyMQ();
req.setOutTradeNo(RandomStringUtils.randomNumeric(12));
Response<LockMarketPayOrderResponseDTO> res = marketTradeService.lockMarketPayOrder(req);
if (res.getData() != null) {
teamId = res.getData().getTeamId(); // 组团ID沿用
}
log.info("第{}笔,测试结果 req:{} res:{}",
i, JSON.toJSONString(req), JSON.toJSONString(res));
sb.append("").append(i).append("笔订单:\n")
.append("请求:").append(JSON.toJSONString(req)).append("\n")
.append("响应:").append(JSON.toJSONString(res)).append("\n\n");
}
return sb.toString();
}
}