diff --git a/docs/tag/group-buy-v3.0/docker-compose-app-v3.0.yml b/docs/tag/group-buy-v3.0/docker-compose-app-v3.0.yml index 96ac2d5..86627fc 100644 --- a/docs/tag/group-buy-v3.0/docker-compose-app-v3.0.yml +++ b/docs/tag/group-buy-v3.0/docker-compose-app-v3.0.yml @@ -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 diff --git a/group-buying-sys-app/src/main/java/edu/whut/config/DCCValueBeanFactory.java b/group-buying-sys-app/src/main/java/edu/whut/config/DCCValueBeanFactory.java index 83ece44..388ac78 100644 --- a/group-buying-sys-app/src/main/java/edu/whut/config/DCCValueBeanFactory.java +++ b/group-buying-sys-app/src/main/java/edu/whut/config/DCCValueBeanFactory.java @@ -38,11 +38,6 @@ public class DCCValueBeanFactory implements BeanPostProcessor { /** 记录「配置 Key → 注入了该 Key 的 Bean 实例」的映射,用于收到变更后反射刷新字段值 */ private final Map dccObjGroup = new HashMap<>(); - /** - * 通过构造器注入 RedissonClient,便于单元测试 Mock。 - * @param redissonClient Spring 上下文提供的 RedissonClient - */ - /** * 定义一个 {@link RTopic} Bean 并注册监听器,用于接收 * “其他节点发布的配置变更消息”。 @@ -138,8 +133,10 @@ public class DCCValueBeanFactory implements BeanPostProcessor { // 1. Redis 同步:若不存在则写默认值;若已存在则取最新值 RBucket 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); diff --git a/group-buying-sys-app/src/main/java/edu/whut/config/RedisClientConfig.java b/group-buying-sys-app/src/main/java/edu/whut/config/RedisClientConfig.java index 174c4a7..3a8fc3b 100644 --- a/group-buying-sys-app/src/main/java/edu/whut/config/RedisClientConfig.java +++ b/group-buying-sys-app/src/main/java/edu/whut/config/RedisClientConfig.java @@ -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()) diff --git a/group-buying-sys-app/src/main/resources/application-prod.yml b/group-buying-sys-app/src/main/resources/application-prod.yml index 82b8ee3..7489bcd 100644 --- a/group-buying-sys-app/src/main/resources/application-prod.yml +++ b/group-buying-sys-app/src/main/resources/application-prod.yml @@ -95,5 +95,5 @@ redis: # ---------- 日志 ---------- logging: level: - root: info + root: WARN config: classpath:logback-spring.xml diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/GroupBuyActivityDiscountVO.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/GroupBuyActivityDiscountVO.java index 25e0919..12b5289 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/GroupBuyActivityDiscountVO.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/GroupBuyActivityDiscountVO.java @@ -81,21 +81,29 @@ public class GroupBuyActivityDiscountVO { private String tagScope; /** - * 可见限制,可以看见不等于能参加拼团 - * 只要存在这样一个值,那么首次获得的默认值就是 false,false代表有限制 + * 可见限制。根据 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(); diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/discount/AbstractDiscountCalculateService.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/discount/AbstractDiscountCalculateService.java index a2dccb8..ace0ca3 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/discount/AbstractDiscountCalculateService.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/discount/AbstractDiscountCalculateService.java @@ -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; } } diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/TagNode.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/TagNode.java index 5098bb5..c107a53 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/TagNode.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/TagNode.java @@ -27,6 +27,7 @@ public class TagNode extends AbstractGroupBuyMarketSupportbuilder() .code(ResponseCode.E0007.getCode()) diff --git a/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTestController.java b/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTestController.java new file mode 100644 index 0000000..434310e --- /dev/null +++ b/group-buying-sys-trigger/src/main/java/edu/whut/trigger/http/MarketTestController.java @@ -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 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(); + } +}