From 6dcbfa025a0717323f681a548c8e728e860fbff5 Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 13 May 2026 16:26:47 +0800 Subject: [PATCH 1/5] =?UTF-8?q?TASK:Global=20Award=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E8=AE=BF=E5=AE=A2=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../da/controller/GlobalAwardController.java | 14 ++++++++ .../com/ai/da/model/vo/PageVisitCountVO.java | 23 +++++++++++++ .../com/ai/da/service/GlobalAwardService.java | 17 ++++++++++ .../service/impl/GlobalAwardServiceImpl.java | 32 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 src/main/java/com/ai/da/model/vo/PageVisitCountVO.java diff --git a/src/main/java/com/ai/da/controller/GlobalAwardController.java b/src/main/java/com/ai/da/controller/GlobalAwardController.java index a63d566b..f8952053 100644 --- a/src/main/java/com/ai/da/controller/GlobalAwardController.java +++ b/src/main/java/com/ai/da/controller/GlobalAwardController.java @@ -5,6 +5,7 @@ import com.ai.da.model.dto.*; import com.ai.da.model.dto.ContestantDTO; import com.ai.da.model.vo.CheckOTPVO; import com.ai.da.model.vo.ContestantCountVO; +import com.ai.da.model.vo.PageVisitCountVO; import com.ai.da.service.GlobalAwardService; import com.ai.da.service.upload.UploadService; import com.ai.da.service.upload.UploadTask; @@ -198,6 +199,19 @@ public class GlobalAwardController { return Response.success(globalAwardService.getContestantCount()); } + @PostMapping("/page/visit") + @ApiOperation(value = "记录比赛页面访问量", notes = "记录比赛页面的访问量,包含两种统计方式:每次访问/刷新计一次,以及5秒内刷新只计一次") + public Response recordPageVisit(@ApiParam(value = "会话ID,用于5秒内去重判断", required = false) @RequestParam(value = "sessionId", required = false) String sessionId) { + globalAwardService.recordPageVisit(sessionId); + return Response.success(); + } + + @GetMapping("/page/visit/count") + @ApiOperation(value = "获取比赛页面访问量", notes = "获取比赛页面的两种访问量:rawVisitCount(每次访问/刷新计一次)和 uniqueVisitCount(5秒内刷新只计一次)") + public Response getPageVisitCount() { + return Response.success(globalAwardService.getPageVisitCount()); + } + } diff --git a/src/main/java/com/ai/da/model/vo/PageVisitCountVO.java b/src/main/java/com/ai/da/model/vo/PageVisitCountVO.java new file mode 100644 index 00000000..ff8bf103 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/PageVisitCountVO.java @@ -0,0 +1,23 @@ +package com.ai.da.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PageVisitCountVO { + + /** + * 每次访问或刷新都计一次(不去重) + */ + private Long rawVisitCount; + + /** + * 5秒内刷新只算一次(去重后的真实访客数) + */ + private Long uniqueVisitCount; +} diff --git a/src/main/java/com/ai/da/service/GlobalAwardService.java b/src/main/java/com/ai/da/service/GlobalAwardService.java index 76232238..d892e8c0 100644 --- a/src/main/java/com/ai/da/service/GlobalAwardService.java +++ b/src/main/java/com/ai/da/service/GlobalAwardService.java @@ -3,6 +3,7 @@ package com.ai.da.service; import com.ai.da.model.dto.ContestantDTO; import com.ai.da.model.vo.CheckOTPVO; import com.ai.da.model.vo.ContestantCountVO; +import com.ai.da.model.vo.PageVisitCountVO; import org.springframework.web.multipart.MultipartFile; import java.util.Map; @@ -46,6 +47,22 @@ public interface GlobalAwardService { * @return 参赛者数量和最大参赛者编号 */ ContestantCountVO getContestantCount(); + + /** + * 记录比赛页面的访问量 + *
    + *
  • rawVisitCount: 每次访问或刷新都计一次(不去重)
  • + *
  • uniqueVisitCount: 5秒内刷新只算一次(基于会话去重)
  • + *
+ * @param sessionId 会话ID(用于5秒去重判断) + */ + void recordPageVisit(String sessionId); + + /** + * 获取比赛页面的两种访问量 + * @return 原始访问量和去重访问量 + */ + PageVisitCountVO getPageVisitCount(); } diff --git a/src/main/java/com/ai/da/service/impl/GlobalAwardServiceImpl.java b/src/main/java/com/ai/da/service/impl/GlobalAwardServiceImpl.java index 804c10cd..53e7812c 100644 --- a/src/main/java/com/ai/da/service/impl/GlobalAwardServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GlobalAwardServiceImpl.java @@ -13,6 +13,7 @@ import com.ai.da.model.dto.ContestantDTO; import com.ai.da.model.dto.PublishSysNotificationDTO; import com.ai.da.model.vo.CheckOTPVO; import com.ai.da.model.vo.ContestantCountVO; +import com.ai.da.model.vo.PageVisitCountVO; import com.ai.da.service.GlobalAwardService; import com.ai.da.service.MessageCenterService; import com.alibaba.fastjson.JSON; @@ -619,6 +620,37 @@ public class GlobalAwardServiceImpl implements GlobalAwardService { private String nullSafe(String value) { return value != null ? value : "N/A"; } + + private static final String RAW_VISIT_COUNT_KEY = "GLOBAL_AWARD:visit:raw"; + private static final String UNIQUE_VISIT_SET_KEY = "GLOBAL_AWARD:visit:unique"; + private static final String SESSION_VISIT_KEY_PREFIX = "GLOBAL_AWARD:visit:session:"; + private static final long SESSION_DEDUP_SECONDS = 5L; + + @Override + public void recordPageVisit(String sessionId) { + redisUtil.increaseCount(RAW_VISIT_COUNT_KEY); + + if (StringUtils.isNotBlank(sessionId)) { + String sessionKey = SESSION_VISIT_KEY_PREFIX + sessionId; + if (!redisUtil.hasKey(sessionKey)) { + redisUtil.increaseCount(UNIQUE_VISIT_SET_KEY); + redisUtil.addToString(sessionKey, "1", SESSION_DEDUP_SECONDS); + } + } else { + redisUtil.increaseCount(UNIQUE_VISIT_SET_KEY); + } + } + + @Override + public PageVisitCountVO getPageVisitCount() { + Long raw = redisUtil.getIncrementCount(RAW_VISIT_COUNT_KEY); + Long unique = redisUtil.getIncrementCount(UNIQUE_VISIT_SET_KEY); + return PageVisitCountVO.builder() + .rawVisitCount(raw != null ? raw : 0L) + .uniqueVisitCount(unique != null ? unique : 0L) + .build(); + } + } From 0073f910a76381ce8a2beb527340beac2648d232 Mon Sep 17 00:00:00 2001 From: ltx Date: Wed, 13 May 2026 20:55:24 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E8=B1=86=E5=8C=85=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ai/da/common/constant/ModelConstants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ai/da/common/constant/ModelConstants.java b/src/main/java/com/ai/da/common/constant/ModelConstants.java index fab503bb..4b9b75ce 100644 --- a/src/main/java/com/ai/da/common/constant/ModelConstants.java +++ b/src/main/java/com/ai/da/common/constant/ModelConstants.java @@ -18,8 +18,8 @@ public class ModelConstants { // 模型名称常量 public static final String PRINTBOARD_ADVANCED_T2I = "qwen-image"; - public static final String MOODBOARD_ADVANCED = "doubao-seedream-3-0-t2i-250415"; - public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-3-0-t2i-250415"; + public static final String MOODBOARD_ADVANCED = "doubao-seedream-4-5-251128"; + public static final String PRINTBOARD_HIGH_T2I = "doubao-seedream-4-0-250828-high"; public static final String PRINTBOARD_HIGH_I2I = "doubao-seedream-4-0-250828-fast"; public static final String PRINTBOARD_ADVANCED_I2I = "doubao-seedream-4-0-250828"; public static final String IMAGEN_MODEL = "imagen-4.0-generate-001"; From d0553316902c40c4eedc752af2f71d1aa748fc62 Mon Sep 17 00:00:00 2001 From: ltx Date: Wed, 13 May 2026 20:56:22 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E8=B1=86=E5=8C=85=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index bbf5111d..68242f2a 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -1553,11 +1553,11 @@ public class GenerateServiceImpl extends ServiceImpl i if (imagePath != null) { requestBuilder.image(finalImagePath1); } - if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)) { + if (useModel.equals(ModelConstants.PRINTBOARD_HIGH_I2I)|| useModel.equals(ModelConstants.PRINTBOARD_HIGH_T2I)) { GenerateImagesRequest.OptimizePromptOptions optimizePromptOptions = new GenerateImagesRequest.OptimizePromptOptions(); optimizePromptOptions.setMode("fast"); requestBuilder.optimizePromptOptions(optimizePromptOptions); - //由于PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast,但传入模型时需要去掉-fast,用PRINTBOARD_ADVANCED_I2I的常量做替代 + //由于PRINTBOARD_HIGH_T2I,PRINTBOARD_HIGH_I2I与PRINTBOARD_ADVANCED_I2I使用模型一致,为了区别积分扣除,PRINTBOARD_HIGH_I2I加入了-fast或者-high,但传入模型时需要去掉-fast或者-high,用PRINTBOARD_ADVANCED_I2I的常量做替代 requestBuilder.model(ModelConstants.PRINTBOARD_ADVANCED_I2I); } From 3273a61066e975dd4035b68d4138a9ace76cd7bb Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 13 May 2026 23:54:29 +0800 Subject: [PATCH 4/5] =?UTF-8?q?BUGFIX:=E5=8D=B0=E8=8A=B1=E4=BC=98=E5=85=88?= =?UTF-8?q?=E7=BA=A7=E4=B8=8D=E4=BB=8E1=E5=BC=80=E5=A7=8B=E4=BC=A0?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=95=B0=E7=BB=84=E8=B6=8A=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ai/da/python/PythonService.java | 107 +++++++++--------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 4ba86ce3..caad71b1 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -2912,72 +2912,71 @@ public class PythonService { private PrintToPython resolveDesignSinglePrint(List printObject, String partialDesign) { PrintToPython printToPython = new PrintToPython(); -// DesignPythonItemPrint printSingle = new DesignPythonItemPrint(); DesignPythonItemPrint printOverall = new DesignPythonItemPrint(); -// printToPython.setSingle(printSingle); printToPython.setOverall(printOverall); printToPython.setPartial(StringUtil.isNullOrEmpty(partialDesign) ? null : partialDesign); if (Objects.isNull(printObject) || printObject.isEmpty()) { return printToPython; } - // 没有印花时的参数设置 -// if (printObject.getIfSingle().equals(Boolean.FALSE) && CollectionUtil.isEmpty(printObject.getPrints())) { -// return new DesignPythonItemPrint(new ArrayList<>(), false); -// } -// DesignPythonItemPrint print = CopyUtil.copyObject(printObject, DesignPythonItemPrint.class); + // 1. 先对 printObject 按 priority 排序(升序) + List sortedPrints = printObject.stream() + .sorted(Comparator.comparingInt(DesignSinglePrint::getPriority)) + .toList(); - int size = printObject.size(); - // 占位符填充数组 - List> locationS = new ArrayList<>(Collections.nCopies(size, null)); - List> scaleS = new ArrayList<>(Collections.nCopies(size, null)); - List angleS = new ArrayList<>(Collections.nCopies(size, null)); - ArrayList pathsS = new ArrayList<>(Collections.nCopies(size, null)); + // 2. 分别收集单印和非单印的数据 + List singlePrints = sortedPrints.stream() + .filter(DesignSinglePrint::getIfSingle) + .toList(); - List> locationO = new ArrayList<>(Collections.nCopies(size, null)); - List> scaleO = new ArrayList<>(Collections.nCopies(size, null)); - List angleO = new ArrayList<>(Collections.nCopies(size, null)); - ArrayList pathsO = new ArrayList<>(Collections.nCopies(size, null)); + List overallPrints = sortedPrints.stream() + .filter(p -> !p.getIfSingle()) + .toList(); - // 设置印花的位置、大小、旋转角度 - // 优先级越大,越靠近顶层,在传输给python的数组中,越靠前 -// List prints = printObject.getPrints(); - printObject.forEach(p -> { - p.getLocation().set(0, p.getLocation().get(0)); - p.getLocation().set(1, p.getLocation().get(1)); - Integer priority = p.getPriority(); - setUriToMinioPath(p); - // todo 下标越界问题 - if (p.getIfSingle()) { - locationS.set(priority - 1, p.getLocation()); - scaleS.set(priority - 1, p.getScale()); - angleS.set(priority - 1, p.getAngle()); - pathsS.set(priority - 1, p.getMinIOPath()); - } else { - locationO.set(priority - 1, p.getLocation()); - scaleO.set(priority - 1, p.getScale()); - angleO.set(priority - 1, p.getAngle()); - pathsO.set(priority - 1, p.getMinIOPath()); + // 3. 处理单印数据 + if (!singlePrints.isEmpty()) { + List> locationS = new ArrayList<>(); + List> scaleS = new ArrayList<>(); + List angleS = new ArrayList<>(); + List pathsS = new ArrayList<>(); + + for (DesignSinglePrint p : singlePrints) { + setUriToMinioPath(p); + locationS.add(p.getLocation()); + scaleS.add(p.getScale()); + angleS.add(p.getAngle()); + pathsS.add(p.getMinIOPath()); } -// log.info("本次print打点locations###{}###fileVO{}", p.getLocation(), JSON.toJSONString(fileVO)); - }); - /*locationS.removeAll(Collections.singleton(null)); - scaleS.removeAll(Collections.singleton(null)); - angleS.removeAll(Collections.singleton(null)); - pathsS.removeAll(Collections.singleton(null)); - printSingle.setLocation(locationS); - printSingle.setPrint_scale_list(scaleS); - printSingle.setPrint_angle_list(angleS); - printSingle.setPrint_path_list(pathsS);*/ - locationO.removeAll(Collections.singleton(null)); - scaleO.removeAll(Collections.singleton(null)); - angleO.removeAll(Collections.singleton(null)); - pathsO.removeAll(Collections.singleton(null)); - printOverall.setLocation(locationO); - printOverall.setPrint_scale_list(scaleO); - printOverall.setPrint_angle_list(angleO); - printOverall.setPrint_path_list(pathsO); + // 注意:如果 printOverall 中需要设置单印数据,请在这里添加相应的 setter + // 根据您的原始代码,似乎只设置了 overall(非单印)的数据 + // 如果需要设置单印,请取消下面的注释并添加对应的字段 + // printOverall.setSingleLocation(locationS); + // printOverall.setSingleScale(scaleS); + // printOverall.setSingleAngle(angleS); + // printOverall.setSinglePath(pathsS); + } + + // 4. 处理非单印数据(整体印花) + if (!overallPrints.isEmpty()) { + List> locationO = new ArrayList<>(); + List> scaleO = new ArrayList<>(); + List angleO = new ArrayList<>(); + List pathsO = new ArrayList<>(); + + for (DesignSinglePrint p : overallPrints) { + setUriToMinioPath(p); + locationO.add(p.getLocation()); + scaleO.add(p.getScale()); + angleO.add(p.getAngle()); + pathsO.add(p.getMinIOPath()); + } + + printOverall.setLocation(locationO); + printOverall.setPrint_scale_list(scaleO); + printOverall.setPrint_angle_list(angleO); + printOverall.setPrint_path_list(pathsO); + } return printToPython; } From 4206bd535609a398968d8bb71f91a1120afeffb4 Mon Sep 17 00:00:00 2001 From: xupei Date: Fri, 22 May 2026 10:26:33 +0800 Subject: [PATCH 5/5] =?UTF-8?q?TASK:=E5=85=81=E8=AE=B8=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E7=BB=93=E6=9D=9F=E6=97=B6=E9=97=B4=E5=88=B0?= =?UTF-8?q?=E4=BB=8A=E5=A4=A9=E4=B9=8B=E5=90=8E=E7=9A=84=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/SubscriptionPlanServiceImpl.java | 18 ++++++++++++++---- src/main/resources/messages_en.properties | 2 ++ src/main/resources/messages_zh.properties | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/ai/da/service/impl/SubscriptionPlanServiceImpl.java b/src/main/java/com/ai/da/service/impl/SubscriptionPlanServiceImpl.java index 4ddd7470..6fd30f94 100644 --- a/src/main/java/com/ai/da/service/impl/SubscriptionPlanServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/SubscriptionPlanServiceImpl.java @@ -169,7 +169,7 @@ public class SubscriptionPlanServiceImpl extends ServiceImpl