领取奖励增加设备指纹校验

This commit is contained in:
tianfeng 2025-12-31 14:33:24 +08:00
parent 6e906a7f15
commit 8f5ef2b9f4

View File

@ -9,8 +9,11 @@ import com.red.circle.other.app.dto.clientobject.activity.ClaimRewardResultCO;
import com.red.circle.other.app.dto.cmd.activity.ClaimActivityRewardCmd;
import com.red.circle.other.domain.gateway.props.ActivitySourceGroupGateway;
import com.red.circle.other.infra.database.rds.dao.activity.UserActivityRewardClaimDAO;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryDeviceRecord;
import com.red.circle.other.infra.database.rds.entity.activity.UserActivityRewardClaim;
import com.red.circle.other.infra.database.rds.service.activity.LotteryDeviceRecordService;
import com.red.circle.other.infra.database.rds.service.activity.UserActivityRechargeService;
import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.endpoint.activity.LotteryTicketClient;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
@ -41,12 +44,17 @@ public class ClaimActivityRewardExe {
private final UserActivityRechargeService userActivityRechargeService;
private final UserActivityRewardClaimDAO userActivityRewardClaimDAO;
private final LotteryTicketClient lotteryTicketClient;
private final LatestMobileDeviceService latestMobileDeviceService;
private final LotteryDeviceRecordService lotteryDeviceRecordService;
@Transactional(rollbackFor = Exception.class)
public ClaimRewardResultCO execute(ClaimActivityRewardCmd cmd) {
PropsActivityTypeEnum activityType = PropsActivityTypeEnum.valueOf(cmd.getActivityType());
SysOriginPlatformEnum sysOrigin = SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin());
// 2. 校验设备唯一性防止小号薅羊毛
checkDeviceUnique(cmd.getActivityId(), cmd.getReqUserId());
List<ActivityPropsRule> ruleConfigs = activitySourceGroupGateway.listRule(sysOrigin, activityType);
ActivityPropsRule targetRule = ruleConfigs.stream()
.filter(rule -> Objects.equals(rule.getId(), cmd.getRuleId()))
@ -108,6 +116,27 @@ public class ClaimActivityRewardExe {
.setLotteryTicketIds(ticketIds);
}
/**
* 校验设备唯一性防止小号薅羊毛
*/
private void checkDeviceUnique(Long activityId, Long userId) {
String fingerprint = latestMobileDeviceService.getEnhancedDeviceFingerprintByUserId(userId);
if (com.red.circle.tool.core.text.StringUtils.isBlank(fingerprint)) {
log.warn("Failed to get device fingerprint, userId: {}", userId);
return;
}
LotteryDeviceRecord existingRecord = lotteryDeviceRecordService
.getByActivityAndFingerprint(activityId, fingerprint);
if (existingRecord != null && !existingRecord.getUserId().equals(userId)) {
log.warn("Duplicate device detected, activityId: {}, currentUser: {}, boundUser: {}, fingerprint: {}",
activityId, userId, existingRecord.getUserId(), fingerprint);
ResponseAssert.isTrue(OtherErrorCode.DEVICE_ALREADY_USED, false);
}
}
private BigDecimal parseRequiredAmount(String jsonData) {
if (StrUtil.isBlank(jsonData)) {
return null;