Parcourir la source

Merge branch 'ticket_coupon_apply'

# Conflicts:
#	netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
#	netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java
#	netflix-service/src/main/java/com/cyksj/service/coupon/CouponFontService.java
#	netflix-service/src/main/java/com/cyksj/service/coupon/impl/CouponFontServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
#	netflix-service/src/main/java/com/cyksj/service/user/UserService.java
#	netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/task/OrderCustomerHandleScheduler.java
#	netflix-web/src/main/java/com/cyksj/web/controller/coupon/CouponFrontController.java
#	netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java
zoujiajian il y a 3 ans
Parent
commit
ffba469966
56 fichiers modifiés avec 1105 ajouts et 140 suppressions
  1. 2 0
      netflix-common/src/main/java/com/cyksj/common/constant/Constant.java
  2. 9 0
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/TicketAdvertiseConfigClickRecordMapper.java
  4. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/TicketAdvertiseConfigMapper.java
  5. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponUserMapper.java
  6. 3 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeMapper.java
  7. 2 0
      netflix-dao/src/main/java/com/cyksj/model/dto/CouponPopularizeDto.java
  8. 18 0
      netflix-dao/src/main/java/com/cyksj/model/dto/NewUserWelfareDto.java
  9. 5 0
      netflix-dao/src/main/java/com/cyksj/model/entity/Coupon.java
  10. 1 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CouponUser.java
  11. 26 0
      netflix-dao/src/main/java/com/cyksj/model/entity/DistributeMoneyApply.java
  12. 10 0
      netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDon.java
  13. 15 0
      netflix-dao/src/main/java/com/cyksj/model/entity/OrderDon.java
  14. 2 4
      netflix-dao/src/main/java/com/cyksj/model/entity/RealGoodsOrderHandle.java
  15. 56 0
      netflix-dao/src/main/java/com/cyksj/model/entity/TicketAdvertiseConfig.java
  16. 18 0
      netflix-dao/src/main/java/com/cyksj/model/entity/TicketAdvertiseConfigClickRecord.java
  17. 93 0
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelServiceMonthStatisticsData.java
  18. 10 0
      netflix-dao/src/main/java/com/cyksj/model/request/ApplyMoneyReq.java
  19. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponActiveView.java
  20. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponRecommendView.java
  21. 6 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponUserView.java
  22. 6 0
      netflix-dao/src/main/java/com/cyksj/model/views/CouponView.java
  23. 13 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributeMoneyApplyView.java
  24. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsHomePageView.java
  25. 22 0
      netflix-dao/src/main/java/com/cyksj/model/views/GroupsRelationUserView.java
  26. 18 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  27. 15 1
      netflix-dao/src/main/java/com/cyksj/model/views/ServiceOrdersDetailView.java
  28. 39 0
      netflix-dao/src/main/java/com/cyksj/model/views/TicketAdvertiseConfigFrontView.java
  29. 37 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserRecommendGoodsFrontView.java
  30. 5 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserTicketView.java
  31. 1 0
      netflix-dao/src/main/resources/mapper/CouponMapper.xml
  32. 1 0
      netflix-dao/src/main/resources/mapper/CouponRecommendMapper.xml
  33. 27 0
      netflix-dao/src/main/resources/mapper/CouponUserMapper.xml
  34. 70 0
      netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml
  35. 6 0
      netflix-dao/src/main/resources/mapper/UserDistributeMapper.xml
  36. 5 0
      netflix-service/src/main/java/com/cyksj/service/coupon/CouponFontService.java
  37. 13 4
      netflix-service/src/main/java/com/cyksj/service/coupon/impl/CouponFontServiceImpl.java
  38. 9 1
      netflix-service/src/main/java/com/cyksj/service/mange/coupon/impl/CouponCommonServiceImpl.java
  39. 7 1
      netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonServiceImpl.java
  40. 14 0
      netflix-service/src/main/java/com/cyksj/service/mange/ticket/TicketAdvertiseConfigClickRecordService.java
  41. 14 0
      netflix-service/src/main/java/com/cyksj/service/mange/ticket/TicketAdvertiseConfigService.java
  42. 48 0
      netflix-service/src/main/java/com/cyksj/service/mange/ticket/impl/TicketAdvertiseConfigClickRecordServiceImpl.java
  43. 25 0
      netflix-service/src/main/java/com/cyksj/service/mange/ticket/impl/TicketAdvertiseConfigServiceImpl.java
  44. 5 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  45. 23 7
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  46. 6 0
      netflix-service/src/main/java/com/cyksj/service/user/UserService.java
  47. 142 0
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
  48. 11 0
      netflix-web/src/main/java/com/cyksj/web/controller/coupon/CouponFrontController.java
  49. 2 5
      netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java
  50. 55 5
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  51. 0 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  52. 26 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  53. 87 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/sys/TicketAdvertiseConfigController.java
  54. 1 100
      netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java
  55. 31 6
      netflix-web/src/main/java/com/cyksj/web/controller/user/DistributePopularizeController.java
  56. 7 5
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

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

@@ -127,4 +127,6 @@ public interface Constant {
 	Long GENERAL_POPULARIZE_COUPON_ID = 111l;
 
 	String CORP_SERVICE_FOLLOWS_KEY = "corp_service_follows_key";
+
+	String NEW_USER_WELFARE_KEY = "new_user_welfare_key";
 }

+ 9 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java

@@ -2,8 +2,11 @@ package com.cyksj.mapper;
 
 import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.manage.views.GroupsRelationView;
+import com.cyksj.model.views.GroupsRelationUserView;
+import com.cyksj.model.views.UserRecommendGoodsFrontView;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 
@@ -42,4 +45,10 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
 	GroupsRelation selectOutsideRelationByGroupsId(@Param("groupsId") Long groupsId, @Param("relationNum") Integer relationNum);
 
 	List<GroupsRelation> selectExpiredChatGPTRelation(@Param("nextBeginDay") DateTime nextBeginDay, @Param("list") List<Long> gptSkuIds);
+
+	List<GroupsRelationUserView> getUserRelationUserViews(@Param("groupsId") Long groupsId, @Param("relationId") Long relationId, @Param("userId") Long userId, @Param("status") List<GroupsRelation.Status> status);
+
+	List<Long> getTicketGoodsId(@Param("list") List<Long> userIds, @Param("status") List<String> status);
+
+	Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(@Param("page") Page<UserRecommendGoodsFrontView> page, @Param("list") List<Long> filter_goods_id, @Param("isPayNf") Boolean isPayNf);
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/TicketAdvertiseConfigClickRecordMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.TicketAdvertiseConfigClickRecord;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigClickRecordMapper
+ *创建者: JavaZou
+ *创建时间:2023/7/12 12:22
+ */
+public interface TicketAdvertiseConfigClickRecordMapper extends BaseMapper<TicketAdvertiseConfigClickRecord> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/TicketAdvertiseConfigMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.TicketAdvertiseConfig;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigMapper
+ *创建者: JavaZou
+ *创建时间:2023/7/12 12:21
+ */
+public interface TicketAdvertiseConfigMapper extends BaseMapper<TicketAdvertiseConfig> {
+}

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/coupon/CouponUserMapper.java

@@ -1,5 +1,6 @@
 package com.cyksj.mapper.manage.coupon;
 
