[用户明细]-用户明细查询增加筛选条件

This commit is contained in:
liaozetao
2024-06-19 14:14:43 +08:00
parent e1364dfc81
commit f78275366a
16 changed files with 555 additions and 603 deletions

View File

@@ -8,6 +8,7 @@ import lombok.Data;
*/ */
@Data @Data
public class UserDetailQueryDto { public class UserDetailQueryDto {
/** /**
* 流量渠道类型:0-全部1-流量团队2-直播导流 * 流量渠道类型:0-全部1-流量团队2-直播导流
*/ */
@@ -17,6 +18,7 @@ public class UserDetailQueryDto {
* 平台号 * 平台号
*/ */
private String erbanNo; private String erbanNo;
/** /**
* 手机号 * 手机号
*/ */
@@ -26,14 +28,17 @@ public class UserDetailQueryDto {
* 起始日期 * 起始日期
*/ */
private String startDate; private String startDate;
/** /**
* 结束日期 * 结束日期
*/ */
private String endDate; private String endDate;
/** /**
* 第几页 * 第几页
*/ */
private Integer pageNumber = 1; private Integer pageNumber = 1;
/** /**
* 每页大小 * 每页大小
*/ */
@@ -43,4 +48,19 @@ public class UserDetailQueryDto {
* 地区ID * 地区ID
*/ */
private Integer partitionId; private Integer partitionId;
/**
* 注册类型
*/
private Integer loginType;
/**
* 是否充值
*/
private Integer isCharge;
/**
* 首进房ID
*/
private Long firstRoomErBanNo;
} }

View File

@@ -4,6 +4,7 @@ import com.accompany.common.annotation.FieldComment;
import com.accompany.core.vo.BaseVo; import com.accompany.core.vo.BaseVo;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
/** /**
@@ -11,42 +12,49 @@ import java.util.Date;
* 用户明细 * 用户明细
*/ */
@Data @Data
public class UserDeatilVo extends BaseVo { public class UserDetailVo extends BaseVo {
/*-----------------------------用户表信息------------------------*/ /*-----------------------------用户表信息------------------------*/
/** /**
* 用户uid * 用户uid
*/ */
@FieldComment("uid") @FieldComment("uid")
public Long uid; public Long uid;
/** /**
* 用户平台号 * 用户平台号
*/ */
@FieldComment("平台号") @FieldComment("平台号")
public Long erbanNo; public Long erbanNo;
/** /**
* 昵称 * 昵称
*/ */
@FieldComment("昵称") @FieldComment("昵称")
public String nick; public String nick;
/** /**
* 新增时间 * 新增时间
*/ */
@FieldComment("新增时间") @FieldComment("新增时间")
public Date createTime; public Date createTime;
/** /**
* 新增渠道 * 新增渠道
*/ */
@FieldComment("新增渠道") @FieldComment("新增渠道")
public String channel; public String channel;
/** /**
* 设备信息 * 设备信息
*/ */
@FieldComment("设备信息") @FieldComment("设备信息")
public String model; public String model;
/** /**
* 是否有同设备 * 是否有同设备
*/ */
public Boolean newDevice; public Boolean newDevice;
/** /**
* 邀请码 * 邀请码
*/ */
@@ -71,31 +79,73 @@ public class UserDeatilVo extends BaseVo {
@FieldComment("ip") @FieldComment("ip")
public String registerIp; public String registerIp;
/*-----------------------------邀请码表信息------------------------*/ /*-----------------------------邀请码表信息------------------------*/
/** /**
* 邀请码信息邀请码+组名 * 邀请码信息邀请码+组名
*/ */
@FieldComment("邀请码信息") @FieldComment("邀请码信息")
public String inviteCodeinfo; public String inviteCodeinfo;
/*-----------------------------流量渠道------------------------*/ /*-----------------------------流量渠道------------------------*/
/** /**
* 流量渠道引流团队新增/直播导流新增 * 流量渠道引流团队新增/直播导流新增
*/ */
@FieldComment("流量渠道") @FieldComment("流量渠道")
public String flowChannel; public String flowChannel;
/*-----------------------------首冲情况------------------------*/ /*-----------------------------首冲情况------------------------*/
/** /**
* 首冲情况充值日期+充值金额 * 首冲情况充值日期+充值金额
*/ */
@FieldComment("首充情况") @FieldComment("首充情况")
public String firstChargeInfo; public String firstChargeInfo;
/**
* 是否有同设备
*/
@FieldComment("是否有同设备") @FieldComment("是否有同设备")
public String newDeviceStr; public String newDeviceStr;
/** /**
* *
*/ */
@FieldComment("") @FieldComment("")
public String partitionDesc; public String partitionDesc;
/**
* 国家
*/
@FieldComment("国家")
public String lastLoginRegion;
/**
* 性别
*/
@FieldComment("性别")
public String genderStr;
/**
* 是否充值
*/
@FieldComment("是否充值")
public String isChargeStr;
/**
* 充值金额
*/
@FieldComment("充值金额")
public BigDecimal chargeAmount;
/**
* 首进房ID
*/
@FieldComment("首进房ID")
public Long firstRoomErBanNo;
/**
* 注册类型
*/
@FieldComment("注册类型")
public String loginTypeStr;
} }

View File

@@ -17,7 +17,23 @@ public interface ChargeRecordAdminMapper extends BaseMapper<ChargeRecord> {
List<ChargeRecord> listFisrChargeRecordByUids(@Param("uids") List<Long> uids); List<ChargeRecord> listFisrChargeRecordByUids(@Param("uids") List<Long> uids);
List<ChargeRecordCountryVo> getCountryGoldDetail(@Param("startTime")Date startTime, @Param("endTime")Date endTime); List<ChargeRecordCountryVo> getCountryGoldDetail(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
List<ChargeRecordPartitionVo> getPartitionGoldDetail(@Param("partitionId")Integer partitionId, @Param("startTime")Date startTime, @Param("endTime")Date endTime); List<ChargeRecordPartitionVo> getPartitionGoldDetail(@Param("partitionId") Integer partitionId, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
/**
* 充值统计
* @param uidList
* @return
*/
List<ChargeRecord> getChargeCount(@Param("uidList") List<Long> uidList);
/**
* 充值金额
* @param uidList
* @param startTime
* @param endTime
* @return
*/
List<ChargeRecord> getChargeAmount(@Param("uidList") List<Long> uidList, @Param("startTime") String startTime, @Param("endTime") String endTime);
} }

View File

@@ -2,7 +2,7 @@ package com.accompany.admin.mapper;
import com.accompany.admin.dto.UserDetailQueryDto; import com.accompany.admin.dto.UserDetailQueryDto;
import com.accompany.admin.vo.UsersVo; import com.accompany.admin.vo.UsersVo;
import com.accompany.admin.vo.stats.UserDeatilVo; import com.accompany.admin.vo.stats.UserDetailVo;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@@ -29,19 +29,19 @@ public interface UserMapperExpand {
List<String> selectChannelList(); List<String> selectChannelList();
/*用户明细全部分页查询*/ /*用户明细全部分页查询*/
List<UserDeatilVo> userDetailList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto); List<UserDetailVo> userDetailList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto);
/*用户明细直播导流分页查询*/ /*用户明细直播导流分页查询*/
List<UserDeatilVo> userLiveDetailList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto); List<UserDetailVo> userLiveDetailList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto);
/*用户明细流量团队分页查询*/ /*用户明细流量团队分页查询*/
List<UserDeatilVo> userDetailFlowTeamList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto); List<UserDetailVo> userDetailFlowTeamList(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto);
/*用户明细直播导流分页查询*/ /*用户明细直播导流分页查询*/
List<UserDeatilVo> userLiveDetailListV2(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto); List<UserDetailVo> userLiveDetailListV2(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto);
/*用户明细流量团队分页查询*/ /*用户明细流量团队分页查询*/
List<UserDeatilVo> userDetailFlowTeamListV2(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto); List<UserDetailVo> userDetailFlowTeamListV2(@Param("userDetailQueryDto") UserDetailQueryDto userDetailQueryDto);
/** /**
* 获取用户地区 * 获取用户地区

View File

@@ -4,13 +4,15 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.accompany.admin.dto.UserDetailQueryDto; import com.accompany.admin.dto.UserDetailQueryDto;
import com.accompany.admin.mapper.ChargeRecordAdminMapper;
import com.accompany.admin.mapper.UserMapperExpand; import com.accompany.admin.mapper.UserMapperExpand;
import com.accompany.admin.service.base.BaseService; import com.accompany.admin.service.base.BaseService;
import com.accompany.admin.service.room.RoomVisitorService; import com.accompany.admin.service.room.RoomVisitorService;
import com.accompany.admin.vo.flowteam.FlowTeamConfVO; import com.accompany.admin.vo.flowteam.FlowTeamConfVO;
import com.accompany.admin.vo.stats.UserDeatilVo; import com.accompany.admin.vo.stats.UserDetailVo;
import com.accompany.business.dto.flow.FlowTeamMemberBaseDto; import com.accompany.business.dto.flow.FlowTeamMemberBaseDto;
import com.accompany.business.model.FirstChargeRewardRecord; import com.accompany.business.model.FirstChargeRewardRecord;
import com.accompany.business.model.UserInRoomRecord;
import com.accompany.business.model.room.RoomVisitor; import com.accompany.business.model.room.RoomVisitor;
import com.accompany.business.model.room.RoomVisitorUserDict; import com.accompany.business.model.room.RoomVisitorUserDict;
import com.accompany.business.mybatismapper.UserInRoomRecordMapper; import com.accompany.business.mybatismapper.UserInRoomRecordMapper;
@@ -27,9 +29,12 @@ import com.accompany.common.utils.DateTimeUtil;
import com.accompany.common.utils.StringUtils; import com.accompany.common.utils.StringUtils;
import com.accompany.core.exception.AdminServiceException; import com.accompany.core.exception.AdminServiceException;
import com.accompany.core.model.AccountLoginRecord; import com.accompany.core.model.AccountLoginRecord;
import com.accompany.core.mybatismapper.AccountLoginRecordMapperExpand;
import com.accompany.core.mybatismapper.UsersMapper; import com.accompany.core.mybatismapper.UsersMapper;
import com.accompany.core.service.SysConfService; import com.accompany.core.service.SysConfService;
import com.accompany.core.service.common.JedisLockService; import com.accompany.core.service.common.JedisLockService;
import com.accompany.payment.model.ChargeRecord;
import com.accompany.sharding.mapper.UserInOutRoomRecordMapper;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
@@ -42,12 +47,16 @@ import com.xuanyin.flowteam.mapper.FlowTeamMemberInviteUserMapper;
import com.xuanyin.flowteam.model.FlowTeamGroup; import com.xuanyin.flowteam.model.FlowTeamGroup;
import com.xuanyin.flowteam.model.FlowTeamInfo; import com.xuanyin.flowteam.model.FlowTeamInfo;
import com.xuanyin.flowteam.model.FlowTeamMemberInviteUser; import com.xuanyin.flowteam.model.FlowTeamMemberInviteUser;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch; import org.springframework.util.StopWatch;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -56,312 +65,163 @@ public class StatsUserDetailAdminService extends BaseService {
@Autowired @Autowired
private UserMapperExpand userMapperExpand; private UserMapperExpand userMapperExpand;
@Autowired @Autowired
private UserInRoomRecordMapper userInRoomRecordMapper; private UserInRoomRecordMapper userInRoomRecordMapper;
@Autowired
private SysConfService sysConfService;
@Autowired
private FirstChargeRewardRecordService firstChargeRewardRecordService;
@Autowired
private FlowTeamMemberBaseMapper flowTeamMemberBaseMapper;
@Autowired
private RoomVisitorService roomVisitorService;
@Autowired
private UserLoginService userLoginService;
@Autowired
private RoomVisitorUserDictMapper roomVisitorUserDictMapper;
@Autowired
private RoomVisitorMapper roomVisitorMapper;
@Autowired
private UsersMapper usersMapper;
@Autowired
private JedisLockService jedisLockService;
@Autowired @Autowired
private FlowTeamInfoMapper flowTeamInfoMapper; private FlowTeamInfoMapper flowTeamInfoMapper;
@Autowired @Autowired
private FlowTeamMemberInviteUserMapper flowTeamMemberInviteUserMapper; private FlowTeamMemberInviteUserMapper flowTeamMemberInviteUserMapper;
@Autowired @Autowired
private FlowTeamGroupMapper flowTeamGroupMapper; private FlowTeamGroupMapper flowTeamGroupMapper;
public PageInfo userDetailList(UserDetailQueryDto userDetailQueryDto) { @Autowired
if (userDetailQueryDto.getStartDate() == null || userDetailQueryDto.getEndDate() == null) { private FlowTeamMemberBaseMapper flowTeamMemberBaseMapper;
@Autowired
private RoomVisitorUserDictMapper roomVisitorUserDictMapper;
@Autowired
private RoomVisitorMapper roomVisitorMapper;
@Autowired
private ChargeRecordAdminMapper chargeRecordAdminMapper;
@Autowired
private UsersMapper usersMapper;
@Autowired
private AccountLoginRecordMapperExpand accountLoginRecordMapperExpand;
@Autowired
private SysConfService sysConfService;
@Autowired
private FirstChargeRewardRecordService firstChargeRewardRecordService;
@Autowired
private RoomVisitorService roomVisitorService;
@Autowired
private UserLoginService userLoginService;
@Autowired
private JedisLockService jedisLockService;
public PageInfo<UserDetailVo> userDetailList(UserDetailQueryDto query) {
String startDate = query.getStartDate();
String endDate = query.getEndDate();
if (startDate == null || endDate == null) {
throw new AdminServiceException(BusiStatus.PARAMERROR); throw new AdminServiceException(BusiStatus.PARAMERROR);
} }
//检查引流场次用户关系对应表有没有数据,没有进行初始化 Byte flowChannelType = query.getFlowChannelType();
initRoomVisitorUserDict(); switch (flowChannelType) {
//流量团队
if (userDetailQueryDto.getFlowChannelType().equals(Byte.valueOf((byte) 1))) { case 1: {
return this.userDetailFlowTeamList(userDetailQueryDto); break;
}
if(userDetailQueryDto.getFlowChannelType().equals(Byte.valueOf((byte) 2))) {
return this.userLiveDetailListV2(userDetailQueryDto);
}
return allUserDetail(userDetailQueryDto);
}
/**
* 直播导流分页查询
* @param userDetailQueryDto
* @return
*/
public PageInfo userLiveDetailList(UserDetailQueryDto userDetailQueryDto) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("liveFlow");
PageHelper.startPage(userDetailQueryDto.getPageNumber(), userDetailQueryDto.getPageSize());
PageInfo pageInfo = new PageInfo(userMapperExpand.userLiveDetailList(userDetailQueryDto));
List<UserDeatilVo> userDeatilVoList = pageInfo.getList();
if (CollectionUtils.isEmpty(userDeatilVoList)) return pageInfo;
//<uid, FirstChargeRewardRecord>
Map<Long, FirstChargeRewardRecord> chargeMap = getFirstChargeRewardRecordMap(userDeatilVoList);
//获取直播导流相关场次
Map<Long, List<RoomVisitor>> rvMap = getLiveMap(userDeatilVoList);
userDeatilVoList.forEach(userDeatilVo -> {
Long uid = userDeatilVo.getUid();
Long inviteUid = userDeatilVo.getInviteUid();
List<RoomVisitor> visitorList = rvMap.get(inviteUid);
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
dealFlowChannel(userDeatilVo, visitorList);
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
//判断是否为新设备
if (!StringUtils.isEmpty(userDeatilVo.getDeviceId())) {
userDeatilVo.setNewDevice(this.isNewDevice(userDeatilVo.getUid(), userDeatilVo.getDeviceId()));
} }
//直播导流
//处理首充信息 case 2: {
FirstChargeRewardRecord rewardRecord = chargeMap.get(uid); //检查引流场次用户关系对应表有没有数据,没有进行初始化
if (rewardRecord == null) { initRoomVisitorUserDict();
userDeatilVo.setFirstChargeInfo("未充值"); break;
}else {
double amount = ((double) rewardRecord.getAmount()) / 100;
String chargeStr = "%s 首充:%s元";
userDeatilVo.setFirstChargeInfo(String.format(chargeStr, DateTimeUtil.convertDate(rewardRecord.getCreateTime()), amount));
} }
}); default: {
stopWatch.stop();
logger.info("直播导流查询耗时信息:{}", stopWatch.prettyPrint()); }
}
String YES_ZH = "";
String NO_ZH = "";
Integer pageNumber = query.getPageNumber();
Integer pageSize = query.getPageSize();
PageHelper.startPage(pageNumber, pageSize);
PageInfo<UserDetailVo> pageInfo = new PageInfo<>(userMapperExpand.userDetailList(query));
List<UserDetailVo> records = pageInfo.getList();
if (CollectionUtil.isNotEmpty(records)) {
List<Long> uidList = records.stream().map(UserDetailVo::getUid).collect(Collectors.toList());
//是否充值
Map<Long, Long> chargeCountMap = null;
List<ChargeRecord> chargeCounts = chargeRecordAdminMapper.getChargeCount(uidList);
if (CollectionUtil.isNotEmpty(chargeCounts)) {
chargeCountMap = chargeCounts.stream().collect(Collectors.toMap(ChargeRecord::getUid, ChargeRecord::getAmount, (v1, v2) -> v1));
}
//充值金额
Map<Long, Long> chargeAmountMap = null;
List<ChargeRecord> chargeAmounts = chargeRecordAdminMapper.getChargeAmount(uidList, startDate, endDate);
if (CollectionUtil.isNotEmpty(chargeAmounts)) {
chargeAmountMap = chargeAmounts.stream().collect(Collectors.toMap(ChargeRecord::getUid, ChargeRecord::getAmount, (v1, v2) -> v1));
}
//首进房ID
Map<Long, Long> firstRoomMap = null;
List<UserInRoomRecord> firstRooms = userInRoomRecordMapper.getFirstRoom(uidList);
if (CollectionUtil.isNotEmpty(firstRooms)) {
firstRoomMap = firstRooms.stream().collect(Collectors.toMap(UserInRoomRecord::getUid, UserInRoomRecord::getRoomuid));
}
//注册类型
Map<Long, Byte> loginTypeMap = null;
List<AccountLoginRecord> loginTypes = accountLoginRecordMapperExpand.getLoginType(uidList);
if (CollectionUtil.isNotEmpty(loginTypes)) {
loginTypeMap = loginTypes.stream().collect(Collectors.toMap(AccountLoginRecord::getUid, AccountLoginRecord::getLoginType, (v1, v2) -> v1));
}
for (UserDetailVo record : records) {
Long uid = record.getUid();
String inviteCode = record.getInviteCode();
record.setInviteCodeinfo(inviteCode);
//是否充值
String isChargeStr = NO_ZH;
if (CollectionUtil.isNotEmpty(chargeCountMap) && chargeCountMap.containsKey(uid)) {
Long chargeCount = chargeCountMap.get(uid);
if (chargeCount > 0) {
isChargeStr = YES_ZH;
}
}
record.setIsChargeStr(isChargeStr);
//充值金额
BigDecimal chargeAmount = BigDecimal.ZERO;
if (CollectionUtil.isNotEmpty(chargeAmountMap) && chargeAmountMap.containsKey(uid)) {
chargeAmount = BigDecimal.valueOf(chargeAmountMap.get(uid)).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
}
record.setChargeAmount(chargeAmount);
//首进房ID
Long firstRoomErBanNo = null;
if (CollectionUtil.isNotEmpty(firstRoomMap) && firstRoomMap.containsKey(uid)) {
firstRoomErBanNo = firstRoomMap.get(uid);
}
record.setFirstRoomErBanNo(firstRoomErBanNo);
//注册类型
String loginTypeStr = null;
if (CollectionUtil.isNotEmpty(loginTypeMap) && loginTypeMap.containsKey(uid)) {
Byte loginType = loginTypeMap.get(uid);
switch (loginType) {
case 3: {
loginTypeStr = "手机号注册";
break;
}
case 5: {
loginTypeStr = "APPLE注册";
break;
}
case 8: {
loginTypeStr = "GOOGLE注册";
break;
}
case 9: {
loginTypeStr = "LINE注册";
break;
}
}
}
record.setLoginTypeStr(loginTypeStr);
record.setNewDevice(isNewDevice(uid, record.getDeviceId()));
setInviteCodeInfo(record);
}
}
return pageInfo; return pageInfo;
} }
/**
* 直播导流分页查询
* @param userDetailQueryDto
* @return
*/
public PageInfo userLiveDetailListV2(UserDetailQueryDto userDetailQueryDto) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("liveFlow");
PageHelper.startPage(userDetailQueryDto.getPageNumber(), userDetailQueryDto.getPageSize());
PageInfo pageInfo = new PageInfo(userMapperExpand.userLiveDetailListV2(userDetailQueryDto));
List<UserDeatilVo> userDeatilVoList = pageInfo.getList();
if (CollectionUtils.isEmpty(userDeatilVoList)) return pageInfo;
//<uid, FirstChargeRewardRecord>
Map<Long, FirstChargeRewardRecord> chargeMap = getFirstChargeRewardRecordMap(userDeatilVoList);
List<Long> uidList = userDeatilVoList.stream().map(userDeatilVo -> userDeatilVo.getUid()).collect(Collectors.toList());
QueryWrapper<RoomVisitorUserDict> userDictQueryWrapper = new QueryWrapper<>();
userDictQueryWrapper.lambda().in(RoomVisitorUserDict::getUid, uidList);
List<RoomVisitorUserDict> userDictList = roomVisitorUserDictMapper.selectList(userDictQueryWrapper);
Map<Long, Long> userDictMap = userDictList.stream().collect(Collectors.toMap(RoomVisitorUserDict::getUid, RoomVisitorUserDict::getRoomVisitorId));
List<Long> roomVisitorIdList = userDictList.stream().map(RoomVisitorUserDict::getRoomVisitorId).distinct().collect(Collectors.toList());
List<RoomVisitor> roomVisitorList = (List<RoomVisitor>) roomVisitorService.listByIds(roomVisitorIdList);
Map<Long, RoomVisitor> roomVisitorMap = Maps.uniqueIndex(roomVisitorList, RoomVisitor::getId);
userDeatilVoList.forEach(userDeatilVo -> {
Long uid = userDeatilVo.getUid();
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
Long roomVisitorId = Optional.ofNullable(userDictMap.get(userDeatilVo.getUid())).orElse(-100l);
RoomVisitor roomVisitor = Optional.ofNullable(roomVisitorMap.get(roomVisitorId)).orElse(new RoomVisitor());
userDeatilVo.setFlowChannel("直播导流新增" + StrUtil.SPACE + roomVisitor.getRecordId());
//判断是否为新设备
if (!StringUtils.isEmpty(userDeatilVo.getDeviceId())) {
userDeatilVo.setNewDevice(this.isNewDevice(userDeatilVo.getUid(), userDeatilVo.getDeviceId()));
}
//处理首充信息
FirstChargeRewardRecord rewardRecord = chargeMap.get(uid);
if (rewardRecord == null) {
userDeatilVo.setFirstChargeInfo("未充值");
}else {
double amount = ((double) rewardRecord.getAmount()) / 100;
String chargeStr = "%s 首充:%s元";
userDeatilVo.setFirstChargeInfo(String.format(chargeStr, DateTimeUtil.convertDate(rewardRecord.getCreateTime()), amount));
}
});
stopWatch.stop();
logger.info("直播导流查询耗时信息:{}", stopWatch.prettyPrint());
return pageInfo;
}
/**
* 流量团队分页查询
* @param userDetailQueryDto
* @return
*/
public PageInfo userDetailFlowTeamList(UserDetailQueryDto userDetailQueryDto) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("flowTeam");
PageHelper.startPage(userDetailQueryDto.getPageNumber(), userDetailQueryDto.getPageSize());
PageInfo<UserDeatilVo> pageInfo = new PageInfo<>(userMapperExpand.userDetailFlowTeamListV2(userDetailQueryDto));
List<UserDeatilVo> userDeatilVoList = pageInfo.getList();
if (CollectionUtils.isEmpty(userDeatilVoList)) return pageInfo;
//<uid, FirstChargeRewardRecord>
Map<Long, FirstChargeRewardRecord> chargeMap = getFirstChargeRewardRecordMap(userDeatilVoList);
//<邀请码,组名>
Map<String, FlowTeamMemberBaseDto> teamNameMap = getTeamNameMap(userDeatilVoList);
userDeatilVoList.forEach(userDeatilVo -> {
Long uid = userDeatilVo.getUid();
//针对流量团队:处理引流小组名称信息
setInviteCodeInfo(userDeatilVo);
//判断是否为新设备
if (!StringUtils.isEmpty(userDeatilVo.getDeviceId())) {
userDeatilVo.setNewDevice(this.isNewDevice(userDeatilVo.getUid(), userDeatilVo.getDeviceId()));
}
//处理首充信息
FirstChargeRewardRecord rewardRecord = chargeMap.get(uid);
if (rewardRecord == null) {
userDeatilVo.setFirstChargeInfo("未充值");
}else {
Long amount = rewardRecord.getAmount() / 100;
String chargeStr = "%s 首充:%s元";
userDeatilVo.setFirstChargeInfo(String.format(chargeStr, DateTimeUtil.convertDate(rewardRecord.getCreateTime()), amount));
}
userDeatilVo.setFlowChannel("流量团队新增");
});
stopWatch.stop();
logger.info("流量团队查询耗时信息:{}", stopWatch.prettyPrint());
return pageInfo;
}
/**
* 获取首充相关
* @param userDeatilVoList
* @return
*/
private Map<Long, FirstChargeRewardRecord> getFirstChargeRewardRecordMap(List<UserDeatilVo> userDeatilVoList) {
List<Long> uidList = userDeatilVoList.stream().map(userDeatilVo -> userDeatilVo.getUid()).collect(Collectors.toList());
//首充信息
QueryWrapper<FirstChargeRewardRecord> queryWrapper= new QueryWrapper<>();
queryWrapper.lambda().in(FirstChargeRewardRecord::getUid, uidList);
List<FirstChargeRewardRecord> chargeList = firstChargeRewardRecordService.list(queryWrapper);
//保险起见去重处理
Map<Long, FirstChargeRewardRecord> chargeMap = new HashMap<>();
if (!CollectionUtils.isEmpty(chargeList)) {
chargeList = chargeList.stream().filter(distinctByKey(FirstChargeRewardRecord::getUid)).collect(Collectors.toList());
chargeMap = Maps.uniqueIndex(chargeList, FirstChargeRewardRecord::getUid);
}
return chargeMap;
}
/**
*
* @param userDeatilVoList
* @return Map<String, String>:存放邀请码和对应的组名
*/
@NotNull
private Map<String, FlowTeamMemberBaseDto> getTeamNameMap(List<UserDeatilVo> userDeatilVoList) {
List<String> inviteCodeList = userDeatilVoList.stream().map(userDeatilVo -> userDeatilVo.getInviteCode()).filter(inviteCode -> !BlankUtil.isBlank(inviteCode)).distinct().collect(Collectors.toList());
Map<String, FlowTeamMemberBaseDto> teamNameMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
if (!CollectionUtils.isEmpty(inviteCodeList)) {
String configStr = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.FLOW_TEAM_MANAGE, "{}");
FlowTeamConfVO flowTeamConfVO = JSONObject.parseObject(configStr, FlowTeamConfVO.class);
List<FlowTeamConfVO.TeamItem> teamsList = flowTeamConfVO.getTeams();
Map<String, String> teamMap = teamsList.stream().collect(Collectors.toMap(FlowTeamConfVO.TeamItem::getTeamId, FlowTeamConfVO.TeamItem::getTeamName));
List<FlowTeamMemberBaseDto> teamMemberBaseDtoList = flowTeamMemberBaseMapper.queryInviteCodeAndTeam(inviteCodeList);
if (!CollectionUtils.isEmpty(teamMemberBaseDtoList)) {
teamMemberBaseDtoList = teamMemberBaseDtoList.stream().filter(distinctByKey(FlowTeamMemberBaseDto::getInviteCode)).collect(Collectors.toList());
teamMemberBaseDtoList = teamMemberBaseDtoList.stream().map(teamMemberDto -> {
teamMemberDto.setTeamName(teamMap.get(teamMemberDto.getTeamId()));
return teamMemberDto;
}).collect(Collectors.toList());
Map<String, FlowTeamMemberBaseDto> teamNameMapData = Maps.uniqueIndex(teamMemberBaseDtoList, FlowTeamMemberBaseDto::getInviteCode);
teamNameMap.putAll(teamNameMapData);
}
}
return teamNameMap;
}
public void dealFlowChannel(UserDeatilVo userDeatilVo, List<RoomVisitor> visitorList) {
if (userDeatilVo.getInviteUid() == null || CollectionUtils.isEmpty(visitorList)) return;
//查询对应的场次id
List<String> recordList = userInRoomRecordMapper.queryRecordId(userDeatilVo.getUid(), userDeatilVo.getInviteUid());
if (!CollectionUtils.isEmpty(recordList)) {
userDeatilVo.setFlowChannel("直播导流新增" + StrUtil.SPACE + recordList.get(0));
}
}
public void checkFlowTeam(UserDeatilVo userDeatilVo, Map<String, FlowTeamMemberBaseDto> teamNameMap, Map<Long, List<RoomVisitor>> rvMap) {
if (BlankUtil.isBlank(userDeatilVo.getInviteCode())) return;
String inviteCode = userDeatilVo.getInviteCode();
//检查邀请码是否为空->检查是否属于流量团队有效邀请码->检查是否属于直播导流
if (teamNameMap.containsKey(inviteCode)) {
FlowTeamMemberBaseDto flowTeamMemberBaseDto = teamNameMap.get(inviteCode);
if (userDeatilVo.getCreateTime().getTime() > flowTeamMemberBaseDto.getCreateTime().getTime()) {
String teamName = flowTeamMemberBaseDto.getTeamName();
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode() + (teamName == null ? "" : StrUtil.SPACE + teamName));
userDeatilVo.setFlowChannel("流量团队新增");
return;
}
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
}
//检查是否为直播导流相关邀请码
Long inviteUid = userDeatilVo.getInviteUid();
List<RoomVisitor> visitorList = rvMap.get(inviteUid);
dealFlowChannel(userDeatilVo, visitorList);
}
private Map<Long, List<RoomVisitor>> getLiveMap(List<UserDeatilVo> userDeatilVoList) {
List<Long> inviteUidList = userDeatilVoList.stream().map(userDeatilVo -> userDeatilVo.getInviteUid()).filter(inviteUid -> inviteUid != null).distinct().collect(Collectors.toList());
List<RoomVisitor> roomVisitorList = roomVisitorService.queryRoomVisitorByUidList(inviteUidList);
//获取直播导流对应的场次
Map<Long, List<RoomVisitor>> rvMap = new HashMap<>();
if (!CollectionUtils.isEmpty(roomVisitorList)) {
rvMap = roomVisitorList.stream().collect(Collectors.groupingBy(RoomVisitor::getUid));
}
Map<Long, List<RoomVisitor>> finalRvMap = rvMap;
return finalRvMap;
}
/** /**
* 检查是否新设备 * 检查是否新设备
* *
@@ -371,11 +231,7 @@ public class StatsUserDetailAdminService extends BaseService {
*/ */
private boolean isNewDevice(Long uid, String deviceId) { private boolean isNewDevice(Long uid, String deviceId) {
AccountLoginRecord record = this.userLoginService.getDeviceFirstLoginRecordV2(uid, deviceId); AccountLoginRecord record = this.userLoginService.getDeviceFirstLoginRecordV2(uid, deviceId);
if (record == null) { return record == null;
return true;
}
return false;
} }
@@ -383,53 +239,38 @@ public class StatsUserDetailAdminService extends BaseService {
//用户进房加锁 //用户进房加锁
String lockKey = RedisKey.room_visitor_user_dict_lock.getKey(); String lockKey = RedisKey.room_visitor_user_dict_lock.getKey();
String lockVal = jedisLockService.lock(lockKey); String lockVal = jedisLockService.lock(lockKey);
if (StringUtils.isEmpty(lockVal)) { if (StringUtils.isEmpty(lockVal)) {
//拿不到锁暂不考虑 //拿不到锁暂不考虑
throw new AdminServiceException(BusiStatus.SERVERBUSY); throw new AdminServiceException(BusiStatus.SERVERBUSY);
} }
StopWatch stw = new StopWatch(); StopWatch stw = new StopWatch();
stw.start(); stw.start();
try { try {
QueryWrapper<RoomVisitorUserDict> queryWrapper = new QueryWrapper<>(); QueryWrapper<RoomVisitorUserDict> queryWrapper = new QueryWrapper<>();
Integer count = roomVisitorUserDictMapper.selectCount(queryWrapper); Integer count = roomVisitorUserDictMapper.selectCount(queryWrapper);
if (count != null && count > 0) return; if (count != null && count > 0) return;
QueryWrapper<RoomVisitor> visitorQuery = new QueryWrapper<>(); QueryWrapper<RoomVisitor> visitorQuery = new QueryWrapper<>();
visitorQuery.lambda().orderByAsc(RoomVisitor::getStartTime); visitorQuery.lambda().orderByAsc(RoomVisitor::getStartTime);
List<RoomVisitor> roomVisitorList = roomVisitorMapper.selectList(visitorQuery); List<RoomVisitor> roomVisitorList = roomVisitorMapper.selectList(visitorQuery);
if (CollectionUtils.isEmpty(roomVisitorList)) return; if (CollectionUtils.isEmpty(roomVisitorList)) return;
for (RoomVisitor roomVisitor : roomVisitorList) {
//Map<Long, RoomVisitor> roomVisitorMap = Maps.uniqueIndex(roomVisitorList, RoomVisitor::getId);
for (RoomVisitor rvisitor : roomVisitorList) {
//查询此时间段完善信息的用户 //查询此时间段完善信息的用户
List<Long> userUidList = usersMapper.queryRoomVisitorSectionUser(rvisitor.getStartTime(), rvisitor.getEndTime()); List<Long> userUidList = usersMapper.queryRoomVisitorSectionUser(roomVisitor.getStartTime(), roomVisitor.getEndTime());
if (CollectionUtils.isEmpty(userUidList)) continue; if (CollectionUtils.isEmpty(userUidList)) continue;
//查询对应此时间段内进房的非机器人用户 //查询对应此时间段内进房的非机器人用户
List<Long> inRoomRecordUidList = userInRoomRecordMapper.queryRoomVisitorSectionRecord(userUidList, rvisitor.getUid(), rvisitor.getStartTime(), rvisitor.getEndTime()); List<Long> inRoomRecordUidList = userInRoomRecordMapper.queryRoomVisitorSectionRecord(userUidList, roomVisitor.getUid(), roomVisitor.getStartTime(), roomVisitor.getEndTime());
if (CollectionUtils.isEmpty(inRoomRecordUidList)) continue; if (CollectionUtils.isEmpty(inRoomRecordUidList)) continue;
List<Long> dictUidList = roomVisitorUserDictMapper.queryUidByUidList(inRoomRecordUidList); List<Long> dictUidList = roomVisitorUserDictMapper.queryUidByUidList(inRoomRecordUidList);
if (!CollectionUtils.isEmpty(dictUidList)) { if (!CollectionUtils.isEmpty(dictUidList)) {
inRoomRecordUidList = (List<Long>) CollectionUtil.disjunction(inRoomRecordUidList, dictUidList); inRoomRecordUidList = (List<Long>) CollectionUtil.disjunction(inRoomRecordUidList, dictUidList);
} }
if (CollectionUtil.isEmpty(inRoomRecordUidList)) continue; if (CollectionUtil.isEmpty(inRoomRecordUidList)) continue;
inRoomRecordUidList = inRoomRecordUidList.stream().distinct().collect(Collectors.toList()); inRoomRecordUidList = inRoomRecordUidList.stream().distinct().collect(Collectors.toList());
//组装写入 //组装写入
inRoomRecordUidList.forEach(uid -> { inRoomRecordUidList.forEach(uid -> {
RoomVisitorUserDict userDict = new RoomVisitorUserDict(); RoomVisitorUserDict userDict = new RoomVisitorUserDict();
userDict.setUid(uid); userDict.setUid(uid);
userDict.setRoomVisitorId(rvisitor.getId()); userDict.setRoomVisitorId(roomVisitor.getId());
roomVisitorUserDictMapper.insert(userDict); roomVisitorUserDictMapper.insert(userDict);
}); });
} }
@@ -439,155 +280,52 @@ public class StatsUserDetailAdminService extends BaseService {
} finally { } finally {
jedisLockService.unlock(lockKey, lockVal); jedisLockService.unlock(lockKey, lockVal);
} }
stw.stop(); stw.stop();
logger.info("初始化直播引流用户耗时:{}", stw.prettyPrint()); logger.info("初始化直播引流用户耗时:{}", stw.prettyPrint());
} }
public PageInfo allUserDetail(UserDetailQueryDto userDetailQueryDto) {
StopWatch stopWatch = new StopWatch();
stopWatch.start("user_detail");
PageHelper.startPage(userDetailQueryDto.getPageNumber(), userDetailQueryDto.getPageSize());
PageInfo pageInfo = new PageInfo(userMapperExpand.userDetailList(userDetailQueryDto));
List<UserDeatilVo> userDeatilVoList = pageInfo.getList();
if (CollectionUtils.isEmpty(userDeatilVoList)) return pageInfo;
//<uid, FirstChargeRewardRecord>
Map<Long, FirstChargeRewardRecord> chargeMap = getFirstChargeRewardRecordMap(userDeatilVoList);
//<邀请码,组名>
//Map<String, FlowTeamMemberBaseDto> teamNameMap = getTeamNameMap(userDeatilVoList);
userDeatilVoList.forEach(userDeatilVo -> {
Long uid = userDeatilVo.getUid();
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
//检查邀请码是否为空->检查是否属于流量团队有效邀请码->检查是否属于直播导流
checkFlowTeamV3(userDeatilVo);
//判断是否为新设备
if (!StringUtils.isEmpty(userDeatilVo.getDeviceId())) {
userDeatilVo.setNewDevice(this.isNewDevice(userDeatilVo.getUid(), userDeatilVo.getDeviceId()));
}
//处理首充信息
FirstChargeRewardRecord rewardRecord = chargeMap.get(uid);
if (rewardRecord == null) {
userDeatilVo.setFirstChargeInfo("未充值");
}else {
Long amount = rewardRecord.getAmount() / 100;
String chargeStr = "%s 首充:%s元";
userDeatilVo.setFirstChargeInfo(String.format(chargeStr, DateTimeUtil.convertDate(rewardRecord.getCreateTime()), amount));
}
});
stopWatch.stop();
logger.info("用户明细耗时信息:{}", stopWatch.prettyPrint());
return pageInfo;
}
public void checkFlowTeamV2(UserDeatilVo userDeatilVo, Map<String, FlowTeamMemberBaseDto> teamNameMap) {
if (! BlankUtil.isBlank(userDeatilVo.getInviteCode())) {
String inviteCode = userDeatilVo.getInviteCode();
//检查邀请码是否为空->检查是否属于流量团队有效邀请码->检查是否属于直播导流
if (teamNameMap.containsKey(inviteCode)) {
FlowTeamMemberBaseDto flowTeamMemberBaseDto = teamNameMap.get(inviteCode);
if (userDeatilVo.getCreateTime().getTime() > flowTeamMemberBaseDto.getCreateTime().getTime()) {
String teamName = flowTeamMemberBaseDto.getTeamName();
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode() + (teamName == null ? "" : StrUtil.SPACE + teamName));
userDeatilVo.setFlowChannel("流量团队新增");
return;
}
//userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode());
}
}
//检查是否为直播导流相关
QueryWrapper<RoomVisitorUserDict> userDictQueryWrapper = new QueryWrapper<>();
userDictQueryWrapper.lambda().eq(RoomVisitorUserDict::getUid, userDeatilVo.getUid());
RoomVisitorUserDict roomVisitorUserDict = roomVisitorUserDictMapper.selectOne(userDictQueryWrapper);
if (roomVisitorUserDict == null) return;
RoomVisitor roomVisitor = roomVisitorService.getById(roomVisitorUserDict.getRoomVisitorId());
if(roomVisitor == null) return;
userDeatilVo.setFlowChannel("直播导流新增" + StrUtil.SPACE + roomVisitor.getRecordId());
}
public HashMap<String, Object> exportUserDetailList(UserDetailQueryDto userDetailQueryDto) { public HashMap<String, Object> exportUserDetailList(UserDetailQueryDto userDetailQueryDto) {
if (userDetailQueryDto.getStartDate() == null || userDetailQueryDto.getEndDate() == null) { if (userDetailQueryDto.getStartDate() == null || userDetailQueryDto.getEndDate() == null) {
throw new AdminServiceException(BusiStatus.PARAMERROR); throw new AdminServiceException(BusiStatus.PARAMERROR);
} }
Integer diffNum = DateTimeUtil.diffDayByDate(DateTimeUtil.convertStrToDate(userDetailQueryDto.getStartDate(), DateTimeUtil.DEFAULT_DATE_PATTERN), DateTimeUtil.convertStrToDate(userDetailQueryDto.getEndDate(), DateTimeUtil.DEFAULT_DATE_PATTERN)); int diffNum = DateTimeUtil.diffDayByDate(Objects.requireNonNull(DateTimeUtil.convertStrToDate(userDetailQueryDto.getStartDate(), DateTimeUtil.DEFAULT_DATE_PATTERN)), Objects.requireNonNull(DateTimeUtil.convertStrToDate(userDetailQueryDto.getEndDate(), DateTimeUtil.DEFAULT_DATE_PATTERN)));
if (diffNum > 31) throw new AdminServiceException(BusiStatus.EXPORT_DATA_BEYOND_LIMIT); if (diffNum > 31) throw new AdminServiceException(BusiStatus.EXPORT_DATA_BEYOND_LIMIT);
PageInfo pageInfo = this.userDetailList(userDetailQueryDto); PageInfo<UserDetailVo> pageInfo = this.userDetailList(userDetailQueryDto);
List<UserDeatilVo> userDeatilVoList = pageInfo.getList(); List<UserDetailVo> userDetailVoList = pageInfo.getList();
if (!CollectionUtils.isEmpty(userDeatilVoList)) { if (!CollectionUtils.isEmpty(userDetailVoList)) {
userDeatilVoList.forEach(userDeatilVo -> { userDetailVoList.forEach(userDetailVo -> {
if(userDeatilVo.getNewDevice() == null) userDeatilVo.setNewDeviceStr("-"); if (userDetailVo.getNewDevice() == null) userDetailVo.setNewDeviceStr("-");
else if (userDeatilVo.getNewDevice()) userDeatilVo.setNewDeviceStr(""); else if (userDetailVo.getNewDevice()) userDetailVo.setNewDeviceStr("");
else userDeatilVo.setNewDeviceStr(""); else userDetailVo.setNewDeviceStr("");
}); });
} }
HashMap<String, Object> data = new HashMap<>(); HashMap<String, Object> data = new HashMap<>();
data.put("rows", userDeatilVoList); data.put("rows", userDetailVoList);
return data; return data;
} }
public void setInviteCodeInfo(UserDetailVo userDetailVo) {
public void checkFlowTeamV3(UserDeatilVo userDeatilVo) { if (BlankUtil.isBlank(userDetailVo.getInviteCode())) return;
Boolean flag = setInviteCodeInfo(userDeatilVo);
if (flag) return;
//检查是否为直播导流相关
QueryWrapper<RoomVisitorUserDict> userDictQueryWrapper = new QueryWrapper<>();
userDictQueryWrapper.lambda().eq(RoomVisitorUserDict::getUid, userDeatilVo.getUid());
RoomVisitorUserDict roomVisitorUserDict = roomVisitorUserDictMapper.selectOne(userDictQueryWrapper);
if (roomVisitorUserDict == null) return;
RoomVisitor roomVisitor = roomVisitorService.getById(roomVisitorUserDict.getRoomVisitorId());
if(roomVisitor == null) return;
userDeatilVo.setFlowChannel("直播导流新增" + StrUtil.SPACE + roomVisitor.getRecordId());
}
public Boolean setInviteCodeInfo(UserDeatilVo userDeatilVo) {
if (BlankUtil.isBlank(userDeatilVo.getInviteCode())) return false;
QueryWrapper<FlowTeamMemberInviteUser> queryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTeamMemberInviteUser> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(FlowTeamMemberInviteUser::getUid, userDeatilVo.getUid()); queryWrapper.lambda().eq(FlowTeamMemberInviteUser::getUid, userDetailVo.getUid());
FlowTeamMemberInviteUser inviteUser = flowTeamMemberInviteUserMapper.selectOne(queryWrapper); FlowTeamMemberInviteUser inviteUser = flowTeamMemberInviteUserMapper.selectOne(queryWrapper);
if (ObjectUtil.isNull(inviteUser)) return;
if (ObjectUtil.isNull(inviteUser)) return false;
QueryWrapper<FlowTeamInfo> teamInfoQueryWrapper = new QueryWrapper<>(); QueryWrapper<FlowTeamInfo> teamInfoQueryWrapper = new QueryWrapper<>();
teamInfoQueryWrapper.lambda().eq(FlowTeamInfo::getTeamId, inviteUser.getTeamId()); teamInfoQueryWrapper.lambda().eq(FlowTeamInfo::getTeamId, inviteUser.getTeamId());
FlowTeamInfo flowTeamInfo = flowTeamInfoMapper.selectOne(teamInfoQueryWrapper); FlowTeamInfo flowTeamInfo = flowTeamInfoMapper.selectOne(teamInfoQueryWrapper);
if (ObjectUtil.isNull(flowTeamInfo)) return;
if (ObjectUtil.isNull(flowTeamInfo)) return false;
FlowTeamGroup group = flowTeamGroupMapper.selectById(flowTeamInfo.getGroupId()); FlowTeamGroup group = flowTeamGroupMapper.selectById(flowTeamInfo.getGroupId());
if (FlowTeamConstant.MemberStatus.MEMBER_STATUS_VALID.equals(flowTeamInfo.getStatus())) { if (FlowTeamConstant.MemberStatus.MEMBER_STATUS_VALID.equals(flowTeamInfo.getStatus())) {
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode() userDetailVo.setInviteCodeinfo(userDetailVo.getInviteCode()
+ (ObjectUtil.isNull(flowTeamInfo.getTeamName()) ? "" : StrUtil.DASHED + flowTeamInfo.getTeamName()) + (ObjectUtil.isNull(flowTeamInfo.getTeamName()) ? "" : StrUtil.DASHED + flowTeamInfo.getTeamName())
+ (ObjectUtil.isNull(group.getGroupName()) ? "" : StrUtil.DASHED + group.getGroupName()) + (ObjectUtil.isNull(group.getGroupName()) ? "" : StrUtil.DASHED + group.getGroupName())
); );
userDeatilVo.setFlowChannel("流量团队新增"); userDetailVo.setFlowChannel("流量团队新增");
}else { } else {
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCode() + (ObjectUtil.isNull(flowTeamInfo.getTeamName()) ? "" : StrUtil.DASHED + flowTeamInfo.getTeamName())); userDetailVo.setInviteCodeinfo(userDetailVo.getInviteCode() + (ObjectUtil.isNull(flowTeamInfo.getTeamName()) ? "" : StrUtil.DASHED + flowTeamInfo.getTeamName()));
userDeatilVo.setInviteCodeinfo(userDeatilVo.getInviteCodeinfo() + "(小组已删除)"); userDetailVo.setInviteCodeinfo(userDetailVo.getInviteCodeinfo() + "(小组已删除)");
userDeatilVo.setFlowChannel("流量团队新增"); userDetailVo.setFlowChannel("流量团队新增");
} }
return true;
} }
} }

