Explorar el Código

add 签到关注引导任务

zoujiajian hace 3 años
padre
commit
20789e9624
Se han modificado 76 ficheros con 3360 adiciones y 79 borrados
  1. 14 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 11 0
      netflix-common/src/main/java/com/cyksj/common/constant/PointsRecordConst.java
  3. 24 0
      netflix-common/src/main/java/com/cyksj/common/constant/TaskTypeEnum.java
  4. 19 0
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  5. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/UserMapper.java
  6. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/SignStatisticsDataMapper.java
  7. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/draw/LuckyDrawMapper.java
  8. 24 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/draw/LuckyDrawRecordMapper.java
  9. 8 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/sign/SignConfigMapper.java
  10. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/sign/SignUserMapper.java
  11. 32 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/sign/UserPointsRecordMapper.java
  12. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskFollowPlatVerifyMapper.java
  13. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskMapper.java
  14. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskTypeMapper.java
  15. 27 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskUserCompleteRecordMapper.java
  16. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/market/task/UserBindPhoneMapper.java
  17. 0 5
      netflix-dao/src/main/java/com/cyksj/model/entity/BaseEntity.java
  18. 3 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java
  19. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/ExchangeCode.java
  20. 62 0
      netflix-dao/src/main/java/com/cyksj/model/entity/LuckyDraw.java
  21. 56 0
      netflix-dao/src/main/java/com/cyksj/model/entity/LuckyDrawRecord.java
  22. 1 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  23. 14 0
      netflix-dao/src/main/java/com/cyksj/model/entity/SignConfig.java
  24. 83 0
      netflix-dao/src/main/java/com/cyksj/model/entity/SignStatisticsData.java
  25. 34 0
      netflix-dao/src/main/java/com/cyksj/model/entity/SignUser.java
  26. 53 0
      netflix-dao/src/main/java/com/cyksj/model/entity/Task.java
  27. 45 0
      netflix-dao/src/main/java/com/cyksj/model/entity/TaskFollowPlatVerify.java
  28. 16 0
      netflix-dao/src/main/java/com/cyksj/model/entity/TaskType.java
  29. 37 0
      netflix-dao/src/main/java/com/cyksj/model/entity/TaskUserCompleteRecord.java
  30. 2 0
      netflix-dao/src/main/java/com/cyksj/model/entity/User.java
  31. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserBindPhone.java
  32. 15 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserPointsRecord.java
  33. 24 2
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java
  34. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/ExchangeCodeReq.java
  35. 26 0
      netflix-dao/src/main/java/com/cyksj/model/request/LuckyDrawReq.java
  36. 44 0
      netflix-dao/src/main/java/com/cyksj/model/request/TaskFollowReq.java
  37. 2 1
      netflix-dao/src/main/java/com/cyksj/model/views/ExchangeCodeView.java
  38. 6 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuView.java
  39. 77 0
      netflix-dao/src/main/java/com/cyksj/model/views/LuckyDrawRecordView.java
  40. 100 0
      netflix-dao/src/main/java/com/cyksj/model/views/LuckyDrawView.java
  41. 54 0
      netflix-dao/src/main/java/com/cyksj/model/views/TaskFollowVerifyView.java
  42. 79 0
      netflix-dao/src/main/java/com/cyksj/model/views/TaskFrontView.java
  43. 82 0
      netflix-dao/src/main/java/com/cyksj/model/views/TaskView.java
  44. 43 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserPersonalView.java
  45. 3 1
      netflix-service/src/main/java/com/cyksj/redis/RedisService.java
  46. 7 0
      netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java
  47. 6 0
      netflix-service/src/main/java/com/cyksj/service/mange/coupon/CouponCommonService.java
  48. 24 0
      netflix-service/src/main/java/com/cyksj/service/mange/coupon/impl/CouponCommonServiceImpl.java
  49. 31 0
      netflix-service/src/main/java/com/cyksj/service/market/MarketFrontService.java
  50. 17 0
      netflix-service/src/main/java/com/cyksj/service/market/draw/LuckyDrawService.java
  51. 133 0
      netflix-service/src/main/java/com/cyksj/service/market/draw/impl/LuckyDrawServiceImpl.java
  52. 575 0
      netflix-service/src/main/java/com/cyksj/service/market/impl/MarketFrontServiceImpl.java
  53. 25 0
      netflix-service/src/main/java/com/cyksj/service/market/task/TaskService.java
  54. 220 0
      netflix-service/src/main/java/com/cyksj/service/market/task/impl/TaskServiceImpl.java
  55. 2 0
      netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java
  56. 20 1
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  57. 12 0
      netflix-service/src/main/java/com/cyksj/service/phone/PhoneCodeService.java
  58. 50 0
      netflix-service/src/main/java/com/cyksj/service/phone/impl/PhoneCodeServiceImpl.java
  59. 15 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  60. 85 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  61. 12 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
  62. 129 0
      netflix-service/src/main/java/com/cyksj/task/SignStatisticsDataScheduler.java
  63. 2 3
      netflix-service/src/main/java/com/cyksj/task/StatisticsDataScheduler.java
  64. 30 0
      netflix-web/src/main/java/com/cyksj/config/SaTokenConfigure.java
  65. 0 35
      netflix-web/src/main/java/com/cyksj/config/WebConfig.java
  66. 5 22
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  67. 3 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java
  68. 101 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/market/LuckyDrawController.java
  69. 42 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/market/SignController.java
  70. 137 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/market/TaskController.java
  71. 20 9
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  72. 111 0
      netflix-web/src/main/java/com/cyksj/web/controller/market/LuckyDrawFrontController.java
  73. 69 0
      netflix-web/src/main/java/com/cyksj/web/controller/market/SignFrontController.java
  74. 169 0
      netflix-web/src/main/java/com/cyksj/web/controller/market/TaskFrontController.java
  75. 11 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java
  76. 55 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

+ 14 - 0
netflix-common/src/main/java/com/cyksj/common/constant/Constant.java

@@ -0,0 +1,14 @@
+package com.cyksj.common.constant;
+
+/*
+ *项目名: netflix
+ *文件名: Constant
+ *创建者: JavaZou
+ *创建时间:2022/12/27 18:30
+ */
+public interface Constant {
+	/**
+	 * 一天秒数
+	 */
+	Long DAY_MILLS = 86400000l;
+}

+ 11 - 0
netflix-common/src/main/java/com/cyksj/common/constant/PointsRecordConst.java

@@ -0,0 +1,11 @@
+package com.cyksj.common.constant;
+
+public interface PointsRecordConst {
+	String SIGN = "每日签到";
+
+	String LOTTERY = "抽奖奖励";
+
+	String POINTS_LOTTERY = "积分抽奖";
+
+	String TASK = "任务奖励";
+}

+ 24 - 0
netflix-common/src/main/java/com/cyksj/common/constant/TaskTypeEnum.java

@@ -0,0 +1,24 @@
+package com.cyksj.common.constant;
+
+import lombok.Getter;
+
+/*
+ *项目名: netflix
+ *文件名: TaskTypeEnum
+ *创建者: JavaZou
+ *创建时间:2022/12/29 14:48
+ */
+@Getter
+public enum TaskTypeEnum {
+	yh_order("下一笔订单"),
+	corp_wx("添加企业微信"),
+	bind_phone("绑定手机号"),
+	share("邀请好友"),
+	;
+
+	String desc;
+
+	TaskTypeEnum(String desc) {
+		this.desc = desc;
+	}
+}

+ 19 - 0
netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java

@@ -408,4 +408,23 @@ public final class StringUtil {
 			sb.append(randomStr.charAt(number));
 		}
 	}
+
+	/**
+	 * 姓名匿名
+	 */
+	public static String anonymity(char[] name) {
+		final int size = name.length;
+
+		char[] chars = new char[3];
+		if (size == 1 || size == 2) {
+			chars[0] = '*';
+			chars[1] = ' ';
+			chars[2] = name[size - 1];
+		} else {
+			chars[0] = '*';
+			chars[1] = name[size - 2];
+			chars[2] = name[size - 1];
+		}
+		return new String(chars);
+	}
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/mapper/UserMapper.java