+import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -24,4 +25,6 @@ public interface CouponUserMapper extends BaseMapper<CouponUser> {
 	Page<CouponActiveView> couponCenterList(@Param("userId") Long userId, IPage<CouponUserView> page);
 
 	Page<CouponUserView> couponPersonalList(@Param("userId") Long userId, @Param("page") Page<CouponUserView> page);
+
+	CouponUserView getNewUserWelfareCouponsByUserId(@Param("userId") long userId, @Param("channel") CouponUser.Channel channel, @Param("now") DateTime now);
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeMapper.java

@@ -1,6 +1,7 @@
 package com.cyksj.mapper.manage.distribute;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.DistributeMoneyApply;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.UserDistribute;
 import com.cyksj.model.views.UserDistributeViews;
@@ -31,4 +32,6 @@ public interface UserDistributeMapper extends BaseMapper<UserDistribute> {
 	User getUserDistributeDetail(@Param("loginPhone") String loginPhone, @Param("email") String email);
 
 	Integer getDistributeGoodsRateByUidAndGid(@Param("userId") Long userId, @Param("goodsId") Long goodsId);
+
+	DistributeMoneyApply selectRelationBusiness(Long userId);
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/CouponPopularizeDto.java

@@ -61,6 +61,8 @@ public class CouponPopularizeDto {
 
 	private Integer validDays;
 
+	private Integer validHours;
+
 	private Boolean isValidTime;
 
 	private Date validStartTime;

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/NewUserWelfareDto.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: NewUserWelfareDto
+ *创建者: JavaZou
+ *创建时间:2023/7/11 15:03
+ */
+@Getter
+@Setter
+public class NewUserWelfareDto {
+	private List<Long> couponIds;
+}

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

@@ -88,6 +88,11 @@ public class Coupon extends BaseEntity {
 	 */
 	private Integer validDays;
 
+	/**
+	 * 领取有效小时
+	 */
+	private Integer validHours;
+
 	/**
 	 * 使用范围
 	 */

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

@@ -63,6 +63,7 @@ public class CouponUser extends BaseEntity {
 		ques_response("ques_response", "问卷回答"),
 		corp_bulk_task("corp_bulk_task", "企业微信群发任务"),
 		channel_popularize("channel_popularize", "渠道推广"),
+		new_welfare("new_welfare", "新人福利"),
 		;
 		private String channel;
 		private String desc;

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/DistributeMoneyApply.java

@@ -1,5 +1,6 @@
 package com.cyksj.model.entity;
 
+import cn.hutool.core.util.StrUtil;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -34,16 +35,41 @@ public class DistributeMoneyApply extends BaseEntity {
 
 	private String img;
 
+	/**
+	 * 钱包地址
+	 */
+	private String walletAddr;
+
+	/**
+	 * 备注
+	 */
+	private String remark;
+
+	private Long businessId;
+
+	private String businessName;
+
 	@Getter
 	public enum Type {
 		zfb("支付宝"),
 		wechat("微信"),
+		usdt("usdt"),
+		pwdRed("口令红包"),
+		other("其他")
 		;
 		String desc;
 
 		Type(String desc) {
 			this.desc = desc;
 		}
+
+		public Type getType(String value) {
+			if (StrUtil.isEmpty(value)) {
+				return null;
+			}
+			return Arrays.stream(Type.values()).filter(type -> type.name().equals(value)).findFirst().get();
+		}
+
 	}
 
 	@Getter

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GoodsDon.java

@@ -112,6 +112,11 @@ public class GoodsDon extends BaseEntity {
      */
     private Integer minMonths;
 
+    /**
+     * 最小规格 天数
+     */
+    private Integer minDays;
+
     /**
      * 最大规格价格
      */
@@ -122,6 +127,11 @@ public class GoodsDon extends BaseEntity {
      */
     private Integer maxMonths;
 
+    /**
+     * 最大规格 天数
+     */
+    private Integer maxDays;
+
     /**
      * 付款说明
      */

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

@@ -1,5 +1,6 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
 import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.*;
 
@@ -111,6 +112,7 @@ public class OrderDon extends BaseEntity implements Serializable {
      * 订单标注来源
      * 用于客服标注订单来源
      */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
     private String labelSource;
 
     /**
@@ -255,4 +257,17 @@ public class OrderDon extends BaseEntity implements Serializable {
             this.desc = desc;
         }
     }
+
+    @Getter
+    public enum LabelSource {
+        red_book("小红书"),
+        guang_dian("广点通"),
+        tik_tok("抖音付费"),
+        ;
+        String desc;
+
+        LabelSource(String desc) {
+            this.desc = desc;
+        }
+    }
 }

+ 2 - 4
netflix-dao/src/main/java/com/cyksj/model/entity/RealGoodsOrderHandle.java

@@ -1,9 +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.baomidou.mybatisplus.annotation.*;
 import com.ejlchina.searcher.bean.DbField;
 import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Getter;
@@ -66,6 +63,7 @@ public class RealGoodsOrderHandle{
 	 * 用于客服标注订单来源
 	 */
 	@DbField("rh.label_source")
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
 	private String labelSource;
 
 	/**

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

@@ -0,0 +1,56 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfig
+ *创建者: JavaZou
+ *创建时间:2023/7/12 12:20
+ */
+@Getter
+@Setter
+@SearchBean(tables = "ticket_advertise_config tc left join goods_don g on g.id = tc.goods_id"
+		, where = "tc.deleted is true")
+public class TicketAdvertiseConfig extends BaseEntity {
+	@DbField("tc.id")
+	@TableField(exist = false)
+	private Long configId;
+
+	@NotEmpty(message = "标题不为空")
+	@DbField("tc.title")
+	private String title;
+
+	@NotNull(message = "请选择对应平台")
+	@DbField("tc.goods_id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	@TableField(exist = false)
+	private String goodsTitle;
+
+	@DbField("tc.link")
+	private String link;
+
+	@DbField("tc.pic")
+	private String pic;
+
+	@DbField("tc.sorted")
+	private Integer sorted;
+
+	@DbField("tc.click")
+	private Integer click;
+
+	@DbField("tc.status")
+	private Boolean status;
+
+	@DbField("tc.deleted")
+	private Boolean deleted;
+}

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

@@ -0,0 +1,18 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigClickRecord
+ *创建者: JavaZou
+ *创建时间:2023/7/12 12:21
+ */
+@Getter
+@Setter
+public class TicketAdvertiseConfigClickRecord extends BaseEntity{
+	private Long userId;
+
+	private Long configId;
+}

+ 93 - 0
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelServiceMonthStatisticsData.java

@@ -0,0 +1,93 @@
+package com.cyksj.model.excel;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.cyksj.model.entity.OrderDon;
+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;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: ExcelServiceMonthStatisticsData
+ *创建者: JavaZou
+ *创建时间:2023/7/11 10:37
+ */
+@Getter
+@Setter
+@SearchBean(tables = "real_goods_order_handle rh left join order_don od on od.id = rh.order_id" +
+		" left join goods_don_sku gdk on gdk.id = od.sku_id" +
+		" left join goods_don gd on gd.id = gdk.goods_id" +
+		" left join user u on u.id = od.user_id")
+public class ExcelServiceMonthStatisticsData {
+
+	@DbField("gd.title")
+	@ExcelProperty("商品名称")
+	private String goodsName;
+
+	@DbField("gdk.id")
+	@ExcelIgnore
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	@ExcelProperty("规格")
+	private String specVal;
+
+	@DbField("cast(od.money/100 as decimal(10,2))")
+	@ExcelProperty("金额")
+	private BigDecimal money;
+
+	@DbField("u.nickname")
+	@ExcelProperty("用户名")
+	private String nickname;
+
+	@DbField("u.id")
+	@ExcelProperty("用户ID")
+	private Long userId;
+
+	@DbField("od.status")
+	@ExcelIgnore
+	private OrderDon.Status status;
+
+	/**
+	 * 订单标注来源
+	 * 用于客服标注订单来源
+	 */
+	@DbField("rh.label_source")
+	@ExcelIgnore
+	private String labelSource;
+
+	@DbIgnore
+	@ExcelProperty("订单来源")
+	private String labelSourceStr;
+
+	@DbField("od.created_time")
+	@ExcelProperty("日期")
+	private Date createdTime;
+
+	@DbField("rh.before_service_name")
+	@ExcelIgnore
+	private String beforeServiceName;
+
+	@DbField("rh.after_service_name")
+	@ExcelIgnore
+	private String afterServiceName;
+
+	@DbField("rh.created_time")
+	@ExcelIgnore
+	private Date recordCreatedTime;
+
+	public String getLabelSourceStr() {
+		if (StrUtil.isEmpty(labelSource)) {
+			return null;
+		}
+		OrderDon.LabelSource labelSource = OrderDon.LabelSource.valueOf(this.labelSource);
+		return labelSource.getDesc();
+	}
+}

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ApplyMoneyReq.java

@@ -23,4 +23,14 @@ public class ApplyMoneyReq {
 	 * true提现所有积分金额
 	 */
 	private Boolean isTakeAll;
+
+	/**
+	 * 钱包地址
+	 */
+	private String walletAddr;
+
+	/**
+	 * 备注
+	 */
+	private String remark;
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponActiveView.java

@@ -116,6 +116,9 @@ public class CouponActiveView {
 	@DbField("c.valid_days")
 	private Integer validDays;
 
+	@DbField("c.valid_hours")
+	private Integer validHours;
+
 	/**
 	 * 使用范围
 	 */

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CouponRecommendView.java

@@ -127,6 +127,9 @@ public class CouponRecommendView {
 	@DbField("c.valid_days")
 	private Integer validDays;
 
+	@DbField("c.valid_hours")
+	private Integer validHours;
+
 	/**
 	 * 使用范围
 	 */

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

@@ -128,12 +128,18 @@ public class CouponUserView {
 	@DbField("c.valid_days")
 	private Integer validDays;
 
+	@DbField("c.valid_hours")
+	private Integer validHours;
+
 	/**
 	 * 截止有效时间
 	 */
 	@DbField("cu.valid_end_time")
 	private Date validEndTime;
 
+	@DbIgnore
+	private Long validEndTimestamp;
+
 	@DbField("c.use_scope")
 	private Coupon.UseScope useScope;
 

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

@@ -103,6 +103,12 @@ public class CouponView {
 	@DbField("c.valid_days")
 	private Integer validDays;
 
+	/**
+	 * 领取有效小时
+	 */
+	@DbField("c.valid_hours")
+	private Integer validHours;
+
 	/**
 	 * 使用范围
 	 */

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributeMoneyApplyView.java

@@ -54,4 +54,17 @@ public class DistributeMoneyApplyView {
 
 	@DbField("dma.created_time")
 	private Date createdTime;
+
+	@DbField("dma.wallet_addr")
+	private String walletAddr;
+
+	@DbField("dma.remark")
+	private String remark;
+
+	@DbField("dma.business_id")
+	private Long businessId;
+
+	@DbField("dma.business_name")
+	private String businessName;
+
 }

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsHomePageView.java

@@ -43,6 +43,9 @@ public class GoodsHomePageView {
 	@DbField("g.logo")
 	private String logo;
 
+	@DbField("g.img")
+	private String img;
+
 	/**
 	 * 类型
 	 */

+ 22 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GroupsRelationUserView.java

@@ -0,0 +1,22 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: GroupsRelationUserView
+ *创建者: JavaZou
+ *创建时间:2023/7/11 16:28
+ */
+@Getter
+@Setter
+public class GroupsRelationUserView {
+	private Long relationId;
+
+	private Boolean isSelf;
+
+	private String nickname;
+
+	private String headimgurl;
+}

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java

@@ -11,6 +11,7 @@ import lombok.Setter;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.List;
 
 /**
  * @author chan
@@ -33,6 +34,9 @@ public class RenewalView {
     @DbField("sku.months")
     private Integer months;
 
+    @DbField("sku.days")
+    private Integer days;
+
     @JsonIgnore
     @DbField("sku.num")
     private Long skuNum;
@@ -64,6 +68,10 @@ public class RenewalView {
     @DbField("g.category")
     private Integer category;
 
+    @DbField("g.type")
+    @JsonIgnore
+    private Integer goodsType;
+
     /**
      * 二级分类
      * 虚物品 1邀请制 2非邀请制
@@ -79,8 +87,12 @@ public class RenewalView {
     private Long userId;
 
     @DbField("gr.expiry_time")
+    @JsonIgnore
     private Date expiryTime;
 
+    @DbIgnore
+    private String expiryTimeStr;
+
     @DbField("gr.status")
     private String status;
 
@@ -116,4 +128,10 @@ public class RenewalView {
 
     @DbIgnore
     private GoodsDonViews goodsDonViews;
+
+    @DbIgnore
+    private String remainDays;
+
+    @DbIgnore
+    private List<GroupsRelationUserView> relationViews;
 }

+ 15 - 1
netflix-dao/src/main/java/com/cyksj/model/views/ServiceOrdersDetailView.java

@@ -1,11 +1,13 @@
 package com.cyksj.model.views;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.cyksj.model.entity.OrderDon;
 import com.ejlchina.searcher.bean.DbField;
 import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /*
@@ -22,6 +24,7 @@ import java.util.Date;
 		" left join user u on u.id = od.user_id")
 public class ServiceOrdersDetailView {
 	@DbField("gd.id")
+	@ExcelIgnore
 	private Long goodsId;
 
 	@DbField("gd.title")
@@ -34,7 +37,7 @@ public class ServiceOrdersDetailView {
 	private String specVal;
 
 	@DbField("od.money")
-	private Long money;
+	private BigDecimal money;
 
 	@DbField("u.nickname")
 	private String nickname;
@@ -43,17 +46,28 @@ public class ServiceOrdersDetailView {
 	private Long userId;
 
 	@DbField("od.status")
+	@ExcelIgnore
 	private OrderDon.Status status;
 
+	/**
+	 * 订单标注来源
+	 * 用于客服标注订单来源
+	 */
+	@DbField("rh.label_source")
+	private String labelSource;
+
 	@DbField("od.created_time")
 	private Date createdTime;
 
 	@DbField("rh.before_service_name")
+	@ExcelIgnore
 	private String beforeServiceName;
 
 	@DbField("rh.after_service_name")
+	@ExcelIgnore
 	private String afterServiceName;
 
 	@DbField("rh.created_time")
+	@ExcelIgnore
 	private Date recordCreatedTime;
 }

+ 39 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TicketAdvertiseConfigFrontView.java

@@ -0,0 +1,39 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigFrontView
+ *创建者: JavaZou
+ *创建时间:2023/7/12 14:16
+ */
+@Getter
+@Setter
+@SearchBean(tables = "ticket_advertise_config tc left join goods_don g on g.id = tc.goods_id"
+		, where = "tc.deleted is true and tc.status is true")
+public class TicketAdvertiseConfigFrontView {
+	@DbField("tc.id")
+	private Long configId;
+
+	@DbField("tc.goods_id")
+	@JsonIgnore
+	private Long goodsId;
+
+	@DbField("tc.title")
+	private String title;
+
+	@DbField("g.title")
+	private String goodsTitle;
+
+	@DbField("tc.link")
+	private String link;
+
+	@DbField("tc.pic")
+	private String pic;
+}

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserRecommendGoodsFrontView.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/*
+ *项目名: netflix
+ *文件名: UserRecommendGoodsFrontView
+ *创建者: JavaZou
+ *创建时间:2023/7/17 16:34
+ */
+@Getter
+@Setter
+@SearchBean(tables = "goods_don g"
+		, where = "g.type = 2 and g.deleted is true and g.status is true")
+public class UserRecommendGoodsFrontView {
+	private Long goodsId;
+
+	private String title;
+
+	private String logo;
+
+	private String img;
+
+	private String tags;
+
+	private Integer type;
+
+	private Integer months;
+
+	private Integer days;
+
+	private BigDecimal price;
+}

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserTicketView.java

@@ -2,6 +2,7 @@ package com.cyksj.model.views;
 
 import com.ejlchina.searcher.bean.DbField;
 import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -33,4 +34,8 @@ public class UserTicketView {
 
 	@DbField("gdk.spec_val")
 	private String specVal;
+
+	@DbField("gr.status")
+	@JsonIgnore
+	private String status;
 }

+ 1 - 0
netflix-dao/src/main/resources/mapper/CouponMapper.xml

@@ -29,6 +29,7 @@
                cp.reduce_condition,
                cp.discount,
                cp.valid_days,
+               cp.valid_hours,
                cp.valid_start_time,
                cp.valid_end_time,
                cp.is_valid_time

+ 1 - 0
netflix-dao/src/main/resources/mapper/CouponRecommendMapper.xml

@@ -17,6 +17,7 @@
         cu.valid_start_time as userValidStartTime,
         cu.valid_end_time as userValidEndTime,
         c.valid_days,
+        c.valid_hours,
         c.is_renew,
         c.scope,
         (case

+ 27 - 0
netflix-dao/src/main/resources/mapper/CouponUserMapper.xml

@@ -17,6 +17,7 @@
         cu.valid_start_time,
         cu.valid_end_time,
         cp.valid_days,
+        cp.valid_hours,
         cp.use_scope,
         cu.created_time,
         cu.status as couponUserStatus,
@@ -104,6 +105,7 @@
                      c.valid_start_time,
                      c.valid_end_time,
                      c.valid_days,
+                     c.valid_hours,
                      ca.num,
                      ca.`status`,
                      ca.expiry_status,
@@ -152,6 +154,7 @@
                c.is_valid_time,
                cu.valid_start_time,
                c.valid_days,
+               c.valid_hours,
                cu.valid_end_time,
                (case
                     when cu.status = 'used' then 'used'
@@ -173,4 +176,28 @@
           and cu.channel != 'exCode'
         order by `orderby`)s where s.couponUserStatus != 'expired' and s.couponUserStatus != 'invalid'
     </select>
+
+    <select id="getNewUserWelfareCouponsByUserId" resultType="com.cyksj.model.views.CouponUserView">
+        select cu.*,
+               c.name,
+               c.goods_type,
+               c.type,
+               c.reduce_condition,
+               c.reduce_money,
+               c.discount,
+               c.use_scope,
+               c.goods_sku_ids,
+               cu.valid_start_time,
+               cu.valid_end_time,
+               unix_timestamp(cu.valid_end_time) * 1000 as validEndTimestamp
+        from (select coupon_id,
+                     valid_start_time,
+                     valid_end_time,
+                     status as couponUserStatus
+              from `coupon_user`
+              where channel = #{channel}
+                and user_id = #{userId}
+                and valid_end_time > #{now} limit 1) cu
+                 inner join coupon c on c.id = cu.coupon_id
+    </select>
 </mapper>

+ 70 - 0
netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml

@@ -137,4 +137,74 @@
         </foreach>
         and gr.expiry_time &lt;= #{nextBeginDay}
     </select>
+
+    <select id="getUserRelationUserViews" resultType="com.cyksj.model.views.GroupsRelationUserView">
+        select gr.*,
+        u.nickname,
+        u.headimgurl
+        from (select * from (select id as relation_id,
+        user_id,
+        1 as isSelf from groups_relation where id = #{relationId}
+        and status in
+        <foreach collection="status" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        limit 1)s1
+        union all
+        select * from (select id as realtion_id,
+        user_id,
+        if(user_id = #{userId},true,false) as isSelf from groups_relation where id != #{relationId}
+        and groups_id = #{groupsId}
+        and status in
+        <foreach collection="status" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        limit 4)s2)gr inner join user u on u.id = gr.user_id
+    </select>
+
+    <select id="getTicketGoodsId" resultType="java.lang.Long">
+        select distinct goods_id from (select sku.goods_id from (select * from `groups_relation` where status in
+        <foreach collection="status" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and user_id in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>)gr left join groups_trips gt on gt.id = gr.groups_id
+        left join goods_don_sku sku on sku.id = gt.sku_id
+        union all
+        select goods_id from order_don o where user_id in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and relation_id = 0 and status not in ('close','noPayment','refund'))s
+    </select>
+
+    <select id="getRecommendGoodsViews" resultType="com.cyksj.model.views.UserRecommendGoodsFrontView">
+        select * from (select
+        id as goodsId,
+        title,
+        logo,
+        img,
+        tags,
+        sort_by,
+        `type`,
+        min_months as months,
+        min_days as days,
+        min_price as price,
+        (
+        case when type = 2 and ${isPayNf} then 999
+        when type = 2 and !${isPayNf} then 666
+        when category = 1 then 888
+        when category = 2 then 777
+        when category = 3 then 755
+        else 666 end
+        ) as sorted
+        from `goods_don` where id not in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        and type in (1,2)
+        and deleted is true and status is true) s order by s.sorted desc,sort_by desc
+    </select>
 </mapper>

+ 6 - 0
netflix-dao/src/main/resources/mapper/UserDistributeMapper.xml

@@ -95,4 +95,10 @@
                             on udr.distribute_id = ud.id
         where udr.goods_id = #{goodsId}
     </select>
+
+    <select id="selectRelationBusiness" resultType="com.cyksj.model.entity.DistributeMoneyApply">
+        select ud.business_id, cu.nickname as businessName
+        from (select business_id from user_distribute where user_id = #{userId} and deleted is true limit 1) ud
+                 inner join cms_user cu on cu.id = ud.business_id
+    </select>
 </mapper>

+ 5 - 0
netflix-service/src/main/java/com/cyksj/service/coupon/CouponFontService.java

@@ -61,4 +61,9 @@ public interface CouponFontService {
 	 * 渠道推广一键领取优惠券
 	 */
 	void collectAllChannelCoupons(long userId, Long popularizeId);
+
+	/**
+	 * 新用户福利优惠券
+	 */
+	CouponUserView getNewUserWelfareCoupons(long userId, DateTime now);
 }

+ 13 - 4
netflix-service/src/main/java/com/cyksj/service/coupon/impl/CouponFontServiceImpl.java

@@ -241,14 +241,18 @@ public class CouponFontServiceImpl implements CouponFontService {
 	@Override
 	public void updateCouponUserValidTime(Long couponId, CouponUser couponUser) {
 		Coupon entity = couponMapper.getCouponById(couponId);
-		Optional.ofNullable(entity).ifPresent(coupon->{
+		Optional.ofNullable(entity).ifPresent(coupon -> {
 			if (coupon.getIsValidTime()) {
 				couponUser.setValidStartTime(coupon.getValidStartTime());
 				couponUser.setValidEndTime(coupon.getValidEndTime());
-			} else {
-				couponUser.setValidStartTime(DateTime.now());
-				couponUser.setValidEndTime(DateUtil.offsetDay(couponUser.getValidStartTime(), coupon.getValidDays()));
+				return;
 			}
+			couponUser.setValidStartTime(DateTime.now());
+			if (coupon.getValidHours() > 0) {
+				couponUser.setValidEndTime(DateUtil.offsetHour(couponUser.getValidStartTime(), coupon.getValidHours()));
+				return;
+			}
+			couponUser.setValidEndTime(DateUtil.offsetDay(couponUser.getValidStartTime(), coupon.getValidDays()));
 		});
 	}
 
@@ -352,4 +356,9 @@ public class CouponFontServiceImpl implements CouponFontService {
 			throw BusinessRuntimeException.getInstance("已领取成功");
 		}
 	}
+
+	@Override
+	public CouponUserView getNewUserWelfareCoupons(long userId, DateTime now) {
+		return couponUserMapper.getNewUserWelfareCouponsByUserId(userId, CouponUser.Channel.new_welfare, now);
+	}
 }

+ 9 - 1
netflix-service/src/main/java/com/cyksj/service/mange/coupon/impl/CouponCommonServiceImpl.java

@@ -230,9 +230,17 @@ public class CouponCommonServiceImpl implements CouponCommonService {
 					throw BusinessRuntimeException.getInstance("请输入正确的有效起始和截止时间");
 				}
 			} else {
-				if (coupon.getValidDays() == null || coupon.getValidDays() < 0) {
+				if (coupon.getValidDays() == null && coupon.getValidHours() == null) {
+					throw BusinessRuntimeException.getInstance("请选择对应领取后有效时间");
+				}
+
+				if (coupon.getValidDays() != null || coupon.getValidDays() < 0) {
 					throw BusinessRuntimeException.getInstance("请输入正确的有效天数");
 				}
+
+				if (coupon.getValidHours() != null || coupon.getValidHours() < 0) {
+					throw BusinessRuntimeException.getInstance("请输入正确的有效小时");
+				}
 			}
 		}
 		if (StrUtil.isNotEmpty(coupon.getExCode())) {

+ 7 - 1
netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonServiceImpl.java

@@ -30,20 +30,26 @@ public class CmsGoodsDonServiceImpl extends ServiceImpl<GoodsDonMapper, GoodsDon
 		List<GoodsDonFrontSkuView> skuViews = beanSearcher.searchAll(GoodsDonFrontSkuView.class, MapUtils.builder()
 				.field(GoodsDonFrontSkuView::getGoodsId, goodsId)
 				.field(GoodsDonFrontSkuView::getStatus, true)
-				.orderBy(GoodsDonFrontSkuView::getPrice).asc().onlySelect(GoodsDonFrontSkuView::getPrice, GoodsDonFrontSkuView::getMonths).build());
+				.orderBy(GoodsDonFrontSkuView::getPrice).asc().onlySelect(GoodsDonFrontSkuView::getPrice, GoodsDonFrontSkuView::getMonths, GoodsDonFrontSkuView::getDays)
+				.build());
 		if (!skuViews.isEmpty()) {
 			GoodsDonFrontSkuView min = skuViews.get(0);
 			if (skuViews.size() == 1) {
 				goods.setMinPrice(min.getPrice());
 				goods.setMinMonths(min.getMonths());
+				goods.setMinDays(min.getDays());
+
 				goods.setMaxPrice(min.getPrice());
 				goods.setMaxMonths(min.getMonths());
 			} else {
 				GoodsDonFrontSkuView max = skuViews.get(skuViews.size() - 1);
 				goods.setMinPrice(min.getPrice());
 				goods.setMinMonths(min.getMonths());
+				goods.setMinDays(min.getDays());
+
 				goods.setMaxPrice(max.getPrice());
 				goods.setMaxMonths(max.getMonths());
+				goods.setMaxDays(max.getDays());
 			}
 			goodsDonMapper.updateById(goods);
 		}

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/mange/ticket/TicketAdvertiseConfigClickRecordService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.mange.ticket;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.TicketAdvertiseConfigClickRecord;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigClickRecordService
+ *创建者: JavaZou
+ *创建时间:2023/7/12 14:01
+ */
+public interface TicketAdvertiseConfigClickRecordService extends IService<TicketAdvertiseConfigClickRecord> {
+	void recordUserClickTicketAdvertise(long userId, Long configId);
+}

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/mange/ticket/TicketAdvertiseConfigService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.mange.ticket;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.TicketAdvertiseConfig;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigService
+ *创建者: JavaZou
+ *创建时间:2023/7/12 13:49
+ */
+public interface TicketAdvertiseConfigService extends IService<TicketAdvertiseConfig> {
+	void saveOrUpdateAdvertiseConfig(TicketAdvertiseConfig config);
+}

+ 48 - 0
netflix-service/src/main/java/com/cyksj/service/mange/ticket/impl/TicketAdvertiseConfigClickRecordServiceImpl.java

@@ -0,0 +1,48 @@
+package com.cyksj.service.mange.ticket.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.TicketAdvertiseConfigClickRecordMapper;
+import com.cyksj.mapper.TicketAdvertiseConfigMapper;
+import com.cyksj.model.entity.TicketAdvertiseConfig;
+import com.cyksj.model.entity.TicketAdvertiseConfigClickRecord;
+import com.cyksj.service.mange.ticket.TicketAdvertiseConfigClickRecordService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigClickRecordServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/7/12 14:01
+ */
+@Service
+@RequiredArgsConstructor
+public class TicketAdvertiseConfigClickRecordServiceImpl extends ServiceImpl<TicketAdvertiseConfigClickRecordMapper, TicketAdvertiseConfigClickRecord> implements TicketAdvertiseConfigClickRecordService {
+	private final TicketAdvertiseConfigMapper ticketAdvertiseConfigMapper;
+
+	@Override
+	public void recordUserClickTicketAdvertise(long userId, Long configId) {
+		TicketAdvertiseConfig ticketAdvertiseConfig = ticketAdvertiseConfigMapper.selectById(configId);
+		if (ticketAdvertiseConfig == null) return;
+		TicketAdvertiseConfigClickRecord record = new TicketAdvertiseConfigClickRecord();
+		record.setUserId(userId);
+		record.setConfigId(configId);
+		this.save(record);
+
+		updateAdvertiseClickNum(ticketAdvertiseConfig.getId(), ticketAdvertiseConfig.getClick());
+	}
+
+	public void updateAdvertiseClickNum(Long configId, Integer o_click) {
+		int update = 0;
+		while (update != 1) {
+			TicketAdvertiseConfig ticketAdvertiseConfig = ticketAdvertiseConfigMapper.selectById(configId);
+			if (ticketAdvertiseConfig == null) break;
+			o_click = ticketAdvertiseConfig.getClick();
+			update = ticketAdvertiseConfigMapper.update(null, Wrappers.lambdaUpdate(TicketAdvertiseConfig.class)
+					.set(TicketAdvertiseConfig::getClick, o_click + 1)
+					.eq(TicketAdvertiseConfig::getId, configId)
+					.eq(TicketAdvertiseConfig::getClick, o_click));
+		}
+	}
+}

+ 25 - 0
netflix-service/src/main/java/com/cyksj/service/mange/ticket/impl/TicketAdvertiseConfigServiceImpl.java

@@ -0,0 +1,25 @@
+package com.cyksj.service.mange.ticket.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.TicketAdvertiseConfigMapper;
+import com.cyksj.model.entity.TicketAdvertiseConfig;
+import com.cyksj.service.mange.ticket.TicketAdvertiseConfigService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: TicketAdvertiseConfigServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/7/12 13:50
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class TicketAdvertiseConfigServiceImpl extends ServiceImpl<TicketAdvertiseConfigMapper, TicketAdvertiseConfig> implements TicketAdvertiseConfigService {
+	@Override
+	public void saveOrUpdateAdvertiseConfig(TicketAdvertiseConfig config) {
+		this.saveOrUpdate(config);
+	}
+}

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

@@ -1,7 +1,10 @@
 package com.cyksj.service.relation;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.views.RenewalView;
+import com.cyksj.model.views.UserRecommendGoodsFrontView;
 
 import java.util.List;
 
@@ -17,4 +20,6 @@ public interface GroupRelationFrontService {
 	Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon);
 
 	GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer days, Integer months, List<Long> errorsRelationIds);
+
+	Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(Boolean isPayNf, List<Long> filter_goods_id, Integer start, Integer limit);
 }

+ 23 - 7
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -1,18 +1,17 @@
 package com.cyksj.service.relation.impl;
 
+import cn.hutool.core.date.BetweenFormater;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
-import com.cyksj.mapper.corp.CorpUserMapper;
 import com.cyksj.model.entity.*;
-import com.cyksj.model.views.CorpUserFollowView;
-import com.cyksj.model.views.GoodsDonViews;
-import com.cyksj.model.views.RenewalView;
+import com.cyksj.model.views.*;
 import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.user.UserService;
@@ -43,8 +42,6 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final BeanSearcher beanSearcher;
 
-	private final CorpUserMapper corpUserMapper;
-
 	private final CouponCommonService couponCommonService;
 
 	private final GroupsRelationMapper groupsRelationMapper;
@@ -80,9 +77,23 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				GoodsDonViews views = beanSearcher.searchFirst(GoodsDonViews.class, MapUtils.builder().field(GoodsDonViews::getId, ticket.getGoodsId()).build());
 				views.setSpecs(beanSearcher.searchFirst(GoodsDonSpec.class, MapUtils.builder().field(GoodsDonSpec::getGoodsId, views.getId()).build()));
 				views.setSkuList(beanSearcher.searchAll(GoodsDonSku.class, MapUtils.builder().field(GoodsDonSku::getGoodsId, views.getId()).field(GoodsDonSku::getStatus, true).build()));
-
 				ticket.setGoodsDonViews(views);
 			}
+			if (ticket.getMonths() != null && ticket.getMonths() >= 300) {
+				ticket.setExpiryTime(null);
+			}
+			if (ticket.getExpiryTime() != null && ticket.getGoodsType() == 1 && ticket.getSecondType() == 2) {
+				String remainDays = DateUtil.formatBetween(now, ticket.getExpiryTime(), BetweenFormater.Level.DAY);
+				if ("0天".equals(remainDays)) {
+					remainDays = "小于1天";
+				}
+				ticket.setRemainDays(remainDays);
+			}
+			List<GroupsRelationUserView> relationUserViews = groupsRelationMapper.getUserRelationUserViews(ticket.getGroupId(), ticket.getRelationId(), ticket.getUserId(), List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside));
+			ticket.setRelationViews(relationUserViews);
+			if (ticket.getExpiryTime() != null) {
+				ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd"));
+			}
 			return true;
 		}).collect(Collectors.toList());
 		return collect;
@@ -146,4 +157,9 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		}
 		return relation;
 	}
+
+	@Override
+	public Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(Boolean isPayNf, List<Long> filter_goods_id, Integer start, Integer limit) {
+		return groupsRelationMapper.getRecommendGoodsViews(new Page<>(start, limit),filter_goods_id, isPayNf);
+	}
 }

+ 6 - 0
netflix-service/src/main/java/com/cyksj/service/user/UserService.java

@@ -5,6 +5,7 @@ import com.cyksj.model.dto.GzhOAuth2UserInfo;
 import com.cyksj.model.dto.UserWhoami;
 import com.cyksj.model.entity.User;
 import com.cyksj.model.entity.WxSyncLog;
+import com.cyksj.model.request.LoginReq;
 
 import java.util.List;
 
@@ -41,4 +42,9 @@ public interface UserService extends IService<User> {
 	 * 根据showId 获取用户id
 	 */
 	Long getUserIdByShowId(String showId);
+
+	/**
+	 * 验证码登录
+	 */
+	User webLogin(LoginReq loginReq) throws Exception;
 }

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

@@ -1,6 +1,8 @@
 package com.cyksj.service.user.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;
@@ -8,16 +10,20 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
+import com.cyksj.common.util.Codec;
 import com.cyksj.common.util.Jsons;
 import com.cyksj.common.util.StringUtil;
+import com.cyksj.mapper.PhoneCodeMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.channel.ChannelPopularizeMapper;
 import com.cyksj.mapper.manage.cps.UserDistributePopularizeMapper;
 import com.cyksj.mapper.market.task.UserBindDetailMapper;
 import com.cyksj.model.dto.GzhOAuth2UserInfo;
 import com.cyksj.model.dto.OrderDonPostDataDto;
+import com.cyksj.model.dto.NewUserWelfareDto;
 import com.cyksj.model.dto.UserWhoami;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.request.LoginReq;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.distribute.DistributeService;
 import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
@@ -31,6 +37,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 
@@ -60,6 +67,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
 	private final UserMapper userMapper;
 
+	private final PhoneCodeMapper phoneCodeMapper;
+
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
 	@Override
@@ -103,6 +112,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 						.setCallbackType(callbackType);
 				redisService.set(RedisService.key.ORDER_DON_POST_DATA_USER_KEY.getName() + user.getId(), Jsons.toJson(orderDonPostDataDto));
 			}
+			//发放新用户福利
+			final Long fUid = user.getId();
+			TASK_POOL.execute(() -> {
+				try {
+					sendNewUserWelfare(fUid);
+				} catch (Exception e) {
+				}
+			});
 		} else {
 			if (StrUtil.isEmpty(user.getRegisterEnv())) {
 				user.setRegisterEnv(registerEnv.name());
@@ -297,4 +314,129 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 		return userMapper.getUserIdByShowId(showId);
 	}
 
+	@Override
+	public User webLogin(LoginReq loginReq) throws Exception {
+		LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class).last("limit 1");
+		if (loginReq.getType() == null || loginReq.getType() < 1 && loginReq.getType() > 2) {
+			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
+		}
+		if (loginReq.getType() == 1) {
+			if (StrUtil.hasEmpty(loginReq.getPhone(), loginReq.getCode())) {
+				throw BusinessRuntimeException.getInstance("请输入对应信息");
+			}
+			DateTime now = DateTime.now();
+			PhoneCode phoneCode = phoneCodeMapper.selectOne(Wrappers.lambdaQuery(PhoneCode.class).eq(PhoneCode::getPhone, loginReq.getPhone()).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(loginReq.getCode(), phoneCode.getCode())) {
+				throw BusinessRuntimeException.getInstance("手机验证码错误,请重新输入");
+			}
+			wrapper.eq(User::getLoginPhone, loginReq.getPhone());
+		}
+		if (loginReq.getType() == 2) {
+			if (StrUtil.isEmpty(loginReq.getEmail())) {
+				throw BusinessRuntimeException.getInstance("邮箱不能为空");
+			}
+			String code = redisService.getStr(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
+			if (StrUtil.isEmpty(code)) {
+				throw BusinessRuntimeException.getInstance("邮箱验证码已失效,请重新获取");
+			}
+			if (!StrUtil.equals(loginReq.getCode(), code)) {
+				throw BusinessRuntimeException.getInstance("邮箱验证码错误,请重新输入");
+			}
+			wrapper.eq(User::getEmail, loginReq.getEmail());
+			redisService.del(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
+		}
+		//保存用户信息
+		User user = this.getOne(wrapper);
+		String dsCode = loginReq.getDsCode();
+		Long sharedId = loginReq.getSharedId();
+		Long dsPopularizeId = null;
+		if (StrUtil.isNotBlank(dsCode)) {
+			dsCode = dsCode.trim();
+			User sharedUser = this.getOne(Wrappers.lambdaQuery(User.class)
+					.eq(User::getShowId, dsCode).last("limit 1"));
+			if (sharedUser != null) {
+				sharedId = sharedUser.getId();
+			} else {
+				UserDistributePopularize distributePopularize = distributePopularizeMapper.selectOne(Wrappers.lambdaQuery(UserDistributePopularize.class)
+						.eq(UserDistributePopularize::getCode, dsCode)
+						.select(UserDistributePopularize::getUserId, UserDistributePopularize::getId).last("limit 1"));
+				if (distributePopularize != null) {
+					log.info("渠道sharedId:{}设置固定推广链接PC用户分销", distributePopularize.getUserId());
+					sharedId = distributePopularize.getUserId();
+					dsPopularizeId = distributePopularize.getId();
+				}
+			}
+		}
+		if (user == null) {
+			user = new User();
+			StringBuilder name = new StringBuilder();
+			name.append(Constant.DEFAULT_NAME);
+			if (loginReq.getPopularizeId() != null) {
+				user.setPopularizeId(loginReq.getPopularizeId());
+			}
+			if (loginReq.getType() == 1) {
+				user.setLoginPhone(loginReq.getPhone());
+			}
+			if (loginReq.getType() == 2) {
+				user.setEmail(loginReq.getEmail());
+				name.append("@");
+			}
+			user.setNickname(String.format("%s%s", name.toString(), Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(String.format("%s%s", user.getId(), loginReq.getType() == 1 ? user.getLoginPhone() : user.getEmail())).toHexString().substring(0, 6)));
+			//默认头像
+			user.setHeadimgurl(Constant.DEFAULT_HEAD_IMG);
+			String registerEnv = loginReq.getRegisterEnv();
+			user.setRegisterEnv(StrUtil.isEmpty(registerEnv) ? User.RegisterEnv.pc.name() : registerEnv);
+			this.save(user);
+			//新用户分销
+			if (sharedId != null) {
+				distributeService.saveDistributionInvitation(sharedId, user.getId(), dsPopularizeId);
+			}
+			//缓存用户注册 回传信息
+			String callback = loginReq.getCallback();
+			String callbackType = loginReq.getCallbackType();
+			if (StrUtil.isNotBlank(callback)) {
+				OrderDonPostDataDto orderDonPostDataDto = new OrderDonPostDataDto().setCallback(callback)
+						.setCallbackType(callbackType);
+				redisService.set(RedisService.key.ORDER_DON_POST_DATA_USER_KEY.getName() + user.getId(), Jsons.toJson(orderDonPostDataDto));
+			}
+			//发放新用户福利
+			final Long fUid = user.getId();
+			TASK_POOL.execute(() -> {
+				try {
+					sendNewUserWelfare(fUid);
+				} catch (Exception e) {
+				}
+			});
+		}
+		if (StrUtil.isEmpty(user.getShowId())) {
+			user.setShowId(getUserShowId(user.getId()));
+		}
+		return user;
+	}
+
+
+	/**
+	 * 发放新用户福利
+	 */
+	public void sendNewUserWelfare(Long userId) throws Exception {
+		SysConfig newUserWelfareConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
+				.eq(SysConfig::getSysKey, Constant.NEW_USER_WELFARE_KEY).last("limit 1"));
+		if (StrUtil.isEmpty(newUserWelfareConfig.getSysValue())) {
+			return;
+		}
+		NewUserWelfareDto newUserWelfareDto = Jsons.parseObject(newUserWelfareConfig.getSysValue(), NewUserWelfareDto.class);
+		if (newUserWelfareDto != null) {
+			List<Long> couponIds = newUserWelfareDto.getCouponIds();
+			couponIds.forEach(couponId -> couponCommonService.sendCouponToUser(userId, couponId, null, null, null, CouponUser.Channel.new_welfare));
+		}
+	}
 }

+ 11 - 0
netflix-web/src/main/java/com/cyksj/web/controller/coupon/CouponFrontController.java

@@ -352,4 +352,15 @@ public class CouponFrontController {
 		couponFontService.collectAllChannelCoupons(userId, popularizeId);
 		return GatewayResponse.SUCCESS.newBuilder().toResult("领取成功");
 	}
+
+	/**
+	 * 新用户福利 优惠券详情展示
+	 */
+	@GetMapping("/get/newUser/welfare")
+	public Result<CouponUserView> getNewUserWelfare() {
+		long userId = StpUserUtil.getLoginIdAsLong();
+		DateTime now = DateTime.now();
+		CouponUserView couponUserView = couponFontService.getNewUserWelfareCoupons(userId, now);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(couponUserView);
+	}
 }

+ 2 - 5
netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java

@@ -198,11 +198,6 @@ public class GoodsDonController {
                     .orderBy(OrderCommentFrontView::getId).desc()
                     .build());
             data.setComments(comments);
-            OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
-                    .eq(OrderDon::getGoodsId, data.getId())
-                    .notIn(OrderDon::getStatus, Constant.noOrderStatus).select(OrderDon::getCreatedTime, OrderDon::getPayTime, OrderDon::getId)
-                    .orderByDesc(OrderDon::getId)
-                    .last("limit 1"));
 	        data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1));
         });
         redisService.setNx(pcCacheKey, list, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
@@ -234,6 +229,7 @@ public class GoodsDonController {
             builder.field(GoodsFrontListView::getId, filter_goodsIds).op(Operator.NotIn);
         }
         List<GoodsHomePageView> dataList = beanSearcher.searchAll(GoodsHomePageView.class, builder.build());
+        DateTime now = DateTime.now();
         dataList.forEach(data -> {
             Integer sold = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
                     .eq(OrderDon::getGoodsId, data.getId()).notIn(OrderDon::getStatus, Constant.noOrderStatus));
@@ -244,6 +240,7 @@ public class GoodsDonController {
                 data.setMonths(skuView.getMonths());
                 data.setDays(skuView.getDays());
             }
+            data.setNotifyMsg(getPayMsgTime(data.getId(), now, 1));
         });
         redisService.setNx(h5CacheKey, dataList, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout());
         return GatewayResponse.SUCCESS.newBuilder().toResult(dataList);

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

@@ -9,7 +9,9 @@ import cn.hutool.extra.servlet.ServletUtil;
 import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.common.annotation.NoSubmit;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.snowflake.Sequence;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
@@ -26,12 +28,10 @@ import com.cyksj.model.dto.QuestionnaireView;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.OrderPayRequest;
-import com.cyksj.model.views.DoubleVerifyCodeView;
-import com.cyksj.model.views.QuestionnairePromotionFieldsListView;
-import com.cyksj.model.views.RenewalView;
-import com.cyksj.model.views.UserTicketView;
+import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
+import com.cyksj.service.mange.ticket.TicketAdvertiseConfigClickRecordService;
 import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.user.UserService;
@@ -91,7 +91,7 @@ public class GroupRelationController {
 
     private final QuestionnairePromotionMapper questionnairePromotionMapper;
 
-    private final QuestionnairePromotionMapper promotionMapper;
+    private final TicketAdvertiseConfigClickRecordService ticketAdvertiseConfigClickRecordService;
 
     private final GlobalThreadPoolTaskExecutor THREAD_POOL;
 
@@ -162,6 +162,7 @@ public class GroupRelationController {
         List<Long> userIds = userService.getRelationUserIdList(userId, null);
         List<UserTicketView> ticketViews = beanSearcher.searchAll(UserTicketView.class, MapUtils.builder()
                 .field(UserTicketView::getUserId, userIds).op(Operator.InList)
+                .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
                 .orderBy(UserTicketView::getRelationId).asc()
                 .build());
         return GatewayResponse.SUCCESS.newBuilder().toResult(ticketViews);
@@ -451,4 +452,53 @@ public class GroupRelationController {
         });
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+    /**
+     * 对应平台车票 广告配置列表
+     */
+    @GetMapping("/get/advertise/{goodsId}")
+    public Result<List<TicketAdvertiseConfigFrontView>> getTicketAdvertiseConfig(@PathVariable Long goodsId) {
+        List<TicketAdvertiseConfigFrontView> views = beanSearcher.searchAll(TicketAdvertiseConfigFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(TicketAdvertiseConfig::getGoodsId, goodsId)
+                .orderBy(TicketAdvertiseConfig::getSorted).desc()
+                .orderBy(TicketAdvertiseConfig::getId).desc()
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(views);
+    }
+
+    /**
+     * 记录用户点击车票广告
+     */
+    @PostMapping("/click/ticket/advertise/record/{configId}")
+    public Result<String> recordClickTicketAdvertise(@PathVariable Long configId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        ticketAdvertiseConfigClickRecordService.recordUserClickTicketAdvertise(userId, configId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * 推荐平台
+     */
+    @GetMapping("/get/recommend/goods")
+    public Result<Page<UserRecommendGoodsFrontView>> getRecommendGoodsViews(@RequestParam(defaultValue = "0") Integer start, @RequestParam(defaultValue = "5") Integer limit) {
+        //推荐用户未购买的车票平台 优先展示ai类平台 然后是影视流媒体
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<Long> userIds = userService.getRelationUserIdList(userId, null);
+        List<Long> filter_goods_id = relationMapper.getTicketGoodsId(userIds, List.of("validity", "overdue", "outside"));
+        //用户是否购买过奈飞产品
+        Boolean isPayNf = false;
+        if (filter_goods_id.contains(1l)) {
+            isPayNf = true;
+        } else {
+            int count = orderDonService.count(Wrappers.lambdaQuery(OrderDon.class)
+                    .eq(OrderDon::getGoodsId, 1)
+                    .notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
+            if (count > 0) {
+                //优先展示路由器、ai、流媒体
+                isPayNf = true;
+            }
+        }
+        Page<UserRecommendGoodsFrontView> page = groupRelationFrontService.getRecommendGoodsViews(isPayNf, filter_goods_id, start, limit);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(page);
+    }
 }

+ 0 - 1
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -457,7 +457,6 @@ public class CmsOrderController {
 	public Result<String> updateOrderSource(@RequestBody OrderDon orderDon) {
 		Long id = orderDon.getId();
 		String labelSource = orderDon.getLabelSource();
-		if (labelSource == null) labelSource = StrUtil.EMPTY;
 		cmsOrderDonService.update(null, Wrappers.lambdaUpdate(OrderDon.class)
 				.set(OrderDon::getLabelSource, labelSource)
 				.eq(OrderDon::getId, id));

+ 26 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -26,6 +26,7 @@ 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.excel.ExcelServiceMonthStatisticsData;
 import com.cyksj.model.excel.ExcelSheetAndData;
 import com.cyksj.model.request.BatchServiceReq;
 import com.cyksj.model.request.RedBookReq;
@@ -295,6 +296,31 @@ public class StatisticsDataController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(view);
 	}
 
+	/**
+	 * 导出客服每月订单数据统计
+	 */
+	@GetMapping("/export/service/orders")
+	public void exportServiceMonthStatisticsData(Integer type, String monthDate, String customerService, HttpServletRequest request, HttpServletResponse response) {
+		DateTime month = null;
+		if (StrUtil.isEmpty(monthDate)) {
+			month = DateTime.now();
+		} else {
+			month = DateUtil.parse(monthDate, "yyyy-MM-dd");
+		}
+		DateTime beginOfMonth = DateUtil.beginOfMonth(month);
+		DateTime endOfMonth = DateUtil.endOfMonth(month);
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap())
+				.field(ExcelServiceMonthStatisticsData::getRecordCreatedTime, beginOfMonth, endOfMonth).op(Operator.Between);
+		if (type == 1) {
+			builder.field(ExcelServiceMonthStatisticsData::getBeforeServiceName, customerService).op(Operator.Equal);
+		} else if (type == 2) {
+			builder.field(ExcelServiceMonthStatisticsData::getAfterServiceName, customerService).op(Operator.Equal);
+		}
+		builder.field(ExcelServiceMonthStatisticsData::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn);
+		List<ExcelServiceMonthStatisticsData> excelServiceMonthStatisticsData = beanSearcher.searchAll(ExcelServiceMonthStatisticsData.class, builder.build());
+		EasyExcelUtils.createExcelStreamMutilByEasyExcel(response, ExcelServiceMonthStatisticsData.class, excelServiceMonthStatisticsData, "客服每月订单数据统计", "客服每月订单数据统计", ExcelTypeEnum.XLSX, null);
+	}
+
 	@GetMapping("/get/stock")
 	public Result<List<StatisticsStockView>> getStock(HttpServletRequest request, @RequestParam(defaultValue = "0") Long startTime,@RequestParam(defaultValue = "0") Long endTime){
 		List<GoodsDonStock> goodsDonStocks = beanSearcher.searchAll(GoodsDonStock.class, MapUtils.flatBuilder(request.getParameterMap()).build());

+ 87 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/sys/TicketAdvertiseConfigController.java

@@ -0,0 +1,87 @@
+package com.cyksj.web.controller.manage.sys;
+
+import cn.hutool.core.lang.Assert;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.TicketAdvertiseConfig;
+import com.cyksj.service.mange.ticket.TicketAdvertiseConfigService;
+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
+ *文件名: TicketAdvertiseConfigController
+ *创建者: JavaZou
+ *创建时间:2023/7/12 12:24
+ */
+@RestController
+@RequestMapping("/manage/ticket/config")
+@RequiredArgsConstructor
+public class TicketAdvertiseConfigController {
+	private final TicketAdvertiseConfigService ticketAdvertiseConfigService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	/**
+	 * 新建车票 广告配置图
+	 */
+	@PostMapping("/advertise")
+	public Result<String> saveTicketAdvertiseConfig(@RequestBody @Validated TicketAdvertiseConfig config) {
+		ticketAdvertiseConfigService.saveOrUpdateAdvertiseConfig(config);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+
+	/**
+	 * 编辑广告配置
+	 */
+	@PutMapping("/advertise/update")
+	public Result<String> updateTicketAdvertiseConfig(@RequestBody @Validated TicketAdvertiseConfig config) {
+		ticketAdvertiseConfigService.saveOrUpdateAdvertiseConfig(config);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除
+	 */
+	@DeleteMapping("/advertise/delete/{id}")
+	public Result<String> saveTicketAdvertiseConfig(@PathVariable Long id) {
+		ticketAdvertiseConfigService.update(null, Wrappers.lambdaUpdate(TicketAdvertiseConfig.class)
+				.set(TicketAdvertiseConfig::getDeleted, false)
+				.eq(TicketAdvertiseConfig::getId, id));
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 广告配置列表
+	 */
+	@GetMapping("/advertise/get")
+	public Result<SearchResult<TicketAdvertiseConfig>> getAdvertiseConfig() {
+		SearchResult<TicketAdvertiseConfig> search = beanSearcher.search(TicketAdvertiseConfig.class, MapUtils.flatBuilder(request.getParameterMap())
+				.orderBy(TicketAdvertiseConfig::getSorted).desc()
+				.orderBy(TicketAdvertiseConfig::getId).desc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 上下架广告配置
+	 */
+	@PutMapping("/advertise/updateStatus/{id}")
+	public Result<String> updateStatusById(@PathVariable Long id) {
+		TicketAdvertiseConfig ticketAdvertiseConfig = ticketAdvertiseConfigService.getById(id);
+		Assert.notNull(ticketAdvertiseConfig, "该车票配置不存在");
+		ticketAdvertiseConfig.setStatus(!ticketAdvertiseConfig.getStatus());
+		ticketAdvertiseConfigService.updateById(ticketAdvertiseConfig);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+}

+ 1 - 100
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -1,16 +1,12 @@
 package com.cyksj.web.controller.user;
 
 import cn.hutool.core.codec.Base64;
-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 cn.hutool.json.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.EnvCommonService;
 import com.cyksj.common.annotation.NoSubmit;
-import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.snowflake.Sequence;
 import com.cyksj.common.util.*;
@@ -23,7 +19,6 @@ import com.cyksj.mapper.manage.cps.UserDistributePopularizeMapper;
 import com.cyksj.model.dto.*;
 import com.cyksj.model.entity.PhoneCode;
 import com.cyksj.model.entity.User;
-import com.cyksj.model.entity.UserDistributePopularize;
 import com.cyksj.model.request.LoginReq;
 import com.cyksj.model.response.LoginPhoneRep;
 import com.cyksj.model.response.WxGzhQrCodeTicketRep;
@@ -44,7 +39,6 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.Date;
 import java.util.Optional;
 
 /**
@@ -374,102 +368,9 @@ public class AuthorizationController {
     @PostMapping("/login/phone")
     @NoSubmit
     public Result<LoginPhoneRep> loginByPhone(@RequestBody LoginReq loginReq) throws Exception {
-        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class).last("limit 1");
-        if (loginReq.getType() == 1) {
-            if (StrUtil.hasEmpty(loginReq.getPhone(), loginReq.getCode())) {
-                throw BusinessRuntimeException.getInstance("请输入对应信息");
-            }
-            DateTime now = DateTime.now();
-            PhoneCode phoneCode = phoneCodeMapper.selectOne(Wrappers.lambdaQuery(PhoneCode.class).eq(PhoneCode::getPhone, loginReq.getPhone()).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(loginReq.getCode(), phoneCode.getCode())) {
-                throw BusinessRuntimeException.getInstance("手机验证码错误,请重新输入");
-            }
-            wrapper.eq(User::getLoginPhone, loginReq.getPhone());
-        } else if (loginReq.getType() == 2) {
-            if (StrUtil.isEmpty(loginReq.getEmail())) {
-                throw BusinessRuntimeException.getInstance("邮箱不能为空");
-            }
-            String code = redisService.getStr(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
-            if (StrUtil.isEmpty(code)) {
-                throw BusinessRuntimeException.getInstance("邮箱验证码已失效,请重新获取");
-            }
-            if (!StrUtil.equals(loginReq.getCode(), code)) {
-                throw BusinessRuntimeException.getInstance("邮箱验证码错误,请重新输入");
-            }
-            wrapper.eq(User::getEmail, loginReq.getEmail());
-            redisService.del(RedisService.key.EMAIL_CODE_KEY.getNameFormat(loginReq.getEmail()));
-        } else {
-            throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新操作");
-        }
-        //保存用户信息
-        User user = userService.getOne(wrapper);
-        String dsCode = loginReq.getDsCode();
-        Long sharedId = loginReq.getSharedId();
-        Long dsPopularizeId = null;
-        if (StrUtil.isNotBlank(dsCode)) {
-            dsCode = dsCode.trim();
-            User sharedUser = userService.getOne(Wrappers.lambdaQuery(User.class)
-                    .eq(User::getShowId, dsCode).last("limit 1"));
-            if (sharedUser != null) {
-                sharedId = sharedUser.getId();
-            } else {
-                UserDistributePopularize distributePopularize = distributePopularizeMapper.selectOne(Wrappers.lambdaQuery(UserDistributePopularize.class)
-                        .eq(UserDistributePopularize::getCode, dsCode)
-                        .select(UserDistributePopularize::getUserId, UserDistributePopularize::getId).last("limit 1"));
-                if (distributePopularize != null) {
-                    log.info("渠道sharedId:{}设置固定推广链接PC用户分销", distributePopularize.getUserId());
-                    sharedId = distributePopularize.getUserId();
-                    dsPopularizeId = distributePopularize.getId();
-                }
-            }
-        }
-        if (user == null) {
-            user = new User();
-            if (loginReq.getPopularizeId() != null) {
-                user.setPopularizeId(loginReq.getPopularizeId());
-            }
-            if (loginReq.getType() == 1) {
-                user.setLoginPhone(loginReq.getPhone());
-            } else if (loginReq.getType() == 2) {
-                user.setEmail(loginReq.getEmail());
-            }
-            String name = Constant.DEFAULT_NAME;
-            if (loginReq.getType() == 2) {
-                name += "@";
-            }
-            user.setNickname(String.format("%s%s", name, Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(String.format("%s%s", user.getId(), loginReq.getType() == 1 ? user.getLoginPhone() : user.getEmail())).toHexString().substring(0, 6)));
-            //默认头像
-            user.setHeadimgurl(Constant.DEFAULT_HEAD_IMG);
-            String registerEnv = loginReq.getRegisterEnv();
-            user.setRegisterEnv(StrUtil.isEmpty(registerEnv) ? User.RegisterEnv.pc.name() : registerEnv);
-            userService.save(user);
-            //新用户分销
-            if (sharedId != null) {
-                distributeService.saveDistributionInvitation(sharedId, user.getId(), dsPopularizeId);
-            }
-            //缓存用户注册 回传信息
-            if (StrUtil.isNotBlank(loginReq.getCallback())) {
-                OrderDonPostDataDto orderDonPostDataDto = new OrderDonPostDataDto()
-                        .setUserId(user.getId())
-                        .setCallback(loginReq.getCallback())
-                        .setCallbackType(loginReq.getCallbackType());
-                redisService.set(RedisService.key.ORDER_DON_POST_DATA_USER_KEY.getName() + user.getId(), Jsons.toJson(orderDonPostDataDto));
-            }
-        }
+        User user = userService.webLogin(loginReq);
         //写回登陆信息
         StpUserUtil.login(user.getId());
-        if (StrUtil.isEmpty(user.getShowId())) {
-            user.setShowId(userService.getUserShowId(user.getId()));
-        }
         LoginPhoneRep loginPhoneRep = new LoginPhoneRep(StpUserUtil.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());
         return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
     }

+ 31 - 6
netflix-web/src/main/java/com/cyksj/web/controller/user/DistributePopularizeController.java

@@ -243,13 +243,35 @@ public class DistributePopularizeController {
 		if (user == null) {
 			throw BusinessRuntimeException.getInstance("请先授权登录");
 		}
-		if (ObjectUtil.hasEmpty(applyMoneyReq.getAccount(), applyMoneyReq.getRealName())) {
-			throw BusinessRuntimeException.getInstance("必填项不能为空");
+		Boolean isTakeAll = applyMoneyReq.getIsTakeAll();
+		DistributeMoneyApply.Type type = applyMoneyReq.getType();
+		if (type == null) type = DistributeMoneyApply.Type.zfb;
+		if (type == DistributeMoneyApply.Type.zfb) {
+			if (ObjectUtil.hasEmpty(applyMoneyReq.getAccount(), applyMoneyReq.getRealName())) {
+				throw BusinessRuntimeException.getInstance("必填项不能为空");
+			}
+			if (applyMoneyReq.getAccount().length() > 255 || applyMoneyReq.getRealName().length() > 32) {
+				throw BusinessRuntimeException.getInstance("请输入正确的账户信息");
+			}
 		}
-		if (applyMoneyReq.getAccount().length() > 255 || applyMoneyReq.getRealName().length() > 32) {
-			throw BusinessRuntimeException.getInstance("请输入正确的账户信息");
+		if (type == DistributeMoneyApply.Type.usdt) {
+			if (StrUtil.isEmpty(applyMoneyReq.getWalletAddr())) {
+				throw BusinessRuntimeException.getInstance("USDT提现钱包地址不能为空");
+			}
+			if (applyMoneyReq.getWalletAddr().length() > 1000) {
+				throw BusinessRuntimeException.getInstance("请输入正确的钱包地址");
+			}
+			if (StrUtil.isNotBlank(applyMoneyReq.getRemark()) && applyMoneyReq.getRemark().length() > 512) {
+				throw BusinessRuntimeException.getInstance("备注过多");
+			}
+			isTakeAll = true;
+
+		}
+		DistributeMoneyApply distributeMoneyApply = null;
+		if (type == DistributeMoneyApply.Type.pwdRed) {
+			distributeMoneyApply = userDistributeMapper.selectRelationBusiness(userId);
+			isTakeAll = true;
 		}
-		Boolean isTakeAll = applyMoneyReq.getIsTakeAll();
 		BigDecimal userPoints = user.getPoints();
 		DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
 		BigDecimal minPoints = BigDecimal.valueOf(distributePointsExchangeMoney.getMinPoints());
@@ -275,12 +297,15 @@ public class DistributePopularizeController {
 		}
 		Integer update = userMapper.subPoints(user.getId(), needSubPoints);
 		if (update == 1) {
-			DistributeMoneyApply distributeMoneyApply = new DistributeMoneyApply();
+			distributeMoneyApply = Optional.ofNullable(distributeMoneyApply).orElse(new DistributeMoneyApply());
 			distributeMoneyApply.setUserId(userId);
 			distributeMoneyApply.setPoints(needSubPoints);
 			distributeMoneyApply.setMoney(needApplyMoney);
 			distributeMoneyApply.setAccount(applyMoneyReq.getAccount());
 			distributeMoneyApply.setRealName(applyMoneyReq.getRealName());
+			distributeMoneyApply.setWalletAddr(applyMoneyReq.getWalletAddr());
+			distributeMoneyApply.setRemark(applyMoneyReq.getRemark());
+			distributeMoneyApply.setType(applyMoneyReq.getType());
 			if (isTakeAll != null && isTakeAll) {
 				distributeMoneyApply.setVerifyStatus(DistributeMoneyApply.Status.verifying);
 			} else {

+ 7 - 5
netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

@@ -28,6 +28,7 @@ import com.cyksj.service.user.WorkOrderFrontService;
 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.util.Assert;
@@ -93,14 +94,15 @@ public class UserController {
     @GetMapping("/personal")
     public Result<UserPersonalView> getPersonalView() {
         long userId = StpUserUtil.getLoginIdAsLong();
-        List<RenewalView> ticket = groupRelationFrontService.getMyTicket(userId, false);
+        List<Long> userIds = userService.getRelationUserIdList(userId, null);
+        Number ticketNum = beanSearcher.searchCount(UserTicketView.class, MapUtils.builder()
+                .field(UserTicketView::getUserId, userIds).op(Operator.InList)
+                .field(RenewalView::getStatus, List.of("validity", "overdue", "outside")).op(Operator.InList)
+                .build());
         UserPersonalView personalView = new UserPersonalView();
         DateTime now = DateTime.now();
         //车票
-        Integer register_count = registerOrderDonMapper.selectCount(Wrappers.lambdaQuery(RegisterOrderDon.class)
-                .eq(RegisterOrderDon::getUserId, userId)
-                .eq(RegisterOrderDon::getStatus, RegisterOrderDon.Status.complete));
-        personalView.setNumOfTickets(ticket.size() + register_count);
+        personalView.setNumOfTickets(ticketNum.intValue());
         //优惠券
         Integer couponSize = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
                 .eq(CouponUser::getUserId, userId)