Browse Source

Merge branch 'master' of http://8.152.195.41:3000/alien/alien_cloud into zjy

zjy 2 months ago
parent
commit
90eea2597a
100 changed files with 3438 additions and 433 deletions
  1. 7 0
      alien-entity/src/main/java/shop/alien/entity/second/SecondGoodsRecord.java
  2. 8 0
      alien-entity/src/main/java/shop/alien/entity/second/SecondTradeRecord.java
  3. 13 0
      alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsRecordDetailVo.java
  4. 3 0
      alien-entity/src/main/java/shop/alien/entity/second/vo/SecondTradeRecordVo.java
  5. 80 0
      alien-entity/src/main/java/shop/alien/entity/store/ActivityInviteConfig.java
  6. 71 0
      alien-entity/src/main/java/shop/alien/entity/store/ActivityInviteLog.java
  7. 3 0
      alien-entity/src/main/java/shop/alien/entity/store/ActivitySignInConfig.java
  8. 75 0
      alien-entity/src/main/java/shop/alien/entity/store/AiIntelligentAssistant.java
  9. 64 0
      alien-entity/src/main/java/shop/alien/entity/store/LifeDiscountCouponFriendRule.java
  10. 51 0
      alien-entity/src/main/java/shop/alien/entity/store/LifeDiscountCouponFriendRuleDetail.java
  11. 8 0
      alien-entity/src/main/java/shop/alien/entity/store/LifeUser.java
  12. 67 0
      alien-entity/src/main/java/shop/alien/entity/store/StoreCommentSummary.java
  13. 7 2
      alien-entity/src/main/java/shop/alien/entity/store/StoreCustomerService.java
  14. 61 0
      alien-entity/src/main/java/shop/alien/entity/store/TagsMain.java
  15. 67 0
      alien-entity/src/main/java/shop/alien/entity/store/TagsSynonym.java
  16. 46 0
      alien-entity/src/main/java/shop/alien/entity/store/UserPoint.java
  17. 3 3
      alien-entity/src/main/java/shop/alien/entity/store/UserSignInRecord.java
  18. 2 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityConfigVo.java
  19. 24 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteConfigVo.java
  20. 28 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteInfoVo.java
  21. 32 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteLogVo.java
  22. 2 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPeriodVo.java
  23. 2 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPointInfoVo.java
  24. 25 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/LifeDiscountCouponFriendRuleDetailVo.java
  25. 49 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/LifeDiscountCouponFriendRuleVo.java
  26. 4 1
      alien-entity/src/main/java/shop/alien/entity/store/vo/LifeUserOrderVo.java
  27. 3 2
      alien-entity/src/main/java/shop/alien/entity/store/vo/StoreInfoVo.java
  28. 23 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/TagsMainVo.java
  29. 13 0
      alien-entity/src/main/java/shop/alien/mapper/ActivityInviteConfigMapper.java
  30. 24 0
      alien-entity/src/main/java/shop/alien/mapper/ActivityInviteLogMapper.java
  31. 1 1
      alien-entity/src/main/java/shop/alien/mapper/ActivityPeriodMapper.java
  32. 0 1
      alien-entity/src/main/java/shop/alien/mapper/ActivitySignInConfigMapper.java
  33. 0 3
      alien-entity/src/main/java/shop/alien/mapper/ActivitySignRewardMapper.java
  34. 19 0
      alien-entity/src/main/java/shop/alien/mapper/AiIntelligentAssistantMapper.java
  35. 53 0
      alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponFriendRuleDetailMapper.java
  36. 18 0
      alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponFriendRuleMapper.java
  37. 35 0
      alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponStoreFriendMapper.java
  38. 1 1
      alien-entity/src/main/java/shop/alien/mapper/LifeMessageMapper.java
  39. 2 1
      alien-entity/src/main/java/shop/alien/mapper/LifeUserDynamicsMapper.java
  40. 7 3
      alien-entity/src/main/java/shop/alien/mapper/LifeUserOrderMapper.java
  41. 4 4
      alien-entity/src/main/java/shop/alien/mapper/StoreCommentMapper.java
  42. 44 0
      alien-entity/src/main/java/shop/alien/mapper/StoreCommentSummaryMapper.java
  43. 21 0
      alien-entity/src/main/java/shop/alien/mapper/StoreIncomeDetailsRecordMapper.java
  44. 2 1
      alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java
  45. 60 0
      alien-entity/src/main/java/shop/alien/mapper/TagsMainMapper.java
  46. 43 0
      alien-entity/src/main/java/shop/alien/mapper/TagsSynonymMapper.java
  47. 13 0
      alien-entity/src/main/java/shop/alien/mapper/UserPointMapper.java
  48. 4 1
      alien-entity/src/main/java/shop/alien/mapper/WebAuditMapper.java
  49. 31 0
      alien-entity/src/main/java/shop/alien/mapper/second/SecondGoodsRecordMapper.java
  50. 32 1
      alien-entity/src/main/java/shop/alien/mapper/second/SecondTradeRecordMapper.java
  51. 38 0
      alien-entity/src/main/resources/mapper/AiIntelligentAssistantMapper.xml
  52. 25 0
      alien-entity/src/main/resources/mapper/LifeDiscountCouponFriendRuleDetailMapper.xml
  53. 18 0
      alien-entity/src/main/resources/mapper/LifeDiscountCouponFriendRuleMapper.xml
  54. 2 1
      alien-entity/src/main/resources/mapper/LifeUserOrderMapper.xml
  55. 1 0
      alien-entity/src/main/resources/mapper/ManagementInfoMapper.xml
  56. 16 15
      alien-entity/src/main/resources/mapper/second/SecondGoodsCategoryMapper.xml
  57. 485 0
      alien-job/src/main/java/shop/alien/job/store/AiTagJob.java
  58. 2 2
      alien-job/src/main/java/shop/alien/job/store/LifeUserOrderJob.java
  59. 15 0
      alien-second/src/main/java/shop/alien/second/platform/PlatformSecondCategoryController.java
  60. 29 2
      alien-second/src/main/java/shop/alien/second/platform/PlatformSecondTradeController.java
  61. 8 0
      alien-second/src/main/java/shop/alien/second/service/PlatformSecondTradeService.java
  62. 53 4
      alien-second/src/main/java/shop/alien/second/service/impl/PlatformSecondTradeServiceImpl.java
  63. 32 21
      alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java
  64. 75 0
      alien-store/src/main/java/shop/alien/store/config/BaseRedisService.java
  65. 27 4
      alien-store/src/main/java/shop/alien/store/controller/ActivityConfigController.java
  66. 147 0
      alien-store/src/main/java/shop/alien/store/controller/ActivityInviteConfigController.java
  67. 1 1
      alien-store/src/main/java/shop/alien/store/controller/LifeCouponController.java
  68. 19 0
      alien-store/src/main/java/shop/alien/store/controller/LifeDiscountCouponController.java
  69. 63 3
      alien-store/src/main/java/shop/alien/store/controller/LifeDiscountCouponStoreFriendController.java
  70. 4 3
      alien-store/src/main/java/shop/alien/store/controller/LifeUserController.java
  71. 1 72
      alien-store/src/main/java/shop/alien/store/controller/PingtaiTaocanController.java
  72. 2 5
      alien-store/src/main/java/shop/alien/store/controller/PlatformLifeUserController.java
  73. 10 4
      alien-store/src/main/java/shop/alien/store/controller/StoreClockInController.java
  74. 5 4
      alien-store/src/main/java/shop/alien/store/controller/StoreCommentController.java
  75. 79 0
      alien-store/src/main/java/shop/alien/store/controller/StoreCustomerServiceController.java
  76. 39 5
      alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java
  77. 0 1
      alien-store/src/main/java/shop/alien/store/service/ActivityConfigService.java
  78. 46 0
      alien-store/src/main/java/shop/alien/store/service/ActivityInviteConfigService.java
  79. 8 0
      alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponService.java
  80. 15 0
      alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponStoreFriendService.java
  81. 8 0
      alien-store/src/main/java/shop/alien/store/service/LifeUserDynamicsService.java
  82. 62 37
      alien-store/src/main/java/shop/alien/store/service/LifeUserOrderService.java
  83. 13 1
      alien-store/src/main/java/shop/alien/store/service/LifeUserService.java
  84. 7 3
      alien-store/src/main/java/shop/alien/store/service/LifeUserStoreService.java
  85. 1 1
      alien-store/src/main/java/shop/alien/store/service/StoreClockInService.java
  86. 1 1
      alien-store/src/main/java/shop/alien/store/service/StoreCommentService.java
  87. 17 0
      alien-store/src/main/java/shop/alien/store/service/StoreCustomerServiceService.java
  88. 0 10
      alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java
  89. 17 0
      alien-store/src/main/java/shop/alien/store/service/UserPointService.java
  90. 296 0
      alien-store/src/main/java/shop/alien/store/service/impl/ActivityInviteConfigServiceImpl.java
  91. 107 70
      alien-store/src/main/java/shop/alien/store/service/impl/LifeCouponServiceImpl.java
  92. 40 11
      alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponServiceImpl.java
  93. 226 103
      alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponStoreFriendServiceImpl.java
  94. 52 1
      alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponUserServiceImpl.java
  95. 1 1
      alien-store/src/main/java/shop/alien/store/service/impl/LifeGroupBuyCountServiceImpl.java
  96. 3 0
      alien-store/src/main/java/shop/alien/store/service/impl/LifeNoticeServiceImpl.java
  97. 4 4
      alien-store/src/main/java/shop/alien/store/service/impl/LifeUserViolationServiceImpl.java
  98. 23 10
      alien-store/src/main/java/shop/alien/store/service/impl/SignInServiceImpl.java
  99. 27 7
      alien-store/src/main/java/shop/alien/store/service/impl/StoreClockInServiceImpl.java
  100. 13 1
      alien-store/src/main/java/shop/alien/store/service/impl/StoreCommentServiceImpl.java

+ 7 - 0
alien-entity/src/main/java/shop/alien/entity/second/SecondGoodsRecord.java

