zoujiajian преди 2 години
родител
ревизия
62c30298e7
променени са 29 файла, в които са добавени 422 реда и са изтрити 1011 реда
  1. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java
  2. 3 1
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java
  3. 0 23
      netflix-dao/src/main/java/com/cyksj/model/dto/CorpMsgBulkTaskContent.java
  4. 0 153
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpMsgBulkTask.java
  5. 23 1
      netflix-dao/src/main/java/com/cyksj/model/entity/GroupsRelation.java
  6. 32 1
      netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java
  7. 67 1
      netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
  8. 0 161
      netflix-dao/src/main/java/com/cyksj/model/request/corp/Attachments.java
  9. 0 105
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpFollowContact.java
  10. 0 40
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpGroupConfig.java
  11. 0 45
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpMsgTemplate.java
  12. 0 258
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpXmlMessage.java
  13. 0 55
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpXmlOutMessage.java
  14. 0 15
      netflix-dao/src/main/java/com/cyksj/model/request/corp/Text.java
  15. 43 9
      netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml
  16. 20 0
      netflix-dao/src/main/resources/mapper/GroupsMapper.xml
  17. 37 73
      netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java
  18. 31 58
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  19. 7 1
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  20. 111 2
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  21. 1 1
      netflix-web/src/main/java/com/cyksj/web/aop/NoSubmitAop.java
  22. 31 5
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java
  23. 1 1
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java
  24. 6 0
      netflix-web/src/main/java/com/cyksj/web/util/StpUserUtil.java
  25. 1 0
      netflix-web/src/main/resources/i18n/yhlx_en_US.properties
  26. 1 0
      netflix-web/src/main/resources/i18n/yhlx_ja_JP.properties
  27. 1 0
      netflix-web/src/main/resources/i18n/yhlx_ko_KR.properties
  28. 2 1
      netflix-web/src/main/resources/i18n/yhlx_zh_CN.properties
  29. 2 1
      netflix-web/src/main/resources/i18n/yhlx_zh_HK.properties

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java

@@ -39,4 +39,6 @@ public interface GroupsMapper extends BaseMapper<GroupsTrips> {
 	Long selectMidJourneySameSpecItemGroups(@Param("groupsId") Long groupsId, @Param("skuId") Long skuId, @Param("expiryTime") Date expiryTime);
 
 	Integer countExpiredNum(Long accountId);
+
+	GroupsTrips selectTicketGroups(@Param("skuId") Long skuId, @Param("status") GroupsTrips.Status status, @Param("maxNum") Integer maxNum, @Param("ip") String ip);
 }

+ 3 - 1
netflix-dao/src/main/java/com/cyksj/mapper/GroupsRelationMapper.java

@@ -28,7 +28,7 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
 	@Update("update groups_relation set customer_service = null where id = #{id}")
 	void updateCustomerService(Long id);
 
-	Long selectSimilarExpiredRelation(@Param("skuId") Long skuId, @Param("minExpiryTime") DateTime minExpiryTime);
+	Long selectSimilarExpiredRelation(@Param("skuId") Long skuId, @Param("minExpiryTime") DateTime minExpiryTime, @Param("maxNum") Integer maxNum, @Param("ip") String ip);
 
 	List<GroupsRelationView> selectRelationByGoodsId(@Param("goodsId") Long goodsId, @Param("userId") Long userId);
 
@@ -51,4 +51,6 @@ public interface GroupsRelationMapper extends BaseMapper<GroupsRelation> {
 	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);
+
+	Long getOutSideGroupsTripsRelationByGoodsId(@Param("skuId") Long skuId, @Param("beginOfDay") DateTime beginOfDay, @Param("extraNum") Integer extraNum, @Param("userId") Long userId, @Param("skuNum") Integer skuNum, @Param("maxNum") Integer maxNum);
 }

+ 0 - 23
netflix-dao/src/main/java/com/cyksj/model/dto/CorpMsgBulkTaskContent.java

@@ -1,23 +0,0 @@
-package com.cyksj.model.dto;
-
-import com.cyksj.model.request.corp.Attachments;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.List;
-
-/*
- *项目名: netflix
- *文件名: CorpMsgBulkTaskContent
- *创建者: JavaZou
- *创建时间:2023/6/21 10:23
- */
-@Getter
-@Setter
-public class CorpMsgBulkTaskContent {
-	private String text;
-
-	@JsonProperty("attachments")
-	private List<Attachments> attachments;
-}

+ 0 - 153
netflix-dao/src/main/java/com/cyksj/model/entity/CorpMsgBulkTask.java

@@ -1,153 +0,0 @@
-package com.cyksj.model.entity;
-
-import com.baomidou.mybatisplus.annotation.*;
-import com.cyksj.model.dto.CornMetaDto;
-import com.cyksj.model.request.corp.Attachments;
-import com.ejlchina.searcher.bean.DbIgnore;
-import com.ejlchina.searcher.bean.SearchBean;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-/**
- * <p>
- * 企业微信群发消息任务
- * </p>
- *
- * @author zoujiajian
- * @since 2022-05-12
- */
-@Data
-@EqualsAndHashCode(callSuper = false)
-@SearchBean(tables = "corp_msg_bulk_task",
-		where = ":tag_id:")
-public class CorpMsgBulkTask implements Serializable {
-
-	@TableId(value = "id", type = IdType.AUTO)
-	private Long id;
-
-	/**
-	 * 企业微信id
-	 */
-	private Long wxCorpId;
-
-	/**
-	 * 群发任务选择标签
-	 */
-	@NotEmpty(message = "标签不能为空")
-	private String chooseTagStr;
-
-	/**
-	 * 标签数量
-	 */
-	@TableField(exist = false)
-	@DbIgnore
-	private Integer tagSize;
-
-	/**
-	 * 群发内容 文本、附件
-	 */
-	@TableField(updateStrategy = FieldStrategy.IGNORED)
-	private String text;
-
-	@TableField(exist = false)
-	@DbIgnore
-	private List<Attachments> attachments;
-
-	/**
-	 * 附件字符串
-	 */
-	@TableField(updateStrategy = FieldStrategy.IGNORED)
-	private String attachmentsStr;
-
-	/**
-	 * 1立即发送,2每日循环,3每周循环,4每月循环
-	 */
-	@NotNull(message = "定时发送或者立即发送不能为空")
-	private Integer sendTimeType;
-
-	private String corn;
-
-	/**
-	 * 优惠券id
-	 */
-	@TableField(updateStrategy = FieldStrategy.IGNORED)
-	private Long couponId;
-
-	@DbIgnore
-	@TableField(exist = false)
-	private String couponName;
-
-	/**
-	 * xxljobId
-	 */
-	private String jobId;
-
-	/**
-	 * 定时发送的发送时间
-	 */
-	@TableField(updateStrategy = FieldStrategy.IGNORED)
-	private String sendTime;
-	/**
-	 * 群发消息任务名称
-	 */
-	private String name;
-
-	@TableField(exist = false)
-	@DbIgnore
-	private CornMetaDto cornDto;
-
-	/**
-	 * 选择时间
-	 */
-	private String chooseTime;
-
-	/**
-	 * 是否启动(true:启用,false:停用)
-	 */
-	private Boolean status;
-
-	private Boolean deleted;
-
-	/**
-	 * 创建时间
-	 */
-	@TableField(fill = FieldFill.INSERT)
-	private Date createdTime;
-
-	/**
-	 * 更新时间
-	 */
-	@TableField(fill = FieldFill.INSERT_UPDATE)
-	private Date updateTime;
-
-	@Getter
-	public enum Week {
-		MON("1"),
-		TUE("2"),
-		WED("3"),
-		THU("4"),
-		FRI("5"),
-		SAT("6"),
-		SUN("7");
-
-		 Week(String week) {
-			this.week = week;
-		}
-
-		public static String getWeek(String week) {
-
-		 return Arrays.stream(values()).filter(week1 -> week1.getWeek().equals(week)).findFirst().get().name();
-		}
-		private String week;
-	}
-
-
-}