View File

@@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?> <?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" > <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.accompany.admin.mapper.ChargeRecordAdminMapper" > <mapper namespace="com.accompany.admin.mapper.ChargeRecordAdminMapper">
<resultMap id="BaseResultMap" type="com.accompany.admin.vo.ChargeRecordAdminVo" > <resultMap id="BaseResultMap" type="com.accompany.admin.vo.ChargeRecordAdminVo">
<id column="id" property="id" jdbcType="BIGINT" /> <id column="chargeRecordId" property="chargeRecordId" jdbcType="VARCHAR"/>
</resultMap> </resultMap>
<select id="page" resultMap="BaseResultMap"> <select id="page" resultMap="BaseResultMap">
select * from ( select * from (
select a.charge_record_id chargeRecordId, a.pingxx_charge_id pingxxChargeId, b.erban_no,b.nick,b.phone,b.channel app_channel,a.uid,a.channel, select a.charge_record_id chargeRecordId, a.pingxx_charge_id pingxxChargeId, b.erban_no,b.nick,b.phone,b.channel
round(a.amount/100,2) amount, local_currency_code localCurrencyCode, round(a.local_amount/100,2) localAmount, app_channel,a.uid,a.channel,
a.charge_status status,DATE_FORMAT(a.create_time, '%Y-%m-%d %H:%i:%s') createTime, round(a.amount/100,2) amount, local_currency_code localCurrencyCode, round(a.local_amount/100,2) localAmount,
if(date(a.create_time)=date(b.create_time), 1, 0) as new_user from charge_record a.charge_status status,DATE_FORMAT(a.create_time, '%Y-%m-%d %H:%i:%s') createTime,
if(date(a.create_time)=date(b.create_time), 1, 0) as new_user from charge_record
as a as a
join users as b on a.uid=b.uid join users as b on a.uid=b.uid
where a.channel &lt;&gt; 'exchange' where a.channel &lt;&gt; 'exchange'
@@ -40,7 +41,8 @@
<select id="listFisrChargeRecordByUids" resultType="com.accompany.payment.model.ChargeRecord"> <select id="listFisrChargeRecordByUids" resultType="com.accompany.payment.model.ChargeRecord">
select charge_record_id, cr.uid, cr.create_time from charge_record cr select charge_record_id, cr.uid, cr.create_time from charge_record cr
inner join (select uid, min(create_time) create_time from charge_record inner join (select uid, min(create_time) create_time from charge_record
where uid in <foreach collection="uids" item="uid" separator="," open="(" close=")">#{uid}</foreach> and charge_status in (2,6) group by uid) crg where uid in <foreach collection="uids" item="uid" separator="," open="(" close=")">#{uid}</foreach> and
charge_status in (2,6) group by uid) crg
on cr.uid = crg.uid and cr.create_time = crg.create_time on cr.uid = crg.uid and cr.create_time = crg.create_time
</select> </select>
@@ -62,11 +64,11 @@
<select id="getPartitionGoldDetail" resultType="com.accompany.admin.vo.ChargeRecordPartitionVo"> <select id="getPartitionGoldDetail" resultType="com.accompany.admin.vo.ChargeRecordPartitionVo">
select date(cr.create_time) `date`, select date(cr.create_time) `date`,
ifnull(sum(case when cr.channel = 'google_play_billing' then amount else 0 end)/100,0) `googleUsd`, ifnull(sum(case when cr.channel = 'google_play_billing' then amount else 0 end)/100,0) `googleUsd`,
ifnull(sum(case when cr.channel = 'payermax' then amount else 0 end)/100,0) `payermaxUsd`, ifnull(sum(case when cr.channel = 'payermax' then amount else 0 end)/100,0) `payermaxUsd`,
ifnull(sum(case when cr.channel = 'MyCard' then amount else 0 end)/100,0) `myCardUsd`, ifnull(sum(case when cr.channel = 'MyCard' then amount else 0 end)/100,0) `myCardUsd`,
ifnull(sum(case when cr.channel = 'ios_pay' then amount else 0 end)/100,0) `iosUsd`, ifnull(sum(case when cr.channel = 'ios_pay' then amount else 0 end)/100,0) `iosUsd`,
ifnull(sum(case when cr.charge_prod_id = 'company' then amount else 0 end)/100,0) `companyUsd`, ifnull(sum(case when cr.charge_prod_id = 'company' then amount else 0 end)/100,0) `companyUsd`,
ifnull(sum(amount)/100,0) `totalUsd` ifnull(sum(amount)/100,0) `totalUsd`
from charge_record cr from charge_record cr
inner join users u on cr.uid = u.uid inner join users u on cr.uid = u.uid
where 1=1 where 1=1
@@ -81,4 +83,36 @@
group by `date` group by `date`
</select> </select>
<select id="getChargeCount" resultType="com.accompany.payment.model.ChargeRecord">
select
cr.uid,
count(1) as amount
from charge_record as cr
where cr.charge_status = 2
and cr.uid in
<foreach collection="uidList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
group by cr.uid
</select>
<select id="getChargeAmount" resultType="com.accompany.payment.model.ChargeRecord">
select
cr.uid,
(ifnull(sum(cr.amount), 0)) as amount
from charge_record as cr
where cr.charge_status = 2
and cr.uid in
<foreach collection="uidList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
<if test="startTime != null and startTime != '' ">
and cr.create_time &gt;= #{startTime}
</if>
<if test="endTime != null and endTime != '' ">
and cr.create_time &lt; #{endTime}
</if>
group by cr.uid
</select>
</mapper> </mapper>

View File

@@ -66,39 +66,80 @@
</select> </select>
<!-- 用户明细全部分页查询 --> <!-- 用户明细全部分页查询 -->
<select id="userDetailList" resultType="com.accompany.admin.vo.stats.UserDeatilVo"> <select id="userDetailList" resultType="com.accompany.admin.vo.stats.UserDetailVo">
select select
u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.invite_uid,u.device_id, pi.`desc` as partitionDesc, u.uid,
ac.register_ip u.erban_no as erbanNo,
from u.nick,
( u.create_time as createTime,
select uid,erban_no,nick,create_time,channel,model,new_device,invite_code,invite_uid,device_id,partition_id from users u.channel,
<where> u.model,
def_user = 1 u.new_device as newDevice,
<if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' "> u.invite_code as inviteCode,
and erban_no = #{userDetailQueryDto.erbanNo} u.device_id as deviceId,
</if> u.partition_id as partitionId,
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' "> u.last_login_region as lastLoginRegion,
and phone = #{userDetailQueryDto.phone} if(u.gender = 1, '男', '女') as genderStr,
</if> pi.`desc` as partitionDesc,
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' "> a.register_ip as registerIp
and create_time &gt;= #{userDetailQueryDto.startDate} from users as u
</if> left join account as a on u.uid = a.uid
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and partition_id = #{userDetailQueryDto.partitionId}
</if>
</where>
) u
left join account ac on u.uid = ac.uid
left join partition_info as pi on pi.id = u.partition_id left join partition_info as pi on pi.id = u.partition_id
<if test="userDetailQueryDto.flowChannelType != null">
<if test="userDetailQueryDto.flowChannelType == 1">
inner join flow_team_member_invite_user as ftmiu on ftmiu.uid = u.uid
</if>
<if test="userDetailQueryDto.flowChannelType == 2">
inner join room_visitor_user_dict as rvud on rvud.uid = u.uid
</if>
</if>
where u.def_user = 1
<if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' ">
and u.erban_no = #{userDetailQueryDto.erbanNo}
</if>
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' ">
and u.phone = #{userDetailQueryDto.phone}
</if>
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' ">
and u.create_time &gt;= #{userDetailQueryDto.startDate}
</if>
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and u.create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and u.partition_id = #{userDetailQueryDto.partitionId}
</if>
<if test="userDetailQueryDto.flowChannelType != null and userDetailQueryDto.flowChannelType == 1">
and u.invite_code is not null and u.invite_code != ''
</if>
<if test="userDetailQueryDto.loginType != null">
and exists(
select 1 from account_login_record as alr
where alr.uid = u.uid and alr.login_type = #{userDetailQueryDto.loginType} and alr.record_id in (
select min(alr1.record_id) from account_login_record as alr1 where alr1.uid = u.uid
))
</if>
<if test="userDetailQueryDto.isCharge != null">
and (select count(1) from charge_record as cr where cr.charge_status = 2 and cr.uid = u.uid) > 0
</if>
<if test="userDetailQueryDto.firstRoomErBanNo != null">
and (
select
count(1)
from user_in_room_record as uirr
left join users as u1 on u1.uid = uirr.roomUid
where uirr.is_first = 1
and uirr.uid != uirr.roomUid
and u1.erban_no is not null
and uirr.uid = u.uid
and u1.erban_no = #{userDetailQueryDto.firstRoomErBanNo}
) > 0
</if>
order by u.create_time desc order by u.create_time desc
</select> </select>
<!--直播导流分页查询--> <!--直播导流分页查询-->
<select id="userLiveDetailList" resultType="com.accompany.admin.vo.stats.UserDeatilVo"> <select id="userLiveDetailList" resultType="com.accompany.admin.vo.stats.UserDetailVo">
select select
u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.invite_uid,u.device_id, u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.invite_uid,u.device_id,
ac.register_ip ac.register_ip
@@ -142,7 +183,7 @@
</select> </select>
<!--流量团队分页查询--> <!--流量团队分页查询-->
<select id="userDetailFlowTeamList" resultType="com.accompany.admin.vo.stats.UserDeatilVo"> <select id="userDetailFlowTeamList" resultType="com.accompany.admin.vo.stats.UserDetailVo">
select select
u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.device_id, u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.device_id,
ac.register_ip ac.register_ip
@@ -178,78 +219,86 @@
order by u.create_time desc order by u.create_time desc
</select> </select>
<!--直播导流分页查询--> <!--直播导流分页查询-->
<select id="userLiveDetailListV2" resultType="com.accompany.admin.vo.stats.UserDeatilVo"> <select id="userLiveDetailListV2" resultType="com.accompany.admin.vo.stats.UserDetailVo">
select select
u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.invite_uid,u.device_id, pi.`desc` as partitionDesc, u.uid,
ac.register_ip u.erban_no as erbanNo,
from u.nick,
( u.create_time as createTime,
select uid,erban_no,nick,create_time,channel,model,new_device,invite_code,invite_uid,device_id, partition_id from users u.channel,
<where> u.model,
def_user = 1 u.new_device as newDevice,
<if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' "> u.invite_code as inviteCode,
and erban_no = #{userDetailQueryDto.erbanNo} u.device_id as deviceId,
</if> u.partition_id as partitionId,
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' "> u.last_login_region as lastLoginRegion,
and phone = #{userDetailQueryDto.phone} u.gender,
</if> pi.`desc` as partitionDesc,
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' "> a.register_ip as registerIp
and create_time &gt;= #{userDetailQueryDto.startDate} from users as u
</if> left join account as a on u.uid = a.uid
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and partition_id = #{userDetailQueryDto.partitionId}
</if>
</where>
) u
left join account ac on u.uid = ac.uid
left join partition_info as pi on pi.id = u.partition_id left join partition_info as pi on pi.id = u.partition_id
<if test="userDetailQueryDto.flowChannelType != null and userDetailQueryDto.flowChannelType == 2 "> inner join room_visitor_user_dict as rvud on rvud.uid = u.uid
inner join room_visitor_user_dict rvud where u.def_user = 1
on rvud.uid = u.uid <if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' ">
and u.erban_no = #{userDetailQueryDto.erbanNo}
</if>
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' ">
and u.phone = #{userDetailQueryDto.phone}
</if>
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' ">
and u.create_time &gt;= #{userDetailQueryDto.startDate}
</if>
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and u.create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and u.partition_id = #{userDetailQueryDto.partitionId}
</if> </if>
order by u.create_time desc order by u.create_time desc
</select> </select>
<!--流量团队分页查询--> <!--流量团队分页查询-->
<select id="userDetailFlowTeamListV2" resultType="com.accompany.admin.vo.stats.UserDeatilVo"> <select id="userDetailFlowTeamListV2" resultType="com.accompany.admin.vo.stats.UserDetailVo">
select select
u.uid,u.erban_no,u.nick,u.create_time,u.channel,u.model,u.new_device,u.invite_code,u.device_id, pi.`desc` as partitionDesc, u.uid,
ac.register_ip u.erban_no as erbanNo,
from u.nick,
( u.create_time as createTime,
select uid,erban_no,nick,create_time,channel,model,new_device,invite_code,device_id, partition_id from users u.channel,
<where> u.model,
def_user = 1 u.new_device as newDevice,
<if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' "> u.invite_code as inviteCode,
and erban_no = #{userDetailQueryDto.erbanNo} u.device_id as deviceId,
</if> u.partition_id as partitionId,
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' "> u.last_login_region as lastLoginRegion,
and phone = #{userDetailQueryDto.phone} u.gender,
</if> pi.`desc` as partitionDesc,
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' "> a.register_ip as registerIp
and create_time &gt;= #{userDetailQueryDto.startDate} from users as u
</if> left join account as a on u.uid = a.uid
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and partition_id = #{userDetailQueryDto.partitionId}
</if>
<if test="userDetailQueryDto.flowChannelType != null and userDetailQueryDto.flowChannelType == 1 ">
and invite_code IS NOT NULL AND invite_code !=''
</if>
</where>
) u
left join account ac on u.uid = ac.uid
left join partition_info as pi on pi.id = u.partition_id left join partition_info as pi on pi.id = u.partition_id
inner join flow_team_member_invite_user as ftmiu on ftmiu.uid = u.uid
where u.def_user = 1
<if test="userDetailQueryDto.erbanNo != null and userDetailQueryDto.erbanNo != '' ">
and u.erban_no = #{userDetailQueryDto.erbanNo}
</if>
<if test="userDetailQueryDto.phone != null and userDetailQueryDto.phone != '' ">
and u.phone = #{userDetailQueryDto.phone}
</if>
<if test="userDetailQueryDto.startDate != null and userDetailQueryDto.startDate != '' ">
and u.create_time &gt;= #{userDetailQueryDto.startDate}
</if>
<if test="userDetailQueryDto.endDate != null and userDetailQueryDto.endDate != '' ">
and u.create_time &lt; #{userDetailQueryDto.endDate}
</if>
<if test="userDetailQueryDto.partitionId != null">
and u.partition_id = #{userDetailQueryDto.partitionId}
</if>
<if test="userDetailQueryDto.flowChannelType != null and userDetailQueryDto.flowChannelType == 1 "> <if test="userDetailQueryDto.flowChannelType != null and userDetailQueryDto.flowChannelType == 1 ">
inner join `flow_team_member_invite_user` ftiu on u.uid = ftiu.uid and u.invite_code is not null and u.invite_code !=''
</if> </if>
order by u.create_time desc order by u.create_time desc
</select> </select>

View File

@@ -1,11 +1,11 @@
package com.accompany.admin.controller.statistic; package com.accompany.admin.controller.statistic;
import com.accompany.admin.base.Pagination;
import com.accompany.admin.controller.BaseController; import com.accompany.admin.controller.BaseController;
import com.accompany.admin.dto.UserDetailQueryDto; import com.accompany.admin.dto.UserDetailQueryDto;
import com.accompany.admin.service.statistic.StatsUserDetailAdminService; import com.accompany.admin.service.statistic.StatsUserDetailAdminService;
import com.accompany.admin.vo.stats.UserDeatilVo; import com.accompany.admin.vo.stats.UserDetailVo;
import com.accompany.core.util.ExcelUtils; import com.accompany.core.util.ExcelUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -26,22 +26,19 @@ public class StatsUserDetailAdminController extends BaseController {
private StatsUserDetailAdminService statsUserDetailAdminService; private StatsUserDetailAdminService statsUserDetailAdminService;
@GetMapping("/list") @GetMapping("/list")
public void userDetailList(UserDetailQueryDto userDetailQueryDto) { public Pagination<UserDetailVo> userDetailList(UserDetailQueryDto userDetailQueryDto) {
PageInfo pageInfo = statsUserDetailAdminService.userDetailList(userDetailQueryDto); PageInfo<UserDetailVo> pageInfo = statsUserDetailAdminService.userDetailList(userDetailQueryDto);
JSONObject jsonObject = new JSONObject(); return new Pagination<>(pageInfo);
jsonObject.put("total",pageInfo.getTotal());
jsonObject.put("rows",pageInfo.getList());
writeJson(jsonObject.toJSONString());
} }
@PostMapping("/export") @PostMapping("/export")
public void exportUserDetailList(UserDetailQueryDto userDetailQueryDto, HttpServletResponse response) throws Exception { public void exportUserDetailList(UserDetailQueryDto query, HttpServletResponse response) throws Exception {
String filename = "userDetailExport"; String filename = "userDetailExport";
List<String> fields = Arrays.asList("uid", "erbanNo", "nick", "createTime", "inviteCodeinfo", "flowChannel", "channel", "model", "newDeviceStr", "registerIp", "firstChargeInfo", "partitionDesc"); List<String> fields = Arrays.asList("uid", "partitionDesc", "lastLoginRegion", "erbanNo", "nick", "createTime", "inviteCodeinfo", "flowChannel", "channel", "model", "newDeviceStr", "registerIp", "isChargeStr", "chargeAmount", "firstRoomErBanNo", "loginTypeStr", "genderStr");
userDetailQueryDto.setPageSize(60000); query.setPageSize(60000);
HashMap<String, Object> data = statsUserDetailAdminService.exportUserDetailList(userDetailQueryDto); HashMap<String, Object> data = statsUserDetailAdminService.exportUserDetailList(query);
ExcelUtils.exportExcel("新增用户明细", filename, fields, (List<UserDeatilVo>)data.get("rows"), response); ExcelUtils.exportExcel("新增用户明细", filename, fields, (List<UserDetailVo>) data.get("rows"), response);
} }
} }

View File

@@ -39,4 +39,11 @@ public interface AccountLoginRecordMapperExpand {
* @return * @return
*/ */
List<Long> getAnchorUidByRecent3Day(); List<Long> getAnchorUidByRecent3Day();
/**
* 获取登录方式
* @param uidList
* @return
*/
List<AccountLoginRecord> getLoginType(@Param("uidList") List<Long> uidList);
} }