@@ -20,6 +20,13 @@ public class SecondGoodsRecord implements Serializable {
     @ApiModelProperty(value = "主键ID")
     private Integer id;
 
+    @ApiModelProperty("一级分类名称")
+    @TableField(exist = false)
+    private String categoryOneName;
+
+    @ApiModelProperty("二级分类名称")
+    @TableField(exist = false)
+    private String categoryTwoName;
 
     @TableField("user_id")
     @ApiModelProperty(value = "用户ID")

+ 8 - 0
alien-entity/src/main/java/shop/alien/entity/second/SecondTradeRecord.java

@@ -135,6 +135,14 @@ public class SecondTradeRecord extends Model<SecondTradeRecord> {
     @TableField("cancel_reason_supplement")
     private String cancelReasonSupplement;
 
+    @ApiModelProperty(value = "失效状态(平台端统计用)  0-未失效  1-已失效")
+    @TableField("failure_flag")
+    private String failureFlag;
+
+    @ApiModelProperty(value = "失效原因")
+    @TableField("failure_reason")
+    private String failureReason;
+
     @ApiModelProperty(value = "删除标记  0:未删除  1:已删除")
     @TableField("delete_flag")
     @TableLogic

+ 13 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondGoodsRecordDetailVo.java

@@ -26,6 +26,14 @@ public class SecondGoodsRecordDetailVo {
     @ApiModelProperty(value = "用户电话")
     private String userPhone;
 
+    @ApiModelProperty("一级分类名称")
+    @TableField(exist = false)
+    private String categoryOneName;
+
+    @ApiModelProperty("二级分类名称")
+    @TableField(exist = false)
+    private String categoryTwoName;
+
     @TableField("user_id")
     @ApiModelProperty(value = "用户ID")
     private Integer userId;
@@ -144,6 +152,11 @@ public class SecondGoodsRecordDetailVo {
         vo.setUpdatedTime(record.getUpdatedTime());
         vo.setUpdatedUserId(record.getUpdatedUserId());
         vo.setAddressText(record.getAddressText());
+        vo.setUpdatedUserId(record.getUpdatedUserId());
+        vo.setAddressText(record.getAddressText());
+        vo.setCategoryOneName(record.getCategoryOneName());
+        vo.setCategoryTwoName(record.getCategoryTwoName());
+
         return vo;
     }
 }

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/second/vo/SecondTradeRecordVo.java

@@ -39,6 +39,9 @@ public class SecondTradeRecordVo extends SecondTradeRecord {
     @ApiModelProperty(value = "商品标题")
     private String title;
 
+    @ApiModelProperty(value = "用户id")
+    private Integer userId;
+
     @TableField(exist = false)
     @ApiModelProperty(value = "用户电话")
     private String userPhone;

+ 80 - 0
alien-entity/src/main/java/shop/alien/entity/store/ActivityInviteConfig.java

@@ -0,0 +1,80 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+@Data
+@JsonInclude
+@TableName("activity_invite_config")
+@ApiModel(value = "ActivityInviteConfig", description = "邀请活动配置表")
+public class ActivityInviteConfig {
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "活动名称")
+    private String activityName;
+
+    @ApiModelProperty(value = "活动类型:1,邀请好友,2.其他")
+    private Integer activityType;
+
+    @ApiModelProperty(value = "活动规则")
+    private String activityRule;
+
+    @ApiModelProperty(value = "活动状态:0-未启用,1-启用,2-已结束")
+    private Integer status;
+
+    @ApiModelProperty(value = "邀请成功条件:1,注册即算,2.实名认证,3,首单支付并成功核销")
+    private Integer inviteCondition;
+
+    @ApiModelProperty(value = "邀请人数")
+    private Integer invitePersonNum;
+
+    @ApiModelProperty(value = "邀请奖励类型:1.优惠券,2.积分")
+    private Integer inviteRewardType;
+
+    @ApiModelProperty(value = "邀请奖励积分")
+    private Integer inviteRewardPoint;
+
+    @ApiModelProperty(value = "邀请奖励优惠券")
+    private Integer inviteRewardCoupon;
+
+    @ApiModelProperty(value = "被邀请奖励类型:1.优惠券,2.积分")
+    private Integer invitedRewardType;
+
+    @ApiModelProperty(value = "被邀请奖励积分")
+    private Integer invitedRewardPoint;
+
+    @ApiModelProperty(value = "被邀请奖励优惠券")
+    private Integer invitedRewardCoupon;
+
+
+    @ApiModelProperty(value = "每天最大邀请人数")
+    private Integer maxInviteNum;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+}

+ 71 - 0
alien-entity/src/main/java/shop/alien/entity/store/ActivityInviteLog.java

@@ -0,0 +1,71 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+@Data
+@JsonInclude
+@TableName("activity_invite_log")
+@ApiModel(value = "ActivityInviteLog", description = "邀请记录表")
+public class ActivityInviteLog {
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "活动ID")
+    private Integer activityId;
+
+    @ApiModelProperty(value = "邀请人用户ID")
+    private Integer inviteUserId;
+
+    @ApiModelProperty(value = "邀请时间")
+    private Date inviteTime;
+
+    @ApiModelProperty(value = "被邀请人用户ID")
+    private Integer invitedUserId;
+
+    @ApiModelProperty(value = "邀请奖励类型:1.优惠券,2.积分")
+    private Integer inviteRewardType;
+
+    @ApiModelProperty(value = "邀请奖励积分")
+    private Integer inviteRewardPoint;
+
+    @ApiModelProperty(value = "邀请奖励优惠券")
+    private Integer inviteRewardCoupon;
+
+    @ApiModelProperty(value = "被邀请奖励类型:1.优惠券,2.积分")
+    private Integer invitedRewardType;
+
+    @ApiModelProperty(value = "被邀请奖励积分")
+    private Integer invitedRewardPoint;
+
+    @ApiModelProperty(value = "被邀请奖励优惠券")
+    private Integer invitedRewardCoupon;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+}

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/ActivitySignInConfig.java

@@ -33,6 +33,9 @@ public class ActivitySignInConfig {
     @ApiModelProperty(value = "活动规则")
     private String activityRule;
 
+    @ApiModelProperty(value = "奖励类型1,积分,2.其他")
+    private Integer baseRewardType;
+
     @ApiModelProperty(value = "基础奖励积分")
     private Integer basePoints;
 

+ 75 - 0
alien-entity/src/main/java/shop/alien/entity/store/AiIntelligentAssistant.java

@@ -0,0 +1,75 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+/**
+ * AI 智能助手表
+ *
+ * @author qxy
+ * @since 2025-09-23
+ */
+@Data
+@JsonInclude
+@TableName("ai_intelligent_assistant")
+@ApiModel(value = "AiIntelligentAssistant对象", description = "AI智能助手")
+public class AiIntelligentAssistant {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "内容")
+    @TableField("context")
+    private String context;
+
+    @ApiModelProperty(value = "1平台使用/2商户运营")
+    @TableField("talk_source")
+    private Integer talkSource;
+
+    @ApiModelProperty(value = "类型(0空数据/1输入的问题/2ai回答/3固定问题)")
+    @TableField("type")
+    private Integer type;
+
+    @ApiModelProperty(value = "回复id")
+    @TableField("reply_id")
+    private Integer replyId;
+
+    @ApiModelProperty(value = "回复时间")
+    @TableField("reply_date")
+    private Date replyDate;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+}

+ 64 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeDiscountCouponFriendRule.java

@@ -0,0 +1,64 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 赠券规则
+ * @TableName life_discount_coupon_friend_rule
+ */
+@TableName(value ="life_discount_coupon_friend_rule")
+@JsonInclude
+@Data
+public class LifeDiscountCouponFriendRule {
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 店铺id
+     */
+    @ApiModelProperty(value = "店铺id")
+    @TableField("store_id")
+    private Integer storeId;
+
+    /**
+     * 活动名称
+     */
+    @ApiModelProperty(value = "活动名称")
+    @TableField("ac_name")
+    private String acName;
+
+    /**
+     * 消费限制(开始)
+     */
+    @ApiModelProperty(value = "消费限制(开始)")
+    @TableField("money_low")
+    private BigDecimal moneyLow;
+
+    /**
+     * 消费限制(结束)
+     */
+    @ApiModelProperty(value = "消费限制(结束)")
+    @TableField("money_high")
+    private BigDecimal moneyHigh;
+
+    /**
+     * 删除状态(0未删除/1已删除)
+     */
+    @ApiModelProperty(value = "删除状态(0未删除/1已删除)")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @TableField(exist = false)
+    private List<LifeDiscountCouponFriendRuleDetail> details;
+}

+ 51 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeDiscountCouponFriendRuleDetail.java

@@ -0,0 +1,51 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 赠券规则明细
+ * @TableName life_discount_coupon_friend_rule_detail
+ */
+@TableName(value ="life_discount_coupon_friend_rule_detail")
+@JsonInclude
+@Data
+public class LifeDiscountCouponFriendRuleDetail {
+    /**
+     * 主键id
+     */
+    @TableId
+    private Integer id;
+
+    /**
+     * 规则id
+     */
+    @ApiModelProperty(value = "规则id")
+    @TableField("rule_id")
+    private Integer ruleId;
+
+    /**
+     * 优惠券id
+     */
+    @ApiModelProperty(value = "优惠券id")
+    @TableField("coupon_id")
+    private Integer couponId;
+
+    /**
+     * 好友店铺id
+     */
+    @ApiModelProperty(value = "好友店铺id")
+    @TableField("friend_store_user_id")
+    private Integer friendStoreUserId;
+
+    /**
+     * 店铺id
+     */
+    @ApiModelProperty(value = "店铺id")
+    @TableField("store_id")
+    private Integer storeId;
+}

+ 8 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeUser.java

@@ -113,4 +113,12 @@ public class LifeUser implements Serializable {
     @ApiModelProperty(value = "打卡广场小人图片id")
     @TableField("clock_img_id")
     private Integer clockImgId;
+
+    @ApiModelProperty(value = "个人邀请码")
+    @TableField("invite_code")
+    private String inviteCode;
+
+    @ApiModelProperty(value = "绑定他人邀请码")
+    @TableField("bind_invite_code")
+    private String bindInviteCode;
 }

+ 67 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreCommentSummary.java

@@ -0,0 +1,67 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+/**
+ * AI服务 店铺评论总结表:记录店铺评论的时间范围、任务信息、总结内容等
+ */
+@Data
+@JsonInclude
+@TableName("tags_main")
+@ApiModel(value = "tags_main", description = "tags_main")
+public class StoreCommentSummary {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "店铺ID(新增字段)")
+    @TableField("store_id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "店铺名称(对应表格“店铺名称”)")
+    @TableField("store_name")
+    private String storeName;
+
+    @ApiModelProperty(value = "总结内容(对应表格“总结内容”,允许为空)")
+    @TableField("summary")
+    private String summary;
+
+    @ApiModelProperty(value = "任务唯一标识(如 UUID,新增字段)")
+    @TableField("task_id")
+    private String taskId;
+
+    @ApiModelProperty(value = "是否显示:0-不显示,1-显示(新增字段)")
+    @TableField("is_show")
+    private Integer isShow;
+
+    @ApiModelProperty(value = "删除标识")
+    @TableLogic
+    @TableField("delete_flag")
+    private Integer  deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 7 - 2
alien-entity/src/main/java/shop/alien/entity/store/StoreCustomerService.java

@@ -2,8 +2,8 @@ package shop.alien.entity.store;
 
 import com.baomidou.mybatisplus.annotation.*;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
+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;
 
@@ -21,7 +21,6 @@ import java.util.Date;
 @Data
 @JsonInclude
 @TableName("store_customer_service")
-@ApiModel(value = "StoreBusinessInfo对象", description = "门店营业时间")
 public class StoreCustomerService extends Model<StoreCustomerService> {
 
     private static final long serialVersionUID = 1L;
@@ -30,6 +29,10 @@ public class StoreCustomerService extends Model<StoreCustomerService> {
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
+    @ApiModelProperty(value = "类型(1/商家/2用户)")
+    @TableField("type")
+    private Integer type;
+
     @ApiModelProperty(value = "问题")
     @TableField("question")
     private String question;
@@ -49,6 +52,7 @@ public class StoreCustomerService extends Model<StoreCustomerService> {
 
     @ApiModelProperty(value = "创建时间")
     @TableField("created_time")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date createdTime;
 
     @ApiModelProperty(value = "创建人ID")
@@ -57,6 +61,7 @@ public class StoreCustomerService extends Model<StoreCustomerService> {
 
     @ApiModelProperty(value = "修改时间")
     @TableField("updated_time")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date updatedTime;
 
     @ApiModelProperty(value = "修改人ID")

+ 61 - 0
alien-entity/src/main/java/shop/alien/entity/store/TagsMain.java

@@ -0,0 +1,61 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * AI服务标签主表
+ */
+@Data
+@JsonInclude
+@TableName("tags_main")
+@ApiModel(value = "tags_main", description = "tags_main")
+public class TagsMain {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "标签名称")
+    @TableField("tag_name")
+    private String tagName;
+
+    @ApiModelProperty(value = "删除标识")
+    @TableLogic
+    @TableField("delete_flag")
+    private Integer  deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "门店id")
+    @TableField("store_id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "标签类型,0:好评,1:中评,2:差评")
+    @TableField("tag_type")
+    private Integer tagType;
+
+}

+ 67 - 0
alien-entity/src/main/java/shop/alien/entity/store/TagsSynonym.java

@@ -0,0 +1,67 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * AI服务标签子表
+ */
+@Data
+@JsonInclude
+@TableName("tags_synonym")
+@ApiModel(value = "tags_synonym", description = "tags_synonym")
+public class TagsSynonym {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "主标签ID")
+    @TableField("main_tag_id")
+    private Integer mainTagId;
+
+    @ApiModelProperty(value = "评论ID")
+    @TableField("comment_id")
+    private Integer commentId;
+
+    @ApiModelProperty(value = "子标签名称")
+    @TableField("synonym_tag")
+    private String synonymTag;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    private int deleteFlag;
+
+    @ApiModelProperty(value = "标签类型, 0:店铺级标签, 1:商品级标签")
+    @TableField("tag_type")
+    private int tagType;
+
+    @ApiModelProperty(value = "任务唯一标识(由生产者生成,如 UUID)")
+    @TableField("task_id")
+    private String taskId;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 46 - 0
alien-entity/src/main/java/shop/alien/entity/store/UserPoint.java

@@ -0,0 +1,46 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+@Data
+@JsonInclude
+@TableName("user_point")
+@ApiModel(value = "UserPoint", description = "用户积分表")
+public class UserPoint {
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "用户积分")
+    private Integer userPoint;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+}

+ 3 - 3
alien-entity/src/main/java/shop/alien/entity/store/UserSignInRecord.java

@@ -20,7 +20,7 @@ public class UserSignInRecord {
     @ApiModelProperty(value = "用户ID")
     private Integer userId;
 
-    @ApiModelProperty(value = "当前连续签到天数")
+    @ApiModelProperty(value = "当前连续签到天数(默认方案,循环签到连续时间)")
     private Integer continuousDays;
 
     @ApiModelProperty(value = "本次获得积分")
@@ -52,9 +52,9 @@ public class UserSignInRecord {
     @TableLogic
     private Integer deleteFlag;
 
-    @ApiModelProperty(value = "总计连续签到天数")
+    @ApiModelProperty(value = "总计连续签到天数(总计连续签到)")
     private Integer totalContinuousDays;
 
-    @ApiModelProperty(value = "特殊方案连续签到天数")
+    @ApiModelProperty(value = "特殊方案连续签到天数(特殊方案的连续签到)")
     private Integer specialContinuousDays;
 }

+ 2 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityConfigVo.java

@@ -1,6 +1,7 @@
 package shop.alien.entity.store.vo;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -18,6 +19,7 @@ import java.util.List;
 @EqualsAndHashCode(callSuper = true)
 @Data
 @JsonInclude
+@ApiModel(value = "ActivityConfigVo对象", description = "ActivityConfigVo")
 public class ActivityConfigVo extends ActivitySignInConfig {
 
     @ApiModelProperty(value = "签到奖励配置列表")

+ 24 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteConfigVo.java

@@ -0,0 +1,24 @@
+package shop.alien.entity.store.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import shop.alien.entity.store.ActivityInviteConfig;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/9/8 10:00
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonInclude
+@ApiModel(value = "ActivityInviteConfigVo对象", description = "ActivityInviteConfigVo")
+public class ActivityInviteConfigVo extends ActivityInviteConfig {
+    @ApiModelProperty(value = "返回错误信息")
+    @TableField(exist = false)
+    private String errorMessage;
+}

+ 28 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteInfoVo.java

@@ -0,0 +1,28 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/9/8 10:00
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+@JsonInclude
+@ApiModel(value = "ActivityInviteInfoVo对象", description = "ActivityInviteInfoVo")
+public class ActivityInviteInfoVo {
+
+    @ApiModelProperty(value = "邀请码")
+    private String inviteCode;
+
+    @ApiModelProperty(value = "邀请数量")
+    private Integer inviteCount;
+
+    @ApiModelProperty(value = "邀请奖励积分")
+    private Integer invitePoint;
+}

+ 32 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityInviteLogVo.java

@@ -0,0 +1,32 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import shop.alien.entity.store.ActivityInviteLog;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/9/8 10:00
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+@JsonInclude
+@ApiModel(value = "ActivityInviteLogVo对象", description = "ActivityInviteLogVo")
+public class ActivityInviteLogVo extends ActivityInviteLog {
+
+    @ApiModelProperty(value = "被邀请人头像")
+    private String userImage;
+
+    @ApiModelProperty(value = "邀请人电话")
+    private String invitePhone;
+
+    @ApiModelProperty(value = "被邀请电话")
+    private String invitedPhone;
+
+    @ApiModelProperty(value = "被邀请人昵称")
+    private String invitedNickName;
+}

+ 2 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPeriodVo.java

@@ -2,6 +2,7 @@ package shop.alien.entity.store.vo;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -9,6 +10,7 @@ import shop.alien.entity.store.ActivityPeriod;
 @EqualsAndHashCode(callSuper = true)
 @Data
 @JsonInclude
+@ApiModel(value = "ActivityPeriodVo对象", description = "ActivityPeriodVo")
 public class ActivityPeriodVo extends ActivityPeriod {
     /**
      * 活动名称

+ 2 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ActivityPointInfoVo.java

@@ -1,6 +1,7 @@
 package shop.alien.entity.store.vo;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -13,6 +14,7 @@ import lombok.EqualsAndHashCode;
 @EqualsAndHashCode(callSuper = false)
 @Data
 @JsonInclude
+@ApiModel(value = "ActivityPointInfoVo对象", description = "ActivityPointInfoVo")
 public class ActivityPointInfoVo {
     @ApiModelProperty(value = "积分")
     private Integer point;

+ 25 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeDiscountCouponFriendRuleDetailVo.java

@@ -0,0 +1,25 @@
+package shop.alien.entity.store.vo;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import shop.alien.entity.store.LifeDiscountCouponFriendRule;
+import shop.alien.entity.store.LifeDiscountCouponFriendRuleDetail;
+
+/**
+ * 赠券规则
+ * @TableName life_discount_coupon_friend_rule
+ */
+@TableName(value ="life_discount_coupon_friend_rule")
+@JsonInclude
+@Data
+public class LifeDiscountCouponFriendRuleDetailVo extends LifeDiscountCouponFriendRuleDetail {
+
+    private String storeName;
+
+    private String couponName;
+
+    private Integer couponNum;
+
+    private Integer friendStoreUserId;
+}

+ 49 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeDiscountCouponFriendRuleVo.java

@@ -0,0 +1,49 @@
+package shop.alien.entity.store.vo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.store.LifeDiscountCouponFriendRule;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 赠券规则
+ * @TableName life_discount_coupon_friend_rule
+ */
+@TableName(value ="life_discount_coupon_friend_rule")
+@JsonInclude
+@Data
+public class LifeDiscountCouponFriendRuleVo extends LifeDiscountCouponFriendRule {
+
+    @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "截止时间")
+    private Date endDate;
+
+    @ApiModelProperty(value = "店铺名称")
+    private String storeName;
+
+    @ApiModelProperty(value = "0启用/1禁用")
+    private String status;
+
+    @ApiModelProperty(value = "img")
+    private String imgUrl;
+
+    @ApiModelProperty(value = "优惠券名称")
+    private String couponName;
+
+    @ApiModelProperty(value = "优惠券数量")
+    private Integer couponNum;
+
+    @ApiModelProperty(value = "面值")
+    private BigDecimal nominalValue;
+
+    @ApiModelProperty(value = "最低消费")
+    private BigDecimal minimumSpendingAmount;
+
+    private List<LifeDiscountCouponFriendRuleDetailVo> lifeDiscountCouponFriendRuleDetailVos;
+}

+ 4 - 1
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeUserOrderVo.java

@@ -144,8 +144,11 @@ public class LifeUserOrderVo {
     private Date endDate;
     @ApiModelProperty(value = "是否评论")
     private Boolean hasComment;
+    @ApiModelProperty(value = "营业状态")
+    private String businessStatus;
 
-
+    @ApiModelProperty(value = "商户状态")
+    private String abnormalStateFlag;
 
     @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
     @TableField("delete_flag")

+ 3 - 2
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreInfoVo.java

@@ -1,6 +1,5 @@
 package shop.alien.entity.store.vo;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.annotations.ApiModel;
@@ -8,7 +7,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
-import shop.alien.entity.store.LifeCoupon;
 import shop.alien.entity.store.StoreBusinessInfo;
 import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.store.StoreStaffConfig;
@@ -210,4 +208,7 @@ public class StoreInfoVo extends StoreInfo {
 
     private String commitCount;
 
+    @ApiModelProperty(value = "食品经营许可")
+    private String foodLicenceImageUrl;
+
 }

+ 23 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/TagsMainVo.java

@@ -0,0 +1,23 @@
+package shop.alien.entity.store.vo;
+
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import shop.alien.entity.store.TagsMain;
+
+
+@Data
+@JsonInclude
+@NoArgsConstructor
+@ApiModel(value = "TagsMainVo对象", description = "AI服务标签")
+public class TagsMainVo extends TagsMain {
+
+    @ApiModelProperty(value = "评价数量")
+    private Integer evaluateNumber;
+
+
+
+}

+ 13 - 0
alien-entity/src/main/java/shop/alien/mapper/ActivityInviteConfigMapper.java

@@ -0,0 +1,13 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.ActivityInviteConfig;
+
+/**
+ * 邀请活动配置mapper
+ */
+@Mapper
+public interface ActivityInviteConfigMapper extends BaseMapper<ActivityInviteConfig> {
+
+}

+ 24 - 0
alien-entity/src/main/java/shop/alien/mapper/ActivityInviteLogMapper.java

@@ -0,0 +1,24 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import shop.alien.entity.store.ActivityInviteLog;
+import shop.alien.entity.store.vo.ActivityInviteLogVo;
+
+/**
+ * 邀请活动记录mapper
+ */
+@Mapper
+public interface ActivityInviteLogMapper extends BaseMapper<ActivityInviteLog> {
+
+    @Select("select ail.*, lu.user_phone as invitePhone, lu1.user_phone as invitedPhone, lu1.user_image, lu1.user_name as invitedNickName  " +
+            "from activity_invite_log ail " +
+            "left join life_user lu on lu.id = ail.invite_user_id and lu.delete_flag  = 0 " +
+            "left join life_user lu1 on lu1.id = ail.invited_user_id and lu1.delete_flag = 0 ${ew.customSqlSegment}")
+    IPage<ActivityInviteLogVo> getInviteActivityLogList(IPage<ActivityInviteLogVo> iPage, @Param(Constants.WRAPPER) QueryWrapper<ActivityInviteLogVo> wrapper);
+}

+ 1 - 1
alien-entity/src/main/java/shop/alien/mapper/ActivityPeriodMapper.java

@@ -10,7 +10,7 @@ import java.util.List;
 public interface ActivityPeriodMapper extends BaseMapper<ActivityPeriod> {
     @Select("select asic.id, asic.activity_name, ap.start_time, ap.end_time from activity_period ap " +
             "left join activity_sign_in_config asic on asic.id = ap.activity_id " +
-            "where asic.delete_flag = 0 and ap.delete_flag = 0 and ap.start_time < #{endTime} and ap.end_time > #{startTime}")
+            "where asic.delete_flag = 0 and ap.delete_flag = 0 and ap.start_time <= #{endTime} and ap.end_time >= #{startTime}")
     List<ActivityPeriodVo> getActivityPeriodList(@Param("startTime") String startTime, @Param("endTime") String endTime);
     @Select("select ap.id,ap.activity_id,asic.activity_name,asic.plan_config_type from activity_period ap " +
             "left join activity_sign_in_config asic on asic.id = ap.activity_id " +

+ 0 - 1
alien-entity/src/main/java/shop/alien/mapper/ActivitySignInConfigMapper.java

@@ -3,7 +3,6 @@ package shop.alien.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 import shop.alien.entity.store.ActivitySignInConfig;
-import shop.alien.entity.store.LifeClassManage;
 
 /**
  * 签到活动配置mapper

+ 0 - 3
alien-entity/src/main/java/shop/alien/mapper/ActivitySignRewardMapper.java

@@ -5,10 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
-import shop.alien.entity.store.ActivitySignInConfig;
 import shop.alien.entity.store.ActivitySignInReward;
-import shop.alien.entity.store.vo.ActivityPeriodVo;
-import shop.alien.entity.store.vo.LifeFansVo;
 
 import java.util.List;
 /**

+ 19 - 0
alien-entity/src/main/java/shop/alien/mapper/AiIntelligentAssistantMapper.java

@@ -0,0 +1,19 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.AiIntelligentAssistant;
+
+import java.util.List;
+
+
+@Mapper
+public interface AiIntelligentAssistantMapper extends BaseMapper<AiIntelligentAssistant> {
+
+
+    void insertList(List<AiIntelligentAssistant> list);
+}
+
+
+
+

+ 53 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponFriendRuleDetailMapper.java

@@ -0,0 +1,53 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import shop.alien.entity.store.LifeDiscountCouponFriendRuleDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleDetailVo;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleVo;
+import shop.alien.entity.store.vo.LifeGroupBuyThaliVo;
+
+import java.util.List;
+
+/**
+* @author youch
+* @description 针对表【life_discount_coupon_friend_rule_detail(赠券规则明细)】的数据库操作Mapper
+* @createDate 2025-09-18 13:32:40
+* @Entity shop.alien.entity.store.LifeDiscountCouponFriendRuleDetail
+*/
+public interface LifeDiscountCouponFriendRuleDetailMapper extends BaseMapper<LifeDiscountCouponFriendRuleDetail> {
+
+    void insertList(List<LifeDiscountCouponFriendRuleDetail> lifeDiscountCouponFriendRuleDetailList);
+
+    @Select("select si.store_name storeName,ldc.name couponName,ldc.id couponId,sum(ldcsf.single_qty) couponNum,ldcsf.friend_store_user_id friendStoreUserId from life_discount_coupon_store_friend ldcsf left join life_discount_coupon ldc on ldcsf.coupon_id = ldc.id left join store_user su on ldcsf.friend_store_user_id = su.id left join store_info si on su.store_id = si.id ${ew.customSqlSegment}")
+    List<LifeDiscountCouponFriendRuleDetailVo> getReceivedFriendCouponList(@Param(Constants.WRAPPER) QueryWrapper<LifeDiscountCouponFriendRuleDetailVo> queryWrapper);
+
+    @Select("SELECT\n" +
+            "\ta.*,\n" +
+            "\t(select MAX( end_get_date ) from life_discount_coupon c left join life_discount_coupon_friend_rule_detail b on c.id = b.coupon_id where b.rule_id = a.id) endDate \n" +
+            "FROM\n" +
+            "\tlife_discount_coupon_friend_rule a\n" +
+            "\t where a.store_id = #{storeId} and a.delete_flag = 0 order by endDate")
+    List<LifeDiscountCouponFriendRuleVo> getRuleList(@Param("storeId")String storeId);
+
+    @Select("SELECT a.*, c.name as couponName, c.id as couponId,si.store_name storeName, " +
+            "(SELECT\n" +
+            "\t\tsum( single_qty ) \n" +
+            "\tFROM\n" +
+            "\t\tlife_discount_coupon_store_friend b\n" +
+            "\tWHERE\n" +
+            "\t\tb.friend_store_user_id = a.friend_store_user_id \n" +
+            "\t\tAND b.coupon_id = a.coupon_id \n" +
+            "\t\tAND b.store_user_id = a.store_id) couponNum " +
+            "FROM life_discount_coupon_friend_rule_detail a " +
+            "LEFT JOIN life_discount_coupon c ON a.coupon_id = c.id LEFT JOIN store_info si on c.store_id = si.id " +
+            "WHERE a.rule_id = #{ruleId}")
+    List<LifeDiscountCouponFriendRuleDetailVo> getDetailList(@Param("ruleId")String ruleId);
+}
+
+
+
+

+ 18 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponFriendRuleMapper.java

@@ -0,0 +1,18 @@
+package shop.alien.mapper;
+
+import shop.alien.entity.store.LifeDiscountCouponFriendRule;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author youch
+* @description 针对表【life_discount_coupon_friend_rule(赠券规则)】的数据库操作Mapper
+* @createDate 2025-09-18 13:32:36
+* @Entity shop.alien.entity.store.LifeDiscountCouponFriendRule
+*/
+public interface LifeDiscountCouponFriendRuleMapper extends BaseMapper<LifeDiscountCouponFriendRule> {
+
+}
+
+
+
+

+ 35 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeDiscountCouponStoreFriendMapper.java

@@ -7,9 +7,12 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import shop.alien.entity.store.LifeDiscountCouponStoreFriend;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponStoreFriendVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponVo;
 
+import java.util.List;
+
 /**
  * <p>
  * 优惠券商户发放好友优惠券关系表	 Mapper 接口
@@ -31,4 +34,36 @@ public interface LifeDiscountCouponStoreFriendMapper extends BaseMapper<LifeDisc
             "on si.id = ldc.store_id and si.delete_flag = 0\n" +
             "${ew.customSqlSegment}")
     IPage<LifeDiscountCouponVo> selectPage(IPage<LifeDiscountCouponStoreFriendVo> iPage, @Param(Constants.WRAPPER) QueryWrapper<LifeDiscountCouponStoreFriendVo> friendLifeDiscountCouponQueryWrapper);
+
+    @Select("select ldcsf.created_time endDate,ldc.nominal_value nominalValue,ldc.minimum_spending_amount minimumSpendingAmount,img.img_url imgUrl,\n" +
+            "si.store_name storeName,\n" +
+            "ldc.name couponName,\n" +
+            "ldcsf.single_qty couponNum\n" +
+            "from  life_discount_coupon_store_friend ldcsf\n" +
+            "left join life_discount_coupon ldc\n" +
+            "on ldc.id = ldcsf.coupon_id and ldc.delete_flag = 0\n" +
+            "left join store_info si\n" +
+            "on si.id = ldc.store_id and si.delete_flag = 0\n" +
+            "left join store_user su on si.id = su.store_id\n" +
+            "left join store_img img on si.id = img.store_id and img.img_type = 1 and img.delete_flag = 0\n" +
+            "${ew.customSqlSegment}")
+    List<LifeDiscountCouponFriendRuleVo> getReceivedSendFriendCouponList(@Param(Constants.WRAPPER) QueryWrapper<LifeDiscountCouponFriendRuleVo> lifeDiscountCouponFriendRuleVoQueryWrapper);
+
+    //我赠好友
+    @Select("select ldcsf.created_time endDate,ldc.nominal_value nominalValue,ldc.minimum_spending_amount minimumSpendingAmount,img.img_url imgUrl,\n" +
+            "si.store_name storeName,\n" +
+            "ldc.name couponName,\n" +
+            "ldcsf.single_qty couponNum\n" +
+            "from  life_discount_coupon_store_friend ldcsf\n" +
+            "left join life_discount_coupon ldc\n" +
+            "on ldc.id = ldcsf.coupon_id and ldc.delete_flag = 0\n" +
+
+            "left join store_info si\n" +
+            "on si.id = ldcsf.store_user_id and si.delete_flag = 0\n" +
+
+            "left join store_user su on ldcsf.store_user_id = su.store_id\n" +
+
+            "left join store_img img on si.id = img.store_id and img.img_type = 1 and img.delete_flag = 0\n" +
+            "${ew.customSqlSegment}")
+    List<LifeDiscountCouponFriendRuleVo> getReceivedSendFriendCouponListwzhy(@Param(Constants.WRAPPER) QueryWrapper<LifeDiscountCouponFriendRuleVo> lifeDiscountCouponFriendRuleVoQueryWrapper);
 }

+ 1 - 1
alien-entity/src/main/java/shop/alien/mapper/LifeMessageMapper.java

@@ -43,7 +43,7 @@ public interface LifeMessageMapper extends BaseMapper<LifeMessage> {
             ") " +
             "select message.id, message.type, message.phoneId, message.content, message.created_time createdTime, message.is_read, " +
             "       if (message.flag = 'user', user.user_name, suser.nick_name) userName, " +
-            "       if (message.flag = 'user', user.user_image, img.img_url) userImage," +
+            " IF(INSTR( #{phoneId}, 'user' ) > 0, user.user_image, suser.head_img ) user_image, "+
             "       if (message.flag = 'user', user.id, suser.id) userId " +
             "from message_num message " +
             "left join life_user user on message.flag = 'user' and message.phone = user.user_phone and user.delete_flag = 0 " +

+ 2 - 1
alien-entity/src/main/java/shop/alien/mapper/LifeUserDynamicsMapper.java

@@ -46,6 +46,7 @@ public interface LifeUserDynamicsMapper extends BaseMapper<LifeUserDynamics> {
     @Select("select lud.*,'1' isLike\n" +
             "from life_user_dynamics lud \n" +
             "where lud.delete_flag = 0 \n" +
-            "and lud.id in (select llr.huifu_id from life_like_record llr where llr.dianzan_id = #{phoneId} and llr.delete_flag = 0)")
+            "and lud.id in (select llr.huifu_id from life_like_record llr where llr.dianzan_id = #{phoneId} and llr.delete_flag = 0) \n"+
+            "and lud.phone_id not in (select lb.blocked_phone_id  from life_blacklist lb where lb.blocker_phone_id = #{phoneId} and lb.delete_flag = 0)")
     List<LifeUserDynamicsVo> selectDianZanList(String phoneId);
 }

+ 7 - 3
alien-entity/src/main/java/shop/alien/mapper/LifeUserOrderMapper.java

@@ -43,14 +43,18 @@ public interface LifeUserOrderMapper extends BaseMapper<LifeUserOrder> {
             "from life_coupon lc where lc.delete_flag = 0\n" +
             ")\n" +
             "select luo.id,luo.buy_time,luo.status,luo.price,luo.final_price,luo.user_id,luo.store_id,luo.order_no,luo.pay_time,luo.cancel_time,luo.finish_time,\n" +
-            "si.store_name,si.commission_rate,si.business_section store_type,\n" +
+            "si.store_name,si.commission_rate,si.business_section store_type,si.business_status,\n" +
             "count(ocm.coupon_code) coupon_count,\n" +
             "simg.img_url,\n" +
             "lu.user_phone,\n" +
             "IF(sc.id is null,false,true) as hasComment,\n" +
-            "tc.*\n" +
+            "tc.*,\n" +
+            "CASE\n" +
+            "        WHEN si.delete_flag = 1 OR si.logout_flag = 1 THEN 1\n" +
+            "        ELSE 0\n" +
+            "    END AS abnormalStateFlag\n" +
             "from life_user_order luo\n" +
-            "left join store_info si on si.id = luo.store_id and si.delete_flag = 0 -- 查询店铺相关 \n" +
+            "left join store_info si on si.id = luo.store_id  -- 查询店铺相关 \n" +
             "left join life_user lu on lu.id = luo.user_id and lu.delete_flag = 0 -- 查询用户相关 \n" +
             "left join order_coupon_middle ocm on ocm.order_id = luo.id and ocm.delete_flag = 0\n" +
             "inner join total_coupon tc on tc.coupon_id = ocm.coupon_id and tc.coupon_type = luo.coupon_type\n" +

+ 4 - 4
alien-entity/src/main/java/shop/alien/mapper/StoreCommentMapper.java

@@ -115,10 +115,10 @@ public interface StoreCommentMapper extends BaseMapper<StoreComment> {
     StoreCommitPercentVo getCommentByStoreId(Integer storeId);
 
     @Select("SELECT " +
-            "SUM( score ) score," +
-            "SUM( taste_score ) tasteScore," +
-            "SUM( en_score ) enScore," +
-            "SUM( service_score ) serviceScore," +
+            "ifnull(SUM( score ),0) score," +
+            "ifnull(SUM( taste_score ),0) tasteScore," +
+            "ifnull(SUM( en_score ),0) enScore," +
+            "ifnull(SUM( service_score ),0) serviceScore," +
             "COUNT(0) total " +
             "FROM" +
             "`store_comment` " +

+ 44 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreCommentSummaryMapper.java

@@ -0,0 +1,44 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.StoreCommentSummary;
+
+
+import java.util.List;
+
+/**
+ * qxy
+ * AI 服务 推荐数据信息 店铺评论总结表
+ */
+@Mapper
+public interface StoreCommentSummaryMapper extends BaseMapper<StoreCommentSummary> {
+
+    @Insert({
+            "<script>", // 开启动态 SQL 脚本
+            "INSERT INTO store_comment_summary (",
+            "  id, store_id, store_name, summary, task_id, is_show, delete_flag, created_time, created_user_id,",
+            "  updated_time, updated_user_id",
+            ")",
+            "VALUES",
+            "<foreach collection='list' item='item' separator=','>",
+            "(",
+            "  #{item.id},",
+            "  #{item.storeId},",
+            "  #{item.storeName},",
+            "  #{item.summary},",
+            "  #{item.taskId},",
+            "  #{item.isShow},",
+            "  #{item.deleteFlag},",
+            "  #{item.createdTime},",
+            "  #{item.createdUserId},",
+            "  #{item.updatedTime},",
+            "  #{item.updatedUserId}",
+            ")",
+            "</foreach>",
+            "</script>" // 关闭动态 SQL 脚本
+    })
+    int insertBatchStoreCommentSummary(List<StoreCommentSummary> storeCommentSummaryList);
+
+}

+ 21 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreIncomeDetailsRecordMapper.java

@@ -32,4 +32,25 @@ public interface StoreIncomeDetailsRecordMapper extends BaseMapper<StoreIncomeDe
     @Update("UPDATE store_income_details_record SET cash_out_id = NULL WHERE delete_flag=0 AND store_id = #{storeId} AND cash_out_id = #{cashOutId}")
     int updateByCashOutId(@Param("storeId") Integer storeId,
                                  @Param("cashOutId") Integer cashOutId);
+
+    @Select("with totalCoupon as (\n" +
+            "select lc.name,1 type,lc.id\n" +
+            "from life_coupon lc  where lc.delete_flag = 0\n" +
+            "union all\n" +
+            "select lgbm.group_name,2 type,lgbm.id\n" +
+            "from life_group_buy_main lgbm where lgbm.delete_flag = 0 \n" +
+            ")            \n" +
+            "SELECT\n" +
+            "\tsidr.id,sidr.updated_time,sidr.created_user_id,sidr.created_time,sidr.income_type,sidr.business_id,sidr.cash_out_id,sidr.store_id,sidr.user_order_id,sidr.delete_flag,sidr.money,sidr.commission,sidr.updated_user_id,\n" +
+            "\tluo.buy_time orderTime,\n" +
+            "\tocm.created_time checkTime,\n" +
+            "\tADDDATE(sidr.created_time, 4) incomeTime,\n" +
+            "\ttc.name couponName\n" +
+            "FROM\n" +
+            "\tstore_income_details_record sidr\n" +
+            "left join order_coupon_middle ocm on ocm.id = sidr.user_order_id and ocm.delete_flag = 0\n" +
+            "left join life_user_order luo on luo.id  = ocm.order_id and luo.delete_flag = 0\n" +
+            "left join totalCoupon tc on tc.id = sidr.business_id and tc.type = luo.coupon_type\n"+
+            "${ew.customSqlSegment}" )
+    List<StoreIncomeDetailsRecordVo> selectRecordList(@Param(Constants.WRAPPER) QueryWrapper<StoreIncomeDetailsRecord> wrapper);
 }

+ 2 - 1
alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java

@@ -60,7 +60,7 @@ public interface StoreInfoMapper extends BaseMapper<StoreInfo> {
      * @param queryWrapper 查询条件
      * @return IPage<StoreInfoVo>
      */
-    @Select("select a.*, img.img_url entranceImage,b.name store_contact, b.phone store_phone, b.id_card idCard, b.password, c.dict_detail store_status_str, d.dict_detail business_status_str, e.dict_detail store_type_str,  " +
+    @Select("select a.*, img.img_url entranceImage,img1.img_url foodLicenceImageUrl,b.name store_contact, b.phone store_phone, b.id_card idCard, b.password, c.dict_detail store_status_str, d.dict_detail business_status_str, e.dict_detail store_type_str,  " +
             "( " +
             " select ifnull(round(avg(score), 1), 0) " +
             " from store_evaluation eval " +
@@ -69,6 +69,7 @@ public interface StoreInfoMapper extends BaseMapper<StoreInfo> {
             "from store_info a " +
             "left join store_user b on a.id = b.store_id and a.delete_flag = 0 and b.delete_flag = 0 " +
             "left join store_img img on img.store_id = a.id and img.img_type = 1 and img.delete_flag = 0 " +
+            "left join store_img img1 on img1.store_id = a.id and img1.img_type = 24 and img1.delete_flag = 0 " +
             "left join store_dictionary c on a.store_status = c.dict_id and c.type_name = 'storeState' and c.delete_flag = 0 " +
             "left join store_dictionary d on a.business_status = d.dict_id and d.type_name = 'businessStatus' and d.delete_flag = 0 " +
             "left join store_dictionary e on e.type_name = 'storeType' and e.dict_id = a.store_type and e.delete_flag = 0 " +

+ 60 - 0
alien-entity/src/main/java/shop/alien/mapper/TagsMainMapper.java

@@ -0,0 +1,60 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import shop.alien.entity.store.TagsMain;
+import shop.alien.entity.store.vo.TagsMainVo;
+
+import java.util.List;
+
+/**
+ * qxy
+ * AI 服务标签主表
+ */
+@Mapper
+public interface TagsMainMapper extends BaseMapper<TagsMain> {
+
+    @Insert({
+            "<script>", // 开启动态 SQL 脚本
+            "INSERT INTO tags_main (",
+            "  id, tag_name, delete_flag, created_time, created_user_id,",
+            "  updated_time, updated_user_id, store_id, tag_type",
+            ")",
+            "VALUES",
+            "<foreach collection='list' item='item' separator=','>",
+            "(",
+            "  #{item.id},",
+            "  #{item.tagName},",
+            "  #{item.deleteFlag},",
+            "  #{item.createdTime},",
+            "  #{item.createdUserId},",
+            "  #{item.updatedTime},",
+            "  #{item.updatedUserId},",
+            "  #{item.storeId},",
+            "  #{item.tagType}",
+            ")",
+            "</foreach>",
+            "</script>" // 关闭动态 SQL 脚本
+    })
+    int insertBatchTagsMain(List<TagsMain> tagsMainList);
+
+    @Select("SELECT\n" +
+            "    main.id,\n" +
+            "    main.tag_name,\n" +
+            "    main.store_id,\n" +
+            "    main.tag_type,\n" +
+            "    COUNT(DISTINCT synonym.comment_id) AS evaluateNumber\n" +
+            "FROM\n" +
+            "    tags_main main\n" +
+            "    LEFT JOIN tags_synonym synonym \n" +
+            "        ON main.id = synonym.main_tag_id\n" +
+            "        AND synonym.delete_flag = 0  \n" +
+            "WHERE\n" +
+            "    main.store_id = #{storeId} \n" +
+            "    AND main.delete_flag = 0\n" +
+            "GROUP BY\n" +
+            "    main.id")
+    List<TagsMainVo> getStoreEvaluateTags(int storeId);
+}

+ 43 - 0
alien-entity/src/main/java/shop/alien/mapper/TagsSynonymMapper.java

@@ -0,0 +1,43 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.TagsSynonym;
+
+import java.util.List;
+
+/**
+ * qxy
+ * AI 服务标签子表
+ */
+
+@Mapper
+public interface TagsSynonymMapper extends BaseMapper<TagsSynonym> {
+
+    @Insert({
+            "<script>", // 开启动态 SQL 脚本
+            "INSERT INTO tags_synonym (",
+            "  id, main_tag_id, comment_id, synonym_tag, delete_flag, created_time, created_user_id,",
+            "  updated_time, updated_user_id, tag_type, task_id",
+            ")",
+            "VALUES",
+            "<foreach collection='list' item='item' separator=','>",
+            "(",
+            "  #{item.id},",
+            "  #{item.mainTagId},",
+            "  #{item.commentId},",
+            "  #{item.synonymTag},",
+            "  #{item.deleteFlag},",
+            "  #{item.createdTime},",
+            "  #{item.createdUserId},",
+            "  #{item.updatedTime},",
+            "  #{item.updatedUserId},",
+            "  #{item.tagType},",
+            "  #{item.taskId}",
+            ")",
+            "</foreach>",
+            "</script>" // 关闭动态 SQL 脚本
+    })
+    int insertBatchTagsSynonym(List<TagsSynonym> tagsSynonymList);
+}

+ 13 - 0
alien-entity/src/main/java/shop/alien/mapper/UserPointMapper.java

@@ -0,0 +1,13 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.store.UserPoint;
+
+/**
+ * 用户积分mapper
+ */
+@Mapper
+public interface UserPointMapper extends BaseMapper<UserPoint> {
+
+}

+ 4 - 1
alien-entity/src/main/java/shop/alien/mapper/WebAuditMapper.java

@@ -24,12 +24,15 @@ public interface WebAuditMapper  extends BaseMapper<WebAudit> {
             "    WHEN 5 THEN\n" +
             "    '活动' \n" +
             "    WHEN 6 THEN\n" +
-            "    '代金券' ELSE '未知类型' \n" +
+            "    '代金券' \n" +
+            "    WHEN 7 THEN\n" +
+            "    '经营许可证' ELSE '未知类型' \n" +
             "  END AS type,\n" +
             "  COUNT(*) AS typeSum \n" +
             "FROM\n" +
             "  web_audit \n" +
             "  where `status` = '0'\n" +
+            "  and `delete_flag` = '0'\n" +
             "GROUP BY\n" +
             "  type;")
     List<WebAuditVo> getAuditSum(QueryWrapper<WebAuditVo> queryWrapper);

+ 31 - 0
alien-entity/src/main/java/shop/alien/mapper/second/SecondGoodsRecordMapper.java

@@ -1,7 +1,38 @@
 package shop.alien.mapper.second;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import shop.alien.entity.second.SecondGoodsRecord;
+import shop.alien.entity.second.vo.SecondGoodsVo;
+
+import java.util.List;
 
 public interface SecondGoodsRecordMapper extends BaseMapper<SecondGoodsRecord> {
+    @Select("SELECT " +
+            "sg.*, " +
+            "sgc1.category_name as categoryOneName, " +
+            "sgc2.category_name as categoryTwoName " +
+            "FROM second_goods_record sg " +
+            "LEFT JOIN second_goods_category sgc1 " +
+            "on sg.category_one_id = sgc1.id " +
+            "LEFT JOIN second_goods_category sgc2 " +
+            "on sg.category_two_id = sgc2.id " +
+            "${ew.customSqlSegment}")
+    List<SecondGoodsRecord> selectdminGoodsList(@Param(Constants.WRAPPER) QueryWrapper<SecondGoodsRecord> queryWrapper);
+
+    @Select("SELECT " +
+            "sg.*, " +
+            "sgc1.category_name as categoryOneName, " +
+            "sgc2.category_name as categoryTwoName " +
+            "FROM second_goods_record sg " +
+            "LEFT JOIN second_goods_category sgc1 " +
+            "on sg.category_one_id = sgc1.id " +
+            "LEFT JOIN second_goods_category sgc2 " +
+            "on sg.category_two_id = sgc2.id " +
+            "${ew.customSqlSegment}")
+    SecondGoodsRecord selectGoodsRecordById(@Param(Constants.WRAPPER) QueryWrapper<SecondGoodsRecord> queryWrapper);
 }

+ 32 - 1
alien-entity/src/main/java/shop/alien/mapper/second/SecondTradeRecordMapper.java

@@ -1,6 +1,7 @@
 package shop.alien.mapper.second;
 
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,6 +14,7 @@ import shop.alien.entity.second.SecondTradeRecord;
 import shop.alien.entity.second.vo.SecondTradeRecordVo;
 import shop.alien.entity.store.vo.LifeFansVo;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -36,9 +38,12 @@ public interface SecondTradeRecordMapper extends BaseMapper<SecondTradeRecord> {
 
     @Select("select trade.id, trade.trade_no, trade.goods_id, goods.title, goods.home_image, goods.price, trade.transaction_amount, trade.trade_status, " +
             "trade.transaction_time, trade.seller_id, trade.transaction_latitude_longitude, trade.transaction_latitude_longitude_address, " +
-            "trade.transaction_location, trade.created_user_id, if (now() >= trade.transaction_time, 1, 0) timeOutFlag " +
+            "trade.transaction_location, trade.created_user_id, trade.failure_flag, trade.failure_reason, if (now() >= trade.transaction_time, 1, 0) timeOutFlag, " +
+            "buyer.user_name buyerName, buyer.user_phone buyerPhone, seller.user_name sellerName, seller.user_phone sellerPhone " +
             "from second_trade_record trade " +
             "left join second_goods_record goods on goods.id = trade.goods_record_id " +
+            "left join life_user buyer on buyer.id = trade.buyer_id " +
+            "left join life_user seller on seller.id = trade.seller_id  " +
             "${ew.customSqlSegment} ")
     IPage<SecondTradeRecordVo> getTradeRecordPage(IPage<SecondTradeRecord> page, @Param(Constants.WRAPPER) QueryWrapper<SecondTradeRecord> wrapper);
 
@@ -48,4 +53,30 @@ public interface SecondTradeRecordMapper extends BaseMapper<SecondTradeRecord> {
             "left join life_user seller on seller.id = trade.seller_id " +
             "where trade.id = #{id}")
     SecondTradeRecordVo getTradeRecordById(@Param("id") Integer id);
+
+    @Select("with record as ( " +
+            "    select buyer_id userId, count(1) num, 'buyer' flag " +
+            "    from second_trade_record " +
+            "    where delete_flag = 0 and trade_status = 4 and failure_flag = 0 " +
+            "    and transaction_time >= #{beginTime} and transaction_time <= #{endTime} " +
+            "    group by buyer_id " +
+            "    union all " +
+            "    select seller_id userId, count(1) num, 'seller' flag " +
+            "    from second_trade_record " +
+            "    where delete_flag = 0 and trade_status = 4 and failure_flag = 0 " +
+            "    and transaction_time >= #{beginTime} and transaction_time <= #{endTime} " +
+            "    group by seller_id " +
+            ") " +
+            "select a.*, ifnull(b.num, 0) buyer, ifnull(c.num, 0) seller, user.user_name userName, concat('user_', user.user_phone) phoneId " +
+            "from ( " +
+            "    select userId, sum(num) num " +
+            "    from record " +
+            "    group by userId " +
+            ") a " +
+            "left join record b on a.userId = b.userId and b.flag = 'buyer' " +
+            "left join record c on a.userId = c.userId and c.flag = 'seller' " +
+            "join life_user user on user.id = a.userId and user.delete_flag = 0 " +
+            "order by a.num desc " +
+            "limit 20 ")
+    List<JSONObject> getRankingList(@Param("beginTime") String beginTime, @Param("endTime") String endTime);
 }

+ 38 - 0
alien-entity/src/main/resources/mapper/AiIntelligentAssistantMapper.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.AiIntelligentAssistantMapper">
+
+    <insert id="insertList">
+        INSERT INTO ai_intelligent_assistant (
+        context,
+        talk_source,
+        type,
+        reply_id,
+        reply_date,
+        delete_flag,
+        created_time,
+        created_user_id,
+        updated_time,
+        updated_user_id,
+        user_id
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.context},
+            #{item.talkSource},
+            #{item.type},
+            #{item.replyId},
+            #{item.replyDate},
+            #{item.deleteFlag},
+            #{item.createdTime},
+            #{item.createdUserId},
+            #{item.updatedTime},
+            #{item.updatedUserId},
+            #{item.userId}
+            )
+        </foreach>
+    </insert>
+
+</mapper>

+ 25 - 0
alien-entity/src/main/resources/mapper/LifeDiscountCouponFriendRuleDetailMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.LifeDiscountCouponFriendRuleDetailMapper">
+
+    <resultMap id="BaseResultMap" type="shop.alien.entity.store.LifeDiscountCouponFriendRuleDetail">
+            <id property="id" column="id" />
+            <result property="ruleId" column="rule_id" />
+            <result property="couponId" column="coupon_id" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,rule_id,coupon_id
+    </sql>
+
+    <insert id="insertList" parameterType="java.util.List">
+        INSERT INTO life_discount_coupon_friend_rule_detail (rule_id, coupon_id, friend_store_user_id,store_id)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.ruleId}, #{item.couponId}, #{item.friendStoreUserId}, #{item.storeId})
+        </foreach>
+    </insert>
+
+</mapper>

+ 18 - 0
alien-entity/src/main/resources/mapper/LifeDiscountCouponFriendRuleMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.LifeDiscountCouponFriendRuleMapper">
+
+    <resultMap id="BaseResultMap" type="shop.alien.entity.store.LifeDiscountCouponFriendRule">
+            <id property="id" column="id" />
+            <result property="acName" column="ac_name" />
+            <result property="moneyLow" column="money_low" />
+            <result property="moneyHigh" column="money_high" />
+            <result property="deleteFlag" column="delete_flag" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,ac_name,money_low,money_high,delete_flag
+    </sql>
+</mapper>

+ 2 - 1
alien-entity/src/main/resources/mapper/LifeUserOrderMapper.xml

@@ -41,6 +41,7 @@
         <result column="store_tel" property="storeTel"/>
         <result column="quan_id" property="quanId"/>
         <result column="total_refund_time" property="totalRefundTime"/>
+        <result column="business_status" property="businessStatus"/>
 
         <result column="business_type" property="businessType"/>
         <result column="business_date" property="businessDate"/>
@@ -77,7 +78,7 @@
         ldc.nominal_value,
         lu.user_phone,lu.user_name,lu.id user_id,
         ocm.id ocmId,ocm.status,ocm.coupon_code,ocm.refund_time,ocm.refund_reason,ocm.price refundPrice,
-        si.id store_id,si.store_name,si.commission_rate,si.store_address,si.store_tel,
+        si.id store_id,si.store_name,si.commission_rate,si.store_address,si.store_tel,si.business_status,
         <if test="position != null and position != ''">
             ROUND(
             ST_Distance_Sphere(

+ 1 - 0
alien-entity/src/main/resources/mapper/ManagementInfoMapper.xml

@@ -38,6 +38,7 @@
         FROM
             store_info store
                 LEFT JOIN ( SELECT * FROM store_income_details_record WHERE created_time > #{startDate} AND created_time &lt; #{endDate} ) income ON store.id = income.store_id
+        WHERE store.delete_flag = 0
         GROUP BY
             store.id
         ORDER BY

+ 16 - 15
alien-entity/src/main/resources/mapper/second/SecondGoodsCategoryMapper.xml

@@ -52,24 +52,25 @@
     <!-- 根据上级ID查询二手商品类别表 -->
     <select id="querySecondGoodsInfo" resultType="shop.alien.entity.second.SecondGoodsCategory">
         SELECT
-        id,
-        category_name,
-        category_url,
-        parent_id,
-        delete_flag,
-        created_time,
-        created_user_id,
-        updated_time,
-        updated_user_id,
-        category_sort,
-        case when category_state = 0 then '显示'
-        when category_state = 1 then '隐藏'
-        else '未知'
-        end as category_state
+            id,
+            category_name,
+            category_url,
+            parent_id,
+            delete_flag,
+            created_time,
+            created_user_id,
+            updated_time,
+            updated_user_id,
+            category_sort,
+            case when category_state = 0 then '显示'
+            when category_state = 1 then '隐藏'
+            else '未知'
+            end as category_state
         FROM
         second_goods_category
         WHERE
-        delete_flag = 0
+            delete_flag = 0
+            and parent_id is not null and parent_id != ''
         ORDER BY category_sort, created_time
     </select>
 </mapper>

+ 485 - 0
alien-job/src/main/java/shop/alien/job/store/AiTagJob.java

@@ -0,0 +1,485 @@
+package shop.alien.job.store;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreCommentSummary;
+import shop.alien.entity.store.TagsMain;
+import shop.alien.entity.store.TagsSynonym;
+import shop.alien.mapper.StoreCommentSummaryMapper;
+import shop.alien.mapper.TagsMainMapper;
+import shop.alien.mapper.TagsSynonymMapper;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 调用AI标签数据服务类
+ *
+ * @author qxy
+ * @date 2025/9/12 14:21
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class AiTagJob {
+
+    private final RestTemplate restTemplate;
+
+    private final TagsMainMapper tagsMainMapper;
+
+    private final TagsSynonymMapper tagsSynonymMapper;
+
+    private final StoreCommentSummaryMapper storeCommentSummaryMapper;
+
+    // 第三方接口地址 获取所有标签主表信息
+    @Value("${third-party-tag.base-url}")
+    private String tagMainUrl;
+
+    // 第三方接口地址 获取所有标签子表信息
+    @Value("${third-party-synonym.base-url}")
+    private String tagsSynonymUrl;
+
+    // 第三方接口地址 获取推荐信息数据 店铺评论总结表
+    @Value("${third-party-summary.base-url}")
+    private String allSummaryUrl;
+
+    // 第三方接口地址 登录接口URL
+    @Value("${third-party-login.base-url}")
+    private String loginUrl;
+
+    // 第三方接口地址 创建Ai标签数据接口
+    @Value("${third-party-savetag.base-url}")
+    private String saveTagUrl;
+
+    //用户名
+    @Value("${third-party-user-name.base-url}")
+    private String userName;
+
+    //密码
+    @Value("${third-party-pass-word.base-url}")
+    private String passWord;
+
+    /**
+     * 创建Ai标签评论数据
+     */
+    @XxlJob("getSaveTagsTask")
+    public R<String> getSaveTagsTask() {
+        log.info("登录Ai服务获取token..." + loginUrl);
+        //构建请求参数
+        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+        formData.add("username", userName);    // 表单字段 1:用户名
+        formData.add("password", passWord);    // 表单字段 2:密码
+
+        //设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
+        ResponseEntity<String> postForEntity = null;
+        try {
+            log.info("请求Ai服务登录接口===================>");
+            postForEntity = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
+        } catch (Exception e) {
+            log.error("类:PostMethod 方法:post", e);
+        }
+
+        if (postForEntity != null) {
+            if (postForEntity.getStatusCodeValue() == 200) {
+                log.info("请求Ai服务登录成功 postForEntity.getBody()\t" + postForEntity.getBody());
+                String responseBody = postForEntity.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONObject dataJson = jsonObject.getJSONObject("data");
+                String accessToken = dataJson.getString("access_token");
+                //调用 创建Ai标签评论数据方法
+                getSaveTagsTaskInfo(accessToken);
+                return R.success("任务执行成功");
+            } else {
+                log.error("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+                return R.fail("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+            }
+        }
+        XxlJobHelper.handleFail("登录任务执行失败 返回异常");
+        return R.fail("登录任务执行失败 返回异常");
+    }
+
+    public R<String> getSaveTagsTaskInfo(String token) {
+        log.info("开始从Ai服务创建店铺评价标签评论数据...");
+        log.info("restTemplate:" + restTemplate + "url:" + saveTagUrl);
+
+        // 获取当前日期
+        LocalDate today = LocalDate.now();
+
+        // 获取当月第一天
+        LocalDate firstDayOfMonth = today.withDayOfMonth(1);
+
+        // 获取当月最后一天
+        LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth());
+
+        // 格式化为字符串(可根据需要调整格式)
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        String startDate = firstDayOfMonth.format(formatter);
+        String endDate = lastDayOfMonth.format(formatter);
+
+        // 1. 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        // Token 认证
+        headers.set("Authorization", "Bearer " + token);
+
+        AnalysisRequest jsonBody = new AnalysisRequest();
+        jsonBody.setStart_time(startDate + "T00:00:00");
+        jsonBody.setEnd_time(endDate + "T23:59:59");
+
+        HttpEntity<AnalysisRequest> request = new HttpEntity<>(jsonBody, headers);
+        ResponseEntity<String> response = null;
+        try {
+            response = restTemplate.postForEntity(saveTagUrl, request, String.class);
+        } catch (Exception e) {
+            log.error("类:PostMethod 方法:post", e);
+        }
+
+        if (response != null) {
+            if (response.getStatusCodeValue() == 200) {
+                log.info("postForEntity.getBody()\t" + response.getStatusCode());
+                XxlJobHelper.handleSuccess("创建标签成功 状态码" + response.getStatusCode());
+                return R.success("创建成功");
+            } else {
+                log.error("请求AI服务 创建标签数据失败 http状态:" + response.getStatusCode());
+                XxlJobHelper.handleFail("请求AI服务 创建标签数据失败 http状态" + response.getStatusCode());
+                return R.fail("请求AI服务 创建标签数据失败 http状态:" + response.getStatusCode());
+            }
+        }
+        log.error("创建标签任务执行失败 返回异常");
+        XxlJobHelper.handleFail("创建标签任务执行失败 返回异常");
+        return R.fail("创建标签任务执行失败 返回异常");
+    }
+
+    /**
+     * 拉取Ai服务标签主表数据
+     */
+    @XxlJob("getTagMainTask")
+    public R<String> getTagMainTask() {
+        log.info("登录Ai服务获取token..." + loginUrl);
+        //构建请求参数
+        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+        formData.add("username", userName);    // 表单字段 1:用户名
+        formData.add("password", passWord);    // 表单字段 2:密码
+
+        //设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
+        ResponseEntity<String> postForEntity = null;
+        try {
+            postForEntity = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
+        } catch (Exception e) {
+            log.error("类:PostMethod 方法:post", e);
+        }
+
+        if (postForEntity != null) {
+            if (postForEntity.getStatusCodeValue() == 200) {
+                log.info("请求Ai服务登录成功 postForEntity.getBody()\t" + postForEntity.getBody());
+                String responseBody = postForEntity.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONObject dataJson = jsonObject.getJSONObject("data");
+                String accessToken = dataJson.getString("access_token");
+                //调用 获取AI服务 标签主表get请求
+                getTagMainTaskInfo(accessToken);
+                return R.success("任务执行成功");
+            } else {
+                log.error("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+                return R.fail("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+            }
+        }
+        XxlJobHelper.handleFail("登录任务执行失败 返回异常");
+        return R.fail("登录任务执行失败 返回异常");
+    }
+
+    public R<String> getTagMainTaskInfo(String token) {
+        log.info("开始从Ai服务获取标签主表信息...");
+        log.info("restTemplate:" + restTemplate + "url:" + tagMainUrl);
+        // 1. 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("Authorization", "Bearer " + token); // Token 认证
+        headers.set("accept", "*/*");
+        headers.set("connection", "Keep-Alive");
+        headers.set("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+        // 2. 构建请求实体(仅包含头信息,GET 请求通常无请求体)
+        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+
+        // 发送 GET 请求,响应体为 String 类型
+        ResponseEntity<String> responseEntity = restTemplate.exchange(
+                tagMainUrl,
+                HttpMethod.GET,  // 指定请求方法为 GET
+                requestEntity,
+                String.class     // 响应体类型
+        );
+
+        // 解析响应
+        if (responseEntity.getStatusCodeValue() == 200) {
+            String responseBody = responseEntity.getBody();
+            JSONObject jsonObject = JSONObject.parseObject(responseBody);
+            Integer code = jsonObject.getInteger("code");
+            String message = jsonObject.getString("message");
+            JSONArray dataArray = jsonObject.getJSONArray("data");
+            List<TagsMain> tagsMainList = new ArrayList<>();
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject tagObj = dataArray.getJSONObject(i);
+                TagsMain tagsMain = new TagsMain();
+                tagsMain.setId(tagObj.getInteger("id"));
+                tagsMain.setTagName(tagObj.getString("tag_name"));
+                tagsMain.setStoreId(tagObj.getInteger("store_id"));
+                tagsMain.setTagType(tagObj.getInteger("tag_type"));
+                tagsMain.setDeleteFlag(tagObj.getInteger("delete_flag"));
+                tagsMain.setCreatedTime(tagObj.getDate("created_time"));
+                tagsMain.setCreatedUserId(tagObj.getInteger("created_user_id"));
+                tagsMain.setUpdatedTime(tagObj.getDate("updated_time"));
+                tagsMain.setUpdatedUserId(tagObj.getInteger("updated_user_id"));
+                tagsMainList.add(tagsMain);
+            }
+            if (!CollectionUtils.isEmpty(tagsMainList)) {
+                int num = tagsMainMapper.insertBatchTagsMain(tagsMainList);
+                XxlJobHelper.handleSuccess("拉取主标签数据成功 执行" + num + "条");
+                return R.success("拉取主标签数据成功 执行" + num + "条");
+            } else {
+                XxlJobHelper.handleSuccess("获取回显数据为空 状态码:" + responseEntity.getStatusCodeValue());
+                return R.success("请求成功 获取回显数据为空 状态码:" + responseEntity.getStatusCodeValue());
+            }
+        }
+        XxlJobHelper.handleFail("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+        return R.fail("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+    }
+
+
+    /**
+     * 拉取Ai服务子标签数据
+     */
+    @XxlJob("getTagsSynonymTask")
+    public R<String> getTagsSynonymTask() {
+        log.info("登录Ai服务获取token..." + loginUrl);
+        //构建请求参数
+        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+        formData.add("username", userName);    // 表单字段 1:用户名
+        formData.add("password", passWord);    // 表单字段 2:密码
+
+        //设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
+        ResponseEntity<String> postForEntity = null;
+        try {
+            postForEntity = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
+        } catch (Exception e) {
+            log.error("类:PostMethod 方法:post", e);
+        }
+
+        if (postForEntity != null) {
+            if (postForEntity.getStatusCodeValue() == 200) {
+                log.info("请求Ai服务登录成功 postForEntity.getBody()\t" + postForEntity.getBody());
+                String responseBody = postForEntity.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONObject dataJson = jsonObject.getJSONObject("data");
+                String accessToken = dataJson.getString("access_token");
+                //调用 获取AI服务 标签子表get请求
+                getTagsSynonymTaskInfo(accessToken);
+                return R.success("任务执行成功");
+            } else {
+                log.error("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+                return R.fail("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+            }
+        }
+        XxlJobHelper.handleFail("登录任务执行失败 返回异常");
+        return R.fail("登录任务执行失败 返回异常");
+    }
+
+    public R<String> getTagsSynonymTaskInfo(String token) {
+        log.info("开始从Ai服务获取数据 获取所有标签子表信息...");
+        log.info("restTemplate:" + restTemplate + "url:" + tagsSynonymUrl);
+        // 1. 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("Authorization", "Bearer " + token); // Token 认证
+        headers.set("accept", "*/*");
+        headers.set("connection", "Keep-Alive");
+        headers.set("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+        // 2. 构建请求实体(仅包含头信息,GET 请求通常无请求体)
+        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+
+        // 发送 GET 请求,响应体为 String 类型
+        ResponseEntity<String> responseEntity = restTemplate.exchange(
+                tagsSynonymUrl,
+                HttpMethod.GET,  // 指定请求方法为 GET
+                requestEntity,
+                String.class     // 响应体类型
+        );
+
+        // 解析响应
+        if (responseEntity.getStatusCodeValue() == 200) {
+            String responseBody = responseEntity.getBody();
+            JSONObject jsonObject = JSONObject.parseObject(responseBody);
+            Integer code = jsonObject.getInteger("code");
+            String message = jsonObject.getString("message");
+            JSONArray dataArray = jsonObject.getJSONArray("data");
+            List<TagsSynonym> tagsSynonymList = new ArrayList<>();
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject tagObj = dataArray.getJSONObject(i);
+                TagsSynonym tagsSynonym = new TagsSynonym();
+                tagsSynonym.setId(tagObj.getInteger("id"));
+                tagsSynonym.setMainTagId(tagObj.getInteger("main_tag_id"));
+                tagsSynonym.setCommentId(tagObj.getInteger("comment_id"));
+                tagsSynonym.setSynonymTag(tagObj.getString("synonym_tag"));
+                tagsSynonym.setTagType(tagObj.getInteger("tag_type"));
+                tagsSynonym.setTaskId(tagObj.getString("task_id"));
+                tagsSynonym.setDeleteFlag(tagObj.getInteger("delete_flag"));
+                tagsSynonym.setCreatedTime(tagObj.getDate("created_time"));
+                tagsSynonym.setCreatedUserId(tagObj.getInteger("created_user_id"));
+                tagsSynonym.setUpdatedTime(tagObj.getDate("updated_time"));
+                tagsSynonym.setUpdatedUserId(tagObj.getInteger("updated_user_id"));
+                tagsSynonymList.add(tagsSynonym);
+            }
+            if (!CollectionUtils.isEmpty(tagsSynonymList)) {
+                int num = tagsSynonymMapper.insertBatchTagsSynonym(tagsSynonymList);
+                XxlJobHelper.handleSuccess("拉取子标签数据成功 执行" + num + "条");
+                return R.success("拉取子标签数据成功 执行" + num + "条");
+            } else {
+                XxlJobHelper.handleSuccess("获取回显数据为空" + "状态码:" + responseEntity.getStatusCodeValue());
+                return R.success("请求成功 获取回显数据为空" + "状态码:" + responseEntity.getStatusCodeValue());
+            }
+        }
+        XxlJobHelper.handleFail("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+        return R.fail("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+    }
+
+    /**
+     * 拉取Ai服务获取推荐信息数据
+     */
+    @XxlJob("getStoreCommentSummaryTask")
+    public R<String> getStoreCommentSummaryTask() {
+        log.info("登录Ai服务获取token..." + loginUrl);
+        //构建请求参数
+        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+        formData.add("username", userName);    // 表单字段 1:用户名
+        formData.add("password", passWord);    // 表单字段 2:密码
+
+        //设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
+        ResponseEntity<String> postForEntity = null;
+        try {
+            postForEntity = restTemplate.postForEntity(loginUrl, requestEntity, String.class);
+        } catch (Exception e) {
+            log.error("类:PostMethod 方法:post", e);
+        }
+
+        if (postForEntity != null) {
+            if (postForEntity.getStatusCodeValue() == 200) {
+                log.info("请求Ai服务登录成功 postForEntity.getBody()\t" + postForEntity.getBody());
+                String responseBody = postForEntity.getBody();
+                JSONObject jsonObject = JSONObject.parseObject(responseBody);
+                JSONObject dataJson = jsonObject.getJSONObject("data");
+                String accessToken = dataJson.getString("access_token");
+                //调用 获取AI服务 获取所有推荐信表 get请求
+                getStoreCommentSummaryTaskInfo(accessToken);
+                return R.success("任务执行成功");
+            } else {
+                log.error("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+                return R.fail("请求AI服务 登录接口失败 http状态:" + postForEntity.getStatusCode());
+            }
+        }
+        XxlJobHelper.handleFail("登录任务执行失败 返回异常");
+        return R.fail("登录任务执行失败 返回异常");
+    }
+
+    public R<String> getStoreCommentSummaryTaskInfo(String token) {
+        log.info("开始从Ai服务获取数据 获取推荐信息数据 店铺评论总结表...");
+        log.info("restTemplate:" + restTemplate + "url:" + allSummaryUrl);
+        // 1. 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("Authorization", "Bearer " + token); // Token 认证
+        headers.set("accept", "*/*");
+        headers.set("connection", "Keep-Alive");
+        headers.set("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+        // 2. 构建请求实体(仅包含头信息,GET 请求通常无请求体)
+        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+
+        // 发送 GET 请求,响应体为 String 类型
+        ResponseEntity<String> responseEntity = restTemplate.exchange(
+                allSummaryUrl,
+                HttpMethod.GET,  // 指定请求方法为 GET
+                requestEntity,
+                String.class     // 响应体类型
+        );
+
+        // 解析响应
+        if (responseEntity.getStatusCodeValue() == 200) {
+            String responseBody = responseEntity.getBody();
+            JSONObject jsonObject = JSONObject.parseObject(responseBody);
+            Integer code = jsonObject.getInteger("code");
+            String message = jsonObject.getString("message");
+            JSONArray dataArray = jsonObject.getJSONArray("data");
+            List<StoreCommentSummary> storeCommentSummaries = new ArrayList<>();
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject tagObj = dataArray.getJSONObject(i);
+                StoreCommentSummary summary = new StoreCommentSummary();
+                summary.setId(tagObj.getInteger("id"));
+                summary.setStoreId(tagObj.getInteger("store_id"));
+                summary.setStoreName(tagObj.getString("store_name"));
+                summary.setSummary(tagObj.getString("summary"));
+                summary.setTaskId(tagObj.getString("task_id"));
+                summary.setIsShow(tagObj.getInteger("is_show"));
+                summary.setDeleteFlag(tagObj.getInteger("delete_flag"));
+                summary.setCreatedTime(tagObj.getDate("created_time"));
+                summary.setCreatedUserId(tagObj.getInteger("created_user_id"));
+                summary.setUpdatedTime(tagObj.getDate("updated_time"));
+                summary.setUpdatedUserId(tagObj.getInteger("updated_user_id"));
+                storeCommentSummaries.add(summary);
+            }
+            if (!CollectionUtils.isEmpty(storeCommentSummaries)) {
+                int num = storeCommentSummaryMapper.insertBatchStoreCommentSummary(storeCommentSummaries);
+                XxlJobHelper.handleSuccess("拉取子标签数据成功 执行" + num + "条");
+                return R.success("拉取子标签数据成功 执行" + num + "条");
+            } else {
+                XxlJobHelper.handleSuccess("获取回显数据为空" + "状态码:" + responseEntity.getStatusCodeValue());
+                return R.success("请求成功 获取回显数据为空" + "状态码:" + responseEntity.getStatusCodeValue());
+            }
+        }
+        log.info("AI服务 推荐信息数据请求失败,状态码:" + responseEntity.getStatusCodeValue());
+        XxlJobHelper.handleFail("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+        return R.success("任务执行失败 状态码" + responseEntity.getStatusCodeValue());
+    }
+
+    class AnalysisRequest {
+        private String start_time;
+        private String end_time;
+
+        public String getStart_time() {
+            return start_time;
+        }
+
+        public void setStart_time(String start_time) {
+            this.start_time = start_time;
+        }
+
+        public String getEnd_time() {
+            return end_time;
+        }
+
+        public void setEnd_time(String end_time) {
+            this.end_time = end_time;
+        }
+    }
+
+}

+ 2 - 2
alien-job/src/main/java/shop/alien/job/store/LifeUserOrderJob.java

@@ -91,7 +91,7 @@ public class LifeUserOrderJob {
             for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
                 // 恢复库存
                 lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
-                        .setSql("stock_qty=stock_qty+" + orderCouponMiddle.getCount())
+                        .setSql("single_qty=single_qty+" + orderCouponMiddle.getCount())
                         .eq(LifeCoupon::getId, orderCouponMiddle.getCouponId()));
             }
         }
@@ -223,7 +223,7 @@ public class LifeUserOrderJob {
                                 // 代金券
                                 // 恢复库存
                                 lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
-                                        .setSql("stock_qty=stock_qty+" + updateNum)
+                                        .setSql("single_qty=single_qty+" + updateNum)
                                         .eq(LifeCoupon::getId, order.getCouponId()));
                             } else {
                                 // 团购

+ 15 - 0
alien-second/src/main/java/shop/alien/second/platform/PlatformSecondCategoryController.java

@@ -1,13 +1,16 @@
 package shop.alien.second.platform;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiSort;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.second.SecondGoodsCategory;
+import shop.alien.mapper.second.SecondGoodsCategoryMapper;
 import shop.alien.second.service.SecondGoodsCategoryService;
 
 import java.util.List;
@@ -23,10 +26,22 @@ public class PlatformSecondCategoryController {
 
     private final SecondGoodsCategoryService service;
 
+    @Autowired
+    private SecondGoodsCategoryMapper mapper;
+
     @ApiOperation("新增商品类型")
     @PostMapping("/insertSecondGoodsCategory")
     public R<String> insertSecondGoodsCategory(@RequestBody SecondGoodsCategory category) throws Exception {
         log.info("SecondGoodsCategoryController.insertSecondGoodsCategory?category={}", category.toString());
+
+        // 查询商品类型名称
+        QueryWrapper<SecondGoodsCategory> repeatCategory = new QueryWrapper<>();
+        repeatCategory.eq("category_name", category.getCategoryName().trim());
+        List<SecondGoodsCategory> list = mapper.selectList(repeatCategory);
+        if (list.size() > 0) {
+            return R.fail("商品类型名称已存在,请修改商品类型名称!");
+        }
+
         Integer reporting = service.insertSecondGoodsCategory(category);
         if (0 == reporting) {
             return R.fail("新增商品类型失败");

+ 29 - 2
alien-second/src/main/java/shop/alien/second/platform/PlatformSecondTradeController.java

@@ -1,5 +1,6 @@
 package shop.alien.second.platform;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
@@ -9,6 +10,7 @@ import shop.alien.entity.result.R;
 import shop.alien.entity.second.vo.SecondTradeRecordVo;
 import shop.alien.second.service.PlatformSecondTradeService;
 
+import java.util.Date;
 import java.util.List;
 
 @Slf4j
@@ -22,7 +24,7 @@ public class PlatformSecondTradeController {
 
     private final PlatformSecondTradeService secondTradeRecordService;
 
-    @ApiOperation("交易列表")
+    @ApiOperation("交易列表(分页)")
     @ApiOperationSupport(order = 1)
     @PostMapping("/getTradeRecordPage")
     public R<IPage<SecondTradeRecordVo>> getTradeRecordPage(@RequestBody SecondTradeRecordVo vo) throws Exception {
@@ -30,12 +32,37 @@ public class PlatformSecondTradeController {
         return R.data(secondTradeRecordService.getTradeRecordPage(vo));
     }
 
-    @ApiOperation("交易详情")
+    @ApiOperation("交易列表(不分页)")
     @ApiOperationSupport(order = 2)
+    @GetMapping("/getTradeRecordList")
+    public R<List<SecondTradeRecordVo>> getTradeRecordList(Integer userId, String beginTime, String endTime) throws Exception {
+        log.info("PlatformSecondTradeController.getTradeRecordList?userId={},beginTime={},endTime={}", userId, beginTime, endTime);
+        return R.data(secondTradeRecordService.getTradeRecordList(userId, beginTime, endTime));
+    }
+
+    @ApiOperation("交易详情")
+    @ApiOperationSupport(order = 3)
     @GetMapping("/getTradeRecordById")
     public R<SecondTradeRecordVo> getTradeRecordById(Integer id) throws Exception {
         log.info("PlatformSecondTradeController.getTradeRecordById?id={}",id);
         return R.data(secondTradeRecordService.getTradeRecordById(id));
     }
 
+    @ApiOperation("排行榜")
+    @ApiOperationSupport(order = 4)
+    @GetMapping("/getRankingList")
+    public R<List<JSONObject>> getRankingList(String beginTime, String endTime) throws Exception {
+        log.info("PlatformSecondTradeController.getRankingList");
+        return R.data(secondTradeRecordService.getRankingList(beginTime, endTime));
+    }
+
+    @ApiOperation("交易失效")
+    @ApiOperationSupport(order = 5)
+    @GetMapping("/setTradeFailure")
+    public R<Boolean> setTradeFailure(Integer tradeId, String failureReason) throws Exception {
+        log.info("PlatformSecondTradeController.setTradeFailure?tradeId={},failureReason={}", tradeId, failureReason);
+        secondTradeRecordService.setTradeFailure(tradeId, failureReason);
+        return R.success("操作成功");
+    }
+
 }

+ 8 - 0
alien-second/src/main/java/shop/alien/second/service/PlatformSecondTradeService.java

@@ -7,12 +7,20 @@ import org.springframework.context.annotation.Lazy;
 import shop.alien.entity.second.SecondTradeRecord;
 import shop.alien.entity.second.vo.SecondTradeRecordVo;
 
+import java.util.Date;
 import java.util.List;
 
 public interface PlatformSecondTradeService extends IService<SecondTradeRecord> {
 
     IPage<SecondTradeRecordVo> getTradeRecordPage(SecondTradeRecordVo vo) throws Exception;
 
+    List<SecondTradeRecordVo> getTradeRecordList(Integer userId, String beginTime, String endTime) throws Exception;
+
     SecondTradeRecordVo getTradeRecordById(Integer id) throws Exception;
+
     List<JSONObject> getOperationJsonList(Integer tradeId) throws Exception;
+
+    List<JSONObject> getRankingList(String beginTime, String endTime) throws Exception;
+
+    void setTradeFailure(Integer tradeId, String failureReason) throws Exception;
 }

+ 53 - 4
alien-second/src/main/java/shop/alien/second/service/impl/PlatformSecondTradeServiceImpl.java

@@ -1,8 +1,10 @@
 package shop.alien.second.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -20,12 +22,11 @@ import shop.alien.mapper.second.SecondTradeRecordMapper;
 import shop.alien.second.service.PlatformSecondTradeService;
 import shop.alien.second.service.SecondGoodsService;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -58,6 +59,28 @@ public class PlatformSecondTradeServiceImpl extends ServiceImpl<SecondTradeRecor
     }
 
     @Override
+    public List<SecondTradeRecordVo> getTradeRecordList(Integer userId, String beginTime, String endTime) throws Exception {
+        try {
+            Page<SecondTradeRecord> page = new Page<>(1, 1000000);
+            QueryWrapper<SecondTradeRecord> wrapper = new QueryWrapper<>();
+            wrapper.eq("trade.delete_flag", 0);
+            wrapper.eq("trade.trade_status", 4);
+            wrapper.ge("trade.transaction_time", StringUtils.isEmpty(beginTime) ? "1970-01-01 00:00:00" : beginTime);
+            wrapper.le("trade.transaction_time", StringUtils.isEmpty(endTime) ? "9999-12-31 23:59:59" : endTime);
+            wrapper.apply(" (trade.buyer_id = " + userId + " or trade.seller_id = " + userId + ") ");
+            wrapper.orderByDesc("trade.created_time");
+            List<SecondTradeRecordVo> voList = secondTradeRecordMapper.getTradeRecordPage(page, wrapper).getRecords();
+            for (SecondTradeRecordVo item : voList) {
+                item.setOperationJsonList(getOperationJsonList(item.getId()));
+            }
+            return voList;
+        } catch (Exception e) {
+            log.error("PlatformSecondTradeServiceImpl.getTradeRecordList(): Error Msg={}", e.getMessage());
+            throw new Exception(e);
+        }
+    }
+
+    @Override
     public SecondTradeRecordVo getTradeRecordById(Integer id) throws Exception {
         try {
             // 交易信息
@@ -254,4 +277,30 @@ public class PlatformSecondTradeServiceImpl extends ServiceImpl<SecondTradeRecor
         }
     }
 
+    @Override
+    public List<JSONObject> getRankingList(String beginTime, String endTime) throws Exception {
+        try {
+            if (StringUtils.isBlank(beginTime)) beginTime = "1970-01-01 00:00:00";
+            if (StringUtils.isBlank(endTime)) endTime = "9999-12-31 23:59:59";
+            return secondTradeRecordMapper.getRankingList(beginTime, endTime);
+        } catch (Exception e) {
+            log.error("PlatformSecondTradeServiceImpl.getRankingList Error Msg={}", e.getMessage());
+            throw new Exception(e);
+        }
+    }
+
+    @Override
+    public void setTradeFailure(Integer tradeId, String failureReason) throws Exception {
+        try {
+            LambdaUpdateWrapper<SecondTradeRecord> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(SecondTradeRecord::getId, tradeId);
+            wrapper.set(SecondTradeRecord::getFailureFlag, 1);
+            wrapper.set(SecondTradeRecord::getFailureReason, failureReason);
+            secondTradeRecordMapper.update(null, wrapper);
+        } catch (Exception e) {
+            log.error("PlatformSecondTradeServiceImpl.setTradeFailure Error Msg={}", e.getMessage());
+            throw new Exception(e);
+        }
+    }
+
 }

+ 32 - 21
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java

@@ -153,7 +153,10 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     @Override
     public SecondGoodsRecordDetailVo getAdminGoodsRecordDetail(Integer recordId) {
         // 1. 获取商品操作记录基本信息
-        SecondGoodsRecord record = secondGoodsRecordMapper.selectById(recordId);
+        QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
+        queryWrapper
+                .eq("sg.id", recordId);
+        SecondGoodsRecord record = secondGoodsRecordMapper.selectGoodsRecordById(queryWrapper);
         if (record == null) {
             return null;
         }
@@ -205,7 +208,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         recordQueryWrapper.lambda()
                 .eq(SecondGoodsRecord::getGoodsId, goodsId)
                 .orderByDesc(SecondGoodsRecord::getCreatedTime);
-        List<SecondGoodsRecord> operationRecords = secondGoodsRecordMapper.selectList(recordQueryWrapper);
+        List<SecondGoodsRecord> operationRecords = secondGoodsRecordMapper.selectdminGoodsList(recordQueryWrapper);
         detailVo.setOperationRecords(operationRecords);
         
         // 4. 获取商品交易记录集合
@@ -596,7 +599,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         // 审核失败。直接返回
         if (!imageAuditResult) {
             // 图片审核不通过,记录操作历史
-//            recordGoodsOperation(goods);
+            recordGoodsOperation(goods,"图片审核失败");
             return;
         }
 
@@ -605,7 +608,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         // 审核失败。直接返回
         if (!textAuditResult) {
             // 文本审核不通过,记录操作历史
-//            recordGoodsOperation(goods);
+            recordGoodsOperation(goods,"文本审核失败");
             return;
         }
         // 视频审核
@@ -704,9 +707,10 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         if ("high".equals(textCheckResult.getRiskLevel())) {
             // 文本审核不通过或存在高风险
             goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
-            goods.setFailedReason("文本审核不通过:" + (textCheckResult.getRiskWords() != null ? textCheckResult.getRiskWords() : "存在高风险内容"));
+            String failReason = "文本审核不通过:" + (textCheckResult.getRiskWords() != null ? textCheckResult.getRiskWords() : "存在高风险内容");
+            goods.setFailedReason(failReason);
             // 插入审核记录
-            createGoodsAudit(goods, textCheckResult.getRiskWords(), Constants.AuditStatus.FAILED);
+            createGoodsAudit(goods, failReason, Constants.AuditStatus.FAILED);
             // 发送审核失败消息
             sendFailedMsg(goods);
             return false;
@@ -738,9 +742,10 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
                 if ("high".equals(response.getRiskLevel())) {
                     // 图片审核不通过或存在高风险
                     goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
-                    goods.setFailedReason("图片审核不通过:图片中包含" + (response.getDescriptions() != null ? response.getDescriptions() : "高风险内容"));
+                    String failReason = "图片审核不通过:图片中包含" + (response.getDescriptions() != null ? response.getDescriptions() : "高风险内容");
+                    goods.setFailedReason(failReason);
                     // 插入审核记录
-                    createGoodsAudit(goods, response.getDescriptions(), Constants.AuditStatus.FAILED);
+                    createGoodsAudit(goods, failReason, Constants.AuditStatus.FAILED);
                     // 发送审核失败消息
                     sendFailedMsg(goods);
                     return false;
@@ -887,17 +892,17 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
      * 创建商品审核记录
      *
      * @param goods 商品
-     * @param riskWords 文本审核结果
+     * @param failReason 审核结果
      */
-    private void createGoodsAudit(SecondGoods goods, String riskWords,Integer goodsStatus) {
+    private void createGoodsAudit(SecondGoods goods, String failReason,Integer goodsStatus) {
         // 保存审核结果
         secondGoodsMapper.updateById(goods);
         // 插入审核记录
         SecondGoodsAudit auditRecord = new SecondGoodsAudit();
         auditRecord.setGoodsId(goods.getId());
-        auditRecord.setGoodsStatus(goodsStatus); // 审核失败
+        auditRecord.setGoodsStatus(goodsStatus); // 审核状态
         if (Constants.AuditStatus.FAILED.equals(goodsStatus)) {
-            auditRecord.setFailedReason("文本审核不通过:" + (riskWords != null ? riskWords : "存在高风险内容"));
+            auditRecord.setFailedReason(failReason);
         }
         auditRecord.setCreatedUserId(goods.getUserId());
         auditRecord.setUpdatedUserId(goods.getUserId());
@@ -973,14 +978,18 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     }
 
     private void sendNotice(String receiverId, LifeNotice lifeNotice) {
-        WebSocketVo webSocketVo = new WebSocketVo();
-        webSocketVo.setSenderId("system");
-        webSocketVo.setReceiverId(receiverId);
-        webSocketVo.setCategory("notice");
-        webSocketVo.setNoticeType("1");
-        webSocketVo.setIsRead(0);
-        webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
-        alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.from(webSocketVo).toJSONString());
+        try {
+            WebSocketVo webSocketVo = new WebSocketVo();
+            webSocketVo.setSenderId("system");
+            webSocketVo.setReceiverId(receiverId);
+            webSocketVo.setCategory("notice");
+            webSocketVo.setNoticeType("1");
+            webSocketVo.setIsRead(0);
+            webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
+            alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.from(webSocketVo).toJSONString());
+        } catch (Exception e) {
+            log.error("发送消息通知失败,receiverId: {}", receiverId, e);
+        }
     }
 
     /**
@@ -1507,7 +1516,9 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
                 
                 // 更新审核记录
                 createGoodsAudit(goods, failedReason, Constants.AuditStatus.FAILED);
-                
+
+                // 记录操作历史
+                recordGoodsOperation(goods, "视频审核失败");
                 // 发送审核失败消息
                 sendFailedMsg(goods);
             }

+ 75 - 0
alien-store/src/main/java/shop/alien/store/config/BaseRedisService.java

@@ -12,6 +12,7 @@ import org.springframework.stereotype.Component;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -307,5 +308,79 @@ public class BaseRedisService {
         return stringRedisTemplate.opsForZSet().remove(type, (Object[]) members);
     }
 
+    /**
+     * 获取分布式锁
+     * @param lockKey 锁的标识
+     * @return 锁的value值,用于释放锁时验证,null表示获取失败
+     */
+    public String lock(String lockKey) {
+        return lock(lockKey, 30000, 10000);
+    }
+
+    /**
+     * 获取分布式锁
+     * @param lockKey 锁的标识
+     * @param expireTime 锁的过期时间(毫秒)
+     * @param acquireTimeout 获取锁的超时时间(毫秒)
+     * @return 锁的value值,用于释放锁时验证,null表示获取失败
+     */
+    public String lock(String lockKey, long expireTime, long acquireTimeout) {
+        // 生成唯一标识,用于释放锁时验证
+        String identifier = UUID.randomUUID().toString();
+        // 完整的锁键
+        String lockKeyWithPrefix = "inventory:lock:" + lockKey;
+        // 超时时间戳
+        long endTime = System.currentTimeMillis() + acquireTimeout;
+
+        while (System.currentTimeMillis() < endTime) {
+            // 尝试获取锁:SET NX PX
+            Boolean success = stringRedisTemplate.opsForValue()
+                    .setIfAbsent(lockKeyWithPrefix, identifier, expireTime, TimeUnit.MILLISECONDS);
+
+            if (Boolean.TRUE.equals(success)) {
+                // 获取锁成功
+                return identifier;
+            }
+
+            try {
+                // 短暂休眠,避免频繁尝试
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                return null;
+            }
+        }
+
+        // 获取锁超时
+        return null;
+    }
+
+    /**
+     * 释放分布式锁
+     * @param lockKey 锁的标识
+     * @param identifier 锁的value值,用于验证
+     * @return 是否释放成功
+     */
+    public boolean unlock(String lockKey, String identifier) {
+        if (identifier == null) {
+            return false;
+        }
+
+        String lockKeyWithPrefix = "inventory:lock:" + lockKey;
+
+        // 使用Lua脚本确保释放锁的原子性
+        String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
+                "return redis.call('del', KEYS[1]) " +
+                "else " +
+                "return 0 " +
+                "end";
+
+        RedisScript<Long> script = new DefaultRedisScript<>(luaScript, Long.class);
+        Long result = stringRedisTemplate.execute(script,
+                Collections.singletonList(lockKeyWithPrefix),
+                identifier);
+
+        return result != null && result > 0;
+    }
 
 }

+ 27 - 4
alien-store/src/main/java/shop/alien/store/controller/ActivityConfigController.java

@@ -8,13 +8,12 @@ import org.apache.commons.lang.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.ActivitySignInConfig;
+import shop.alien.entity.store.UserPoint;
 import shop.alien.entity.store.vo.ActivityConfigVo;
 import shop.alien.entity.store.vo.ActivityPeriodVo;
 import shop.alien.store.service.ActivityConfigService;
-
-import java.util.Date;
+import shop.alien.store.service.UserPointService;
 import java.util.List;
-
 @Api(tags = {"二期-签到活动"})
 @Slf4j
 @CrossOrigin
@@ -22,8 +21,8 @@ import java.util.List;
 @RequestMapping("/activity")
 @RequiredArgsConstructor
 public class ActivityConfigController {
-
     private final ActivityConfigService activityConfigService;
+    private final UserPointService userPointService;
 
     /**
      * 创建签到活动
@@ -119,4 +118,28 @@ public class ActivityConfigController {
         List<ActivityPeriodVo> activityPeriodVoList = activityConfigService.checkOverlapTime(startTime, endTime);
         return R.data(activityPeriodVoList);
     }
+
+    @ApiOperation("获取用户积分")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/getUserPoint")
+    public R<UserPoint> getUserPoint(@RequestParam(required = true) Integer userId) {
+        log.info("ActivityConfigController.getUserPoint");
+        UserPoint userPoint = userPointService.getPoint(userId);
+        return R.data(userPoint);
+    }
+
+    @ApiOperation("获取用户积分详情")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/getUserPointDetails")
+    public R<UserPoint> getUserPointDetails(@RequestParam(required = true) Integer userId) {
+        log.info("ActivityConfigController.getUserPointDetails");
+        UserPoint userPoint = userPointService.getUserPointDetails(userId);
+        return R.data(userPoint);
+    }
 }

+ 147 - 0
alien-store/src/main/java/shop/alien/store/controller/ActivityInviteConfigController.java

@@ -0,0 +1,147 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.ActivityInviteConfig;
+import shop.alien.entity.store.vo.*;
+import shop.alien.store.service.ActivityInviteConfigService;
+
+@Api(tags = {"二期-邀请活动"})
+@Slf4j
+@CrossOrigin
+@RestController
+@RequestMapping("/activityInvite")
+@RequiredArgsConstructor
+public class ActivityInviteConfigController {
+
+    private final ActivityInviteConfigService activityInviteConfigService;
+
+    /**
+     * 创建签到活动
+     */
+    @ApiOperation("创建/更新邀请活动")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("createOrUpdateInviteActivity")
+    public R<ActivityInviteConfigVo> createOrUpdateInviteActivity(@RequestBody ActivityInviteConfigVo configVO) {
+        ActivityInviteConfigVo activity = activityInviteConfigService.createOrUpdateInviteActivity(configVO);
+        if(activity == null) {
+            return R.fail("插入/更新失败");
+        }
+        if(StringUtils.isNotBlank(activity.getErrorMessage())){
+            return R.fail(activity.getErrorMessage());
+        }
+        return R.data(activity);
+    }
+
+    /**
+     * web-分页查询邀请活动
+     */
+    @ApiOperation("分页查询邀请活动列表")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "pageSize", value = "页容", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "createdTime", value = "创建时间", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "activityType", value = "活动类型", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "状态", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/getInviteActivityConfigList")
+    public R<IPage<ActivityInviteConfig>> getInviteActivityConfigList(@RequestParam(defaultValue = "1") int pageNum,
+                                                                      @RequestParam(defaultValue = "10") int pageSize,
+                                                                      @RequestParam(required = false) String createdTime,
+                                                                      @RequestParam(required = false) Integer activityType,
+                                                                      @RequestParam(required = false) Integer status){
+        IPage<ActivityInviteConfig> activitySignInConfigList = activityInviteConfigService.getInviteActivityConfigList(pageNum, pageSize,createdTime, activityType, status);
+        return R.data(activitySignInConfigList);
+    }
+
+    @ApiOperation("获取邀请活动详情")
+    @ApiOperationSupport(order = 3)
+    @GetMapping("/getInviteActivitySignInConfigById")
+    public R<ActivityInviteConfigVo> getInviteActivitySignInConfigById(@RequestParam(required = false) Long activityId) {
+        log.info("ActivityConfigController.getActivitySignInConfigById={}", activityId);
+        ActivityInviteConfigVo activityConfigVO = activityInviteConfigService.getInviteActivitySignInConfigById(activityId);
+        return R.data(activityConfigVO);
+    }
+
+    /**
+     * 修改邀请活动状态
+     *
+     * @param id     主键
+     * @param status 状态
+     * @return boolean
+     */
+    @ApiOperation("更新签到活动状态")
+    @ApiOperationSupport(order = 4)
+    @GetMapping("/updateActivityStatus")
+    public R<Boolean> updateInviteActivityStatus(@RequestParam("id") Integer id, @RequestParam("status") Integer status) {
+        log.info("ActivityConfigController.updateActivityStatus?id={}&status={}", id, status);
+        if (activityInviteConfigService.updateInviteActivityStatus(id, status)) {
+            return R.success("成功");
+        }
+        return R.fail("失败");
+    }
+
+    @ApiOperation("删除邀请活动")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "活动ID", dataType = "Integer", paramType = "query", required = true)})
+    @GetMapping("/deleteInviteActivity")
+    public R<Boolean> deleteInviteActivity(Integer id) {
+        return R.data(activityInviteConfigService.deleteInviteActivity(id));
+    }
+
+    @ApiOperation("获取个人邀请码")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户ID", dataType = "Integer", paramType = "query", required = true)})
+    @GetMapping("/getInviteInfo")
+    public R<ActivityInviteInfoVo> getInviteInfo(Integer userId) {
+        return R.data(activityInviteConfigService.getInviteInfo(userId));
+    }
+
+
+    /**
+     * web-分页查询邀请活动
+     */
+    @ApiOperation("分页查询邀请记录")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "pageSize", value = "页容", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "userId", value = "邀请人", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "invitePhone", value = "手机号", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "inviteStartTime", value = "开始时间", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "inviteEndTime", value = "结束时间", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getInviteActivityLogList")
+    public R<IPage<ActivityInviteLogVo>> getInviteActivityLogList(@RequestParam(defaultValue = "1") int pageNum,
+                                                                @RequestParam(defaultValue = "10") int pageSize,
+                                                                @RequestParam(required = false) Integer userId,
+                                                                  @RequestParam(required = false) String invitePhone,
+                                                                  @RequestParam(required = false) String inviteStartTime,
+                                                                  @RequestParam(required = false) String inviteEndTime){
+        IPage<ActivityInviteLogVo> activityLogList = activityInviteConfigService.getInviteActivityLogList(pageNum, pageSize, userId, invitePhone, inviteStartTime, inviteEndTime);
+        return R.data(activityLogList);
+    }
+
+    /**
+     * 绑定邀请码
+     */
+    @ApiOperation("绑定邀请码")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "invitedUserId", value = "被邀请用户ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "inviteCode", value = "邀请码", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/bindInviteCode")
+    public R<String> bindInviteCode(@RequestParam(required = true) Integer invitedUserId,
+                                    @RequestParam(required = true) String inviteCode){
+        String result = activityInviteConfigService.bindInviteCode(invitedUserId, inviteCode);
+        return R.data(result);
+    }
+
+}

+ 1 - 1
alien-store/src/main/java/shop/alien/store/controller/LifeCouponController.java

@@ -52,7 +52,7 @@ public class LifeCouponController {
     }
 
     @ApiOperation("代金劵列表")
-    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "页数", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "size", value = "页容", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "status", value = "状态", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "name", value = "名称", dataType = "Integer", paramType = "query"), @ApiImplicitParam(name = "dataType", value = "数据类型: 0:正式数据, 1:草稿数据", dataType = "Integer", paramType = "query", defaultValue = "0")})
+    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "页数", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "size", value = "页容", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "storeId", value = "门店id", dataType = "Integer", paramType = "query", required = true), @ApiImplicitParam(name = "status", value = "状态", dataType = "Integer", paramType = "query", required = false), @ApiImplicitParam(name = "name", value = "名称", dataType = "Integer", paramType = "query"), @ApiImplicitParam(name = "dataType", value = "数据类型: 0:正式数据, 1:草稿数据", dataType = "Integer", paramType = "query", defaultValue = "0")})
     @GetMapping("/getCouponList")
     private R<IPage<LifeCoupon>> getCouponList(@RequestParam(value = "page", defaultValue = "1") int page, @RequestParam(value = "size", defaultValue = "10") int size, @RequestParam("storeId") String storeId, @RequestParam("status") String status, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "dataType", defaultValue = "0") Integer dataType) {
         log.info("LifeCouponController.getCouponList?page={},size={},storeId={},status={},name={},dataType={}", page, size, storeId, status, name, dataType);

+ 19 - 0
alien-store/src/main/java/shop/alien/store/controller/LifeDiscountCouponController.java

@@ -395,4 +395,23 @@ public class LifeDiscountCouponController {
         return R.data(lifeDiscountCouponService.getPlatformCouponLogList(pageNum, pageSize, userName, phone, couponId));
     }
 
+    /**
+     * 获取平台优惠券列表
+     *
+     * @param couponId 优惠券ID
+     * @param couponType 类型:(1,优惠券 2,红包 3,平台优惠券)
+     * @return List<LifeDiscountCoupon>
+     */
+    @ApiOperation("获取平台优惠券列表")
+    @ApiOperationSupport(order = 15)
+    @GetMapping("/getPlatformCoupon")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "couponId", value = "优惠券ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "couponType", value = "优惠券类型", dataType = "Integer", paramType = "query")
+    })
+    public R<List<LifeDiscountCoupon>> getPlatformCoupon(@RequestParam(value = "couponId") Integer couponId,
+                                                         @RequestParam(defaultValue = "3") Integer couponType) {
+        return R.data(lifeDiscountCouponService.getPlatformCoupon(couponId, couponType));
+    }
+
 }

+ 63 - 3
alien-store/src/main/java/shop/alien/store/controller/LifeDiscountCouponStoreFriendController.java

@@ -1,16 +1,20 @@
 package shop.alien.store.controller;
 
 import com.alibaba.fastjson.JSONObject;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiOperationSupport;
+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.store.LifeDiscountCouponFriendRule;
+import shop.alien.entity.store.LifeGroupBuyThali;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.dto.LifeDiscountCouponStoreFriendDto;
+import shop.alien.entity.store.dto.LifeGroupBuyDto;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleDetailVo;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponStoreFriendVo;
+import shop.alien.entity.store.vo.LifeGroupBuyCountDateVo;
 import shop.alien.store.service.LifeDiscountCouponStoreFriendService;
 import shop.alien.util.common.TokenInfo;
 import springfox.documentation.annotations.ApiIgnore;
@@ -119,4 +123,60 @@ public class LifeDiscountCouponStoreFriendController {
         }
         return R.fail("删除失败");
     }
+
+    @ApiOperation("保存好友赠券规则")
+    @PostMapping("/saveFriendCouponRule")
+    public R saveFriendCouponRule(@RequestBody LifeDiscountCouponFriendRule lifeDiscountCouponFriendRule) {
+        log.info("LifeDiscountCouponStoreFriendController.saveFriendCouponRule?lifeDiscountCouponFriendRule={}", lifeDiscountCouponFriendRule.toString());
+        LifeDiscountCouponFriendRuleVo lifeDiscountCouponFriendRuleVo = lifeDiscountCouponStoreFriendService.saveFriendCouponRule(lifeDiscountCouponFriendRule);
+        return R.data(lifeDiscountCouponFriendRuleVo);
+    }
+
+    @ApiOperation("删除赠券规则")
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/delFriendCouponRule")
+    private R delFriendCouponRule(@RequestParam(value = "id") String id) {
+        log.info("LifeDiscountCouponStoreFriendController.delFriendCouponRule?id={}", id);
+        lifeDiscountCouponStoreFriendService.delFriendCouponRule(id);
+        return R.success("删除成功");
+    }
+
+    @ApiOperation("查询赠券规则明细")
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/getRuleById")
+    private R<LifeDiscountCouponFriendRuleVo> getRuleById(@RequestParam(value = "id") String id) {
+        log.info("LifeDiscountCouponStoreFriendController.getRuleById?id={}", id);
+        return R.data(lifeDiscountCouponStoreFriendService.getRuleById(id));
+    }
+
+    @ApiOperation("查询好友赠券")
+    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "当前登录店铺id", dataType = "String", paramType = "query", required = true)
+    ,@ApiImplicitParam(name = "friendStoreUserId", value = "选中好友店铺用户id", dataType = "String", paramType = "query", required = false)
+    })
+    @GetMapping("/getReceivedFriendCouponList")
+    private R<List<LifeDiscountCouponFriendRuleDetailVo>> getReceivedFriendCouponList(@RequestParam(value = "storeId") String storeId, @RequestParam(value = "friendStoreUserId",required = false)String friendStoreUserId) {
+        log.info("LifeDiscountCouponStoreFriendController.getReceivedFriendCouponList?storeId={},friendStoreUserId={}", storeId,friendStoreUserId);
+        return R.data(lifeDiscountCouponStoreFriendService.getReceivedFriendCouponList(storeId,friendStoreUserId));
+    }
+
+    @ApiOperation("查询赠券规则")
+    @ApiImplicitParams({@ApiImplicitParam(name = "storeId", value = "当前登录店铺id", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/getRuleList")
+    private R<List<LifeDiscountCouponFriendRuleVo>> getRuleList(@RequestParam(value = "storeId") String storeId) {
+        log.info("LifeDiscountCouponStoreFriendController.getRuleList?storeId={}", storeId);
+        return R.data(lifeDiscountCouponStoreFriendService.getRuleList(storeId));
+    }
+
+    @ApiOperation("查询赠券记录")
+    @ApiImplicitParams({@ApiImplicitParam(name = "storeUserId", value = "好友赠我-当前登录店铺id", dataType = "String", paramType = "query", required = false)
+            ,@ApiImplicitParam(name = "friendStoreUserId", value = "我赠好友-选中好友店铺用户id", dataType = "String", paramType = "query", required = false)
+    })
+    @GetMapping("/getReceivedSendFriendCouponList")
+    private R<List<LifeDiscountCouponFriendRuleVo>> getReceivedSendFriendCouponList(@RequestParam(value = "storeUserId",required = false) String storeUserId, @RequestParam(value = "friendStoreUserId",required = false)String friendStoreUserId, @RequestParam(value = "storeName",required = false)String storeName) {
+        log.info("LifeDiscountCouponStoreFriendController.getReceivedSendFriendCouponList?storeId={},friendStoreUserId={},storeName={}", storeUserId,friendStoreUserId,storeName);
+        return R.data(lifeDiscountCouponStoreFriendService.getReceivedSendFriendCouponList(storeUserId,friendStoreUserId,storeName));
+    }
 }

+ 4 - 3
alien-store/src/main/java/shop/alien/store/controller/LifeUserController.java

@@ -41,11 +41,12 @@ public class LifeUserController {
 
     @ApiOperation("用户登录")
     @ApiOperationSupport(order = 1)
-    @ApiImplicitParams({@ApiImplicitParam(name = "phoneNum", value = "手机号", dataType = "String", paramType = "query", required = true)})
+    @ApiImplicitParams({@ApiImplicitParam(name = "phoneNum", value = "手机号", dataType = "String", paramType = "query", required = true),
+                        @ApiImplicitParam(name = "inviteCode", value = "邀请码", dataType = "String", paramType = "query", required = false)})
     @GetMapping("/userLogin")
-    public R<LifeUserVo> userLogin(@RequestParam("phoneNum") String phoneNum) {
+    public R<LifeUserVo> userLogin(@RequestParam("phoneNum") String phoneNum,  @RequestParam(required = false) String inviteCode) {
         log.info("LifeUserController.userLogin?phoneNum={}", phoneNum);
-        LifeUserVo userVo = service.userLogin(phoneNum);
+        LifeUserVo userVo = service.userLogin(phoneNum, inviteCode);
         if (null == userVo) {
             return R.fail("登录失败");
         }

+ 1 - 72
alien-store/src/main/java/shop/alien/store/controller/PingtaiTaocanController.java

@@ -1,20 +1,15 @@
 package shop.alien.store.controller;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.store.LifeCoupon;
-import shop.alien.entity.store.vo.StoreInfoVo;
 import shop.alien.mapper.LifeCouponMapper;
 import shop.alien.mapper.StoreInfoMapper;
 
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Date;
 
 /**
  * 套餐
@@ -31,72 +26,6 @@ public class PingtaiTaocanController {
 
     private final StoreInfoMapper storeInfoMapper;
 
-    @GetMapping("getTaocanList")
-    private Map<String, Object> getTaocanList(@RequestParam(value = "page", defaultValue = "1") int page,
-                                              @RequestParam(value = "size", defaultValue = "10") int size,
-                                              @RequestParam("storeName") String storeName,
-                                              @RequestParam("status") String status) {
-        log.info("LifeCouponController.getTaocanList?page={},size={},storeName={},status={}", page, size, storeName, status);
-        Map<String, Object> returnMap = new HashMap<>();
-        IPage<LifeCoupon> quanPage = new Page<>(page, size);
-        LambdaUpdateWrapper<LifeCoupon> wrapper = new LambdaUpdateWrapper<>();
-        if (storeName != null && !storeName.isEmpty()) {
-            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
-            queryWrapper.eq("a.store_name", storeName).eq("a.delete_flag", 0);
-            List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getStoreInfoVoList(queryWrapper);
-            if (storeInfoVoList.isEmpty()) {
-                return returnMap;
-            }
-            List<Integer> storeIds = storeInfoVoList.stream().map(StoreInfoVo::getId).collect(Collectors.toList());
-            wrapper.in(LifeCoupon::getStoreId, storeIds);
-        }
-        if (status != null && !status.isEmpty()) {
-            if (status.equals("0")) {
-                List<Integer> statuss = new ArrayList<>();
-                statuss.add(0);
-                statuss.add(1);
-                statuss.add(2);
-                statuss.add(3);
-                wrapper.in(LifeCoupon::getStatus, statuss);
-            } else {
-                wrapper.eq(LifeCoupon::getStatus, Integer.valueOf(status));
-            }
-        }
-        wrapper.eq(LifeCoupon::getType, 2);
-        wrapper.orderByDesc(LifeCoupon::getUpdatedTime);
-        IPage<LifeCoupon> lifeyouhuiquans = lifeCouponMapper.selectPage(quanPage, wrapper);
-        int totalCnt = lifeCouponMapper.selectCount(wrapper);
-        if (lifeyouhuiquans.getRecords().isEmpty()) {
-            return returnMap;
-        }
-        List<Map<String, Object>> mapList = new ArrayList<>();
-        for (LifeCoupon taocan : lifeyouhuiquans.getRecords()) {
-            Map<String, Object> map = new HashMap<>();
-            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
-            queryWrapper.eq("a.id", taocan.getStoreId()).eq("a.delete_flag", 0);
-            StoreInfoVo storeInfoVoOne = storeInfoMapper.getStoreInfoVoOne(queryWrapper);
-            map.put("id", taocan.getId());
-            map.put("storeName", storeInfoVoOne.getStoreName());
-            map.put("phoneNum", storeInfoVoOne.getStorePhone());
-            map.put("tijiaoTime", taocan.getCreatedTime());
-            String statusStr;
-            if (taocan.getStatus() == -1) {
-                statusStr = "待审核";
-            } else if (taocan.getStatus() == -2) {
-                statusStr = "已驳回";
-            } else {
-                statusStr = "已通过";
-            }
-            map.put("status", statusStr);
-            map.put("taocanName", taocan.getName());
-            mapList.add(map);
-        }
-        returnMap.put("data", mapList);
-        returnMap.put("total", totalCnt);
-        returnMap.put("current", quanPage.getCurrent());
-        returnMap.put("size", quanPage.getSize());
-        return returnMap;
-    }
 
     @GetMapping("getTaocanDetial")
     private LifeCoupon getTaocanList(@RequestParam("id") String id) {

+ 2 - 5
alien-store/src/main/java/shop/alien/store/controller/PlatformLifeUserController.java

@@ -4,10 +4,7 @@ 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.CrossOrigin;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeUser;
 import shop.alien.entity.store.vo.LifeUserVo;
@@ -30,7 +27,7 @@ public class PlatformLifeUserController {
             @ApiImplicitParam(name = "realName", value = "姓名", dataType = "String", paramType = "query"),
             @ApiImplicitParam(name = "userPhone", value = "手机号码", dataType = "String", paramType = "query")})
     @GetMapping("/getUserList")
-    public R<IPage<LifeUserVo>> getUserList(Integer page, Integer size, String realName, String userPhone) {
+    public R<IPage<LifeUserVo>> getUserList(@RequestParam("page") Integer page, @RequestParam("size") Integer size, String realName, String userPhone) {
         log.info("PlatformLifeUserController.getUserList?page={},size={},name={},phone={}", page, size, realName, userPhone);
         IPage<LifeUserVo> userList = platformLifeUserService.getUserList(page, size, realName, userPhone);
         return R.data(userList);

+ 10 - 4
alien-store/src/main/java/shop/alien/store/controller/StoreClockInController.java

@@ -30,11 +30,17 @@ public class StoreClockInController {
 
     @ApiOperation("打卡列表")
     @ApiOperationSupport(order = 2)
-    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", paramType = "query"), @ApiImplicitParam(name = "page", value = "分页页数", dataType = "Integer", defaultValue = "1", paramType = "query"), @ApiImplicitParam(name = "size", value = "分页条数", dataType = "Integer", defaultValue = "10", paramType = "query"), @ApiImplicitParam(name = "phoneId", value = "'user_' + 手机号", dataType = "String", paramType = "query"), @ApiImplicitParam(name = "mySelf", value = "是否只查看自己(0-否  1-是)", dataType = "Integer", defaultValue = "0", paramType = "query")})
+    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "page", value = "分页页数", dataType = "Integer", defaultValue = "1", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "分页条数", dataType = "Integer", defaultValue = "10", paramType = "query"),
+            @ApiImplicitParam(name = "phoneId", value = "'user_' + 手机号", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "mySelf", value = "是否只查看自己(0-否  1-是)", dataType = "Integer", defaultValue = "0", paramType = "query"),
+            @ApiImplicitParam(name = "storeId", value = "店铺id", dataType = "Integer", paramType = "query")
+    })
     @GetMapping("/getStoreClockInList")
-    public R<IPage<StoreClockInVo>> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf) {
-        log.info("StoreClockInController.getStoreClockInList?userId={},page={},size={},phoneId={},mySelf={}", userId, page, size, phoneId, mySelf);
-        return R.data(storeClockInService.getStoreClockInList(userId, page, size, phoneId, mySelf));
+    public R<IPage<StoreClockInVo>> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf, @RequestParam(required = false) Integer storeId) {
+        log.info("StoreClockInController.getStoreClockInList?userId={},page={},size={},phoneId={},mySelf={},storeId={}", userId, page, size, phoneId, mySelf,storeId);
+        return R.data(storeClockInService.getStoreClockInList(userId, page, size, phoneId, mySelf,storeId));
     }
 
     @ApiOperation("删除打卡记录")

+ 5 - 4
alien-store/src/main/java/shop/alien/store/controller/StoreCommentController.java

@@ -43,12 +43,13 @@ public class StoreCommentController {
             @ApiImplicitParam(name = "commentLevel", value = "评论等级(0:全部, 1:好评, 2:中评, 3:差评)", dataType = "Integer", paramType = "query"),
             @ApiImplicitParam(name = "days", value = "查询时间, 多少天前", dataType = "Integer", paramType = "query"),
             @ApiImplicitParam(name = "phoneId", value = "消息标识", dataType = "String", paramType = "query"),
-            @ApiImplicitParam(name = "userType", value = "评论的用户类型(0:商家, 其他:用户)", dataType = "String", paramType = "query")
+            @ApiImplicitParam(name = "userType", value = "评论的用户类型(0:商家, 其他:用户)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "tagId", value = "标签id)", dataType = "Integer", paramType = "query")
     })
     @GetMapping("/getList")
-    public R<IPage<StoreCommentVo>> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType) {
-        log.info("StoreCommentController.getList?pageNum={}&pageSize={}&businessId={}&businessType={}&storeId={}&replyStatus={}&commentLevel={}&days={}&phoneId={}&userType={}", pageNum, pageSize, businessId, businessType, storeId, replyStatus, commentLevel, days, phoneId, userType);
-        return R.data(storeCommentService.getList(pageNum, pageSize, businessId, businessType, storeId, replyStatus, commentLevel, days, phoneId, userType));
+    public R<IPage<StoreCommentVo>> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType, Integer tagId) {
+        log.info("StoreCommentController.getList?pageNum={}&pageSize={}&businessId={}&businessType={}&storeId={}&replyStatus={}&commentLevel={}&days={}&phoneId={}&userType={}&tagId={}", pageNum, pageSize, businessId, businessType, storeId, replyStatus, commentLevel, days, phoneId, userType, tagId);
+        return R.data(storeCommentService.getList(pageNum, pageSize, businessId, businessType, storeId, replyStatus, commentLevel, days, phoneId, userType, tagId));
     }
 
     @ApiOperation("获取最新一条评论/评价")

+ 79 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreCustomerServiceController.java

@@ -1,13 +1,17 @@
 package shop.alien.store.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.store.AiIntelligentAssistant;
 import shop.alien.entity.store.StoreCustomerService;
 import shop.alien.store.service.StoreCustomerServiceService;
 
+import java.util.List;
+
 /**
  * <p>
  * 智能客服
@@ -39,4 +43,79 @@ public class StoreCustomerServiceController {
         return R.data(result);
     }
 
+    @ApiOperation("获取随机问题")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({@ApiImplicitParam(name = "type", value = "类型(1/商家/2用户)", dataType = "String", paramType = "query", required = true)
+    , @ApiImplicitParam(name = "limit", value = "数量", dataType = "Integer", paramType = "query", required = true)})
+    @GetMapping("/getRandList")
+    public R<List<StoreCustomerService>> getRandList(@RequestParam String type, @RequestParam Integer limit) {
+        List<StoreCustomerService> result = storeCustomerServiceService.getRandList(type,limit);
+        return R.data(result);
+    }
+
+    @ApiOperation("删除问题")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query", required = true)
+            })
+    @GetMapping("/delStoreCustomerService")
+    public R delStoreCustomerService(@RequestParam String id) {
+        storeCustomerServiceService.delStoreCustomerService(id);
+        return R.data("删除成功");
+    }
+
+    @ApiOperation("中台-问题列表")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "页数", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "size", value = "页容", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "question", value = "问题", dataType = "String", paramType = "query", required = false),
+            @ApiImplicitParam(name = "type", value = "类型(1/商家/2用户)", dataType = "String", paramType = "query", required = false),
+    })
+    @GetMapping("/getStoreCustomerServicePage")
+    private R<IPage<StoreCustomerService>> getStoreCustomerServicePage(@RequestParam(value = "page", defaultValue = "1") int page,
+                                                       @RequestParam(value = "size", defaultValue = "10") int size,
+                                                       @RequestParam(value = "question", required = false) String question,
+                                                       @RequestParam(value = "type", required = false) String type) {
+        log.info("StoreCustomerServiceController.getStoreCustomerServicePage?page={},size={},question={},type={}", page, size, question, type);
+        return R.data(storeCustomerServiceService.getStoreCustomerServicePage(page, size, question, type));
+    }
+
+    @ApiOperation("中台-保存问题")
+    @ApiOperationSupport(order = 5)
+    @PostMapping("/saveStoreCustomerService")
+    public R<StoreCustomerService> saveStoreCustomerService(@RequestBody StoreCustomerService storeCustomerService) {
+        log.info("StoreCustomerServiceController.saveStoreCustomerService?storeCustomerService={}", storeCustomerService.toString());
+        StoreCustomerService saved = storeCustomerServiceService.saveStoreCustomerService(storeCustomerService);
+        return R.data(saved);
+    }
+
+    @ApiOperation("id查询问题")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/getById")
+    public R<StoreCustomerService> getById(@RequestParam String id) {
+        log.info("StoreCustomerServiceController.getById?id={}", id);
+        StoreCustomerService saved = storeCustomerServiceService.getById(id);
+        return R.data(saved);
+    }
+
+    @ApiOperation("保存聊天")
+    @ApiOperationSupport(order = 5)
+    @PostMapping("/saveAiIntelligentAssistant")
+    public R<List<AiIntelligentAssistant>> saveAiIntelligentAssistant(@RequestBody List<AiIntelligentAssistant> aiIntelligentAssistants) {
+        log.info("StoreCustomerServiceController.saveAiIntelligentAssistant?aiIntelligentAssistants={}", aiIntelligentAssistants.toString());
+        List<AiIntelligentAssistant> saved = storeCustomerServiceService.saveAiIntelligentAssistant(aiIntelligentAssistants);
+        return R.data(saved);
+    }
+
+    @ApiOperation("查询聊天记录")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({@ApiImplicitParam(name = "userId", value = "用户id)", dataType = "String", paramType = "query", required = true)
+            , @ApiImplicitParam(name = "time", value = "时间", dataType = "String", paramType = "query", required = true)
+            , @ApiImplicitParam(name = "talkSource", value = "1平台使用/2商户运营", dataType = "Integer", paramType = "query", required = true)})
+    @GetMapping("/selectAiIntelligentAssistant")
+    public R<List<AiIntelligentAssistant>> selectAiIntelligentAssistant(@RequestParam String userId, @RequestParam String time,@RequestParam Integer talkSource) {
+        List<AiIntelligentAssistant> result = storeCustomerServiceService.selectAiIntelligentAssistant(userId,time,talkSource);
+        return R.data(result);
+    }
 }

+ 39 - 5
alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java

@@ -10,13 +10,12 @@ import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartRequest;
 import shop.alien.entity.result.R;
-import shop.alien.entity.store.StoreBusinessInfo;
-import shop.alien.entity.store.StoreImg;
-import shop.alien.entity.store.StoreInfo;
-import shop.alien.entity.store.StoreInfoDraft;
+import shop.alien.entity.store.*;
 import shop.alien.entity.store.dto.StoreInfoDto;
 import shop.alien.entity.store.vo.*;
 import shop.alien.mapper.StoreImgMapper;
+import shop.alien.mapper.TagsMainMapper;
+import shop.alien.mapper.WebAuditMapper;
 import shop.alien.store.service.StoreInfoService;
 
 import java.io.IOException;
@@ -43,6 +42,10 @@ public class StoreInfoController {
 
     private final StoreImgMapper storeImgMapper;
 
+    private final TagsMainMapper tagsMainMapper;
+
+    private final WebAuditMapper webAuditMapper;
+
     @ApiOperation("获取所有门店")
     @ApiOperationSupport(order = 1)
     @GetMapping("/getAll")
@@ -665,6 +668,12 @@ public class StoreInfoController {
         log.info("StoreInfoController.uploadfoodLicence?storeImg={}", storeImg);
         int num = storeInfoService.uploadfoodLicence(storeImg);
         if (num > 0) {
+            WebAudit webAudit = new WebAudit();
+            webAudit.setStoreInfoId(storeImg.getStoreId().toString());
+            webAudit.setType("7");
+            webAudit.setStatus("0");
+            webAudit.setContent("经营许可证");
+            webAuditMapper.insert(webAudit);
             return R.success("食品经营许可证图片添加成功");
         }
         return R.fail("食品经营许可证图片添加失败");
@@ -689,6 +698,12 @@ public class StoreInfoController {
                 storeInfo.setFoodLicenceStatus(storeInfoDto.getFoodLicenceStatus());
                 boolean flag = storeInfoService.updateById(storeInfo);
                 if (flag) {
+                    //待审核状态变为已审核
+                    WebAudit webAudit = webAuditMapper.selectOne(new LambdaQueryWrapper<WebAudit>().eq(WebAudit::getStoreInfoId,storeInfo.getId()).eq(WebAudit::getDeleteFlag,0).eq(WebAudit::getType,"7"));
+                    if(webAudit != null){
+                        webAudit.setStatus("1");
+                        webAuditMapper.updateById(webAudit);
+                    }
                     return R.success("拒绝审核成功");
                 } else {
                     return R.fail("拒绝审核失败");
@@ -698,7 +713,15 @@ public class StoreInfoController {
             storeInfo.setFoodLicenceStatus(storeInfoDto.getFoodLicenceStatus());
             boolean flag = storeInfoService.updateById(storeInfo);
             if (flag) {
-                storeInfoService.foodLicenceType(storeInfoDto.getId());
+                int num = storeInfoService.foodLicenceType(storeInfoDto.getId());
+                if(num > 0){
+                    //待审核状态变为已审核
+                    WebAudit webAudit = webAuditMapper.selectOne(new LambdaQueryWrapper<WebAudit>().eq(WebAudit::getStoreInfoId,storeInfo.getId()).eq(WebAudit::getDeleteFlag,0).eq(WebAudit::getType,"7"));
+                    if(webAudit != null){
+                        webAudit.setStatus("1");
+                        webAuditMapper.updateById(webAudit);
+                    }
+                }
                 return R.success("审核通过成功");
             }else{
                 return R.fail("审核失败");
@@ -707,4 +730,15 @@ public class StoreInfoController {
         return R.fail("审核失败 店铺不存在");
     }
 
+    @ApiOperation(value = "AI服务-门店评价标签")
+    @GetMapping("/getStoreEvaluateTags")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店id", dataType = "int", paramType = "query")
+    })
+    public R<List<TagsMainVo>> getStoreEvaluateTags(int storeId) {
+        log.info("StoreInfoController.getStoreEvaluateTags?storeId={}", storeId);
+        List<TagsMainVo> voList = tagsMainMapper.getStoreEvaluateTags(storeId);
+        return R.data(voList);
+    }
+
 }

+ 0 - 1
alien-store/src/main/java/shop/alien/store/service/ActivityConfigService.java

@@ -7,7 +7,6 @@ import shop.alien.entity.store.ActivitySignInReward;
 import shop.alien.entity.store.vo.ActivityConfigVo;
 import shop.alien.entity.store.vo.ActivityPeriodVo;
 
-import java.util.Date;
 import java.util.List;
 
 /**

+ 46 - 0
alien-store/src/main/java/shop/alien/store/service/ActivityInviteConfigService.java

@@ -0,0 +1,46 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.*;
+import shop.alien.entity.store.vo.*;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/09/05 10:00
+ */
+public interface ActivityInviteConfigService extends IService<ActivityInviteConfig> {
+    /**
+     * 创建签到活动
+     */
+    ActivityInviteConfigVo createOrUpdateInviteActivity(ActivityInviteConfigVo configVO);
+
+    /**
+     * 获取活动详情
+     */
+    ActivityInviteConfigVo getInviteActivitySignInConfigById(Long id);
+
+    /**
+     * 获取活动列表
+     */
+    IPage<ActivityInviteConfig> getInviteActivityConfigList(int pageNum, int pageSize, String createdTime, Integer activityType, Integer status);
+
+    /**
+     * 更新活动状态
+     */
+    boolean updateInviteActivityStatus(Integer id, Integer status);
+
+
+    /**
+     * 删除活动
+     */
+    boolean deleteInviteActivity(Integer id);
+
+    ActivityInviteInfoVo getInviteInfo(Integer userId);
+
+    IPage<ActivityInviteLogVo> getInviteActivityLogList(int pageNum, int pageSize, Integer status, String invitePhone, String inviteStartTime, String inviteEndTime);
+
+    String bindInviteCode(Integer invitedUserId, String inviteCode);
+
+}

+ 8 - 0
alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponService.java

@@ -151,4 +151,12 @@ public interface LifeDiscountCouponService extends IService<LifeDiscountCoupon>
      * @return IPage<LifeDiscountCouponUserWebVo>
      */
     IPage<LifeDiscountCouponUserWebVo> getPlatformCouponLogList(Integer pageNum, Integer pageSize, String userName, String phone, Integer couponId);
+
+    /**
+     * 查询平台优惠券
+     *
+     * @param couponType 优惠券类型
+     * @return List<LifeDiscountCoupon>
+     */
+    List<LifeDiscountCoupon> getPlatformCoupon(Integer couponId, Integer couponType);
 }

+ 15 - 0
alien-store/src/main/java/shop/alien/store/service/LifeDiscountCouponStoreFriendService.java

@@ -1,9 +1,12 @@
 package shop.alien.store.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.LifeDiscountCouponFriendRule;
 import shop.alien.entity.store.LifeDiscountCouponStoreFriend;
 import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.entity.store.dto.LifeDiscountCouponStoreFriendDto;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleDetailVo;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponStoreFriendVo;
 
 import java.util.List;
@@ -45,4 +48,16 @@ public interface LifeDiscountCouponStoreFriendService extends IService<LifeDisco
      * @param releaseType
      */
     int releaseAndCancelFriendStoreCoupon(String giveCouponId, String releaseType);
+
+    LifeDiscountCouponFriendRuleVo saveFriendCouponRule(LifeDiscountCouponFriendRule lifeDiscountCouponFriendRule);
+
+    void delFriendCouponRule(String id);
+
+    List<LifeDiscountCouponFriendRuleDetailVo> getReceivedFriendCouponList(String storeId,String friendStoreUserId);
+
+    List<LifeDiscountCouponFriendRuleVo> getRuleList(String storeId);
+
+    LifeDiscountCouponFriendRuleVo getRuleById(String id);
+
+    List<LifeDiscountCouponFriendRuleVo> getReceivedSendFriendCouponList(String storeUserId, String friendStoreUserId,String storeName);
 }

+ 8 - 0
alien-store/src/main/java/shop/alien/store/service/LifeUserDynamicsService.java

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
 import shop.alien.entity.store.*;
@@ -432,6 +433,13 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
 
     public List<LifeUserDynamicsVo> getDianZanList(String phoneId) {
         List<LifeUserDynamicsVo> lifeUserDynamicsVos = lifeUserDynamicsMapper.selectDianZanList(phoneId);
+        if (!CollectionUtils.isEmpty(lifeUserDynamicsVos)){
+            for (LifeUserDynamicsVo lifeUserDynamicsVo : lifeUserDynamicsVos) {
+                String phoneIdNew = lifeUserDynamicsVo.getPhoneId().substring(6);
+                StoreUser storeUser = storeUserService.getUserByPhone(phoneIdNew);
+                lifeUserDynamicsVo.setUserName(storeUser.getNickName());
+            }
+        }
         return  lifeUserDynamicsVos;
     }
 }

+ 62 - 37
alien-store/src/main/java/shop/alien/store/service/LifeUserOrderService.java

@@ -421,9 +421,10 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
                 .eq("order_id", refundOrder.getOrderId()).eq("delete_flag",0));
         // 1.查询订单信息  订单表 + 中间表
         LifeUserOrder order = lifeUserOrderMapper.selectById(refundOrder.getOrderId());
+        Integer refundCouponAmount = refundOrder.getRefundCouponAmount();
         // 待使用的券(可退款的券 || 退款失败的券 目前没做失败的券状态更新 暂时不加)
         List<OrderCouponMiddle> orderCouponMiddles1 = orderCouponMiddles.stream().filter(orderCouponMiddle -> orderCouponMiddle.getStatus() == OrderStatusEnum.WAIT_USE.getStatus()).collect(Collectors.toList());
-        if (orderCouponMiddles1.size() < refundOrder.getRefundCouponAmount()) {
+        if (orderCouponMiddles1.size() < refundCouponAmount) {
             returnMap.put("fail", "退款券数不足");
             return returnMap;
         }
@@ -445,7 +446,7 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
         boolean ifPartialRefund = false;
         String PartialRefundCode = "";
         // 只要本次退款不是全退都是部分退
-        if (refundOrder.getRefundCouponAmount() != orderCouponMiddles.size()){
+        if (refundCouponAmount != orderCouponMiddles.size()){
             ifPartialRefund = true;
             PartialRefundCode = UniqueRandomNumGenerator.generateUniqueCode(12);
         }
@@ -453,7 +454,7 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
         String refundMessage = "";
 
         // 更新的中间表id
-        List<Integer> updateIds = orderCouponMiddles1.stream().limit(refundOrder.getRefundCouponAmount()).map(x -> x.getId()).collect(Collectors.toList());
+        List<Integer> updateIds = orderCouponMiddles1.stream().limit(refundCouponAmount).map(x -> x.getId()).collect(Collectors.toList());
         if (result.equals("调用失败")) {
             refundMessage = "编号为"+order.getOrderNo()+"的订单退款失败,请重新发起申请。";
             // TODO 退款失败目前不做处理
@@ -479,8 +480,8 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
                 refundOrder.setPartialRefundCode(PartialRefundCode);
             }
         }
-        // 更新数据(中间表数据+订单表数据:当已退款个数+当前退款个数=已使用的券数时,订单状态改为已退款)
-        if (refundCouponCount + refundOrder.getRefundCouponAmount() == orderCouponMiddles.size()) {
+        // 更新总订单数据(中间表数据+订单表数据:当已退款个数+当前退款个数=已使用的券数时,订单状态改为已退款)
+        if (refundCouponCount + refundCouponAmount == orderCouponMiddles.size()) {
             lifeUserOrderMapper.update(null,new UpdateWrapper<LifeUserOrder>().eq("id",order.getId())
                     .set("status",OrderStatusEnum.REFUND.getStatus())
                     .set("refund_time",now)
@@ -492,7 +493,7 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
                 // 处理 quanId 为 null 的情况,例如日志记录
                 log.error("更新优惠券状态失败");
             }
-        } else if (refundCouponCount + refundOrder.getRefundCouponAmount() != orderCouponMiddles.size() && refundOrder.getRefundCouponAmount() == orderCouponMiddles1.size()) {
+        } else if (refundCouponCount + refundCouponAmount != orderCouponMiddles.size() && refundCouponAmount == orderCouponMiddles1.size()) {
             // 累计退券个数+当前退券个数!=总个数 且 当前退券数量 = 可退券数
             lifeUserOrderMapper.update(null,new UpdateWrapper<LifeUserOrder>().eq("id",order.getId())
                     .set("status",OrderStatusEnum.COMPLETE.getStatus())
@@ -526,26 +527,42 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
                 log.error("LifeUserOrderService requestRefund Stack={}", e);
             }
         }
-        // 券核销完成后,退款的情况下,需要向 store_income_details_record 表插入一条记录
-//        if (null != refundOrder.getStoreId()) {
-//            BigDecimal amounts = new BigDecimal(refundOrder.getRefundMoney()).multiply(new BigDecimal(100));
-//            BigDecimal commission = amounts.multiply(new BigDecimal(0.04)).setScale(0, RoundingMode.HALF_UP);
-//            BigDecimal money = amounts.subtract(commission);
-//
-//            StoreIncomeDetailsRecord record = new StoreIncomeDetailsRecord();
-//            record.setStoreId(refundOrder.getStoreId());
-//            record.setUserOrderId(Integer.parseInt(refundOrder.getOrderId()));
-//            record.setIncomeType(Integer.parseInt(refundOrder.getQuanType()));
-//            record.setBusinessId(Integer.parseInt(refundOrder.getQuanId()));
-//            record.setCommission(-commission.intValue());
-//            record.setMoney(-money.intValue());
-//            storeIncomeDetailsRecordMapper.insert(record);
-//        }
+        // 退款后更新库存
+        Integer couponType = order.getCouponType();
+        OrderCouponMiddle orderCouponMiddle = orderCouponMiddleMapper.selectOne(new QueryWrapper<OrderCouponMiddle>().eq("order_id", refundOrder.getOrderId()).last("limit 1"));
+        Integer couponId = orderCouponMiddle.getCouponId();
+
+        restoreInventory(couponType, refundCouponAmount, couponId);
         returnMap.put("success", refundMessage);
         return returnMap;
     }
 
     /**
+     * 退款,取消订单时候,恢复库存
+     * @param couponType 类型 1-代金券,2-团购
+     * @param refundCouponAmount 团购券/代金券张数
+     * @param couponId 团购券/代金券id
+     */
+    private void restoreInventory(Integer couponType, Integer refundCouponAmount, Integer couponId) {
+        try{
+            if( CouponTypeEnum.COUPON.getCode() == couponType){
+                // 代金券信息
+                lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
+                        .setSql("single_qty=single_qty+" + refundCouponAmount)
+                        .eq(LifeCoupon::getId, couponId));
+            } else {
+                // 团购信息
+                lifeGroupBuyMainMapper.update(null, new LambdaUpdateWrapper<LifeGroupBuyMain>()
+                        .setSql("inventory_num=inventory_num+" + refundCouponAmount)
+                        .eq(LifeGroupBuyMain::getId, couponId));
+            }
+        } catch (Exception e) {
+            log.error("LifeUserOrderService,恢复团购券/代金券数量报错={}", e);
+        }
+
+    }
+
+    /**
      * 退款检查
      * @param refundOrder
      * @return
@@ -714,8 +731,12 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
             lifeDiscountCouponUserMapper.updateById(lifeDiscountCouponUser);
         }
         //3.根据购买数量增加中间关系 订单id+券编号 确定一条数据
-        BigDecimal sumPrice = new BigDecimal(0);
-        for (int i = 0; i < lifeUserOrderDto.getCount(); i++) {
+        int buyCount = lifeUserOrderDto.getCount();
+        BigDecimal totalPrice = new BigDecimal(lifeUserOrderDto.getFinalPrice());
+        BigDecimal countDecimal = new BigDecimal(buyCount);
+        BigDecimal perPrice = totalPrice.divide(countDecimal, 2, RoundingMode.DOWN);
+        BigDecimal lastPrice = totalPrice.subtract(perPrice.multiply(countDecimal.subtract(BigDecimal.ONE)));
+        for (int i = 0; i < buyCount; i++) {
             String code = UniqueRandomNumGenerator.generateUniqueCode(12);
             OrderCouponMiddle orderCouponMiddle = new OrderCouponMiddle();
             // 订单id
@@ -725,29 +746,20 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
             // 团购/代金券 code
             orderCouponMiddle.setCouponCode(code);
             // 团购/代金券价格
-            if(i == lifeUserOrderDto.getCount() - 1){
-                orderCouponMiddle.setPrice(new BigDecimal(lifeUserOrderDto.getFinalPrice()).subtract(sumPrice).setScale(2,RoundingMode.DOWN));
-            } else {
-                BigDecimal divide = new BigDecimal(lifeUserOrderDto.getFinalPrice()).divide(new BigDecimal(lifeUserOrderDto.getCount()), 2, RoundingMode.DOWN);
-                orderCouponMiddle.setPrice(divide);
-                sumPrice = sumPrice.add(divide);
-            }
+            orderCouponMiddle.setPrice(i == buyCount - 1 ? lastPrice : perPrice);
             // 订单状态
             orderCouponMiddle.setStatus(0);
             orderCouponMiddleService.save(orderCouponMiddle);
-            // 使用时间
-            // 退款时间
-            // 删除标记
         }
         //4. 代金券/团购库存扣除 coupon_type 1 代金券 2团购
         int successful = 0;
         if(lifeUserOrderDto.getCouponType() == 2){
             // 团购库存扣除
             successful = lifeGroupBuyMainMapper.update(null, new UpdateWrapper<LifeGroupBuyMain>()
-                    .eq("id", lifeUserOrderDto.getCouponId()).setSql("inventory_num = inventory_num - " + lifeUserOrderDto.getCount()));
+                    .eq("id", lifeUserOrderDto.getCouponId()).ge("inventory_num",lifeUserOrderDto.getCount()).setSql("inventory_num = inventory_num - " + lifeUserOrderDto.getCount()));
         } else {
             successful = lifeCouponMapper.update(null, new UpdateWrapper<LifeCoupon>()
-                    .eq("id", lifeUserOrderDto.getCouponId()).setSql("stock_qty = stock_qty - " + lifeUserOrderDto.getCount()));
+                    .eq("id", lifeUserOrderDto.getCouponId()).ge("single_qty",lifeUserOrderDto.getCount()).setSql("single_qty = single_qty - " + lifeUserOrderDto.getCount()));
         }
         if(successful == 0){
             log.error("库存不足");
@@ -776,7 +788,6 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
         UpdateWrapper<OrderCouponMiddle> orderCouponMiddleUpdateWrapper = new UpdateWrapper<>();
         orderCouponMiddleUpdateWrapper.eq("order_id",lifeUserOrderDto.getId());
         // 根据状态判断怎么更新数据 目前只进行已支付,已取消,已过期判断
-        // TODO 后续再进行已核销和已退款判断 ()
         switch (lifeUserOrderDto.getStatus()){
             case 1:
                 lifeUserOrder.setPayTime(date);
@@ -793,7 +804,21 @@ public class LifeUserOrderService extends ServiceImpl<LifeUserOrderMapper, LifeU
                 orderCouponMiddleUpdateWrapper.set("status",lifeUserOrderDto.getStatus());
                 break;
         }
-        return this.saveOrUpdate(lifeUserOrder) && orderCouponMiddleService.update(orderCouponMiddleUpdateWrapper);
+        // 查询券id->查询一个
+        int updateNum = orderCouponMiddleMapper.update(null, orderCouponMiddleUpdateWrapper);
+        if(1 != lifeUserOrderDto.getStatus()) {
+            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(new QueryWrapper<OrderCouponMiddle>().eq("order_id", lifeUserOrderDto.getId()));
+            if (0 != updateNum && orderCouponMiddles.size() > 0) {
+                Integer couponId = orderCouponMiddles.get(0).getCouponId();
+                // 2.过期后更新库存
+                Integer couponType = lifeUserOrder.getCouponType();
+                restoreInventory(couponType, updateNum, couponId);
+            } else {
+                log.error("取消失败,未查询到订单");
+                throw new RuntimeException("取消失败,未查询到订单");
+            }
+        }
+        return this.saveOrUpdate(lifeUserOrder);
     }
 
     /**

+ 13 - 1
alien-store/src/main/java/shop/alien/store/service/LifeUserService.java

@@ -53,6 +53,8 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
 
     private final WebSocketProcess webSocketProcess;
 
+    private final ActivityInviteConfigService activityInviteConfigService;
+
     @Value("${jwt.expiration-time}")
     private String effectiveTime;
 
@@ -136,7 +138,7 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
         return voList;
     }
 
-    public LifeUserVo userLogin(String phoneNum) {
+    public LifeUserVo userLogin(String phoneNum, String inviteCode) {
         LifeUser user = getUserByPhone(phoneNum);
         if (user == null) {
             LifeUser lifeUser = new LifeUser();
@@ -158,6 +160,11 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
                 String token = getToken(phoneNum, userVo.getUserName(), tokenMap);
                 userVo.setToken(token);
                 baseRedisService.setString("user_" + phoneNum, token);
+
+                // 生成邀请记录
+                if(StringUtils.isNotEmpty(inviteCode)){
+                    activityInviteConfigService.bindInviteCode(lifeUser.getId(), inviteCode);
+                }
                 return userVo;
             } else {
                 return null;
@@ -173,6 +180,11 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
             String token = getToken(phoneNum, user.getUserName(), tokenMap);
             userVo.setToken(token);
             baseRedisService.setString("user_" + phoneNum, token);
+            if(StringUtils.isNotEmpty(inviteCode)){
+                // 生成邀请记录
+                activityInviteConfigService.bindInviteCode(user.getId(), inviteCode);
+            }
+
             return userVo;
         }
     }

+ 7 - 3
alien-store/src/main/java/shop/alien/store/service/LifeUserStoreService.java

@@ -4,15 +4,17 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.vo.LifeUserDynamicsVo;
 import shop.alien.entity.store.vo.StoreInfoVo;
-import shop.alien.store.config.GaoDeMapUtil;
 import shop.alien.mapper.*;
+import shop.alien.store.config.GaoDeMapUtil;
 import shop.alien.util.common.DistanceUtil;
+import shop.alien.util.common.ListToPage;
 import shop.alien.util.common.UniqueRandomNumGenerator;
 import shop.alien.util.common.constant.DiscountCouponEnum;
 
@@ -152,6 +154,8 @@ public class LifeUserStoreService {
                 storeMap.put("entranceImage", store.getEntranceImage());
                 // 添加门店图片
                 storeMap.put("storeImage", store.getImgUrl());
+                // 添加门店简介
+                storeMap.put("storeBlurb",store.getStoreBlurb());
                 // 解析并添加门店经纬度
                 String[] position = store.getStorePosition().split(",");
                 storeMap.put("longitude", position.length == 2 ? position[0] : "");
@@ -209,9 +213,9 @@ public class LifeUserStoreService {
 
             returnMaps = returnMaps.stream().sorted(Comparator.comparingDouble(storeMap -> Double.parseDouble( storeMap.get("avgScore").toString()) * -1)).collect(Collectors.toList());
             //returnMaps.sort(Collections.reverseOrder());
-
+            IPage<Map<String, Object>> mapIPage = ListToPage.setPage(returnMaps, page, size);
             // 返回最终结果列表
-            return returnMaps;
+            return mapIPage.getRecords();
         } catch (Exception e) {
             // 捕获并抛出运行时异常
             throw new RuntimeException(e);

+ 1 - 1
alien-store/src/main/java/shop/alien/store/service/StoreClockInService.java

@@ -20,7 +20,7 @@ public interface StoreClockInService extends IService<StoreClockIn> {
 
     StoreClockIn addStoreClockIn(StoreClockIn storeClockIn);
 
-    IPage<StoreClockInVo> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf);
+    IPage<StoreClockInVo> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf,Integer storeId);
 
     int deleteClockIn(Integer id);
 

+ 1 - 1
alien-store/src/main/java/shop/alien/store/service/StoreCommentService.java

@@ -33,7 +33,7 @@ public interface StoreCommentService extends IService<StoreComment> {
      * @param userType     评论的用户类型(0:商家, 其他:用户)
      * @return IPage<StoreComment>
      */
-    IPage<StoreCommentVo> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType);
+    IPage<StoreCommentVo> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType, Integer tagId);
 
     /**
      * 获取最新一条评论/评价

+ 17 - 0
alien-store/src/main/java/shop/alien/store/service/StoreCustomerServiceService.java

@@ -1,8 +1,12 @@
 package shop.alien.store.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.AiIntelligentAssistant;
 import shop.alien.entity.store.StoreCustomerService;
 
+import java.util.List;
+
 /**
  * <p>
  * 门店客服 服务类
@@ -15,4 +19,17 @@ public interface StoreCustomerServiceService extends IService<StoreCustomerServi
 
     StoreCustomerService getByQuestion(String question);
 
+    StoreCustomerService saveStoreCustomerService(StoreCustomerService storeCustomerService);
+
+    void delStoreCustomerService(String id);
+
+    IPage<StoreCustomerService> getStoreCustomerServicePage(int page, int size, String question, String type);
+
+    StoreCustomerService getById(String id);
+
+    List<StoreCustomerService> getRandList(String type,Integer limit);
+
+    List<AiIntelligentAssistant> saveAiIntelligentAssistant(List<AiIntelligentAssistant> aiIntelligentAssistants);
+
+    List<AiIntelligentAssistant> selectAiIntelligentAssistant(String userId,String time,Integer talkSource);
 }

+ 0 - 10
alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.multipart.MultipartRequest;
-import shop.alien.entity.result.R;
 import shop.alien.entity.store.StoreBusinessInfo;
 import shop.alien.entity.store.StoreImg;
 import shop.alien.entity.store.StoreInfo;
@@ -53,15 +52,6 @@ public interface StoreInfoService extends IService<StoreInfo> {
     StoreMainInfoVo getStoreInfo(Integer id);
 
     /**
-     * 门店关联门店用户
-     *
-     * @param storeName 门店名称
-     * @param id        门店id
-     * @return List<StoreInfoVo>
-     */
-    List<StoreInfoVo> getStoreInfoVo(String storeName, Integer id);
-
-    /**
      * web-分页查询店铺信息
      *
      * @param page         页码

+ 17 - 0
alien-store/src/main/java/shop/alien/store/service/UserPointService.java

@@ -0,0 +1,17 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.UserPoint;
+
+/**
+ * @author zhangchen
+ * @version 1.0
+ * @date 2025/09/05 10:00
+ */
+public interface UserPointService extends IService<UserPoint> {
+    UserPoint getPoint(Integer userId);
+
+    UserPoint addPoint(Integer userId, Integer point);
+
+    UserPoint getUserPointDetails(Integer userId);
+}

+ 296 - 0
alien-store/src/main/java/shop/alien/store/service/impl/ActivityInviteConfigServiceImpl.java

@@ -0,0 +1,296 @@
+package shop.alien.store.service.impl;
+
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.store.*;
+import shop.alien.entity.store.vo.ActivityInviteConfigVo;
+import shop.alien.entity.store.vo.ActivityInviteInfoVo;
+import shop.alien.entity.store.vo.ActivityInviteLogVo;
+import shop.alien.mapper.ActivityInviteConfigMapper;
+import shop.alien.mapper.ActivityInviteLogMapper;
+import shop.alien.mapper.LifeUserMapper;
+import shop.alien.store.service.ActivityInviteConfigService;
+import shop.alien.store.service.UserPointService;
+import shop.alien.util.common.RandomCreateUtil;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ActivityInviteConfigServiceImpl extends ServiceImpl<ActivityInviteConfigMapper, ActivityInviteConfig> implements ActivityInviteConfigService {
+
+   private final UserPointService userPointService;
+
+   private final ActivityInviteConfigMapper activityInviteConfigMapper;
+
+   private final LifeUserMapper lifeUserMapper;
+
+   private final ActivityInviteLogMapper activityInviteLogMapper;
+
+    @Override
+    public ActivityInviteConfigVo createOrUpdateInviteActivity(ActivityInviteConfigVo activityInviteConfigVo) {
+
+        log.info("创建邀请活动开始执行,请求参数: {}", activityInviteConfigVo);
+        if(activityInviteConfigVo == null) {
+            log.error("创建邀请活动activityInviteConfigVo为空。");
+            activityInviteConfigVo = new ActivityInviteConfigVo();
+            activityInviteConfigVo.setErrorMessage("参数为空");
+            return activityInviteConfigVo;
+        }
+
+        ActivityInviteConfig activityInviteConfig = new ActivityInviteConfig();
+        if(activityInviteConfigVo.getId() == null) {
+            LambdaQueryWrapper<ActivityInviteConfig> activityInviteConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getDeleteFlag, 0);
+            int count = activityInviteConfigMapper.selectCount(activityInviteConfigLambdaQueryWrapper);
+            if(count > 0){
+                log.error("存在有效的邀请活动。");
+                activityInviteConfigVo = new ActivityInviteConfigVo();
+                activityInviteConfigVo.setErrorMessage("存在有效的邀请活动");
+                return activityInviteConfigVo;
+            }
+
+            BeanUtils.copyProperties(activityInviteConfigVo, activityInviteConfig);
+            int insertCount = activityInviteConfigMapper.insert(activityInviteConfig);
+            if(insertCount == 0){
+                //插入活动配置数据失败,返回
+                log.error("插入邀请活动配置数据失败, {}", activityInviteConfigVo);
+                activityInviteConfigVo.setErrorMessage("插入邀请活动配置数据失败");
+                return activityInviteConfigVo;
+            }
+        } else {
+            BeanUtils.copyProperties(activityInviteConfigVo, activityInviteConfig);
+            int updateCount = activityInviteConfigMapper.updateById(activityInviteConfig);
+            if(updateCount == 0){
+                //更新活动配置数据失败,返回
+                log.error("更新邀请活动配置数据失败, {}", activityInviteConfigVo);
+                activityInviteConfigVo.setErrorMessage("更新邀请活动配置数据失败");
+                return activityInviteConfigVo;
+            }
+        }
+
+        return activityInviteConfigVo;
+    }
+
+    @Override
+    public ActivityInviteConfigVo getInviteActivitySignInConfigById(Long id) {
+        ActivityInviteConfig activityInviteConfig = null;
+        if(id != null && id > 0){
+            activityInviteConfig = activityInviteConfigMapper.selectById(id);
+        } else {
+            LambdaQueryWrapper<ActivityInviteConfig> activityInviteConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getDeleteFlag, 0);
+            activityInviteConfigLambdaQueryWrapper.orderByDesc(ActivityInviteConfig::getCreatedTime);
+            List<ActivityInviteConfig> activityInviteConfigList = activityInviteConfigMapper.selectList(activityInviteConfigLambdaQueryWrapper);
+            if(CollectionUtils.isNotEmpty(activityInviteConfigList)){
+                activityInviteConfig = activityInviteConfigList.get(0);
+            }
+        }
+        ActivityInviteConfigVo activityInviteConfigVo = new ActivityInviteConfigVo();
+        if(activityInviteConfig != null){
+            BeanUtils.copyProperties(activityInviteConfig, activityInviteConfigVo);
+        }
+        return activityInviteConfigVo;
+    }
+
+    @Override
+    public IPage<ActivityInviteConfig> getInviteActivityConfigList(int pageNum, int pageSize, String createdTime, Integer activityType, Integer status) {
+        IPage<ActivityInviteConfig> iPage = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<ActivityInviteConfig> activityInviteConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        if(StringUtils.isNotBlank(createdTime)){
+            activityInviteConfigLambdaQueryWrapper.between(ActivityInviteConfig::getCreatedTime,createdTime + " 00:00:00", createdTime + " 23:59:59");
+        }
+        if(activityType != null) {
+            activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getActivityType, activityType);
+        }
+
+        if(status != null) {
+            activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getStatus, status);
+        }
+        activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getDeleteFlag, 0 );
+        return activityInviteConfigMapper.selectPage(iPage, activityInviteConfigLambdaQueryWrapper);
+    }
+
+    @Override
+    public boolean updateInviteActivityStatus(Integer id, Integer status) {
+        if(id == null || status == null){
+            return false;
+        }
+        ActivityInviteConfig activityInviteConfig = new ActivityInviteConfig();
+        activityInviteConfig.setId(id);
+        activityInviteConfig.setStatus(status);
+        int updateResult = activityInviteConfigMapper.updateById(activityInviteConfig);
+        return updateResult > 0;
+    }
+
+    @Override
+    public boolean deleteInviteActivity(Integer id) {
+        if(id != null){
+            int deleteResult =  activityInviteConfigMapper.deleteById(id);
+            if(deleteResult == 0){
+                return false;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public ActivityInviteInfoVo getInviteInfo(Integer userId) {
+        LifeUser lifeUser = lifeUserMapper.selectById(userId);
+        String inviteCode = "";
+
+        if(lifeUser != null && StringUtils.isNotBlank(lifeUser.getInviteCode())){
+            inviteCode = lifeUser.getInviteCode();
+        } else{
+            int count = 1;
+            while (count <= 5) {
+                count++;
+                inviteCode = RandomCreateUtil.getRandomNStr(6);
+                LambdaQueryWrapper<LifeUser> lifeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
+                lifeUserLambdaQueryWrapper.eq(LifeUser::getInviteCode, inviteCode);
+                lifeUserLambdaQueryWrapper.eq(LifeUser::getDeleteFlag, 0);
+                int repeatCount = lifeUserMapper.selectCount(lifeUserLambdaQueryWrapper);
+                if(repeatCount == 0) {
+                    LifeUser updateLifeUser = new LifeUser();
+                    updateLifeUser.setId(userId);
+                    updateLifeUser.setInviteCode(inviteCode);
+                    lifeUserMapper.updateById(updateLifeUser);
+                    break;
+                }
+            }
+        }
+
+        LambdaQueryWrapper<ActivityInviteLog> activityInviteLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        activityInviteLogLambdaQueryWrapper.eq(ActivityInviteLog::getInviteUserId, userId);
+        activityInviteLogLambdaQueryWrapper.eq(ActivityInviteLog::getDeleteFlag, 0);
+        List<ActivityInviteLog> activityInviteLogList = activityInviteLogMapper.selectList(activityInviteLogLambdaQueryWrapper);
+        int inviteCount = 0;
+        int invitePoint = 0;
+        if(CollectionUtils.isNotEmpty(activityInviteLogList)){
+            inviteCount = activityInviteLogList.size();
+            for(ActivityInviteLog activityInviteLog : activityInviteLogList){
+                int inviteRewardType = activityInviteLog.getInviteRewardType();
+                if(inviteRewardType == 2 && activityInviteLog.getInviteRewardPoint() != null){
+                    invitePoint = activityInviteLog.getInviteRewardPoint() + invitePoint;
+                }
+            }
+        }
+        ActivityInviteInfoVo activityInviteInfoVo = new ActivityInviteInfoVo();
+        activityInviteInfoVo.setInviteCode(inviteCode);
+        activityInviteInfoVo.setInviteCount(inviteCount);
+        activityInviteInfoVo.setInvitePoint(invitePoint);
+
+        return activityInviteInfoVo;
+    }
+
+    @Override
+    public IPage<ActivityInviteLogVo> getInviteActivityLogList(int pageNum, int pageSize, Integer userId, String invitePhone, String inviteStartTime, String inviteEndTime) {
+
+        IPage<ActivityInviteLogVo> iPage = new Page<>(pageNum, pageSize);
+        QueryWrapper<ActivityInviteLogVo> queryWrapper = new QueryWrapper<>();
+        if(userId != null) {
+            queryWrapper.eq("ail.invite_user_id", userId);
+        }
+        if(StringUtils.isNotBlank(invitePhone)) {
+            queryWrapper.eq("lu.user_phone", invitePhone);
+        }
+        if(StringUtils.isNotBlank(inviteStartTime) && StringUtils.isNotBlank(inviteEndTime) ) {
+            queryWrapper.between("ail.invite_time", inviteStartTime + " 00:00:00",inviteEndTime + " 23:59:59");
+        }
+
+        return activityInviteLogMapper.getInviteActivityLogList(iPage, queryWrapper);
+    }
+
+    @Override
+    public String bindInviteCode(Integer invitedUserId, String inviteCode) {
+        if(StringUtils.isNotBlank(inviteCode) && invitedUserId != null){
+            // 根据邀请码查询邀请用户
+            LambdaQueryWrapper<LifeUser> lifeUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            lifeUserLambdaQueryWrapper.eq(LifeUser::getInviteCode, inviteCode);
+            lifeUserLambdaQueryWrapper.eq(LifeUser::getDeleteFlag, 0);
+            List<LifeUser> lifeUserList = lifeUserMapper.selectList(lifeUserLambdaQueryWrapper);
+            if(CollectionUtils.isEmpty(lifeUserList)){
+                return "邀请码异常或邀请用户已注销";
+            }
+
+           LifeUser originalLifeUser =  lifeUserList.get(0);
+           int inviteUserId = originalLifeUser.getId();
+           LifeUser invitedLifeUser =  lifeUserMapper.selectById(invitedUserId);
+
+
+           if(invitedLifeUser == null){
+               return "被邀请用户异常";
+           } else if (StringUtils.isNotBlank(invitedLifeUser.getBindInviteCode())){
+               return "已经绑定邀请码不能重复绑定";
+           } else if (StringUtils.isNotBlank(invitedLifeUser.getInviteCode()) && invitedLifeUser.getInviteCode().equals(inviteCode)){
+               return "不能绑定自己的邀请码";
+           }else {
+               LambdaQueryWrapper<ActivityInviteConfig> activityInviteConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
+               activityInviteConfigLambdaQueryWrapper.eq(ActivityInviteConfig::getDeleteFlag,0);
+               List<ActivityInviteConfig> activityInviteConfigList = activityInviteConfigMapper.selectList(activityInviteConfigLambdaQueryWrapper);
+               if(CollectionUtils.isNotEmpty(activityInviteConfigList)){
+                   ActivityInviteConfig activityInviteConfig = activityInviteConfigList.get(0);
+
+                   // 判断是否达到当天邀请最大次数
+                   Integer maxInviteNum = activityInviteConfig.getMaxInviteNum();
+                   if(maxInviteNum != null){
+                       LambdaQueryWrapper<ActivityInviteLog> activityInviteLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
+                       activityInviteLogLambdaQueryWrapper.eq(ActivityInviteLog::getInviteUserId, inviteUserId);
+                       activityInviteLogLambdaQueryWrapper.eq(ActivityInviteLog::getDeleteFlag, 0);
+                       String today = LocalDate.now().toString();
+                       activityInviteLogLambdaQueryWrapper.between(ActivityInviteLog::getInviteTime, today + " 00:00:00", today + " 23:59:59");
+                       int todayInviteCount = activityInviteLogMapper.selectCount(activityInviteLogLambdaQueryWrapper);
+                       if(todayInviteCount > maxInviteNum){
+                           return "绑定数量已超过当天最大绑定数量";
+                       }
+                   }
+
+                   ActivityInviteLog activityInviteLog = new ActivityInviteLog();
+                   activityInviteLog.setInviteUserId(inviteUserId);
+                   activityInviteLog.setInvitedUserId(invitedUserId);
+                   activityInviteLog.setActivityId(activityInviteConfig.getId());
+
+                   // 邀请奖励
+                   activityInviteLog.setInviteRewardType(activityInviteConfig.getInviteRewardType());
+                   activityInviteLog.setInviteRewardCoupon(activityInviteConfig.getInviteRewardCoupon());
+                   activityInviteLog.setInviteRewardPoint(activityInviteConfig.getInviteRewardPoint());
+                   // 被邀请奖励
+                   activityInviteLog.setInvitedRewardType(activityInviteConfig.getInvitedRewardType());
+                   activityInviteLog.setInvitedRewardCoupon(activityInviteConfig.getInvitedRewardCoupon());
+                   activityInviteLog.setInvitedRewardPoint(activityInviteConfig.getInvitedRewardPoint());
+                   activityInviteLog.setInviteTime(Date.from(Instant.now()));
+                   activityInviteLogMapper.insert(activityInviteLog);
+
+                   if(activityInviteConfig.getInviteRewardType() == 2){
+                       userPointService.addPoint(inviteUserId, activityInviteConfig.getInviteRewardPoint());
+                   }
+                   if(activityInviteConfig.getInvitedRewardType() == 2){
+                       userPointService.addPoint(invitedUserId, activityInviteConfig.getInvitedRewardPoint());
+                   }
+
+                   LifeUser updateLifeUser = new LifeUser();
+                   updateLifeUser.setId(invitedLifeUser.getId());
+                   updateLifeUser.setBindInviteCode(inviteCode);
+                   lifeUserMapper.updateById(updateLifeUser);
+                   return "绑定成功";
+               } else {
+                   return "活动未开始或已结束";
+               }
+           }
+        }
+        return "参数异常";
+    }
+}

+ 107 - 70
alien-store/src/main/java/shop/alien/store/service/impl/LifeCouponServiceImpl.java

@@ -1,5 +1,6 @@
 package shop.alien.store.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -17,6 +18,7 @@ import shop.alien.entity.store.*;
 import shop.alien.entity.store.dto.LifeDiscountCouponStoreFriendDto;
 import shop.alien.entity.store.vo.LifeCouponStatusVo;
 import shop.alien.mapper.*;
+import shop.alien.store.config.BaseRedisService;
 import shop.alien.store.service.LifeCouponService;
 import shop.alien.store.service.LifeDiscountCouponStoreFriendService;
 import shop.alien.util.common.UniqueRandomNumGenerator;
@@ -61,6 +63,7 @@ public class LifeCouponServiceImpl extends ServiceImpl<LifeCouponMapper, LifeCou
 
     private final StoreInfoMapper storeInfoMapper;
 
+    private final BaseRedisService baseRedisService;
 
     @Override
     public LifeCoupon addOrUpdateCoupon(LifeCoupon lifeCoupon) {
@@ -134,6 +137,11 @@ public class LifeCouponServiceImpl extends ServiceImpl<LifeCouponMapper, LifeCou
         wrapper.eq(LifeCoupon::getDataType, dataType);
         wrapper.orderByDesc(LifeCoupon::getCreatedTime);
         IPage<LifeCoupon> lifeCouponIPage = new Page<>(page, size);
+        //如果singleQty 库存的数量<=0,则修改status状态为已售罄 状态为4
+        LifeCoupon lifeCouponNew = new LifeCoupon();
+        lifeCouponNew.setStoreId(storeId);
+        lifeCouponNew.setStatus(4);
+        lifeCouponMapper.update(lifeCouponNew, new LambdaUpdateWrapper<LifeCoupon>().eq(LifeCoupon::getSingleQty, 0));
         return lifeCouponMapper.selectPage(lifeCouponIPage, wrapper);
     }
 
@@ -233,77 +241,85 @@ public class LifeCouponServiceImpl extends ServiceImpl<LifeCouponMapper, LifeCou
     @Transactional(rollbackFor = Exception.class)
     public Map<String, String> newCouponVerify(String storeId, String quanCode) {
         Map<String, String> resultMap = new HashMap<>();
-        OrderCouponMiddle orderCouponMiddle = orderCouponMiddleMapper.selectOne(new LambdaQueryWrapper<OrderCouponMiddle>().eq(OrderCouponMiddle::getCouponCode, quanCode));
-        if (!StringUtils.isEmpty(orderCouponMiddle)) {
-            LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectOne(new LambdaQueryWrapper<LifeUserOrder>().eq(LifeUserOrder::getId, orderCouponMiddle.getOrderId()));
-            orderCouponMiddle.setStatus(OrderStatusEnum.USED.getStatus());
-            orderCouponMiddle.setUsedTime(new Date());
-            orderCouponMiddleMapper.updateById(orderCouponMiddle);
-            //通过订单id查询中间表 如果该订单下所有劵都为已核销状态更改订单表状态为已核销
-            List<OrderCouponMiddle> couponMiddleList = orderCouponMiddleMapper.selectList(new LambdaQueryWrapper<OrderCouponMiddle>()
-                    .eq(OrderCouponMiddle::getOrderId, lifeUserOrder.getId()));
-            // 排除要核销的券的 所以券状态
-            boolean isExist = couponMiddleList.stream().filter(x -> x.getId() != orderCouponMiddle.getId())
-                    .allMatch(str -> str.getStatus() == OrderStatusEnum.USED.getStatus());
-            if (isExist) {
-                lifeUserOrder.setStatus(OrderStatusEnum.USED.getStatus());
-                lifeUserOrder.setFinishTime(new Date());
-                lifeUserOrder.setCreatedTime(new Date());
-                lifeUserOrderMapper.updateById(lifeUserOrder);
-
-                //发放好友优惠券
-                LifeDiscountCouponStoreFriendDto lifeDiscountCouponStoreFriendDto = new LifeDiscountCouponStoreFriendDto();
-                lifeDiscountCouponStoreFriendDto.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
-                lifeDiscountCouponStoreFriendService.issueFriendCoupon(lifeDiscountCouponStoreFriendDto);
-            }
-            // TODO  订单状态 -> 变已完成 筛选出未完成的状态
-            List<OrderCouponMiddle> collect = couponMiddleList.stream().filter(x -> x.getId() != orderCouponMiddle.getId())
-                    .filter(x -> x.getStatus() != OrderStatusEnum.WAIT_USE.getStatus() && x.getStatus() != OrderStatusEnum.REFUND_FAILED.getStatus())
-                    .collect(Collectors.toList());
-            if (collect.size() == 0) {
-                lifeUserOrder.setStatus(OrderStatusEnum.COMPLETE.getStatus());
-                lifeUserOrder.setFinishTime(new Date());
-                lifeUserOrder.setCreatedTime(new Date());
-                lifeUserOrderMapper.updateById(lifeUserOrder);
-
-                //发放好友优惠券
-                LifeDiscountCouponStoreFriendDto lifeDiscountCouponStoreFriendDto = new LifeDiscountCouponStoreFriendDto();
-                lifeDiscountCouponStoreFriendDto.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
-                lifeDiscountCouponStoreFriendService.issueFriendCoupon(lifeDiscountCouponStoreFriendDto);
-            }
-            // 计算总退款金额(orderCouponMiddle金额按实际的存)
-            BigDecimal refundAmount = couponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.REFUND.getStatus()).map(x -> x.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
-            StoreInfo storeInfo = storeInfoMapper.selectOne(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, lifeUserOrder.getStoreId()));
-            BigDecimal amounts = new BigDecimal(lifeUserOrder.getFinalPrice()).multiply(new BigDecimal(100)).subtract(refundAmount);
-            // 先将抽成比例转换为BigDecimal,再除以100
-            BigDecimal commissionRate = new BigDecimal(storeInfo.getCommissionRate())
-                    .divide(new BigDecimal(100));
-            // 感觉有问题。HALF_UP有问题。
-            BigDecimal commission = amounts.multiply(commissionRate).setScale(0, RoundingMode.HALF_UP);
-            BigDecimal money = amounts.subtract(commission);
-
-            // 插入收入明细表数据
-            StoreIncomeDetailsRecord record = new StoreIncomeDetailsRecord();
-            record.setStoreId(Integer.parseInt(storeId));
-            record.setUserOrderId(orderCouponMiddle.getId());
-            record.setIncomeType(lifeUserOrder.getCouponType());
-            record.setBusinessId(orderCouponMiddle.getCouponId());
-            record.setCommission(commission.intValue());
-            record.setMoney(money.intValue());
-            storeIncomeDetailsRecordMapper.insert(record);
-
-            // 店铺账户余额增加
-            UpdateWrapper<StoreUser> updateWrapper = new UpdateWrapper();
-            updateWrapper.eq("store_id", storeId);
-            updateWrapper.eq("delete_flag", 0);
-            updateWrapper.setSql("money = money + " + money);
-            storeUserMapper.update(null, updateWrapper);
-
-            resultMap.put("code", "true");
-            resultMap.put("message", "核销成功");
-        } else {
+        String lockKey = "coupon:use:" + quanCode;
+        if(baseRedisService.hasKey(lockKey)) {
             resultMap.put("code", "false");
-            resultMap.put("message", "核销失败");
+            resultMap.put("message", "请勿重复核销");
+            return resultMap;
+        };
+        baseRedisService.setListRight(lockKey, quanCode);
+        try {
+            OrderCouponMiddle orderCouponMiddle = orderCouponMiddleMapper.selectOne(new LambdaQueryWrapper<OrderCouponMiddle>().eq(OrderCouponMiddle::getCouponCode, quanCode).in(OrderCouponMiddle::getStatus,OrderStatusEnum.WAIT_USE.getStatus(),OrderStatusEnum.REFUND_FAILED.getStatus()));
+            if (!StringUtils.isEmpty(orderCouponMiddle)) {
+                // 查询总订单
+                LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectOne(new LambdaQueryWrapper<LifeUserOrder>().eq(LifeUserOrder::getId, orderCouponMiddle.getOrderId()));
+                orderCouponMiddle.setStatus(OrderStatusEnum.USED.getStatus());
+                orderCouponMiddle.setUsedTime(new Date());
+                orderCouponMiddleMapper.updateById(orderCouponMiddle);
+                //通过订单id查询中间表 如果该订单下所有劵都为已核销状态更改订单表状态为已核销
+                List<OrderCouponMiddle> couponMiddleList = orderCouponMiddleMapper.selectList(new LambdaQueryWrapper<OrderCouponMiddle>()
+                        .eq(OrderCouponMiddle::getOrderId, lifeUserOrder.getId()));
+                // 排除要核销的券的 所以券状态
+                boolean isExist = couponMiddleList.stream().allMatch(str -> str.getStatus() == OrderStatusEnum.USED.getStatus());
+                // 订单状态 -> 已完成 筛选出未完成的状态
+                List<OrderCouponMiddle> collect = couponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.WAIT_USE.getStatus() || x.getStatus() == OrderStatusEnum.REFUND_FAILED.getStatus())
+                        .collect(Collectors.toList());
+                if (isExist) {
+                    lifeUserOrder.setStatus(OrderStatusEnum.USED.getStatus());
+                    lifeUserOrder.setFinishTime(new Date());
+                    lifeUserOrder.setCreatedTime(new Date());
+                    lifeUserOrderMapper.updateById(lifeUserOrder);
+
+                    //发放好友优惠券
+                    LifeDiscountCouponStoreFriendDto lifeDiscountCouponStoreFriendDto = new LifeDiscountCouponStoreFriendDto();
+                    lifeDiscountCouponStoreFriendDto.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
+                    lifeDiscountCouponStoreFriendService.issueFriendCoupon(lifeDiscountCouponStoreFriendDto);
+                } else if (collect.size() == 0) {
+                    lifeUserOrder.setStatus(OrderStatusEnum.COMPLETE.getStatus());
+                    lifeUserOrder.setFinishTime(new Date());
+                    lifeUserOrder.setCreatedTime(new Date());
+                    lifeUserOrderMapper.updateById(lifeUserOrder);
+
+                    //发放好友优惠券
+                    LifeDiscountCouponStoreFriendDto lifeDiscountCouponStoreFriendDto = new LifeDiscountCouponStoreFriendDto();
+                    lifeDiscountCouponStoreFriendDto.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
+                    lifeDiscountCouponStoreFriendService.issueFriendCoupon(lifeDiscountCouponStoreFriendDto);
+                }
+                // 计算总退款金额(orderCouponMiddle金额按实际的存)
+//            BigDecimal refundAmount = couponMiddleList.stream().filter(x -> x.getStatus() == OrderStatusEnum.REFUND.getStatus()).map(x -> x.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                StoreInfo storeInfo = storeInfoMapper.selectOne(new LambdaQueryWrapper<StoreInfo>().eq(StoreInfo::getId, lifeUserOrder.getStoreId()));
+                // 先将抽成比例转换为BigDecimal,再除以100
+                BigDecimal commissionRate = new BigDecimal(storeInfo.getCommissionRate())
+                        .divide(new BigDecimal(100));
+                // 感觉有问题。HALF_UP有问题。 price 正常存储
+                BigDecimal commission = orderCouponMiddle.getPrice().multiply(new BigDecimal(100).multiply(commissionRate)).setScale(2, RoundingMode.HALF_UP);
+                BigDecimal money = orderCouponMiddle.getPrice().multiply(new BigDecimal(100)).subtract(commission);
+
+                // 插入收入明细表数据
+                StoreIncomeDetailsRecord record = new StoreIncomeDetailsRecord();
+                record.setStoreId(Integer.parseInt(storeId));
+                record.setUserOrderId(orderCouponMiddle.getId());
+                record.setIncomeType(lifeUserOrder.getCouponType());
+                record.setBusinessId(orderCouponMiddle.getCouponId());
+                record.setCommission(commission.intValue());
+                record.setMoney(money.intValue());
+                storeIncomeDetailsRecordMapper.insert(record);
+
+                // 店铺账户余额增加
+                UpdateWrapper<StoreUser> updateWrapper = new UpdateWrapper();
+                updateWrapper.eq("store_id", storeId);
+                updateWrapper.eq("delete_flag", 0);
+                updateWrapper.setSql("money = money + " + money);
+                storeUserMapper.update(null, updateWrapper);
+
+                resultMap.put("code", "true");
+                resultMap.put("message", "核销成功");
+            } else {
+                resultMap.put("code", "false");
+                resultMap.put("message", "核销失败");
+            }
+        } finally {
+            baseRedisService.delete(lockKey);
         }
         return resultMap;
     }
@@ -581,6 +597,27 @@ public class LifeCouponServiceImpl extends ServiceImpl<LifeCouponMapper, LifeCou
                 return R.fail("该劵在不可用日期内");
             }
         }