@@ -24,4 +24,7 @@ public interface UserMapper extends BaseMapper<User> {
 
     @Update("update user set points = points + #{addPoints} where id = #{id} and points = #{originalPoints} and points >=0")
     Integer updatePoints(@Param("id") Long id, @Param("originalPoints") BigDecimal originalPoints, @Param("addPoints") BigDecimal addPoints);
+
+    @Update("update user set active_points = active_points - #{subPoints} where active_points > 0 and active_points >= #{subPoints} and id = #{userId}")
+    Integer subActivePoints(@Param("userId") Long userId, @Param("subPoints") BigDecimal subPoints);
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/statistics/SignStatisticsDataMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.statistics;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.SignStatisticsData;
+
+/*
+ *项目名: netflix
+ *文件名: SignStatisticsDataMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/27 18:23
+ */
+public interface SignStatisticsDataMapper extends BaseMapper<SignStatisticsData> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/draw/LuckyDrawMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.draw;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.LuckyDraw;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/27 16:05
+ */
+public interface LuckyDrawMapper extends BaseMapper<LuckyDraw> {
+}

+ 24 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/draw/LuckyDrawRecordMapper.java

@@ -0,0 +1,24 @@
+package com.cyksj.mapper.market.draw;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.LuckyDrawRecord;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawRecordMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/28 16:39
+ */
+public interface LuckyDrawRecordMapper extends BaseMapper<LuckyDrawRecord> {
+	@Update("update lucky_draw_record set status = #{success},order_id = #{orderId} where id = #{id} and status = 'pending'")
+	Integer updateStatus(@Param("id") Long id, @Param("orderId") Long orderId, @Param("success") LuckyDrawRecord.Status success);
+
+	@Select("select count(distinct user_id) from lucky_draw_record where draw_id = #{drawId}")
+	Integer getLotteryNum(Long drawId);
+
+	@Update("update lucky_draw_record set status = 'success' where user_id = #{userId} and ex_code = #{code}")
+	void updateExCodeStatus(@Param("userId") Long userId, @Param("code") String code);
+}

+ 8 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/sign/SignConfigMapper.java

@@ -0,0 +1,8 @@
+package com.cyksj.mapper.market.sign;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.SignConfig;
+
+public interface SignConfigMapper extends BaseMapper<SignConfig> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/sign/SignUserMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.sign;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.SignUser;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.Date;
+
+public interface SignUserMapper extends BaseMapper<SignUser> {
+    @Update("update sign_user set day = #{day}, day_period = #{dayPeriod},update_time = current_timestamp() where user_id = #{userId} and update_time = #{originalTime}")
+    Integer updateUserSignDay(@Param("day") Integer day, @Param("dayPeriod") Integer dayPeriod, @Param("userId") Long userId, @Param("originalTime") Date originalTime);
+}

+ 32 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/sign/UserPointsRecordMapper.java

@@ -0,0 +1,32 @@
+package com.cyksj.mapper.market.sign;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserPointsRecord;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.Date;
+
+public interface UserPointsRecordMapper extends BaseMapper<UserPointsRecord> {
+	@Update("update user set active_points = active_points + #{points} where id = #{userId}")
+	void updateUserPoints(@Param("userId") Long userId, @Param("points") Integer points);
+
+	@Select("select sum(points) from user_points_record ur where created_time between #{yesZeroDate} and #{thisZeroDate} and points > 0")
+	Integer getTodayNumOfPoints(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select sum(points) from user_points_record ur where points > 0")
+	Integer getSumOfPoints();
+
+	@Select("select sum(points) from user_points_record ur where created_time between #{yesZeroDate} and #{thisZeroDate} and points < 0")
+	Integer getTodayUseOfPoints(@Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select sum(points) from user_points_record ur where points < 0")
+	Integer getSumUseOfPoints();
+
+	@Select("select count(*) from user_points_record ur where created_time between #{yesZeroDate} and #{thisZeroDate} and points < 0 and remark = #{remark}")
+	Integer getTodayNumOfLottery(@Param("remark") String remark, @Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+
+	@Select("select count(*) from sign_user where update_time between #{yesZeroDate} and #{thisZeroDate} and day_period = #{dayPeriod}")
+	Integer getSignDayByCondition(@Param("dayPeriod") Integer dayPeriod, @Param("yesZeroDate") Date yesZeroDate, @Param("thisZeroDate") Date thisZeroDate);
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskFollowPlatVerifyMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.task;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFollowPlatVerifyMapper
+ *创建者: JavaZou
+ *创建时间:2023/1/6 14:07
+ */
+public interface TaskFollowPlatVerifyMapper extends BaseMapper<TaskFollowPlatVerify> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.task;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.Task;
+
+/*
+ *项目名: netflix
+ *文件名: TaskMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/27 15:28
+ */
+public interface TaskMapper extends BaseMapper<Task> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskTypeMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.task;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.TaskType;
+
+/*
+ *项目名: netflix
+ *文件名: TaskTypeMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:40
+ */
+public interface TaskTypeMapper extends BaseMapper<TaskType> {
+}

+ 27 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/task/TaskUserCompleteRecordMapper.java

@@ -0,0 +1,27 @@
+package com.cyksj.mapper.market.task;
+
+import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.TaskUserCompleteRecord;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+/*
+ *项目名: netflix
+ *文件名: TaskUserCompleteRecordMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/28 17:15
+ */
+public interface TaskUserCompleteRecordMapper extends BaseMapper<TaskUserCompleteRecord> {
+	@Select("select ifnull(sum(points),0) from task_user_complete_record where task_id = #{taskId} and status = 'received' and created_time between #{beginOfDay} and #{endOfDay}")
+	Integer sumTodayPoints(@Param("taskId") Long taskId, @Param("beginOfDay") DateTime beginOfDay, @Param("endOfDay") DateTime endOfDay);
+
+	@Select("select ifnull(sum(points),0) from task_user_complete_record where task_id = #{taskId} and status = 'received'")
+	Integer sumPoints(Long taskId);
+
+	@Select("select count(distinct user_id) from task_user_complete_record where task_id = #{taskId} and created_time between #{beginOfDay} and #{endOfDay}")
+	Integer getTodayCompleteNum(@Param("taskId") Long taskId, @Param("beginOfDay") DateTime beginOfDay, @Param("endOfDay") DateTime endOfDay);
+
+	@Select("select count(distinct user_id) from task_user_complete_record where task_id = #{taskId}")
+	Integer getSumCompleteNum(Long taskId);
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/market/task/UserBindPhoneMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.market.task;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.UserBindPhone;
+
+/*
+ *项目名: netflix
+ *文件名: UserBindPhoneMapper
+ *创建者: JavaZou
+ *创建时间:2022/12/29 13:54
+ */
+public interface UserBindPhoneMapper extends BaseMapper<UserBindPhone> {
+}

+ 0 - 5
netflix-dao/src/main/java/com/cyksj/model/entity/BaseEntity.java

@@ -1,8 +1,6 @@
 package com.cyksj.model.entity;
 
-import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.ejlchina.searcher.bean.DbField;
 import lombok.Data;
@@ -19,7 +17,6 @@ import java.util.Date;
 public class BaseEntity {
 
     @TableId(value = "id",type = IdType.AUTO)
-    @DbField("id")
     private Long id;
 
     /**
@@ -27,13 +24,11 @@ public class BaseEntity {
      */
 
     @DbField("created_time")
-    @TableField(fill = FieldFill.INSERT)
     private Date createdTime;
 
     /**
      * 修改时间
      */
     @DbField("update_time")
-    @TableField(fill = FieldFill.INSERT_UPDATE)
     private Date updateTime;
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java

@@ -56,6 +56,9 @@ public class CouponUser extends BaseEntity {
 		center("unused", "领卷中心"),
 		exCode("exCode", "兑换码"),
 		wxCorp("wxCorp", "企业微信"),
+		manual("manual","手动发放"),
+		lottery("lottery","抽奖"),
+		task("task","完成任务"),
 		;
 		private String channel;
 		private String desc;

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/ExchangeCode.java

@@ -40,4 +40,9 @@ public class ExchangeCode extends BaseEntity{
 	 * 使用人id
 	 */
 	private Long userId;
+
+	/**
+	 * 0平台 1抽奖
+	 */
+	private Integer type;
 }

+ 62 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/LuckyDraw.java

@@ -0,0 +1,62 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDraw
+ *创建者: JavaZou
+ *创建时间:2022/12/27 15:57
+ */
+@Getter
+@Setter
+public class LuckyDraw extends BaseEntity {
+	@NotNull(message = "类型不能为空")
+	private Type type;
+
+	@NotEmpty(message = "奖品名称不能为空")
+	private String name;
+
+	private Integer points;
+
+	private Long couponId;
+
+	private Long goodsId;
+
+	private Long skuId;
+
+	private Integer cost;
+
+	private Integer num;
+
+	@NotEmpty(message = "奖品位置不能为空")
+	private String position;
+
+	@NotNull(message = "概率不能为空")
+	private BigDecimal probability;
+
+	private String picture;
+
+	private Boolean status;
+
+	private Boolean deleted;
+
+	@Getter
+	public enum Type {
+		points("积分"),
+		coupon("优惠券"),
+		realGoods("实物"),
+		virtualGoods("虚物"),
+		;
+		String desc;
+
+		Type(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 56 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/LuckyDrawRecord.java

@@ -0,0 +1,56 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawRecord
+ *创建者: JavaZou
+ *创建时间:2022/12/28 14:49
+ */
+@Getter
+@Setter
+public class LuckyDrawRecord extends BaseEntity{
+	private LuckyDraw.Type type;
+
+	private Long userId;
+
+	private Long drawId;
+
+	private Long orderId;
+
+	private String name;
+
+	private Integer points;
+
+	private Long couponId;
+
+	private Long goodsId;
+
+	private Long skuId;
+
+	private Integer cost;
+
+	/**
+	 * 兑换码
+	 */
+	private String exCode;
+
+	private String picture;
+
+	private Status status;
+
+	@Getter
+	public enum Status{
+		pending("待领取"),
+		success("已领取");
+		;
+
+		String desc;
+
+		Status(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 1 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java

@@ -141,6 +141,7 @@ public class OrderDon extends BaseEntity implements Serializable {
         WeChat("wechat","微信"),
         ALI_PAY("zfb","支付宝"),
         EX_CODE("exchange_code","兑换码"),
+        LOTTERY("lottery","抽奖"),
         ;
         String type;
         String desc;

+ 14 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/SignConfig.java

@@ -0,0 +1,14 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class SignConfig extends BaseEntity{
+    private String type;
+
+    private Integer minPoints;
+
+    private Integer maxPoints;
+}

+ 83 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/SignStatisticsData.java

@@ -0,0 +1,83 @@
+package com.cyksj.model.entity;
+
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: SignStatisticsData
+ *创建者: JavaZou
+ *创建时间:2022/12/27 18:19
+ */
+@Getter
+@Setter
+@SearchBean(tables = "sign_statistics_data")
+public class SignStatisticsData extends BaseEntity {
+	/**
+	 * 今日签到人数
+	 */
+	private Integer todayNumOfSign;
+
+	/**
+	 * 今日发放积分
+	 */
+	private Integer todayNumOfPoints;
+
+	/**
+	 * 累计发放积分
+	 */
+	private Integer sumOfPoints;
+
+	/**
+	 * 今日使用积分
+	 */
+	private Integer todayUseOfPoints;
+
+	/**
+	 * 累计使用积分
+	 */
+	private Integer sumUseOfPoints;
+
+	/**
+	 * 今日抽奖次数
+	 */
+	private Integer todayNumOfLottery;
+
+	/**
+	 * 连签2天
+	 */
+	private Integer t2;
+
+	/**
+	 * 连签3天
+	 */
+	private Integer t3;
+
+	/**
+	 * 连签4天
+	 */
+	private Integer t4;
+
+	/**
+	 * 连签5天
+	 */
+	private Integer t5;
+
+	/**
+	 * 连签6天
+	 */
+	private Integer t6;
+
+	/**
+	 * 连签7天
+	 */
+	private Integer t7;
+
+	/**
+	 * 统计日期
+	 */
+	private Date statisticsDate;
+}

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/SignUser.java

@@ -0,0 +1,34 @@
+package com.cyksj.model.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class SignUser extends BaseEntity{
+    private Long userId;
+
+    /**
+     * 签到天数
+     */
+    private Integer day;
+
+    /**
+     * 周期签到天数(7天)
+     */
+    private Integer dayPeriod;
+
+    /**
+     * 是否已签 true 签到成功 false 已签到
+     */
+    @TableField(exist = false)
+    private Boolean isHadChecked;
+
+    /**
+     * 签到发放的积分
+     */
+    @TableField(exist = false)
+    private Integer points;
+}

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/Task.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.entity;
+
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: Task
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:36
+ */
+@Getter
+@Setter
+@SearchBean(tables = "task")
+public class Task extends BaseEntity{
+	@NotEmpty(message = "任务名称不能为空")
+	private String name;
+
+	/**
+	 * 类型id
+	 */
+	@NotNull(message = "类型不能为空")
+	private Long typeId;
+
+	private String description;
+
+	/**
+	 * 任务时限 time,day,week
+	 */
+	@NotEmpty(message = "任务时限不能为空")
+	private String taskLimit;
+
+	private Long couponId;
+
+	/**
+	 * 邀请人数
+	 */
+	private Integer inviteNum;
+
+	/**
+	 * 积分
+	 */
+	@NotNull(message = "积分不能为空")
+	@Min(value = 1)
+	private Integer points;
+
+	private Boolean deleted;
+}

+ 45 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/TaskFollowPlatVerify.java

@@ -0,0 +1,45 @@
+package com.cyksj.model.entity;
+
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFollowPlatVerify
+ *创建者: JavaZou
+ *创建时间:2023/1/6 14:03
+ */
+@Getter
+@Setter
+@SearchBean(tables = "task_follow_plat_verify")
+public class TaskFollowPlatVerify extends BaseEntity {
+	private Long taskId;
+
+	private Long userId;
+
+	private String platNickname;
+
+	private String img;
+
+	private Status status;
+
+	private String errorReason;
+
+	private Date verifyTime;
+
+	@Getter
+	public enum Status {
+		verifying("审核中"),
+		fail("审核失败"),
+		success("审核成功"),
+		;
+		String desc;
+
+		Status(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 16 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/TaskType.java

@@ -0,0 +1,16 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TaskType
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:35
+ */
+@Getter
+@Setter
+public class TaskType extends BaseEntity{
+	private String name;
+}

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/TaskUserCompleteRecord.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TaskUserCompleteRecord
+ *创建者: JavaZou
+ *创建时间:2022/12/28 17:11
+ */
+@Setter
+@Getter
+public class TaskUserCompleteRecord extends BaseEntity {
+	private Long userId;
+
+	private Long taskId;
+
+	private Status status;
+
+	private Integer points;
+
+	@Getter
+	public enum Status {
+		waiting("待完成"),
+		complete("已完成"),
+		received("已领取"),
+		verifying("审核中"),
+		fail("审核失败"),
+		;
+		String desc;
+
+		Status(String desc) {
+			this.desc = desc;
+		}
+	}
+}

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/User.java

@@ -45,5 +45,7 @@ public class User extends BaseEntity implements Serializable{
     private Integer sex ;
 
     private BigDecimal points;
+
+    private BigDecimal activePoints;
 }
 

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserBindPhone.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserBindPhone
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:39
+ */
+@Getter
+@Setter
+public class UserBindPhone extends BaseEntity{
+	private Long userId;
+
+	private String phone;
+}

+ 15 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserPointsRecord.java

@@ -0,0 +1,15 @@
+package com.cyksj.model.entity;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class UserPointsRecord extends BaseEntity{
+    private Long userId;
+
+    private Integer points;
+
+    private String remark;
+}

+ 24 - 2
netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java

@@ -6,13 +6,17 @@ import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * @author chan
  * @date 2022/10/12 2:31 PM
  */
 @Getter
 @Setter
-@SearchBean(tables = "user u left join user_distribute_shared usd on usd.user_id = u.id")
+@SearchBean(tables = "user u left join user_distribute_shared usd on usd.user_id = u.id" +
+        " left join user_bind_phone up on up.user_id = u.id")
 public class UserView {
 
     /**
@@ -33,6 +37,12 @@ public class UserView {
     @DbField("u.phone")
     private String phone;
 
+    /**
+     * 绑定手机号
+     */
+    @DbField("up.phone")
+    private String bindPhone;
+
     /**
      * 头像
      */
@@ -49,7 +59,13 @@ public class UserView {
      * 积分
      */
     @DbField("u.points")
-    private Integer points;
+    private BigDecimal points;
+
+    /**
+     * 活跃抽奖积分
+     */
+    @DbField("u.active_points")
+    private BigDecimal activePoints;
 
     /**
      * 账户数
@@ -63,6 +79,12 @@ public class UserView {
     @DbField("usd.shared_id")
     private Long sharedId;
 
+    /**
+     * 创建时间
+     */
+    @DbField("u.created_time")
+    private Date createdTime;
+
     /**
      * 邀请人名称
      */

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ExchangeCodeReq.java

@@ -26,4 +26,9 @@ public class ExchangeCodeReq {
 	 * 数量
 	 */
 	private Integer number;
+
+	/**
+	 * 0平台 1抽奖
+	 */
+	private Integer type;
 }

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/request/LuckyDrawReq.java

@@ -0,0 +1,26 @@
+package com.cyksj.model.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawReq
+ *创建者: JavaZou
+ *创建时间:2022/12/28 16:37
+ */
+@Getter
+@Setter
+public class LuckyDrawReq {
+
+	/**
+	 * 地址id
+	 */
+	@NotNull
+	private Long addressId;
+
+	@NotNull
+	private Long recordId;
+}

+ 44 - 0
netflix-dao/src/main/java/com/cyksj/model/request/TaskFollowReq.java

@@ -0,0 +1,44 @@
+package com.cyksj.model.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFollowReq
+ *创建者: JavaZou
+ *创建时间:2023/1/6 13:55
+ */
+@Getter
+@Setter
+public class TaskFollowReq {
+	/**
+	 * 提交记录id
+	 */
+	private Long id;
+
+	/**
+	 * 关注任务id
+	 */
+	@NotNull
+	@Min(value = 1)
+	private Long taskId;
+
+	/**
+	 * 所在平台昵称
+	 */
+	@NotEmpty(message = "昵称不能为空")
+	private String platNickname;
+
+	/**
+	 * 关注平台截图
+	 */
+	@NotEmpty(message = "截图不能为空")
+	private String img;
+
+	private Long userId;
+}

+ 2 - 1
netflix-dao/src/main/java/com/cyksj/model/views/ExchangeCodeView.java

@@ -17,7 +17,8 @@ import java.util.Date;
 @Setter
 @SearchBean(tables = "exchange_code ec left join user u on u.id = ec.user_id" +
 		" left join goods_don gd on ec.goods_id = gd.id" +
-		" left join goods_don_sku gdk on gdk.id = ec.sku_id")
+		" left join goods_don_sku gdk on gdk.id = ec.sku_id",
+where = "ec.type = 0")
 public class ExchangeCodeView {
 	@DbField("ec.id")
 	private Long id;

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuView.java

@@ -34,4 +34,10 @@ public class GoodsDonSkuView {
 
 	@DbField("gdk.price")
 	private BigDecimal money;
+
+	@DbField("gd.status")
+	private Boolean goodsDonStatus;
+
+	@DbField("gdk.status")
+	private Boolean goodsDonSkuStatus;
 }

+ 77 - 0
netflix-dao/src/main/java/com/cyksj/model/views/LuckyDrawRecordView.java

@@ -0,0 +1,77 @@
+package com.cyksj.model.views;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawRecordView
+ *创建者: JavaZou
+ *创建时间:2022/12/28 16:56
+ */
+
+import com.cyksj.model.entity.LuckyDraw;
+import com.cyksj.model.entity.LuckyDrawRecord;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+@SearchBean(tables = "lucky_draw_record lr" +
+		" left join coupon c on c.id = lr.coupon_id" +
+		" left join goods_don gd on gd.id = lr.goods_id" +
+		" left join goods_don_sku gdk on gdk.id = lr.sku_id")
+public class LuckyDrawRecordView {
+	@DbField("lr.id")
+	private Long id;
+
+	@DbField("lr.user_id")
+	private Long userId;
+
+	@DbField("lr.type")
+	private LuckyDraw.Type type;
+
+	@DbField("lr.name")
+	private String name;
+
+	@DbIgnore
+	private String nickname;
+
+	@DbField("lr.points")
+	private Integer points;
+
+	@DbField("lr.coupon_id")
+	private Long couponId;
+
+	@DbField("c.name")
+	private String couponName;
+
+	@DbField("lr.goods_id")
+	private Long goodsId;
+
+	@DbField("gd.title")
+	private String goodsName;
+
+	@DbField("lr.sku_id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("lr.ex_code")
+	private String exCode;
+
+	@DbField("lr.picture")
+	private String picture;
+
+	@DbField("lr.cost")
+	private Integer cost;
+
+	@DbField("lr.status")
+	private LuckyDrawRecord.Status status;
+
+	@DbField("lr.created_time")
+	private Date createdTime;
+}

+ 100 - 0
netflix-dao/src/main/java/com/cyksj/model/views/LuckyDrawView.java

@@ -0,0 +1,100 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.LuckyDraw;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawView
+ *创建者: JavaZou
+ *创建时间:2022/12/27 16:35
+ */
+@Getter
+@Setter
+@SearchBean(tables = "lucky_draw ld" +
+		" left join coupon c on c.id = ld.coupon_id" +
+		" left join goods_don gd on gd.id = ld.goods_id" +
+		" left join goods_don_sku gdk on gdk.id = ld.sku_id",
+where = "ld.deleted is true")
+public class LuckyDrawView {
+	@DbField("ld.id")
+	private Long id;
+
+	@DbField("ld.type")
+	private LuckyDraw.Type type;
+
+	@DbField("ld.name")
+	private String name;
+
+	@DbField("ld.points")
+	private Integer points;
+
+	@DbField("ld.coupon_id")
+	private Long couponId;
+
+	/**
+	 * 优惠券名称
+	 */
+	@DbField("c.name")
+	private String couponName;
+
+	@DbField("ld.goods_id")
+	private Long goodsId;
+
+	/**
+	 * 平台名称
+	 */
+	@DbField("gd.title")
+	private String goodsName;
+
+	@DbField("ld.sku_id")
+	private Long skuId;
+
+	/**
+	 * 规格
+	 */
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("ld.cost")
+	private Integer cost;
+
+	@DbField("ld.position")
+	private String position;
+
+	@DbField("ld.probability")
+	private BigDecimal probability;
+
+	@DbField("ld.num")
+	private Integer num;
+
+	@DbField("ld.picture")
+	private String picture;
+
+	@DbField("ld.status")
+	private Boolean status;
+
+	/**
+	 * 中奖人数
+	 */
+	@DbIgnore
+	private Integer LotteryNum;
+
+	/**
+	 * 中奖次数
+	 */
+	@DbIgnore
+	private Integer LotteryCount;
+
+	/**
+	 * 奖品领取次数
+	 */
+	@DbIgnore
+	private Integer luckyOrderCount;
+}

+ 54 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TaskFollowVerifyView.java

@@ -0,0 +1,54 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFollowVerifyView
+ *创建者: JavaZou
+ *创建时间:2023/1/6 14:21
+ */
+@Getter
+@Setter
+@SearchBean(tables = "task_follow_plat_verify tv left join task t on t.id = tv.task_id" +
+		" left join user u on u.id = tv.user_id")
+public class TaskFollowVerifyView {
+	@DbField("tv.id")
+	private Long id;
+
+	@DbField("u.id")
+	private Long userId;
+
+	@DbField("tv.task_id")
+	private Long taskId;
+
+	@DbField("u.nickname")
+	private String nickname;
+
+	@DbField("tv.plat_nickname")
+	private String platNickname;
+
+	@DbField("tv.img")
+	private String img;
+
+	@DbField("t.points")
+	private Integer points;
+
+	@DbField("tv.status")
+	private TaskFollowPlatVerify.Status status;
+
+	@DbField("tv.error_reason")
+	private String errorReason;
+
+	@DbField("tv.created_time")
+	private Date createdTime;
+
+	@DbField("tv.verify_time")
+	private Date verifyTime;
+}

+ 79 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TaskFrontView.java

@@ -0,0 +1,79 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.TaskUserCompleteRecord;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFrontView
+ *创建者: JavaZou
+ *创建时间:2022/12/28 17:21
+ */
+@Getter
+@Setter
+@SearchBean(tables = "task t left join task_type tt on tt.id = t.type_id" +
+		" left join coupon c on c.id = t.coupon_id",
+		where = "t.deleted is true")
+public class TaskFrontView {
+
+	@DbField("t.id")
+	private Long id;
+
+	@DbField("t.name")
+	private String name;
+
+	/**
+	 * 类型id
+	 */
+	@DbField("t.type_id")
+	private Long typeId;
+
+	@DbField("t.description")
+	private String description;
+
+	/**
+	 * 任务时限 time,day,week
+	 */
+	@DbField("t.task_limit")
+	private String taskLimit;
+
+	@DbField("tt.name")
+	private String typeName;
+
+	@DbField("t.coupon_id")
+	private Long couponId;
+
+	@DbField("c.name")
+	private String couponName;
+
+	/**
+	 * 邀请人数
+	 */
+	@DbField("t.invite_num")
+	private Integer inviteNum;
+
+	/**
+	 * 个人邀请人数
+	 */
+	@DbIgnore
+	private Integer hadInvitedNum;
+
+	@DbIgnore
+	private String phone;
+
+	/**
+	 * 积分
+	 */
+	@DbField("t.points")
+	private Integer points;
+
+	@DbIgnore
+	private Long taskCompleteRecordId;
+
+	@DbIgnore
+	private TaskUserCompleteRecord.Status status = TaskUserCompleteRecord.Status.waiting;
+}

+ 82 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TaskView.java

@@ -0,0 +1,82 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TaskView
+ *创建者: JavaZou
+ *创建时间:2022/12/27 15:35
+ */
+@Getter
+@Setter
+@SearchBean(tables = "task t left join task_type tt on tt.id = t.type_id",
+where = "t.deleted is true")
+public class TaskView {
+	@DbField("t.id")
+	private Long id;
+
+	/**
+	 * 类型id
+	 */
+	@DbField("tt.id")
+	private Long typeId;
+
+	@DbField("t.name")
+	private String name;
+
+	@DbField("tt.name")
+	private String typeName;
+
+	@DbField("t.description")
+	private String description;
+
+	@DbField("t.task_limit")
+	private String taskLimit;
+
+	@DbField("t.points")
+	private Integer points;
+
+	@DbField("t.coupon_id")
+	private Long couponId;
+
+	/**
+	 * 邀请人数
+	 */
+	@DbField("t.invite_num")
+	private Integer inviteNum;
+
+	/**
+	 * 今天完成人数
+	 */
+	@DbIgnore
+	private Integer todayCompleteNum;
+
+	/**
+	 * 累计完成人数
+	 */
+	@DbIgnore
+	private Integer sumCompleteNum;
+
+	/**
+	 * 今日奖励积分
+	 */
+	@DbIgnore
+	private Integer todayPoints;
+
+	/**
+	 * 累计奖励积分
+	 */
+	@DbIgnore
+	private Integer sumPoints;
+
+	/**
+	 * 待审核数量
+	 */
+	@DbIgnore
+	private Integer verifyNum;
+}

+ 43 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserPersonalView.java

@@ -0,0 +1,43 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: UserPersonalView
+ *创建者: JavaZou
+ *创建时间:2022/12/29 15:46
+ */
+@Getter
+@Setter
+public class UserPersonalView {
+	/**
+	 * 可用优惠券数量
+	 */
+	private Integer numOfCoupons;
+
+	/**
+	 * 车票数量
+	 */
+	private Integer numOfTickets;
+
+	/**
+	 * 我的积分
+	 */
+	private BigDecimal activePoints;
+
+	/**
+	 * 推广积分
+	 */
+	private BigDecimal popularizePoints;
+
+	/**
+	 * 是否有待支付订单 true有
+	 */
+	private Boolean isNoPayment;
+
+	private String phone;
+}

+ 3 - 1
netflix-service/src/main/java/com/cyksj/redis/RedisService.java

@@ -589,7 +589,9 @@ public class RedisService {
 	    CORP_ACCESSO_TOKEN_KEY("corp:access_token:", "corp_access_token", 60 * 30L),
 	    MAPPING_INDEX_KEY("mapper:index:", "授权跳转", 60 * 10L),
         WX_LOGIN_AUTH_URI("wx_login_auth_uri:%s", "微信网页授权登录uri", 60 * 60 * 24L),
-        RECOMMEND_COUPON_DAY("recommend_coupon_day:%s", "推荐优惠券弹窗", 60 * 60 * 24L)
+        RECOMMEND_COUPON_DAY("recommend_coupon_day:%s", "推荐优惠券弹窗", 60 * 60 * 24L),
+        LOTTERY_KEY("lottery_key:%s", "抽奖key", 60 * 60 * 24l),
+        TASK_TIME_LIMIT_KEY("task_time_limit:%s", "一次性任务key", 30),
         ;
 
         private String name;

+ 7 - 0
netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java

@@ -16,6 +16,7 @@ import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.*;
 import com.cyksj.mapper.manage.exchange.ExchangeCodeMapper;
+import com.cyksj.mapper.market.draw.LuckyDrawRecordMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.excel.ExcelExchangeCodeData;
 import com.cyksj.model.request.ExchangeCodeReq;
@@ -69,6 +70,8 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 
 	private final CustomerServiceMapper customerServiceMapper;
 
+	private final LuckyDrawRecordMapper luckyDrawRecordMapper;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public List<ExcelExchangeCodeData> createExchangeCode(ExchangeCodeReq exchangeCodeReq) {
@@ -99,6 +102,7 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 			exchangeCode.setSkuId(exchangeCodeReq.getSkuId());
 			exchangeCode.setCode(sb.toString());
 			exchangeCode.setUseStatus(false);
+			exchangeCode.setType(exchangeCodeReq.getType());
 			exchangeCodeMapper.insert(exchangeCode);
 			ExcelExchangeCodeData excelExchangeCodeData = new ExcelExchangeCodeData();
 			BeanUtils.copyProperties(exchangeCode, excelExchangeCodeData);
@@ -137,6 +141,9 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 		//生成车票订单
 		getGroupTripsTicket(goodsDonSkuMapper.selectById(exchangeCode.getSkuId()), userId);
 		log.info("用户:{}通过兑换码:{}兑换成功", userId, exchangeCodeTicket.getCode());
+		if (exchangeCode.getType() == 1) {
+			luckyDrawRecordMapper.updateExCodeStatus(userId, exchangeCode.getCode());
+		}
 		return GatewayResponse.SUCCESS.newBuilder().toResult("兑换成功");
 	}
 

+ 6 - 0
netflix-service/src/main/java/com/cyksj/service/mange/coupon/CouponCommonService.java

@@ -2,6 +2,7 @@ package com.cyksj.service.mange.coupon;
 
 import com.cyksj.model.entity.Coupon;
 import com.cyksj.model.entity.CouponDistributePopularize;
+import com.cyksj.model.entity.CouponUser;
 import com.cyksj.model.request.CorpCouponSendReq;
 import com.cyksj.model.request.CouponActiveReq;
 import com.cyksj.model.request.CouponDistributeReq;
@@ -59,4 +60,9 @@ public interface CouponCommonService {
 	 * 发放优惠券
 	 */
 	void corpSendCoupon(CorpCouponSendReq corpCouponSendReq) throws Exception;
+
+	/**
+	 * 发放优惠券至用户
+	 */
+	Boolean sendCouponToUser(Long userId, Long couponId, Long couponActiveId, Long recommendId, Long popularizeId, CouponUser.Channel channel);
 }

+ 24 - 0
netflix-service/src/main/java/com/cyksj/service/mange/coupon/impl/CouponCommonServiceImpl.java

@@ -199,6 +199,30 @@ public class CouponCommonServiceImpl implements CouponCommonService {
 		}
 	}
 
+	@Override
+	public Boolean sendCouponToUser(Long userId, Long couponId, Long couponActiveId, Long recommendId, Long popularizeId, CouponUser.Channel channel) {
+		CouponUser couponUser = couponUserMapper.selectOne(Wrappers.lambdaQuery(CouponUser.class).eq(CouponUser::getUserId, userId).eq(CouponUser::getCouponId, couponId).last("limit 1"));
+		if (couponUser == null) {
+			couponUser = new CouponUser();
+			couponUser.setUserId(userId);
+			couponUser.setCouponId(couponId);
+			//领券中心
+			couponUser.setChannel(channel);
+			couponUser.setStatus(CouponUser.Status.unused);
+			couponUser.setCouponActiveId(couponActiveId);
+			couponUser.setRecommendId(recommendId);
+			couponUser.setPopularizeId(recommendId);
+			//优惠券有效时间
+			couponFontService.updateCouponUserValidTime(couponId, couponUser);
+			try {
+				couponUserMapper.insert(couponUser);
+				return true;
+			} catch (DuplicateKeyException e) {
+				log.info("用户:{}重复领取优惠券{}插入数据错误", userId, couponId);
+			}
+		}
+		return false;
+	}
 
 	public void checkCouponParamsAndSaveOrUpdate(Coupon coupon) throws Exception {
 		List<Coupon.CouponGoodsSku> goodsSkuList = Jsons.parseList(coupon.getGoodsSkuIds(), Coupon.CouponGoodsSku.class);

+ 31 - 0
netflix-service/src/main/java/com/cyksj/service/market/MarketFrontService.java

@@ -0,0 +1,31 @@
+package com.cyksj.service.market;
+
+
+import com.cyksj.model.entity.SignUser;
+import com.cyksj.model.request.LuckyDrawReq;
+import com.cyksj.model.request.TaskFollowReq;
+import com.cyksj.model.views.LuckyDrawView;
+import com.cyksj.model.views.TaskFrontView;
+
+public interface MarketFrontService {
+	SignUser signByUserId(Long userId);
+
+	SignUser getUserSignDetail(Long userId);
+
+	/**
+	 * 记录积分明细,发放积分
+	 */
+	void pointsRecord(Long userId, Integer points, String remark, Boolean isLottery);
+
+	LuckyDrawView lottery(Long userId);
+
+	void receivedLuckyDraw(Long userId, LuckyDrawReq luckyDrawReq);
+
+	void updateTaskStatus(TaskFrontView data, Long userId);
+
+	void receivedTaskPoints(Long userId, Long taskId);
+
+	void toCompleteFollowTask(TaskFollowReq taskFollowReq);
+
+	void updateFailFollowTask(TaskFollowReq taskFollowReq);
+}

+ 17 - 0
netflix-service/src/main/java/com/cyksj/service/market/draw/LuckyDrawService.java

@@ -0,0 +1,17 @@
+package com.cyksj.service.market.draw;
+
+import com.cyksj.model.entity.LuckyDraw;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawService
+ *创建者: JavaZou
+ *创建时间:2022/12/27 16:04
+ */
+public interface LuckyDrawService {
+	void saveLuckyDraw(LuckyDraw luckyDraw) throws Exception;
+
+	void putStatus(Long id) throws Exception;
+
+	void updateLuckyDraw(LuckyDraw luckyDraw) throws Exception;
+}

+ 133 - 0
netflix-service/src/main/java/com/cyksj/service/market/draw/impl/LuckyDrawServiceImpl.java

@@ -0,0 +1,133 @@
+package com.cyksj.service.market.draw.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.mapper.manage.coupon.CouponMapper;
+import com.cyksj.mapper.market.draw.LuckyDrawMapper;
+import com.cyksj.model.entity.Coupon;
+import com.cyksj.model.entity.LuckyDraw;
+import com.cyksj.model.views.GoodsDonSkuView;
+import com.cyksj.service.market.draw.LuckyDrawService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.HashSet;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawServiceImpl
+ *创建者: JavaZou
+ *创建时间:2022/12/27 16:05
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class LuckyDrawServiceImpl implements LuckyDrawService {
+	private final LuckyDrawMapper luckyDrawMapper;
+
+	private final CouponMapper couponMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	@Override
+	public void saveLuckyDraw(LuckyDraw luckyDraw) throws Exception {
+		//校验参数
+		checkLuckyDraw(luckyDraw);
+		luckyDrawMapper.insert(luckyDraw);
+	}
+
+	@Override
+	public void putStatus(Long id) throws Exception {
+		LuckyDraw luckyDraw = luckyDrawMapper.selectById(id);
+		if (luckyDraw == null || !luckyDraw.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("该奖品已不存在");
+		}
+		if (!luckyDraw.getStatus()) {
+			//剔除相同位置的奖品
+			changeLuckyDrawIndex(luckyDraw);
+		}
+		luckyDraw.setStatus(!luckyDraw.getStatus());
+		luckyDrawMapper.updateById(luckyDraw);
+	}
+
+	@Override
+	public void updateLuckyDraw(LuckyDraw luckyDraw) throws Exception {
+		if (luckyDraw.getId() == null || luckyDraw.getId() < 1) {
+			throw BusinessRuntimeException.getInstance("奖品id为空");
+		}
+		LuckyDraw entity = luckyDrawMapper.selectById(luckyDraw.getId());
+		if (entity == null || !entity.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("该奖品已不存在");
+		}
+		if (entity.getStatus()) {
+			changeLuckyDrawIndex(luckyDraw);
+		}
+		BeanUtil.copyProperties(luckyDraw, entity);
+		//校验参数
+		checkLuckyDraw((entity));
+		luckyDrawMapper.updateById(entity);
+	}
+
+	public void checkLuckyDraw(LuckyDraw luckyDraw) throws Exception {
+		HashSet<Integer> set = Jsons.parseObject(luckyDraw.getPosition(), HashSet.class);
+		for (Integer index : set) {
+			if (index < 1 || index > 9) {
+				throw BusinessRuntimeException.getInstance("奖品位置错误");
+			}
+		}
+		luckyDraw.setPosition(set.toString());
+		if (luckyDraw.getType() == LuckyDraw.Type.coupon) {
+			//优惠券是否存在
+			if (luckyDraw.getCouponId() == null || luckyDraw.getCouponId() < 1) {
+				throw BusinessRuntimeException.getInstance("选择的优惠券不存在");
+			}
+			Long couponId = luckyDraw.getCouponId();
+			Coupon coupon = couponMapper.selectById(couponId);
+			if (coupon == null) {
+				throw BusinessRuntimeException.getInstance("选择的优惠券不存在");
+			}
+		} else if (luckyDraw.getType() == LuckyDraw.Type.points) {
+			if (luckyDraw.getPoints() == null || luckyDraw.getPoints() < 0) {
+				throw BusinessRuntimeException.getInstance("积分为空");
+			}
+		} else {
+			GoodsDonSkuView goodsDonSkuView = beanSearcher.searchFirst(GoodsDonSkuView.class, MapUtils.builder()
+					.field(GoodsDonSkuView::getGoodsId, luckyDraw.getGoodsId()).op(Operator.Equal)
+					.field(GoodsDonSkuView::getSkuId, luckyDraw.getSkuId()).op(Operator.Equal)
+					.field(GoodsDonSkuView::getGoodsDonStatus, true).op(Operator.Equal)
+					.field(GoodsDonSkuView::getGoodsDonSkuStatus, true).op(Operator.Equal).build());
+			if (goodsDonSkuView == null) {
+				throw BusinessRuntimeException.getInstance("所选平台或规格 不存在或已下架");
+			}
+		}
+	}
+
+	public void changeLuckyDrawIndex(LuckyDraw entity) throws Exception {
+		//先找出所有已上架的商品
+		List<LuckyDraw> luckyDraws = luckyDrawMapper.selectList(Wrappers.lambdaQuery(LuckyDraw.class)
+				.eq(LuckyDraw::getStatus, true)
+				.ne(LuckyDraw::getId, entity.getId()));
+		List<Integer> self = Jsons.parseList(entity.getPosition(), Integer.class);
+		for (LuckyDraw luckyDraw : luckyDraws) {
+			List<Integer> list = Jsons.parseList(luckyDraw.getPosition(), Integer.class);
+			for (Integer selfIndex : self) {
+				if (list.contains(selfIndex)) {
+					if (list.size() == 1) {
+						luckyDraw.setStatus(false);
+					} else {
+						list.removeIf(i -> i.equals(selfIndex));
+						luckyDraw.setPosition(list.toString());
+					}
+					luckyDrawMapper.updateById(luckyDraw);
+				}
+			}
+		}
+	}
+}

+ 575 - 0
netflix-service/src/main/java/com/cyksj/service/market/impl/MarketFrontServiceImpl.java

@@ -0,0 +1,575 @@
+package com.cyksj.service.market.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.common.constant.PointsRecordConst;
+import com.cyksj.common.constant.TaskTypeEnum;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.snowflake.Sequence;
+import com.cyksj.mapper.AddressMapper;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.mapper.OrderDonTransportMapper;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.corp.CorpUserMapper;
+import com.cyksj.mapper.manage.coupon.CouponUserMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
+import com.cyksj.mapper.market.draw.LuckyDrawRecordMapper;
+import com.cyksj.mapper.market.sign.SignConfigMapper;
+import com.cyksj.mapper.market.sign.SignUserMapper;
+import com.cyksj.mapper.market.sign.UserPointsRecordMapper;
+import com.cyksj.mapper.market.task.TaskFollowPlatVerifyMapper;
+import com.cyksj.mapper.market.task.TaskUserCompleteRecordMapper;
+import com.cyksj.mapper.market.task.UserBindPhoneMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.excel.ExcelExchangeCodeData;
+import com.cyksj.model.request.ExchangeCodeReq;
+import com.cyksj.model.request.LuckyDrawReq;
+import com.cyksj.model.request.TaskFollowReq;
+import com.cyksj.model.views.LuckyDrawView;
+import com.cyksj.model.views.TaskFrontView;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.exchange.ExchangeCodeService;
+import com.cyksj.service.mange.coupon.CouponCommonService;
+import com.cyksj.service.market.MarketFrontService;
+import com.cyksj.service.sys.SysConfigService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class MarketFrontServiceImpl implements MarketFrontService {
+	private final SignUserMapper signUserMapper;
+
+	private final SignConfigMapper signConfigMapper;
+
+	private final UserPointsRecordMapper userPointsRecordMapper;
+
+	private final SysConfigService sysConfigService;
+
+	private final UserMapper userMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	private final CouponCommonService couponCommonService;
+
+	private final CouponUserMapper couponUserMapper;
+
+	private final ExchangeCodeService exchangeCodeService;
+
+	private final LuckyDrawRecordMapper luckyDrawRecordMapper;
+
+	private final OrderDonMapper orderDonMapper;
+
+	private final AddressMapper addressMapper;
+
+	private final OrderDonTransportMapper orderDonTransportMapper;
+
+	private static final Sequence SEQUENCE = new Sequence(0);
+
+	private final CorpUserMapper corpUserMapper;
+
+	private final TaskUserCompleteRecordMapper taskUserCompleteRecordMapper;
+
+	private final UserDistributeSharedMapper userDistributeSharedMapper;
+
+	private final UserBindPhoneMapper userBindPhoneMapper;
+
+	private final RedisService redisService;
+
+	private final TaskFollowPlatVerifyMapper taskFollowPlatVerifyMapper;
+
+	@Override
+	public SignUser signByUserId(Long userId) {
+		//第一次签到
+		SignUser signUser = signUserMapper.selectOne(Wrappers.lambdaQuery(SignUser.class)
+				.eq(SignUser::getUserId, userId).last("limit 1"));
+		if (signUser == null) {
+			log.info("用户:{}第一次签到", userId);
+			signUser = new SignUser();
+			signUser.setUserId(userId);
+			signUser.setDay(1);
+			signUser.setDayPeriod(1);
+			try {
+				signUserMapper.insert(signUser);
+				//发放积分
+				updateUserSignDay(signUser, true);
+				signUser.setIsHadChecked(true);
+			} catch (DuplicateKeyException e) {
+				log.info("用户:{}重复签到记录插入", userId);
+			}
+		}else {
+			//更新签到
+			signCheck(signUser);
+		}
+		SignUser sign = signUserMapper.selectOne(Wrappers.lambdaQuery(SignUser.class)
+				.eq(SignUser::getUserId, userId).last("limit 1"));
+		sign.setPoints(signUser.getPoints());
+		sign.setIsHadChecked(signUser.getIsHadChecked());
+		return sign;
+	}
+
+	@Override
+	public SignUser getUserSignDetail(Long userId) {
+		//未签到时,签到
+		SignUser signUser = signByUserId(userId);
+		return signUser;
+	}
+
+	@Override
+	public void pointsRecord(Long userId, Integer points, String remark, Boolean isLottery) {
+		UserPointsRecord userPointsRecord = new UserPointsRecord();
+		userPointsRecord.setUserId(userId);
+		userPointsRecord.setPoints(points);
+		userPointsRecord.setRemark(remark);
+		userPointsRecordMapper.insert(userPointsRecord);
+
+		if (!isLottery) {
+			//发放爱心
+			userPointsRecordMapper.updateUserPoints(userId, points);
+		}
+	}
+
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public LuckyDrawView lottery(Long userId) {
+		SysConfig lottery_points_limit = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "lottery_points_limit").last("limit 1"));
+		User user = userMapper.selectById(userId);
+		BigDecimal subPoints = BigDecimal.valueOf(Long.parseLong(lottery_points_limit.getSysValue()));
+		if (user.getActivePoints().compareTo(subPoints) < 0) {
+			throw BusinessRuntimeException.getInstance("积分不足");
+		}
+		//扣减积分
+		Integer sub = userMapper.subActivePoints(userId, subPoints);
+		if (sub != 1) {
+			throw BusinessRuntimeException.getInstance("积分不足");
+		}
+		pointsRecord(userId, -subPoints.intValue(), PointsRecordConst.POINTS_LOTTERY, true);
+		List<LuckyDrawView> drawViews = beanSearcher.searchAll(LuckyDrawView.class, MapUtils.builder()
+				.field(LuckyDrawView::getStatus, true).op(Operator.Equal)
+				.orderBy(LuckyDrawView::getProbability).asc()
+				.build());
+		if (drawViews.isEmpty()) {
+			throw BusinessRuntimeException.getInstance("暂未配置奖品");
+		}
+		Integer index = randomProbabilityIndex(drawViews);
+		if (index == -1) {
+			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
+		}
+		LuckyDrawView luckyDraw = drawViews.get(index);
+		if (luckyDraw.getType() != LuckyDraw.Type.points) {
+			Integer num = 1;
+			luckyDraw = randomNum(luckyDraw, drawViews, num, userId);
+			if (luckyDraw == null) {
+				//随机给一份爱心值谢谢惠顾奖品
+				List<LuckyDrawView> others = beanSearcher.searchAll(LuckyDrawView.class, MapUtils.builder()
+						.field(LuckyDrawView::getStatus, true).op(Operator.Equal)
+						.field(LuckyDrawView::getType, LuckyDraw.Type.points.name()).op(Operator.Equal)
+						.build());
+				Integer finalIndex = randomProbabilityIndex(others);
+				luckyDraw = others.get(finalIndex);
+			}
+		}
+		LuckyDrawRecord record = new LuckyDrawRecord();
+		BeanUtil.copyProperties(luckyDraw, record, "status");
+		if (luckyDraw.getType() == LuckyDraw.Type.points) {
+			pointsRecord(userId, luckyDraw.getPoints(), PointsRecordConst.LOTTERY, false);
+			record.setStatus(LuckyDrawRecord.Status.success);
+		} else if (luckyDraw.getType() == LuckyDraw.Type.coupon) {
+			//发放优惠券
+			couponCommonService.sendCouponToUser(userId, luckyDraw.getCouponId(), null, null, null, CouponUser.Channel.lottery);
+			record.setStatus(LuckyDrawRecord.Status.success);
+		} else if (luckyDraw.getType() == LuckyDraw.Type.virtualGoods) {
+			ExchangeCodeReq exchangeCodeReq = new ExchangeCodeReq();
+			exchangeCodeReq.setGoodsId(luckyDraw.getGoodsId());
+			exchangeCodeReq.setSkuId(luckyDraw.getSkuId());
+			exchangeCodeReq.setNumber(1);
+			exchangeCodeReq.setType(1);
+			List<ExcelExchangeCodeData> exchangeCode = exchangeCodeService.createExchangeCode(exchangeCodeReq);
+			ExcelExchangeCodeData excelExchangeCodeData = exchangeCode.get(0);
+			record.setExCode(excelExchangeCodeData.getCode());
+			record.setStatus(LuckyDrawRecord.Status.pending);
+		} else if (luckyDraw.getType() == LuckyDraw.Type.realGoods) {
+			record.setStatus(LuckyDrawRecord.Status.pending);
+		}
+		record.setUserId(userId);
+		record.setDrawId(luckyDraw.getId());
+		luckyDrawRecordMapper.insert(record);
+		return luckyDraw;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void receivedLuckyDraw(Long userId, LuckyDrawReq luckyDrawReq) {
+		LuckyDrawRecord record = luckyDrawRecordMapper.selectOne(Wrappers.lambdaQuery(LuckyDrawRecord.class)
+				.eq(LuckyDrawRecord::getId, luckyDrawReq.getRecordId())
+				.eq(LuckyDrawRecord::getUserId, userId).last("limit 1"));
+		if (record == null) {
+			throw BusinessRuntimeException.getInstance("该中奖奖品不存在");
+		}
+		if (record.getStatus() == LuckyDrawRecord.Status.success) {
+			throw BusinessRuntimeException.getInstance("您已领取该中奖奖品");
+		}
+		User user = userMapper.selectById(userId);
+		/* 生成订单 */
+		String donNo = SEQUENCE.nextId().toString();
+		OrderDon orderDon = new OrderDon();
+		orderDon.setOrderNo(donNo);
+		orderDon.setOpenId(user.getOpenId());
+		BigDecimal zero = BigDecimal.ZERO;
+		orderDon.setMoney(zero);
+		orderDon.setRealMoney(zero);
+		orderDon.setSkuId(record.getSkuId());
+		orderDon.setRelationId(0L);
+		orderDon.setNum(1);
+		orderDon.setGoodsId(record.getGoodsId());
+		orderDon.setStatus(record.getType() == LuckyDraw.Type.realGoods ? OrderDon.Status.hasPayment : OrderDon.Status.complete);
+		orderDon.setUserId(user.getId());
+		orderDon.setType(OrderDon.Type.LOTTERY);
+		orderDonMapper.insert(orderDon);
+
+		Address address = addressMapper.selectById(luckyDrawReq.getAddressId());
+		if (address == null) {
+			throw new BusinessRuntimeException("请添加收货地址.");
+		}
+		OrderDonTransport transport = new OrderDonTransport();
+		transport.setOrderId(orderDon.getId());
+		transport.setReceiver(address.getReceiver());
+		transport.setPhone(address.getPhone());
+		transport.setProvince(address.getProvince());
+		transport.setCity(address.getCity());
+		transport.setDistrict(address.getDistrict());
+		transport.setAddress(address.getAddress());
+		orderDonTransportMapper.insert(transport);
+
+		Integer update = luckyDrawRecordMapper.updateStatus(record.getId(), orderDon.getId(), LuckyDrawRecord.Status.success);
+		if (update != 1) {
+			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
+		}
+	}
+
+	@Override
+	public void updateTaskStatus(TaskFrontView data, Long userId) {
+		this.checkTaskStatus(data, userId);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void receivedTaskPoints(Long userId, Long taskId) {
+		TaskFrontView data = beanSearcher.searchFirst(TaskFrontView.class, MapUtils.builder()
+				.field(TaskFrontView::getId, taskId).build());
+		if (data == null) {
+			throw BusinessRuntimeException.getInstance("该任务不存在");
+		}
+		this.checkTaskStatus(data, userId);
+		if (data.getStatus() == TaskUserCompleteRecord.Status.waiting) {
+			throw BusinessRuntimeException.getInstance("您未完成该任务");
+		}
+		if (data.getStatus() == TaskUserCompleteRecord.Status.received) {
+			throw BusinessRuntimeException.getInstance("您已领取该任务奖励");
+		}
+		if (data.getCouponId() != null && data.getCouponId() != 0) {
+			couponCommonService.sendCouponToUser(userId, data.getCouponId(), null, null, null, CouponUser.Channel.task);
+		}
+		pointsRecord(userId, data.getPoints(), PointsRecordConst.TASK, false);
+		//改变状态
+		TaskUserCompleteRecord record = new TaskUserCompleteRecord();
+		record.setId(data.getTaskCompleteRecordId());
+		record.setStatus(TaskUserCompleteRecord.Status.received);
+		taskUserCompleteRecordMapper.updateById(record);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void toCompleteFollowTask(TaskFollowReq taskFollowReq) {
+		Long taskId = taskFollowReq.getTaskId();
+		Long userId = taskFollowReq.getUserId();
+		TaskFrontView data = beanSearcher.searchFirst(TaskFrontView.class, MapUtils.builder()
+				.field(TaskFrontView::getId, taskId).build());
+		if (!"关注引导".equals(data.getTypeName())) {
+			throw BusinessRuntimeException.getInstance("");
+		}
+		TaskFollowPlatVerify taskFollowPlatVerify = new TaskFollowPlatVerify();
+		taskFollowPlatVerify.setTaskId(taskId);
+		taskFollowPlatVerify.setUserId(userId);
+		taskFollowPlatVerify.setPlatNickname(taskFollowReq.getPlatNickname());
+		taskFollowPlatVerify.setImg(taskFollowReq.getImg());
+		try {
+			taskFollowPlatVerifyMapper.insert(taskFollowPlatVerify);
+			TaskUserCompleteRecord record = new TaskUserCompleteRecord();
+			record.setTaskId(taskId);
+			record.setUserId(userId);
+			record.setPoints(data.getPoints());
+			record.setStatus(TaskUserCompleteRecord.Status.verifying);
+			taskUserCompleteRecordMapper.insert(record);
+		} catch (DuplicateKeyException e) {
+
+		}
+	}
+
+	@Override
+	public void updateFailFollowTask(TaskFollowReq taskFollowReq) {
+		if (taskFollowReq.getId() == null || taskFollowReq.getId() < 1) {
+			throw BusinessRuntimeException.getInstance("");
+		}
+		TaskFollowPlatVerify dbTaskFollowPlatVerify = taskFollowPlatVerifyMapper.selectById(taskFollowReq.getId());
+		if (dbTaskFollowPlatVerify == null) {
+			throw BusinessRuntimeException.getInstance("该提交记录不存在");
+		}
+		if (dbTaskFollowPlatVerify.getStatus() == TaskFollowPlatVerify.Status.success) {
+			throw BusinessRuntimeException.getInstance("您提交的记录已审核成功");
+		}
+		dbTaskFollowPlatVerify.setPlatNickname(taskFollowReq.getPlatNickname());
+		dbTaskFollowPlatVerify.setStatus(TaskFollowPlatVerify.Status.verifying);
+		dbTaskFollowPlatVerify.setImg(taskFollowReq.getImg());
+		taskFollowPlatVerifyMapper.updateById(dbTaskFollowPlatVerify);
+
+		TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+				.eq(TaskUserCompleteRecord::getUserId, dbTaskFollowPlatVerify.getUserId())
+				.eq(TaskUserCompleteRecord::getTaskId, dbTaskFollowPlatVerify.getTaskId())
+				.last("limit 1"));
+		if (record != null) {
+			record.setStatus(TaskUserCompleteRecord.Status.verifying);
+			taskUserCompleteRecordMapper.updateById(record);
+		}
+	}
+
+	/**
+	 * 更新签到时间
+	 */
+	public void signCheck(SignUser signUser) {
+		//更新时间是否小于今日零时且是否为连签
+		Date updateTime = signUser.getUpdateTime();
+		DateTime signZero = DateUtil.beginOfDay(updateTime);
+		DateTime thisZero = DateUtil.beginOfDay(DateTime.now());
+		if (updateTime.getTime() >= thisZero.getTime()) {
+			signUser.setIsHadChecked(false);
+//            throw BusinessRuntimeException.getInstance("您已签到");
+		} else {
+			if (updateTime.before(thisZero) && thisZero.getTime() - signZero.getTime() == Constant.DAY_MILLS) {
+				log.info("用户:{}连续签到,此时天数为:{}", signUser.getUserId(), signUser.getDayPeriod());
+				signUser.setDay(signUser.getDay() + 1);
+				if (signUser.getDayPeriod() == 7) {
+					signUser.setDayPeriod(0);
+				}
+				signUser.setDayPeriod(signUser.getDayPeriod() + 1);
+				//更新签到时间
+				updateUserSignDay(signUser, false);
+				signUser.setIsHadChecked(true);
+			} else {
+				log.info("用户:{}断签,断签天数为:{}", signUser.getUserId(), signUser.getDayPeriod());
+				signUser.setDay(1);
+				signUser.setDayPeriod(1);
+				//更新签到时间
+				updateUserSignDay(signUser, false);
+				signUser.setIsHadChecked(true);
+			}
+		}
+	}
+
+	public void updateUserSignDay(SignUser signUser, Boolean isFirst) {
+		Integer update = 1;
+		if (!isFirst) {
+			update = signUserMapper.updateUserSignDay(signUser.getDay(), signUser.getDayPeriod(), signUser.getUserId(), signUser.getUpdateTime());
+		}
+		Integer points = 0;
+		if (update > 0) {
+			if (signUser.getDayPeriod() > 1) {
+				//发放积分
+				SignConfig signConfig = signConfigMapper.selectOne(Wrappers.lambdaQuery(SignConfig.class)
+						.like(SignConfig::getType, signUser.getDayPeriod()).last("limit 1"));
+				if (signConfig != null) {
+					points = ThreadLocalRandom.current().nextInt(signConfig.getMinPoints(), signConfig.getMaxPoints() + 1);
+				} else {
+					points = signConfigMapper.selectOne(Wrappers.lambdaQuery(SignConfig.class)
+							.orderByAsc(SignConfig::getId).last("limit 1")).getMaxPoints();
+				}
+			} else {
+				points = signConfigMapper.selectOne(Wrappers.lambdaQuery(SignConfig.class)
+						.orderByAsc(SignConfig::getId).last("limit 1")).getMaxPoints();
+			}
+			pointsRecord(signUser.getUserId(), points, PointsRecordConst.SIGN, false);
+		}
+		signUser.setPoints(points);
+	}
+
+	/**
+	 * 随机概率奖励
+	 * 获取下标
+	 */
+	public Integer randomProbabilityIndex(List<LuckyDrawView> list) {
+		int random = -1;
+		//总权重
+		BigDecimal sums = list.stream().map(LuckyDrawView::getProbability).reduce(BigDecimal::add).get();
+		Double totalProbability = sums.doubleValue();
+		//产生随机数
+		Double randomNumber = ThreadLocalRandom.current().nextDouble();
+		//根据随机数在所有奖品分布的区域并确定所抽奖品
+		Double d1 = 0d;
+		Double d2 = 0d;
+		for (int i = 0; i < list.size(); i++) {
+			d2 += Double.parseDouble(String.valueOf(list.get(i).getProbability())) / totalProbability;
+			if (i == 0) {
+				d1 = 0d;
+			} else {
+				d1 += Double.parseDouble(String.valueOf(list.get(i - 1).getProbability())) / totalProbability;
+			}
+			if (randomNumber >= d1 && randomNumber < d2) {
+				random = i;
+				break;
+			}
+		}
+		return random;
+	}
+
+	public LuckyDrawView randomNum(LuckyDrawView luckyDrawView, List<LuckyDrawView> list, Integer num, Long userId) {
+		if (luckyDrawView.getNum() == 0) {
+			return null;
+		}
+		if (luckyDrawView.getType() == LuckyDraw.Type.coupon) {
+			CouponUser couponUser = couponUserMapper.selectOne(Wrappers.lambdaQuery(CouponUser.class)
+					.eq(CouponUser::getCouponId, luckyDrawView.getCouponId())
+					.eq(CouponUser::getUserId, userId).last("limit 1"));
+			if (couponUser != null) {
+				Integer index = randomProbabilityIndex(list);
+				if (index == -1) {
+					throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
+				}
+				LuckyDrawView next = list.get(index);
+				num++;
+				if (num >= 3) {
+					return null;
+				}
+				return randomNum(next, list, num, userId);
+			}
+		}
+		DateTime zero = DateUtil.beginOfDay(DateTime.now());
+		String key = RedisService.key.LOTTERY_KEY.getNameFormat(String.format("%s_%s", zero.toString(), luckyDrawView.getId().toString()));
+		Object o = redisService.get(key);
+		if (o != null) {
+			Integer incr = (Integer) o;
+			if (luckyDrawView.getNum() - incr > 0) {
+				redisService.incr(key, 1l);
+			} else {
+				if (num >= 3) {
+					return null;
+				}
+				Integer index = randomProbabilityIndex(list);
+				if (index == -1) {
+					throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
+				}
+				LuckyDrawView next = list.get(index);
+				num++;
+				return randomNum(next, list, num, userId);
+			}
+		} else {
+			redisService.set(key, 0, RedisService.key.LOTTERY_KEY.getTimeout());
+			redisService.incr(key, 1l);
+			return luckyDrawView;
+		}
+		return luckyDrawView;
+	}
+
+	public void checkTaskStatus(TaskFrontView data, Long userId) {
+		DateTime now = DateTime.now();
+		DateTime beginOfDay = DateUtil.beginOfDay(now);
+		DateTime endOfDay = DateUtil.endOfDay(now);
+		DateTime beginOfWeek = DateUtil.beginOfWeek(now);
+		DateTime endOfWeek = DateUtil.endOfWeek(now);
+		LambdaQueryWrapper<TaskUserCompleteRecord> wrapper = Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+				.eq(TaskUserCompleteRecord::getUserId, userId)
+				.eq(TaskUserCompleteRecord::getTaskId, data.getId())
+				.last("limit 1");
+		User user = userMapper.selectById(userId);
+		if ("time".equals(data.getTaskLimit())) {
+			Boolean isWx = false;
+			if ("添加企业微信".equals(data.getTypeName())) {
+				isWx = true;
+			}
+			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
+			if (record != null) {
+				data.setStatus(record.getStatus());
+				data.setTaskCompleteRecordId(record.getId());
+			}
+			if (record == null && isWx && StrUtil.isNotEmpty(user.getUnionid())) {
+				CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class)
+						.eq(CorpUser::getUnionid, user.getUnionid())
+						.last("limit 1"));
+				if (corpUser != null) {
+					data.setStatus(TaskUserCompleteRecord.Status.complete);
+					if (redisService.setNx(RedisService.key.TASK_TIME_LIMIT_KEY.getNameFormat(String.format("wx_%s", userId)), userId, RedisService.key.TASK_TIME_LIMIT_KEY.getTimeout())) {
+						record = new TaskUserCompleteRecord();
+						record.setUserId(userId);
+						record.setTaskId(data.getId());
+						record.setPoints(data.getPoints());
+						record.setStatus(TaskUserCompleteRecord.Status.complete);
+						taskUserCompleteRecordMapper.insert(record);
+					}
+				}
+			}
+		} else if ("day".equals(data.getTaskLimit())) {
+			wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginOfDay, endOfDay);
+			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
+			if (record != null) {
+				data.setTaskCompleteRecordId(record.getId());
+				data.setStatus(record.getStatus());
+			}
+			handleSpecialTask(userId, data, record, beginOfDay, endOfDay);
+
+		} else if ("week".equals(data.getTaskLimit())) {
+			wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginOfWeek, endOfWeek);
+			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
+			if (record != null) {
+				data.setTaskCompleteRecordId(record.getId());
+				data.setStatus(record.getStatus());
+			}
+			handleSpecialTask(userId, data, record, beginOfWeek, endOfWeek);
+		}
+	}
+
+	public void handleSpecialTask(Long userId, TaskFrontView data, TaskUserCompleteRecord record, DateTime beginTime, DateTime endTime) {
+		if (TaskTypeEnum.share.getDesc().equals(data.getTypeName())) {
+			//邀请人数是否达标
+			Integer count = userDistributeSharedMapper.selectCount(Wrappers.lambdaQuery(UserDistributeShared.class)
+					.eq(UserDistributeShared::getSharedId, userId)
+					.between(UserDistributeShared::getCreatedTime, beginTime, endTime));
+			data.setHadInvitedNum(count);
+			if (count >= data.getInviteNum() && data.getStatus() == TaskUserCompleteRecord.Status.waiting) {
+				data.setStatus(TaskUserCompleteRecord.Status.complete);
+				if (record == null) {
+					if (redisService.setNx(RedisService.key.TASK_TIME_LIMIT_KEY.getNameFormat(String.format("day_week_%s", userId)), userId, RedisService.key.TASK_TIME_LIMIT_KEY.getTimeout())) {
+						record = new TaskUserCompleteRecord();
+						record.setUserId(userId);
+						record.setTaskId(data.getId());
+						record.setPoints(data.getPoints());
+						record.setStatus(TaskUserCompleteRecord.Status.complete);
+						taskUserCompleteRecordMapper.insert(record);
+					}
+				}
+			}
+		} else if (TaskTypeEnum.bind_phone.getDesc().equals(data.getTypeName())) {
+			UserBindPhone bindPhone = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+					.eq(UserBindPhone::getUserId, userId).last("limit 1"));
+			if (bindPhone != null) {
+				data.setPhone(bindPhone.getPhone());
+			}
+		}
+	}
+}

+ 25 - 0
netflix-service/src/main/java/com/cyksj/service/market/task/TaskService.java

@@ -0,0 +1,25 @@
+package com.cyksj.service.market.task;
+
+import com.cyksj.model.entity.Task;
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+import com.cyksj.model.entity.TaskType;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: TaskService
+ *创建者: JavaZou
+ *创建时间:2022/12/27 15:17
+ */
+public interface TaskService {
+	void saveTask(Task task);
+
+	void updateTask(Task task);
+
+	void completeTask(TaskType type, Long userId);
+
+	void batchVerifyFollow( List<TaskFollowPlatVerify> taskFollowPlatVerifyList);
+
+	void pointsRecord(Long userId, Integer points, String remark, Boolean isLottery);
+}

+ 220 - 0
netflix-service/src/main/java/com/cyksj/service/market/task/impl/TaskServiceImpl.java

@@ -0,0 +1,220 @@
+package com.cyksj.service.market.task.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.PointsRecordConst;
+import com.cyksj.common.constant.TaskTypeEnum;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
+import com.cyksj.mapper.market.sign.UserPointsRecordMapper;
+import com.cyksj.mapper.market.task.TaskFollowPlatVerifyMapper;
+import com.cyksj.mapper.market.task.TaskMapper;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
+import com.cyksj.mapper.market.task.TaskUserCompleteRecordMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.service.market.task.TaskService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: TaskServiceImpl
+ *创建者: JavaZou
+ *创建时间:2022/12/27 15:17
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class TaskServiceImpl implements TaskService {
+
+	public static List<String> times = List.of("添加企业微信", "绑定手机号", "关注引导");
+
+	private final TaskTypeMapper taskTypeMapper;
+
+	private final TaskMapper taskMapper;
+
+	private final TaskUserCompleteRecordMapper taskUserCompleteRecordMapper;
+
+	private final UserDistributeSharedMapper userDistributeSharedMapper;
+
+	private final TaskFollowPlatVerifyMapper taskFollowPlatVerifyMapper;
+
+	private final UserPointsRecordMapper userPointsRecordMapper;
+
+	@Override
+	public void saveTask(Task task) {
+		checkTask(task);
+		taskMapper.insert(task);
+	}
+
+	@Override
+	public void updateTask(Task task) {
+		Task db = taskMapper.selectById(task.getId());
+		if (db == null || !db.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("该任务已不存在");
+		}
+		BeanUtil.copyProperties(task, db);
+		checkTask(db);
+		taskMapper.updateById(db);
+	}
+
+	@Override
+	public void completeTask(TaskType type, Long userId) {
+		DateTime now = DateTime.now();
+		DateTime beginOfDay = DateUtil.beginOfDay(now);
+		DateTime endOfDay = DateUtil.endOfDay(now);
+		DateTime beginOfWeek = DateUtil.beginOfWeek(now);
+		DateTime endOfWeek = DateUtil.endOfWeek(now);
+		LambdaQueryWrapper<TaskUserCompleteRecord> wrapper = Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+				.eq(TaskUserCompleteRecord::getUserId, userId)
+				.last("limit 1");
+		List<Task> tasks = taskMapper.selectList(Wrappers.lambdaQuery(Task.class)
+				.eq(Task::getTypeId, type.getId())
+				.eq(Task::getDeleted, true));
+		tasks.forEach(task -> {
+			if ("time".equals(task.getTaskLimit())) {
+				TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+						.eq(TaskUserCompleteRecord::getTaskId, task.getId())
+						.eq(TaskUserCompleteRecord::getUserId, userId).last("limit 1"));
+				if (record == null) {
+					saveCompleteTask(task.getId(), userId, task.getPoints());
+				}
+			} else if ("day".equals(task.getTaskLimit())) {
+				handleSpecialTask(type, task, userId, wrapper, beginOfDay, endOfDay);
+
+			} else if ("week".equals(task.getTaskLimit())) {
+				handleSpecialTask(type, task, userId, wrapper, beginOfWeek, endOfWeek);
+			}
+		});
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void batchVerifyFollow(List<TaskFollowPlatVerify> taskFollowPlatVerifyList) {
+		TaskFollowPlatVerify.Status success = TaskFollowPlatVerify.Status.success;
+		TaskFollowPlatVerify.Status fail = TaskFollowPlatVerify.Status.fail;
+		TaskFollowPlatVerify.Status verifying = TaskFollowPlatVerify.Status.verifying;
+		taskFollowPlatVerifyList.forEach(taskVerify -> {
+			if (taskVerify.getId() != null) {
+				TaskFollowPlatVerify dbPlatVerify = taskFollowPlatVerifyMapper.selectById(taskVerify.getId());
+				TaskFollowPlatVerify.Status verifyStatus = taskVerify.getStatus();
+				TaskFollowPlatVerify.Status dbStatus = dbPlatVerify.getStatus();
+				Boolean isFlag = false;
+				if (dbPlatVerify != null && dbStatus != success) {
+					if (dbStatus == fail && verifyStatus == success) {
+						dbPlatVerify.setStatus(success);
+						dbPlatVerify.setErrorReason("");
+						isFlag = true;
+					} else if (dbStatus == verifying) {
+						if (verifyStatus == fail) {
+							dbPlatVerify.setStatus(fail);
+							dbPlatVerify.setErrorReason(taskVerify.getErrorReason());
+							isFlag = true;
+						} else if (verifyStatus == success) {
+							dbPlatVerify.setStatus(success);
+							isFlag = true;
+						}
+					}
+				}
+				if (isFlag) {
+					dbPlatVerify.setVerifyTime(DateTime.now());
+					taskFollowPlatVerifyMapper.updateById(dbPlatVerify);
+					TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+							.eq(TaskUserCompleteRecord::getUserId, taskVerify.getUserId())
+							.eq(TaskUserCompleteRecord::getTaskId, taskVerify.getTaskId())
+							.last("limit 1"));
+					if (record == null) {
+						return;
+					}
+					if (verifyStatus == success) {
+						record.setStatus(TaskUserCompleteRecord.Status.received);
+						this.pointsRecord(record.getUserId(), record.getPoints(), PointsRecordConst.TASK, false);
+					} else if (verifyStatus == fail) {
+						record.setStatus(TaskUserCompleteRecord.Status.fail);
+					}
+					taskUserCompleteRecordMapper.updateById(record);
+				}
+			}
+		});
+	}
+
+	@Override
+	public void pointsRecord(Long userId, Integer points, String remark, Boolean isLottery) {
+		UserPointsRecord userPointsRecord = new UserPointsRecord();
+		userPointsRecord.setUserId(userId);
+		userPointsRecord.setPoints(points);
+		userPointsRecord.setRemark(remark);
+		userPointsRecordMapper.insert(userPointsRecord);
+
+		if (!isLottery) {
+			//发放爱心
+			userPointsRecordMapper.updateUserPoints(userId, points);
+		}
+	}
+
+	public void checkTask(Task task) {
+		Long typeId = task.getTypeId();
+		TaskType taskType = taskTypeMapper.selectById(typeId);
+		if (times.contains(taskType.getName())) {
+			if (!"time".equals(task.getTaskLimit())) {
+				throw BusinessRuntimeException.getInstance("该任务类型只能为一次性");
+			}
+		}
+		if ("邀请好友".equals(taskType.getName())) {
+			if (task.getInviteNum() == null || task.getInviteNum() < 1) {
+				throw BusinessRuntimeException.getInstance("邀请人数错误");
+			}
+		}
+		LambdaQueryWrapper<Task> wrapper = Wrappers.lambdaQuery(Task.class)
+				.eq(Task::getTypeId, typeId)
+				.eq(Task::getDeleted, true).last("limit 1");
+		if (task.getId() != null) {
+			wrapper.ne(Task::getId, task.getId());
+		}
+		if (!"关注引导".equals(taskType.getName())) {
+			Task selectOne = taskMapper.selectOne(wrapper);
+			if (selectOne != null) {
+				throw BusinessRuntimeException.getInstance("已新增对应的任务");
+			}
+		}
+	}
+
+	public void saveCompleteTask(Long taskId, Long userId, Integer points) {
+		TaskUserCompleteRecord record = new TaskUserCompleteRecord();
+		record.setTaskId(taskId);
+		record.setStatus(TaskUserCompleteRecord.Status.complete);
+		record.setUserId(userId);
+		record.setPoints(points);
+		taskUserCompleteRecordMapper.insert(record);
+	}
+
+	public void handleSpecialTask(TaskType type, Task task, Long userId, LambdaQueryWrapper<TaskUserCompleteRecord> wrapper, DateTime beginTime, DateTime endTime) {
+		wrapper.eq(TaskUserCompleteRecord::getTaskId, task.getId());
+		if (!TaskTypeEnum.share.getDesc().equals(type.getName())) {
+			wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginTime, endTime);
+			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
+			if (record == null) {
+				saveCompleteTask(task.getId(), userId, task.getPoints());
+			}
+		} else if (TaskTypeEnum.share.getDesc().equals(type.getName())) {
+			//邀请人数是否达标
+			Integer count = userDistributeSharedMapper.selectCount(Wrappers.lambdaQuery(UserDistributeShared.class)
+					.eq(UserDistributeShared::getSharedId, userId)
+					.between(UserDistributeShared::getCreatedTime, beginTime, endTime));
+			if (count >= task.getInviteNum()) {
+				wrapper.between(TaskUserCompleteRecord::getCreatedTime, beginTime, endTime);
+				TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(wrapper);
+				if (record == null) {
+					saveCompleteTask(task.getId(), userId, task.getPoints());
+				}
+			}
+		}
+	}
+}

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java

@@ -83,4 +83,6 @@ public interface OrderDonService extends IService<OrderDon> {
     Integer updateHasPaymentInterestRealGoods();
 
     void updateHasPaymentInterestRealGoodsPayTime();
+
+    void saveTransport(Long addressId, Long orderId);
 }

+ 20 - 1
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -19,6 +19,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.cyksj.common.AliPayCommon;
 import com.cyksj.common.EnvCommonService;
+import com.cyksj.common.constant.TaskTypeEnum;
 import com.cyksj.common.constant.TemplateEnum;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.snowflake.Sequence;
@@ -28,7 +29,6 @@ import com.cyksj.common.util.Jsons;
 import com.cyksj.common.util.Xmls;
 import com.cyksj.config.WeChatConfig;
 import com.cyksj.config.zfb.BaseZfbConfig;
-import com.cyksj.config.zfb.ZfbConfig;
 import com.cyksj.config.zfb.ZfbProductCode;
 import com.cyksj.dto.RedisKey;
 import com.cyksj.dto.Result;
@@ -39,6 +39,7 @@ import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.mapper.manage.coupon.CouponSkuMapper;
 import com.cyksj.mapper.manage.coupon.CouponUserMapper;
 import com.cyksj.mapper.manage.distribute.*;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
 import com.cyksj.model.dto.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.OrderDonView;
@@ -52,6 +53,7 @@ import com.cyksj.model.views.CouponUserView;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.coupon.CouponFontService;
 import com.cyksj.service.mange.stock.GoodsDonStockService;
+import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.wechat.WeChatService;
 import com.cyksj.task.JobManager;
@@ -150,6 +152,10 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final GoodsDonStockService goodsDonStockService;
 
+	private final TaskService taskService;
+
+	private final TaskTypeMapper taskTypeMapper;
+
 	@Transactional(rollbackFor = Throwable.class)
 	@Override
 	public OrderDon submit(OrderPayRequest payRequest) throws Exception {
@@ -424,6 +430,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			//无车队,新增车队
 			checkNoGroupsTripsAndSendMsg(sku, order);
 		}
+		//完成任务
+		TASK_POOL.execute(() -> {
+			TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
+					.eq(TaskType::getName, TaskTypeEnum.yh_order.getDesc()).last("limit 1"));
+			taskService.completeTask(taskType, order.getUserId());
+		});
 	}
 
     @Override
@@ -707,6 +719,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			//无车队,新增车队
 			checkNoGroupsTripsAndSendMsg(sku, orderDon);
 		}
+		//完成任务
+		TASK_POOL.execute(() -> {
+			TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
+					.eq(TaskType::getName, TaskTypeEnum.yh_order.getDesc()).last("limit 1"));
+			taskService.completeTask(taskType, orderDon.getUserId());
+		});
 	}
 
 	@Override
@@ -992,6 +1010,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 	}
 
+	@Override
 	public void saveTransport(Long addressId, Long orderId) {
 		if (addressId == null) {
 			throw new BusinessRuntimeException("请选择收货地址.");

+ 12 - 0
netflix-service/src/main/java/com/cyksj/service/phone/PhoneCodeService.java

@@ -0,0 +1,12 @@
+package com.cyksj.service.phone;
+
+/*
+ *项目名: netflix
+ *文件名: PhoneCodeService
+ *创建者: JavaZou
+ *创建时间:2022/12/29 14:03
+ */
+public interface PhoneCodeService {
+
+	void checkPhone(String phone,String code);
+}

+ 50 - 0
netflix-service/src/main/java/com/cyksj/service/phone/impl/PhoneCodeServiceImpl.java

@@ -0,0 +1,50 @@
+package com.cyksj.service.phone.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.PhoneCodeMapper;
+import com.cyksj.model.entity.PhoneCode;
+import com.cyksj.service.phone.PhoneCodeService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: PhoneCodeServiceImpl
+ *创建者: JavaZou
+ *创建时间:2022/12/29 14:03
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class PhoneCodeServiceImpl implements PhoneCodeService {
+	private final PhoneCodeMapper phoneCodeMapper;
+
+	@Override
+	public void checkPhone(String phone, String code) {
+		if (!Validator.isMobile(phone)) {
+			throw BusinessRuntimeException.getInstance("请输入正确的手机号码");
+		}
+		DateTime now = DateTime.now();
+		PhoneCode phoneCode = phoneCodeMapper.selectOne(Wrappers.lambdaQuery(PhoneCode.class).eq(PhoneCode::getPhone, phone).last("limit 1"));
+		if (phoneCode == null || StrUtil.isEmpty(phoneCode.getCode())) {
+			throw BusinessRuntimeException.getInstance("请重新获取手机验证码");
+		}
+		//3分钟失效
+		Date updateTime = phoneCode.getUpdateTime();
+		DateTime afterFiveMinutes = DateUtil.offsetMinute(updateTime, 3);
+		if (now.isAfter(afterFiveMinutes)) {
+			throw BusinessRuntimeException.getInstance("手机验证码已失效,请重新获取");
+		}
+		if (!StrUtil.equals(code, phoneCode.getCode())) {
+			throw BusinessRuntimeException.getInstance("手机验证码错误,请重新输入");
+		}
+	}
+}

+ 15 - 0
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -0,0 +1,15 @@
+package com.cyksj.service.relation;
+
+import com.cyksj.model.views.RenewalView;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: GroupRelationFrontService
+ *创建者: JavaZou
+ *创建时间:2022/12/29 15:42
+ */
+public interface GroupRelationFrontService {
+	List<RenewalView> getMyTicket(long userId);
+}

+ 85 - 0
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -0,0 +1,85 @@
+package com.cyksj.service.relation.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.market.task.UserBindPhoneMapper;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserBindPhone;
+import com.cyksj.model.views.RenewalView;
+import com.cyksj.service.relation.GroupRelationFrontService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/*
+ *项目名: netflix
+ *文件名: GroupRelationFrontServiceImpl
+ *创建者: JavaZou
+ *创建时间:2022/12/29 15:42
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class GroupRelationFrontServiceImpl implements GroupRelationFrontService {
+	private final UserBindPhoneMapper userBindPhoneMapper;
+
+	private final UserMapper userMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	@Override
+	public List<RenewalView> getMyTicket(long userId) {
+		User u = userMapper.selectById(userId);
+		Boolean isPcUser = false;
+		if (StrUtil.isNotBlank(u.getLoginPhone())) {
+			isPcUser = true;
+		}
+		//是否绑定过手机号
+		LambdaQueryWrapper<UserBindPhone> wrapper = Wrappers.lambdaQuery(UserBindPhone.class).last("limit 1");
+		if (isPcUser) {
+			wrapper.eq(UserBindPhone::getPhone, u.getLoginPhone());
+		} else {
+			wrapper.eq(UserBindPhone::getUserId, userId);
+		}
+		UserBindPhone userBindPhone = userBindPhoneMapper.selectOne(wrapper);
+		Long otherUserId = 0l;
+		if (userBindPhone != null) {
+			if (isPcUser) {
+				otherUserId = userBindPhone.getUserId();
+			}else {
+				User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
+						.eq(User::getLoginPhone, userBindPhone.getPhone()).last("limit 1"));
+				if (user != null) {
+					otherUserId = user.getId();
+				}
+			}
+		}
+		List<RenewalView> list = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
+				.field(RenewalView::getUserId, userId, otherUserId).op(Operator.InList)
+				.field(RenewalView::getStatus, List.of("validity", "overdue")).op(Operator.InList)
+				.orderBy(RenewalView::getExpiryTime).asc()
+				.build());
+		//过滤邀请制、已失效的车位
+		DateTime now = DateTime.now();
+		List<RenewalView> collect = list.stream().filter(ticket -> {
+			if (ticket.getExpiryTime() != null && ticket.getExpiryTime().before(now)) {
+				return false;
+			}
+			if (ticket.getSecondType() == 1) {
+				ticket.setAccount(null);
+				ticket.setPassword(null);
+			}
+			return true;
+		}).collect(Collectors.toList());
+		return collect;
+	}
+}

+ 12 - 0
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -3,14 +3,19 @@ package com.cyksj.service.user.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.constant.TaskTypeEnum;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
 import com.cyksj.model.dto.GzhOAuth2UserInfo;
 import com.cyksj.model.dto.UserWhoami;
+import com.cyksj.model.entity.TaskType;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.UserDistributeShared;
+import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.service.wechat.WeChatService;
 import lombok.RequiredArgsConstructor;
@@ -35,6 +40,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
     private final UserDistributeSharedMapper userDistributeSharedMapper;
 
+    private final TaskService taskService;
+
+    private final TaskTypeMapper taskTypeMapper;
+
     @Override
     public User saveAuth(GzhOAuth2UserInfo info, Long sharedId) {
         final String unionid = info.getUnionid();
@@ -70,6 +79,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             userDistributeShared.setUserId(user.getId());
             try {
                 userDistributeSharedMapper.insert(userDistributeShared);
+                TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
+                        .eq(TaskType::getName, TaskTypeEnum.share.getDesc()).last("limit 1"));
+                taskService.completeTask(taskType, sharedId);
             } catch (DuplicateKeyException e) {
                 log.info("分销被邀请人重复插入");
             }

+ 129 - 0
netflix-service/src/main/java/com/cyksj/task/SignStatisticsDataScheduler.java

@@ -0,0 +1,129 @@
+package com.cyksj.task;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.common.constant.PointsRecordConst;
+import com.cyksj.mapper.manage.statistics.SignStatisticsDataMapper;
+import com.cyksj.mapper.market.sign.SignUserMapper;
+import com.cyksj.mapper.market.sign.UserPointsRecordMapper;
+import com.cyksj.mapper.market.task.TaskFollowPlatVerifyMapper;
+import com.cyksj.mapper.market.task.TaskUserCompleteRecordMapper;
+import com.cyksj.model.entity.SignStatisticsData;
+import com.cyksj.model.entity.SignUser;
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+import com.cyksj.model.entity.TaskUserCompleteRecord;
+import com.cyksj.service.market.MarketFrontService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: SignStatisticsDataScheduler
+ *创建者: JavaZou
+ *创建时间:2022/12/27 18:27
+ */
+@Component
+@Slf4j
+@RequiredArgsConstructor
+public class SignStatisticsDataScheduler {
+	private final SignStatisticsDataMapper signStatisticsDataMapper;
+
+	private final UserPointsRecordMapper userPointsRecordMapper;
+
+	private final SignUserMapper signUserMapper;
+
+	private final TaskFollowPlatVerifyMapper taskFollowPlatVerifyMapper;
+
+	private final TaskUserCompleteRecordMapper taskUserCompleteRecordMapper;
+
+	private final MarketFrontService marketFrontService;
+
+	@Scheduled(cron = "0 0 0 * * ?")
+	public void signStatisticsData() {
+		Date thisZeroDate = DateUtil.beginOfDay(DateTime.now());
+		Date yesZeroDate = DateTime.of(thisZeroDate.getTime() - Constant.DAY_MILLS);
+		SignStatisticsData signStatisticsData = new SignStatisticsData();
+		//今日签到人数
+		Integer todayNumOfSign = signUserMapper.selectCount(Wrappers.lambdaQuery(SignUser.class)
+				.between(SignUser::getUpdateTime, yesZeroDate, thisZeroDate));
+		signStatisticsData.setTodayNumOfSign(todayNumOfSign);
+
+		//今日发放积分
+		Integer todayNumOfPoints = userPointsRecordMapper.getTodayNumOfPoints(yesZeroDate, thisZeroDate);
+
+		signStatisticsData.setTodayNumOfPoints(todayNumOfPoints);
+
+		//累计发放积分
+		Integer sumOfPoints = userPointsRecordMapper.getSumOfPoints();
+
+		signStatisticsData.setSumOfPoints(sumOfPoints);
+
+		//今日使用积分
+		Integer todayUseOfPoints = userPointsRecordMapper.getTodayUseOfPoints(yesZeroDate, thisZeroDate);
+		signStatisticsData.setTodayUseOfPoints(-todayUseOfPoints);
+
+		//累计使用积分
+		Integer sumUseOfPoints = userPointsRecordMapper.getSumUseOfPoints();
+		signStatisticsData.setSumUseOfPoints(-sumUseOfPoints);
+
+		//今日抽奖次数
+		Integer todayNumOfLottery = userPointsRecordMapper.getTodayNumOfLottery(PointsRecordConst.POINTS_LOTTERY, yesZeroDate, thisZeroDate);
+		signStatisticsData.setTodayNumOfLottery(todayNumOfLottery);
+
+		//连签2天
+		Integer sign2Day = userPointsRecordMapper.getSignDayByCondition(2, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT2(sign2Day);
+
+		//连签3天
+		Integer sign3Day = userPointsRecordMapper.getSignDayByCondition(3, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT3(sign3Day);
+
+		//连签4天
+		Integer sign4Day = userPointsRecordMapper.getSignDayByCondition(4, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT4(sign4Day);
+
+		//连签5天
+		Integer sign5Day = userPointsRecordMapper.getSignDayByCondition(5, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT5(sign5Day);
+
+		//连签6天
+		Integer sign6Day = userPointsRecordMapper.getSignDayByCondition(6, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT6(sign6Day);
+
+		//连签7天
+		Integer sign7Day = userPointsRecordMapper.getSignDayByCondition(7, yesZeroDate, thisZeroDate);
+		signStatisticsData.setT7(sign7Day);
+
+		signStatisticsData.setStatisticsDate(yesZeroDate);
+		signStatisticsDataMapper.insert(signStatisticsData);
+	}
+
+	/**
+	 * 关注任务3天未审核 自动审核成功
+	 */
+	@Scheduled(cron = "0 30 0 * * ?")
+	public void autoVerifySuccess() {
+		DateTime now = DateTime.now();
+		DateTime threeBefore = DateUtil.offsetDay(now, -3);
+		List<TaskFollowPlatVerify> taskFollowPlatVerifies = taskFollowPlatVerifyMapper.selectList(Wrappers.lambdaQuery(TaskFollowPlatVerify.class)
+				.le(TaskFollowPlatVerify::getCreatedTime, threeBefore)
+				.eq(TaskFollowPlatVerify::getStatus, TaskFollowPlatVerify.Status.verifying));
+		taskFollowPlatVerifies.forEach(data->{
+			data.setStatus(TaskFollowPlatVerify.Status.success);
+			TaskUserCompleteRecord record = taskUserCompleteRecordMapper.selectOne(Wrappers.lambdaQuery(TaskUserCompleteRecord.class)
+					.eq(TaskUserCompleteRecord::getUserId, data.getUserId())
+					.eq(TaskUserCompleteRecord::getTaskId, data.getTaskId())
+					.last("limit 1"));
+			record.setStatus(TaskUserCompleteRecord.Status.received);
+			taskUserCompleteRecordMapper.updateById(record);
+			marketFrontService.pointsRecord(record.getUserId(), record.getPoints(), PointsRecordConst.TASK, false);
+		});
+	}
+}

+ 2 - 3
netflix-service/src/main/java/com/cyksj/task/StatisticsDataScheduler.java

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.mapper.GoodsDonMapper;
 import com.cyksj.mapper.RegisterAccountDataMapper;
@@ -60,8 +61,6 @@ public class StatisticsDataScheduler {
 
 	private final static List<String> registerAccount = List.of("apple", "spotify", "google");
 
-	private static Long DAY_MILLS = 86400000l;
-
 	private final GoodsDonMapper goodsDonMapper;
 
 	private final RealGoodsDataMapper realGoodsDataMapper;
@@ -80,7 +79,7 @@ public class StatisticsDataScheduler {
 	@Scheduled(cron = "0 0 1 * * ?")
 	public void statisticsData() {
 		Date thisZeroDate = DateUtil.beginOfDay(DateTime.now());
-		Date yesZeroDate = DateTime.of(thisZeroDate.getTime() - DAY_MILLS);
+		Date yesZeroDate = DateTime.of(thisZeroDate.getTime() - Constant.DAY_MILLS);
 		//统计AppleOne数据
 		TASK_POOL.execute(() -> statisticsAppleOneData(yesZeroDate, thisZeroDate, false));
 		//统计流媒体账号数据

+ 30 - 0
netflix-web/src/main/java/com/cyksj/config/SaTokenConfigure.java

@@ -0,0 +1,30 @@
+package com.cyksj.config;
+
+import cn.dev33.satoken.interceptor.SaRouteInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.List;
+
+/*
+ *项目名: yicang-admin
+ *文件名: SaTokenConfigure
+ *创建者: JavaZou
+ *创建时间:2022/12/19 10:01
+ */
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+	// 注册拦截器
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new SaRouteInterceptor())
+				.addPathPatterns(List.of("/manage/**", "/manager/**", "/sys/update", "/sys/delete/**"))
+				.excludePathPatterns(List.of("/manage/admin/login",
+						"/manage/admin/get/loginInfo",
+						"/manage/corp/**",
+						"/manage/coupon/corp/send",
+						"/manage/coupon",
+						"/manage/register/wx/refund/notify"));
+	}
+}

+ 0 - 35
netflix-web/src/main/java/com/cyksj/config/WebConfig.java

@@ -1,35 +0,0 @@
-package com.cyksj.config;
-
-import cn.dev33.satoken.interceptor.SaRouteInterceptor;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-import java.util.List;
-
-/*
- *项目名: yicang-admin
- *文件名: WebConfig
- *创建者: JavaZou
- *创建时间:2022/12/19 10:01
- */
-@Configuration
-public class WebConfig implements WebMvcConfigurer {
-
-	@Configuration
-	public class SaTokenConfigure implements WebMvcConfigurer {
-		// 注册拦截器
-		@Override
-		public void addInterceptors(InterceptorRegistry registry) {
-			registry.addInterceptor(new SaRouteInterceptor())
-					.addPathPatterns(List.of("/manage/**","/manager/**","/sys/update","/sys/delete/**"))
-					.excludePathPatterns(List.of("/manage/admin/login",
-							"/manage/admin/get/loginInfo",
-							"/manage/corp/**",
-							"/manage/coupon/corp/send",
-							"/manage/coupon",
-							"/manage/register/wx/refund/notify"));
-		}
-	}
-
-}

+ 5 - 22
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -1,6 +1,5 @@
 package com.cyksj.web.controller.group;
 
-import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
@@ -11,16 +10,14 @@ import com.cyksj.model.entity.OrderDon;
 import com.cyksj.model.request.OrderPayRequest;
 import com.cyksj.model.views.RenewalView;
 import com.cyksj.service.order.OrderDonService;
+import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
-import com.ejlchina.searcher.param.Operator;
-import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @author chan
@@ -38,27 +35,13 @@ public class GroupRelationController {
 
     private final GroupsRelationMapper relationMapper;
 
+    private final GroupRelationFrontService groupRelationFrontService;
+
     @RequestMapping("/get/renewal")
     public Result<List<RenewalView>> get() {
         long userId = StpUserUtil.getLoginIdAsLong();
-        List<RenewalView> list = beanSearcher.searchAll(RenewalView.class, MapUtils.builder()
-                .field(RenewalView::getUserId, userId)
-                .field(RenewalView::getStatus, List.of("validity", "overdue")).op(Operator.InList)
-                .orderBy(RenewalView::getExpiryTime).asc()
-                .build());
-        //过滤邀请制、已失效的车位
-        DateTime now = DateTime.now();
-        List<RenewalView> collect = list.stream().filter(ticket -> {
-            if (ticket.getExpiryTime() != null && ticket.getExpiryTime().before(now)) {
-                return false;
-            }
-            if (ticket.getSecondType() == 1) {
-                ticket.setAccount(null);
-                ticket.setPassword(null);
-            }
-            return true;
-        }).collect(Collectors.toList());
-        return GatewayResponse.SUCCESS.newBuilder().toResult(collect);
+        List<RenewalView> list = groupRelationFrontService.getMyTicket(userId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(list);
     }
 
     @PostMapping("/post/renewal")

+ 3 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java

@@ -5,6 +5,7 @@ import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.market.task.UserBindPhoneMapper;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.manage.views.UserView;
@@ -37,6 +38,8 @@ public class CmsUserController{
 
     private final UserMapper userMapper;
 
+    private final UserBindPhoneMapper userBindPhoneMapper;
+
 
     @GetMapping("/get")
     public Result<SearchResult<UserView>> get(){

+ 101 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/market/LuckyDrawController.java

@@ -0,0 +1,101 @@
+package com.cyksj.web.controller.manage.market;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.market.draw.LuckyDrawMapper;
+import com.cyksj.mapper.market.draw.LuckyDrawRecordMapper;
+import com.cyksj.model.entity.LuckyDraw;
+import com.cyksj.model.entity.LuckyDrawRecord;
+import com.cyksj.model.views.LuckyDrawView;
+import com.cyksj.service.market.draw.LuckyDrawService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawController
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:33
+ */
+@RestController
+@RequestMapping("/manage/market/luckyDraw")
+@RequiredArgsConstructor
+public class LuckyDrawController {
+	private final LuckyDrawService luckyDrawService;
+
+	private final LuckyDrawMapper luckyDrawMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	private final LuckyDrawRecordMapper luckyDrawRecordMapper;
+
+	/**
+	 * 新增抽奖奖品
+	 */
+	@PostMapping("/post")
+	public Result<String> saveLuckyDraw(@RequestBody @Validated LuckyDraw luckyDraw) throws Exception {
+		luckyDrawService.saveLuckyDraw(luckyDraw);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("新增奖品成功");
+	}
+
+	/**
+	 * 上下架奖品
+	 */
+	@PutMapping("/put/status/{id}")
+	public Result<String> putStatus(@PathVariable Long id) throws Exception {
+		luckyDrawService.putStatus(id);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("操作成功");
+	}
+
+	/**
+	 * 编辑奖品
+	 */
+	@PutMapping("/put")
+	public Result<String> updateLuckyDraw(@RequestBody LuckyDraw luckyDraw) throws Exception {
+		luckyDrawService.updateLuckyDraw(luckyDraw);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("操作成功");
+	}
+
+	/**
+	 * 删除奖品
+	 */
+	@DeleteMapping("/delete/{id}")
+	public Result<String> deleteLuckyDraw(@PathVariable Long id) {
+		LuckyDraw luckyDraw = luckyDrawMapper.selectById(id);
+		if (luckyDraw == null || !luckyDraw.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("该奖品已不存在");
+		}
+		luckyDraw.setDeleted(!luckyDraw.getDeleted());
+		luckyDrawMapper.updateById(luckyDraw);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("删除奖品成功");
+	}
+
+	/**
+	 * 奖品列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<LuckyDrawView>> get(HttpServletRequest request) {
+		SearchResult<LuckyDrawView> search = beanSearcher.search(LuckyDrawView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.build());
+		search.getDataList().forEach(data->{
+			Integer lotteryNum = luckyDrawRecordMapper.getLotteryNum(data.getId());
+			data.setLotteryNum(lotteryNum);
+			Integer lotteryCount = luckyDrawRecordMapper.selectCount(Wrappers.lambdaQuery(LuckyDrawRecord.class)
+					.eq(LuckyDrawRecord::getDrawId, data.getId()));
+			data.setLotteryCount(lotteryCount);
+			Integer luckyOrderCount = luckyDrawRecordMapper.selectCount(Wrappers.lambdaQuery(LuckyDrawRecord.class)
+					.eq(LuckyDrawRecord::getDrawId, data.getId())
+					.eq(LuckyDrawRecord::getStatus, LuckyDrawRecord.Status.success));
+			data.setLuckyOrderCount(luckyOrderCount);
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+}

+ 42 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/market/SignController.java

@@ -0,0 +1,42 @@
+package com.cyksj.web.controller.manage.market;
+
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.market.sign.SignConfigMapper;
+import com.cyksj.model.entity.SignConfig;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/manage/market/sign")
+@RequiredArgsConstructor
+public class SignController {
+    private final SignConfigMapper signConfigMapper;
+
+    /**
+     * 每日签到设置明细
+     */
+    @GetMapping("/get")
+    public Result<List<SignConfig>> getSign() {
+        return GatewayResponse.SUCCESS.newBuilder().toResult(signConfigMapper.selectList(Wrappers.lambdaQuery(SignConfig.class).orderByAsc(SignConfig::getId)));
+    }
+
+    /**
+     * 编辑每日签到设置
+     */
+    @PutMapping("/put")
+    public Result<String> getSign(@RequestBody List<SignConfig> signConfigs) {
+        signConfigs.forEach(signConfig->{
+            if (signConfig.getId() == null || signConfig.getId() < 1) {
+                throw BusinessRuntimeException.getInstance("id为空");
+            }
+            signConfigMapper.updateById(signConfig);
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult("编辑成功");
+    }
+}

+ 137 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/market/TaskController.java

@@ -0,0 +1,137 @@
+package com.cyksj.web.controller.manage.market;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.market.task.TaskFollowPlatVerifyMapper;
+import com.cyksj.mapper.market.task.TaskMapper;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
+import com.cyksj.mapper.market.task.TaskUserCompleteRecordMapper;
+import com.cyksj.model.entity.Task;
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+import com.cyksj.model.entity.TaskType;
+import com.cyksj.model.views.TaskFollowVerifyView;
+import com.cyksj.model.views.TaskView;
+import com.cyksj.service.market.task.TaskService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: TaskController
+ *创建者: JavaZou
+ *创建时间:2022/12/27 13:34
+ */
+@RestController
+@RequestMapping("/manage/market/task")
+@RequiredArgsConstructor
+public class TaskController {
+	private final TaskTypeMapper taskTypeMapper;
+
+	private final TaskMapper taskMapper;
+
+	private final TaskService taskService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final TaskUserCompleteRecordMapper taskUserCompleteRecordMapper;
+
+	private final TaskFollowPlatVerifyMapper taskFollowPlatVerifyMapper;
+
+	/**
+	 * 任务分类列表
+	 */
+	@GetMapping("/get/type")
+	public Result<List<TaskType>> getType() {
+		return GatewayResponse.SUCCESS.newBuilder().toResult(taskTypeMapper.selectList(null));
+	}
+
+	/**
+	 * 新增任务
+	 */
+	@PostMapping("/post")
+	public Result<String> saveTask(@RequestBody @Validated Task task) {
+		taskService.saveTask(task);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("新增任务成功");
+	}
+
+	/**
+	 * 删除任务
+	 */
+	@DeleteMapping("/delete/{id}")
+	public Result<String> deleteTask(@PathVariable Long id) {
+		Task task = taskMapper.selectById(id);
+		if (task == null || !task.getDeleted()) {
+			throw BusinessRuntimeException.getInstance("该任务已不存在");
+		}
+		task.setDeleted(!task.getDeleted());
+		taskMapper.updateById(task);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("删除任务成功");
+	}
+
+	/**
+	 * 修改任务
+	 */
+	@PutMapping("/put")
+	public Result<String> updateTask(@RequestBody Task task) {
+		if (task.getId() == null || task.getId() < 1) {
+			throw BusinessRuntimeException.getInstance("任务id错误");
+		}
+		taskService.updateTask(task);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("编辑任务成功");
+	}
+
+	/**
+	 * 任务列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<TaskView>> getTask(HttpServletRequest request) {
+		DateTime now = DateTime.now();
+		DateTime beginOfDay = DateUtil.beginOfDay(now);
+		DateTime endOfDay = DateUtil.endOfDay(now);
+		SearchResult<TaskView> search = beanSearcher.search(TaskView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		search.getDataList().forEach(data -> {
+			Integer todayCompleteNum = taskUserCompleteRecordMapper.getTodayCompleteNum(data.getId(),beginOfDay,endOfDay);
+			data.setTodayCompleteNum(todayCompleteNum);
+			Integer sumCompleteNum = taskUserCompleteRecordMapper.getSumCompleteNum(data.getId());
+			data.setSumCompleteNum(sumCompleteNum);
+			Integer todayPoints = taskUserCompleteRecordMapper.sumTodayPoints(data.getId(), beginOfDay, endOfDay);
+			data.setTodayPoints(todayPoints);
+			Integer sumPoints = taskUserCompleteRecordMapper.sumPoints(data.getId());
+			data.setSumPoints(sumPoints);
+			//关注任务待审核数量
+			data.setVerifyNum(taskFollowPlatVerifyMapper.selectCount(Wrappers.lambdaQuery(TaskFollowPlatVerify.class)
+					.eq(TaskFollowPlatVerify::getStatus, TaskFollowPlatVerify.Status.verifying)));
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 关注任务 待审核详情
+	 */
+	@GetMapping("/get/follow/detail")
+	public Result<SearchResult<TaskFollowVerifyView>> getFollowDetail(HttpServletRequest request) {
+		SearchResult<TaskFollowVerifyView> search = beanSearcher.search(TaskFollowVerifyView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 批量审核 关注任务
+	 */
+	@PutMapping("/batch/verify/follow")
+	public Result<String> batchVerifyFollow(@RequestBody List<TaskFollowPlatVerify> taskFollowPlatVerifyList) {
+		taskService.batchVerifyFollow(taskFollowPlatVerifyList);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("审核成功");
+	}
+}
+

+ 20 - 9
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -8,22 +8,21 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
-import com.cyksj.model.entity.*;
-import com.cyksj.model.excel.ExcelAccountData;
-import com.cyksj.model.views.BackgroundDataView;
-import com.cyksj.model.views.ExpiredAccountDataView;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.manage.CustomerServiceEveryMonthDetailMapper;
 import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
 import com.cyksj.mapper.manage.statistics.IncrExpiryTimeRecordMapper;
+import com.cyksj.mapper.manage.statistics.SignStatisticsDataMapper;
 import com.cyksj.mapper.manage.statistics.StatisticsUserDataMapper;
+import com.cyksj.mapper.stock.GoodsDonStockRecordMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.excel.ExcelAccountData;
 import com.cyksj.model.request.RenewTimeUpReq;
 import com.cyksj.model.views.*;
 import com.cyksj.service.mange.statistics.StatisticsDataService;
-import com.cyksj.web.util.EasyExcelUtils;
 import com.cyksj.task.OrderCustomerHandleScheduler;
+import com.cyksj.web.util.EasyExcelUtils;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.param.Operator;
@@ -33,13 +32,14 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.*;
-
-import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /*
@@ -72,6 +72,8 @@ public class StatisticsDataController {
 
 	private final GoodsDonStockRecordMapper stockRecordMapper;
 
+	private final SignStatisticsDataMapper signStatisticsDataMapper;
+
 	/**
 	 * 查询统计数据
 	 */
@@ -279,4 +281,13 @@ public class StatisticsDataController {
 		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, StatisticsStockView.class, res, "库存统计", "库存统计", ExcelTypeEnum.XLSX, null);
 
 	}
+
+	/**
+	 * 签到以及积分数据统计
+	 */
+	@GetMapping("/get/sign")
+	public Result<SearchResult<SignStatisticsData>> getSign(HttpServletRequest request) {
+		SearchResult<SignStatisticsData> search = beanSearcher.search(SignStatisticsData.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
 }

+ 111 - 0
netflix-web/src/main/java/com/cyksj/web/controller/market/LuckyDrawFrontController.java

@@ -0,0 +1,111 @@
+package com.cyksj.web.controller.market;
+
+import com.cyksj.common.annotation.NoSubmit;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.common.util.StringUtil;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.UserMapper;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.request.LuckyDrawReq;
+import com.cyksj.model.views.LuckyDrawRecordView;
+import com.cyksj.model.views.LuckyDrawView;
+import com.cyksj.service.market.MarketFrontService;
+import com.cyksj.web.util.StpUserUtil;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/*
+ *项目名: netflix
+ *文件名: LuckyDrawFrontController
+ *创建者: JavaZou
+ *创建时间:2022/12/28 13:51
+ */
+@RestController
+@RequestMapping("/applets/market/luckyDraw")
+@RequiredArgsConstructor
+public class LuckyDrawFrontController {
+	private final BeanSearcher beanSearcher;
+
+	private final MarketFrontService marketFrontService;
+
+	private final UserMapper userMapper;
+
+	/**
+	 * 奖品列表
+	 */
+	@GetMapping("/get")
+	public Result<List<LuckyDrawView>> getLuckyDraw(@RequestParam(defaultValue = "true") Boolean isRepeat) throws Exception {
+		List<LuckyDrawView> drawViews = beanSearcher.searchAll(LuckyDrawView.class, MapUtils.builder()
+				.field(LuckyDrawView::getStatus, true).op(Operator.Equal).build());
+		if (drawViews.isEmpty()) {
+			throw BusinessRuntimeException.getInstance("暂未配置奖品");
+		}
+		List<LuckyDrawView> re = new ArrayList<>();
+		for (LuckyDrawView drawView : drawViews) {
+			List<Integer> positions = Jsons.parseList(drawView.getPosition(), Integer.class);
+			for (Integer i : positions) {
+				LuckyDrawView view = new LuckyDrawView();
+				BeanUtils.copyProperties(drawView, view);
+				view.setPosition(i.toString());
+				re.add(view);
+				if (!isRepeat) {
+					break;
+				}
+			}
+		}
+		re = re.stream().sorted(Comparator.comparing(LuckyDrawView::getPosition)).collect(Collectors.toList());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(re);
+	}
+
+	/**
+	 * 我的抽奖记录
+	 */
+	@GetMapping("/get/record")
+	public Result<SearchResult<LuckyDrawRecordView>> getLuckyDrawRecord(HttpServletRequest request) {
+		SearchResult<LuckyDrawRecordView> search = beanSearcher.search(LuckyDrawRecordView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		search.getDataList().forEach(data -> {
+			User user = userMapper.selectById(data.getUserId());
+			if (user != null) {
+				data.setNickname(StringUtil.anonymity(user.getNickname().toCharArray()));
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 抽奖
+	 */
+	@PostMapping("/lottery")
+	@NoSubmit
+	public Result<LuckyDrawView> lottery() {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		LuckyDrawView luckyDrawView = marketFrontService.lottery(userId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(luckyDrawView);
+	}
+
+	/**
+	 * 领取奖品
+	 */
+	@PostMapping("/post/receive")
+	@NoSubmit
+	public Result<String> receivedLuckyDraw(@RequestBody @Validated LuckyDrawReq luckyDrawReq) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		marketFrontService.receivedLuckyDraw(userId, luckyDrawReq);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
+	}
+
+}

+ 69 - 0
netflix-web/src/main/java/com/cyksj/web/controller/market/SignFrontController.java

@@ -0,0 +1,69 @@
+package com.cyksj.web.controller.market;
+
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.market.sign.SignConfigMapper;
+import com.cyksj.mapper.market.sign.UserPointsRecordMapper;
+import com.cyksj.model.entity.SignConfig;
+import com.cyksj.model.entity.SignUser;
+import com.cyksj.model.entity.UserPointsRecord;
+import com.cyksj.service.market.MarketFrontService;
+import com.cyksj.web.util.StpUserUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/applets/market/sign")
+@RequiredArgsConstructor
+public class SignFrontController {
+    private final MarketFrontService marketFrontService;
+
+    private final UserPointsRecordMapper userPointsRecordMapper;
+
+    private final SignConfigMapper signConfigMapper;
+
+    /**
+     * 用户积分详情
+     */
+    @GetMapping("/get/points/detail")
+    public Result<Page<UserPointsRecord>> getUserPointsDetail(@RequestParam(defaultValue = "1") Integer start, @RequestParam(defaultValue = "5") Integer limit) {
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        return GatewayResponse.SUCCESS.newBuilder().toResult(userPointsRecordMapper.selectPage(new Page<>(start, limit), Wrappers.lambdaQuery(UserPointsRecord.class)
+                .eq(UserPointsRecord::getUserId, userId)
+                .orderByDesc(UserPointsRecord::getId)));
+    }
+
+    /**
+     * 签到详情
+     */
+    @GetMapping("/get/detail")
+    public Result<SignUser> getUserSignDetail() {
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        return GatewayResponse.SUCCESS.newBuilder().toResult(marketFrontService.getUserSignDetail(userId));
+    }
+
+
+    /**
+     * 每日签到
+     */
+    @PostMapping("/post")
+    public Result<Integer> sign() {
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        SignUser signUser = marketFrontService.signByUserId(userId);
+        return GatewayResponse.SUCCESS.newBuilder().setMsg("签到成功").toResult(signUser.getDayPeriod());
+    }
+
+    /**
+     * 积分配置
+     */
+    @GetMapping("/get/points/config")
+    public Result<List<SignConfig>> getSign() {
+        return GatewayResponse.SUCCESS.newBuilder().toResult(signConfigMapper.selectList(Wrappers.lambdaQuery(SignConfig.class).orderByAsc(SignConfig::getId)));
+    }
+
+}

+ 169 - 0
netflix-web/src/main/java/com/cyksj/web/controller/market/TaskFrontController.java

@@ -0,0 +1,169 @@
+package com.cyksj.web.controller.market;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.annotation.NoSubmit;
+import com.cyksj.common.constant.TaskTypeEnum;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
+import com.cyksj.mapper.market.task.UserBindPhoneMapper;
+import com.cyksj.model.entity.TaskFollowPlatVerify;
+import com.cyksj.model.entity.TaskType;
+import com.cyksj.model.entity.UserBindPhone;
+import com.cyksj.model.request.LoginPhoneReq;
+import com.cyksj.model.request.TaskFollowReq;
+import com.cyksj.model.views.TaskFrontView;
+import com.cyksj.service.market.MarketFrontService;
+import com.cyksj.service.market.task.TaskService;
+import com.cyksj.service.phone.PhoneCodeService;
+import com.cyksj.web.util.StpUserUtil;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/*
+ *项目名: netflix
+ *文件名: TaskFrontController
+ *创建者: JavaZou
+ *创建时间:2022/12/28 13:51
+ */
+@RestController
+@RequestMapping("/applets/market/task")
+@RequiredArgsConstructor
+public class TaskFrontController {
+
+	private final BeanSearcher beanSearcher;
+
+	private final MarketFrontService marketFrontService;
+
+	private final HttpServletRequest request;
+
+	private final UserBindPhoneMapper userBindPhoneMapper;
+
+	private final PhoneCodeService phoneCodeService;
+
+	private final TaskService taskService;
+
+	private final TaskTypeMapper taskTypeMapper;
+
+	/**
+	 * 任务列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<TaskFrontView>> getTask(HttpServletRequest request) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		SearchResult<TaskFrontView> search = beanSearcher.search(TaskFrontView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		search.getDataList().forEach(data -> {
+			marketFrontService.updateTaskStatus(data, userId);
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 领取任务积分
+	 */
+	@PostMapping("/post/points/{taskId}")
+	@NoSubmit
+	public Result<String> getTaskPoints(@PathVariable Long taskId) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		marketFrontService.receivedTaskPoints(userId, taskId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
+	}
+
+	/**
+	 * 绑定手机号
+	 */
+	@PostMapping("/bind/phone")
+	@NoSubmit
+	public Result<String> bindPhone(@RequestBody LoginPhoneReq phoneReq) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		UserBindPhone other = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+				.eq(UserBindPhone::getPhone, phoneReq.getPhone()).ne(UserBindPhone::getUserId, userId).select(UserBindPhone::getId).last("limit 1"));
+		if (other != null) {
+			throw BusinessRuntimeException.getInstance("该手机号已被绑定");
+		}
+		UserBindPhone bindPhone = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+				.eq(UserBindPhone::getUserId, userId).last("limit 1"));
+		if (bindPhone != null) {
+			throw BusinessRuntimeException.getInstance("您已绑定手机号");
+		}
+		//校验
+		phoneCodeService.checkPhone(phoneReq.getPhone(), phoneReq.getCode());
+		UserBindPhone userBindPhone = new UserBindPhone();
+		userBindPhone.setUserId(userId);
+		userBindPhone.setPhone(phoneReq.getPhone());
+		try {
+			userBindPhoneMapper.insert(userBindPhone);
+		} catch (DuplicateKeyException e) {
+
+		}
+		TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
+				.eq(TaskType::getName, TaskTypeEnum.bind_phone.getDesc()).last("limit 1"));
+		//完成任务
+		taskService.completeTask(taskType, userId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("绑定手机号成功");
+	}
+
+	/**
+	 * 修改手机号
+	 */
+	@PutMapping("/put/bind/phone")
+	public Result<String> updateBindPhone(@RequestBody LoginPhoneReq phoneReq) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		UserBindPhone bindPhone = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+				.eq(UserBindPhone::getUserId, userId).last("limit 1"));
+		if (bindPhone == null) {
+			throw BusinessRuntimeException.getInstance("您未绑定手机号");
+		}
+		UserBindPhone other = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+				.eq(UserBindPhone::getPhone, phoneReq.getPhone()).ne(UserBindPhone::getUserId, userId).select(UserBindPhone::getId).last("limit 1"));
+		if (other != null) {
+			throw BusinessRuntimeException.getInstance("该手机号已被绑定");
+		}
+		phoneCodeService.checkPhone(phoneReq.getPhone(), phoneReq.getCode());
+		bindPhone.setPhone(phoneReq.getPhone());
+		userBindPhoneMapper.updateById(bindPhone);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("更换手机号成功");
+	}
+
+	/**
+	 * 去完成关注任务
+	 */
+	@PostMapping("/post/follow")
+	@NoSubmit
+	public Result<String> toCompleteFollowTask(@RequestBody @Validated TaskFollowReq taskFollowReq) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		taskFollowReq.setUserId(userId);
+		marketFrontService.toCompleteFollowTask(taskFollowReq);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("提交成功");
+	}
+
+	/**
+	 * 关注任务提交详情
+	 */
+	@GetMapping("/get/follow/detail")
+	public Result<TaskFollowPlatVerify> getFollowDetail(HttpServletRequest request) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		TaskFollowPlatVerify taskFollowPlatVerify = beanSearcher.searchFirst(TaskFollowPlatVerify.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(TaskFollowPlatVerify::getUserId, userId).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(taskFollowPlatVerify);
+	}
+
+	/**
+	 * 关注任务审核失败,重新提交
+	 */
+	@PutMapping("/put/follow")
+	public Result<String> updateFailFollowTask(@RequestBody @Validated TaskFollowReq taskFollowReq) {
+		Long userId = StpUserUtil.getLoginIdAsLong();
+		taskFollowReq.setUserId(userId);
+		marketFrontService.updateFailFollowTask(taskFollowReq);
+		return GatewayResponse.SUCCESS.newBuilder().toResult("提交成功");
+	}
+}

+ 11 - 0
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.EnvCommonService;
+import com.cyksj.common.constant.TaskTypeEnum;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.snowflake.Sequence;
 import com.cyksj.common.util.Codec;
@@ -20,17 +21,20 @@ import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.PhoneCodeMapper;
 import com.cyksj.mapper.WxAppMapper;
 import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
+import com.cyksj.mapper.market.task.TaskTypeMapper;
 import com.cyksj.model.dto.AuthRedirect;
 import com.cyksj.model.dto.AuthToken;
 import com.cyksj.model.dto.GzhOAuth2UserInfo;
 import com.cyksj.model.dto.JsSdkTicket;
 import com.cyksj.model.entity.PhoneCode;
+import com.cyksj.model.entity.TaskType;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.UserDistributeShared;
 import com.cyksj.model.request.LoginPhoneReq;
 import com.cyksj.model.response.LoginPhoneRep;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.authorization.AuthorizationService;
+import com.cyksj.service.market.task.TaskService;
 import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.service.wechat.WeChatService;
@@ -88,6 +92,10 @@ public class AuthorizationController {
 
     private final UserDistributeSharedMapper userDistributeSharedMapper;
 
+    private final TaskService taskService;
+
+    private final TaskTypeMapper taskTypeMapper;
+
     @GetMapping(value = "/weChat")
     public void base(String url,Long sharedId, String authType, HttpServletResponse response) throws Exception {
 
@@ -331,6 +339,9 @@ public class AuthorizationController {
             userDistributeShared.setUserId(user.getId());
             try {
                 userDistributeSharedMapper.insert(userDistributeShared);
+                TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
+                        .eq(TaskType::getName, TaskTypeEnum.share.getDesc()).last("limit 1"));
+                taskService.completeTask(taskType, sharedId);
             } catch (DuplicateKeyException e) {
                 log.info("分销被邀请人重复插入");
             }

+ 55 - 0
netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

@@ -1,15 +1,29 @@
 package com.cyksj.web.controller.user;
 
+import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.mapper.manage.coupon.CouponUserMapper;
+import com.cyksj.mapper.market.task.UserBindPhoneMapper;
 import com.cyksj.model.dto.UserWhoami;
+import com.cyksj.model.entity.CouponUser;
+import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.entity.User;
+import com.cyksj.model.entity.UserBindPhone;
 import com.cyksj.model.request.ExchangeCodeTicket;
+import com.cyksj.model.views.RenewalView;
+import com.cyksj.model.views.UserPersonalView;
 import com.cyksj.service.exchange.ExchangeCodeService;
+import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.web.util.StpUserUtil;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * @author chan
  * @date 2021/10/11 下午11:05
@@ -23,7 +37,13 @@ public class UserController {
 
     private final ExchangeCodeService exchangeCodeService;
 
+    private final GroupRelationFrontService groupRelationFrontService;
+
+    private final CouponUserMapper couponUserMapper;
 
+    private final OrderDonMapper orderDonMapper;
+
+    private final UserBindPhoneMapper userBindPhoneMapper;
 
     @GetMapping(value = "/wx/whoami")
     public Result<UserWhoami> whoami(){
@@ -43,4 +63,39 @@ public class UserController {
         return exchangeCodeService.getTicketByExchangeCode(exchangeCodeTicket, userId);
     }
 
+    /**
+     * 个人中心详情
+     */
+    @GetMapping("/personal")
+    public Result<UserPersonalView> getPersonalView() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<RenewalView> ticket = groupRelationFrontService.getMyTicket(userId);
+        UserPersonalView personalView = new UserPersonalView();
+        DateTime now = DateTime.now();
+        //车票
+        personalView.setNumOfTickets(ticket.size());
+        //优惠券
+        Integer couponSize = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
+                .eq(CouponUser::getUserId, userId)
+                .eq(CouponUser::getStatus, CouponUser.Status.unused)
+                .le(CouponUser::getValidStartTime, now)
+                .gt(CouponUser::getValidEndTime, now));
+        personalView.setNumOfCoupons(couponSize);
+        //积分
+        User user = userService.getById(userId);
+        personalView.setActivePoints(user.getActivePoints());
+        //推广积分
+        personalView.setPopularizePoints(user.getPoints());
+        OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+                .eq(OrderDon::getUserId, userId)
+                .eq(OrderDon::getStatus, OrderDon.Status.noPayment).last("limit 1"));
+        personalView.setIsNoPayment(orderDon != null ? true : false);
+        UserBindPhone bindPhone = userBindPhoneMapper.selectOne(Wrappers.lambdaQuery(UserBindPhone.class)
+                .eq(UserBindPhone::getUserId, userId).last("limit 1"));
+        //手机号
+        if (bindPhone != null) {
+            personalView.setPhone(bindPhone.getPhone());
+        }
+        return GatewayResponse.SUCCESS.newBuilder().toResult(personalView);
+    }
 }