azizi签到处理

This commit is contained in:
tianfeng 2026-02-12 19:33:59 +08:00
parent cc291ce9f6
commit 466d517205
2 changed files with 85 additions and 16 deletions

View File

@ -6,6 +6,7 @@ import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.app.dto.cmd.task.CheckInRewardCmd;
import com.red.circle.other.app.util.EnhancedDeviceUtil;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.props.PropsSendCommon;
import com.red.circle.other.infra.database.cache.key.CheckInKeys;
@ -13,6 +14,7 @@ import com.red.circle.other.infra.database.cache.service.other.CheckInCacheServi
import com.red.circle.other.infra.database.rds.entity.activity.LotteryDeviceRecord;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRewardConfig;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRuleConfig;
import com.red.circle.other.infra.database.rds.entity.user.user.LatestMobileDevice;
import com.red.circle.other.infra.database.rds.service.activity.LotteryDeviceRecordService;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRewardConfigService;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRuleConfigService;
@ -126,8 +128,6 @@ public class CheckInExe {
.setQuantity(config.getQuantity())))
);
recordDeviceAfterDraw(AZIZI_FIXED_ACTIVITY_ID, cmd.getReqUserId());
return checkInCacheService.getCheckInDays(sevenCheckInKey);
} finally {
@ -139,31 +139,33 @@ public class CheckInExe {
* 校验设备唯一性防止小号薅羊毛
*/
private void checkDeviceUnique(Long activityId, Long userId) {
String fingerprint = latestMobileDeviceService.getEnhancedDeviceFingerprintByUserId(userId);
LatestMobileDevice device = latestMobileDeviceService.getByUserId(userId);
if (StringUtils.isBlank(fingerprint)) {
if (device == null) {
return;
}
LotteryDeviceRecord existingRecord = lotteryDeviceRecordService
.getByActivityAndFingerprint(activityId, fingerprint);
// 1. 先用新指纹查询不含IMEI
String fingerprintV2 = EnhancedDeviceUtil.buildEnhancedDeviceFingerprintV2(device);
LotteryDeviceRecord existingRecord = lotteryDeviceRecordService.getByActivityAndFingerprint(activityId, fingerprintV2);
if (existingRecord != null && !existingRecord.getUserId().equals(userId)) {
ResponseAssert.isTrue(OtherErrorCode.DEVICE_ALREADY_USED, false);
}
}
/**
* 记录设备信息
*/
private void recordDeviceAfterDraw(Long activityId, Long userId) {
try {
String fingerprint = latestMobileDeviceService.getEnhancedDeviceFingerprintByUserId(userId);
if (StringUtils.isNotBlank(fingerprint)) {
lotteryDeviceRecordService.recordDevice(activityId, userId, fingerprint);
// 2. 兜底再用旧指纹查询含IMEI- 兼容历史数据
String fingerprintV1 = EnhancedDeviceUtil.buildEnhancedDeviceFingerprint(device);
if (!fingerprintV1.equals(fingerprintV2)) { // 只有当两个指纹不同时才需要再查一次
LotteryDeviceRecord existingRecordV1 = lotteryDeviceRecordService
.getByActivityAndFingerprint(activityId, fingerprintV1);
if (existingRecordV1 != null && !existingRecordV1.getUserId().equals(userId)) {
ResponseAssert.isTrue(OtherErrorCode.DEVICE_ALREADY_USED, false);
}
} catch (Exception e) {
}
lotteryDeviceRecordService.recordDevice(activityId, userId, fingerprintV2);
}
/**

View File

@ -0,0 +1,67 @@
package com.red.circle.other.app.util;
import com.alibaba.nacos.common.utils.StringUtils;
import com.red.circle.other.infra.database.rds.entity.user.user.LatestMobileDevice;
import java.util.Objects;
public class EnhancedDeviceUtil {
/**
* 构建增强版设备指纹新版本 - 不含IMEI
* 组成手机型号 + 系统版本 + IP段 + 编译版本
*/
public static String buildEnhancedDeviceFingerprintV2(LatestMobileDevice device) {
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.isBlank(device.getPhoneModel()) ? "" : device.getPhoneModel()).append("|");
sb.append(StringUtils.isBlank(device.getPhoneSysVersion()) ? "" : device.getPhoneSysVersion()).append("|");
sb.append(getIpPrefix(device.getIp())).append("|");
sb.append(Objects.nonNull(device.getBuildVersion()) ? device.getBuildVersion() : 0);
return sb.toString();
}
/**
* 构建增强版设备指纹
* 组成手机型号 + 系统版本 + IMEI + IP段 + 编译版本
*/
public static String buildEnhancedDeviceFingerprint(LatestMobileDevice device) {
StringBuilder sb = new StringBuilder();
sb.append(com.red.circle.tool.core.text.StringUtils.isBlank(device.getPhoneModel()) ? "" : device.getPhoneModel()).append("|");
sb.append(com.red.circle.tool.core.text.StringUtils.isBlank(device.getPhoneSysVersion()) ? "" : device.getPhoneSysVersion()).append("|");
sb.append(com.red.circle.tool.core.text.StringUtils.isBlank(device.getImei()) ? "" : device.getImei()).append("|");
sb.append(getIpPrefix(device.getIp())).append("|");
sb.append(Objects.nonNull(device.getBuildVersion()) ? device.getBuildVersion() : 0);
return sb.toString();
}
/**
* 获取IP前缀段提高稳定性
* IPv4: 取前3段 192.168.1.xxx -> 192.168.1
* IPv6: 取前4段 2a0d:5600:24:449:xxx -> 2a0d:5600:24:449
*/
private static String getIpPrefix(String ip) {
if (com.red.circle.tool.core.text.StringUtils.isBlank(ip)) {
return "";
}
if (ip.contains(":")) {
String[] parts = ip.split(":");
if (parts.length >= 4) {
return parts[0] + ":" + parts[1] + ":" + parts[2] + ":" + parts[3];
}
return ip;
} else {
String[] parts = ip.split("\\.");
if (parts.length >= 3) {
return parts[0] + "." + parts[1] + "." + parts[2];
}
return ip;
}
}
}