+        // 判断是否在使用时间内
+        Integer buyUseStartTime = Integer.parseInt(lifeCoupon.getBuyUseStartTime());
+        Integer buyUseEndTime = Integer.parseInt(lifeCoupon.getBuyUseEndTime());
+        // 获取当前小时
+        LocalTime now = LocalTime.now();
+        int currentHour = now.getHour();
+        // 验证输入的小时是否有效
+        if (buyUseStartTime < 0 || buyUseStartTime > 23 || buyUseEndTime < 0 || buyUseEndTime > 23) {
+            throw new IllegalArgumentException("小时必须在0-23之间");
+        }
+        // 处理跨天的情况,例如22点到次日3点
+        if (buyUseStartTime >= buyUseEndTime) {
+            if(currentHour<buyUseStartTime &&  currentHour>buyUseEndTime) {
+                return R.fail("该劵不在有效期内");
+            }
+
+        } else {
+            if (!(currentHour >= buyUseStartTime && currentHour <= buyUseEndTime)) {
+                return R.fail("该劵不在有效期内");
+            }
+        }
         return R.success("效验通过");
     }
 

+ 40 - 11
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
+import org.apache.poi.util.StringUtil;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.stereotype.Service;
@@ -346,7 +347,7 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
         List<LifeDiscountCouponVo> lifeDiscountCouponVos = new ArrayList<>();
         //根据店铺id查询该店铺的优惠券,状态是开启领取的券
         List<LifeDiscountCoupon> lifeDiscountCoupons = lifeDiscountCouponMapper.selectList(new LambdaQueryWrapper<LifeDiscountCoupon>().eq(LifeDiscountCoupon::getStoreId, storeId).eq(LifeDiscountCoupon::getGetStatus, "1").gt(LifeDiscountCoupon::getSingleQty, 0) //还有库存
-                .ge(LifeDiscountCoupon::getEndGetDate, new Date()).orderByDesc(LifeDiscountCoupon::getCreatedTime));
+                .gt(LifeDiscountCoupon::getEndGetDate, new Date()).orderByDesc(LifeDiscountCoupon::getCreatedTime));
         //根据优惠券列表查询该优惠券是否领取过
         for (LifeDiscountCoupon lifeDiscountCoupon : lifeDiscountCoupons) {
             LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
@@ -456,7 +457,11 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
             //查询该优惠券属于哪个店铺
             LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectById(lifeDiscountCouponUser.getCouponId());
             String couponStoreId = lifeDiscountCoupon.getStoreId();
-            if (couponStoreId.equals(storeId)) {
+            if (null != couponStoreId && couponStoreId.equals(storeId)) {
+                lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
+            }
+            //平台优惠券
+            if (3 == lifeDiscountCoupon.getType()) {
                 lifeDiscountCouponUsers.add(lifeDiscountCouponUser);
             }
         }
@@ -665,14 +670,19 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
         //优惠券的所有门店
         List<String> storeIdList = lifeDiscountCoupons.stream().map(LifeDiscountCoupon::getStoreId).collect(Collectors.toList());
         List<StoreInfo> storeInfoList = storeInfoMapper.getList(new LambdaQueryWrapper<StoreInfo>().in(!storeIdList.isEmpty(), StoreInfo::getId, storeIdList));
-        if (storeInfoList.isEmpty()) {
+        if (storeInfoList.isEmpty() && lifeDiscountCouponUserIPage.getRecords().isEmpty()) {
             return lifeDiscountCouponVos;
         }
         for (LifeDiscountCouponUser lifeDiscountCouponUser : lifeDiscountCouponUserIPage.getRecords()) {
             LifeDiscountCoupon lifeDiscountCouponOne = lifeDiscountCoupons.stream().filter(lifeDiscountCoupon -> lifeDiscountCoupon.getId().equals(lifeDiscountCouponUser.getCouponId())).collect(Collectors.toList()).get(0);
-            StoreInfo storeInfoOne = storeInfoList.stream().filter(storeInfo -> storeInfo.getId().toString().equals(lifeDiscountCouponOne.getStoreId())).collect(Collectors.toList()).get(0);
+            StoreInfo storeInfoOne = null;
+            if (!storeInfoList.isEmpty() && !StringUtils.isEmpty(lifeDiscountCouponOne.getStoreId())) {
+                storeInfoOne = storeInfoList.stream().filter(storeInfo -> storeInfo.getId().toString().equals(lifeDiscountCouponOne.getStoreId())).collect(Collectors.toList()).get(0);
+            }
             LifeDiscountCouponVo lifeDiscountCouponVo = new LifeDiscountCouponVo();
-            lifeDiscountCouponVo.setBusinessSection(storeInfoOne.getBusinessSection());
+            if (null != storeInfoOne) {
+                lifeDiscountCouponVo.setBusinessSection(storeInfoOne.getBusinessSection());
+            }
             lifeDiscountCouponVo.setCouponId(lifeDiscountCouponOne.getId());
             BeanUtils.copyProperties(lifeDiscountCouponOne, lifeDiscountCouponVo);
             lifeDiscountCouponVo.setQuantityClaimed(lifeDiscountCouponUserIPage.getRecords().size());
@@ -691,7 +701,7 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
 
             // 判断是否到了优惠券的开始时间
             lifeDiscountCouponVo.setReachUseTimeFlag(1);
-            if (localNow1.isBefore(lifeDiscountCouponOne.getBeginGetDate())) {
+            if (null != lifeDiscountCouponOne.getBeginGetDate() && localNow1.isBefore(lifeDiscountCouponOne.getBeginGetDate())) {
                 lifeDiscountCouponVo.setReachUseTimeFlag(0);
             }
             lifeDiscountCouponVos.add(lifeDiscountCouponVo);
@@ -727,6 +737,7 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
                 lifeDiscountCouponLambdaQueryWrapper.le(LifeDiscountCoupon::getBeginGetDate, getPureDate(now));
                 //结束时间大于当前时间
                 lifeDiscountCouponLambdaQueryWrapper.ge(LifeDiscountCoupon::getEndGetDate, getPureDate(now));
+                lifeDiscountCouponLambdaQueryWrapper.gt(LifeDiscountCoupon::getSingleQty, 0);
 
                 //不要已暂停关闭领取的
                 lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getGetStatus, 1);
@@ -755,10 +766,10 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
                     //如果当前时间小于开始时间
                     if (lifeDiscountCoupon.getSingleQty() == null || lifeDiscountCoupon.getSingleQty() == 0) {//无库存则已售罄
                         lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_SOLD_OUT.getValue()));
-                    } else if (lifeDiscountCoupon.getGetStatus() == null || lifeDiscountCoupon.getGetStatus().toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
-                        lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue()));
                     } else if (startResult < 0) {
                         lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_NOT_STARTED.getValue()));
