Procházet zdrojové kódy

Merge branch 'corp_radar'

# Conflicts:
#	netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
#	netflix-service/src/main/java/com/cyksj/redis/RedisService.java
#	netflix-service/src/main/java/com/cyksj/service/corp/WxCorpOps.java
#	netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java
#	netflix-service/src/main/java/com/cyksj/service/corp/impl/WxCorpOpsImpl.java
#	netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
#	netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java
zoujiajian před 2 roky
rodič
revize
a34282baa3
43 změnil soubory, kde provedl 1398 přidání a 73 odebrání
  1. 4 0
      netflix-common/src/main/java/com/cyksj/common/util/StringUtil.java
  2. 23 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpGroupChatMemberMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpInteractiveRadarMapper.java
  4. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpInteractiveRadarUserRecordMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpInteractiveUserOrderRelationMapper.java
  6. 5 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserMapper.java
  7. 12 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpGroupChat.java
  8. 38 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpGroupChatMember.java
  9. 39 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveRadar.java
  10. 20 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveRadarUserRecord.java
  11. 20 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveReaderLink.java
  12. 25 0
      netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveUserOrderRelation.java
  13. 3 0
      netflix-dao/src/main/java/com/cyksj/model/entity/WxCorpApp.java
  14. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderPayRequest.java
  15. 6 0
      netflix-dao/src/main/java/com/cyksj/model/request/corp/CorpXmlMessage.java
  16. 16 0
      netflix-dao/src/main/java/com/cyksj/model/request/corp/message/TextCard.java
  17. 28 0
      netflix-dao/src/main/java/com/cyksj/model/request/corp/message/WxCorpAgentMessage.java
  18. 45 0
      netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatDetail.java
  19. 37 0
      netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatListDetail.java
  20. 78 0
      netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatMemberObj.java
  21. 43 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpGroupChatDetailView.java
  22. 48 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpGroupChatView.java
  23. 50 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveRadarOrderDataView.java
  24. 15 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveReaderOrderDetail.java
  25. 26 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveReaderOrderDetailView.java
  26. 54 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveReaderView.java
  27. 26 0
      netflix-dao/src/main/java/com/cyksj/model/views/CorpUserSearchView.java
  28. 39 0
      netflix-dao/src/main/resources/mapper/CorpGroupChatMemberMapper.xml
  29. 10 0
      netflix-service/src/main/java/com/cyksj/service/corp/CorpGroupChatService.java
  30. 14 0
      netflix-service/src/main/java/com/cyksj/service/corp/CorpInteractiveRadarService.java
  31. 11 0
      netflix-service/src/main/java/com/cyksj/service/corp/CorpInteractiveReaderFrontService.java
  32. 0 2
      netflix-service/src/main/java/com/cyksj/service/corp/CropChatService.java
  33. 14 2
      netflix-service/src/main/java/com/cyksj/service/corp/WxCorpOps.java
  34. 210 0
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java
  35. 16 0
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpGroupChatServiceImpl.java
  36. 60 0
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpInteractiveRadarServiceImpl.java
  37. 79 0
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpInteractiveReaderFrontServiceImpl.java
  38. 0 5
      netflix-service/src/main/java/com/cyksj/service/corp/impl/CropChatServiceImpl.java
  39. 62 20
      netflix-service/src/main/java/com/cyksj/service/corp/impl/WxCorpOpsImpl.java
  40. 6 0
      netflix-service/src/main/java/com/cyksj/service/corp/msg/CorpEventActionService.java
  41. 34 44
      netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpChatController.java
  42. 124 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpInteractiveRadarController.java
  43. 14 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

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

