x用户
This commit is contained in:
@@ -402,6 +402,11 @@ public class AdminUserService extends BaseService {
|
||||
return adminUserMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 特殊方法,不能当通用后台用
|
||||
* @param adminId
|
||||
* @return
|
||||
*/
|
||||
public AdminUserVo getByAdminId(Integer adminId) {
|
||||
AdminUser adminUserById = this.getAdminUserById(adminId);
|
||||
List<AdminRefUserRoleKey> roleByAdminId = adminRoleService.getRoleByAdminId(adminId);
|
||||
|
@@ -0,0 +1,98 @@
|
||||
package com.accompany.admin.controller.game;
|
||||
|
||||
import com.accompany.admin.controller.BaseController;
|
||||
import com.accompany.admin.model.AdminUser;
|
||||
import com.accompany.admin.service.system.AdminPartitionService;
|
||||
import com.accompany.admin.service.system.AdminUserService;
|
||||
import com.accompany.business.service.game.ChargeUserXDetailService;
|
||||
import com.accompany.business.vo.game.ChargeUserXDetailVo;
|
||||
import com.accompany.common.result.BusiResult;
|
||||
import com.accompany.common.utils.StringUtils;
|
||||
import com.accompany.core.exception.AdminServiceException;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.support.ExcelTypeEnum;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/chargeUserXDetail")
|
||||
public class ChargeUserXDetailAdminController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private AdminUserService adminUserService;
|
||||
@Autowired
|
||||
private AdminPartitionService adminPartitionService;
|
||||
@Autowired
|
||||
private ChargeUserXDetailService chargeUserXDetailService;
|
||||
|
||||
@GetMapping(value = "/list")
|
||||
public BusiResult<IPage<ChargeUserXDetailVo>> listPage(Long erbanNo, String ip,
|
||||
String device, Integer identity, Integer pageNo, Integer pageSize) {
|
||||
List<Integer> allPartitionId = adminPartitionService.getAllPartitionId(getAdminId());
|
||||
IPage<ChargeUserXDetailVo> ipage = chargeUserXDetailService.listPage(allPartitionId, erbanNo, ip, device, identity, pageNo, pageSize);
|
||||
return BusiResult.success(ipage);
|
||||
}
|
||||
|
||||
@ApiImplicitParam(paramType = "query", name = "erbanNos", value = "逗号隔开ID", required = false)
|
||||
@ApiOperation(value = "新增", httpMethod = "POST")
|
||||
@PostMapping(value = "/save")
|
||||
public BusiResult<Void> save(String erbanNos, String addReason) {
|
||||
if (erbanNos == null) {
|
||||
throw new AdminServiceException(5001, "请填写用户id");
|
||||
}
|
||||
AdminUser adminUserVo = adminUserService.getAdminUserById(getAdminId());
|
||||
|
||||
String[] split = erbanNos.split(",");
|
||||
List<Long> erbanNoList = new ArrayList<>();
|
||||
for (String erbanNo : split) {
|
||||
erbanNoList.add(Long.parseLong(erbanNo.trim()));
|
||||
}
|
||||
chargeUserXDetailService.saveDetail(erbanNoList, addReason, adminUserVo.getId(), adminUserVo.getUsername());
|
||||
return BusiResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除", httpMethod = "POST")
|
||||
@PostMapping(value = "/delete")
|
||||
public BusiResult<Void> delete(Long uid, String removeReason) {
|
||||
AdminUser adminUser = adminUserService.getAdminUserById(getAdminId());
|
||||
if (StringUtils.isEmpty(removeReason)) {
|
||||
throw new AdminServiceException(5001, "请填写删除原因");
|
||||
}
|
||||
chargeUserXDetailService.delete(uid, removeReason, adminUser.getId(), adminUser.getUsername());
|
||||
return BusiResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "导出", httpMethod = "POST")
|
||||
@PostMapping("/export")
|
||||
public void export(Long erbanNo, String ip, String device, Integer identity, HttpServletResponse response) throws IOException {
|
||||
List<Integer> allPartitionId = adminPartitionService.getAllPartitionId(getAdminId());
|
||||
IPage<ChargeUserXDetailVo> ipage = chargeUserXDetailService.listPage(allPartitionId, erbanNo, ip, device, identity, -1, -1);
|
||||
response.setContentType("application/vnd.ms-excel");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
// 这里URLEncoder.encode可以防止中文乱码
|
||||
String excelName = URLEncoder.encode("嫌疑人x用户", StandardCharsets.UTF_8);
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + excelName + ExcelTypeEnum.XLSX.getValue());
|
||||
EasyExcel.write(response.getOutputStream(), ChargeUserXDetailVo.class).sheet("嫌疑人x用户").doWrite(ipage.getRecords());
|
||||
}
|
||||
}
|
@@ -1396,6 +1396,8 @@ public class Constant {
|
||||
public static final String EXTRA_DIAMOND_RATE_CONFIG = "extra_diamond_rate_config";
|
||||
|
||||
public static final String CP_MIC_SVGA_URL = "cp_mic_svga_url";
|
||||
|
||||
public static String charge_user_x_gold = "charge_user_x_gold";
|
||||
}
|
||||
|
||||
public static class WithDrawStatus {
|
||||
|
@@ -1470,6 +1470,7 @@ public enum RedisKey {
|
||||
|
||||
guild_usd_withdraw_num, //公会薪资提现次数
|
||||
guild_usd_to_recharge_num,//公会薪资转代理次数
|
||||
charge_user_x_detail,//嫌疑用户
|
||||
;
|
||||
|
||||
public String getKey() {
|
||||
|
@@ -4,6 +4,7 @@ import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.payment.mapper.ChargeRecordMapperMgr;
|
||||
import com.accompany.payment.mapper.UserRechargeLevelMapper;
|
||||
import com.accompany.payment.model.UserRechargeLevel;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.redisson.api.RMapCache;
|
||||
import org.redisson.api.RedissonClient;
|
||||
@@ -13,7 +14,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -92,4 +95,10 @@ public class UserRechargeLevelService extends ServiceImpl<UserRechargeLevelMappe
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
cacheMap = redissonClient.getMapCache(RedisKey.user_recharge_level.getKey());
|
||||
}
|
||||
|
||||
public List<UserRechargeLevel> listByZeroTotalGold() {
|
||||
LambdaQueryWrapper<UserRechargeLevel> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(UserRechargeLevel::getTotalGold, 0);
|
||||
return baseMapper.selectList(queryWrapper);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package com.accompany.business.model.game;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* X嫌疑人用户表实体类
|
||||
*
|
||||
* @author
|
||||
* @since 2025-09-26
|
||||
*/
|
||||
@Data
|
||||
public class ChargeUserXDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long uid;
|
||||
/**
|
||||
* 用户身份 0 待评测 1嫌疑用户 2 充值用户 3后台删除用户
|
||||
*/
|
||||
private Integer identity;
|
||||
/**
|
||||
* h5小游戏支出
|
||||
*/
|
||||
private BigDecimal payGold;
|
||||
/**
|
||||
* h5小游戏获得
|
||||
*/
|
||||
private BigDecimal winGold;
|
||||
private String ip;
|
||||
private String deviceId;
|
||||
/**
|
||||
* 是否因为关联被记录,0-否,1-是
|
||||
*/
|
||||
private Integer refStatus;
|
||||
/**
|
||||
* 是否后台添加,0-否,1-是
|
||||
*/
|
||||
private Integer adminAdd;
|
||||
/**
|
||||
* 标记原因
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 移除原因
|
||||
*/
|
||||
private String removeReason;
|
||||
private Integer adminId;
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package com.accompany.business.model.game;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 嫌疑人ip,设备记录表实体类
|
||||
*
|
||||
* @author
|
||||
* @since 2025-09-26
|
||||
*/
|
||||
@Data
|
||||
public class ChargeUserXRecord implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long uid;
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 设备
|
||||
*/
|
||||
private String deviceId;
|
||||
/**
|
||||
* 类型 1ip 2设备
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 状态 1正常 2删除
|
||||
*/
|
||||
private Integer status;
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
package com.accompany.business.vo.game;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ChargeUserXDetailVo {
|
||||
|
||||
@ExcelProperty("用户ID")
|
||||
@ApiModelProperty("用户ID")
|
||||
private Long erbanNo;
|
||||
@ExcelProperty("用户等级")
|
||||
@ApiModelProperty("用户等级")
|
||||
private String chargeUserLevel;
|
||||
@ExcelProperty("用户UID")
|
||||
@ApiModelProperty("用户UID")
|
||||
private Long uid;
|
||||
|
||||
@ExcelProperty("用户昵称")
|
||||
@ApiModelProperty("用户昵称")
|
||||
private String nick;
|
||||
@ExcelProperty("用户国家")
|
||||
@ApiModelProperty("用户国家")
|
||||
private String regionName;
|
||||
@ExcelProperty("投入")
|
||||
@ApiModelProperty("投入")
|
||||
private BigDecimal payGold;
|
||||
/**
|
||||
* h5小游戏获得
|
||||
*/
|
||||
|
||||
@ExcelProperty("支出")
|
||||
@ApiModelProperty("支出")
|
||||
private BigDecimal winGold;
|
||||
|
||||
@ExcelProperty("差额")
|
||||
@ApiModelProperty("差额")
|
||||
private BigDecimal diff;
|
||||
|
||||
@ExcelProperty("ip")
|
||||
@ApiModelProperty("ip")
|
||||
private String ip;
|
||||
|
||||
@ExcelProperty("设备")
|
||||
@ApiModelProperty("设备")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 用户身份 0 待评测 1嫌疑用户 2 充值用户 3后台删除用户
|
||||
*/
|
||||
@ExcelProperty("当前是否为X身份 1嫌疑用户 2 充值用户 3后台删除用户")
|
||||
@ApiModelProperty("当前是否为X身份 1嫌疑用户 2 充值用户 3后台删除用户")
|
||||
private Integer identity;
|
||||
|
||||
/**
|
||||
* 标记原因
|
||||
*/
|
||||
@ExcelProperty("成为X身份标记原因")
|
||||
@ApiModelProperty("成为X身份标记原因")
|
||||
private String remark;
|
||||
/**
|
||||
* 移除原因
|
||||
*/
|
||||
|
||||
@ExcelProperty("取消X身份标记原因")
|
||||
@ApiModelProperty("取消X身份标记原因")
|
||||
private String removeReason;
|
||||
|
||||
}
|
@@ -10,4 +10,6 @@ public class GameUserInfoResponseVO {
|
||||
private Long coin;//玩家当前游戏币 必选
|
||||
private Integer vipLevel; //VIP等级 必选
|
||||
private Double water;
|
||||
//传1代表是特殊用户,不传或者其他是正常用户
|
||||
private Integer prizeLabel;
|
||||
}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
package com.accompany.business.mybatismapper.game;
|
||||
|
||||
import com.accompany.business.model.game.ChargeUserXDetail;
|
||||
import com.accompany.business.vo.game.ChargeUserXDetailVo;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@Mapper
|
||||
public interface ChargeUserXDetailMapper extends BaseMapper<ChargeUserXDetail> {
|
||||
|
||||
void updateCharge(@Param("uid") Long uid);
|
||||
|
||||
ChargeUserXDetail getRecord(@Param("uid") Long uid);
|
||||
|
||||
IPage<ChargeUserXDetailVo> listPage(@Param("page") Page<ChargeUserXDetailVo> page,
|
||||
@Param("partitionIds") List<Integer> partitionIds,
|
||||
@Param("erbanNo") Long erbanNo,
|
||||
@Param("ip") String ip,
|
||||
@Param("device") String device,
|
||||
@Param("identity") Integer identity);
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package com.accompany.business.mybatismapper.game;
|
||||
|
||||
import com.accompany.business.model.game.ChargeUserXRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@Mapper
|
||||
public interface ChargeUserXRecordMapper extends BaseMapper<ChargeUserXRecord> {
|
||||
|
||||
List<String> getLastThirtyXIp(@Param("uid") Long uid);
|
||||
|
||||
List<String> getLastThirtyXDevice(@Param("uid") Long uid);
|
||||
|
||||
ChargeUserXRecord getRecordByIp(@Param("loginIp") String loginIp);
|
||||
|
||||
ChargeUserXRecord deviceId(@Param("deviceId") String deviceId);
|
||||
|
||||
void deleteRecord(@Param("uid") Long uid);
|
||||
|
||||
IPage<ChargeUserXRecord> listPage(@Param("page") Page<ChargeUserXRecord> page, @Param("uid") Long uid, @Param("type") Integer type);
|
||||
}
|
@@ -19,4 +19,7 @@ public interface GameDayStatDataMapper extends BaseMapper<GameDayStatData> {
|
||||
|
||||
IPage<GameDataTotalVo> selectGroupDateList(IPage<GameDayStatData> iPage, @Param("channel") String channel, @Param("gameId") String gameId,
|
||||
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime, @Param("partitionId") Integer partitionId);
|
||||
|
||||
List<GameDayStatData> statByChannelUid4XRecord(@Param("channel") String channel, @Param("miniWin") Long miniWin);
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,188 @@
|
||||
package com.accompany.business.service.game;
|
||||
|
||||
import com.accompany.business.model.game.ChargeUserXDetail;
|
||||
import com.accompany.business.model.game.ChargeUserXRecord;
|
||||
import com.accompany.business.mybatismapper.game.ChargeUserXDetailMapper;
|
||||
import com.accompany.business.service.AccountLoginRecordService;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.business.vo.game.ChargeUserXDetailVo;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.core.exception.AdminServiceException;
|
||||
import com.accompany.core.model.AccountLoginRecord;
|
||||
import com.accompany.core.model.Users;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.redisson.api.RMap;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.codec.TypedJsonJacksonCodec;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@Service
|
||||
public class ChargeUserXDetailService extends ServiceImpl<ChargeUserXDetailMapper, ChargeUserXDetail> {
|
||||
@Autowired
|
||||
private AccountLoginRecordService accountLoginRecordService;
|
||||
@Autowired
|
||||
private ChargeUserXRecordService chargeUserXRecordService;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private UsersService usersService;
|
||||
|
||||
|
||||
public IPage<ChargeUserXDetailVo> listPage(List<Integer> partitionIds, Long erbanNo, String ip, String device, Integer identity, Integer pageNo, Integer pageSize) {
|
||||
Page<ChargeUserXDetailVo> page = new Page<>(pageNo, pageSize);
|
||||
if (CollectionUtils.isEmpty(partitionIds)) {
|
||||
return page;
|
||||
}
|
||||
return this.baseMapper.listPage(page, partitionIds, erbanNo, ip, device, identity);
|
||||
}
|
||||
|
||||
public void saveDetail(List<Long> erbanNos, String addReason, Integer adminId,String username) {
|
||||
List<Users> usersList = new ArrayList<>();
|
||||
for (Long erbanNo : erbanNos) {
|
||||
Users userByErbanNo = usersService.getUserByErbanNo(erbanNo);
|
||||
if (userByErbanNo == null) {
|
||||
throw new AdminServiceException(5001, "不存在该用户");
|
||||
}
|
||||
usersList.add(userByErbanNo);
|
||||
}
|
||||
String remark = "后台添加:[" + username + "]" + addReason;
|
||||
for (Users users : usersList) {
|
||||
Long uid = users.getUid();
|
||||
ChargeUserXDetail record = this.baseMapper.getRecord(uid);
|
||||
if (record != null) {
|
||||
if (record.getIdentity() != 1) {
|
||||
record.setIdentity(1);
|
||||
record.setRemark(remark);
|
||||
record.setRemoveReason("");
|
||||
record.setUpdateTime(new Date());
|
||||
record.setAdminId(adminId);
|
||||
record.setAdminAdd(1);
|
||||
this.updateById(record);
|
||||
this.delCache(uid);
|
||||
chargeUserXRecordService.saveRecord(uid);
|
||||
}
|
||||
|
||||
} else {
|
||||
ChargeUserXDetail chargeUserXDetail = new ChargeUserXDetail();
|
||||
AccountLoginRecord lastLogin = accountLoginRecordService.getLastLoginRecord(uid);
|
||||
if (lastLogin != null) {
|
||||
chargeUserXDetail.setIp(lastLogin.getLoginIp());
|
||||
chargeUserXDetail.setDeviceId(lastLogin.getDeviceId());
|
||||
}
|
||||
chargeUserXDetail.setAdminId(adminId);
|
||||
chargeUserXDetail.setAdminAdd(1);
|
||||
chargeUserXDetail.setUid(uid);
|
||||
chargeUserXDetail.setIdentity(1);
|
||||
chargeUserXDetail.setRemark(remark);
|
||||
this.save(chargeUserXDetail);
|
||||
this.delCache(uid);
|
||||
chargeUserXRecordService.saveRecord(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void delete(Long uid, String removeReason, Integer adminId, String username) {
|
||||
ChargeUserXDetail record = this.baseMapper.getRecord(uid);
|
||||
record.setIdentity(3);
|
||||
record.setUpdateTime(new Date());
|
||||
record.setRemoveReason("后台移除:" + username + ":" + removeReason);
|
||||
record.setAdminId(adminId);
|
||||
this.updateById(record);
|
||||
chargeUserXRecordService.deleteRecord(uid);
|
||||
this.delCache(uid);
|
||||
}
|
||||
|
||||
|
||||
public void updateCharge(Long uid) {
|
||||
ChargeUserXDetail record = this.baseMapper.getRecord(uid);
|
||||
if (record != null && record.getIdentity() == 1) {
|
||||
record.setIdentity(2);
|
||||
record.setRemoveReason("每日搜索:充值");
|
||||
record.setUpdateTime(new Date());
|
||||
this.updateById(record);
|
||||
this.delCache(uid);
|
||||
//删除记录
|
||||
chargeUserXRecordService.deleteRecord(uid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void delCache(Long uid) {
|
||||
detailCache().remove(uid);
|
||||
}
|
||||
|
||||
|
||||
public ChargeUserXDetail getRecord(Long uid) {
|
||||
ChargeUserXDetail value = detailCache().get(uid);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
ChargeUserXDetail chargeUserXDetail = this.baseMapper.getRecord(uid);
|
||||
if (chargeUserXDetail == null) {
|
||||
return null;
|
||||
}
|
||||
detailCache().put(uid, chargeUserXDetail);
|
||||
return chargeUserXDetail;
|
||||
}
|
||||
|
||||
public void check(Long uid) {
|
||||
ChargeUserXDetail chargeUserXDetail = new ChargeUserXDetail();
|
||||
AccountLoginRecord lastLogin = accountLoginRecordService.getLastLoginRecord(uid);
|
||||
if (lastLogin != null) {
|
||||
chargeUserXDetail.setUid(uid);
|
||||
chargeUserXDetail.setIp(lastLogin.getLoginIp());
|
||||
chargeUserXDetail.setDeviceId(lastLogin.getDeviceId());
|
||||
chargeUserXDetail.setIdentity(1);
|
||||
//进行iP检测
|
||||
ChargeUserXRecord recordByIp = chargeUserXRecordService.getRecordByIp(lastLogin.getLoginIp());
|
||||
String remark = "注册关联,关联记录id:{0}";
|
||||
ChargeUserXRecord recordByDevice = chargeUserXRecordService.getRecordByDevice(lastLogin.getDeviceId());
|
||||
if (recordByDevice != null) {
|
||||
chargeUserXDetail.setRemark(MessageFormat.format(remark, recordByDevice.getId()));
|
||||
this.save(chargeUserXDetail);
|
||||
this.delCache(uid);
|
||||
chargeUserXRecordService.saveRecord(uid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordByIp != null) {
|
||||
chargeUserXDetail.setRemark(MessageFormat.format(remark, recordByIp.getId()));
|
||||
this.save(chargeUserXDetail);
|
||||
this.delCache(uid);
|
||||
chargeUserXRecordService.saveRecord(uid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public List<ChargeUserXDetail> listExistAutoRecord() {
|
||||
LambdaQueryWrapper<ChargeUserXDetail> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ChargeUserXDetail::getIdentity, 1)
|
||||
.gt(ChargeUserXDetail::getRefStatus, 0);
|
||||
return this.baseMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
public RMap<Long, ChargeUserXDetail> detailCache() {
|
||||
String key = RedisKey.charge_user_x_detail.getKey();
|
||||
return redissonClient.getMap(key, new TypedJsonJacksonCodec(Long.class, ChargeUserXDetail.class));
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package com.accompany.business.service.game;
|
||||
|
||||
import com.accompany.business.model.game.ChargeUserXRecord;
|
||||
import com.accompany.business.mybatismapper.game.ChargeUserXRecordMapper;
|
||||
import com.accompany.business.param.BasePageParams;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-30
|
||||
*/
|
||||
@Service
|
||||
public class ChargeUserXRecordService extends ServiceImpl<ChargeUserXRecordMapper, ChargeUserXRecord> {
|
||||
|
||||
public IPage<ChargeUserXRecord> listPage(BasePageParams basePageParams, Long uid, Integer type) {
|
||||
Page<ChargeUserXRecord> page = new Page<>(basePageParams.getPageNo(),basePageParams.getPageSize());
|
||||
return this.baseMapper.listPage(page,uid, type);
|
||||
}
|
||||
|
||||
public void saveRecord(Long uid) {
|
||||
List<String> ips = this.baseMapper.getLastThirtyXIp(uid);
|
||||
if (!CollectionUtils.isEmpty(ips)){
|
||||
List<ChargeUserXRecord> chargeUserXRecords = new ArrayList<>();
|
||||
for (String ip : ips) {
|
||||
ChargeUserXRecord chargeUserXRecord = new ChargeUserXRecord();
|
||||
chargeUserXRecord.setUid(uid);
|
||||
chargeUserXRecord.setIp(ip);
|
||||
chargeUserXRecord.setType(1);
|
||||
chargeUserXRecords.add(chargeUserXRecord);
|
||||
}
|
||||
this.saveBatch(chargeUserXRecords);
|
||||
}
|
||||
List<String> devices = this.baseMapper.getLastThirtyXDevice(uid);
|
||||
if (!CollectionUtils.isEmpty(devices)){
|
||||
List<ChargeUserXRecord> chargeUserXRecords = new ArrayList<>();
|
||||
for (String device : devices) {
|
||||
ChargeUserXRecord chargeUserXRecord = new ChargeUserXRecord();
|
||||
chargeUserXRecord.setUid(uid);
|
||||
chargeUserXRecord.setDeviceId(device);
|
||||
chargeUserXRecord.setType(2);
|
||||
chargeUserXRecords.add(chargeUserXRecord);
|
||||
}
|
||||
this.saveBatch(chargeUserXRecords);
|
||||
}
|
||||
}
|
||||
|
||||
public ChargeUserXRecord getRecordByIp(String loginIp) {
|
||||
return this.baseMapper.getRecordByIp(loginIp);
|
||||
}
|
||||
|
||||
public ChargeUserXRecord getRecordByDevice(String deviceId) {
|
||||
return this.baseMapper.deviceId(deviceId);
|
||||
}
|
||||
|
||||
public void deleteRecord(Long uid) {
|
||||
this.baseMapper.deleteRecord(uid);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
package com.accompany.business.service.game;
|
||||
|
||||
import com.accompany.business.model.game.ChargeUserXDetail;
|
||||
import com.accompany.business.model.game.GameDayStatData;
|
||||
import com.accompany.business.service.AccountLoginRecordService;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.constant.GameConstant;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.payment.model.UserRechargeLevel;
|
||||
import com.accompany.payment.service.UserRechargeLevelService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户充值等级 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author wxf
|
||||
* @since 2025-06-19
|
||||
*/
|
||||
@Service
|
||||
public class ChargeUserXService {
|
||||
|
||||
@Autowired
|
||||
private GameDayStatDataService gameDayStatDataService;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
@Autowired
|
||||
private UsersService usersService;
|
||||
@Autowired
|
||||
private AccountLoginRecordService accountLoginRecordService;
|
||||
@Autowired
|
||||
private ChargeUserXDetailService chargeUserXDetailService;
|
||||
@Autowired
|
||||
private UserRechargeLevelService rechargeLevelService;
|
||||
|
||||
|
||||
public void updateUserX(Date date) {
|
||||
List<UserRechargeLevel> zeroChargeList = rechargeLevelService.listByZeroTotalGold();
|
||||
List<ChargeUserXDetail> chargeUserXDetails = chargeUserXDetailService.listExistAutoRecord();
|
||||
|
||||
//无总充值为0的用户
|
||||
if (CollectionUtils.isEmpty(zeroChargeList)) {
|
||||
if (CollectionUtils.isNotEmpty(chargeUserXDetails)) {
|
||||
chargeUserXDetails.stream().forEach(x -> {
|
||||
x.setIdentity(2);
|
||||
x.setUpdateTime(date);
|
||||
});
|
||||
chargeUserXDetailService.saveOrUpdateBatch(chargeUserXDetails);
|
||||
chargeUserXDetailService.detailCache().delete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
String value = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.charge_user_x_gold, "200000");
|
||||
Map<Long, GameDayStatData> gameDayStatDataMap = gameDayStatDataService.statByChannelUid4XRecord(GameConstant.GameChannel.LEADERCC.name(), Long.valueOf(value));
|
||||
|
||||
List<Long> zeroChargeUidList = new ArrayList<>();
|
||||
List<Long> existXUidList = new ArrayList<>();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(zeroChargeList)) {
|
||||
zeroChargeUidList = zeroChargeList.stream().map(UserRechargeLevel::getUid).toList();
|
||||
}
|
||||
|
||||
Map<Long, ChargeUserXDetail> existXMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(chargeUserXDetails)) {
|
||||
existXMap = chargeUserXDetails.stream().collect(Collectors.toMap(ChargeUserXDetail::getUid, v -> v));
|
||||
for (ChargeUserXDetail x : chargeUserXDetails) {
|
||||
if (zeroChargeUidList.contains(x.getUid())) {
|
||||
GameDayStatData gameDayStatData = gameDayStatDataMap.get(x.getUid());
|
||||
if (gameDayStatData != null) {
|
||||
x.setPayGold(gameDayStatData.getPayGold());
|
||||
x.setWinGold(gameDayStatData.getWinGold());
|
||||
x.setUpdateTime(date);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
x.setIdentity(2);
|
||||
x.setUpdateTime(date);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(zeroChargeList)) {
|
||||
for (UserRechargeLevel zeroCharge : zeroChargeList) {
|
||||
if (existXMap.containsKey(zeroCharge.getUid())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void initChargeUserX() {
|
||||
}
|
||||
|
||||
|
||||
private void sendMsg() {
|
||||
}
|
||||
|
||||
|
||||
public void initDetail() {
|
||||
|
||||
}
|
||||
}
|
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 游戏日统计表 服务类
|
||||
@@ -43,4 +44,6 @@ public interface GameDayStatDataService extends IService<GameDayStatData> {
|
||||
void statDayList(String channel, Date statTime);
|
||||
|
||||
GameUserDataDetailVo userTotalALL(Long erbanNo, String channel, String gameId, String startDate, String endDate, List<Integer> rolePartitionIds);
|
||||
|
||||
Map<Long, GameDayStatData> statByChannelUid4XRecord(String channel, Long miniWin);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import com.accompany.business.config.LeaderccMiniGameConfig;
|
||||
import com.accompany.business.enums.resource.ResourceCodeEnum;
|
||||
import com.accompany.business.message.GameMsgMessage;
|
||||
import com.accompany.business.model.UserPurse;
|
||||
import com.accompany.business.model.game.ChargeUserXDetail;
|
||||
import com.accompany.business.model.game.GameFeeRateConfig;
|
||||
import com.accompany.business.model.game.GameFeeRateUserRechargeLevelConfig;
|
||||
import com.accompany.business.service.mq.RocketMQService;
|
||||
@@ -33,10 +34,7 @@ import org.redisson.client.codec.StringCodec;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -71,6 +69,8 @@ public class GameService {
|
||||
private GameFeeRateUserRechargeLevelConfigService gameFeeRateUserRechargeLevelConfigService;
|
||||
@Autowired
|
||||
private RocketMQService rocketMQService;
|
||||
@Autowired
|
||||
private ChargeUserXDetailService chargeUserXDetailService;
|
||||
|
||||
public static final String ALL = "All";
|
||||
|
||||
@@ -110,6 +110,7 @@ public class GameService {
|
||||
vo.setNickname(users.getNick());
|
||||
vo.setUid(param.getUid());
|
||||
vo.setWater(this.getGameFeeRate(uid, param.getGameId()));
|
||||
vo.setPrizeLabel(this.getPrizeLabel(uid));
|
||||
return vo;
|
||||
}
|
||||
|
||||
@@ -287,4 +288,18 @@ public class GameService {
|
||||
}
|
||||
return gameConfigVOS;
|
||||
}
|
||||
|
||||
|
||||
private Integer getPrizeLabel(Long uid) {
|
||||
ChargeUserXDetail record = chargeUserXDetailService.getRecord(uid);
|
||||
if (record == null){
|
||||
return 0;
|
||||
}
|
||||
Integer identity = record.getIdentity();
|
||||
List<Integer> cancelTypes = Arrays.asList(2, 3);
|
||||
if (record.getIdentity() != null && cancelTypes.contains(record.getIdentity())) {
|
||||
return -1;
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
@@ -580,4 +580,13 @@ public class GameDayStatDataServiceImpl extends ServiceImpl<GameDayStatDataMappe
|
||||
}
|
||||
return gameUserDataDetailVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, GameDayStatData> statByChannelUid4XRecord(String channel, Long miniWin) {
|
||||
List<GameDayStatData> gameDayStatDatas = baseMapper.statByChannelUid4XRecord(channel, miniWin);
|
||||
if (CollectionUtils.isEmpty(gameDayStatDatas)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return gameDayStatDatas.stream().collect(Collectors.toMap(GameDayStatData::getUid, v -> v));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,48 @@
|
||||
<?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.accompany.business.mybatismapper.game.ChargeUserXDetailMapper">
|
||||
|
||||
<update id="updateCharge">
|
||||
UPDATE `charge_user_x_detail`
|
||||
SET `identity` = 2
|
||||
WHERE `uid` = #{uid};
|
||||
</update>
|
||||
<select id="getRecord" resultType="com.accompany.business.model.game.ChargeUserXDetail">
|
||||
select *
|
||||
from charge_user_x_detail
|
||||
where uid = #{uid}
|
||||
</select>
|
||||
<select id="listPage" resultType="com.accompany.business.vo.game.ChargeUserXDetailVo">
|
||||
select cuxd.*,
|
||||
u.erban_no,
|
||||
u.nick,
|
||||
ri.name regionName,
|
||||
u.partition_id partitionId,
|
||||
cuxd.win_gold - cuxd.pay_gold diff,
|
||||
cul.`level` chargeUserLevel
|
||||
from charge_user_x_detail cuxd
|
||||
left join users u on cuxd.uid = u.uid
|
||||
left join user_recharge_level cul on cul.uid = cuxd.uid
|
||||
left join region_info ri on u.region_id = ri.id
|
||||
where
|
||||
<foreach collection="partitionIds" open="u.partition_id in(" separator="," item="pi" close=")">
|
||||
#{pi}
|
||||
</foreach>
|
||||
<if test="erbanNo != null">
|
||||
and u.erban_no = #{erbanNo}
|
||||
</if>
|
||||
<if test="identity != null and identity == 1">
|
||||
and cuxd.identity = #{identity}
|
||||
</if>
|
||||
<if test="identity != null and identity != 1">
|
||||
and not cuxd.identity = 1
|
||||
</if>
|
||||
<if test="ip != null">
|
||||
and cuxd.uid in (select uid from charge_user_x_record where type = 1 and ip = #{ip})
|
||||
</if>
|
||||
<if test="device != null">
|
||||
and cuxd.uid in (select uid from charge_user_x_record where type = 2 and device_id = #{device})
|
||||
</if>
|
||||
order by cuxd.update_time desc
|
||||
</select>
|
||||
</mapper>
|
@@ -0,0 +1,22 @@
|
||||
<?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.accompany.business.mybatismapper.game.ChargeUserXRecordMapper">
|
||||
<update id="deleteRecord">
|
||||
UPDATE `charge_user_x_record` SET `status` = 2 WHERE `uid` = #{uid};
|
||||
</update>
|
||||
<select id="getLastThirtyXIp" resultType="java.lang.String">
|
||||
select login_ip from account_login_record where uid = #{uid} and create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) group by login_ip
|
||||
</select>
|
||||
<select id="getLastThirtyXDevice" resultType="java.lang.String">
|
||||
select device_id from account_login_record where uid = #{uid} and create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) group by device_id
|
||||
</select>
|
||||
<select id="deviceId" resultType="com.accompany.business.model.game.ChargeUserXRecord">
|
||||
select * from charge_user_x_record where type = 2 and device_id = #{deviceId} and status = 1 limit 1
|
||||
</select>
|
||||
<select id="getRecordByIp" resultType="com.accompany.business.model.game.ChargeUserXRecord">
|
||||
select * from charge_user_x_record where type = 1 and ip = #{loginIp} and status = 1 limit 1
|
||||
</select>
|
||||
<select id="listPage" resultType="com.accompany.business.model.game.ChargeUserXRecord">
|
||||
select * from charge_user_x_record where uid = #{uid} and status = 1 and type = #{type}
|
||||
</select>
|
||||
</mapper>
|
@@ -27,4 +27,17 @@
|
||||
group by stat_date
|
||||
order by stat_date desc
|
||||
</select>
|
||||
|
||||
<select id="statByChannelUid4XRecord" resultType="com.accompany.business.model.game.GameDayStatData">
|
||||
select uid,
|
||||
sum(pay_gold) payGold,
|
||||
sum(win_gold) winGold
|
||||
from game_day_stat_data
|
||||
where channel = #{channel}
|
||||
GROUP BY
|
||||
uid
|
||||
HAVING
|
||||
winGold - payGold > #{miniWin}
|
||||
|
||||
</select>
|
||||
</mapper>
|
||||
|
@@ -0,0 +1,20 @@
|
||||
package com.accompany.scheduler.task.game;
|
||||
|
||||
import com.accompany.business.service.game.ChargeUserXService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class ChargeUserXTask {
|
||||
|
||||
@Autowired
|
||||
private ChargeUserXService chargeUserXService;
|
||||
|
||||
@Scheduled(cron = "0 0 4 * * *")
|
||||
public void statDayList() {
|
||||
chargeUserXService.updateUserX(new Date());
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@ public class GameDayStatDataTask {
|
||||
@Autowired
|
||||
private GameDayStatDataService gameDayStatDataService;
|
||||
|
||||
@Scheduled(cron = "0 0 9 * * *")
|
||||
@Scheduled(cron = "0 0 10 * * *")
|
||||
public void statDayList() {
|
||||
for (GameConstant.GameChannel gameChannel : GameConstant.GameChannel.values()) {
|
||||
gameDayStatDataService.statDayList(gameChannel.name(), new Date());
|
||||
|
Reference in New Issue
Block a user