+                    } else if (lifeDiscountCoupon.getGetStatus() == null || lifeDiscountCoupon.getGetStatus().toString().equals(DiscountCouponEnum.NO_GET.getValue())) {
+                        lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.SUSPEND_GET.getValue()));
                     } else if (endResult > 0) {
                         lifeDiscountCouponVo.setStatus(Integer.parseInt(DiscountCouponEnum.FINISHED.getValue()));
                     } else if (startResult >= 0 && endResult <= 0) {
@@ -1083,8 +1094,14 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
      */
     @Override
     public boolean addPlatformCoupon(LifeDiscountCoupon lifeDiscountCoupon) {
+        lifeDiscountCoupon.setStartDate(LocalDate.now());
+        if (null == lifeDiscountCoupon.getSpecifiedDay()) {
+            return false;
+        }
+        lifeDiscountCoupon.setEndDate(LocalDate.now().plusDays(Long.parseLong(lifeDiscountCoupon.getSpecifiedDay())));
         lifeDiscountCoupon.setType(3);
         lifeDiscountCoupon.setGetStatus(1);
+//        lifeDiscountCoupon.setMinimumSpendingAmount(BigDecimal.ZERO);
         return this.save(lifeDiscountCoupon);
     }
 
@@ -1115,7 +1132,7 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
             lifeDiscountCouponUser.setUserId(userId);
             lifeDiscountCouponUser.setCouponId(couponId);
             lifeDiscountCouponUser.setReceiveTime(new Date());
-            lifeDiscountCouponUser.setExpirationTime(lifeDiscountCoupon.getEndDate());
+            lifeDiscountCouponUser.setExpirationTime(LocalDate.now().plusDays(Long.parseLong(lifeDiscountCoupon.getSpecifiedDay())));
             lifeDiscountCouponUser.setStatus(0);
             lifeDiscountCouponUser.setDeleteFlag(0);
             lifeDiscountCouponUser.setCreatedTime(new Date());
@@ -1132,7 +1149,7 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
      */
     @Override
     public boolean recoverPlatformCoupon(Integer couponId) {
-        return lifeDiscountCouponUserService.remove(new LambdaQueryWrapper<LifeDiscountCouponUser>().eq(LifeDiscountCouponUser::getCouponId, couponId)) && this.updateById(new LifeDiscountCoupon().setId(couponId).setGetStatus(0));
+        return lifeDiscountCouponUserService.remove(new LambdaQueryWrapper<LifeDiscountCouponUser>().eq(LifeDiscountCouponUser::getCouponId, couponId));
     }
 
     /**
@@ -1170,5 +1187,17 @@ public class LifeDiscountCouponServiceImpl extends ServiceImpl<LifeDiscountCoupo
                 .like(!StringUtils.isEmpty(phone), "b.user_phone", phone));
     }
 
-
+    @Override
+    public List<LifeDiscountCoupon> getPlatformCoupon(Integer couponId, Integer couponType) {
+        LambdaQueryWrapper<LifeDiscountCoupon> lifeDiscountCouponLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        if (couponId != null) {
+            lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getId, couponId);
+        }
+        if (couponType != null) {
+            lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getType, couponType);
+        }
+        lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getDeleteFlag, 0);
+        lifeDiscountCouponLambdaQueryWrapper.eq(LifeDiscountCoupon::getGetStatus, 1);
+        return lifeDiscountCouponMapper.selectList(lifeDiscountCouponLambdaQueryWrapper);
+    }
 }

+ 226 - 103
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponStoreFriendServiceImpl.java

@@ -1,7 +1,9 @@
 package shop.alien.store.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
@@ -10,17 +12,21 @@ import org.springframework.beans.BeansException;
 import org.springframework.stereotype.Service;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.dto.LifeDiscountCouponStoreFriendDto;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleDetailVo;
+import shop.alien.entity.store.vo.LifeDiscountCouponFriendRuleVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponStoreFriendVo;
 import shop.alien.entity.store.vo.LifeDiscountCouponVo;
 import shop.alien.mapper.*;
 import shop.alien.store.service.LifeDiscountCouponStoreFriendService;
 import shop.alien.util.common.constant.DiscountCouponEnum;
 
+import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -56,6 +62,10 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
 
     private final LifeNoticeMapper lifeNoticeMapper;
 
+    private final LifeDiscountCouponFriendRuleMapper lifeDiscountCouponFriendRuleMapper;
+
+    private final LifeDiscountCouponFriendRuleDetailMapper lifeDiscountCouponFriendRuleDetailMapper;
+
     @Override
     public List<LifeDiscountCouponStoreFriendVo> getFriendCouponList(UserLoginInfo userLoginInfo, String friendUserId) {
         List<LifeDiscountCouponStoreFriendVo> result = new ArrayList<>();
@@ -201,122 +211,146 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
     @Override
     public List<LifeDiscountCouponStoreFriendVo> issueFriendCoupon(LifeDiscountCouponStoreFriendDto lifeDiscountCouponStoreFriendDto) {
 
+        // 用于存储最终成功发放的优惠券信息的列表
+        List<LifeDiscountCouponStoreFriendVo> result = new ArrayList<>();
+
         //判断该订单是否已经发放过好友店铺优惠券
         LifeUserOrder lifeUserOrder = lifeUserOrderMapper.selectById(lifeDiscountCouponStoreFriendDto.getOrderId());
         if (lifeUserOrder.getSendDiscountCouponFlag() == 1) {
             throw new RuntimeException("已发放优惠券");
         }
+
+        //送券规则
+        List<Integer> couponList = new ArrayList<>();
+        LambdaQueryWrapper<LifeDiscountCouponFriendRule> ruleLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        ruleLambdaQueryWrapper.eq(LifeDiscountCouponFriendRule::getStoreId, lifeUserOrder.getStoreId())
+                .eq(LifeDiscountCouponFriendRule::getDeleteFlag, 0);
+        List<LifeDiscountCouponFriendRule> lifeDiscountCouponFriendRules = lifeDiscountCouponFriendRuleMapper.selectList(ruleLambdaQueryWrapper);
+        lifeDiscountCouponFriendRules = lifeDiscountCouponFriendRules.stream().filter(i -> i.getMoneyLow().compareTo(new BigDecimal(lifeUserOrder.getFinalPrice())) <= 0 && i.getMoneyHigh().compareTo(new BigDecimal(lifeUserOrder.getFinalPrice())) >= 0).collect(Collectors.toList());
+        if (ObjectUtils.isNotEmpty(lifeDiscountCouponFriendRules)) {
+            LambdaQueryWrapper<LifeDiscountCouponFriendRuleDetail> detailLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            detailLambdaQueryWrapper.in(LifeDiscountCouponFriendRuleDetail::getRuleId, lifeDiscountCouponFriendRules.stream().map(LifeDiscountCouponFriendRule::getId).collect(Collectors.toList()));
+            List<LifeDiscountCouponFriendRuleDetail> lifeDiscountCouponFriendRuleDetails = lifeDiscountCouponFriendRuleDetailMapper.selectList(detailLambdaQueryWrapper);
+            couponList = lifeDiscountCouponFriendRuleDetails.stream().map(LifeDiscountCouponFriendRuleDetail::getCouponId).collect(Collectors.toList());
+        }
+
+
         lifeUserOrder.setSendDiscountCouponFlag(1);
         lifeUserOrderMapper.updateById(lifeUserOrder);
 
-        // 用于存储最终成功发放的优惠券信息的列表
-        List<LifeDiscountCouponStoreFriendVo> result = new ArrayList<>();
-
-        // 获取当前消费用户的ID
-        int userId = Integer.parseInt(lifeUserOrder.getUserId());
-        LifeUser lifeUser = lifeUserMapper.selectById(userId);
-        // 从传入的DTO对象中获取店铺ID
-        StoreUser storeUser =
-                storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, lifeUserOrder.getStoreId()));
-        Integer storeUserId = storeUser.getId();
-        Integer storeId = storeUser.getStoreId();
-        StoreInfo storeInfo = storeInfoMapper.selectById(storeUser.getStoreId());
-
-        // 根据店铺ID从数据库中查询该店铺为好友设定的所有优惠券信息
-        List<LifeDiscountCouponStoreFriend> lifeDiscountCouponStoreFriends = lifeDiscountCouponStoreFriendMapper.selectList(
-                // 使用LambdaQueryWrapper构建查询条件,筛选出店铺ID等于指定店铺ID的优惠券记录,并且发布状态为已发布
-                new LambdaQueryWrapper<LifeDiscountCouponStoreFriend>().eq(LifeDiscountCouponStoreFriend::getStoreUserId, storeId)
-                        .eq(LifeDiscountCouponStoreFriend::getReleaseType, 1));
-
-        // 获取当前日期,用于后续判断优惠券是否在有效期内
-        LocalDate currentDate = LocalDate.now();
-        if (!lifeDiscountCouponStoreFriends.isEmpty()) {
-            // 遍历该店铺为好友设定的所有优惠券信息
-            for (LifeDiscountCouponStoreFriend coupon : lifeDiscountCouponStoreFriends) {
-                // 创建一个Lambda查询包装器,用于构建查询优惠券的条件
-                LambdaQueryWrapper<LifeDiscountCoupon> queryWrapper = new LambdaQueryWrapper<>();
-                // 设置查询条件:优惠券的领取状态为可领取
-                queryWrapper.eq(LifeDiscountCoupon::getGetStatus, DiscountCouponEnum.CAN_GET.getValue());
-                // 设置查询条件:优惠券的ID等于当前遍历到的优惠券ID
-                queryWrapper.eq(LifeDiscountCoupon::getId, coupon.getCouponId());
-                // 设置查询条件:优惠券的结束日期大于等于当前日期,即优惠券在有效期内
-                queryWrapper.ge(LifeDiscountCoupon::getValidDate, currentDate);
-                // 设置查询条件:优惠券还有库存
-                queryWrapper.gt(LifeDiscountCoupon::getSingleQty, 0);
-
-                // 根据上述查询条件从数据库中查询符合条件的优惠券信息
-                LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectOne(queryWrapper);
-
-                // 如果查询到符合条件的优惠券,说明该优惠券可领
-                if (lifeDiscountCoupon != null) {
-                    // 设定本次领取优惠券的数量,这里固定为1张
-                    Integer receiveQuantity = 1;
-
-                    // 循环领取优惠券,根据设定的领取数量进行多次领取操作
-                    for (int i = 0; i < receiveQuantity; i++) {
-                        // 创建一个新的用户优惠券记录对象
-                        LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
-                        // 设置该优惠券记录的优惠券ID
-                        lifeDiscountCouponUser.setCouponId(coupon.getCouponId());
-                        // 设置该优惠券记录的用户ID为当前用户ID
-                        lifeDiscountCouponUser.setUserId(userId);
-                        // 设置该优惠券的领取时间为当前时间
-                        lifeDiscountCouponUser.setReceiveTime(new Date());
-                        // 设置该优惠券的过期时间为优惠券本身的结束日期
-                        lifeDiscountCouponUser.setExpirationTime(lifeDiscountCoupon.getValidDate());
-                        // 设置该优惠券的状态为待使用
-                        lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
-                        // 将该用户优惠券记录插入到数据库中
-                        lifeDiscountCouponUserMapper.insert(lifeDiscountCouponUser);
+        //有符合规则的优惠券
+        if (ObjectUtils.isNotEmpty(couponList) && !couponList.isEmpty()) {
+            // 获取当前消费用户的ID
+            int userId = Integer.parseInt(lifeUserOrder.getUserId());
+            LifeUser lifeUser = lifeUserMapper.selectById(userId);
+            // 从传入的DTO对象中获取店铺ID
+            StoreUser storeUser =
+                    storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, lifeUserOrder.getStoreId()));
+            Integer storeUserId = storeUser.getId();
+            Integer storeId = storeUser.getStoreId();
+            StoreInfo storeInfo = storeInfoMapper.selectById(storeUser.getStoreId());
+
+            // 根据店铺ID从数据库中查询该店铺为好友设定的所有优惠券信息
+            List<LifeDiscountCouponStoreFriend> lifeDiscountCouponStoreFriends = lifeDiscountCouponStoreFriendMapper.selectList(
+                    // 使用LambdaQueryWrapper构建查询条件,筛选出店铺ID等于指定店铺ID的优惠券记录,并且发布状态为已发布
+                    new LambdaQueryWrapper<LifeDiscountCouponStoreFriend>().eq(LifeDiscountCouponStoreFriend::getStoreUserId, storeId)
+                            .eq(LifeDiscountCouponStoreFriend::getReleaseType, 1)
+                            .in(LifeDiscountCouponStoreFriend::getCouponId, couponList));
+
+            // 获取当前日期,用于后续判断优惠券是否在有效期内
+            LocalDate currentDate = LocalDate.now();
+            if (!lifeDiscountCouponStoreFriends.isEmpty()) {
+                // 遍历该店铺为好友设定的所有优惠券信息
+                for (LifeDiscountCouponStoreFriend coupon : lifeDiscountCouponStoreFriends) {
+                    // 创建一个Lambda查询包装器,用于构建查询优惠券的条件
+                    LambdaQueryWrapper<LifeDiscountCoupon> queryWrapper = new LambdaQueryWrapper<>();
+                    // 设置查询条件:优惠券的领取状态为可领取
+                    queryWrapper.eq(LifeDiscountCoupon::getGetStatus, DiscountCouponEnum.CAN_GET.getValue());
+                    // 设置查询条件:优惠券的ID等于当前遍历到的优惠券ID
+                    queryWrapper.eq(LifeDiscountCoupon::getId, coupon.getCouponId());
+                    // 设置查询条件:优惠券的结束日期大于等于当前日期,即优惠券在有效期内
+                    queryWrapper.ge(LifeDiscountCoupon::getValidDate, currentDate);
+                    // 设置查询条件:优惠券还有库存
+                    queryWrapper.gt(LifeDiscountCoupon::getSingleQty, 0);
+
+                    // 根据上述查询条件从数据库中查询符合条件的优惠券信息
+                    LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectOne(queryWrapper);
+
+                    // 如果查询到符合条件的优惠券,说明该优惠券可领
+                    if (lifeDiscountCoupon != null) {
+                        // 设定本次领取优惠券的数量,这里固定为1张
+                        Integer receiveQuantity = 1;
+
+                        // 循环领取优惠券,根据设定的领取数量进行多次领取操作
+                        for (int i = 0; i < receiveQuantity; i++) {
+                            // 创建一个新的用户优惠券记录对象
+                            LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
+                            // 设置该优惠券记录的优惠券ID
+                            lifeDiscountCouponUser.setCouponId(coupon.getCouponId());
+                            // 设置该优惠券记录的用户ID为当前用户ID
+                            lifeDiscountCouponUser.setUserId(userId);
+                            // 设置该优惠券的领取时间为当前时间
+                            lifeDiscountCouponUser.setReceiveTime(new Date());
+                            // 设置该优惠券的过期时间为优惠券本身的结束日期
+                            lifeDiscountCouponUser.setExpirationTime(lifeDiscountCoupon.getValidDate());
+                            // 设置该优惠券的状态为待使用
+                            lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
+                            // 将该用户优惠券记录插入到数据库中
+                            lifeDiscountCouponUserMapper.insert(lifeDiscountCouponUser);
+                        }
+
+                        // 削减该优惠券的库存,根据领取数量减少库存
+                        coupon.setSingleQty(coupon.getSingleQty() - receiveQuantity);
+                        // 更新数据库中该优惠券的库存信息
+                        lifeDiscountCouponStoreFriendMapper.updateById(coupon);
+
+                        // 创建一个用于存储优惠券信息的VO对象
+                        LifeDiscountCouponStoreFriendVo lifeDiscountCouponStoreFriendVo = new LifeDiscountCouponStoreFriendVo();
+                        // 将优惠券信息复制到VO对象中
+                        BeanUtils.copyProperties(coupon, lifeDiscountCouponStoreFriendVo);
+                        // 将该VO对象添加到最终结果列表中
+                        result.add(lifeDiscountCouponStoreFriendVo);
                     }
-
-                    // 削减该优惠券的库存,根据领取数量减少库存
-                    coupon.setSingleQty(coupon.getSingleQty() - receiveQuantity);
-                    // 更新数据库中该优惠券的库存信息
-                    lifeDiscountCouponStoreFriendMapper.updateById(coupon);
-
-                    // 创建一个用于存储优惠券信息的VO对象
-                    LifeDiscountCouponStoreFriendVo lifeDiscountCouponStoreFriendVo = new LifeDiscountCouponStoreFriendVo();
-                    // 将优惠券信息复制到VO对象中
-                    BeanUtils.copyProperties(coupon, lifeDiscountCouponStoreFriendVo);
-                    // 将该VO对象添加到最终结果列表中
-                    result.add(lifeDiscountCouponStoreFriendVo);
                 }
-            }
 
-            //存储发放日志
-            LifeDiscountCouponStoreFriendSendRecord lifeDiscountCouponStoreFriendSendRecord = new LifeDiscountCouponStoreFriendSendRecord();
-            //存入门店id
-            lifeDiscountCouponStoreFriendSendRecord.setStoreId(Integer.parseInt(lifeUserOrder.getStoreId()));
-            //存入接收人id
-            lifeDiscountCouponStoreFriendSendRecord.setUserId(userId);
-            //存入发放人id
-            lifeDiscountCouponStoreFriendSendRecord.setStoreUserId(storeUserId);
-            //存入订单id
-            lifeDiscountCouponStoreFriendSendRecord.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
-            //存入优惠券ids
-            String[] couponIds = result.stream()
-                    .map(LifeDiscountCouponStoreFriendVo::getCouponId)
-                    .map(String::valueOf)  // 将 Integer 转换为 String
-                    .toArray(String[]::new);
-
-            String join = String.join(",", couponIds);
-            lifeDiscountCouponStoreFriendSendRecord.setDiscountCouponIds(join);
-            lifeDiscountCouponStoreFriendSendRecordMapper.insert(lifeDiscountCouponStoreFriendSendRecord);
-
-            //发送公告消息
-            LifeNotice lifeNotice = new LifeNotice();
-            //存入发送人
-            lifeNotice.setSenderId("system");
-            //存入接收人
-            lifeNotice.setReceiverId("user_" + lifeUser.getUserPhone());
-            //存入信息
-            lifeNotice.setContext(storeInfo.getStoreName() + " 赠送了您他的好友店铺优惠券,快去我的券包查看吧~");
-            //存入类型
-            lifeNotice.setNoticeType(1);
-            lifeNoticeMapper.insert(lifeNotice);
+                //存储发放日志
+                LifeDiscountCouponStoreFriendSendRecord lifeDiscountCouponStoreFriendSendRecord = new LifeDiscountCouponStoreFriendSendRecord();
+                //存入门店id
+                lifeDiscountCouponStoreFriendSendRecord.setStoreId(Integer.parseInt(lifeUserOrder.getStoreId()));
+                //存入接收人id
+                lifeDiscountCouponStoreFriendSendRecord.setUserId(userId);
+                //存入发放人id
+                lifeDiscountCouponStoreFriendSendRecord.setStoreUserId(storeUserId);
+                //存入订单id
+                lifeDiscountCouponStoreFriendSendRecord.setOrderId(Integer.parseInt(lifeUserOrder.getId()));
+                //存入优惠券ids
+                String[] couponIds = result.stream()
+                        .map(LifeDiscountCouponStoreFriendVo::getCouponId)
+                        .map(String::valueOf)  // 将 Integer 转换为 String
+                        .toArray(String[]::new);
+
+                String join = String.join(",", couponIds);
+                lifeDiscountCouponStoreFriendSendRecord.setDiscountCouponIds(join);
+                lifeDiscountCouponStoreFriendSendRecordMapper.insert(lifeDiscountCouponStoreFriendSendRecord);
+
+                //发送公告消息
+                LifeNotice lifeNotice = new LifeNotice();
+                //存入发送人
+                lifeNotice.setSenderId("system");
+                //存入接收人
+                lifeNotice.setReceiverId("user_" + lifeUser.getUserPhone());
+                //存入信息
+                lifeNotice.setContext(storeInfo.getStoreName() + " 赠送了您他的好友店铺优惠券,快去我的券包查看吧~");
+                //存入类型
+                lifeNotice.setNoticeType(1);
+                lifeNoticeMapper.insert(lifeNotice);
 
+            }
         }
+
+
+
+
         // 返回成功发放的优惠券信息列表
         return result;
     }
@@ -353,4 +387,93 @@ public class LifeDiscountCouponStoreFriendServiceImpl extends ServiceImpl<LifeDi
                 .set(LifeDiscountCouponStoreFriend::getReleaseType, releaseType);
         return lifeDiscountCouponStoreFriendMapper.update(null, updateWrapper);
     }
+
+    @Override
+    public LifeDiscountCouponFriendRuleVo saveFriendCouponRule(LifeDiscountCouponFriendRule lifeDiscountCouponFriendRule) {
+        if (ObjectUtils.isNotEmpty(lifeDiscountCouponFriendRule.getId())) {
+            List<LifeDiscountCouponFriendRuleDetail> details = lifeDiscountCouponFriendRule.getDetails();
+            lifeDiscountCouponFriendRuleDetailMapper.delete(new LambdaQueryWrapper<LifeDiscountCouponFriendRuleDetail>().eq(LifeDiscountCouponFriendRuleDetail::getRuleId, lifeDiscountCouponFriendRule.getId()));
+            for (LifeDiscountCouponFriendRuleDetail detail : details) {
+                detail.setRuleId(lifeDiscountCouponFriendRule.getId());
+                detail.setStoreId(lifeDiscountCouponFriendRule.getStoreId());
+            }
+            lifeDiscountCouponFriendRuleDetailMapper.insertList(details);
+            lifeDiscountCouponFriendRuleMapper.updateById(lifeDiscountCouponFriendRule);
+        }else {
+            lifeDiscountCouponFriendRuleMapper.insert(lifeDiscountCouponFriendRule);
+            if (ObjectUtils.isNotEmpty(lifeDiscountCouponFriendRule.getDetails())) {
+                lifeDiscountCouponFriendRule.getDetails().forEach(detail -> detail.setRuleId(lifeDiscountCouponFriendRule.getId()));
+                lifeDiscountCouponFriendRuleDetailMapper.insertList(lifeDiscountCouponFriendRule.getDetails());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void delFriendCouponRule(String id) {
+        lifeDiscountCouponFriendRuleDetailMapper.delete(new LambdaQueryWrapper<LifeDiscountCouponFriendRuleDetail>().eq(LifeDiscountCouponFriendRuleDetail::getRuleId, id));
+        lifeDiscountCouponFriendRuleMapper.deleteById(id);
+    }
+
+    /**
+     * 获取好友送的优惠券列表
+     *
+     * @param storeId 当前登录店铺id
+     * @param friendStoreUserId 选中好友店铺用户id
+     * @return 领取的优惠券列表
+     */
+    @Override
+    public List<LifeDiscountCouponFriendRuleDetailVo> getReceivedFriendCouponList(String storeId,String friendStoreUserId) {
+        QueryWrapper<LifeDiscountCouponFriendRuleDetailVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("ldcsf.store_user_id", storeId);
+        queryWrapper.eq("ldcsf.delete_flag", 0);
+        queryWrapper.eq("ldcsf.release_type", 1);
+        //查询送过优惠券的店铺
+        if (StringUtils.isEmpty(friendStoreUserId)) {
+            queryWrapper.groupBy("ldcsf.friend_store_user_id").orderByDesc("couponNum");
+        }
+        //查询选中店铺送的优惠券
+        else {
+            queryWrapper.eq("ldcsf.friend_store_user_id", friendStoreUserId).groupBy("ldcsf.coupon_id").orderByDesc("couponNum");
+        }
+        return lifeDiscountCouponFriendRuleDetailMapper.getReceivedFriendCouponList(queryWrapper);
+    }
+
+    @Override
+    public List<LifeDiscountCouponFriendRuleVo> getRuleList(String storeId) {
+        List<LifeDiscountCouponFriendRuleVo> ruleList = lifeDiscountCouponFriendRuleDetailMapper.getRuleList(storeId);
+        if (ObjectUtils.isNotEmpty(ruleList)) {
+            ruleList.forEach(i -> i.setStatus(i.getEndDate().after(new Date()) ? "0" : "1"));
+        }
+        return ruleList;
+    }
+
+    @Override
+    public LifeDiscountCouponFriendRuleVo getRuleById(String id) {
+        LifeDiscountCouponFriendRule lifeDiscountCouponFriendRule = lifeDiscountCouponFriendRuleMapper.selectById(id);
+        LifeDiscountCouponFriendRuleVo ruleVo = new LifeDiscountCouponFriendRuleVo();
+        BeanUtils.copyProperties(lifeDiscountCouponFriendRule, ruleVo);
+        if (ObjectUtils.isNotEmpty(lifeDiscountCouponFriendRule)) {
+            List<LifeDiscountCouponFriendRuleDetailVo> lifeDiscountCouponFriendRuleDetails = lifeDiscountCouponFriendRuleDetailMapper.getDetailList(lifeDiscountCouponFriendRule.getId().toString());
+            ruleVo.setLifeDiscountCouponFriendRuleDetailVos(lifeDiscountCouponFriendRuleDetails);
+        }
+        return ruleVo;
+    }
+
+    @Override
+    public List<LifeDiscountCouponFriendRuleVo> getReceivedSendFriendCouponList(String storeUserId, String friendStoreUserId,String storeName) {
+        QueryWrapper<LifeDiscountCouponFriendRuleVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq(StringUtils.isNotEmpty(storeUserId),"ldcsf.store_user_id", storeUserId)
+                .eq(StringUtils.isNotEmpty(friendStoreUserId),"ldcsf.friend_store_user_id", friendStoreUserId)
+                .like(StringUtils.isNotEmpty(storeName),"si.store_name", storeName);
+        if (StringUtils.isNotEmpty(storeUserId)) {
+            return lifeDiscountCouponStoreFriendMapper.getReceivedSendFriendCouponList(queryWrapper);
+        }
+        if (StringUtils.isNotEmpty(friendStoreUserId)) {
+            return lifeDiscountCouponStoreFriendMapper.getReceivedSendFriendCouponListwzhy(queryWrapper);
+        }
+        else {
+            return new ArrayList<>();
+        }
+    }
 }