View File

@@ -117,7 +117,7 @@ public class UsersBaseService extends BaseService {
} }
} }
public List<Users> getUsersListByUids(List<Long> uids){ public List<Users> getUsersListByUids(List<Long> uids) {
UsersExample usersExample = new UsersExample(); UsersExample usersExample = new UsersExample();
usersExample.createCriteria().andUidIn(uids); usersExample.createCriteria().andUidIn(uids);
List<Users> usersList = usersMapper.selectByExample(usersExample); List<Users> usersList = usersMapper.selectByExample(usersExample);
@@ -175,12 +175,12 @@ public class UsersBaseService extends BaseService {
* @param uids * @param uids
* @return * @return
*/ */
public List<Users> getUsersListByUidsFromDB(List<Long> uids){ public List<Users> getUsersListByUidsFromDB(List<Long> uids) {
Assert.notEmpty(uids, "uids is empty"); Assert.notEmpty(uids, "uids is empty");
UsersExample example = new UsersExample(); UsersExample example = new UsersExample();
example.createCriteria().andUidIn(uids); example.createCriteria().andUidIn(uids);
List<Users> users = usersMapper.selectByExample(example); List<Users> users = usersMapper.selectByExample(example);
if (CollectionUtils.isEmpty(users)){ if (CollectionUtils.isEmpty(users)) {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
return users; return users;
@@ -280,7 +280,7 @@ public class UsersBaseService extends BaseService {
return; return;
} }
String usersJson = gson.toJson(users); String usersJson = gson.toJson(users);
logger.info("debug_getUsersByUid,user={}",usersJson); logger.info("debug_getUsersByUid,user={}", usersJson);
jedisService.hwrite(RedisKey.user.getKey(), users.getUid().toString(), usersJson); jedisService.hwrite(RedisKey.user.getKey(), users.getUid().toString(), usersJson);
jedisService.hwrite(RedisKey.user_erban_no.getKey(), users.getErbanNo().toString(), usersJson); jedisService.hwrite(RedisKey.user_erban_no.getKey(), users.getErbanNo().toString(), usersJson);
@@ -320,7 +320,7 @@ public class UsersBaseService extends BaseService {
Users user = usersMapper.selectByPrimaryKey(uid); Users user = usersMapper.selectByPrimaryKey(uid);
if (user != null) { if (user != null) {
//如果手机号是平台号,则更换为靓号 //如果手机号是平台号,则更换为靓号
if (StringUtils.isBlank(user.getPhone()) || !CommonUtil.checkPhoneFormat(user.getPhoneAreaCode(),user.getPhone())) { if (StringUtils.isBlank(user.getPhone()) || !CommonUtil.checkPhoneFormat(user.getPhoneAreaCode(), user.getPhone())) {
user.setPhone(CommonUtil.genSpecialPhoneForInitAccount(String.valueOf(erbanNo))); user.setPhone(CommonUtil.genSpecialPhoneForInitAccount(String.valueOf(erbanNo)));
} }
user.setErbanNo(erbanNo); user.setErbanNo(erbanNo);
@@ -426,7 +426,8 @@ public class UsersBaseService extends BaseService {
if (StringUtils.isBlank(erbanNos)) return null; if (StringUtils.isBlank(erbanNos)) return null;
List<Long> erbanNoList = gson.fromJson(erbanNos, new TypeToken<List<Long>>() {}.getType()); List<Long> erbanNoList = gson.fromJson(erbanNos, new TypeToken<List<Long>>() {
}.getType());
if (CollectionUtils.isEmpty(erbanNoList)) return null; if (CollectionUtils.isEmpty(erbanNoList)) return null;
List<String> uidStrList = getUidByErbanNo(Arrays.asList(String.valueOf(erbanNoList.get(0)))); List<String> uidStrList = getUidByErbanNo(Arrays.asList(String.valueOf(erbanNoList.get(0))));
@@ -450,20 +451,20 @@ public class UsersBaseService extends BaseService {
} }
public void updateCache(Long uid, Long erbanNo) { public void updateCache(Long uid, Long erbanNo) {
if (null != uid){ if (null != uid) {
jedisService.hdel(RedisKey.uid_access_token.getKey(), uid.toString()); jedisService.hdel(RedisKey.uid_access_token.getKey(), uid.toString());
jedisService.hdel(RedisKey.uid_ticket.getKey(), uid.toString()); jedisService.hdel(RedisKey.uid_ticket.getKey(), uid.toString());
jedisService.hdel(RedisKey.user.getKey(), String.valueOf(uid)); jedisService.hdel(RedisKey.user.getKey(), String.valueOf(uid));
jedisService.hdel(RedisKey.user_summary.getKey(), String.valueOf(uid)); jedisService.hdel(RedisKey.user_summary.getKey(), String.valueOf(uid));
} }
if (null != erbanNo){ if (null != erbanNo) {
jedisService.hdel(RedisKey.user_erban_no.getKey(), String.valueOf(erbanNo)); jedisService.hdel(RedisKey.user_erban_no.getKey(), String.valueOf(erbanNo));
jedisService.del(RedisKey.cancel_user_recover_credentials.getKey(String.valueOf(erbanNo))); jedisService.del(RedisKey.cancel_user_recover_credentials.getKey(String.valueOf(erbanNo)));
} }
} }
public void changePartition(Long uid, Integer partitionId){ public void changePartition(Long uid, Integer partitionId) {
Users user = new Users(); Users user = new Users();
user.setUid(uid); user.setUid(uid);
user.setPartitionId(partitionId); user.setPartitionId(partitionId);

View File

@@ -68,4 +68,18 @@
and exists(select 1 from hall_member as hm where hm.status = 1 and hm.uid = alr.uid) and exists(select 1 from hall_member as hm where hm.status = 1 and hm.uid = alr.uid)
</select> </select>
<select id="getLoginType" resultType="com.accompany.core.model.AccountLoginRecord">
select
alr.uid,
alr.login_type as loginType
from account_login_record as alr where alr.record_id in (
select min(alr1.record_id) from account_login_record as alr1
where alr1.uid in
<foreach collection="uidList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
group by alr1.uid
)
</select>
</mapper> </mapper>

View File

@@ -25,4 +25,11 @@ public interface UserInRoomRecordMapper extends BaseMapper<UserInRoomRecord> {
List<UserInRoomRecord> getUserInRoomUidByUid(@Param("uid") Long uid, @Param("startDate") Date startDate, @Param("endDate") Date endDate); List<UserInRoomRecord> getUserInRoomUidByUid(@Param("uid") Long uid, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
/**
* 获取首次进房
* @param uidList
* @return
*/
List<UserInRoomRecord> getFirstRoom(@Param("uidList") List<Long> uidList);
} }

View File

@@ -1,6 +1,7 @@
package com.accompany.business.service.user; package com.accompany.business.service.user;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.accompany.business.event.room.UserInRoomEvent; import com.accompany.business.event.room.UserInRoomEvent;
import com.accompany.business.message.room.UserInRoomMessage; import com.accompany.business.message.room.UserInRoomMessage;
import com.accompany.business.model.UserInRoomRecord; import com.accompany.business.model.UserInRoomRecord;
@@ -99,7 +100,6 @@ public class UserInRoomService {
Map<Integer, Long> publicChatRoomIdMap = partitionInfoService.getPublicChatRoomIdMap(); Map<Integer, Long> publicChatRoomIdMap = partitionInfoService.getPublicChatRoomIdMap();
if (CollectionUtil.isEmpty(publicChatRoomIdMap) || !publicChatRoomIdMap.containsValue(roomVo.getRoomId())) { if (CollectionUtil.isEmpty(publicChatRoomIdMap) || !publicChatRoomIdMap.containsValue(roomVo.getRoomId())) {
saveUserInRoomCache(uid, roomVo); saveUserInRoomCache(uid, roomVo);
;
} }
applicationContext.publishEvent(new UserInRoomEvent(new UserInRoomMessage(uid, roomVo, Calendar.getInstance().getTime(), inviteUid, behaveType))); applicationContext.publishEvent(new UserInRoomEvent(new UserInRoomMessage(uid, roomVo, Calendar.getInstance().getTime(), inviteUid, behaveType)));
return roomVo; return roomVo;
@@ -235,6 +235,11 @@ public class UserInRoomService {
//保存进房记录 //保存进房记录
updateUserInRoomRecord(uid, roomUid, behaveType); updateUserInRoomRecord(uid, roomUid, behaveType);
saveRoomVisitorDict(uid, roomUid, enterTime); saveRoomVisitorDict(uid, roomUid, enterTime);
Users users = usersBaseService.getUsersByUid(uid);
if (users != null && users.getRoomUid() == null) {
users.setRoomUid(roomUid);
usersBaseService.updateUser(users);
}
// 记录活动用户 // 记录活动用户
jedisService.zadd(RedisKey.active_user_sortset.getKey(), (double) System.currentTimeMillis(), uid.toString()); jedisService.zadd(RedisKey.active_user_sortset.getKey(), (double) System.currentTimeMillis(), uid.toString());
} }

View File

@@ -39,4 +39,19 @@
and update_time &gt;= #{startDate} and update_time &lt;= #{endDate} and update_time &gt;= #{startDate} and update_time &lt;= #{endDate}
GROUP BY roomUid GROUP BY roomUid
</select> </select>
<select id="getFirstRoom" resultType="com.accompany.business.model.UserInRoomRecord">
select
uirr.uid,
u.erban_no as roomUid
from user_in_room_record as uirr
left join users as u on u.uid = uirr.roomUid
where uirr.is_first = 1
and uirr.uid != uirr.roomUid
and u.erban_no is not null
and uirr.uid in
<foreach collection="uidList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</select>
</mapper> </mapper>

View File

@@ -41,21 +41,21 @@ public enum LoginTypeEnum {
/** /**
* 谷歌登录 * 谷歌登录
*/ */
GOOGLE((byte)8), GOOGLE((byte) 8),
/** /**
* line登录 * line登录
*/ */
LINE((byte)9), LINE((byte) 9),
/** /**
* facebook登录 * facebook登录
*/ */
FACEBOOK((byte)10), FACEBOOK((byte) 10),
; ;
private byte value; private final byte value;
LoginTypeEnum(byte value) { LoginTypeEnum(byte value) {
this.value = value; this.value = value;

View File

@@ -80,19 +80,18 @@ public class AccountManageService {
protected Gson gson = new Gson(); protected Gson gson = new Gson();
public Account getOrGenAccountByPhone(String phone,String phoneAreaCode, String smsCode, DeviceInfo deviceInfo, String ipAddress) public Account getOrGenAccountByPhone(String phone, String phoneAreaCode, String smsCode, DeviceInfo deviceInfo, String ipAddress)
throws Exception { throws Exception {
log.info("getOrGenAccountByPhone phone:{},smsCode:{},phoneAreaCode{}",phone,smsCode,phoneAreaCode); log.info("getOrGenAccountByPhone phone:{},smsCode:{},phoneAreaCode{}", phone, smsCode, phoneAreaCode);
final String lockVal = jedisLockService.lock(RedisKey.lock_register_by_phone.getKey(phone)); final String lockVal = jedisLockService.lock(RedisKey.lock_register_by_phone.getKey(phone));
try { try {
if (BlankUtil.isBlank(lockVal)){ if (BlankUtil.isBlank(lockVal)) {
throw new ServiceException(BusiStatus.REQUEST_FAST); throw new ServiceException(BusiStatus.REQUEST_FAST);
} }
Account account = accountService.getAccountByPhone(phone); Account account = accountService.getAccountByPhone(phone);
if (account == null) { if (account == null) {
account = saveSignUpByPhone(phone,null, deviceInfo,ipAddress,phoneAreaCode); account = saveSignUpByPhone(phone, null, deviceInfo, ipAddress, phoneAreaCode);
} else { } else {
//account = fillDeviceInfo(account, deviceInfo);
String state = account.getState(); String state = account.getState();
if ("2".equals(state)) { if ("2".equals(state)) {
throw new CustomOAuth2Exception(CustomOAuth2Exception.INVALID_USER, throw new CustomOAuth2Exception(CustomOAuth2Exception.INVALID_USER,
@@ -111,15 +110,15 @@ public class AccountManageService {
public Account getOrGenAccountByOpenid(String openid, Byte type, DeviceInfo deviceInfo, String ipAddress, String unionId) throws Exception { public Account getOrGenAccountByOpenid(String openid, Byte type, DeviceInfo deviceInfo, String ipAddress, String unionId) throws Exception {
log.info("getOrGenAccountByOpenid openId:{},type:{},unionId:{}",openid,type,unionId); log.info("getOrGenAccountByOpenid openId:{},type:{},unionId:{}", openid, type, unionId);
final String locKey = RedisKey.lock_register_by_openid.getKey(openid, unionId, String.valueOf(type)); final String locKey = RedisKey.lock_register_by_openid.getKey(openid, unionId, String.valueOf(type));
final String lockVal = jedisLockService.lock(locKey, 10 * 1000); final String lockVal = jedisLockService.lock(locKey, 10 * 1000);
try { try {
if (BlankUtil.isBlank(lockVal)){ if (BlankUtil.isBlank(lockVal)) {
throw new ServiceException(BusiStatus.REQUEST_FAST); throw new ServiceException(BusiStatus.REQUEST_FAST);
} }
Account account = accountService.getAccountByThird(type, unionId, Account account = accountService.getAccountByThird(type, unionId,
LoginTypeEnum.GOOGLE.getValue() == type? deviceInfo.getApp(): null); LoginTypeEnum.GOOGLE.getValue() == type ? deviceInfo.getApp() : null);
if (account == null) { if (account == null) {
checkRegisterLimit(deviceInfo.getDeviceId(), ipAddress); checkRegisterLimit(deviceInfo.getDeviceId(), ipAddress);
@@ -177,27 +176,27 @@ public class AccountManageService {
} }
} }
private void checkRegisterLimit(String deviceId, String ipAddress){ private void checkRegisterLimit(String deviceId, String ipAddress) {
if (!StringUtils.hasText(deviceId)){ if (!StringUtils.hasText(deviceId)) {
throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.DEVICE_ERROR.getReasonPhrase()); throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.DEVICE_ERROR.getReasonPhrase());
} }
RepeatedDeviceIpRegisterLimitConfig repeatedConfig = getRepeatedDeviceIpLimitConfig(); RepeatedDeviceIpRegisterLimitConfig repeatedConfig = getRepeatedDeviceIpLimitConfig();
if (repeatedConfig.isOpen()){ if (repeatedConfig.isOpen()) {
int repeatedDeviceNum = accountService.lambdaQuery().eq(Account::getDeviceId, deviceId).count(); int repeatedDeviceNum = accountService.lambdaQuery().eq(Account::getDeviceId, deviceId).count();
if (repeatedDeviceNum >= repeatedConfig.getRepeatedDeviceNumLimit()){ if (repeatedDeviceNum >= repeatedConfig.getRepeatedDeviceNumLimit()) {
throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase()); throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
} }
int repeatedIpNum = accountService.lambdaQuery().eq(Account::getRegisterIp, ipAddress).count(); int repeatedIpNum = accountService.lambdaQuery().eq(Account::getRegisterIp, ipAddress).count();
if (repeatedIpNum >= repeatedConfig.getRepeatedIpNumLimit()){ if (repeatedIpNum >= repeatedConfig.getRepeatedIpNumLimit()) {
throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase()); throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
} }
} }
//当日单个ip注册数 //当日单个ip注册数
DayIpMaxRegisterLimitConfig config = getIpMaxLimitConfig(); DayIpMaxRegisterLimitConfig config = getIpMaxLimitConfig();
if (config.getOpen()){ if (config.getOpen()) {
int count = accountService.getRegisterIpCountByOneDay(ipAddress); int count = accountService.getRegisterIpCountByOneDay(ipAddress);
if (count >= config.getMax()) { if (count >= config.getMax()) {
throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase()); throw new CustomOAuth2Exception(CustomOAuth2Exception.SIGN_IP_TO_OFTEN, BusiStatus.REGISTER_FREQUENT.getReasonPhrase());
@@ -217,8 +216,8 @@ public class AccountManageService {
* @return * @return
*/ */
public Account saveSignUpByPhone(String phone, String password, DeviceInfo deviceInfo, public Account saveSignUpByPhone(String phone, String password, DeviceInfo deviceInfo,
String ipAddress,String phoneAreaCode) throws Exception { String ipAddress, String phoneAreaCode) throws Exception {
return saveSignUpByPhone(phone, password, deviceInfo, null, null, ipAddress,phoneAreaCode); return saveSignUpByPhone(phone, password, deviceInfo, null, null, ipAddress, phoneAreaCode);
} }
@@ -230,14 +229,14 @@ public class AccountManageService {
* @return * @return
*/ */
public Account saveSignUpByPhone(String phone, String password, DeviceInfo deviceInfo, String prefillInviteCode, Long prefillInviteUid, public Account saveSignUpByPhone(String phone, String password, DeviceInfo deviceInfo, String prefillInviteCode, Long prefillInviteUid,
String ipAddress,String phoneAreaCode) throws Exception { String ipAddress, String phoneAreaCode) throws Exception {
checkRegisterLimit(deviceInfo.getDeviceId(), ipAddress); checkRegisterLimit(deviceInfo.getDeviceId(), ipAddress);
Date date = new Date(); Date date = new Date();
Account account = new Account(); Account account = new Account();
account.setPhone(phone); account.setPhone(phone);
account.setPhoneAreaCode(phoneAreaCode); account.setPhoneAreaCode(phoneAreaCode);
if(!StringUtils.isEmpty(password)){ if (!StringUtils.isEmpty(password)) {
account.setPassword(encryptPassword(password)); account.setPassword(encryptPassword(password));
} }
account.setNeteaseToken(UUIDUtil.get()); account.setNeteaseToken(UUIDUtil.get());
@@ -307,7 +306,7 @@ public class AccountManageService {
throw new ServiceException(BusiStatus.USER_NOT_EXISTED); throw new ServiceException(BusiStatus.USER_NOT_EXISTED);
} }
phone = account.getPhone(); phone = account.getPhone();
if (!CommonUtil.checkPhoneFormat(account.getPhoneAreaCode(),account.getPhone())) { if (!CommonUtil.checkPhoneFormat(account.getPhoneAreaCode(), account.getPhone())) {
throw new ServiceException(BusiStatus.ACCOUNT_NOT_BIND_PHONE); throw new ServiceException(BusiStatus.ACCOUNT_NOT_BIND_PHONE);
} }
} }
@@ -318,19 +317,19 @@ public class AccountManageService {
} }
Account account = accountService.getAccountByPhone(phone); Account account = accountService.getAccountByPhone(phone);
if (null == account || (uid != null && !account.getUid().equals(uid)) ) { if (null == account || (uid != null && !account.getUid().equals(uid))) {
throw new ServiceException(BusiStatus.PHONE_BIND_ERROR); throw new ServiceException(BusiStatus.PHONE_BIND_ERROR);
} }
uid = account.getUid(); uid = account.getUid();
//检验验证码 //检验验证码
if (!accountService.verifySmsCodeByCache(phone, resetCode, uid)){ if (!accountService.verifySmsCodeByCache(phone, resetCode, uid)) {
throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_CODE); throw new ServiceException(BusiStatus.INVALID_IDENTIFYING_CODE);
} }
accountService.resetAccountPwd(account.getUid(), password); accountService.resetAccountPwd(account.getUid(), password);
//成功后删除验证码缓存 //成功后删除验证码缓存
accountService.delSmsCodeCache(phone,account.getUid()); accountService.delSmsCodeCache(phone, account.getUid());
//accountService.delNickPasswordCache(account.getErbanNo()); //accountService.delNickPasswordCache(account.getErbanNo());
// 删除用户信息缓存 // 删除用户信息缓存
jedisService.hdel(RedisKey.user.getKey(), account.getUid().toString()); jedisService.hdel(RedisKey.user.getKey(), account.getUid().toString());
@@ -346,7 +345,7 @@ public class AccountManageService {
String oldPwd = account.getPassword(); String oldPwd = account.getPassword();
password = encryptPassword(password); password = encryptPassword(password);
if (!StringUtils.hasText(password) || !password.equals(oldPwd)){ if (!StringUtils.hasText(password) || !password.equals(oldPwd)) {
throw new ServiceException(BusiStatus.OLD_PASSWORD_ERROR); throw new ServiceException(BusiStatus.OLD_PASSWORD_ERROR);
} }
@@ -355,7 +354,7 @@ public class AccountManageService {
//记录最近30天内绑定手机号 //记录最近30天内绑定手机号
jedisService.setex(RedisKey.modify_pwd_sign.getKey(String.valueOf(account.getUid())), jedisService.setex(RedisKey.modify_pwd_sign.getKey(String.valueOf(account.getUid())),
30 * 24 * 60 *60, String.valueOf(new Date().getTime())); 30 * 24 * 60 * 60, String.valueOf(new Date().getTime()));
} }
/** /**
@@ -371,7 +370,7 @@ public class AccountManageService {
} }
Boolean result = accountService.updateAccountPwd(account.getUid(), password); Boolean result = accountService.updateAccountPwd(account.getUid(), password);
if (!result){ if (!result) {
throw new ServiceException(BusiStatus.INVALID_REQUEST); throw new ServiceException(BusiStatus.INVALID_REQUEST);
} }
@@ -413,17 +412,17 @@ public class AccountManageService {
throw exception; throw exception;
} }
private DayIpMaxRegisterLimitConfig getIpMaxLimitConfig(){ private DayIpMaxRegisterLimitConfig getIpMaxLimitConfig() {
String config = sysConfService.getSysConfValueById(Constant.SysConfId.IP_MAX_REGISTER_LIMIT_CONFIG); String config = sysConfService.getSysConfValueById(Constant.SysConfId.IP_MAX_REGISTER_LIMIT_CONFIG);
if (!StringUtils.hasText(config)){ if (!StringUtils.hasText(config)) {
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG); throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
} }
return gson.fromJson(config, DayIpMaxRegisterLimitConfig.class); return gson.fromJson(config, DayIpMaxRegisterLimitConfig.class);
} }
private RepeatedDeviceIpRegisterLimitConfig getRepeatedDeviceIpLimitConfig(){ private RepeatedDeviceIpRegisterLimitConfig getRepeatedDeviceIpLimitConfig() {
String config = sysConfService.getSysConfValueById(Constant.SysConfId.REPEATED_DEVICE_IP_REGISTER_LIMIT_CONFIG); String config = sysConfService.getSysConfValueById(Constant.SysConfId.REPEATED_DEVICE_IP_REGISTER_LIMIT_CONFIG);
if (!StringUtils.hasText(config)){ if (!StringUtils.hasText(config)) {
throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG); throw new ServiceException(BusiStatus.ALREADY_NOTEXISTS_CONFIG);
} }
return gson.fromJson(config, RepeatedDeviceIpRegisterLimitConfig.class); return gson.fromJson(config, RepeatedDeviceIpRegisterLimitConfig.class);