|
|
@@ -3059,6 +3059,110 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String retryGptActivityRedeemCode(long userId, Long relationId) throws Exception {
|
|
|
+ List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
|
|
|
+ if (CollUtil.isEmpty(userIds)) {
|
|
|
+ userIds = List.of(userId);
|
|
|
+ }
|
|
|
+ String lockKey = String.format("%s:%s", RedisKey.GPT_API_QUOTA_KEY, Collections.min(userIds));
|
|
|
+ String lockToken = UUID.randomUUID().toString();
|
|
|
+ if (!redisService.setNx(lockKey, lockToken, 60L)) {
|
|
|
+ throw BusinessRuntimeException.getInstance("兑换码正在发放,请稍后再试");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ TicketRedemptionCodeRecord record = ticketRedemptionCodeRecordMapper.selectOne(Wrappers.lambdaQuery(TicketRedemptionCodeRecord.class)
|
|
|
+ .eq(TicketRedemptionCodeRecord::getRelationId, relationId)
|
|
|
+ .in(TicketRedemptionCodeRecord::getUserId, userIds)
|
|
|
+ .eq(TicketRedemptionCodeRecord::getSkuId, Constant.GPT_ACTIVITY_GIFT_SKU_ID)
|
|
|
+ .in(TicketRedemptionCodeRecord::getStatus, List.of("error", "processing"))
|
|
|
+ .isNotNull(TicketRedemptionCodeRecord::getErrorMsg)
|
|
|
+ .ne(TicketRedemptionCodeRecord::getErrorMsg, "")
|
|
|
+ .orderByDesc(TicketRedemptionCodeRecord::getId)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (record == null) {
|
|
|
+ throw BusinessRuntimeException.getInstance("兑换码不存在,请联系客服");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 老记录未落 quota/redeemName 时,按原领取规则还原参数。
|
|
|
+ String redeemName = resolveRetryRedeemName(record);
|
|
|
+ Integer quota = resolveRetryGptApiQuota(record);
|
|
|
+ GptActivityRedeemResult redeemResult = requestGptActivityRedeemCode(
|
|
|
+ Constant.AI_API_SVC_DOMAIN,
|
|
|
+ redeemName,
|
|
|
+ quota);
|
|
|
+ record.setRedeemCode(redeemResult.getRedeemCode());
|
|
|
+ record.setQuota(redeemResult.getQuota());
|
|
|
+ record.setRedeemCount(0);
|
|
|
+ record.setExpiredTime(redeemResult.getExpiredTime());
|
|
|
+ record.setApiResponse(redeemResult.getApiResponse());
|
|
|
+ record.setStatus("success");
|
|
|
+ record.setErrorMsg(null);
|
|
|
+ if (ticketRedemptionCodeRecordMapper.updateById(record) != 1) {
|
|
|
+ throw BusinessRuntimeException.getInstance("额度发放结果待确认,请联系客服,勿重复领取");
|
|
|
+ }
|
|
|
+ return redeemResult.getRedeemCode();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 远端调用可能已成功但响应丢失,继续保留 processing;仅有错误信息时允许下次查询重试。
|
|
|
+ record.setStatus("processing");
|
|
|
+ record.setErrorMsg(StringUtil.getErrorText(e));
|
|
|
+ try {
|
|
|
+ ticketRedemptionCodeRecordMapper.updateById(record);
|
|
|
+ } catch (Exception persistenceError) {
|
|
|
+ e.addSuppressed(persistenceError);
|
|
|
+ log.error("GPT API quota retry result persistence failed, recordId={}", record.getId(), persistenceError);
|
|
|
+ }
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ redisService.deleteIfValueEquals(lockKey, lockToken);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private Integer resolveRetryGptApiQuota(TicketRedemptionCodeRecord record) {
|
|
|
+ if (record.getQuota() != null && record.getQuota() > 0) {
|
|
|
+ return record.getQuota();
|
|
|
+ }
|
|
|
+ //学生认证
|
|
|
+ if (RedisKey.STUDENT_CERT_GPT_API_QUOTA_KEY.equals(record.getSourceType())) {
|
|
|
+ return DEFAULT_API_QUOTA;
|
|
|
+ }
|
|
|
+ //为null 检查手动兑换
|
|
|
+ throw BusinessRuntimeException.getInstance("兑换码不存在,请联系客服");
|
|
|
+
|
|
|
+// Long userId = record.getUserId();
|
|
|
+// Long relationId = record.getRelationId();
|
|
|
+// GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
|
|
|
+// .eq(GroupsRelation::getId, relationId)
|
|
|
+// .eq(GroupsRelation::getUserId, userId)
|
|
|
+// .in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.validity.name(), GroupsRelation.Status.outside.name()))
|
|
|
+// .last("limit 1"));
|
|
|
+// if (relation == null) {
|
|
|
+// throw BusinessRuntimeException.getInstance("车票不存在");
|
|
|
+// }
|
|
|
+// GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
|
|
|
+// GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
|
|
|
+// boolean yearQuota = isYearRechargeSku(goodsDonSku.getGoodsId(), goodsDonSku.getMonths(), goodsDonSku.getNum());
|
|
|
+// return yearQuota ? YEAR_RECHARGE_API_QUOTA : DEFAULT_API_QUOTA;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String resolveRetryRedeemName(TicketRedemptionCodeRecord record) {
|
|
|
+ if (StrUtil.isNotBlank(record.getRedeemName())) {
|
|
|
+ return record.getRedeemName();
|
|
|
+ }
|
|
|
+ if (RedisKey.GPT_API_QUOTA_KEY.equals(record.getSourceType())) {
|
|
|
+ return GPT_ACTIVITY_REDEEM_NAME;
|
|
|
+ }
|
|
|
+ if (RedisKey.STUDENT_CERT_GPT_API_QUOTA_KEY.equals(record.getSourceType())) {
|
|
|
+ return STUDENT_CERT_API_QUOTA_REDEEM_NAME;
|
|
|
+ }
|
|
|
+ throw BusinessRuntimeException.getInstance("兑换码不存在,请联系客服");
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public ReceiveGptActivityTicketResp receiveStudentCertGptApiQuotaTicket(long userId, Integer quota) throws Exception {
|
|
|
List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, null);
|