+ 52 - 1
alien-store/src/main/java/shop/alien/store/service/impl/LifeDiscountCouponUserServiceImpl.java

@@ -1,17 +1,25 @@
 package shop.alien.store.service.impl;
 
 import com.aliyun.tea.utils.StringUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeCollect;
 import shop.alien.entity.store.LifeDiscountCoupon;
 import shop.alien.entity.store.LifeDiscountCouponUser;
+import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.store.dto.LifeDiscountCouponUserDto;
+import shop.alien.mapper.LifeCollectMapper;
 import shop.alien.mapper.LifeDiscountCouponMapper;
 import shop.alien.mapper.LifeDiscountCouponUserMapper;
+import shop.alien.mapper.StoreInfoMapper;
+import shop.alien.store.config.BaseRedisService;
 import shop.alien.store.service.LifeDiscountCouponUserService;
 import shop.alien.util.common.constant.DiscountCouponEnum;
 
@@ -32,13 +40,28 @@ import java.util.Date;
 @RequiredArgsConstructor
 public class LifeDiscountCouponUserServiceImpl extends ServiceImpl<LifeDiscountCouponUserMapper, LifeDiscountCouponUser> implements LifeDiscountCouponUserService {
 
+    private final LifeCollectMapper lifeCollectMapper;
+
+    private final StoreInfoMapper storeInfoMapper;
+
     private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
 
     private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
 
+    private final BaseRedisService baseRedisService;
+
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R<Boolean> receiveCoupon(LifeDiscountCouponUserDto lifeDiscountCouponUserDto) {
+        // 锁value
+        String identifier = null;
         try {
+            identifier = baseRedisService.lock(lifeDiscountCouponUserDto.getCouponId().toString());
+            if (StringUtils.isEmpty(identifier)) {
+                throw new RuntimeException("抢购人数过多,请稍后重试");
+            }
+
             Integer receiveQuantity = lifeDiscountCouponUserDto.getReceiveQuantity();
             LifeDiscountCoupon lifeDiscountCoupon = lifeDiscountCouponMapper.selectById(lifeDiscountCouponUserDto.getCouponId());
             // 判断是否在领取时间内
@@ -54,6 +77,15 @@ public class LifeDiscountCouponUserServiceImpl extends ServiceImpl<LifeDiscountC
             if (getStatus == 0) {
                 return R.fail("该优惠劵已经关闭领取");
             }
+
+            if(lifeDiscountCoupon.getSingleQty() != null && lifeDiscountCoupon.getSingleQty() <= 0){
+                return R.fail("已发放完毕");
+            }
+
+            if(lifeDiscountCoupon.getSingleQty() != null && lifeDiscountCoupon.getSingleQty() < receiveQuantity){
+                return R.fail("已发放完毕");
+            }
+
             String specifiedDay = lifeDiscountCoupon.getSpecifiedDay();
 
             //判断领取数量
@@ -81,9 +113,28 @@ public class LifeDiscountCouponUserServiceImpl extends ServiceImpl<LifeDiscountC
             //削减该优惠券库存
             lifeDiscountCoupon.setSingleQty(lifeDiscountCoupon.getSingleQty() - receiveQuantity);
             lifeDiscountCouponMapper.updateById(lifeDiscountCoupon);
-        } catch (BeansException e) {
+
+            //是否领取优惠券收藏店铺
+            Integer attentionCanReceived = lifeDiscountCoupon.getAttentionCanReceived();
+            if(attentionCanReceived != null && attentionCanReceived == 1){
+                LifeCollect lifeCollect = new LifeCollect();
+                lifeCollect.setStoreId(lifeDiscountCoupon.getStoreId());
+                lifeCollect.setUserId(lifeDiscountCouponUserDto.getUserId().toString());
+                lifeCollectMapper.insert(lifeCollect);
+
+                //同步店铺收藏数量
+                if (!StringUtils.isEmpty(lifeCollect.getStoreId())) {
+                    LambdaQueryWrapper<LifeCollect> queryWrapper = new LambdaQueryWrapper<>();
+                    queryWrapper.eq(LifeCollect::getStoreId, lifeCollect.getStoreId());
+                    storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>().eq(StoreInfo::getId, lifeCollect.getStoreId()).set(StoreInfo::getCollectNum, lifeCollectMapper.selectCount(queryWrapper)));
+                }
+            }
+        } catch (Exception e) {
             log.error("LifeDiscountCouponController.receiveCoupon ERROR Msg=" + e.getMessage());
+            baseRedisService.unlock(lifeDiscountCouponUserDto.getCouponId().toString(), identifier);
             return R.fail("领取失败");
+        } finally {
+            baseRedisService.unlock(lifeDiscountCouponUserDto.getCouponId().toString(), identifier);
         }
         return R.success("领取成功");
     }