+ 23 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/GroupsRelation.java

@@ -72,6 +72,8 @@ public class GroupsRelation extends BaseEntity {
      */
     private String verifyCode;
 
+    private Long yhsId;
+
     /**
      * 获取权益时的订单id
      */
@@ -87,6 +89,26 @@ public class GroupsRelation extends BaseEntity {
     private Long newRelationId;
 
 
+    /**
+     * 车队目前可用停车数
+     */
+    @TableField(exist = false)
+    @DbIgnore
+    private Integer groupsAvailParkingNum;
+
+    /**
+     * 车队最多可用车位数
+     */
+    @TableField(exist = false)
+    @DbIgnore
+    private Integer maxNum;
+
+    /**
+     * 车票获取类型 默认1购买,2.体验
+     */
+    private Integer aqType;
+
+
     @AllArgsConstructor
     @Getter
     public enum Status{
@@ -112,4 +134,4 @@ public class GroupsRelation extends BaseEntity {
         private String desc;
 
     }
-}
+}

+ 32 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/GroupsTrips.java

@@ -79,6 +79,14 @@ public class GroupsTrips {
     @DbField("sku.spec_val")
     @TableField(exist = false)
     private String specVal;
+
+    /**
+     * 商品规格
+     */
+    @DbField("sku.is_mirror")
+    @TableField(exist = false)
+    private Boolean isMirror;
+
     /**
      * 录入人
      */
@@ -126,6 +134,29 @@ public class GroupsTrips {
     @TableField(exist = false)
     private Date expiryTime;
 
+    @DbField("a.is_disable")
+    @TableField(exist = false)
+    private Boolean isDisable;
+
+    /**
+     * 车队上是否有人
+     */
+    @DbIgnore
+    @TableField(exist = false)
+    private Boolean isExists;
+
+    /**
+     * 可上车队时间
+     */
+    @DbField("gt.parking_time")
+    private Date parkingTime;
+
+    /**
+     * 目前可停车数目
+     */
+    @DbField("gt.available_parking_num")
+    private Integer availableParkingNum;
+
     /**
      * 创建时间
      */
@@ -153,4 +184,4 @@ public class GroupsTrips {
         private String desc;
 
     }
-}
+}

+ 67 - 1
netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java

@@ -114,4 +114,70 @@ public class OrderPayRequest {
     private String callback;
 
     private String callbackType;
-}
+
+    /**
+     * 是否是特定价格
+     */
+    private Boolean isSpecificPrice;
+
+    private Long goodsId;
+
+    /**
+     * 礼品卡现金支付
+     */
+    private BigDecimal gcCash;
+
+    /**
+     * 礼品卡现金支付所拥有id
+     */
+    private List<Long> gcpIds;
+
+    /**
+     * 店铺id
+     */
+    private String customId;
+
+    /**
+     * 购买实物
+     */
+    private Boolean isPayReal;
+
+    /**
+     * 雷达链接id
+     */
+    private Long radarId;
+
+    /**
+     * 下单手机号
+     */
+    private String phone;
+
+    private String ip;
+
+    private String location;
+
+    /**
+     * 是否设备满减活动优惠
+     */
+    private Boolean isAcReduce;
+
+    /**
+     * 百亿补贴规格id
+     */
+    private Long subsidyId;
+
+    /**
+     * 套餐id
+     */
+    private Long packageId;
+
+    /**
+     * 源订单id
+     */
+    private Long originalOrderId;
+
+    /**
+     * 是否是试用车票跳转
+     */
+    private Boolean isTrial;
+}

+ 0 - 161
netflix-dao/src/main/java/com/cyksj/model/request/corp/Attachments.java

@@ -1,161 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-/*
- *项目名: shanxing-admin
- *文件名: LinkTitle
- *创建者: JavaZou
- *创建时间:2022/6/20 16:01
- */
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Attachments implements Serializable {
-
-	private static final long serialVersionUID = 3529000560142115378L;
-
-	/**
-	 * 图片消息.
-	 */
-	public static final String IMAGE = "image";
-	/**
-	 * 图文消息.
-	 */
-	public static final String LINK = "link";
-	/**
-	 * 视频消息.
-	 */
-	public static final String VIDEO = "video";
-	/**
-	 * 小程序消息.
-	 */
-	public static final String MINIPROGRAM = "miniprogram";
-
-
-	private String msgtype;
-
-	private Image image;
-
-	private Link link;
-
-	@JsonProperty("miniprogram")
-	private MiniProgram miniProgram;
-
-	private Video video;
-
-	public Attachments(String msgtype, Link link) {
-		this.msgtype = msgtype;
-		this.link = link;
-	}
-
-	public void setImage(Image image) {
-		this.image = image;
-		this.msgtype = IMAGE;
-	}
-
-	public void setLink(Link link) {
-		this.link = link;
-		this.msgtype = LINK;
-	}
-
-	public void setMiniProgram(MiniProgram miniProgram) {
-		this.miniProgram = miniProgram;
-		this.msgtype = MINIPROGRAM;
-	}
-
-
-	public void setVideo(Video video) {
-		this.video = video;
-		this.msgtype = VIDEO;
-	}
-
-
-	@Data
-	@AllArgsConstructor
-	@NoArgsConstructor
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	public static class Link implements Serializable{
-		private static final long serialVersionUID = -1036758941402144780L;
-
-		/**
-		 * 标题
-		 */
-		private String title;
-		/**
-		 * 封面
-		 */
-		private String picurl;
-
-		/**
-		 * 描述
-		 */
-		private String desc;
-
-		/**
-		 * 项目地址
-		 */
-		private String url;
-
-		@JsonProperty("media_id")
-		private String mediaId;
-
-		public Link(String title, String picurl, String desc, String url) {
-			this.title = title;
-			this.picurl = picurl;
-			this.desc = desc;
-			this.url = url;
-		}
-	}
-
-	@Data
-	@AllArgsConstructor
-	@NoArgsConstructor
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	public static class Image implements Serializable {
-		private static final long serialVersionUID = -606286372867787121L;
-
-		@JsonProperty("media_id")
-		private String mediaId;
-
-		@JsonProperty("pic_url")
-		private String picUrl;
-	}
-
-
-	@Data
-	@AllArgsConstructor
-	@NoArgsConstructor
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	public static class MiniProgram implements Serializable {
-		private static final long serialVersionUID = 4242074162638170679L;
-
-		private String title;
-		@JsonProperty("pic_media_id")
-		private String picMediaId;
-		private String appid;
-		private String page;
-		private String url;
-	}
-
-	@Data
-	@AllArgsConstructor
-	@NoArgsConstructor
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	public static class Video implements Serializable {
-		private static final long serialVersionUID = -6048642921382867138L;
-		@JsonProperty("media_id")
-		private String mediaId;
-		@JsonProperty("thumb_media_id")
-		private String thumbMediaId;
-		private String url;
-	}
-
-}

