Преглед изворни кода

feat(activity): 添加运营活动报名管理和案例查询功能

- 在OperationalActivityController中添加活动类型查询参数
- 实现运营活动报名管理功能,包括查询、审核通过、审核拒绝等操作
- 添加商家端案例列表查询功能,支持按上传情况和活动名称筛选
- 集成AI内容审核功能,自动设置活动状态并处理审核结果
- 扩展活动报名实体类,增加审核拒绝原因和审核时间字段
- 优化活动列表查询逻辑,添加活动类型过滤条件
- 完善活动详情展示,添加用户姓名、联系方式等信息字段
fcw пре 2 месеци
родитељ
комит
8acd6a2d74
20 измењених фајлова са 850 додато и 11 уклоњено
  1. 9 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/StoreOperationalActivitySignup.java
  2. 11 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseDetailVo.java
  3. 4 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseItemVo.java
  4. 6 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseVo.java
  5. 2 2
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityDTO.java
  6. 23 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupIdDTO.java
  7. 32 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupQueryDTO.java
  8. 70 0
      alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupVO.java
  9. 15 0
      alien-entity/src/main/java/shop/alien/mapper/storePlantform/StoreOperationalActivityAchievementMapper.java
  10. 69 0
      alien-entity/src/main/resources/mapper/storePlatform/StoreOperationalActivityAchievementMapper.xml
  11. 1 1
      alien-store-platform/src/main/java/shop/alien/storeplatform/controller/OperationalActivityController.java
  12. 111 0
      alien-store-platform/src/main/java/shop/alien/storeplatform/controller/OperationalActivitySignupController.java
  13. 1 1
      alien-store-platform/src/main/java/shop/alien/storeplatform/service/OperationalActivityService.java
  14. 51 0
      alien-store-platform/src/main/java/shop/alien/storeplatform/service/OperationalActivitySignupService.java
  15. 149 7
      alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/OperationalActivityServiceImpl.java
  16. 217 0
      alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/OperationalActivitySignupServiceImpl.java
  17. 22 0
      alien-store/src/main/java/shop/alien/store/controller/StoreOperationalActivityController.java
  18. 32 0
      alien-store/src/main/java/shop/alien/store/dto/StoreOperationalActivityCaseQueryDto.java
  19. 13 0
      alien-store/src/main/java/shop/alien/store/service/StoreOperationalActivityAchievementService.java
  20. 12 0
      alien-store/src/main/java/shop/alien/store/service/impl/StoreOperationalActivityAchievementServiceImpl.java

+ 9 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/StoreOperationalActivitySignup.java