+ 1 - 1
alien-store/src/main/java/shop/alien/store/service/impl/LifeGroupBuyCountServiceImpl.java

@@ -155,7 +155,7 @@ public class LifeGroupBuyCountServiceImpl extends ServiceImpl<LifeGroupBuyCountM
         List<LifeGroupBuyCountDateVo> lifeGroupBuyCountDateVos = lifeGroupBuyCountMapper.selectDpzbpmListByStoreId(storeId);
         for (LifeGroupBuyCountDateVo lifeGroupBuyCountDateVo : lifeGroupBuyCountDateVos) {
             lifeGroupBuyCountDateVo.setRjfws(StringUtils.isNotEmpty(lifeGroupBuyCountDateVo.getSpfks()) ? (new BigDecimal(lifeGroupBuyCountDateVo.getSpfwl()).divide(new BigDecimal(lifeGroupBuyCountDateVo.getSpfks()), 0, RoundingMode.HALF_UP)).toString() : "0");
-            lifeGroupBuyCountDateVo.setScl(StringUtils.isNotEmpty(lifeGroupBuyCountDateVo.getSpfks()) ? new BigDecimal(lifeGroupBuyCountDateVo.getSpscl()).divide(new BigDecimal(lifeGroupBuyCountDateVo.getSpfks()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)) + "%" : "0.0%");
+            lifeGroupBuyCountDateVo.setScl(StringUtils.isNotEmpty(lifeGroupBuyCountDateVo.getSpfks()) ? new BigDecimal(lifeGroupBuyCountDateVo.getSpscl()).divide(new BigDecimal(lifeGroupBuyCountDateVo.getSpfks()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP) + "%" : "0.0%");
         }
         return lifeGroupBuyCountDateVos;
     }