+ 0 - 105
netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpFollowContact.java

@@ -1,105 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.List;
-
-
-@Getter
-@Setter
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class CorpFollowContact {
-	/**
-	 * 联系方式类型,1-单人, 2-多人
-	 */
-	private Integer type;
-
-	/**
-	 * 场景,1-在小程序中联系,2-通过二维码联系
-	 */
-	private Integer scene;
-
-	private Integer style;
-
-	private String remark;
-
-	private boolean skip_verify;
-
-	private String state;
-
-	private List<String> user;
-
-	private List<Integer> party;
-
-	private boolean is_temp;
-
-	private Integer expires_in;
-
-	private Integer chat_expires_in;
-
-	private String unionid;
-
-	private boolean is_exclusive;
-
-	private Conclusions conclusions;
-
-	@Getter
-	@Setter
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	class Conclusions {
-		private Text text;
-
-		private Image image;
-
-		private Link link;
-
-		@JsonProperty("miniprogram")
-		private MiniProgram miniprogram;
-	}
-
-	@Getter
-	@Setter
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	class Text {
-		private String content;
-	}
-
-
-	@Getter
-	@Setter
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	class MiniProgram {
-		private String title;
-
-		private String pic_media_id;
-
-		private String appid;
-
-		private String page;
-	}
-
-	@Getter
-	@Setter
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	class Image {
-		private String media_id;
-	}
-
-	@Getter
-	@Setter
-	@JsonInclude(JsonInclude.Include.NON_NULL)
-	class Link {
-		private String title;
-
-		private String picurl;
-
-		private String desc;
-
-		private String url;
-	}
-
-
-}

+ 0 - 40
netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpGroupConfig.java

@@ -1,40 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.Getter;
-import lombok.Setter;
-
-import javax.validation.constraints.NotEmpty;
-import java.util.List;
-
-/*
- *项目名: netflix
- *文件名: A
- *创建者: JavaZou
- *创建时间:2023/7/7 12:28
- */
-@Getter
-@Setter
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class CorpGroupConfig {
-	@NotEmpty
-	private String config_id;
-
-	@NotEmpty
-	private int scene;
-
-	private String remark;
-
-	@NotEmpty
-	private int auto_create_room;
-
-	private String room_base_name;
-
-	private int room_base_id;
-
-	@NotEmpty
-	private List<String> chat_id_list;
-
-	private String state;
-}
-

+ 0 - 45
netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpMsgTemplate.java

@@ -1,45 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author chan
- * @date 2022/3/16 下午2:33
- */
-@Data
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class CorpMsgTemplate implements Serializable {
-
-    /**
-     * 群发任务的类型,默认为single,表示发送给客户,group表示发送给客户群
-     */
-    @JsonProperty("chat_type")
-    private String chatType;
-
-    /**
-     * 客户的外部联系人id列表,仅在chat_type为single时有效,不可与sender同时为空,最多可传入1万个客户
-     */
-    @JsonProperty("external_userid")
-    private List<String> externalUserid;
-
-    /**
-     * 发送企业群发消息的成员userid,当类型为发送给客户群时必填
-     */
-    private String sender;
-
-    /**
-     * 消息文本内容,最多4000个字节
-     */
-    private Text text;
-
-
-
-    List<Attachments> attachments;
-
-
-}

+ 0 - 258
netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpXmlMessage.java

