Browse Source

Merge branch 'back_user_info_detail'

zoujiajian 3 năm trước cách đây
mục cha
commit
e94b645931
17 tập tin đã thay đổi với 425 bổ sung66 xóa
  1. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/corp/CorpUserFollowRelationMapper.java
  2. 6 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeSharedMapper.java
  3. 34 0
      netflix-dao/src/main/java/com/cyksj/model/dto/UserDistributeDto.java
  4. 27 0
      netflix-dao/src/main/java/com/cyksj/model/entity/User.java
  5. 73 23
      netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java
  6. 2 0
      netflix-dao/src/main/java/com/cyksj/model/request/LoginPhoneReq.java
  7. 7 3
      netflix-dao/src/main/java/com/cyksj/model/views/CorpUserFollowView.java
  8. 31 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessInfoView.java
  9. 53 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserOrderDonDetail.java
  10. 13 0
      netflix-dao/src/main/resources/mapper/CorpUserFollowRelationMapper.xml
  11. 3 3
      netflix-dao/src/main/resources/mapper/OrderDonMapper.xml
  12. 11 7
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  13. 1 1
      netflix-service/src/main/java/com/cyksj/service/user/UserService.java
  14. 9 5
      netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java
  15. 127 19
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java
  16. 11 5
      netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java
  17. 15 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

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