+ 3 - 0
alien-store/src/main/java/shop/alien/store/service/impl/LifeNoticeServiceImpl.java

@@ -102,6 +102,9 @@ public class LifeNoticeServiceImpl extends ServiceImpl<LifeNoticeMapper, LifeNot
             if(lifeNoticeVo.getBusinessId() == null){
                 lifeNoticeVo.setPlatformType("1");
             }
+            if(StringUtils.isNotBlank(lifeNoticeVo.getTitle()) && "店铺审核通知".equals(lifeNoticeVo.getTitle())){
+                lifeNoticeVo.setPlatformType("1");
+            }
             if(lifeNoticeVo.getBusinessId() != null && lifeUserViolationMap.containsKey(lifeNoticeVo.getBusinessId())){
                 String reportContextType = lifeUserViolationMap.get(lifeNoticeVo.getBusinessId());
                 if(StringUtils.isNotBlank(reportContextType) && "1,2,3".contains(reportContextType)){

+ 4 - 4
alien-store/src/main/java/shop/alien/store/service/impl/LifeUserViolationServiceImpl.java

@@ -143,11 +143,8 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
     }
 
     private LifeNotice getLifeNotice(LifeUserViolation lifeuserViolation) {
-        JSONObject data = JwtUtil.getCurrentUserInfo();
         String phoneId = null;
-//        if (data != null) {
-//            phoneId = data.getString("phone");
-//        }
+
         LifeNotice lifeNotice = new LifeNotice();
         lifeNotice.setSenderId("system");
         lifeNotice.setBusinessId(lifeuserViolation.getId());
@@ -319,6 +316,9 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
         IPage<LifeUserViolation> iPage = new Page<>(page, size);
         QueryWrapper<LifeUserViolation> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq(StringUtils.isNotEmpty(processingStatus), PROCESSING_STATUS, processingStatus).and(flag, wrapper -> wrapper.nested(wq -> wq.eq(REPORTING_USER_TYPE, "1").in(!MIDs.isEmpty(), REPORTING_USER_ID, MIDs)).or(wq -> wq.eq(REPORTING_USER_TYPE, "2").in(!UIDs.isEmpty(), REPORTING_USER_ID, UIDs))).orderByDesc("updated_time");
+        String commonReportContextType = "1,2,3";
+        List<String> commonReportContextTypeList = Arrays.asList(commonReportContextType.split(","));
+        queryWrapper.lambda().in(LifeUserViolation::getReportContextType, commonReportContextTypeList);
         IPage<LifeUserViolation> resultPage = lifeUserViolationMapper.selectPage(iPage, queryWrapper);
         return resultPage.convert(e -> {
             LifeUserViolationDto dto = new LifeUserViolationDto();

+ 23 - 10
alien-store/src/main/java/shop/alien/store/service/impl/SignInServiceImpl.java

@@ -16,17 +16,17 @@ import shop.alien.entity.store.vo.SignInVo;
 import shop.alien.entity.store.vo.UserSignInRecordVo;
 import shop.alien.mapper.ActivityPeriodMapper;
 import shop.alien.mapper.ActivitySignInConfigMapper;
-import shop.alien.mapper.UserSignInRecordMapper;
 import shop.alien.mapper.ActivitySignRewardMapper;
+import shop.alien.mapper.UserSignInRecordMapper;
 import shop.alien.mapper.system.SignInActivityMapper;
 import shop.alien.store.service.SignInService;
+import shop.alien.store.service.UserPointService;
 
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -46,6 +46,7 @@ public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserS
     private final ActivityPeriodMapper activityPeriodMapper;
     private final UserSignInRecordMapper userSignInRecordMapper;
     private final SignInActivityMapper signInActivityMapper;
+    private final UserPointService userPointService;
 
     @Override
     public UserSignInRecordVo signIn(int userId) {
@@ -117,10 +118,12 @@ public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserS
                 if(!CollectionUtils.isEmpty(activitySignInRewards)){
                     ActivitySignInReward activitySignInReward = activitySignInRewards.get(0);
                     basePoints = basePoints + activitySignInReward.getPoints();
-                    ActivityPointInfoVo groupActivityPointInfoVo = new ActivityPointInfoVo();
-                    groupActivityPointInfoVo.setPoint(activitySignInReward.getPoints());
-                    groupActivityPointInfoVo.setPointInfo("已连续签到"+continueDay+"天奖励积分"+activitySignInReward.getPoints());
-                    activityPointInfoVoList.add(groupActivityPointInfoVo);
+                    if(activitySignInReward.getPoints() != 0){
+                        ActivityPointInfoVo groupActivityPointInfoVo = new ActivityPointInfoVo();
+                        groupActivityPointInfoVo.setPoint(activitySignInReward.getPoints());
+                        groupActivityPointInfoVo.setPointInfo("已连续签到"+continueDay+"天奖励积分"+activitySignInReward.getPoints());
+                        activityPointInfoVoList.add(groupActivityPointInfoVo);
+                    }
                 }
             }
         }
@@ -180,7 +183,7 @@ public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserS
         record.setUserId(userId);
         record.setDeleteFlag(0);
         userSignInRecordMapper.insert(record);
-
+        userPointService.addPoint(userId, basePoints + specialPoints);
         if(!CollectionUtils.isEmpty(activityPoint)){
             activityPoint.forEach((key, value) -> {
                 if(value == 0 ){
@@ -243,8 +246,8 @@ public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserS
         signInVo.setTotalPoint(totalPoint);
 
         // 获取连续签到天数
-        int continueDay = totalContinuousDays(userId,0);
-        signInVo.setTotalContinueDay(continueDay);
+        int totalContinueDay = 1;
+//        signInVo.setTotalContinueDay(continueDay);
 
         // 计算连续签到天数
         int countDay = 1;
@@ -252,14 +255,24 @@ public class SignInServiceImpl extends ServiceImpl<UserSignInRecordMapper, UserS
             boolean isToday = isSameDay(lastUserSignInRecord.getSignInDate(),0);
             if(isToday){
                 countDay = lastUserSignInRecord.getContinuousDays();
+                totalContinueDay = lastUserSignInRecord.getTotalContinuousDays();
             } else{
                 boolean isYestDay = isSameDay(lastUserSignInRecord.getSignInDate(),1);
                 if(isYestDay){
-                    countDay = lastUserSignInRecord.getContinuousDays() + 1;
+                    countDay = lastUserSignInRecord.getContinuousDays() ;
+                    totalContinueDay = lastUserSignInRecord.getTotalContinuousDays();
+                } else{
+                    countDay = 0;
+                    totalContinueDay = 0;
                 }
             }
+        } else {
+            countDay = 0;
+            totalContinueDay = 0;
         }
         signInVo.setContinuousDays(countDay);
+        signInVo.setTotalContinueDay(totalContinueDay);
+
 
         // 获取签到记录
 //        LambdaQueryWrapper<UserSignInRecord> wrapper = new LambdaQueryWrapper<>();

+ 27 - 7
alien-store/src/main/java/shop/alien/store/service/impl/StoreClockInServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import shop.alien.entity.store.*;
 import shop.alien.entity.store.vo.StoreClockInVo;
@@ -51,8 +52,32 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
     }
 
     @Override
-    public IPage<StoreClockInVo> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf) {
+    public IPage<StoreClockInVo> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf,Integer storeId) {
         IPage<StoreClockIn> iPage = new Page<>(page, size);
+        // 查询我的点赞
+        LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
+        likeWrapper.eq(LifeLikeRecord::getDianzanId, phoneId);
+        likeWrapper.eq(LifeLikeRecord::getType, "5");
+        List<LifeLikeRecord> lifeLikeList = lifeLikeRecordMapper.selectList(likeWrapper);
+        List<String> likeList = lifeLikeList.stream().map(LifeLikeRecord::getHuifuId).collect(Collectors.toList());
+
+
+        if(StringUtils.isNotBlank(String.valueOf(storeId)) && !String.valueOf(storeId).equals("null")){
+            IPage<StoreClockInVo> storeClockInIPage1 = storeClockInMapper.getStoreClockInList(iPage, new QueryWrapper<StoreClockIn>()
+                    .eq("clock.store_id", storeId)
+                    .eq("clock.delete_flag", 0)
+                    .eq("user.delete_flag", 0)
+                    .eq("store.delete_flag", 0)
+                    .orderByDesc("created_time"));
+            storeClockInIPage1.getRecords().forEach(vo -> {
+                if (likeList.contains(String.valueOf(vo.getId()))) {
+                    vo.setIsLike("1");
+                } else {
+                    vo.setIsLike("0");
+                }
+            });
+            return storeClockInIPage1;
+        }
         QueryWrapper<StoreClockIn> wrapper = new QueryWrapper<>();
         wrapper.eq(1 == mySelf, "clock.user_id", userId);
         wrapper.eq("clock.delete_flag", 0);
@@ -73,12 +98,7 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
         lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
         List<String> fansList = lifeFansList.stream().map(LifeFans::getFansId).collect(Collectors.toList());
 
-        // 查询我的点赞
-        LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
-        likeWrapper.eq(LifeLikeRecord::getDianzanId, phoneId);
-        likeWrapper.eq(LifeLikeRecord::getType, "5");
-        List<LifeLikeRecord> lifeLikeList = lifeLikeRecordMapper.selectList(likeWrapper);
-        List<String> likeList = lifeLikeList.stream().map(LifeLikeRecord::getHuifuId).collect(Collectors.toList());
+
 
         // 查询我的收藏
         LambdaQueryWrapper<LifeCollect> collectWrapper = new LambdaQueryWrapper<>();

+ 13 - 1
alien-store/src/main/java/shop/alien/store/service/impl/StoreCommentServiceImpl.java

@@ -72,6 +72,8 @@ public class StoreCommentServiceImpl extends ServiceImpl<StoreCommentMapper, Sto
 
     private final WebSocketProcess webSocketProcess;
 
+    private final TagsSynonymMapper tagsSynonymMapper;
+
     @Autowired
     private TextModerationUtil textModerationUtil;
 
@@ -91,7 +93,7 @@ public class StoreCommentServiceImpl extends ServiceImpl<StoreCommentMapper, Sto
      * @return IPage<StoreComment>
      */
     @Override
-    public IPage<StoreCommentVo> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType) {
+    public IPage<StoreCommentVo> getList(Integer pageNum, Integer pageSize, Integer businessId, Integer businessType, Integer storeId, Integer replyStatus, Integer commentLevel, Integer days, String phoneId, Integer userType, Integer tagId) {
         IPage<StoreCommentVo> storeCommentIPage = new Page<>(pageNum, pageSize);
         QueryWrapper<StoreCommentVo> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq(null != businessId, "a.business_id", businessId);
@@ -142,6 +144,16 @@ public class StoreCommentServiceImpl extends ServiceImpl<StoreCommentMapper, Sto
             queryWrapper.notIn("a.id",businessIds);
         }
 
+        //根据标签id查询表签字表拿到评论ids
+        if(tagId !=null){
+            List<TagsSynonym> tagsSynonymList = tagsSynonymMapper.selectList(new LambdaQueryWrapper<TagsSynonym>().eq(TagsSynonym::getMainTagId,tagId));
+            if(CollectionUtils.isNotEmpty(tagsSynonymList)){
+                List<Integer> commentIdList = tagsSynonymList.stream().filter(synonym -> synonym != null)
+                        .map(TagsSynonym::getCommentId).filter(commentId -> commentId != null).collect(Collectors.toList());
+                queryWrapper.in("a.id",commentIdList);
+            }
+        }
+
         //先查询父级评论
         queryWrapper.isNull(businessType != 1, "a.reply_id").eq("a.delete_flag", 0).orderByDesc("a.created_time");
         IPage<StoreCommentVo> page = storeCommentMapper.getCommentPage(storeCommentIPage, queryWrapper);

Some files were not shown because too many files changed in this diff