@@ -1,258 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.cyksj.common.util.Xmls;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-
-/**
- * @author chan
- * @date 2022/3/14 上午10:57
- */
-@Slf4j
-@Getter
-@Setter
-@ToString
-public class CorpXmlMessage implements Serializable {
-
-	///////////////////////
-	// 以下都是微信推送过来的消息的xml的element所对应的属性
-	///////////////////////
-
-	@JacksonXmlProperty(localName = "AgentID")
-	private String agentId;
-
-	@JacksonXmlProperty(localName = "ToUserName")
-	private String toUserName;
-
-	@JacksonXmlProperty(localName = "FromUserName")
-	private String fromUserName;
-
-	@JacksonXmlProperty(localName = "CreateTime")
-	private Long createTime;
-
-	/**
-	 * <pre>
-	 * 当接受用户消息时,可能会获得以下值:
-	 * {@link WxConsts.XmlMsgType#TEXT}
-	 * {@link WxConsts.XmlMsgType#IMAGE}
-	 * {@link WxConsts.XmlMsgType#VOICE}
-	 * {@link WxConsts.XmlMsgType#VIDEO}
-	 * {@link WxConsts.XmlMsgType#LOCATION}
-	 * {@link WxConsts.XmlMsgType#LINK}
-	 * {@link WxConsts.XmlMsgType#EVENT}
-	 * 当发送消息的时候使用:
-	 * {@link WxConsts.XmlMsgType#TEXT}
-	 * {@link WxConsts.XmlMsgType#IMAGE}
-	 * {@link WxConsts.XmlMsgType#VOICE}
-	 * {@link WxConsts.XmlMsgType#VIDEO}
-	 * {@link WxConsts.XmlMsgType#NEWS}
-	 * </pre>
-	 */
-	@JacksonXmlProperty(localName = "MsgType")
-	private String msgType;
-
-	@JacksonXmlProperty(localName = "Content")
-	private String content;
-
-	@JacksonXmlProperty(localName = "MsgId")
-	private Long msgId;
-
-	@JacksonXmlProperty(localName = "PicUrl")
-	private String picUrl;
-
-	@JacksonXmlProperty(localName = "MediaId")
-	private String mediaId;
-
-	@JacksonXmlProperty(localName = "Format")
-	private String format;
-
-	@JacksonXmlProperty(localName = "ThumbMediaId")
-	private String thumbMediaId;
-
-	@JacksonXmlProperty(localName = "Location_X")
-	private Double locationX;
-
-	@JacksonXmlProperty(localName = "Location_Y")
-	private Double locationY;
-
-	@JacksonXmlProperty(localName = "Scale")
-	private Double scale;
-
-	@JacksonXmlProperty(localName = "Label")
-	private String label;
-
-	@JacksonXmlProperty(localName = "Title")
-	private String title;
-
-	@JacksonXmlProperty(localName = "Description")
-	private String description;
-
-	@JacksonXmlProperty(localName = "Url")
-	private String url;
-
-	@JacksonXmlProperty(localName = "Event")
-	private String event;
-
-	@JacksonXmlProperty(localName = "UpdateDetail")
-	private String updateDetail;
-
-	@JacksonXmlProperty(localName = "JoinScene")
-	private String joinScene;
-
-	@JacksonXmlProperty(localName = "QuitScene")
-	private String quitScene;
-
-	@JacksonXmlProperty(localName = "MemChangeCnt")
-	private String memChangeCnt;
-
-	@JacksonXmlProperty(localName = "Source")
-	private String source;
-
-	@JacksonXmlProperty(localName = "StrategyId")
-	private String strategyId;
-
-	@JacksonXmlProperty(localName = "EventKey")
-	private String eventKey;
-
-	@JacksonXmlProperty(localName = "Ticket")
-	private String ticket;
-
-	@JacksonXmlProperty(localName = "Latitude")
-	private Double latitude;
-
-	@JacksonXmlProperty(localName = "Longitude")
-	private Double longitude;
-
-	@JacksonXmlProperty(localName = "Precision")
-	private Double precision;
-
-	@JacksonXmlProperty(localName = "Recognition")
-	private String recognition;
-
-	@JacksonXmlProperty(localName = "TaskId")
-	private String taskId;
-
-	/**
-	 * 通讯录变更事件.
-	 * 请参考常量 me.chanjar.weixin.cp.constant.WxCpConsts.ContactChangeType
-	 */
-	@JacksonXmlProperty(localName = "ChangeType")
-	private String changeType;
-
-	/**
-	 * 变更信息的成员UserID.
-	 */
-	@JacksonXmlProperty(localName = "UserID")
-	private String userId;
-
-	/**
-	 * 变更信息的外部联系人的userid,注意不是企业成员的帐号.
-	 */
-	@JacksonXmlProperty(localName = "ExternalUserID")
-	private String externalUserId;
-
-	/**
-	 * 添加此用户的「联系我」方式配置的state参数,可用于识别添加此用户的渠道.
-	 */
-	@JacksonXmlProperty(localName = "State")
-	private String state;
-
-	/**
-	 * 欢迎语code,可用于发送欢迎语.
-	 */
-	@JacksonXmlProperty(localName = "WelcomeCode")
-	private String welcomeCode;
-
-	/**
-	 * 新的UserID,变更时推送(userid由系统生成时可更改一次).
-	 */
-	@JacksonXmlProperty(localName = "NewUserID")
-	private String newUserId;
-
-	/**
-	 * 客户联系回调: 客户接替失败的原因
-	 */
-	@JacksonXmlProperty(localName = "FailReason")
-	private String failReason;
-
-	/**
-	 * 客户联系回调: 标签类型
-	 */
-	@JacksonXmlProperty(localName = "TagType")
-	private String tagType;
-
-	/**
-	 * 客户联系回调 标签id
-	 */
-	@JacksonXmlProperty(localName = "Id")
-	private String id;
-
-
-	///////////////////////////////////////
-	// 群发消息返回的结果
-	///////////////////////////////////////
-	/**
-	 * 多个时间共用字段.
-	 * 1. 群发的结果.
-	 * 2. 通讯录变更事件
-	 * 激活状态:1=已激活 2=已禁用 4=未激活 已激活代表已激活企业微信或已关注微工作台(原企业号).
-	 */
-	@JacksonXmlProperty(localName = "Status")
-	private String status;
-
-	/**
-	 * group_id下粉丝数;或者openid_list中的粉丝数.
-	 */
-	@JacksonXmlProperty(localName = "TotalCount")
-	private Integer totalCount;
-
-	/**
-	 * 过滤.
-	 * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
-	 */
-	@JacksonXmlProperty(localName = "FilterCount")
-	private Integer filterCount;
-
-	/**
-	 * 发送成功的粉丝数.
-	 */
-	@JacksonXmlProperty(localName = "SentCount")
-	private Integer sentCount;
-
-	/**
-	 * 发送失败的粉丝数.
-	 */
-	@JacksonXmlProperty(localName = "ErrorCount")
-	private Integer errorCount;
-
-
-	public static CorpXmlMessage fromXml(String xml) {
-		//修改微信变态的消息内容格式,方便解析
-		xml = xml.replace("</PicList><PicList>", "");
-		final CorpXmlMessage xmlMessage;
-		try {
-			xmlMessage = Xmls.parseObject(xml, CorpXmlMessage.class);
-			return xmlMessage;
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	public static CorpXmlMessage fromXml(String xml, String agentId) {
-		//修改微信变态的消息内容格式,方便解析
-		xml = xml.replace("</PicList><PicList>", "");
-		final CorpXmlMessage xmlMessage;
-		try {
-			xmlMessage = Xmls.parseObject(xml, CorpXmlMessage.class);
-			xmlMessage.setAgentId(agentId);
-			return xmlMessage;
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-}

+ 0 - 55
netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpXmlOutMessage.java

@@ -1,55 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import com.cyksj.common.exception.AesException;
-import com.cyksj.common.exception.BusinessRuntimeException;
-import com.cyksj.common.util.StringUtil;
-import com.cyksj.common.util.Xmls;
-import com.cyksj.common.util.corp.WxCryptUtil;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.io.Serializable;
-
-/**
- * @author chan
- * @date 2022/3/14 上午10:38
- */
-@Getter
-@Setter
-public class CorpXmlOutMessage implements Serializable {
-
-	@JacksonXmlCData
-	@JacksonXmlProperty(localName = "ToUserName")
-	protected String toUserName;
-
-	@JacksonXmlCData
-	@JacksonXmlProperty(localName = "FromUserName")
-	protected String fromUserName;
-
-	@JacksonXmlCData
-	@JacksonXmlProperty(localName = "CreateTime")
-	protected Long createTime;
-
-	@JacksonXmlCData
-	@JacksonXmlProperty(localName = "MsgType")
-	protected String msgType;
-
-	protected String toXml() {
-		try {
-			return Xmls.toXml(this);
-		} catch (JsonProcessingException e) {
-			throw BusinessRuntimeException.getInstance("企业微信 xml转换error:" + StringUtil.getErrorText(e));
-		}
-	}
-
-	/**
-	 * 转换成加密的xml格式.
-	 */
-	public String toEncryptedXml(WxCryptUtil wxCryptUtil) throws AesException {
-		String plainXml = toXml();
-		return wxCryptUtil.encrypt(plainXml);
-	}
-}

+ 0 - 15
netflix-dao/src/main/java/com/cyksj/model/request/corp/Text.java

@@ -1,15 +0,0 @@
-package com.cyksj.model.request.corp;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author chan
- * @date 2022-03-16 下午2:37
- */
-@Data
-public class Text implements Serializable {
-  private static final long serialVersionUID = 6608288753719551600L;
-  private String content;
-}

+ 43 - 9
netflix-dao/src/main/resources/mapper/GroupRelationMapper.xml

@@ -48,16 +48,24 @@
     <select id="selectSimilarExpiredRelation" resultType="java.lang.Long">
         select s.id
         from (select gt.id, min(gr.expiry_time) minExpiryTime
-              from `groups_trips` gt
-                       left join `groups_relation` gr on gr.groups_id = gt.id
-              where gt.sku_id = #{skuId}
-                and gt.available_num > 0
-                and gt.status = 'validity'
-                and gr.status = 'validity'
-                and gr.user_id != 0
-              and gr.expiry_time is not null
-              group by gr.groups_id) s
+        from `groups_trips` gt
+        left join `groups_relation` gr on gr.groups_id = gt.id
+        where gt.sku_id = #{skuId}
+        and (gt.available_parking_num = 0 or (select count(*)
+        from groups_relation gr
+        where gr.groups_id = gt.id and gr.user_id != 0 and gr.num &lt;=
+        #{maxNum}) &lt; gt.available_parking_num) and gt.available_num > 0
+        and gt.status = 'validity'
+        and gr.status = 'validity'
+        and gr.user_id != 0
+        and gr.expiry_time is not null
+        group by gr.groups_id) s
         where s.minExpiryTime >= #{minExpiryTime}
+        <if test="ip != null">
+            and not exists (select 1 from (select id, user_id from groups_relation gnr where gnr.groups_id = s.id and gnr.user_id != 0) gr inner join
+            order_don o on o.user_id = gr.user_id and o.relation_id = gr.id
+            inner join order_don_location_relate ocr on ocr.order_id = o.id where ocr.ip = #{ip} limit 1)
+        </if>
         order by minExpiryTime desc limit 1
     </select>
 
@@ -211,4 +219,30 @@
         </if>
         and deleted is true and status is true) s order by s.sorted desc,sort_by desc
     </select>
+
+    <select id="getOutSideGroupsTripsRelationByGoodsId" resultType="java.lang.Long">
+        select gt.id
+        from `groups_trips` gt
+                 inner join account a on a.id = gt.account_id
+        where gt.sku_id = #{skuId}
+          and gt.status = 'validity'
+          and a.expiry_time >= #{beginOfDay}
+          and (select count(*)
+               from groups_relation gr
+               where gr.num > #{skuNum}
+                 and gr.num &lt;= #{maxNum}
+                 and gr.groups_id = gt.id
+                 and gr.user_id
+            != 0)
+         &lt; #{extraNum}
+          and
+            (
+        select count(*)
+        from groups_relation gr
+        where gr.groups_id = gt.id
+          and gr.user_id
+            = #{userId}) = 0
+          and (gt.available_parking_num = 0 or (select count(*) from groups_relation gr where gr.groups_id = gt.id and gr.user_id != 0 and gr.num &lt;= #{maxNum}) &lt; gt.available_parking_num)
+        order by RAND() limit 1
+    </select>
 </mapper>

+ 20 - 0
netflix-dao/src/main/resources/mapper/GroupsMapper.xml

@@ -78,4 +78,24 @@
           and deleted is true
           and source = 'self'
     </select>
+
+    <select id="selectTicketGroups" resultType="com.cyksj.model.entity.GroupsTrips">
+        select *
+        from groups_trips gt
+        where gt.sku_id = #{skuId}
+        and gt.status = #{status}
+        and gt.available_num > 0
+        <if test="ip != null">
+            and not exists (select 1 from (select id, user_id from groups_relation gnr where gnr.groups_id = gt.id
+            and gnr.user_id != 0) gr inner join
+            order_don o on o.user_id = gr.user_id and o.relation_id = gr.id
+            inner join order_don_location_relate ocr on ocr.order_id = o.id where ocr.ip = #{ip} limit 1)
+        </if>
+        and (available_parking_num = 0 or available_parking_num > (select count(*)
+        from groups_relation gr
+        where gr.groups_id = gt.id
+        and gr.user_id != 0 and gr.num &lt;= #{maxNum}))
+        order by available_num asc
+        limit 1
+    </select>
 </mapper>

+ 37 - 73
netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java

@@ -251,56 +251,19 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 
 	@Override
 	public GroupsRelation getRelationNoOrder(GoodsDonSku sku, Long userId) {
-		GroupsRelation relation = null;
 		Integer retryNum = 1;
 		List<Long> errorsRelationIds = new ArrayList<>();
-		relation = getFinalRelation(sku, userId, relation, retryNum, errorsRelationIds);
+		GroupsRelation relation = getFinalRelation(sku, userId, retryNum, errorsRelationIds);
 		return relation;
 	}
 
-	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, GroupsRelation relation, Integer retryNum, List<Long> errorsRelationIds) {
-		//寻找差不多过期时间规格的车位
-		relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getDays(), sku.getMonths(), errorsRelationIds);
-		if (relation == null) {
-			GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-					.eq(GroupsTrips::getSkuId, sku.getId())
-					.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-					.eq(GroupsTrips::getStatus, GroupsTrips.Status.validity)
-					.orderByAsc(GroupsTrips::getAvailableNum));
-			//待发车
-			if (groups == null) {
-				groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
-						.eq(GroupsTrips::getSkuId, sku.getId())
-						.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-						.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
-						.orderByAsc(GroupsTrips::getAvailableNum));
-			}
-			if (groups == null) {
-				//新增车位 并关联
-				relation = createNewGroupTripsAndRelation(sku, groups, relation);
-				log.info("无合适规格车队,新增新车队,获取车位relationId:{}", relation.getId());
-			} else {
-				//寻找快满编车队进行占座
-				relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-						.eq(GroupsRelation::getGroupsId, groups.getId())
-						.notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds)
-						.eq(GroupsRelation::getStatus, "none")
-						.eq(GroupsRelation::getUserId, 0)
-						.orderByAsc(GroupsRelation::getNum)
-						.last("limit 1")
-				);
-				log.info("寻找快满编车队的车位relationId:{}", relation.getId());
-				//如果占位失败 新增车位并关联
-				if (relation == null) {
-					relation = createNewGroupTripsAndRelation(sku, groups, relation);
-					log.info("占位新车队车位失败,再次新增新车队,获取车位relationId:{}", relation.getId());
-				}
-			}
-		}
+	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, Integer retryNum, List<Long> errorsRelationIds) {
+		//获取车票车位
+		GroupsRelation relation = groupRelationFrontService.getRelation(null, userId, sku, null);
 
 		try {
 			//锁定座位
-			setRelation(relation.getId(), userId);
+			setRelation(relation);
 			relation.setUserId(userId);
 			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
 			if (GroupsTrips.Status.validity.equals(groupsTrips.getStatus())) {
@@ -310,26 +273,21 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 				if (sku.getDays() != null && sku.getDays() > 0) {
 					newDate = DateUtil.offsetDay(expiryTime, sku.getDays() * 1);
 				} else {
-					newDate = DateUtil.offset(expiryTime, DateField.MONTH, sku.getMonths() * 1);
+					//奈飞月付 按30天计算
+					if (sku.getId() == 4) {
+						newDate = DateUtil.offsetDay(expiryTime, 30);
+					} else {
+						newDate = DateUtil.offset(expiryTime, DateField.MONTH, sku.getMonths() * 1);
+					}
 				}
 				relation.setExpiryTime(newDate);
 				relation.setStartTime(relation.getStartTime() == null ? new Date() : null);
 			}
-			relation.setStatus(GroupsRelation.Status.validity);
-
-			int isSuccess = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-					.set(GroupsRelation::getUserId, userId)
-					.set(GroupsRelation::getStatus, GroupsRelation.Status.validity)
-					.set(GroupsRelation::getStartTime, relation.getStartTime())
-					.set(GroupsRelation::getExpiryTime, relation.getExpiryTime())
-					.eq(GroupsRelation::getId, relation.getId())
-					.eq(GroupsRelation::getUserId, 0)
-					.eq(GroupsRelation::getStatus, GroupsRelation.Status.none));
-			if (isSuccess != 1) {
-				log.error("该车位已被占,用户userId:{}更新上车relationId:{}状态失败", userId, relation.getId());
-				throw BusinessRuntimeException.getInstance("该车位已被占");
+			if (relation.getStatus() != GroupsRelation.Status.outside) {
+				relation.setStatus(GroupsRelation.Status.validity);
 			}
-			redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
+			groupsRelationMapper.updateById(relation);
+
 		} catch (Exception e) {
 			Object value = redisService.get(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
 			if (value != null && userId.equals(Long.parseLong(value.toString()))) {
@@ -338,31 +296,37 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 			errorsRelationIds.add(relation.getId());
 			if (retryNum == 15) {
 				log.error("用户:{}获取车票:{}异常", userId, relation.getId());
-				throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("get_ticket_error"));
+				throw BusinessRuntimeException.getInstance("获取车票异常,请联系客服");
 			}
 			//失败重新给他分配车位
-			getFinalRelation(sku, userId, relation, ++retryNum, errorsRelationIds);
+			return getFinalRelation(sku, userId, ++retryNum, errorsRelationIds);
 		}
 		return relation;
 	}
 
-	private void setRelation(Long relationId, Long userId) {
-		if (redisService.get(RedisKey.GROUPS_RELATION_NUM_KEY + relationId) != null) {
-			log.info("=====>用户:{}获取了已有人座位:{}", userId, relationId);
-			throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
-		} else {
-			if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) {
+	public void setRelation(GroupsRelation relation) {
+		Long relationId = relation.getId();
+		Long userId = relation.getUserId();
+		Long groupsId = relation.getGroupsId();
+		GroupsRelation.Status status = relation.getStatus();
+		String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId;
+		if (!redisService.setNx(relation_num_key, userId, 60 * 5L)) {
+			GroupsRelation dbRelation = groupsRelationMapper.selectById(relationId);
+			if (dbRelation.getUserId() != 0) {
 				log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
-				throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
-			}
-			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
-			int count = groupsMapper.decrAvailableNum(relation.getGroupsId());
-			if (count == 0) {
-				log.error("车位异常 groupId:{}", relation.getGroupsId());
-				groupsMapper.updateAvailableNum(relation.getGroupsId());
-				throw new BusinessRuntimeException("车位异常");
+				throw new BusinessRuntimeException("系统繁忙,请重试...");
 			}
 		}
+		if (status == GroupsRelation.Status.outside) {
+			return;
+		}
+		int count = groupsMapper.decrAvailableNum(groupsId);
+		if (count == 0) {
+			log.error("车位异常 groupId:{}", groupsId);
+			groupsMapper.updateAvailableNum(groupsId);
+			redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relationId);
+			throw new BusinessRuntimeException("车位异常");
+		}
 	}
 
 	/**

+ 31 - 58
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -67,9 +67,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 
-import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER;
-import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND;
-
 /**
  * @author chan
  * @date 2021/10/11 下午4:08
@@ -165,6 +162,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		User user;
 		String payOpenId = null;
 		Long relationId = 0L;
+		GroupsRelation relation = null;
 
 		if (isNoLogin != null && isNoLogin) {
 			user = new User();
@@ -178,7 +176,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			payOpenId = user.getOpenId();
 			if (goodsDon.getType() == 1) {
 				//获取座位
-				relationId = getRelation(payRequest, sku);
+				relation = getRelation(payRequest, sku);
+				relationId = relation.getId();
 			} else {
 
 			}
@@ -321,7 +320,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	public void closeOrder(Long orderId, Long userId) {
 		String orderCloseKey = RedisService.key.CLOSE_ORDER_TIME_KEY.getName() + orderId;
 		if (!redisService.setNx(orderCloseKey, orderId, RedisService.key.CLOSE_ORDER_TIME_KEY.getTimeout())) {
-			throw BusinessRuntimeException.getInstance("订单正在关闭中..");
+			return;
 		}
 		//关闭订单逻辑
 		OrderDon orderDon = getById(orderId);
@@ -560,23 +559,28 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	public List<OrderDon> getAppleOneOrderDons(List<Long> skuIds, List<String> noOrderStatus, Date yesZeroDate, Date thisZeroDate) {
 		return orderDonMapper.getAppleOneOrderDons(skuIds, noOrderStatus, yesZeroDate, thisZeroDate);
 	}
-	public void setRelation(Long relationId, Long groupsId, Long userId, Long goodsId, Boolean isLoginPopularize) {
-		if (isLoginPopularize == null || !isLoginPopularize) {
-			int noPayCount = count(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, userId).eq(OrderDon::getGoodsId, goodsId).eq(OrderDon::getStatus, OrderDon.Status.noPayment.toString()));
-			if (noPayCount > 0) {
-				throw new BusinessRuntimeException(I18nMessageUtil.getI18nMsg("order_noPayment_error"));
+	public void setRelation(GroupsRelation relation) {
+		Long relationId = relation.getId();
+		Long userId = relation.getUserId();
+		Long groupsId = relation.getGroupsId();
+		GroupsRelation.Status status = relation.getStatus();
+		String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId;
+		if (!redisService.setNx(relation_num_key, userId, 60 * 5L)) {
+			GroupsRelation dbRelation = groupsRelationMapper.selectById(relationId);
+			if (dbRelation.getUserId() != 0) {
+				log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
+				throw new BusinessRuntimeException("系统繁忙,请重试...");
 			}
 		}
-		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) {
-			log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
-			throw new BusinessRuntimeException(I18nMessageUtil.getI18nMsg("sys_busy_error"));
+		if (status == GroupsRelation.Status.outside) {
+			return;
 		}
 		int count = groupsMapper.decrAvailableNum(groupsId);
 		if (count == 0) {
 			log.error("车位异常 groupId:{}", groupsId);
 			groupsMapper.updateAvailableNum(groupsId);
 			redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relationId);
-			throw new BusinessRuntimeException(I18nMessageUtil.getI18nMsg("sys_busy_error"));
+			throw new BusinessRuntimeException("车位异常");
 		}
 	}
 
@@ -1036,58 +1040,27 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 	/**
 	 * 获取车位
 	 */
-	public Long getRelation(OrderPayRequest payRequest, GoodsDonSku sku) {
-		GroupsRelation relation;
+	public GroupsRelation getRelation(OrderPayRequest payRequest, GoodsDonSku sku) {
 		Long payRelationId = payRequest.getRelationId();
-		Boolean isLoginPopularize = payRequest.getIsLoginPopularize();
 		Long userId = payRequest.getUserId();
-		//锁定座位
-		if (payRelationId != null && payRelationId > 0) {
-			relation = groupsRelationMapper.selectById(payRelationId);
-			if (relation == null) {
-				throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
-			}
-			if (relation.getUserId() != null && relation.getUserId() > 0L) {
-				throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg());
-			}
-
-		} else {
-			//寻找差不多过期时间规格的车位
-			relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getDays(), sku.getMonths(), null);
-			if (relation == null) {
-				//TODO 如果没指定座位,等待逻辑确认
-				GroupsTrips groups = groupsMapper.selectOne( Wrappers.lambdaQuery(GroupsTrips.class)
-						.eq(GroupsTrips::getSkuId, sku.getId())
-						.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-						.eq(GroupsTrips::getStatus, GroupsTrips.Status.validity)
-						.orderByAsc(GroupsTrips::getAvailableNum));
-				//待发车
-				if (groups == null) {
-					groups = groupsMapper.selectOne( Wrappers.lambdaQuery(GroupsTrips.class)
-							.eq(GroupsTrips::getSkuId, sku.getId())
-							.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
-							.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
-							.orderByAsc(GroupsTrips::getAvailableNum));
-				}
-				if (groups == null) {
-					relation = groupsFuncService.createNewGroupsTrips(sku);
-				} else {
-					//寻找快满编车队进行占座
-					relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
-					if (relation == null) {
-						throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
-					}
-				}
-			}
+		String ip = null;
+		//MJ车票统一ip不允许上同一车次
+		if (sku.getGoodsId() == 26) {
+			ip = payRequest.getIp();
 		}
+		//获取车票车位
+		GroupsRelation relation = groupRelationFrontService.getRelation(payRelationId, userId, sku, ip);
 
 		//锁定座位
-		setRelation(relation.getId(), relation.getGroupsId(), userId, sku.getGoodsId(), isLoginPopularize);
+		setRelation(relation);
 		relation.setUserId(userId);
+		//重新置为锁定
 		relation.setStatus(GroupsRelation.Status.locking);
 		groupsRelationMapper.updateById(relation);
-		redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
-		return relation.getId();
+
+		Long skuId = sku.getId();
+		Long groupsId = relation.getGroupsId();
+		return relation;
 	}
 
 

+ 7 - 1
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -1,6 +1,7 @@
 package com.cyksj.service.relation;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.views.RenewalView;
 import com.cyksj.model.views.UserRecommendGoodsFrontView;
@@ -18,7 +19,7 @@ public interface GroupRelationFrontService {
 
 	Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon);
 
-	GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer days, Integer months, List<Long> errorsRelationIds);
+	GroupsRelation getSimilarExpiredGroupRelation(GoodsDonSku sku, List<Long> errorsRelationIds, String ip);
 
 	Page<UserRecommendGoodsFrontView> getRecommendGoodsViews(Boolean isPayNf, List<Long> filter_goods_id, Integer start, Integer limit);
 
@@ -26,4 +27,9 @@ public interface GroupRelationFrontService {
 	 * 获取车票账号登录 验证码
 	 */
 	String getAiVerifyCode(Long userId, Long relationId, Integer type, Boolean sync) throws Exception;
+
+	/**
+	 * 获取车票座位
+	 */
+	GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku, String ip);
 }

+ 111 - 2
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -10,10 +10,13 @@ import cn.hutool.http.HttpStatus;
 import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.StringUtil;
 import com.cyksj.common.util.TicketCodeCommonUtil;
 import com.cyksj.enums.GatewayApiCode;
+import com.cyksj.mapper.GroupsMapper;
 import com.cyksj.mapper.GroupsRelationLoginCodeRecordMapper;
 import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
@@ -22,6 +25,7 @@ import com.cyksj.model.entity.*;
 import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.chatgpt.ChatGptAuthService;
+import com.cyksj.service.groups.GroupsFuncService;
 import com.cyksj.service.mail.CuiQiuMailService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.relation.GroupRelationFrontService;
@@ -40,6 +44,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_ALREADY_BE_USER;
+import static com.cyksj.enums.GatewayApiCode.GROUP_INDEX_NOT_FIND;
+
 /*
  *项目名: netflix
  *文件名: GroupRelationFrontServiceImpl
@@ -60,6 +67,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final GroupsRelationMapper groupsRelationMapper;
 
+	private final GroupsMapper groupsMapper;
+
 	private final ChatGptAuthService chatGptAuthService;
 
 	private final RedisService redisService;
@@ -72,6 +81,10 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final GroupsRelationNetflixService groupsRelationNetflixService;
 
+	private final GroupsFuncService groupsFuncService;
+
+	private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
+
 	//脆球邮箱后缀
 	private final static String CUI_QIU_EMAIL_SUFFIX = "@kindvd.com";
 
@@ -177,15 +190,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 	}
 
 	@Override
-	public GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer days, Integer months, List<Long> errorsRelationIds) {
+	public GroupsRelation getSimilarExpiredGroupRelation(GoodsDonSku sku, List<Long> errorsRelationIds, String ip) {
+		Long skuId = sku.getId();
+		Integer days = sku.getDays();
+		Integer months = sku.getMonths();
+		Integer maxNum = sku.getNum();
 		DateTime expiryTime = null;
 		if (days != null && days > 0) {
 			expiryTime = DateUtil.offsetDay(DateTime.now(), days);
 		} else {
 			expiryTime = DateUtil.offsetMonth(DateTime.now(), months);
 		}
+		Integer extraNum = 5;
+		if (sku.getId() == 178l) {
+			extraNum = 2;
+		}
+		maxNum += extraNum;
 		DateTime minExpiryTime = DateUtil.offsetDay(expiryTime, -5);
-		Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime);
+		Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime, maxNum, ip);
 		if (groupsId == null) {
 			log.info("暂无相似过期时间车队");
 			return null;
@@ -264,6 +286,93 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return code;
 	}
 
+	@Override
+	public GroupsRelation getRelation(Long payRelationId, Long userId, GoodsDonSku sku, String ip) {
+		GroupsRelation relation = null;
+		Integer maxNum = sku.getNum();
+		if (payRelationId != null && payRelationId > 0) {
+			relation = groupsRelationMapper.selectById(payRelationId);
+			if (relation == null) {
+				throw new BusinessRuntimeException(GROUP_INDEX_NOT_FIND.getCode(), GROUP_INDEX_NOT_FIND.getMsg());
+			}
+			if (relation.getUserId() != null && relation.getUserId() > 0L) {
+				throw new BusinessRuntimeException(GROUP_INDEX_ALREADY_BE_USER.getCode(), GROUP_INDEX_ALREADY_BE_USER.getMsg());
+			}
+
+		} else {
+			GroupsTrips groups = null;
+			//ChatGpt Plus、Midjourney非独立规格 上车先获取硬塞座位 硬塞5个座位
+			//主账号过期时间25天以外
+			//23-12-06 MidJourney 不硬塞
+			if (sku.getNum() > 1 && Constant.AI_goodsIds.get(0) == sku.getGoodsId()) {
+				Integer extraNum = 5;
+				if (sku.getId() == 178l || sku.getId() == 423l) {
+					extraNum = 2;
+				}
+				maxNum += extraNum;
+				DateTime time = DateUtil.offsetDay(DateUtil.beginOfDay(DateTime.now()), 25);
+				//不塞存在该用户的车队
+				Long groupsId = groupsRelationMapper.getOutSideGroupsTripsRelationByGoodsId(sku.getId(), time, extraNum, userId, sku.getNum(), maxNum);
+				if (groupsId != null) {
+					relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+							.eq(GroupsRelation::getGroupsId, groupsId)
+							.eq(GroupsRelation::getUserId, 0)
+							.eq(GroupsRelation::getStatus, GroupsRelation.Status.outside)
+							.last("limit 1"));
+					if (relation == null) {
+						relation = new GroupsRelation();
+						relation.setStatus(GroupsRelation.Status.outside);
+						relation.setUserId(userId);
+						relation.setGroupsId(groupsId);
+						GroupsRelation maxNumRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1"));
+						Integer nextNum = maxNumRelation.getNum() + 1;
+						if (redisService.setNx(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, nextNum), nextNum, RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getTimeout())) {
+							relation.setNum(nextNum);
+							groupsRelationMapper.insert(relation);
+						} else {
+							throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+						}
+					}
+					groups = groupsMapper.selectById(groupsId);
+				}
+			}
+			if (groups == null) {
+				//寻找差不多过期时间规格的车位
+				relation = getSimilarExpiredGroupRelation(sku, null, ip);
+				if (relation == null) {
+					//TODO 如果没指定座位,等待逻辑确认
+					groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.validity, maxNum, ip);
+
+					if (groups == null) {
+						//待发车
+						groups = groupsMapper.selectTicketGroups(sku.getId(), GroupsTrips.Status.waiting, maxNum, ip);
+					}
+					//新增空车队
+					if (groups == null) {
+						relation = groupsFuncService.createNewGroupsTrips(sku);
+					}
+					//获取车位
+					if (relation == null) {
+						//寻找快满编车队进行占座
+						relation = groupsRelationMapper.selectRandomOneRelationByGroupsId(groups.getId());
+						if (relation == null) {
+							Long groupsId = groups.getId();
+							TASK_EXECUTOR.execute(() -> groupsMapper.updateAvailableNum(groupsId));
+							throw BusinessRuntimeException.getInstance("系统繁忙,请重试...");
+						}
+					}
+				}
+			}
+			if (groups == null) {
+				groups = groupsMapper.selectById(relation.getGroupsId());
+			}
+			//车队目前可用停车数
+			relation.setGroupsAvailParkingNum(groups.getAvailableParkingNum());
+			relation.setMaxNum(maxNum);
+		}
+		return relation;
+	}
+
 
 	public String getDifferentGoodsCode(Long goodsId, String body, Integer type, Boolean sync) {
 		String code = null;

+ 1 - 1
netflix-web/src/main/java/com/cyksj/web/aop/NoSubmitAop.java

@@ -41,7 +41,7 @@ public class NoSubmitAop {
 			return pjp.proceed();
 		} else {
 			logger.error("重复提交");
-			throw BusinessRuntimeException.getInstance("请勿重复提交");
+			throw BusinessRuntimeException.getInstance("Please do not submit repeatedly");
 		}
 	}
 

+ 31 - 5
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -1,6 +1,9 @@
 package com.cyksj.web.controller.payment;
 
+import cn.hutool.core.codec.Base64;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.i18n.I18nMessageUtil;
@@ -42,6 +45,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.InputStream;
@@ -105,15 +109,37 @@ public class OrderController {
      * @date 2021-10-11 下午4:56
      */
     @PostMapping("/post/submit")
-    public Result<OrderDon> submit(@Validated @RequestBody OrderPayRequest payRequest) throws Exception {
+    public Result<OrderDon> submit(@Validated @RequestBody OrderPayRequest payRequest, HttpServletResponse response) throws Exception {
         final String methodName = "吊起微信支付";
-        if (payRequest.getIsNoLogin() == null || !payRequest.getIsNoLogin()) {
-            payRequest.setUserId(StpUserUtil.getLoginIdAsLong());
-        }
-        log.info("{}[start] params:{}",methodName,payRequest);
+        Long userId = StpUserUtil.getUserIdAfterLogin();
+        payRequest.setUserId(userId);
+        log.info("{}[start] params:{}", methodName, payRequest);
+
+        String ip = ServletUtil.getClientIP(request);
+        payRequest.setIp(ip);
 
         OrderDon orderDon = orderDonService.submit(payRequest);
 
+        //无登录订单 预留手机号免登录
+        if (userId == null && payRequest.getPopularizeId() != null && StrUtil.isNotBlank(payRequest.getPhone())) {
+            User user = userMapper.selectById(orderDon.getUserId());
+            //写回登陆信息
+            StpUserUtil.login(user.getId());
+            response.addHeader("satoken-user", StpUserUtil.getTokenValue());
+
+            Cookie cookie = new Cookie("satoken-user", StpUserUtil.getTokenValue());
+            cookie.setMaxAge(31536000);
+            cookie.setPath("/");
+            response.addCookie(cookie);
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.putOpt("showId", user.getShowId());
+            jsonObject.putOpt("nickName", user.getNickname());
+
+            Cookie userInfo = new Cookie("info", Base64.encode(jsonObject.toString()));
+            cookie.setMaxAge(31536000);
+            cookie.setPath("/");
+            response.addCookie(userInfo);
+        }
         return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
     }
 

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

@@ -205,7 +205,7 @@ public class UserController {
         Boolean isFlag = false;
         if (StrUtil.isNotBlank(request.getNickname())) {
             if (request.getNickname().length() > 32) {
-                throw BusinessRuntimeException.getInstance("名称过长");
+                throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("name_too_long"));
             }
             user.setNickname(request.getNickname());
             isFlag = true;

+ 6 - 0
netflix-web/src/main/java/com/cyksj/web/util/StpUserUtil.java

@@ -324,4 +324,10 @@ public class StpUserUtil {
         stpLogic.login(loginId, loginModel);
     }
 
+    public static Long getUserIdAfterLogin() {
+        if (isLogin()) {
+            return StpUserUtil.getLoginIdAsLong();
+        }
+        return null;
+    }
 }

+ 1 - 0
netflix-web/src/main/resources/i18n/yhlx_en_US.properties

@@ -118,3 +118,4 @@ bind_account_detail_not_exist=You have not bound your account information
 coupon_sku_not_available_renew_error=Cannot be used for renewal of this specification
 coupon_sku_not_available_order_error=Cannot be used to place an order for this specification
 coupon_money_error=The payment amount cannot be less than the discounted amount
+name_too_long=Name is too long

+ 1 - 0
netflix-web/src/main/resources/i18n/yhlx_ja_JP.properties

@@ -118,3 +118,4 @@ bind_account_detail_not_exist=アカウント情報が関連付けられてい
 coupon_sku_not_available_renew_error=本仕様の更新には使用できません
 coupon_sku_not_available_order_error=この仕様の注文には使用できません
 coupon_money_error=支払額が割引額を下回ることはない
+name_too_long=名前が長すぎます

+ 1 - 0
netflix-web/src/main/resources/i18n/yhlx_ko_KR.properties

@@ -118,3 +118,4 @@ bind_account_detail_not_exist=계정 정보가 없습니다.
 coupon_sku_not_available_renew_error=이 사양의 갱신에는 사용할 수 없습니다
 coupon_sku_not_available_order_error=이 사양을 주문하는 데 사용할 수 없습니다
 coupon_money_error=결제 금액은 할인된 금액보다 작을 수 없습니다
+name_too_long=이름이 너무 깁니다

+ 2 - 1
netflix-web/src/main/resources/i18n/yhlx_zh_CN.properties

@@ -117,4 +117,5 @@ bind_account_phone_change_has_registered=您更换的手机号已注册,无法
 bind_account_detail_not_exist=您未有绑定账号信息
 coupon_sku_not_available_renew_error=不能用于该规格续费
 coupon_sku_not_available_order_error=不能用于该规格下单
-coupon_money_error=支付金额不能小于优惠金额
+coupon_money_error=支付金额不能小于优惠金额
+name_too_long=名称过长

+ 2 - 1
netflix-web/src/main/resources/i18n/yhlx_zh_HK.properties

@@ -117,4 +117,5 @@ bind_account_phone_change_has_registered=你更換的手機號已註冊,無法
 bind_account_detail_not_exist=您未有綁定賬號信息
 coupon_sku_not_available_renew_error=不能用于該規格續費
 coupon_sku_not_available_order_error=不能用于該規格下單
-coupon_money_error=支付金額不能小于優惠金額
+coupon_money_error=支付金額不能小于優惠金額
+name_too_long=名稱過長