@@ -8,4 +8,6 @@ import com.cyksj.model.entity.CorpUserFollowRelation;
  * @date 2022/3/15 上午9:49
  */
 public interface CorpUserFollowRelationMapper extends BaseMapper<CorpUserFollowRelation> {
+
+	String selectCorpCustomers(String unionid);
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/UserDistributeSharedMapper.java

@@ -1,7 +1,9 @@
 package com.cyksj.mapper.manage.distribute;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.dto.UserDistributeDto;
 import com.cyksj.model.entity.UserDistributeShared;
+import org.apache.ibatis.annotations.Select;
 
 /*
  *项目名: netflix
@@ -10,4 +12,8 @@ import com.cyksj.model.entity.UserDistributeShared;
  *创建时间:2022/11/15 11:51
  */
 public interface UserDistributeSharedMapper extends BaseMapper<UserDistributeShared> {
+	@Select("select ud.*,u.nickname,(select count(*) from user_distribute_shared where shared_id = ud.user_id) as inviteCount" +
+			" from (select user_id,business_id from user_distribute) ud inner join user_distribute_shared us on us.shared_id = ud.user_id and us.user_id = #{userId}" +
+			" inner join user u on u.id = ud.user_id")
+	UserDistributeDto selectUserDistributeDtoByUserId(Long userId);
 }

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/UserDistributeDto.java

@@ -0,0 +1,34 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeDto
+ *创建者: JavaZou
+ *创建时间:2023/4/26 13:43
+ */
+@Getter
+@Setter
+public class UserDistributeDto {
+	/**
+	 * 推广者用户id
+	 */
+	private Long userId;
+
+	/**
+	 * 推广者用户昵称
+	 */
+	private String nickname;
+
+	/**
+	 * 商务用户id
+	 */
+	private Long businessId;
+
+	/**
+	 * 分销人数
+	 */
+	private Integer inviteCount;
+}

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

@@ -6,6 +6,7 @@ import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * @author chan
@@ -61,5 +62,31 @@ public class User extends BaseEntity implements Serializable{
      * 用户是否被拉黑 true是
      */
     private Boolean isBlack;
+
+    /**
+     * 注册环境
+     * h5:移动端浏览器登录
+     * 微信:公众号h5授权登录
+     * pc:浏览器登录,包括微信扫码在浏览器登录
+     */
+    private String registerEnv;
+
+    /**
+     * 最后登录时间
+     */
+    private Date lastTime;
+
+    @Getter
+    public enum RegisterEnv{
+        wx("公众号h5授权登录"),
+        h5("移动端浏览器登录"),
+        pc("浏览器登录,包括微信扫码在浏览器登录"),
+        ;
+        String desc;
+
+        RegisterEnv(String desc) {
+            this.desc = desc;
+        }
+    }
 }
 

+ 73 - 23
netflix-dao/src/main/java/com/cyksj/model/manage/views/UserView.java

@@ -15,10 +15,8 @@ import java.util.Date;
  */
 @Getter
 @Setter
-@SearchBean(tables = "user u left join user_bind_detail up on up.user_id = u.id" +
-        " left join channel_popularize cp on cp.id = u.popularize_id" +
-        " left join channel c on c.id = cp.channel_id",
-where = ":otherPhone:")
+@SearchBean(tables = "user u left join user_distribute_shared us on us.user_id = u.id"
+		, where = ":otherConditionSql:")
 public class UserView {
 
     /**
@@ -42,13 +40,13 @@ public class UserView {
     /**
      * 绑定手机号
      */
-    @DbField("up.phone")
+    @DbIgnore
     private String bindPhone;
 
     /**
      * 绑定邮箱
      */
-    @DbField("up.email")
+    @DbIgnore
     private String bindEmail;
 
     /**
@@ -57,12 +55,6 @@ public class UserView {
     @DbField("u.headimgurl")
     private String headimgurl;
 
-    /**
-     *  收款码
-     */
-    @DbField("u.img")
-    private String img;
-
     /**
      * 积分
      */
@@ -90,6 +82,12 @@ public class UserView {
     @DbField("u.active_points")
     private BigDecimal activePoints;
 
+    @DbField("u.register_env")
+    private String registerEnv;
+
+    @DbField("u.last_time")
+    private Date lastTime;
+
     /**
      * 账户数
      */
@@ -99,33 +97,85 @@ public class UserView {
     /**
      * 邀请人id
      */
-    @DbIgnore
+    @DbField("us.shared_id")
     private Long sharedId;
 
     /**
-     * 渠道来源
+     * 邀请人名称
      */
-    @DbField("c.name")
-    private String channelName;
+    @DbIgnore
+    private String distributeName;
+
+    @DbIgnore
+    private String businessName;
+
+    @DbIgnore
+    private Integer inviteCount;
 
     /**
-     * 创建时间
+     * 渠道来源
      */
-    @DbField("u.created_time")
-    private Date createdTime;
+    @DbIgnore
+    private String channelName;
 
     @DbField("u.is_black")
     private Boolean isBlack;
 
+    @DbField("u.unionid")
+    private String unionid;
+
     /**
-     * 邀请人名称
+     * 企业微信客服
+     */
+    @DbIgnore
+    private String corpCustomers;
+
+    /**
+     * 首单信息
+     */
+    @DbIgnore
+    private String firstOrderDetail;
+
+    /**
+     * 有无路由器订单
+     */
+    @DbIgnore
+    private Boolean isHadRouteOrder;
+
+
+    /**
+     * 订单金额
+     */
+    @DbIgnore
+    private BigDecimal orderMoney;
+
+    /**
+     * 订单数
      */
     @DbIgnore
-    private String sharedNickName;
+    private Integer numOfOrder;
 
     /**
-     * 邀请人头像
+     * 退款金额
      */
     @DbIgnore
-    private String sharedHeadimgurl;
+    private BigDecimal refundMoney;
+
+    /**
+     * 退款率
+     */
+    @DbIgnore
+    private BigDecimal refundRate;
+
+    /**
+     * 创建时间
+     */
+    @DbField("u.created_time")
+    private Date createdTime;
+
+    /**
+     * 最后更新时间
+     */
+    @DbField("u.update_time")
+    private Date updateTime;
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/request/LoginPhoneReq.java

@@ -43,4 +43,6 @@ public class LoginPhoneReq {
 	 * 推广id
 	 */
 	private Long popularizeId;
+
+	private String registerEnv;
 }

+ 7 - 3
netflix-dao/src/main/java/com/cyksj/model/views/CorpUserFollowView.java

@@ -11,11 +11,12 @@ import lombok.Setter;
  *创建者: JavaZou
  *创建时间:2023/3/3 10:59
  */
-@SearchBean(tables = "corp_user cu left join corp_user_auth ca on ca.corp_user_id = cu.id" +
-		" left join corp_user_follow_relation cr on cr.corp_user_id = ca.external_userid" +
-		" and cr.wx_corp_id = ca.wx_corp_id")
 @Getter
 @Setter
+@SearchBean(tables = "corp_user cu left join corp_user_auth ca on ca.corp_user_id = cu.id" +
+		" left join corp_user_follow_relation cr on cr.corp_user_id = ca.external_userid" +
+		" and cr.wx_corp_id = ca.wx_corp_id",
+		where = "ca.wx_corp_id = 2")
 public class CorpUserFollowView {
 
 	@DbField("cu.id")
@@ -26,4 +27,7 @@ public class CorpUserFollowView {
 
 	@DbField("cr.follow_id")
 	private String followId;
+
+	@DbField("cr.status")
+	private Integer status;
 }

+ 31 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserDistributeBusinessInfoView.java

@@ -0,0 +1,31 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: UserDistributeBusinessInfoView
+ *创建者: JavaZou
+ *创建时间:2023/5/8 12:02
+ */
+@Getter
+@Setter
+@SearchBean(tables = "user_distribute ud left join cms_user cu on cu.id = ud.business_id" +
+		" inner join user u on u.id = ud.user_id",
+		where = "ud.deleted is true")
+public class UserDistributeBusinessInfoView {
+	@DbField("ud.user_id")
+	private Long userId;
+
+	@DbField("ud.business_id")
+	private Long businessId;
+
+	@DbField("u.nickname")
+	private String distributeName;
+
+	@DbField("cu.nickname")
+	private String businessName;
+}

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserOrderDonDetail.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.views;
+
+import com.cyksj.model.entity.OrderDon;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: UserOrderDonDetail
+ *创建者: JavaZou
+ *创建时间:2023/4/27 12:06
+ */
+@Getter
+@Setter
+@SearchBean(tables = "order_don od left join goods_don g on g.id = od.goods_id" +
+		" left join goods_don_sku gdk on gdk.id = od.sku_id")
+public class UserOrderDonDetail {
+	@DbField("od.id")
+	private Long orderId;
+
+	@DbField("od.user_id")
+	private Long userId;
+
+	@DbField("od.sku_id")
+	private Long skuId;
+
+	@DbField("gdk.spec_val")
+	private String specVal;
+
+	@DbField("od.goods_id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("od.money")
+	private BigDecimal money;
+
+	@DbField("od.status")
+	private OrderDon.Status status;
+
+	@DbField("od.pay_time")
+	private Date payTime;
+
+	@DbField("od.created_time")
+	private Date createdTime;
+
+}

+ 13 - 0
netflix-dao/src/main/resources/mapper/CorpUserFollowRelationMapper.xml

@@ -0,0 +1,13 @@
+<?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.CorpUserFollowRelationMapper">
+
+    <select id="selectCorpCustomers" resultType="java.lang.String">
+        select group_concat(cf.name) from (select id from corp_user
+        where unionid = #{unionid}) cu
+        inner join corp_user_auth ca on ca.corp_user_id = cu.id and wx_corp_id = 2
+        inner join corp_user_follow_relation cfr on cfr.corp_user_id = ca.external_userid
+        inner join corp_follow cf on cf.userid = cfr.follow_id and cf.wx_corp_id = 2
+    </select>
+</mapper>

+ 3 - 3
netflix-dao/src/main/resources/mapper/OrderDonMapper.xml

@@ -95,7 +95,7 @@
             and curdate >= #{first}
         </if>
         <if test="end != null">
-            and curdate &lt;= #{end}
+            and curdate &lt; #{end}
         </if>
     </select>
 
@@ -115,7 +115,7 @@
             and curdate >= #{first}
         </if>
         <if test="end != null">
-            and curdate &lt;= #{end}
+            and curdate &lt; #{end}
         </if>
     </select>
 
@@ -131,7 +131,7 @@
             and curdate >= #{first}
         </if>
         <if test="end != null">
-            and curdate &lt;= #{end}
+            and curdate &lt; #{end}
         </if>
     </select>
 

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

@@ -10,6 +10,7 @@ import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.UserMapper;
 import com.cyksj.mapper.corp.CorpUserMapper;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.views.CorpUserFollowView;
 import com.cyksj.model.views.GoodsDonViews;
 import com.cyksj.model.views.RenewalView;
 import com.cyksj.service.mange.coupon.CouponCommonService;
@@ -91,13 +92,16 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			if (user == null || StrUtil.isEmpty(user.getUnionid())) {
 				return true;
 			}
-			CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class)
-					.ne(CorpUser::getUnionid, "")
-					.eq(CorpUser::getUnionid, user.getUnionid())
-					.last("limit 1")
-					.select(CorpUser::getId)
-			);
-			if (corpUser == null) {
+//			CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class)
+//					.ne(CorpUser::getUnionid, "")
+//					.eq(CorpUser::getUnionid, user.getUnionid())
+//					.last("limit 1")
+//					.select(CorpUser::getId)
+//			);
+			CorpUserFollowView corpUserFollowView = beanSearcher.searchFirst(CorpUserFollowView.class, MapUtils.builder()
+					.field(CorpUserFollowView::getUnionId, user.getUnionid())
+					.field(CorpUserFollowView::getStatus, 1).build());
+			if (corpUserFollowView == null) {
 				return false;
 			}
 		}

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

@@ -14,7 +14,7 @@ import java.util.List;
  */
 public interface UserService extends IService<User> {
 
-    User saveAuth(GzhOAuth2UserInfo userinfo, Long sharedId, Integer dsType, Long pid);
+    User saveAuth(GzhOAuth2UserInfo userinfo, Long sharedId, Integer dsType, Long pid, User.RegisterEnv registerEnv);
 
     UserWhoami whoami(long userId);
 

+ 9 - 5
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -67,11 +67,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
 	@Override
-    public User saveAuth(GzhOAuth2UserInfo info, Long sharedId, Integer dsType, Long pid) {
-        final String unionid = info.getUnionid();
-        if (StrUtil.isEmpty(unionid)) {
-            throw BusinessRuntimeException.getInstance("授权操作异常,请刷新页面");
-        }
+	public User saveAuth(GzhOAuth2UserInfo info, Long sharedId, Integer dsType, Long pid, User.RegisterEnv registerEnv) {
+		final String unionid = info.getUnionid();
+		if (StrUtil.isEmpty(unionid)) {
+			throw BusinessRuntimeException.getInstance("授权操作异常,请刷新页面");
+		}
 
 		User user = getSyncUser(info.getOpenid(), info.getUnionid(), null);
 
@@ -93,12 +93,16 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 		if (user.getId() == null) {
 			isNewUser = true;
 			user.setPopularizeId(pid);
+			user.setRegisterEnv(registerEnv.name());
 			if (!redisService.setNx(RedisService.key.REPEAT_USER_KEY.getNameFormat(user.getUnionid()), user.getUnionid(), RedisService.key.REPEAT_USER_KEY.getTimeout())) {
 				return this.getOne(Wrappers.lambdaQuery(User.class)
 						.eq(User::getUnionid, unionid).last("limit 1"));
 			}
 			this.save(user);
 		} else {
+			if (StrUtil.isEmpty(user.getRegisterEnv())) {
+				user.setRegisterEnv(registerEnv.name());
+			}
 			this.updateById(user);
 		}
 		if (sharedId != null && isNewUser) {

+ 127 - 19
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsUserController.java

@@ -3,18 +3,24 @@ package com.cyksj.web.controller.manage;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.mapper.OrderDonMapper;
 import com.cyksj.mapper.UserMapper;
-import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
+import com.cyksj.mapper.corp.CorpUserFollowRelationMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.UserView;
+import com.cyksj.model.views.GoodsDonSkuView;
 import com.cyksj.model.views.RenewalView;
+import com.cyksj.model.views.UserDistributeBusinessInfoView;
+import com.cyksj.model.views.UserOrderDonDetail;
 import com.cyksj.service.relation.GroupRelationClearService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.param.Operator;
 import com.ejlchina.searcher.util.MapBuilder;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
@@ -22,6 +28,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.List;
 import java.util.Optional;
 
@@ -49,36 +57,46 @@ public class CmsUserController{
 
     private final GroupRelationFrontService groupRelationFrontService;
 
-    private final UserDistributeSharedMapper userDistributeSharedMapper;
+    private final CorpUserFollowRelationMapper cmsUserFollowRelationMapper;
 
+    private final OrderDonMapper orderDonMapper;
 
     @GetMapping("/get")
     @SaCheckPermission("user:view")
-    public Result<SearchResult<UserView>> get(String otherPhone) {
+    public Result<SearchResult<UserView>> get(String otherPhone, Long sharedId, String userid, Long businessId, String sort, String order) {
         MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+        String otherSql = StrUtil.EMPTY;
         if (StrUtil.isNotBlank(otherPhone)) {
-            builder.put("otherPhone", String.format("(up.phone like '%s%%' or u.login_phone like '%s%%')", otherPhone, otherPhone));
+            otherSql += String.format("(u.id in (select user_id from user_bind_detail where phone like '%s%%') or u.login_phone like '%s%%')", otherPhone, otherPhone);
+        }
+        if (businessId != null) {
+            if (StrUtil.isNotBlank(otherSql)) {
+                otherSql += " and ";
+            }
+            otherSql += String.format("us.shared_id in (select user_id from user_distribute where business_id = %s)", businessId);
+        }
+        if (StrUtil.isNotBlank(otherSql)) {
+            builder.put("otherConditionSql", otherSql);
         }
         SearchResult<UserView> search = beanSearcher.search(UserView.class, builder.build());
-        search.getDataList().forEach((userView)->{
-            userView.setAccountNum(relationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getUserId,userView.getId())));
-            UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
-                    .eq(UserDistributeShared::getUserId, userView.getId()).last("limit 1"));
-            if (userDistributeShared != null) {
-                userView.setSharedId(userDistributeShared.getSharedId());
-                if (userView.getSharedId() != null) {
-                    User user = userMapper.selectById(userView.getSharedId());
-                    if (user != null) {
-                        userView.setSharedNickName(user.getNickname());
-                        userView.setSharedHeadimgurl(user.getHeadimgurl());
-                    }
-                }
+        search.getDataList().forEach(data->{
+            Long userId = data.getId();
+            UserBindDetail userBindDetail = beanSearcher.searchFirst(UserBindDetail.class, MapUtils.builder().field(UserBindDetail::getUserId, userId).onlySelect(UserBindDetail::getPhone, UserBindDetail::getEmail).build());
+            Optional.ofNullable(userBindDetail).ifPresent(bind->{
+                data.setBindEmail(bind.getEmail());
+                data.setBindPhone(bind.getPhone());
+            });
+            if (data.getSharedId() != null) {
+                UserDistributeBusinessInfoView userDistributeBusinessInfoView = beanSearcher.searchFirst(UserDistributeBusinessInfoView.class, MapUtils.builder().field(UserDistributeBusinessInfoView::getUserId, data.getSharedId()).build());
+                Optional.ofNullable(userDistributeBusinessInfoView).ifPresent(info->{
+                    data.setDistributeName(info.getDistributeName());
+                    data.setBusinessName(info.getBusinessName());
+                });
             }
         });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 
-
     /**
      * 修改用户的拉黑状态
      */
@@ -86,7 +104,7 @@ public class CmsUserController{
     @SaCheckPermission("user:black")
     public Result<String> putBlackStatus(@PathVariable Long id) {
         User user = userMapper.selectById(id);
-        Optional.ofNullable(user).ifPresent(u->{
+        Optional.ofNullable(user).ifPresent(u -> {
             u.setIsBlack(!u.getIsBlack());
             if (u.getIsBlack()) {
                 List<RenewalView> groupsRelations = groupRelationFrontService.getMyTicket(u.getId(), null);
@@ -100,5 +118,95 @@ public class CmsUserController{
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 
+    /**
+     * 用户加入企业微信客服详情
+     */
+    @GetMapping("/get/corpFollow/detail/{userId}")
+    public Result<String> getCorpFollowDetailById(@PathVariable Long userId) {
+        User user = userMapper.selectById(userId);
+        if (user == null || StrUtil.isEmpty(user.getUnionid())) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult();
+        }
+        String corpCustomers = cmsUserFollowRelationMapper.selectCorpCustomers(user.getUnionid());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(corpCustomers);
+    }
+
+    /**
+     * 企业微信客服列表
+     */
+    @GetMapping("/get/corpFollow")
+    public Result<List<CorpFollow>> getCorpFollow() {
+        List<CorpFollow> corpFollows = beanSearcher.searchAll(CorpFollow.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(CorpFollow::getWxCorpId, 2)
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(corpFollows);
+    }
 
+    /**
+     * 用户订单详情title
+     */
+    @GetMapping("/get/order/title")
+    public Result<UserView> getUserOrderDetailTitle(Long userId) {
+        UserView userView = new UserView();
+        List<OrderDon> orderDons = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
+                .eq(OrderDon::getUserId, userId)
+                .notIn(OrderDon::getStatus, Constant.noOrderStatus)
+                .orderByAsc(OrderDon::getId));
+        //首单产品
+        Optional<OrderDon> firstOrder = orderDons.stream().filter(don -> don.getStatus() != OrderDon.Status.refund).findFirst();
+        if (firstOrder.isPresent()) {
+            OrderDon orderDon = firstOrder.get();
+            BigDecimal money = orderDon.getMoney().divide(BigDecimal.valueOf(100));
+            Optional.ofNullable(beanSearcher.searchFirst(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, orderDon.getSkuId()).onlySelect(GoodsDonSkuView::getGoodsTitle, GoodsDonSkuView::getSpecVal).build()))
+                    .ifPresent(goodsDonSkuView -> {
+                        String msg = String.format("%s%s %s元", goodsDonSkuView.getGoodsTitle(), goodsDonSkuView.getSpecVal(), money);
+                        if (orderDon.getCouponUserId() != 0) {
+                            BigDecimal subMoney = orderDon.getCouponMoney().divide(BigDecimal.valueOf(100));
+                            msg = String.format("%s(减免%s元)", msg, subMoney);
+                        }
+                        userView.setFirstOrderDetail(msg);
+                    });
+        }
+        //有无路由器订单
+        Optional<OrderDon> routeOrder = orderDons.stream().filter(don -> don.getGoodsId() == 15).findFirst();
+        userView.setIsHadRouteOrder(routeOrder.isPresent() ? true : false);
+
+        Integer noRefundOrders = 0;
+        Integer refundOrders = 0;
+        //除去退款 下单金额
+        BigDecimal orderMoney = BigDecimal.ZERO;
+        BigDecimal refundMoney = BigDecimal.ZERO;
+        for (OrderDon orderDon : orderDons) {
+            if (orderDon.getStatus() == OrderDon.Status.refund) {
+                refundOrders++;
+                if (orderDon.getRefundMoney() != null) {
+                    refundMoney = refundMoney.add(orderDon.getRefundMoney());
+                }
+            }else {
+                noRefundOrders++;
+                orderMoney = orderMoney.add(orderDon.getMoney());
+            }
+        }
+        BigDecimal refundRate = BigDecimal.ZERO;
+        if (!orderDons.isEmpty()) {
+            //退款率
+            refundRate = BigDecimal.valueOf(refundOrders).divide(BigDecimal.valueOf(orderDons.size()), 2, RoundingMode.HALF_UP);
+        }
+        userView.setOrderMoney(orderMoney);
+        userView.setNumOfOrder(noRefundOrders);
+        userView.setRefundMoney(refundMoney);
+        userView.setRefundRate(refundRate);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(userView);
+    }
+
+    /**
+     * 用户下单详情
+     */
+    @GetMapping("/get/order/list")
+    public Result<SearchResult<UserOrderDonDetail>> getUserOrderDetails() {
+        SearchResult<UserOrderDonDetail> search = beanSearcher.search(UserOrderDonDetail.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(UserOrderDonDetail::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    }
 }

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

@@ -119,7 +119,7 @@ public class AuthorizationController {
     public void redirect(String code, String state, HttpServletResponse response) throws Exception {
         AuthToken token = weChatService.getAuthToken(code,weChatConfig.getAppid());
 
-        baseRedirect(token, state, response);
+        baseRedirect(token, state, User.RegisterEnv.wx, response);
     }
 
     /**
@@ -219,7 +219,7 @@ public class AuthorizationController {
 
         AuthToken token = weChatService.getAuthToken(code, wxOpenPlatYHLXLoginConfig.getAppId());
         //重定向
-        baseRedirect(token, state, response);
+        baseRedirect(token, state, User.RegisterEnv.pc, response);
     }
 
     /**
@@ -255,6 +255,10 @@ public class AuthorizationController {
 
         redisService.del(key);
         User user = userService.getById(userId);
+        if (StrUtil.isEmpty(user.getRegisterEnv())) {
+            user.setRegisterEnv(User.RegisterEnv.pc.name());
+            userService.updateById(user);
+        }
         StpUserUtil.login(userId);
         String token = StpUserUtil.getTokenValue();
 
@@ -346,7 +350,7 @@ public class AuthorizationController {
     }
 
     /**
-     * 手机号授权登录
+     * 手机号、邮箱验证码授权登录
      */
     @PostMapping("/login/phone")
     @NoSubmit
@@ -407,6 +411,8 @@ public class AuthorizationController {
             user.setNickname(String.format("%s%s", name, Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(String.format("%s%s", user.getId(), loginPhoneReq.getType() == 1 ? user.getLoginPhone() : user.getEmail())).toHexString().substring(0, 6)));
             //默认头像
             user.setHeadimgurl(Constant.DEFAULT_HEAD_IMG);
+            String registerEnv = loginPhoneReq.getRegisterEnv();
+            user.setRegisterEnv(StrUtil.isEmpty(registerEnv) ? User.RegisterEnv.pc.name() : registerEnv);
             userService.save(user);
             //新用户分销
             if (sharedId != null) {
@@ -419,7 +425,7 @@ public class AuthorizationController {
         return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
     }
 
-    public void baseRedirect(AuthToken token, String state, HttpServletResponse response) throws Exception {
+    public void baseRedirect(AuthToken token, String state, User.RegisterEnv registerEnv, HttpServletResponse response) throws Exception {
         // 根据openid 与 access_token 获取用户信息
         GzhOAuth2UserInfo userinfo = weChatService.getUserInfo(token.getAccessToken(), token.getOpenid());
 
@@ -427,7 +433,7 @@ public class AuthorizationController {
         String json = Codec.DoBase64.custom().setData(state).decodeAsText();
         AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);
         //保存用户信息
-        User user = userService.saveAuth(userinfo, re.getSharedId(), re.getDsType(), re.getPid());
+        User user = userService.saveAuth(userinfo, re.getSharedId(), re.getDsType(), re.getPid(), registerEnv);
         if (user == null) {
             throw BusinessRuntimeException.getInstance("系统错误,请重新授权");
         }

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

@@ -235,4 +235,19 @@ public class UserController {
         userService.updateById(user);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+    /**
+     * 更新用户最后一次登录时间
+     */
+    @PutMapping("/update/lastTime")
+    public Result<String> updateLastTime() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        User user = userService.getById(userId);
+        if (user == null) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult();
+        }
+        user.setLastTime(DateTime.now());
+        userService.updateById(user);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
 }