@@ -32,6 +32,10 @@ public final class StringUtil {
 	 */
 	private static final String CRLF = "\r\n";
 
+	public static final String QM = "?";
+
+	public static final String AD = "&";
+
 	/**
 	 * An empty immutable {@code String} array.
 	 */

+ 23 - 0
netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpGroupChatMemberMapper.java

@@ -0,0 +1,23 @@
+package com.cyksj.mapper.corp;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.CorpGroupChatMember;
+import com.cyksj.model.response.corp.CorpGroupChatMemberObj;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatMemberMapper
+ *创建者: JavaZou
+ *创建时间:2023/8/8 13:45
+ */
+public interface CorpGroupChatMemberMapper extends BaseMapper<CorpGroupChatMember> {
+
+	void batchInsert(@Param("groupChatId") Long groupChatId, @Param("wxCorpId") Long wxCorpId, @Param("memberList") List<CorpGroupChatMemberObj> memberList);
+
+	List<String> getAllMemberByCorpIdAndChatId(Long groupChatId);
+
+	void batchDeleteByChatIdAndUserId(@Param("groupChatId") Long groupChatId, @Param("delUserIds") List<String> delUserIds);
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.corp;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.CorpInteractiveRadar;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveRadarMapper
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:34
+ */
+public interface CorpInteractiveRadarMapper extends BaseMapper<CorpInteractiveRadar> {
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.corp;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.CorpInteractiveRadarUserRecord;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveRadarUserRecordMapper
+ *创建者: JavaZou
+ *创建时间:2023/8/4 18:31
+ */
+public interface CorpInteractiveRadarUserRecordMapper extends BaseMapper<CorpInteractiveRadarUserRecord> {
+}

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

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.corp;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.CorpInteractiveUserOrderRelation;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveUserOrderRelationMapper
+ *创建者: JavaZou
+ *创建时间:2023/8/8 16:11
+ */
+public interface CorpInteractiveUserOrderRelationMapper extends BaseMapper<CorpInteractiveUserOrderRelation> {
+}

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserMapper.java

@@ -2,6 +2,7 @@ package com.cyksj.mapper.corp;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.CorpUser;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
 
@@ -12,4 +13,8 @@ import org.apache.ibatis.annotations.Select;
 public interface CorpUserMapper extends BaseMapper<CorpUser> {
 	@Select("select cu.id,cu.user_id,cu.unionid from (select corp_user_id from corp_user_auth where external_userid = #{corpUserId} limit 1) cua inner join corp_user cu on cu.id = cua.corp_user_id and cu.unionid != '' limit 1")
 	CorpUser setCorpUserUserId(String corpUserId);
+
+	@Select("select u.id from (select corp_user_id from corp_user_auth where wx_corp_id = #{wxCorpId} and external_userid = #{corpUserId} limit 1) ca inner join corp_user cu on cu.id = ca.corp_user_id and cu.unionid != ''" +
+			" inner join user u on u.uionid = cu.unionid")
+	Long selectUserIdByCropUserId(@Param("wxCorpId") Long wxCorpId, @Param("corpUserId") String corpUserId);
 }

+ 12 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpGroupChat.java

@@ -1,8 +1,11 @@
 package com.cyksj.model.entity;
 
+import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.Date;
+
 /*
  *项目名: netflix
  *文件名: CorpGroupChat
@@ -11,14 +14,23 @@ import lombok.Setter;
  */
 @Getter
 @Setter
+@Builder
 public class CorpGroupChat extends BaseEntity{
 	private String chatId;
 
 	private String chatName;
 
+	private String owner;
+
 	private Long wxCorpId;
 
+	private String corpId;
+
 	private Long goodsId;
 
 	private String configId;
+
+	private Date groupCreateTime;
+
+	private Boolean deleted;
 }

+ 38 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpGroupChatMember.java

@@ -0,0 +1,38 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatMember
+ *创建者: JavaZou
+ *创建时间:2023/8/8 13:46
+ */
+@Getter
+@Setter
+public class CorpGroupChatMember extends BaseEntity{
+	private Long groupChatId;
+
+	private Long wxCorpId;
+
+	private String corpUserId;
+
+	private Long userId;
+
+	private Integer type;
+
+	private String unionid;
+
+	private Long joinTime;
+
+	private Integer joinScene;
+
+	private String groupName;
+
+	private String name;
+
+	private String inviterUserId;
+
+	private Boolean deleted;
+}

+ 39 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveRadar.java

@@ -0,0 +1,39 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveRadar
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:01
+ */
+@Getter
+@Setter
+public class CorpInteractiveRadar extends BaseEntity{
+	@NotEmpty(message = "雷达标题不为空")
+	private String title;
+
+	@NotEmpty(message = "雷达链接不为空")
+	private String url;
+
+	/**
+	 * 1、企业微信,2、普通
+	 */
+	@NotNull(message = "雷达类型不为空")
+	private Integer type;
+
+	private Integer wxCorpId;
+
+	@TableField(exist = false)
+	private CorpInteractiveReaderLink linkInfo;
+
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String linkInfoStr;
+}

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveRadarUserRecord.java

@@ -0,0 +1,20 @@
+package com.cyksj.model.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author chan
+ * @date 2023/5/10 3:54 PM
+ * 互动记录
+ */
+@Data
+@Accessors(chain = true)
+public class CorpInteractiveRadarUserRecord extends BaseEntity {
+
+    private Long radarId;
+
+    private Long userId;
+
+    private Long corpUserId;
+}

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveReaderLink.java

@@ -0,0 +1,20 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderLink
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:07
+ */
+@Getter
+@Setter
+public class CorpInteractiveReaderLink {
+	private String title;
+
+	private String desc;
+
+	private String img;
+}

+ 25 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CorpInteractiveUserOrderRelation.java

@@ -0,0 +1,25 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveUserOrderRelation
+ *创建者: JavaZou
+ *创建时间:2023/8/8 16:11
+ */
+@Getter
+@Setter
+public class CorpInteractiveUserOrderRelation extends BaseEntity{
+	private Long radarId;
+
+	private Long orderId;
+
+	private Long userId;
+
+	/**
+	 * 1新用户,0老用户
+	 */
+	private Boolean isNew;
+}

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

@@ -14,6 +14,9 @@ public class WxCorpApp {
 
     private Long id;
 
+    @TableField(value = "agentId")
+    private String agentId;
+
     /**
      * appId
      */

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

@@ -136,4 +136,9 @@ public class OrderPayRequest {
      * 购买实物
      */
     private Boolean isPayReal;
+
+    /**
+     * 雷达链接id
+     */
+    private Long radarId;
 }

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

@@ -230,6 +230,12 @@ public class CorpXmlMessage implements Serializable {
 	@JacksonXmlProperty(localName = "ErrorCount")
 	private Integer errorCount;
 
+	/**
+	 * 客户群id
+	 */
+	@JacksonXmlProperty(localName = "ChatId")
+	private String chatId;
+
 
 	public static CorpXmlMessage fromXml(String xml) {
 		//修改微信变态的消息内容格式,方便解析

+ 16 - 0
netflix-dao/src/main/java/com/cyksj/model/request/corp/message/TextCard.java

@@ -0,0 +1,16 @@
+package com.cyksj.model.request.corp.message;
+
+import lombok.Data;
+
+/**
+ * 文本卡片消息
+ */
+@Data
+public class TextCard{
+
+  private String title;
+  private String description;
+  private String url;
+  private String btnTxt;
+
+}

+ 28 - 0
netflix-dao/src/main/java/com/cyksj/model/request/corp/message/WxCorpAgentMessage.java

@@ -0,0 +1,28 @@
+package com.cyksj.model.request.corp.message;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+/**
+ * @author chan
+ * @date 2023/5/10 3:12 PM
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Data
+public class WxCorpAgentMessage {
+
+    /**
+     * The Msg type.
+     */
+    private String msgtype;
+    /**
+     * The Agent id.
+     */
+    private Integer agentid;
+
+    private String touser;
+
+    private String safe;
+
+    private TextCard textcard;
+}

+ 45 - 0
netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatDetail.java

@@ -0,0 +1,45 @@
+package com.cyksj.model.response.corp;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/*
+ *项目名: yicang-admin
+ *文件名: CorpGroupChatDetail
+ *创建者: JavaZou
+ *创建时间:2022/7/28 15:44
+ */
+@Data
+public class CorpGroupChatDetail implements Serializable {
+	private static final long serialVersionUID = 484416340115135824L;
+	/**
+	 * 客户群ID
+	 */
+	@JsonProperty("chat_id")
+	private String chatId;
+
+	/**
+	 * 群名
+	 */
+	private String name;
+
+	/**
+	 * 群主ID
+	 */
+	private String owner;
+
+	/**
+	 * 群的创建时间
+	 */
+	@JsonProperty("create_time")
+	private Long createTime;
+
+	/**
+	 * 群成员列表
+	 */
+	@JsonProperty("member_list")
+	private List<CorpGroupChatMemberObj> memberList;
+}

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatListDetail.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.response.corp;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/*
+ *项目名: yicang-admin
+ *文件名: CorpGroupChatList
+ *创建者: JavaZou
+ *创建时间:2022/7/29 9:11
+ */
+@Data
+public class CorpGroupChatListDetail implements Serializable {
+	private static final long serialVersionUID = -5449657540578173535L;
+
+	private Integer errcode;
+
+	private String errmsg;
+
+	@JsonProperty("next_cursor")
+	private String nextCursor;
+
+	@JsonProperty("group_chat_list")
+	private List<GroupChatList> groupChatList;
+
+	@Data
+	public static class GroupChatList implements Serializable{
+		private static final long serialVersionUID = -8548903091451327483L;
+		@JsonProperty("chat_id")
+		private String chatId;
+
+		private Integer status;
+	}
+}

+ 78 - 0
netflix-dao/src/main/java/com/cyksj/model/response/corp/CorpGroupChatMemberObj.java

@@ -0,0 +1,78 @@
+package com.cyksj.model.response.corp;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/*
+ *项目名: yicang-admin
+ *文件名: CorpGroupChatMember
+ *创建者: JavaZou 企业微信客户群用户表
+ *创建时间:2022/7/28 15:49
+ */
+@Data
+public class CorpGroupChatMemberObj implements Serializable {
+	private static final long serialVersionUID = -2623222587422001198L;
+
+	/**
+	 * 客户群ID
+	 */
+	private String chatId;
+
+	private Long yhUserId;
+
+	/**
+	 * 群成员用户id
+	 */
+	@JsonProperty("userid")
+	private String userId;
+
+	/**
+	 * 成员类型。
+	 * 1 - 企业成员
+	 * 2 - 外部联系人
+	 */
+	private Integer type;
+
+	/**
+	 * 外部联系人在微信开放平台的唯一身份标识
+	 */
+	@JsonProperty("unionid")
+	private String unionId;
+
+	/**
+	 * 入群时间
+	 */
+	@JsonProperty("join_time")
+	private Long joinTime;
+
+	/**
+	 * 入群方式。
+	 * 1 - 由群成员邀请入群(直接邀请入群)
+	 * 2 - 由群成员邀请入群(通过邀请链接入群)
+	 * 3 - 通过扫描群二维码入群
+	 */
+	@JsonProperty("join_scene")
+	private Integer joinScene;
+
+	/**
+	 * 客户群里昵称
+	 */
+	@JsonProperty("group_nickname")
+	private String groupNickname;
+
+	/**
+	 * 客户名称
+	 */
+	private String name;
+
+	@JsonProperty("invitor")
+	private Invitor invitor;
+
+	@Data
+	class Invitor implements Serializable {
+		private static final long serialVersionUID = -7054342546494309122L;
+		private String userid;
+	}
+}

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

@@ -0,0 +1,43 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatDetailView
+ *创建者: JavaZou
+ *创建时间:2023/8/8 11:59
+ */
+@Getter
+@Setter
+@SearchBean(tables = "corp_group_chat_member cm left join corp_user_follow_relation cfr on cfr.corp_user_id = cm.corp_user_id and cfr.wx_corp_id = cm.wx_corp_id" +
+		" left join corp_user_tag ct on ct.relation_id = cfr.id",
+		where = ":condition:",
+		groupBy = "cm.user_id,group_chat_id,cm.corp_user_id,cm.group_nickname,cm.join_time")
+public class CorpGroupChatDetailView {
+	@DbField("cm.group_chat_id")
+	private Long groupChatId;
+
+	@DbField("cm.user_id")
+	private Long userId;
+
+	@DbField("cm.corp_user_id")
+	private String corpUserId;
+
+	@DbField("group_concat(ct.tag_name)")
+	private String tagNames;
+
+	/**
+	 * 用户群里昵称
+	 */
+	@DbField("cm.group_nickname")
+	private String groupNickname;
+
+	@DbField("FROM_UNIXTIME(cm.join_time)")
+	private Date joinTime;
+}

+ 48 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CorpGroupChatView.java

@@ -0,0 +1,48 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatView
+ *创建者: JavaZou
+ *创建时间:2023/8/8 11:50
+ */
+@Getter
+@Setter
+@SearchBean(tables = "corp_group_chat cgc left join corp_follow cf on cf.userid = cgc.owner and cgc.wx_corp_id = cf.wx_corp_id" +
+		" left join corp_group_chat_member cm on cm.group_chat_id = cgc.id",
+		groupBy = "cgc.id,cgc.chat_name,cgc.chat_id,cgc.chat_id,cgc.group_create_time,cf.name")
+public class CorpGroupChatView {
+	@DbField("cgc.id")
+	private Long id;
+
+	/**
+	 * 群名
+	 */
+	@DbField("cgc.chat_name")
+	private String chatName;
+
+	/**
+	 * 群人数
+	 */
+	@DbField("count(cm.id)")
+	private Integer userNUm;
+
+	/**
+	 * 群主
+	 */
+	@DbField("cf.name")
+	private String ownerName;
+
+	@DbField("cgc.chat_id")
+	private String chatId;
+
+	@DbField("cgc.group_create_time")
+	private Date groupCreatedTime;
+}

+ 50 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveRadarOrderDataView.java

@@ -0,0 +1,50 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: CorpInteractiveRadarOrderDataView
+ * 创建者: JavaZou
+ * 创建时间:2023/10/24 11:37
+ */
+@Getter
+@Setter
+public class CorpInteractiveRadarOrderDataView {
+
+	private CorpInteractiveRadarOrderData today;
+
+	private CorpInteractiveRadarOrderData history;
+
+	@Getter
+	@Setter
+	@SearchBean(tables = "corp_interactive_radar_user_record cr left join corp_interactive_user_order_relation cor on cor.radar_id = cr.id" +
+			" left join order_don o on o.id = cor.order_id and o.status not in ('close','noPayment','refund')",
+			where = ":condition:")
+	public static class CorpInteractiveRadarOrderData{
+		@DbField("count(distinct cr.id)")
+		private Integer click;
+
+		@DbField("count(distinct o.id)")
+		private Integer payNum;
+
+		@DbField("count(distinct cr.user_id)")
+		private Integer clickUserNum;
+
+		@DbField("count(distinct o.user_id)")
+		private Integer payUserNum;
+
+		@DbField("count(distinct if(cor.is_new = 1,o.user_id,NULL))")
+		private Integer payNewUserNum;
+
+		@DbField("count(distinct if(cor.is_new = 0,o.user_id,NULL))")
+		private Integer payOldUserNum;
+
+
+		@DbField("count(distinct if(o.order_type = 2,o.user_id,NULL))")
+		private Integer renewUserNum;
+	}
+}

+ 15 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveReaderOrderDetail.java

@@ -0,0 +1,15 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderOrderDetail
+ *创建者: JavaZou
+ *创建时间:2023/8/8 11:16
+ */
+@Getter
+@Setter
+public class CorpInteractiveReaderOrderDetail {
+}

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CorpInteractiveReaderOrderDetailView.java

@@ -0,0 +1,26 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderOrderDetailView
+ *创建者: JavaZou
+ *创建时间:2023/8/8 16:19
+ */
+@Getter
+@Setter
+@SearchBean(tables = "(select * from corp_interactive_user_order_relation where :id:) cor inner join order_don o on cor.order_id = o.id and o.status not in ('close','noPayment','refund')")
+public class CorpInteractiveReaderOrderDetailView {
+	@DbField("count(distinct cor.user_id)")
+	private Integer total;
+
+	@DbField("count(distinct if(is_new,cor.user_id,NUll))")
+	private Integer numOfNewUser;
+
+	@DbField("count(distinct if(is_new,NUll,cor.user_id))")
+	private Integer numOfOldUser;
+}

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

@@ -0,0 +1,54 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.CorpInteractiveReaderLink;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderView
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:57
+ */
+@Getter
+@Setter
+@SearchBean(tables = "corp_interactive_radar cr")
+public class CorpInteractiveReaderView {
+	@DbField("cr.id")
+	private Long id;
+
+	@DbField("cr.title")
+	private String title;
+
+	@DbField("cr.url")
+	private String url;
+
+	@DbField("cr.type")
+	private Integer type;
+
+	@DbIgnore
+	private Integer clickNum;
+
+	@DbIgnore
+	private Integer payNum;
+
+	@DbIgnore
+	private Integer payNewUserNum;
+
+	@DbIgnore
+	private Integer payOldUserNum;
+
+	@DbField("cr.link_info_str")
+	private String linkInfoStr;
+
+	@DbIgnore
+	private CorpInteractiveReaderLink linkInfo;
+
+	@DbField("cr.created_time")
+	private Date createdTime;
+}

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/views/CorpUserSearchView.java

@@ -0,0 +1,26 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: CorpUserSearchView
+ *创建者: JavaZou
+ *创建时间:2023/8/8 14:02
+ */
+@Getter
+@Setter
+@SearchBean(tables = "corp_user cu left join corp_user_auth ca on ca.corp_user_id = cu.id")
+public class CorpUserSearchView {
+	@DbField("ca.wx_corp_id")
+	private Long wxCorpId;
+
+	@DbField("ca.corp_user_id")
+	private String corpUserId;
+
+	@DbField("cu.user_id")
+	private Long userId;
+}

+ 39 - 0
netflix-dao/src/main/resources/mapper/CorpGroupChatMemberMapper.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.cyksj.mapper.corp.CorpGroupChatMemberMapper">
+
+    <insert id="batchInsert">
+        insert into
+        corp_group_chat_member(`wx_crop_id`,`user_id`,`group_chat_id`,`corp_user_id`,`type`,`unionid`,`join_time`,`join_scene`,`group_nickname`,`name`,`inviter_user_id`,`created_time`,`update_time`)
+        values
+        <foreach collection="memberList" item="item" separator=",">
+            (#{wxCorpId},#{item.yhUserId},#{groupChatId},#{item.userId},#{item.type},#{item.unionId},#{item.joinTime},#{item.joinScene},#{item.groupNickname},#{item.name},
+            <if test="item.invitor == null">
+                ''
+            </if>
+            <if test="item.invitor != null">
+                #{item.invitor.userid}
+            </if>
+            ,now(),now())
+        </foreach>
+        ON DUPLICATE KEY UPDATE chatId = VALUES(chatId),
+        deleted = 1
+    </insert>
+
+    <update id="batchDeleteByChatIdAndUserId">
+        update corp_group_chat_member
+        set deleted = false
+        where group_chat_id = #{groupChatId} and
+        corp_user_id in
+        <foreach collection="delUserIds" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </update>
+
+    <select id="getAllMemberByCorpIdAndChatId" resultType="java.lang.String">
+        select corp_user_id
+        from corp_group_chat_member
+        where group_chat_id = #{groupChatId}
+    </select>
+</mapper>

+ 10 - 0
netflix-service/src/main/java/com/cyksj/service/corp/CorpGroupChatService.java

@@ -0,0 +1,10 @@
+package com.cyksj.service.corp;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatService
+ *创建者: JavaZou
+ *创建时间:2023/8/8 11:46
+ */
+public interface CorpGroupChatService {
+}

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/corp/CorpInteractiveRadarService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.corp;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.CorpInteractiveRadar;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveRadarService
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:33
+ */
+public interface CorpInteractiveRadarService extends IService<CorpInteractiveRadar> {
+	void saveOrUpdateRadar(CorpInteractiveRadar radar);
+}

+ 11 - 0
netflix-service/src/main/java/com/cyksj/service/corp/CorpInteractiveReaderFrontService.java

@@ -0,0 +1,11 @@
+package com.cyksj.service.corp;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderFrontService
+ *创建者: JavaZou
+ *创建时间:2023/8/4 18:22
+ */
+public interface CorpInteractiveReaderFrontService {
+	void clickReader(Long userId, Long radarId) throws Exception;
+}

+ 0 - 2
netflix-service/src/main/java/com/cyksj/service/corp/CropChatService.java

@@ -13,8 +13,6 @@ import java.util.List;
 public interface CropChatService {
 	void getCorpChat(String corpId, String configId) throws Exception;
 
-	String getGroupsList() throws Exception;
-
 	/**
 	 * 设置企业微信群配置
 	 */

+ 14 - 2
netflix-service/src/main/java/com/cyksj/service/corp/WxCorpOps.java

@@ -5,6 +5,8 @@ import com.cyksj.dto.CorpOauth2UserInfo;
 import com.cyksj.model.request.corp.CorpFollowContact;
 import com.cyksj.model.request.corp.CorpGroupConfig;
 import com.cyksj.model.request.corp.CorpMsgTemplate;
+import com.cyksj.model.request.corp.CorpXmlMessage;
+import com.cyksj.model.request.corp.message.WxCorpAgentMessage;
 import com.cyksj.model.response.corp.*;
 
 import java.util.List;
@@ -79,8 +81,6 @@ public interface WxCorpOps {
 
 	String getCorpChatGroups(String corpId,String config) throws Exception;
 
-	String getGroupsList() throws Exception;
-
 	String setGroupsConfig(List<String> chatIds) throws Exception;
 
 	String getGroupsDetail(String chatId) throws Exception;
@@ -147,4 +147,16 @@ public interface WxCorpOps {
 	 * 更新客服配置
 	 */
 	void updateCorpFollowContactConfig(CorpFollowContact corpFollowContact) throws Exception;
+
+	void sendAgentMessage(String corpId, WxCorpAgentMessage agentMessage) throws Exception;
+
+	/**
+	 * 获取客户群列表
+	 */
+	CorpGroupChatListDetail getGroupChatList(String corpId, String cursor, Integer limit) throws Exception;
+
+	/**
+	 * 获取客户群详情
+	 */
+	CorpGroupChatDetail getCorpGroupChatDetail(String corpId, CorpXmlMessage message) throws Exception;
 }

+ 210 - 0
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpEventActionServiceImpl.java

@@ -27,6 +27,9 @@ import com.cyksj.model.response.corp.CorpExternalContactInfo;
 import com.cyksj.model.response.corp.CorpUserExternalTagGroupInfo;
 import com.cyksj.model.response.corp.CorpUserExternalTagGroupList;
 import com.cyksj.service.corp.CorpService;
+import com.cyksj.model.response.corp.*;
+import com.cyksj.model.views.CorpUserSearchView;
+import com.cyksj.redis.RedisService;
 import com.cyksj.service.corp.WxCorpOps;
 import com.cyksj.service.corp.msg.CorpEventActionService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
@@ -34,8 +37,13 @@ import com.cyksj.service.market.MarketFrontService;
 import com.cyksj.service.oceanengine.OceanengineService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.sys.SysConfigService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import com.google.common.collect.Lists;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -92,6 +100,16 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 
 	private final CorpService corpService;
 
+	private final WxCorpAppMapper wxCorpAppMapper;
+
+	private final CorpGroupChatMapper corpGroupChatMapper;
+
+	private final RedisService redisService;
+
+	private final CorpGroupChatMemberMapper corpGroupChatMemberMapper;
+
+	private final BeanSearcher beanSearcher;
+
 	private static final String DEFAULT_MSG = "您好,欢迎加入银河录像局";
 
 	/**
@@ -291,6 +309,198 @@ public class CorpEventActionServiceImpl implements CorpEventActionService {
 		return null;
 	}
 
+	@Override
+	public CorpXmlOutMessage saveCorpGroupChat(CorpXmlMessage message, Map<String, Object> context) throws Exception {
+		String corpId = message.getToUserName();
+		WxCorpApp wxCorpApp = wxCorpAppMapper.selectOne(Wrappers.lambdaQuery(WxCorpApp.class)
+				.eq(WxCorpApp::getCorpId, corpId).last("limit 1"));
+		if (wxCorpApp == null) {
+			log.error("企业微信:{}配置不存在", corpId);
+			return null;
+		}
+		if (initCorpGroupsChat(wxCorpApp)) {
+			return null;
+		}
+		saveCorpGroupChatDetail(wxCorpApp, message);
+		return null;
+	}
+
+	/**
+	 * 初始化企业微信客户群
+	 */
+	public Boolean initCorpGroupsChat(WxCorpApp wxCorpApp) {
+		List<CorpGroupChat> corpGroupChats = corpGroupChatMapper.selectList(null);
+		if (corpGroupChats.isEmpty()) {
+			String key = RedisService.key.CORP_GROUP_CHAT_LIST.getNameFormat(wxCorpApp.getCorpId());
+			if (redisService.setNx(key, wxCorpApp.getCorpId(), 60 * 60 * 24l)) {
+				THREAD_POOL.execute(() -> {
+					try {
+						getChatGroupChatListDetail(wxCorpApp, "", 100);
+					} catch (Exception e) {
+					}
+					redisService.del(key);
+				});
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * 获取企业客户群列表信息
+	 */
+	private void getChatGroupChatListDetail(WxCorpApp wxCorpApp, String cursor, Integer limit) throws Exception {
+		String corpId = wxCorpApp.getCorpId();
+		CorpGroupChatListDetail list = wxCorpOps.getGroupChatList(corpId, cursor, limit);
+		predicateOrSaveCorpGroupChat(wxCorpApp,list);
+		if (StrUtil.isNotEmpty(list.getNextCursor())) {
+			getChatGroupChatListDetail(wxCorpApp, list.getNextCursor(), limit);
+		}
+	}
+
+	private void predicateOrSaveCorpGroupChat(WxCorpApp wxCorpApp, CorpGroupChatListDetail list) {
+		list.getGroupChatList().stream().forEach(obj -> {
+			CorpXmlMessage message = new CorpXmlMessage();
+			message.setChatId(obj.getChatId());
+			try {
+				saveCorpGroupChatDetail(wxCorpApp, message);
+			} catch (Exception e) {
+			}
+		});
+	}
+
+	private void saveCorpGroupChatDetail(WxCorpApp wxCorpApp, CorpXmlMessage message) throws Exception {
+		String corpId = wxCorpApp.getCorpId();
+		CorpGroupChatDetail detail = wxCorpOps.getCorpGroupChatDetail(corpId, message);
+		//企业客户群信息
+		CorpGroupChat corpGroupChat = CorpGroupChat.builder()
+				.chatId(detail.getChatId())
+				.chatName(detail.getName())
+				.wxCorpId(wxCorpApp.getId())
+				.corpId(corpId)
+				.owner(detail.getOwner())
+				.groupCreateTime(DateTime.of(detail.getCreateTime() * 1000))
+				.build();
+		try {
+			//企业客户群
+			corpGroupChatMapper.insert(corpGroupChat);
+			final Long groupChatId =corpGroupChat.getId();
+			//企业客户群成员信息
+			List<CorpGroupChatMemberObj> memberList = detail.getMemberList();
+			corpGroupSyncYhUserId(memberList, wxCorpApp.getId(), groupChatId);
+		} catch (DuplicateKeyException e) {
+		}
+	}
+
+	@Override
+	public CorpXmlOutMessage updateCorpGroupChat(CorpXmlMessage message, Map<String, Object> context) throws Exception {
+		String corpId = message.getToUserName();
+		WxCorpApp wxCorpApp = wxCorpAppMapper.selectOne(Wrappers.lambdaQuery(WxCorpApp.class)
+				.eq(WxCorpApp::getCorpId, corpId).last("limit 1"));
+		if (wxCorpApp == null) {
+			log.error("企业微信:{}配置不存在", corpId);
+			return null;
+		}
+		if (initCorpGroupsChat(wxCorpApp)) {
+			return null;
+		}
+		CorpGroupChatDetail detail = wxCorpOps.getCorpGroupChatDetail(corpId, message);
+
+		THREAD_POOL.execute(()->{
+			List<String> corpGroupEvent = List.of("change_owner", "change_name");
+			if (corpGroupEvent.contains(message.getUpdateDetail())) {
+				CorpGroupChat entity = corpGroupChatMapper.selectOne(Wrappers.lambdaQuery(CorpGroupChat.class)
+						.eq(CorpGroupChat::getWxCorpId, wxCorpApp.getId())
+						.eq(CorpGroupChat::getChatId, message.getChatId()).last("limit 1"));
+				if ("change_owner".equals(message.getUpdateDetail())) {
+					log.info("{}群主变更事件", message.getChatId());
+					entity.setOwner(detail.getOwner());
+				}
+				if ("change_name".equals(message.getUpdateDetail())) {
+					log.info("{}群名修改事件", message.getChatId());
+					entity.setChatName(detail.getName());
+				}
+				corpGroupChatMapper.updateById(entity);
+			}
+			List<String> memberEvent = List.of("del_member", "add_member");
+			if (memberEvent.contains(message.getUpdateDetail())) {
+				CorpGroupChat corpGroupChat = corpGroupChatMapper.selectOne(Wrappers.lambdaQuery(CorpGroupChat.class)
+						.eq(CorpGroupChat::getWxCorpId, wxCorpApp.getId())
+						.eq(CorpGroupChat::getChatId, detail.getChatId()).last("limit 1"));
+				if (corpGroupChat == null) {
+					log.info("企业微信客户群:{} 库中不存在", detail.getChatId());
+					return;
+				}
+				List<String> userList = corpGroupChatMemberMapper.getAllMemberByCorpIdAndChatId(corpGroupChat.getId());
+				if ("del_member".equals(message.getUpdateDetail())) {
+					log.info("客户退群{}事件", message.getChatId());
+					//存在库里面没有群成员
+					List<String> collect = detail.getMemberList().stream().map(CorpGroupChatMemberObj::getUserId).collect(Collectors.toList());
+					userList.removeAll(collect);
+					Lists.partition(userList, 100).stream().forEach(objs -> corpGroupChatMemberMapper.batchDeleteByChatIdAndUserId(corpGroupChat.getId(), objs));
+				}
+				if ("add_member".equals(message.getUpdateDetail())) {
+					log.info("客户入群{}事件", message.getChatId());
+					List<CorpGroupChatMemberObj> addCollect = detail.getMemberList().stream().filter(obj -> !userList.contains(obj.getUserId())).collect(Collectors.toList());
+					corpGroupSyncYhUserId(addCollect, wxCorpApp.getId(), corpGroupChat.getId());
+				}
+			}
+		});
+
+		return null;
+	}
+
+	public void corpGroupSyncYhUserId(List<CorpGroupChatMemberObj> memberList, Long wxCorpId, Long groupChatId) {
+		Lists.partition(memberList, 100).forEach(members -> {
+			List<String> corpUserIds = members.stream().map(CorpGroupChatMemberObj::getUserId).collect(Collectors.toList());
+			Map<String, List<CorpUserSearchView>> corpUserIdMap = beanSearcher.searchAll(CorpUserSearchView.class, MapUtils.builder()
+					.field(CorpUserSearchView::getWxCorpId, wxCorpId)
+					.field(CorpUserSearchView::getCorpUserId, corpUserIds).op(Operator.InList).build())
+					.stream().collect(Collectors.groupingBy(CorpUserSearchView::getCorpUserId));
+			members.forEach(data -> {
+				List<CorpUserSearchView> corpUserSearchViews = corpUserIdMap.get(data.getUserId());
+				Long yhUserId = null;
+				if (CollUtil.isNotEmpty(corpUserSearchViews)) {
+					yhUserId = corpUserSearchViews.get(0).getUserId();
+				}
+				if (yhUserId.intValue() == 0) {
+					yhUserId = corpUserMapper.selectUserIdByCropUserId(wxCorpId, data.getUserId());
+				}
+				data.setYhUserId(yhUserId);
+			});
+			corpGroupChatMemberMapper.batchInsert(groupChatId, wxCorpId, members);
+		});
+	}
+
+	@Override
+	public CorpXmlOutMessage delCorpGroupChat(CorpXmlMessage message) {
+		//删除企业客户群及关联关系
+		String corpId = message.getToUserName();
+		WxCorpApp wxCorpApp = wxCorpAppMapper.selectOne(Wrappers.lambdaQuery(WxCorpApp.class)
+				.eq(WxCorpApp::getCorpId, corpId).last("limit 1"));
+		if (wxCorpApp == null) {
+			log.error("企业客服群删除,企业微信配置:{}不存在", corpId);
+			return null;
+		}
+		corpGroupChatMapper.update(null, Wrappers.lambdaUpdate(CorpGroupChat.class)
+				.set(CorpGroupChat::getDeleted, false)
+				.eq(CorpGroupChat::getWxCorpId, wxCorpApp.getId())
+				.eq(CorpGroupChat::getChatId, message.getChatId()));
+
+		CorpGroupChat corpGroupChat = corpGroupChatMapper.selectOne(Wrappers.lambdaQuery(CorpGroupChat.class)
+				.eq(CorpGroupChat::getChatId, message.getChatId())
+				.eq(CorpGroupChat::getWxCorpId, wxCorpApp.getId()));
+		if (corpGroupChat != null) {
+			corpGroupChat.setDeleted(false);
+			corpGroupChatMapper.updateById(corpGroupChat);
+
+			corpGroupChatMemberMapper.update(null, Wrappers.lambdaUpdate(CorpGroupChatMember.class)
+					.set(CorpGroupChatMember::getDeleted, false)
+					.eq(CorpGroupChatMember::getGroupChatId, corpGroupChat.getId()));
+		}
+		return null;
+	}
+
 	/**
 	 * 修改客户成员关系,客户标签
 	 */

+ 16 - 0
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpGroupChatServiceImpl.java

@@ -0,0 +1,16 @@
+package com.cyksj.service.corp.impl;
+
+import com.cyksj.service.corp.CorpGroupChatService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: CorpGroupChatServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/8/8 11:46
+ */
+@Service
+@RequiredArgsConstructor
+public class CorpGroupChatServiceImpl implements CorpGroupChatService {
+}

+ 60 - 0
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpInteractiveRadarServiceImpl.java

@@ -0,0 +1,60 @@
+package com.cyksj.service.corp.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.common.util.StringUtil;
+import com.cyksj.mapper.corp.CorpInteractiveRadarMapper;
+import com.cyksj.model.entity.CorpInteractiveRadar;
+import com.cyksj.model.entity.CorpInteractiveReaderLink;
+import com.cyksj.service.corp.CorpInteractiveRadarService;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveRadarServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/8/4 17:34
+ */
+@Service
+public class CorpInteractiveRadarServiceImpl extends ServiceImpl<CorpInteractiveRadarMapper, CorpInteractiveRadar> implements CorpInteractiveRadarService {
+	private final static String RADAR_MARK = "radarId";
+
+	@Override
+	public void saveOrUpdateRadar(CorpInteractiveRadar radar) {
+		Integer type = radar.getType();
+		//企业微信类型
+		if (type == 1) {
+			CorpInteractiveReaderLink linkInfo = radar.getLinkInfo();
+			if (linkInfo == null) {
+				throw BusinessRuntimeException.getInstance("链接信息为空");
+			}
+			try {
+				if (ObjectUtil.hasEmpty(linkInfo.getTitle(), linkInfo.getDesc(), linkInfo.getImg())) {
+					throw BusinessRuntimeException.getInstance("请完善链接信息");
+				}
+				radar.setLinkInfoStr(Jsons.toJson(linkInfo));
+			} catch (Exception e) {
+				throw BusinessRuntimeException.getInstance("链接信息格式错误");
+			}
+		}
+		if (type == 2) {
+			radar.setLinkInfoStr(null);
+		}
+		if (radar.getWxCorpId() == null) {
+			radar.setWxCorpId(2);
+		}
+		this.saveOrUpdate(radar);
+		String url = radar.getUrl();
+		if (!url.contains(RADAR_MARK)) {
+			String connect = StringUtil.QM;
+			if (url.contains(StringUtil.QM)) {
+				connect = StringUtil.AD;
+			}
+			url = String.format("%s%s%s", url, connect, RADAR_MARK + "=" + radar.getId());
+			radar.setUrl(url);
+			this.updateById(radar);
+		}
+	}
+}

+ 79 - 0
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpInteractiveReaderFrontServiceImpl.java

@@ -0,0 +1,79 @@
+package com.cyksj.service.corp.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.mapper.corp.*;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.request.corp.message.TextCard;
+import com.cyksj.model.request.corp.message.WxCorpAgentMessage;
+import com.cyksj.service.corp.CorpInteractiveReaderFrontService;
+import com.cyksj.service.corp.WxCorpOps;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/*
+ *项目名: netflix
+ *文件名: CorpInteractiveReaderFrontServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/8/4 18:22
+ */
+@Service
+@RequiredArgsConstructor
+public class CorpInteractiveReaderFrontServiceImpl implements CorpInteractiveReaderFrontService {
+	private final CorpInteractiveRadarMapper corpInteractiveRadarMapper;
+
+	private final CorpInteractiveRadarUserRecordMapper corpInteractiveRadarUserRecordMapper;
+
+	private final WxCorpAppMapper wxCorpAppMapper;
+
+	private final CorpUserMapper corpUserMapper;
+
+	private final CorpUserAuthMapper corpUserAuthMapper;
+
+	private final CorpUserFollowRelationMapper corpUserFollowRelationMapper;
+
+	private final WxCorpOps wxCorpOps;
+
+	@Override
+	public void clickReader(Long userId, Long radarId) throws Exception {
+		CorpInteractiveRadar radar = corpInteractiveRadarMapper.selectById(radarId);
+		if (radar == null) return;
+		CorpInteractiveRadarUserRecord corpInteractiveRadarUserRecord = new CorpInteractiveRadarUserRecord();
+		corpInteractiveRadarUserRecord.setUserId(userId);
+		corpInteractiveRadarUserRecord.setRadarId(radarId);
+		Integer type = radar.getType();
+		if (type == 1) {
+			//给企业微信客服发送消息
+			WxCorpApp wxCorpApp = wxCorpAppMapper.selectById(radar.getWxCorpId());
+			CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class).eq(CorpUser::getUserId, userId));
+			if (corpUser != null) {
+				//记录点击
+				corpInteractiveRadarUserRecord.setCorpUserId(corpUser.getId());
+				CorpUserAuth corpUserAuth = corpUserAuthMapper.selectOne(Wrappers.lambdaQuery(CorpUserAuth.class)
+						.eq(CorpUserAuth::getWxCorpId, wxCorpApp.getId())
+						.eq(CorpUserAuth::getCorpUserId, corpUser.getId())
+						.last(" limit 1"));
+				String externalUserid = corpUserAuth.getExternalUserid();
+				List<CorpUserFollowRelation> corpUserFollowRelations = corpUserFollowRelationMapper.selectList(Wrappers.lambdaQuery(CorpUserFollowRelation.class).eq(CorpUserFollowRelation::getCorpUserId, externalUserid));
+
+				String msg = "【%s】打开了雷达链接【%s】<div class='highlight'>客户昵称:%s</div>";
+				//发送卡片消息
+				WxCorpAgentMessage agentMessage = new WxCorpAgentMessage();
+				agentMessage.setAgentid(Integer.valueOf(wxCorpApp.getAgentId()));
+				agentMessage.setTouser(corpUserFollowRelations.stream().map(CorpUserFollowRelation::getFollowId).collect(Collectors.joining("|")));
+				agentMessage.setMsgtype("textcard");
+				TextCard textCard = new TextCard();
+				textCard.setTitle("雷达链接");
+				textCard.setUrl(radar.getUrl());
+				textCard.setDescription(String.format(msg, corpUser.getName(), radar.getTitle(), corpUser.getName()));
+				textCard.setBtnTxt("点击查看链接");
+				agentMessage.setTextcard(textCard);
+				//发送卡片消息
+				wxCorpOps.sendAgentMessage(wxCorpApp.getCorpId(), agentMessage);
+			}
+		}
+		corpInteractiveRadarUserRecordMapper.insert(corpInteractiveRadarUserRecord);
+	}
+}

+ 0 - 5
netflix-service/src/main/java/com/cyksj/service/corp/impl/CropChatServiceImpl.java

@@ -40,11 +40,6 @@ public class CropChatServiceImpl implements CropChatService {
 		wxCorpOps.getCorpChatGroups(corpId,configId);
 	}
 
-	@Override
-	public String getGroupsList() throws Exception {
-		return wxCorpOps.getGroupsList();
-	}
-
 	@Override
 	public void setGroupsConfig(List<String> chatIds) throws Exception {
 		String body = wxCorpOps.setGroupsConfig(chatIds);

+ 62 - 20
netflix-service/src/main/java/com/cyksj/service/corp/impl/WxCorpOpsImpl.java

@@ -18,6 +18,8 @@ import com.cyksj.model.entity.WxCorpApp;
 import com.cyksj.model.request.corp.CorpFollowContact;
 import com.cyksj.model.request.corp.CorpGroupConfig;
 import com.cyksj.model.request.corp.CorpMsgTemplate;
+import com.cyksj.model.request.corp.CorpXmlMessage;
+import com.cyksj.model.request.corp.message.WxCorpAgentMessage;
 import com.cyksj.model.response.OffiaccountJsTicket;
 import com.cyksj.model.response.UserExternalContactList;
 import com.cyksj.model.response.UserWithExternalPermission;
@@ -228,26 +230,6 @@ public class WxCorpOpsImpl implements WxCorpOps {
 		return qr_code;
 	}
 
-	@Override
-	public String getGroupsList() throws Exception {
-		String corpId = yhlXWxCorpConfig.getCorpId();
-		String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=" + getAccessToken(corpId);
-		JSONObject jsonObject = new JSONObject();
-		jsonObject.putOpt("limit", 1000);
-		HttpResponse<byte[]> res =
-				J11HttpC.custom()
-						.ofPost()
-						.url(url)
-						.cacheURI()
-						.body(HttpRequest.BodyPublishers.ofString(jsonObject.toString(), IoKit.Charsets.UTF_8.getCharset()))
-						.send(HttpResponse.BodyHandlers.ofByteArray());
-		String body = IoKit.toString(res.body());
-		if (200 != res.statusCode()) {
-			throw BusinessRuntimeException.getInstance("获取access_token失败: " + IoKit.toString(res.body()));
-		}
-		return body;
-	}
-
 	@Override
 	public String setGroupsConfig(List<String> chatIds) throws Exception {
 		String corpId = yhlXWxCorpConfig.getCorpId();
@@ -332,6 +314,66 @@ public class WxCorpOpsImpl implements WxCorpOps {
 		}
 	}
 
+	@Override
+	public void sendAgentMessage(String corpId, WxCorpAgentMessage agentMessage) throws Exception {
+		String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + getAccessToken(corpId);
+
+		HttpResponse<String> res =
+				J11HttpC.custom()
+						.ofPost()
+						.url(url)
+						.headers(J11HttpC.ReqType.raw_json)
+						.body(HttpRequest.BodyPublishers.ofString(Jsons.toJson(agentMessage), IoKit.Charsets.UTF_8.getCharset()))
+						.send(HttpResponse.BodyHandlers.ofString());
+		if (200 != res.statusCode()) {
+			throw BusinessRuntimeException.getInstance("发送应用消息: " + res.body());
+		}
+
+		JSONObject response = Jsons.parseObject(res.body(), JSONObject.class);
+		if (response.getInt("errcode") != 0) {
+			throw BusinessRuntimeException.getInstance("发送应用消息: " + response.getStr("errmsg"));
+		}
+	}
+
+	@Override
+	public CorpGroupChatListDetail getGroupChatList(String corpId, String cursor, Integer limit) throws Exception {
+		String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=%s", getAccessToken(corpId));
+		JSONObject params = new JSONObject();
+		params.putOpt("cursor", cursor);
+		params.putOpt("limit", limit);
+		HttpResponse<String> response = J11HttpC.custom()
+				.ofPost()
+				.headers(J11HttpC.ReqType.raw_json)
+				.body(HttpRequest.BodyPublishers.ofString(params.toString(), IoKit.Charsets.UTF_8.getCharset()))
+				.url(url)
+				.send(HttpResponse.BodyHandlers.ofString());
+		CorpGroupChatListDetail chatListDetail = Jsons.parseObject(response.body(), CorpGroupChatListDetail.class);
+		if (response.statusCode() != 200 || chatListDetail.getErrcode() != 0) {
+			throw BusinessRuntimeException.getInstance("企业微信获取客户群列表错误:" + chatListDetail.getErrmsg());
+		}
+		return chatListDetail;
+	}
+
+	@Override
+	public CorpGroupChatDetail getCorpGroupChatDetail(String corpId, CorpXmlMessage message) throws Exception {
+		String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=%s", getAccessToken(corpId));
+		JSONObject params = new JSONObject();
+		params.putOpt("chat_id", message.getChatId());
+		//是否需要返回群成员的名字group_chat.member_list.name。0-不返回;1-返回。默认不返回
+		params.putOpt("need_name", 1);
+		HttpResponse<String> response = J11HttpC.custom()
+				.ofPost()
+				.headers(J11HttpC.ReqType.raw_json)
+				.body(HttpRequest.BodyPublishers.ofString(params.toString(), IoKit.Charsets.UTF_8.getCharset()))
+				.url(url)
+				.send(HttpResponse.BodyHandlers.ofString());
+		JSONObject jsonObject = Jsons.parseObject(response.body(), JSONObject.class);
+		if (response.statusCode() != 200 || jsonObject.getInt("errcode") != 0) {
+			throw BusinessRuntimeException.getInstance("企业微信获取客户群详情错误:" + jsonObject.get("errmsg"));
+		}
+		return Jsons.parseObject(jsonObject.get("group_chat"), CorpGroupChatDetail.class);
+	}
+
 	@Override
 	public CorpUserExternalTagGroupInfo addCorpTag(CorpUserExternalTagGroupInfo tagGroup, String corpId) throws Exception {
 		corpId = Optional.ofNullable(corpId).orElse(yhlXWxCorpConfig.getCorpId());

+ 6 - 0
netflix-service/src/main/java/com/cyksj/service/corp/msg/CorpEventActionService.java

@@ -23,4 +23,10 @@ public interface CorpEventActionService {
 	CorpXmlOutMessage saveCorpTag(CorpXmlMessage message, Map<String, Object> context) throws Exception;
 
 	CorpXmlOutMessage delCorpTag(CorpXmlMessage message, Map<String, Object> context);
+
+	CorpXmlOutMessage saveCorpGroupChat(CorpXmlMessage message, Map<String, Object> context) throws Exception;
+
+	CorpXmlOutMessage updateCorpGroupChat(CorpXmlMessage message, Map<String, Object> context) throws Exception;
+
+	CorpXmlOutMessage delCorpGroupChat(CorpXmlMessage message);
 }

+ 34 - 44
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpChatController.java

@@ -1,14 +1,21 @@
 package com.cyksj.web.controller.manage.corp;
 
+import cn.hutool.core.util.StrUtil;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.model.request.corp.CorpGroupConfig;
-import com.cyksj.service.corp.CropChatService;
+import com.cyksj.model.views.CorpGroupChatDetailView;
+import com.cyksj.model.views.CorpGroupChatView;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapBuilder;
+import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
+import javax.servlet.http.HttpServletRequest;
 
 /*
  *项目名: netflix
@@ -17,57 +24,40 @@ import java.util.List;
  *创建时间:2023/6/26 16:24
  */
 @RestController
-@RequestMapping("/manage/corpChat")
+@RequestMapping("/manage/corp/group/chat")
 @RequiredArgsConstructor
 public class CorpChatController {
-	private final CropChatService cropChatService;
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
 
 	/**
 	 * 客户群列表
 	 */
-	@GetMapping("/get/groups/list")
-	public Result<String> getGroupsList() throws Exception {
-		String body = cropChatService.getGroupsList();
-		return GatewayResponse.SUCCESS.newBuilder().toResult(body);
+	@GetMapping("/get")
+	public Result<SearchResult<CorpGroupChatView>> getGroupsChatList() {
+		SearchResult<CorpGroupChatView> search = beanSearcher.search(CorpGroupChatView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
 
 	/**
 	 * 客户群详情
 	 */
-	@GetMapping("/get/groups/detail")
-	public Result<String> getGroupsDetail(String chatId) throws Exception {
-		String body = cropChatService.getGroupsDetail(chatId);
-		return GatewayResponse.SUCCESS.newBuilder().toResult(body);
-	}
-
-	/**
-	 * 客户群配置列表
-	 */
-	@GetMapping("/get/config/list")
-	public Result<String> getCorpChat(String corpId,String configId) throws Exception {
-		cropChatService.getCorpChat(corpId, configId);
-		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	@GetMapping("/get/detail/{id}")
+	public Result<SearchResult<CorpGroupChatDetailView>> getGroupsDetail(@PathVariable Long id, Long goodsId, Boolean exists) {
+		String condition = StrUtil.EMPTY;
+		if (goodsId != null) {
+			String connect = (exists == null || exists) ? "in" : "not in";
+			condition += String.format("user_id %s (select gr.user_id from (select gt.id from groups_trips gt inner join goods_don_sku sku on sku.id = gt.sku_id and goods_id = %s) s inner join groups_relation gr on gr.groups_id = s.id)", connect, goodsId);
+		}
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap())
+				.field(CorpGroupChatDetailView::getGroupChatId, id);
+		if (StrUtil.isNotBlank(condition)) {
+			builder.put("condition", condition);
+		}
+		SearchResult<CorpGroupChatDetailView> search = beanSearcher.search(CorpGroupChatDetailView.class, builder.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
-
-
-	/**
-	 * 配置客户群
-	 */
-	@PostMapping("/set/group")
-	public Result<String> setGroupsConfig(@RequestBody List<String> chatIds) throws Exception {
-		cropChatService.setGroupsConfig(chatIds);
-		return GatewayResponse.SUCCESS.newBuilder().toResult();
-	}
-
-	/**
-	 * 更新配置客户群
-	 */
-	@PutMapping("/put/groups")
-	public Result<String> updateGroupsConfig(@RequestBody @Validated CorpGroupConfig config) throws Exception {
-		cropChatService.updateGroupsConfig(config);
-		return GatewayResponse.SUCCESS.newBuilder().toResult();
-	}
-
 }
 
 

+ 124 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/CorpInteractiveRadarController.java

@@ -0,0 +1,124 @@
+package com.cyksj.web.controller.manage.corp;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.CorpInteractiveRadar;
+import com.cyksj.model.entity.CorpInteractiveRadarUserRecord;
+import com.cyksj.model.entity.CorpInteractiveReaderLink;
+import com.cyksj.model.views.CorpInteractiveRadarOrderDataView;
+import com.cyksj.model.views.CorpInteractiveReaderOrderDetailView;
+import com.cyksj.model.views.CorpInteractiveReaderView;
+import com.cyksj.service.corp.CorpInteractiveRadarService;
+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
+ *文件名: CorpInteractiveRadarController
+ *创建者: JavaZou
+ *创建时间:2023/8/4 16:27
+ */
+@RestController
+@RequestMapping("/manage/corp/interactive/reader")
+@RequiredArgsConstructor
+public class CorpInteractiveRadarController {
+	private final CorpInteractiveRadarService corpInteractiveRadarService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	/**
+	 * 新增互动雷达
+	 */
+	@PostMapping
+	public Result<String> saveInteractiveReader(@RequestBody @Validated CorpInteractiveRadar radar) {
+		corpInteractiveRadarService.saveOrUpdateRadar(radar);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 编辑互动雷达
+	 */
+	@PutMapping
+	public Result<String> updateInteractiveReader(@RequestBody @Validated CorpInteractiveRadar radar) {
+		if (radar.getId() == null || corpInteractiveRadarService.getById(radar.getId()) == null) {
+			throw BusinessRuntimeException.getInstance("雷达链接不存在");
+		}
+		corpInteractiveRadarService.saveOrUpdateRadar(radar);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除互动雷达
+	 */
+	@DeleteMapping("/{id}")
+	public Result<String> deleteById(@PathVariable Long id) {
+		corpInteractiveRadarService.removeById(id);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 互动雷达列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<CorpInteractiveReaderView>> get() {
+		SearchResult<CorpInteractiveReaderView> search = beanSearcher.search(CorpInteractiveReaderView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		search.getDataList().forEach(data -> {
+			if (data.getType() == 1) {
+				String linkInfoStr = data.getLinkInfoStr();
+				try {
+					CorpInteractiveReaderLink linkInfo = Jsons.parseObject(linkInfoStr, CorpInteractiveReaderLink.class);
+					data.setLinkInfo(linkInfo);
+				} catch (Exception e) {
+				}
+				data.setClickNum(beanSearcher.searchCount(CorpInteractiveRadarUserRecord.class, MapUtils.builder()
+						.field(CorpInteractiveRadarUserRecord::getRadarId, data.getId()).build()).intValue());
+
+				CorpInteractiveReaderOrderDetailView detailView = beanSearcher.searchFirst(CorpInteractiveReaderOrderDetailView.class, MapUtils.builder().put("id", String.format("id = %s", data.getId())).build());
+				data.setPayNum(detailView.getTotal());
+				data.setPayNewUserNum(detailView.getNumOfNewUser());
+				data.setPayOldUserNum(detailView.getNumOfOldUser());
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 购买人数详情
+	 */
+	@GetMapping("/get/payNum/detail/{id}")
+	public Result<CorpInteractiveReaderOrderDetailView> getPayNumDetailById(@PathVariable Long id) {
+		CorpInteractiveReaderOrderDetailView detailView = beanSearcher.searchFirst(CorpInteractiveReaderOrderDetailView.class, MapUtils.builder().put("id", String.format("id = %s", id)).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(detailView);
+	}
+
+
+	/**
+	 * 雷达数据
+	 */
+	@GetMapping("/get/data/{id}")
+	public Result<CorpInteractiveRadarOrderDataView> corpInteractiveRadarOrderDataViewResult(@PathVariable Long id) {
+		CorpInteractiveRadarOrderDataView view = new CorpInteractiveRadarOrderDataView();
+		DateTime beginOfDay = DateUtil.beginOfDay(DateTime.now());
+		String idEq = String.format(" cr.id = %s", id);
+		String conditionSql = String.format(" %s and cr.created_time >= '%s'", idEq, beginOfDay.toString());
+		CorpInteractiveRadarOrderDataView.CorpInteractiveRadarOrderData today = beanSearcher.searchFirst(CorpInteractiveRadarOrderDataView.CorpInteractiveRadarOrderData.class, MapUtils.builder().put("condition", conditionSql).build());
+
+		CorpInteractiveRadarOrderDataView.CorpInteractiveRadarOrderData history = beanSearcher.searchFirst(CorpInteractiveRadarOrderDataView.CorpInteractiveRadarOrderData.class, MapUtils.builder().put("condition", idEq).build());
+
+		view.setToday(today);
+		view.setHistory(history);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(view);
+	}
+}

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

@@ -16,6 +16,7 @@ import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.*;
 import com.cyksj.model.response.UserAuthLoginResp;
 import com.cyksj.model.views.*;
+import com.cyksj.service.corp.CorpInteractiveReaderFrontService;
 import com.cyksj.service.corp.CropChatService;
 import com.cyksj.service.exchange.ExchangeCodeService;
 import com.cyksj.service.order.UserRealOrderBenefitsService;
@@ -69,6 +70,8 @@ public class UserController {
 
     private final YhShopFrontService yhShopFrontService;
 
+    private final CorpInteractiveReaderFrontService corpInteractiveReaderFrontService;
+
     @GetMapping(value = "/wx/whoami")
     public Result<UserWhoami> whoami() {
         long userId = StpUserUtil.getLoginIdAsLong();
@@ -404,4 +407,15 @@ public class UserController {
         userService.receiveGiftCardByRc(userId, req.getCode(), relationId);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+    /**
+     * 点击雷达链接
+     */
+    @PostMapping("/click/reader/{radarId}")
+    public Result<String> clickInteractiveReader(@PathVariable Long radarId) throws Exception {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        corpInteractiveReaderFrontService.clickReader(userId, radarId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
 }