@@ -54,6 +54,15 @@ public class StoreOperationalActivitySignup {
     @TableField("status")
     @TableField("status")
     private Integer status;
     private Integer status;
 
 
+    @ApiModelProperty(value = "审核拒绝原因")
+    @TableField("reject_reason")
+    private String rejectReason;
+
+    @ApiModelProperty(value = "审核时间")
+    @TableField("audit_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date auditTime;
+
     @ApiModelProperty(value = "报名时间")
     @ApiModelProperty(value = "报名时间")
     @TableField("signup_time")
     @TableField("signup_time")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

+ 11 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseDetailVo.java

@@ -1,5 +1,7 @@
 package shop.alien.entity.storePlatform.vo;
 package shop.alien.entity.storePlatform.vo;
 
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
@@ -40,9 +42,18 @@ public class StoreOperationalActivityAchievementCaseDetailVo {
     @ApiModelProperty(value = "用户昵称")
     @ApiModelProperty(value = "用户昵称")
     private String nickName;
     private String nickName;
 
 
+    @ApiModelProperty(value = "用户姓名")
+    private String userName;
+
+    @ApiModelProperty(value = "联系方式(手机号)")
+    private String phone;
+
     @ApiModelProperty(value = "用户头像")
     @ApiModelProperty(value = "用户头像")
     private String userImage;
     private String userImage;
 
 
+    @ApiModelProperty(value = "创建时间")
+    private Date createdTime;
+
     @ApiModelProperty(value = "成果列表")
     @ApiModelProperty(value = "成果列表")
     private List<StoreOperationalActivityAchievementCaseItemVo> achievementList;
     private List<StoreOperationalActivityAchievementCaseItemVo> achievementList;
 }
 }

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseItemVo.java

@@ -32,6 +32,10 @@ public class StoreOperationalActivityAchievementCaseItemVo {
     @ApiModelProperty(value = "图片/视频URL列表")
     @ApiModelProperty(value = "图片/视频URL列表")
     private List<String> mediaUrlList;
     private List<String> mediaUrlList;
 
 
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
     @ApiModelProperty(value = "更新时间")
     @ApiModelProperty(value = "更新时间")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date updatedTime;
     private Date updatedTime;

+ 6 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityAchievementCaseVo.java

@@ -51,6 +51,12 @@ public class StoreOperationalActivityAchievementCaseVo {
     @ApiModelProperty(value = "店铺用户昵称")
     @ApiModelProperty(value = "店铺用户昵称")
     private String storeUserNickName;
     private String storeUserNickName;
 
 
+    @ApiModelProperty(value = "联系方式(手机号)")
+    private String phone;
+
+    @ApiModelProperty(value = "上传情况:0-未上传, 1-已上传")
+    private Integer hasResult;
+
     @ApiModelProperty(value = "成果首图")
     @ApiModelProperty(value = "成果首图")
     private String firstMediaUrl;
     private String firstMediaUrl;
 
 

+ 2 - 2
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivityDTO.java

@@ -87,11 +87,11 @@ public class StoreOperationalActivityDTO {
     private String activityType;
     private String activityType;
 
 
     @ApiModelProperty(value = "报名开始时间")
     @ApiModelProperty(value = "报名开始时间")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date signupStartTime;
     private Date signupStartTime;
 
 
     @ApiModelProperty(value = "报名结束时间")
     @ApiModelProperty(value = "报名结束时间")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date signupEndTime;
     private Date signupEndTime;
 
 
     @ApiModelProperty(value = "活动限制人数")
     @ApiModelProperty(value = "活动限制人数")

+ 23 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupIdDTO.java

@@ -0,0 +1,23 @@
+package shop.alien.entity.storePlatform.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 运营活动报名ID DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "StoreOperationalActivitySignupIdDTO", description = "运营活动报名ID DTO")
+public class StoreOperationalActivitySignupIdDTO {
+
+    @ApiModelProperty(value = "报名ID", required = true)
+    private Integer id;
+
+    @ApiModelProperty(value = "审核拒绝原因(审核拒绝时必填)")
+    private String rejectReason;
+}
+

+ 32 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupQueryDTO.java

@@ -0,0 +1,32 @@
+package shop.alien.entity.storePlatform.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 运营活动报名查询DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "StoreOperationalActivitySignupQueryDTO", description = "运营活动报名查询DTO")
+public class StoreOperationalActivitySignupQueryDTO {
+
+    @ApiModelProperty(value = "商户ID", required = true)
+    private Integer storeId;
+
+    @ApiModelProperty(value = "报名状态:0-待审核,1-拒绝,2-通过")
+    private Integer status;
+
+    @ApiModelProperty(value = "活动名称(模糊查询)")
+    private String activityName;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer pageNum;
+
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize;
+}
+

+ 70 - 0
alien-entity/src/main/java/shop/alien/entity/storePlatform/vo/StoreOperationalActivitySignupVO.java

@@ -0,0 +1,70 @@
+package shop.alien.entity.storePlatform.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 运营活动报名列表返回对象
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@ApiModel(value = "StoreOperationalActivitySignupVO", description = "运营活动报名列表返回对象")
+public class StoreOperationalActivitySignupVO {
+
+    @ApiModelProperty(value = "主键ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "活动ID")
+    private Integer activityId;
+
+    @ApiModelProperty(value = "商户ID")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "报名人姓名")
+    private String userName;
+
+    @ApiModelProperty(value = "用户昵称")
+    private String nickName;
+
+    @ApiModelProperty(value = "手机号")
+    private String phone;
+
+    @ApiModelProperty(value = "所属活动")
+    private String activityName;
+
+    @ApiModelProperty(value = "活动类型:COMMENT-评论有礼, MARKETING-营销活动")
+    private String activityType;
+
+    @ApiModelProperty(value = "报名状态:0-待审核,1-拒绝,2-通过")
+    private Integer status;
+
+    @ApiModelProperty(value = "报名状态文字:待审核、拒绝、通过")
+    private String statusText;
+
+    @ApiModelProperty(value = "审核拒绝原因")
+    private String rejectReason;
+
+    @ApiModelProperty(value = "审核时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date auditTime;
+
+    @ApiModelProperty(value = "报名时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date signupTime;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+}
+

+ 15 - 0
alien-entity/src/main/java/shop/alien/mapper/storePlantform/StoreOperationalActivityAchievementMapper.java

@@ -50,4 +50,19 @@ public interface StoreOperationalActivityAchievementMapper extends BaseMapper<St
      */
      */
     List<StoreOperationalActivityAchievementCaseItemVo> selectCaseItems(@Param("activityId") Integer activityId,
     List<StoreOperationalActivityAchievementCaseItemVo> selectCaseItems(@Param("activityId") Integer activityId,
                                                                         @Param("userId") Integer userId);
                                                                         @Param("userId") Integer userId);
+
+    /**
+     * 商家端分页查询案例列表(按商户ID、上传情况、活动名称筛选)
+     *
+     * @param page 分页
+     * @param storeId 商户ID
+     * @param hasResult 上传情况:0-未上传, 1-已上传
+     * @param activityName 活动名称(模糊查询)
+     * @return 分页列表
+     */
+    IPage<StoreOperationalActivityAchievementCaseVo> selectStoreCasePage(
+            IPage<?> page,
+            @Param("storeId") Integer storeId,
+            @Param("hasResult") Integer hasResult,
+            @Param("activityName") String activityName);
 }
 }

+ 69 - 0
alien-entity/src/main/resources/mapper/storePlatform/StoreOperationalActivityAchievementMapper.xml

@@ -63,9 +63,14 @@
             act.end_time AS endTime,
             act.end_time AS endTime,
             u.id AS userId,
             u.id AS userId,
             u.user_name AS nickName,
             u.user_name AS nickName,
+            signup.user_name AS userName,
+            signup.phone AS phone,
             u.user_image AS userImage
             u.user_image AS userImage
         FROM store_operational_activity act
         FROM store_operational_activity act
         LEFT JOIN life_user u ON u.id = #{userId}
         LEFT JOIN life_user u ON u.id = #{userId}
+        LEFT JOIN store_operational_activity_signup signup ON signup.activity_id = #{activityId}
+            AND signup.user_id = #{userId}
+            AND signup.delete_flag = 0
         WHERE act.id = #{activityId}
         WHERE act.id = #{activityId}
           AND act.delete_flag = 0
           AND act.delete_flag = 0
           AND u.delete_flag = 0
           AND u.delete_flag = 0
@@ -77,6 +82,7 @@
             ach.id AS achievementId,
             ach.id AS achievementId,
             ach.achievement_desc AS achievementDesc,
             ach.achievement_desc AS achievementDesc,
             ach.media_urls AS mediaUrls,
             ach.media_urls AS mediaUrls,
+            ach.created_time AS createdTime,
             COALESCE(ach.updated_time, ach.created_time) AS updatedTime
             COALESCE(ach.updated_time, ach.created_time) AS updatedTime
         FROM store_operational_activity_achievement ach
         FROM store_operational_activity_achievement ach
         WHERE ach.activity_id = #{activityId}
         WHERE ach.activity_id = #{activityId}
@@ -84,4 +90,67 @@
           AND ach.delete_flag = 0
           AND ach.delete_flag = 0
         ORDER BY COALESCE(ach.updated_time, ach.created_time) DESC, ach.id DESC
         ORDER BY COALESCE(ach.updated_time, ach.created_time) DESC, ach.id DESC
     </select>
     </select>
+
+    <select id="selectStoreCasePage" resultType="shop.alien.entity.storePlatform.vo.StoreOperationalActivityAchievementCaseVo">
+        SELECT
+            ach.id AS achievementId,
+            ach.user_id AS userId,
+            ach.activity_id AS activityId,
+            act.activity_name AS activityName,
+            CASE
+                WHEN act.status = 7 THEN 7
+                WHEN act.status IN (4, 5) AND act.end_time IS NOT NULL AND NOW() > act.end_time THEN 7
+                WHEN act.status IN (4, 5) AND (act.start_time IS NULL OR NOW() >= act.start_time) THEN 5
+                ELSE act.status
+            END AS activityStatus,
+            u.user_name AS nickName,
+            signup.phone AS phone,
+            CASE
+                WHEN (act.result_media_url IS NOT NULL AND act.result_media_url != '')
+                    OR (act.result_text IS NOT NULL AND act.result_text != '') THEN 1
+                ELSE 0
+            END AS hasResult,
+            SUBSTRING_INDEX(ach.media_urls, ',', 1) AS firstMediaUrl,
+            COALESCE(ach.updated_time, ach.created_time) AS updatedTime
+        FROM store_operational_activity_achievement ach
+        INNER JOIN (
+            SELECT t.activity_id, t.user_id, MAX(t.id) AS max_id
+            FROM store_operational_activity_achievement t
+            INNER JOIN (
+                SELECT activity_id, user_id, MAX(COALESCE(updated_time, created_time)) AS max_time
+                FROM store_operational_activity_achievement
+                WHERE delete_flag = 0
+                GROUP BY activity_id, user_id
+            ) latest_time
+                ON t.activity_id = latest_time.activity_id
+                AND t.user_id = latest_time.user_id
+                AND COALESCE(t.updated_time, t.created_time) = latest_time.max_time
+            WHERE t.delete_flag = 0
+            GROUP BY t.activity_id, t.user_id
+        ) latest ON latest.max_id = ach.id
+        INNER JOIN store_operational_activity act ON act.id = ach.activity_id
+        LEFT JOIN life_user u ON u.id = ach.user_id
+        LEFT JOIN store_operational_activity_signup signup ON signup.activity_id = ach.activity_id
+            AND signup.user_id = ach.user_id
+            AND signup.delete_flag = 0
+        WHERE ach.delete_flag = 0
+          AND act.delete_flag = 0
+          AND act.store_id = #{storeId}
+        <if test="hasResult != null">
+            <choose>
+                <when test="hasResult == 0">
+                    AND ((act.result_media_url IS NULL OR act.result_media_url = '')
+                    AND (act.result_text IS NULL OR act.result_text = ''))
+                </when>
+                <when test="hasResult == 1">
+                    AND ((act.result_media_url IS NOT NULL AND act.result_media_url != '')
+                    OR (act.result_text IS NOT NULL AND act.result_text != ''))
+                </when>
+            </choose>
+        </if>
+        <if test="activityName != null and activityName != ''">
+            AND act.activity_name LIKE CONCAT('%', #{activityName}, '%')
+        </if>
+        ORDER BY COALESCE(ach.updated_time, ach.created_time) DESC, ach.id DESC
+    </select>
 </mapper>
 </mapper>

+ 1 - 1
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/OperationalActivityController.java

@@ -125,7 +125,7 @@ public class OperationalActivityController {
             if (dto.getStoreId() == null || dto.getStoreId() <= 0) {
             if (dto.getStoreId() == null || dto.getStoreId() <= 0) {
                  return R.data(null, "暂无承载数据!!!");
                  return R.data(null, "暂无承载数据!!!");
             }
             }
-            IPage<StoreOperationalActivityVO> result = activityService.queryActivityList( dto.getStoreId(), dto.getStatus(), dto.getActivityName(), dto.getPageNum(), dto.getPageSize());
+            IPage<StoreOperationalActivityVO> result = activityService.queryActivityList( dto.getStoreId(), dto.getStatus(), dto.getActivityType(), dto.getActivityName(), dto.getPageNum(), dto.getPageSize());
             return R.data(result);
             return R.data(result);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("OperationalActivityController.qeryActivityList ERROR: {}", e.getMessage(), e);
             log.error("OperationalActivityController.qeryActivityList ERROR: {}", e.getMessage(), e);

+ 111 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/OperationalActivitySignupController.java

@@ -0,0 +1,111 @@
+package shop.alien.storeplatform.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupVO;
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupQueryDTO;
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupIdDTO;
+import shop.alien.storeplatform.service.OperationalActivitySignupService;
+
+/**
+ * 运营活动报名管理控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"商家端-运营活动报名管理"})
+@ApiSort(11)
+@CrossOrigin
+@RestController
+@RequestMapping("/operationalActivitySignup")
+@RequiredArgsConstructor
+public class OperationalActivitySignupController {
+
+    private final OperationalActivitySignupService signupService;
+
+    @ApiOperation("根据商户ID查询报名列表")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/queryList")
+    public R<IPage<StoreOperationalActivitySignupVO>> querySignupList(@RequestBody StoreOperationalActivitySignupQueryDTO dto) {
+        log.info("OperationalActivitySignupController.querySignupList: dto={}", dto);
+        try {
+            if (dto.getStoreId() == null || dto.getStoreId() <= 0) {
+                return R.fail("商户ID不能为空");
+            }
+            Integer pageNum = dto.getPageNum() != null ? dto.getPageNum() : 1;
+            Integer pageSize = dto.getPageSize() != null ? dto.getPageSize() : 10;
+            IPage<StoreOperationalActivitySignupVO> result = signupService.querySignupList(
+                    dto.getStoreId(), dto.getStatus(), dto.getActivityName(), pageNum, pageSize);
+            return R.data(result);
+        } catch (Exception e) {
+            log.error("OperationalActivitySignupController.querySignupList ERROR: {}", e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    @ApiOperation("根据ID查询报名详情")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/queryById")
+    public R<StoreOperationalActivitySignupVO> querySignupById(@RequestBody StoreOperationalActivitySignupIdDTO dto) {
+        log.info("OperationalActivitySignupController.querySignupById: id={}", dto.getId());
+        try {
+            if (dto.getId() == null || dto.getId() <= 0) {
+                return R.fail("报名ID不能为空");
+            }
+            StoreOperationalActivitySignupVO result = signupService.querySignupById(dto.getId());
+            if (result == null) {
+                return R.fail("报名记录不存在");
+            }
+            return R.data(result);
+        } catch (Exception e) {
+            log.error("OperationalActivitySignupController.querySignupById ERROR: {}", e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    @ApiOperation("审核通过")
+    @ApiOperationSupport(order = 3)
+    @PostMapping("/approve")
+    public R<String> approveSignup(@RequestBody StoreOperationalActivitySignupIdDTO dto) {
+        log.info("OperationalActivitySignupController.approveSignup: id={}", dto.getId());
+        try {
+            if (dto.getId() == null || dto.getId() <= 0) {
+                return R.fail("报名ID不能为空");
+            }
+            int result = signupService.approveSignup(dto.getId());
+            if (result > 0) {
+                return R.success("审核通过成功");
+            }
+            return R.fail("审核通过失败");
+        } catch (Exception e) {
+            log.error("OperationalActivitySignupController.approveSignup ERROR: {}", e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    @ApiOperation("审核拒绝")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/reject")
+    public R<String> rejectSignup(@RequestBody StoreOperationalActivitySignupIdDTO dto) {
+        log.info("OperationalActivitySignupController.rejectSignup: id={}, rejectReason={}", dto.getId(), dto.getRejectReason());
+        try {
+            if (dto.getId() == null || dto.getId() <= 0) {
+                return R.fail("报名ID不能为空");
+            }
+            int result = signupService.rejectSignup(dto.getId(), dto.getRejectReason());
+            if (result > 0) {
+                return R.success("审核拒绝成功");
+            }
+            return R.fail("审核拒绝失败");
+        } catch (Exception e) {
+            log.error("OperationalActivitySignupController.rejectSignup ERROR: {}", e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
+}
+

+ 1 - 1
alien-store-platform/src/main/java/shop/alien/storeplatform/service/OperationalActivityService.java

@@ -56,7 +56,7 @@ public interface OperationalActivityService {
      * @param pageSize     每页大小
      * @param pageSize     每页大小
      * @return 分页结果
      * @return 分页结果
      */
      */
-    IPage<StoreOperationalActivityVO> queryActivityList(Integer storeId, Integer status, String activityName, Integer pageNum, Integer pageSize);
+    IPage<StoreOperationalActivityVO> queryActivityList(Integer storeId, Integer status,String activityType, String activityName,  Integer pageNum, Integer pageSize);
 
 
     /**
     /**
      * 启用/禁用活动
      * 启用/禁用活动

+ 51 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/OperationalActivitySignupService.java

@@ -0,0 +1,51 @@
+package shop.alien.storeplatform.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupVO;
+
+/**
+ * 运营活动报名服务接口
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface OperationalActivitySignupService {
+
+    /**
+     * 根据商户ID分页查询报名列表
+     *
+     * @param storeId   商户ID
+     * @param status    报名状态(可选,0-待审核,1-拒绝,2-通过)
+     * @param activityName 活动名称(可选,模糊查询)
+     * @param pageNum   页码
+     * @param pageSize  每页大小
+     * @return 分页结果
+     */
+    IPage<StoreOperationalActivitySignupVO> querySignupList(Integer storeId, Integer status, String activityName, Integer pageNum, Integer pageSize);
+
+    /**
+     * 根据ID查询报名详情
+     *
+     * @param id 报名ID
+     * @return 报名详情
+     */
+    StoreOperationalActivitySignupVO querySignupById(Integer id);
+
+    /**
+     * 审核通过
+     *
+     * @param id 报名ID
+     * @return 更新结果
+     */
+    int approveSignup(Integer id);
+
+    /**
+     * 审核拒绝
+     *
+     * @param id 报名ID
+     * @param rejectReason 拒绝原因
+     * @return 更新结果
+     */
+    int rejectSignup(Integer id, String rejectReason);
+}
+

+ 149 - 7
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/OperationalActivityServiceImpl.java

@@ -115,6 +115,16 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
                     String authorization = "Bearer " + accessToken;
                     String authorization = "Bearer " + accessToken;
                     
                     
                     JsonNode auditParam = dto.getAuditParam();
                     JsonNode auditParam = dto.getAuditParam();
+                    // 如果 auditParam 是字符串,先解析为 JsonNode
+                    if (auditParam != null && auditParam.isTextual()) {
+                        try {
+                            auditParam = objectMapper.readTree(auditParam.asText());
+                        } catch (Exception e) {
+                            log.error("解析 auditParam JSON 字符串失败: {}", auditParam.asText(), e);
+                            auditParam = null;
+                        }
+                    }
+                    
                     String auditText = (auditParam != null && auditParam.has("text")) ? auditParam.get("text").asText() : "";
                     String auditText = (auditParam != null && auditParam.has("text")) ? auditParam.get("text").asText() : "";
                     JsonNode imagesNode = (auditParam != null) ? auditParam.get("image_urls") : null;
                     JsonNode imagesNode = (auditParam != null) ? auditParam.get("image_urls") : null;
                     
                     
@@ -127,15 +137,35 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
                     // 调用同步审核工具类
                     // 调用同步审核工具类
                     AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(auditText, imageUrls);
                     AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(auditText, imageUrls);
                     
                     
+
+                    
+                    // 审核通过,根据活动时间自动设置状态
+                    Date currentTime = new Date();
+                    Date startTime = activity.getStartTime();
+                    Date endTime = activity.getEndTime();
+                    
+                    int status;
+                    if (currentTime.before(startTime)) {
+                        // 当前时间在活动开始时间之前,设置为未开始
+                        status = 2;
+                    } else if (currentTime.compareTo(startTime) >= 0 && currentTime.compareTo(endTime) <= 0) {
+                        // 当前时间在活动时间之间,设置为进行中
+                        status = 5;
+                    } else {
+                        // 当前时间在活动结束时间之后,设置为已结束
+                        status = 7;
+                    }
+                    activity.setStatus(status);
+
                     // 如果审核不通过,记录原因并提前结束
                     // 如果审核不通过,记录原因并提前结束
                     if (!auditResult.isPassed()) {
                     if (!auditResult.isPassed()) {
                         log.warn("AI内容审核未通过: {}", auditResult.getFailureReason());
                         log.warn("AI内容审核未通过: {}", auditResult.getFailureReason());
                         failureReasonHolder.set(auditResult.getFailureReason());
                         failureReasonHolder.set(auditResult.getFailureReason());
-                        return 2; // 返回2表示审核失败
+                        activity.setApprovalComments(auditResult.getFailureReason());
+                        activity.setStatus(3);
+//                        return 2; // 返回2表示审核失败
                     }
                     }
-                    
-                    // 审核通过,执行入库操作(状态设为8:待生成海报)
-                    activity.setStatus(8);
+
                     result = activityMapper.insert(activity);
                     result = activityMapper.insert(activity);
                     // 使用用户描述和页面输入框其他信息,让AI生成海报图片。
                     // 使用用户描述和页面输入框其他信息,让AI生成海报图片。
                     if (dto.getUploadImgType() == 2) {
                     if (dto.getUploadImgType() == 2) {
@@ -231,7 +261,112 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
 
 
         StoreOperationalActivity activity = new StoreOperationalActivity();
         StoreOperationalActivity activity = new StoreOperationalActivity();
         BeanUtils.copyProperties(dto, activity);
         BeanUtils.copyProperties(dto, activity);
-        Integer result = activityMapper.updateById(activity);
+        Integer result =0;
+        try {
+            String accessToken = getToken();
+            if (accessToken == null || accessToken.isEmpty()) {
+                log.error("获取AI服务access_token失败,无法生成促销图片");
+            } else {
+                // AI登录成功
+                // 先调用AI进行运营名称和图片的审核,同步调用
+                String authorization = "Bearer " + accessToken;
+
+                JsonNode auditParam = dto.getAuditParam();
+                // 如果 auditParam 是字符串,先解析为 JsonNode
+                if (auditParam != null && auditParam.isTextual()) {
+                    try {
+                        auditParam = objectMapper.readTree(auditParam.asText());
+                    } catch (Exception e) {
+                        log.error("解析 auditParam JSON 字符串失败: {}", auditParam.asText(), e);
+                        auditParam = null;
+                    }
+                }
+
+                String auditText = (auditParam != null && auditParam.has("text")) ? auditParam.get("text").asText() : "";
+                JsonNode imagesNode = (auditParam != null) ? auditParam.get("image_urls") : null;
+
+                List<String> imageUrls = (imagesNode != null && imagesNode.isArray())
+                        ? StreamSupport.stream(imagesNode.spliterator(), false)
+                        .map(JsonNode::asText)
+                        .collect(Collectors.toList())
+                        : new ArrayList<>();
+
+                // 调用同步审核工具类
+                AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(auditText, imageUrls);
+
+
+
+                // 审核通过,根据活动时间自动设置状态
+                Date currentTime = new Date();
+                Date startTime = activity.getStartTime();
+                Date endTime = activity.getEndTime();
+
+                int status;
+                if (currentTime.before(startTime)) {
+                    // 当前时间在活动开始时间之前,设置为未开始
+                    status = 2;
+                } else if (currentTime.compareTo(startTime) >= 0 && currentTime.compareTo(endTime) <= 0) {
+                    // 当前时间在活动时间之间,设置为进行中
+                    status = 5;
+                } else {
+                    // 当前时间在活动结束时间之后,设置为已结束
+                    status = 7;
+                }
+                activity.setStatus(status);
+
+                // 如果审核不通过,记录原因并提前结束
+                if (!auditResult.isPassed()) {
+                    log.warn("AI内容审核未通过: {}", auditResult.getFailureReason());
+                    failureReasonHolder.set(auditResult.getFailureReason());
+                    activity.setApprovalComments(auditResult.getFailureReason());
+                    activity.setStatus(3);
+//                        return 2; // 返回2表示审核失败
+                }
+
+                result = activityMapper.updateById(activity);
+                // 使用用户描述和页面输入框其他信息,让AI生成海报图片。
+                if (dto.getUploadImgType() == 2) {
+                    // 格式化输入AI参数
+                    ObjectNode requestBody = objectMapper.createObjectNode();
+                    String filled = String.format(
+                            tpl,
+                            dto.getActivityName(),
+                            dto.getStartTime(),
+                            dto.getEndTime(),
+                            dto.getParticipationLimit(),
+                            dto.getActivityRule(),
+                            dto.getCouponQuantity(),
+                            dto.getImgDescribe()
+                    );
+                    requestBody.put("text", filled);
+                    JsonNode imgResponse = alienAIFeign.generatePromotionImage(authorization, requestBody);
+                    // 解析响应
+                    if (imgResponse.has("data")) {
+                        JsonNode data = imgResponse.get("data");
+                        // 提取横向图(banner_image)的图片URL
+                        if (data.has("banner_image")) {
+                            JsonNode bannerImage = data.get("banner_image");
+                            if (bannerImage.has("image_url") && !bannerImage.get("image_url").isNull()) {
+                                String bannerImageUrl = bannerImage.get("image_url").asText();
+                                dto.getActivityTitleImg().setImgUrl(bannerImageUrl);
+                            }
+                        }
+                        // 提取竖向图(vertical_image)的图片URL
+                        if (data.has("vertical_image")) {
+                            JsonNode verticalImage = data.get("vertical_image");
+                            if (verticalImage.has("image_url") && !verticalImage.get("image_url").isNull()) {
+                                String verticalImageUrl = verticalImage.get("image_url").asText();
+                                dto.getActivityDetailImg().setImgUrl(verticalImageUrl);
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // AI调用失败,也可以添加数据
+            log.error("调用AI服务生成促销图片失败", e);
+        }
+//         result = activityMapper.updateById(activity);
 
 
         // 添加
         // 添加
         if (result > 0) {
         if (result > 0) {
@@ -342,7 +477,7 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
 
 
 
 
     @Override
     @Override
-    public IPage<StoreOperationalActivityVO> queryActivityList(Integer storeId, Integer status, String activityName, Integer pageNum, Integer pageSize) {
+    public IPage<StoreOperationalActivityVO> queryActivityList(Integer storeId, Integer status,String activityType, String activityName, Integer pageNum, Integer pageSize) {
         log.info("OperationalActivityServiceImpl.queryActivityList: storeId={}, status={}, activityName={}, pageNum={}, pageSize={}",
         log.info("OperationalActivityServiceImpl.queryActivityList: storeId={}, status={}, activityName={}, pageNum={}, pageSize={}",
                 storeId, status, activityName, pageNum, pageSize);
                 storeId, status, activityName, pageNum, pageSize);
 
 
@@ -350,6 +485,7 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
         wrapper.eq(storeId != null, StoreOperationalActivity::getStoreId, storeId);
         wrapper.eq(storeId != null, StoreOperationalActivity::getStoreId, storeId);
         wrapper.like(activityName != null && activityName != "", StoreOperationalActivity::getActivityName, activityName);
         wrapper.like(activityName != null && activityName != "", StoreOperationalActivity::getActivityName, activityName);
         wrapper.eq(status != null, StoreOperationalActivity::getStatus, status);
         wrapper.eq(status != null, StoreOperationalActivity::getStatus, status);
+        wrapper.eq(activityType != null, StoreOperationalActivity::getActivityType, activityType);
 
 
         IPage<StoreOperationalActivity> list = activityMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
         IPage<StoreOperationalActivity> list = activityMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
 
 
@@ -377,7 +513,13 @@ public class OperationalActivityServiceImpl implements OperationalActivityServic
                 vo.setStatusName("已结束");
                 vo.setStatusName("已结束");
             }
             }
 
 
-            vo.setCouponName(lifeDiscountCouponMapper.selectById(activity.getCouponId()).getName());
+            // 设置优惠券名称(判空处理)
+            if (activity.getCouponId() != null) {
+                LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectById(activity.getCouponId());
+                if (coupon != null) {
+                    vo.setCouponName(coupon.getName());
+                }
+            }
 
 
             voRecords.add(vo);
             voRecords.add(vo);
         }
         }

+ 217 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/OperationalActivitySignupServiceImpl.java

@@ -0,0 +1,217 @@
+package shop.alien.storeplatform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.store.LifeUser;
+import shop.alien.entity.storePlatform.StoreOperationalActivity;
+import shop.alien.entity.storePlatform.StoreOperationalActivitySignup;
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupVO;
+import shop.alien.mapper.LifeUserMapper;
+import shop.alien.mapper.storePlantform.StoreOperationalActivityMapper;
+import shop.alien.mapper.storePlantform.StoreOperationalActivitySignupMapper;
+import shop.alien.storeplatform.service.OperationalActivitySignupService;
+
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 运营活动报名服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class OperationalActivitySignupServiceImpl implements OperationalActivitySignupService {
+
+    private final StoreOperationalActivitySignupMapper signupMapper;
+    private final StoreOperationalActivityMapper activityMapper;
+    private final LifeUserMapper lifeUserMapper;
+
+    @Override
+    public IPage<StoreOperationalActivitySignupVO> querySignupList(Integer storeId, Integer status, String activityName, Integer pageNum, Integer pageSize) {
+        log.info("OperationalActivitySignupServiceImpl.querySignupList: storeId={}, status={}, activityName={}, pageNum={}, pageSize={}", 
+                storeId, status, activityName, pageNum, pageSize);
+
+        if (storeId == null || storeId <= 0) {
+            throw new IllegalArgumentException("商户ID不能为空");
+        }
+
+        // 构建查询条件
+        LambdaQueryWrapper<StoreOperationalActivitySignup> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(StoreOperationalActivitySignup::getStoreId, storeId);
+        
+        if (status != null) {
+            wrapper.eq(StoreOperationalActivitySignup::getStatus, status);
+        }
+
+        // 如果指定了活动名称,先查询活动ID列表
+        if (activityName != null && !activityName.trim().isEmpty()) {
+            LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
+            activityWrapper.eq(StoreOperationalActivity::getStoreId, storeId)
+                    .like(StoreOperationalActivity::getActivityName, activityName.trim())
+                    .eq(StoreOperationalActivity::getDeleteFlag, 0);
+            List<StoreOperationalActivity> activities = activityMapper.selectList(activityWrapper);
+            if (activities.isEmpty()) {
+                // 如果没有匹配的活动,返回空结果
+                return new Page<>(pageNum, pageSize);
+            }
+            List<Integer> activityIds = activities.stream()
+                    .map(StoreOperationalActivity::getId)
+                    .collect(Collectors.toList());
+            wrapper.in(StoreOperationalActivitySignup::getActivityId, activityIds);
+        }
+
+        wrapper.orderByDesc(StoreOperationalActivitySignup::getCreatedTime);
+
+        // 分页查询
+        IPage<StoreOperationalActivitySignup> page = new Page<>(pageNum, pageSize);
+        IPage<StoreOperationalActivitySignup> signupPage = signupMapper.selectPage(page, wrapper);
+
+        // 转换为VO
+        IPage<StoreOperationalActivitySignupVO> voPage = new Page<>(pageNum, pageSize);
+        voPage.setTotal(signupPage.getTotal());
+        voPage.setPages(signupPage.getPages());
+
+        List<StoreOperationalActivitySignupVO> voList = signupPage.getRecords().stream().map(signup -> {
+            StoreOperationalActivitySignupVO vo = new StoreOperationalActivitySignupVO();
+            BeanUtils.copyProperties(signup, vo);
+
+            // 查询活动名称和活动类型
+            LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
+            activityWrapper.eq(StoreOperationalActivity::getId, signup.getActivityId())
+                    .eq(StoreOperationalActivity::getDeleteFlag, 0);
+            StoreOperationalActivity activity = activityMapper.selectOne(activityWrapper);
+            if (activity != null) {
+                vo.setActivityName(activity.getActivityName());
+                vo.setActivityType(activity.getActivityType());
+            }
+
+            // 查询用户昵称
+            if (signup.getUserId() != null) {
+                LifeUser lifeUser = lifeUserMapper.selectById(signup.getUserId());
+                if (lifeUser != null && lifeUser.getUserName() != null) {
+                    vo.setNickName(lifeUser.getUserName());
+                }
+            }
+
+            // 设置状态文字
+            vo.setStatusText(getStatusText(signup.getStatus()));
+
+            return vo;
+        }).collect(Collectors.toList());
+
+        voPage.setRecords(voList);
+        return voPage;
+    }
+
+    @Override
+    public StoreOperationalActivitySignupVO querySignupById(Integer id) {
+        log.info("OperationalActivitySignupServiceImpl.querySignupById: id={}", id);
+
+        if (id == null || id <= 0) {
+            throw new IllegalArgumentException("报名ID不能为空");
+        }
+
+        StoreOperationalActivitySignup signup = signupMapper.selectById(id);
+        if (signup == null) {
+            return null;
+        }
+
+        StoreOperationalActivitySignupVO vo = new StoreOperationalActivitySignupVO();
+        BeanUtils.copyProperties(signup, vo);
+
+        // 查询活动名称和活动类型
+        LambdaQueryWrapper<StoreOperationalActivity> activityWrapper = new LambdaQueryWrapper<>();
+        activityWrapper.eq(StoreOperationalActivity::getId, signup.getActivityId())
+                .eq(StoreOperationalActivity::getDeleteFlag, 0);
+        StoreOperationalActivity activity = activityMapper.selectOne(activityWrapper);
+        if (activity != null) {
+            vo.setActivityName(activity.getActivityName());
+            vo.setActivityType(activity.getActivityType());
+        }
+
+        // 查询用户昵称
+        if (signup.getUserId() != null) {
+            LifeUser lifeUser = lifeUserMapper.selectById(signup.getUserId());
+            if (lifeUser != null && lifeUser.getUserName() != null) {
+                vo.setNickName(lifeUser.getUserName());
+            }
+        }
+
+        // 设置状态文字
+        vo.setStatusText(getStatusText(signup.getStatus()));
+
+        return vo;
+    }
+
+    @Override
+    public int approveSignup(Integer id) {
+        log.info("OperationalActivitySignupServiceImpl.approveSignup: id={}", id);
+
+        if (id == null || id <= 0) {
+            throw new IllegalArgumentException("报名ID不能为空");
+        }
+
+        LambdaUpdateWrapper<StoreOperationalActivitySignup> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(StoreOperationalActivitySignup::getId, id)
+                .set(StoreOperationalActivitySignup::getStatus, 2) // 2-通过
+                .set(StoreOperationalActivitySignup::getAuditTime, new Date()); // 设置审核时间为当前时间
+
+        return signupMapper.update(null, wrapper);
+    }
+
+    @Override
+    public int rejectSignup(Integer id, String rejectReason) {
+        log.info("OperationalActivitySignupServiceImpl.rejectSignup: id={}, rejectReason={}", id, rejectReason);
+
+        if (id == null || id <= 0) {
+            throw new IllegalArgumentException("报名ID不能为空");
+        }
+
+        LambdaUpdateWrapper<StoreOperationalActivitySignup> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(StoreOperationalActivitySignup::getId, id)
+                .set(StoreOperationalActivitySignup::getStatus, 1) // 1-拒绝
+                .set(StoreOperationalActivitySignup::getAuditTime, new Date()); // 设置审核时间为当前时间
+        
+        // 如果提供了拒绝原因,则保存;否则使用默认值
+        if (rejectReason != null && !rejectReason.trim().isEmpty()) {
+            wrapper.set(StoreOperationalActivitySignup::getRejectReason, rejectReason.trim());
+        } else {
+            wrapper.set(StoreOperationalActivitySignup::getRejectReason, "审核未通过");
+        }
+
+        return signupMapper.update(null, wrapper);
+    }
+
+    /**
+     * 获取状态文字
+     *
+     * @param status 状态值
+     * @return 状态文字
+     */
+    private String getStatusText(Integer status) {
+        if (status == null) {
+            return "未知";
+        }
+        switch (status) {
+            case 0:
+                return "待审核";
+            case 1:
+                return "拒绝";
+            case 2:
+                return "通过";
+            default:
+                return "未知";
+        }
+    }
+}
+

+ 22 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreOperationalActivityController.java

@@ -26,6 +26,7 @@ import shop.alien.entity.storePlatform.vo.StoreOperationalActivityAchievementVo;
 import shop.alien.entity.storePlatform.vo.StoreOperationalActivityMySignupVo;
 import shop.alien.entity.storePlatform.vo.StoreOperationalActivityMySignupVo;
 import shop.alien.store.dto.StoreOperationalActivitySignupDto;
 import shop.alien.store.dto.StoreOperationalActivitySignupDto;
 import shop.alien.store.dto.StoreOperationalActivityAchievementDto;
 import shop.alien.store.dto.StoreOperationalActivityAchievementDto;
+import shop.alien.store.dto.StoreOperationalActivityCaseQueryDto;
 import shop.alien.store.service.StoreOperationalActivityService;
 import shop.alien.store.service.StoreOperationalActivityService;
 import shop.alien.store.service.StoreOperationalActivityAchievementService;
 import shop.alien.store.service.StoreOperationalActivityAchievementService;
 
 
@@ -253,4 +254,25 @@ public class StoreOperationalActivityController {
             return R.fail(e.getMessage());
             return R.fail(e.getMessage());
         }
         }
     }
     }
+
+    @ApiOperation("商家端案例列表")
+    @ApiOperationSupport(order = 10)
+    @PostMapping("/achievement/case/store/list")
+    public R<IPage<StoreOperationalActivityAchievementCaseVo>> listStoreCasePage(
+            @RequestBody StoreOperationalActivityCaseQueryDto dto) {
+        log.info("StoreOperationalActivityController.listStoreCasePage dto={}", dto);
+        try {
+            if (dto == null || dto.getStoreId() == null || dto.getStoreId() <= 0) {
+                return R.fail("商户ID不能为空");
+            }
+            IPage<StoreOperationalActivityAchievementCaseVo> result = achievementService.listStoreCasePage(
+                    dto.getStoreId(), dto.getHasResult(), dto.getActivityName(), dto.getPageNum(), dto.getPageSize());
+            return R.data(result);
+        } catch (IllegalArgumentException e) {
+            return R.fail(e.getMessage());
+        } catch (Exception e) {
+            log.error("StoreOperationalActivityController.listStoreCasePage ERROR: {}", e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
 }
 }

+ 32 - 0
alien-store/src/main/java/shop/alien/store/dto/StoreOperationalActivityCaseQueryDto.java

@@ -0,0 +1,32 @@
+package shop.alien.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 商家端案例列表查询请求
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "StoreOperationalActivityCaseQueryDto", description = "商家端案例列表查询请求")
+public class StoreOperationalActivityCaseQueryDto {
+
+    @ApiModelProperty(value = "商户ID", required = true)
+    private Integer storeId;
+
+    @ApiModelProperty(value = "上传情况:0-未上传, 1-已上传")
+    private Integer hasResult;
+
+    @ApiModelProperty(value = "所属活动(活动名称,支持模糊查询)")
+    private String activityName;
+
+    @ApiModelProperty(value = "当前页", example = "1")
+    private Integer pageNum;
+
+    @ApiModelProperty(value = "每页条数", example = "10")
+    private Integer pageSize;
+}
+

+ 13 - 0
alien-store/src/main/java/shop/alien/store/service/StoreOperationalActivityAchievementService.java

@@ -61,4 +61,17 @@ public interface StoreOperationalActivityAchievementService {
      * @return 详情
      * @return 详情
      */
      */
     StoreOperationalActivityAchievementCaseDetailVo getCaseDetail(Integer activityId, Integer userId);
     StoreOperationalActivityAchievementCaseDetailVo getCaseDetail(Integer activityId, Integer userId);
+
+    /**
+     * 商家端案例列表(按商户ID、上传情况、活动名称筛选)
+     *
+     * @param storeId 商户ID
+     * @param hasResult 上传情况:0-未上传, 1-已上传
+     * @param activityName 活动名称(模糊查询)
+     * @param pageNum 当前页
+     * @param pageSize 每页条数
+     * @return 分页列表
+     */
+    IPage<StoreOperationalActivityAchievementCaseVo> listStoreCasePage(Integer storeId, Integer hasResult,
+                                                                        String activityName, Integer pageNum, Integer pageSize);
 }
 }

+ 12 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreOperationalActivityAchievementServiceImpl.java

@@ -145,6 +145,18 @@ public class StoreOperationalActivityAchievementServiceImpl implements StoreOper
         return header;
         return header;
     }
     }
 
 
+    @Override
+    public IPage<StoreOperationalActivityAchievementCaseVo> listStoreCasePage(Integer storeId, Integer hasResult,
+                                                                               String activityName, Integer pageNum, Integer pageSize) {
+        if (storeId == null || storeId <= 0) {
+            throw new IllegalArgumentException("商户ID不能为空");
+        }
+        int current = pageNum == null || pageNum <= 0 ? 1 : pageNum;
+        int size = pageSize == null || pageSize <= 0 ? 10 : pageSize;
+        Page<StoreOperationalActivityAchievementCaseVo> page = new Page<>(current, size);
+        return achievementMapper.selectStoreCasePage(page, storeId, hasResult, activityName);
+    }
+
     private List<String> splitMediaUrls(String mediaUrls) {
     private List<String> splitMediaUrls(String mediaUrls) {
         if (mediaUrls == null || mediaUrls.trim().isEmpty()) {
         if (mediaUrls == null || mediaUrls.trim().isEmpty()) {
             return Collections.emptyList();
             return Collections.emptyList();