Kaynağa Gözat

新增:卡密激活平台cdk.aicnm.cc

mutao 4 ay önce
ebeveyn
işleme
50d3aa8739

+ 6 - 0
netflix-common/src/main/java/com/cyksj/common/constant/Constant.java

@@ -828,11 +828,17 @@ public interface Constant {
      */
     Long HIBOY_PRO_ONE_CHANNEL_ID = 11L;
 
+
     /**
      * HIBOY-pro$200
      */
     Long HIBOY_PRO_TWO_CHANNEL_ID = 12L;
 
+	/**
+	 * cdk.aicnm
+	 */
+	Long CDK_AICNM_CHANNEL_ID = 13L;
+
 	/**
 	 * Adobe 全家桶
 	 */

+ 21 - 0
netflix-dao/src/main/java/com/cyksj/model/response/recharge/CdkAicnmCardKeyLookupResp.java

@@ -0,0 +1,21 @@
+package com.cyksj.model.response.recharge;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CdkAicnmCardKeyLookupResp {
+    @JsonProperty("activated_at")
+    private String activatedAt;
+
+    private String email;
+
+    private Boolean exists;
+
+    private String status;
+
+    @JsonProperty("type_key")
+    private String typeKey;
+}

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/response/recharge/CdkAicnmRedeemStartResp.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.response.recharge;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CdkAicnmRedeemStartResp {
+    @JsonProperty("activated_at")
+    private String activatedAt;
+
+    private String code;
+
+    @JsonProperty("created_at")
+    private Double createdAt;
+
+    private Boolean done;
+
+    private String email;
+
+    @JsonProperty("finished_at")
+    private Double finishedAt;
+
+    @JsonProperty("job_id")
+    private String jobId;
+
+    private String message;
+
+    private Boolean ok;
+
+    private Boolean success;
+
+    @JsonProperty("trace_id")
+    private String traceId;
+}

+ 283 - 276
netflix-service/src/main/java/com/cyksj/server/recharge/impl/GptProxyRechargeServiceImpl.java

@@ -55,25 +55,27 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
 
     private final OrderDonMapper orderDonMapper;
 
-	private final GptUserRechargeRecordService gptUserRechargeRecordService;
+    private final GptUserRechargeRecordService gptUserRechargeRecordService;
 
-	private final RedisService redisService;
+    private final RedisService redisService;
 
-	private final GptRechargeCardKeyChannelService gptRechargeCardKeyChannelService;
+    private final GptRechargeCardKeyChannelService gptRechargeCardKeyChannelService;
 
-	private final AfDianRechargeService afDianRechargeService;
+    private final AfDianRechargeService afDianRechargeService;
 
-	private final ChongAfDianRechargeService chongAfDianRechargeService;
+    private final ChongAfDianRechargeService chongAfDianRechargeService;
 
     private final YearAfDianRechargeService yearAfDianRechargeService;
 
     private final GoAfDianRechargeService goAfDianRechargeService;
+    private final CdkAicnmRechargeService cdkAicnmRechargeService;
+
 
     private final HiBoyRechargeService hiBoyRechargeService;
 
-	private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
+    private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
 
-	private HttpRequest createBaseRequest(String url) {
+    private HttpRequest createBaseRequest(String url) {
         return HttpRequest.get(url)
                 .header("accept", "application/json, text/plain, */*")
                 .header("accept-language", "zh-CN,zh;q=0.9,en;q=0.8")
@@ -85,15 +87,15 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
     public CardKeyValidationResult validateCardKey(String cardKey) {
         log.info("开始验证卡密: {}", cardKey);
         try {
-	        String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-	        HttpResponse response = createBaseRequest(BASE_URL + "/card-keys/" + cardKey)
-			        .execute();
+            String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
+            HttpResponse response = createBaseRequest(BASE_URL + "/card-keys/" + cardKey)
+                    .execute();
             String body = response.body();
             log.info("卡密验证响应: {}", body);
-            
+
             JSONObject jsonResponse = JSONUtil.parseObj(body);
             CardKeyValidationResult result = new CardKeyValidationResult(
-                jsonResponse.getBool("available")
+                    jsonResponse.getBool("available")
             );
             //{"available":false,"error":"卡密已被使用"}
             log.info("卡密验证结果: {}", result);
@@ -107,11 +109,11 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
     public TokenParseResult parseToken(String accessToken) {
         log.info("开始验证凭证: {}", accessToken.substring(0, Math.min(20, accessToken.length())) + "...");
         try {
-	        String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(null);
-	        String url = BASE_URL + "/parse-token";
+            String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(null);
+            String url = BASE_URL + "/parse-token";
             JSONObject requestBody = new JSONObject();
             requestBody.put("access_token", accessToken);
-            
+
             HttpResponse response = HttpRequest.post(url)
                     .header("accept", "application/json, text/plain, */*")
                     .header("accept-language", "zh-CN,zh;q=0.9,en;q=0.8")
@@ -123,11 +125,11 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
                     .execute();
             String body = response.body();
             log.info("凭证验证响应: {}", body);
-            
+
             JSONObject jsonResponse = JSONUtil.parseObj(body);
             TokenParseResult result = new TokenParseResult(
-                jsonResponse.getStr("message"),
-                jsonResponse.getBool("success")
+                    jsonResponse.getStr("message"),
+                    jsonResponse.getBool("success")
             );
             log.info("凭证验证结果: {}", result);
             return result;
@@ -140,16 +142,16 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
     public TaskSubmitResult submitTask(String cardKey, String accessToken, String idp) {
         log.info("开始提交任务 - 卡密: {}, idp: {}", cardKey, idp);
         try {
-	        String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-	        String url = BASE_URL + "/tasks";
+            String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
+            String url = BASE_URL + "/tasks";
             JSONObject requestBody = new JSONObject();
             requestBody.put("card_key", cardKey);
             requestBody.put("access_token", accessToken);
             requestBody.put("idp", idp);
-            
+
             HttpResponse response = HttpRequest.post(url)
-		            .setConnectionTimeout(60000)
-		            .header("accept", "application/json, text/plain, */*")
+                    .setConnectionTimeout(60000)
+                    .header("accept", "application/json, text/plain, */*")
                     .header("accept-language", "zh-CN,zh;q=0.9,en;q=0.8")
                     .header("content-type", "application/json")
                     .header("origin", "https://www.ow520.com")
@@ -159,11 +161,11 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
                     .execute();
             String body = response.body();
             log.info("任务提交响应: {}", body);
-            
+
             JSONObject jsonResponse = JSONUtil.parseObj(body);
             TaskSubmitResult result = new TaskSubmitResult(
-                jsonResponse.getStr("task_id"),
-                jsonResponse.getBool("success")
+                    jsonResponse.getStr("task_id"),
+                    jsonResponse.getBool("success")
             );
             log.info("任务提交结果: {}", result);
             return result;
@@ -194,22 +196,22 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
         }
         log.info("开始查询任务结果: {}", taskId);
         try {
-	        GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-			        .eq(GroupsRelation::getGptTaskId, taskId)
-			        .last("limit 1"));
-	        if (relation == null) {
-		        return null;
-	        }
-	        String cardKey = relation.getCardKey();
-	        GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class).eq(GptRechargeCardKey::getCardKey, cardKey).last("limit 1"));
-	        if (gptRechargeCardKey.getChannelId() == Constant.AF_DIAN_CHANNEL_ID) {
-		        return afDianRechargeService.getTaskResult(relation);
-	        }
-			if (gptRechargeCardKey.getChannelId()==Constant.CHONG_AF_DIAN_CHANNEL_ID){
-				return chongAfDianRechargeService.getTaskResult(relation);
-			}
-	        String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-	        String url = BASE_URL + "/tasks/" + taskId;
+            GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+                    .eq(GroupsRelation::getGptTaskId, taskId)
+                    .last("limit 1"));
+            if (relation == null) {
+                return null;
+            }
+            String cardKey = relation.getCardKey();
+            GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class).eq(GptRechargeCardKey::getCardKey, cardKey).last("limit 1"));
+            if (gptRechargeCardKey.getChannelId() == Constant.AF_DIAN_CHANNEL_ID) {
+                return afDianRechargeService.getTaskResult(relation);
+            }
+            if (gptRechargeCardKey.getChannelId() == Constant.CHONG_AF_DIAN_CHANNEL_ID) {
+                return chongAfDianRechargeService.getTaskResult(relation);
+            }
+            String BASE_URL = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
+            String url = BASE_URL + "/tasks/" + taskId;
             HttpResponse response = createBaseRequest(url)
                     .execute();
             String body = response.body();
@@ -217,58 +219,58 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
 
             JSONObject jsonResponse = JSONUtil.parseObj(body);
             TaskResult result = new TaskResult(
-                jsonResponse.getStr("status"),
-                jsonResponse.getStr("result"),
-                jsonResponse.getStr("error")
+                    jsonResponse.getStr("status"),
+                    jsonResponse.getStr("result"),
+                    jsonResponse.getStr("error")
             );
             log.info("任务查询结果: {}", result);
-	        String status = result.getStatus();
-	        String resultResult = Optional.ofNullable(result.getError()).orElse(result.getResult());
-			//更新代充状态
-			resetGroupsRelationRechargeStatus(relation, status, resultResult);
-	        return result;
+            String status = result.getStatus();
+            String resultResult = Optional.ofNullable(result.getError()).orElse(result.getResult());
+            //更新代充状态
+            resetGroupsRelationRechargeStatus(relation, status, resultResult);
+            return result;
         } catch (Exception e) {
             log.error("获取任务结果失败: {}", e.getMessage(), e);
             throw new RuntimeException("获取任务结果失败: " + e.getMessage(), e);
         }
     }
 
-	@Override
-	@Transactional(rollbackFor = Throwable.class)
-	public String confirmRecharge(GroupsRelationRechargeReq req) {
-		Long relationId = req.getRelationId();
-		Long userId = req.getUserId();
-		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
-		GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
-				.in(GroupsRelation::getUserId, userIdList)
-				.eq(GroupsRelation::getId, relationId)
-				.eq(GroupsRelation::getStatus, GroupsRelation.Status.validity));
-		if (relation == null) {
-			throw BusinessRuntimeException.getInstance("车票不存在");
-		}
-		String userAccount = relation.getAccount();
-		GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
-		GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public String confirmRecharge(GroupsRelationRechargeReq req) {
+        Long relationId = req.getRelationId();
+        Long userId = req.getUserId();
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+                .in(GroupsRelation::getUserId, userIdList)
+                .eq(GroupsRelation::getId, relationId)
+                .eq(GroupsRelation::getStatus, GroupsRelation.Status.validity));
+        if (relation == null) {
+            throw BusinessRuntimeException.getInstance("车票不存在");
+        }
+        String userAccount = relation.getAccount();
+        GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+        GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
 //		//GPT 代充
 //		if (sku.getGoodsId() != Constant.GPT_RECHARGE_GOODS_ID) {
 //			throw BusinessRuntimeException.getInstance("车票类型错误");
 //		}
-		Integer rechargeNum = relation.getRechargeNum();
-		Integer rechargeRemainNum = relation.getRechargeRemainNum();
-		if (rechargeRemainNum == null || rechargeRemainNum <= 0) {
-			throw BusinessRuntimeException.getInstance("剩余可代充次数为0");
-		}
-		if (relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharging) {
-			throw BusinessRuntimeException.getInstance("确认充值中");
-		}
-		if (relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharge_error) {
-			throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
-		}
-		String key = RedisService.key.GPT_RECHARGE_KEY.getName() + relationId;
-		boolean b = redisService.setNx(key, relationId, RedisService.key.GPT_RECHARGE_KEY.getTimeout());
-		if (!b) {
-			throw BusinessRuntimeException.getInstance("确认充值中");
-		}
+        Integer rechargeNum = relation.getRechargeNum();
+        Integer rechargeRemainNum = relation.getRechargeRemainNum();
+        if (rechargeRemainNum == null || rechargeRemainNum <= 0) {
+            throw BusinessRuntimeException.getInstance("剩余可代充次数为0");
+        }
+        if (relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharging) {
+            throw BusinessRuntimeException.getInstance("确认充值中");
+        }
+        if (relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharge_error) {
+            throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+        }
+        String key = RedisService.key.GPT_RECHARGE_KEY.getName() + relationId;
+        boolean b = redisService.setNx(key, relationId, RedisService.key.GPT_RECHARGE_KEY.getTimeout());
+        if (!b) {
+            throw BusinessRuntimeException.getInstance("确认充值中");
+        }
         Integer subRechargeNum = 1;
         Integer specificChannel = null;
         //活动gpt代充类型
@@ -280,217 +282,222 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
         if (sku.getRechargeChannelId() != null) {
             specificChannel = sku.getRechargeChannelId();
         }
-		try {
-			int updateRemainNum = relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-					.set(GroupsRelation::getRechargeRemainNum, rechargeRemainNum - subRechargeNum)
-					.eq(GroupsRelation::getId, relationId)
-					.eq(GroupsRelation::getUserId, relation.getUserId())
-					.eq(GroupsRelation::getRechargeRemainNum, rechargeRemainNum));
-			if (updateRemainNum == 0) {
-				throw BusinessRuntimeException.getInstance("代充异常,请重试");
-			}
-			OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
-					.in(OrderDon::getUserId, userIdList)
-					.eq(OrderDon::getRelationId, relationId)
-					.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
-					.orderByDesc(OrderDon::getId)
-					.last("limit 1"));
-			if (orderDon == null) {
-				throw BusinessRuntimeException.getInstance("代充订单不存在或已退款");
-			}
-			//入库token json
-			String saveTokenJson = req.getAccessToken();
-			String accessToken;
-			try {
-				GptCardTokenDto gptCardTokenDto = Jsons.parseObject(saveTokenJson, GptCardTokenDto.class);
-				accessToken = gptCardTokenDto.getAccessToken();
-			} catch (Exception e) {
-				accessToken = saveTokenJson;
-			}
-			//验证用户token是否正确
-			TokenParseResult tokenParseResult = parseToken(accessToken);
-			if (!tokenParseResult.getSuccess()) {
-				throw BusinessRuntimeException.getInstance("您输入的凭证有误,请重新输入");
-			}
-			String rechargeAccount = tokenParseResult.getMessage();
-			//月付校验前后账号是否一致
-			if (sku.getMonths() == 1 && !StrUtil.equals(rechargeAccount, userAccount)) {
-				throw BusinessRuntimeException.getInstance("请填入绑定账号的token");
-			}
-			//记录代充账号 token
-			relation.setGptToken(saveTokenJson);
-			relation.setAccount(rechargeAccount);
-			//获取GPT代充key
-			//代充卡密类型
-			Integer gptRechargeCardKeyType = 0;
-			//若是季、年付 且首月代充
-			if (sku.getMonths() > 1 && rechargeNum == rechargeRemainNum) {
-				gptRechargeCardKeyType = 1;
-			}
-			GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class)
-					.eq(GptRechargeCardKey::getType, gptRechargeCardKeyType)
-					.eq(GptRechargeCardKey::getStatus, Boolean.FALSE)
+        try {
+            int updateRemainNum = relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                    .set(GroupsRelation::getRechargeRemainNum, rechargeRemainNum - subRechargeNum)
+                    .eq(GroupsRelation::getId, relationId)
+                    .eq(GroupsRelation::getUserId, relation.getUserId())
+                    .eq(GroupsRelation::getRechargeRemainNum, rechargeRemainNum));
+            if (updateRemainNum == 0) {
+                throw BusinessRuntimeException.getInstance("代充异常,请重试");
+            }
+            OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+                    .in(OrderDon::getUserId, userIdList)
+                    .eq(OrderDon::getRelationId, relationId)
+                    .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+                    .orderByDesc(OrderDon::getId)
+                    .last("limit 1"));
+            if (orderDon == null) {
+                throw BusinessRuntimeException.getInstance("代充订单不存在或已退款");
+            }
+            //入库token json
+            String saveTokenJson = req.getAccessToken();
+            String accessToken;
+            try {
+                GptCardTokenDto gptCardTokenDto = Jsons.parseObject(saveTokenJson, GptCardTokenDto.class);
+                accessToken = gptCardTokenDto.getAccessToken();
+            } catch (Exception e) {
+                accessToken = saveTokenJson;
+            }
+            //验证用户token是否正确
+            TokenParseResult tokenParseResult = parseToken(accessToken);
+            if (!tokenParseResult.getSuccess()) {
+                throw BusinessRuntimeException.getInstance("您输入的凭证有误,请重新输入");
+            }
+            String rechargeAccount = tokenParseResult.getMessage();
+            //月付校验前后账号是否一致
+            if (sku.getMonths() == 1 && !StrUtil.equals(rechargeAccount, userAccount)) {
+                throw BusinessRuntimeException.getInstance("请填入绑定账号的token");
+            }
+            //记录代充账号 token
+            relation.setGptToken(saveTokenJson);
+            relation.setAccount(rechargeAccount);
+            //获取GPT代充key
+            //代充卡密类型
+            Integer gptRechargeCardKeyType = 0;
+            //若是季、年付 且首月代充
+            if (sku.getMonths() > 1 && rechargeNum == rechargeRemainNum) {
+                gptRechargeCardKeyType = 1;
+            }
+            GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class)
+                    .eq(GptRechargeCardKey::getType, gptRechargeCardKeyType)
+                    .eq(GptRechargeCardKey::getStatus, Boolean.FALSE)
                     .eq(specificChannel != null, GptRechargeCardKey::getChannelId, specificChannel)
                     .notIn(specificChannel == null, GptRechargeCardKey::getChannelId, List.of(Constant.YEAR_AF_DIAN_CHANNEL_ID, Constant.HIBOY_PRO_ONE_CHANNEL_ID, Constant.HIBOY_PRO_TWO_CHANNEL_ID))
                     .last("order by channel_id desc, rand() limit 1"));
-			//季、年付卡密不存在 从月付代充卡密中获取
-			if (gptRechargeCardKey == null && gptRechargeCardKeyType == 1) {
+            //季、年付卡密不存在 从月付代充卡密中获取
+            if (gptRechargeCardKey == null && gptRechargeCardKeyType == 1) {
                 gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class)
                         .eq(GptRechargeCardKey::getType, 0)
                         .eq(GptRechargeCardKey::getStatus, Boolean.FALSE)
                         .eq(specificChannel != null, GptRechargeCardKey::getChannelId, specificChannel)
                         .notIn(specificChannel == null, GptRechargeCardKey::getChannelId, List.of(Constant.YEAR_AF_DIAN_CHANNEL_ID, Constant.HIBOY_PRO_ONE_CHANNEL_ID, Constant.HIBOY_PRO_TWO_CHANNEL_ID))
                         .last("order by channel_id desc, rand() limit 1"));
-			}
-			if (gptRechargeCardKey == null) {
-				setRechargeRelationStatusAutoError(relation);
-				throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
-			}
-			int update = gptRechargeCardKeyMapper.update(null, Wrappers.lambdaUpdate(GptRechargeCardKey.class)
-					.set(GptRechargeCardKey::getStatus, Boolean.TRUE)
-					.set(GptRechargeCardKey::getOrderId, orderDon.getId())
-					.set(GptRechargeCardKey::getUpdateTime, DateTime.now())
-					.set(GptRechargeCardKey::getOrderNo, orderDon.getOrderNo())
-					.eq(GptRechargeCardKey::getId, gptRechargeCardKey.getId())
-					.eq(GptRechargeCardKey::getStatus, Boolean.FALSE));
-			if (update == 0) {
-				setRechargeRelationStatusAutoError(relation);
-				throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
-			}
-			String gptCardKey = gptRechargeCardKey.getCardKey();
-
-			Long channelId = gptRechargeCardKey.getChannelId();
-			//AF dian
-			if (channelId == Constant.AF_DIAN_CHANNEL_ID) {
-				return afDianRechargeService.confirmRecharge(relation, gptCardKey, null);
-			}
-			//chong.afdian
-			if (channelId == Constant.CHONG_AF_DIAN_CHANNEL_ID) {
-				return chongAfDianRechargeService.confirmRecharge(relation, gptCardKey, null);
-			}
+            }
+            if (gptRechargeCardKey == null) {
+                setRechargeRelationStatusAutoError(relation);
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            int update = gptRechargeCardKeyMapper.update(null, Wrappers.lambdaUpdate(GptRechargeCardKey.class)
+                    .set(GptRechargeCardKey::getStatus, Boolean.TRUE)
+                    .set(GptRechargeCardKey::getOrderId, orderDon.getId())
+                    .set(GptRechargeCardKey::getUpdateTime, DateTime.now())
+                    .set(GptRechargeCardKey::getOrderNo, orderDon.getOrderNo())
+                    .eq(GptRechargeCardKey::getId, gptRechargeCardKey.getId())
+                    .eq(GptRechargeCardKey::getStatus, Boolean.FALSE));
+            if (update == 0) {
+                setRechargeRelationStatusAutoError(relation);
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            String gptCardKey = gptRechargeCardKey.getCardKey();
+
+            Long channelId = gptRechargeCardKey.getChannelId();
+            //AF dian
+            if (channelId == Constant.AF_DIAN_CHANNEL_ID) {
+                return afDianRechargeService.confirmRecharge(relation, gptCardKey, null);
+            }
+            //chong.afdian
+            if (channelId == Constant.CHONG_AF_DIAN_CHANNEL_ID) {
+                return chongAfDianRechargeService.confirmRecharge(relation, gptCardKey, null);
+            }
             //year.afdian
-			if (channelId == Constant.YEAR_AF_DIAN_CHANNEL_ID) {
-				return yearAfDianRechargeService.confirmRecharge(relation, gptCardKey, null);
-			}
+            if (channelId == Constant.YEAR_AF_DIAN_CHANNEL_ID) {
+                return yearAfDianRechargeService.confirmRecharge(relation, gptCardKey, null);
+            }
             //go.afdian
             if (channelId == Constant.GO_AF_DIAN_CHANNEL_ID) {
                 return goAfDianRechargeService.confirmRecharge(relation, gptCardKey, null);
             }
+            //cdk.aicnm
+            if (channelId == Constant.CDK_AICNM_CHANNEL_ID) {
+                return cdkAicnmRechargeService.confirmRecharge(relation, gptCardKey, null);
+            }
+
             //hiboy
             if (channelId == Constant.HIBOY_CHANNEL_ID || channelId == Constant.HIBOY_PRO_ONE_CHANNEL_ID || channelId == Constant.HIBOY_PRO_TWO_CHANNEL_ID) {
                 return hiBoyRechargeService.confirmRecharge(relation, gptCardKey, null);
             }
-			//校验卡密是否可用
-			CardKeyValidationResult cardKeyValidationResult = validateCardKey(gptCardKey);
-			if (!cardKeyValidationResult.getAvailable()) {
-				setRechargeRelationStatusAutoError(relation);
-				throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
-			}
-			//提交任务
-			TaskSubmitResult result = submitTask(gptCardKey, accessToken, "auth0");
-			if (!result.getSuccess()) {
-				setRechargeRelationStatusAutoError(relation);
-				throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
-			}
-			String taskId = result.getTaskId();
-			relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-					//记录代充账号
-					.set(GroupsRelation::getAccount, rechargeAccount)
-					.set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging)
-					.set(GroupsRelation::getCardKey, gptCardKey)
-					.set(GroupsRelation::getGptToken, saveTokenJson)
-					.set(GroupsRelation::getGptTaskId, taskId)
-					.eq(GroupsRelation::getId, relationId));
-			return taskId;
-		} finally {
-			if (redisService.hasKey(key)) {
-				redisService.del(key);
-			}
-		}
-	}
-
-	/**
-	 * 设置代充自动充值异常
-	 */
-	public void setRechargeRelationStatusAutoError(GroupsRelation relation) {
-		TASK_EXECUTOR.execute(()->{
-			relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-					.set(GroupsRelation::getAccount, relation.getAccount())
-					.set(GroupsRelation::getGptToken, relation.getGptToken())
-					.set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharge_error)
-					.eq(GroupsRelation::getId, relation.getId()));
-		});
-	}
-
-	/**
-	 * 更新代充状态
-	 */
-	private void resetGroupsRelationRechargeStatus(GroupsRelation relation, String status, String result) {
-		if ("completed".equals(status) || "failed".equals(status) || "unknown".equals(status)) {
-			String taskId = relation.getGptTaskId();
-			if (relation != null && relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharging) {
-				Integer rechargeRemainNum = relation.getRechargeRemainNum();
-				GroupsRelation.RechargeStatus rechargeStatus = "completed".equals(status) ? GroupsRelation.RechargeStatus.complete : GroupsRelation.RechargeStatus.recharge_error;
-				String cardKey = relation.getCardKey();
-				GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class)
-						.eq(GptRechargeCardKey::getCardKey, cardKey)
-						.last("limit 1"));
-				if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
-					if (gptRechargeCardKey != null) {
-						gptRechargeCardKeyMapper.update(null, Wrappers.lambdaUpdate(GptRechargeCardKey.class)
-								.set(GptRechargeCardKey::getStatus, Boolean.FALSE)
-								.set(GptRechargeCardKey::getOrderId, null)
-								.set(GptRechargeCardKey::getOrderNo, null)
-								.eq(GptRechargeCardKey::getId, gptRechargeCardKey.getId())
-								.eq(GptRechargeCardKey::getStatus, Boolean.TRUE));
-					}
-				}
-				if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
-					if (!redisService.setNx(RedisService.key.GPT_RECHARGE_RECOVER_KEY.getName() + taskId, taskId, RedisService.key.GPT_RECHARGE_RECOVER_KEY.getTimeout())) {
-						return;
-					}
-				}
-				Date startTime = relation.getStartTime();
-				DateTime expiryTime = null;
-				if (rechargeStatus == GroupsRelation.RechargeStatus.complete && startTime == null) {
-					GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
-					if (groupsTrips != null) {
-						startTime = DateTime.now();
-						GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
-						if (sku.getDays() != null && sku.getDays() > 0) {
-							expiryTime = DateUtil.offsetDay(startTime, sku.getDays());
-						} else {
-							expiryTime = DateUtil.offsetMonth(startTime, sku.getMonths());
-						}
-					}
-				}
-				String rechargeErrorInfo = null;
-				if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
-					rechargeErrorInfo = result;
-				}
-				relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
-						.set(rechargeStatus == GroupsRelation.RechargeStatus.recharge_error, GroupsRelation::getRechargeRemainNum, rechargeRemainNum + 1)
-						.set(GroupsRelation::getRechargeStatus, rechargeStatus)
-						.set(expiryTime != null, GroupsRelation::getStartTime, startTime)
-						.set(expiryTime != null, GroupsRelation::getExpiryTime, expiryTime)
-						.set(StrUtil.isNotEmpty(rechargeErrorInfo), GroupsRelation::getRechargeErrorInfo, rechargeErrorInfo)
-						.eq(GroupsRelation::getId, relation.getId())
-						.le(GroupsRelation::getRechargeRemainNum, relation.getRechargeNum())
-						.eq(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging));
-				//记录代充记录
-				if (rechargeStatus == GroupsRelation.RechargeStatus.complete) {
+            //校验卡密是否可用
+            CardKeyValidationResult cardKeyValidationResult = validateCardKey(gptCardKey);
+            if (!cardKeyValidationResult.getAvailable()) {
+                setRechargeRelationStatusAutoError(relation);
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            //提交任务
+            TaskSubmitResult result = submitTask(gptCardKey, accessToken, "auth0");
+            if (!result.getSuccess()) {
+                setRechargeRelationStatusAutoError(relation);
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            String taskId = result.getTaskId();
+            relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                    //记录代充账号
+                    .set(GroupsRelation::getAccount, rechargeAccount)
+                    .set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging)
+                    .set(GroupsRelation::getCardKey, gptCardKey)
+                    .set(GroupsRelation::getGptToken, saveTokenJson)
+                    .set(GroupsRelation::getGptTaskId, taskId)
+                    .eq(GroupsRelation::getId, relationId));
+            return taskId;
+        } finally {
+            if (redisService.hasKey(key)) {
+                redisService.del(key);
+            }
+        }
+    }
+
+    /**
+     * 设置代充自动充值异常
+     */
+    public void setRechargeRelationStatusAutoError(GroupsRelation relation) {
+        TASK_EXECUTOR.execute(() -> {
+            relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                    .set(GroupsRelation::getAccount, relation.getAccount())
+                    .set(GroupsRelation::getGptToken, relation.getGptToken())
+                    .set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharge_error)
+                    .eq(GroupsRelation::getId, relation.getId()));
+        });
+    }
+
+    /**
+     * 更新代充状态
+     */
+    private void resetGroupsRelationRechargeStatus(GroupsRelation relation, String status, String result) {
+        if ("completed".equals(status) || "failed".equals(status) || "unknown".equals(status)) {
+            String taskId = relation.getGptTaskId();
+            if (relation != null && relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharging) {
+                Integer rechargeRemainNum = relation.getRechargeRemainNum();
+                GroupsRelation.RechargeStatus rechargeStatus = "completed".equals(status) ? GroupsRelation.RechargeStatus.complete : GroupsRelation.RechargeStatus.recharge_error;
+                String cardKey = relation.getCardKey();
+                GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(Wrappers.lambdaQuery(GptRechargeCardKey.class)
+                        .eq(GptRechargeCardKey::getCardKey, cardKey)
+                        .last("limit 1"));
+                if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
+                    if (gptRechargeCardKey != null) {
+                        gptRechargeCardKeyMapper.update(null, Wrappers.lambdaUpdate(GptRechargeCardKey.class)
+                                .set(GptRechargeCardKey::getStatus, Boolean.FALSE)
+                                .set(GptRechargeCardKey::getOrderId, null)
+                                .set(GptRechargeCardKey::getOrderNo, null)
+                                .eq(GptRechargeCardKey::getId, gptRechargeCardKey.getId())
+                                .eq(GptRechargeCardKey::getStatus, Boolean.TRUE));
+                    }
+                }
+                if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
+                    if (!redisService.setNx(RedisService.key.GPT_RECHARGE_RECOVER_KEY.getName() + taskId, taskId, RedisService.key.GPT_RECHARGE_RECOVER_KEY.getTimeout())) {
+                        return;
+                    }
+                }
+                Date startTime = relation.getStartTime();
+                DateTime expiryTime = null;
+                if (rechargeStatus == GroupsRelation.RechargeStatus.complete && startTime == null) {
+                    GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+                    if (groupsTrips != null) {
+                        startTime = DateTime.now();
+                        GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
+                        if (sku.getDays() != null && sku.getDays() > 0) {
+                            expiryTime = DateUtil.offsetDay(startTime, sku.getDays());
+                        } else {
+                            expiryTime = DateUtil.offsetMonth(startTime, sku.getMonths());
+                        }
+                    }
+                }
+                String rechargeErrorInfo = null;
+                if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
+                    rechargeErrorInfo = result;
+                }
+                relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                        .set(rechargeStatus == GroupsRelation.RechargeStatus.recharge_error, GroupsRelation::getRechargeRemainNum, rechargeRemainNum + 1)
+                        .set(GroupsRelation::getRechargeStatus, rechargeStatus)
+                        .set(expiryTime != null, GroupsRelation::getStartTime, startTime)
+                        .set(expiryTime != null, GroupsRelation::getExpiryTime, expiryTime)
+                        .set(StrUtil.isNotEmpty(rechargeErrorInfo), GroupsRelation::getRechargeErrorInfo, rechargeErrorInfo)
+                        .eq(GroupsRelation::getId, relation.getId())
+                        .le(GroupsRelation::getRechargeRemainNum, relation.getRechargeNum())
+                        .eq(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging));
+                //记录代充记录
+                if (rechargeStatus == GroupsRelation.RechargeStatus.complete) {
                     gptUserRechargeRecordService.recordGptUserRechargeNum(relation.getCardKey(), relation.getUserId(), relation.getId(), relation.getAccount(), -1, null, "自动代充");
-					//修改对应订单状态
-					if (gptRechargeCardKey != null) {
-						Long orderId = gptRechargeCardKey.getOrderId();
-						OrderDon orderDon = orderDonMapper.selectById(orderId);
-						if (orderDon != null && orderDon.getStatus() == OrderDon.Status.hasPayment) {
-							orderDon.setStatus(OrderDon.Status.complete);
-							orderDonMapper.updateById(orderDon);
-						}
-					}
-				}
-			}
-		}
-	}
+                    //修改对应订单状态
+                    if (gptRechargeCardKey != null) {
+                        Long orderId = gptRechargeCardKey.getOrderId();
+                        OrderDon orderDon = orderDonMapper.selectById(orderId);
+                        if (orderDon != null && orderDon.getStatus() == OrderDon.Status.hasPayment) {
+                            orderDon.setStatus(OrderDon.Status.complete);
+                            orderDonMapper.updateById(orderDon);
+                        }
+                    }
+                }
+            }
+        }
+    }
 }

+ 6 - 0
netflix-service/src/main/java/com/cyksj/service/mange/gpt/impl/GptRechargeServiceImpl.java

@@ -78,6 +78,7 @@ public class GptRechargeServiceImpl implements GptRechargeService {
     private final YearAfDianRechargeService yearAfDianRechargeService;
 
     private final GoAfDianRechargeService goAfDianRechargeService;
+    private final CdkAicnmRechargeService cdkAicnmRechargeService;
 
     private final HiBoyRechargeService hiBoyRechargeService;
 
@@ -256,6 +257,11 @@ public class GptRechargeServiceImpl implements GptRechargeService {
                 req.setCmsUser(cmsUser);
                 relation.setCardKey(gptCardKey);
                 return goAfDianRechargeService.confirmRecharge(relation, gptCardKey, cmsUser);
+            }
+			if (gptRechargeCardKey.getChannelId() == Constant.CDK_AICNM_CHANNEL_ID) {
+                req.setCmsUser(cmsUser);
+                relation.setCardKey(gptCardKey);
+                return cdkAicnmRechargeService.confirmRecharge(relation, gptCardKey, cmsUser);
             }
             //hiboy
             if (gptRechargeCardKey.getChannelId() == Constant.HIBOY_CHANNEL_ID || gptRechargeCardKey.getChannelId() == Constant.HIBOY_PRO_ONE_CHANNEL_ID || gptRechargeCardKey.getChannelId() == Constant.HIBOY_PRO_TWO_CHANNEL_ID) {

+ 8 - 0
netflix-service/src/main/java/com/cyksj/service/recharge/CdkAicnmRechargeService.java

@@ -0,0 +1,8 @@
+package com.cyksj.service.recharge;
+
+import com.cyksj.model.entity.CmsUser;
+import com.cyksj.model.entity.GroupsRelation;
+
+public interface CdkAicnmRechargeService {
+    String confirmRecharge(GroupsRelation relation, String cardKey, CmsUser user);
+}

+ 326 - 0
netflix-service/src/main/java/com/cyksj/service/recharge/impl/CdkAicnmRechargeServiceImpl.java

@@ -0,0 +1,326 @@
+package com.cyksj.service.recharge.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.GptRechargeCardKeyMapper;
+import com.cyksj.mapper.GroupsMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.model.entity.CmsUser;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.GptRechargeCardKey;
+import com.cyksj.model.entity.GroupsRelation;
+import com.cyksj.model.entity.GroupsTrips;
+import com.cyksj.model.entity.OrderDon;
+import com.cyksj.model.response.recharge.CdkAicnmCardKeyLookupResp;
+import com.cyksj.model.response.recharge.CdkAicnmRedeemStartResp;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.chatgpt.GptUserRechargeRecordService;
+import com.cyksj.service.recharge.CdkAicnmRechargeService;
+import com.cyksj.service.recharge.GptRechargeCardKeyChannelService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class CdkAicnmRechargeServiceImpl implements CdkAicnmRechargeService {
+
+    private static final String BASE_URL = "https://cdk.aicnm.cc";
+    private static final int MAX_POLL_TIMES = 20;
+    private static final long POLL_INTERVAL_MILLIS = 1000L;
+
+    private final GroupsRelationMapper relationMapper;
+
+    private final GroupsMapper groupsMapper;
+
+    private final GoodsDonSkuMapper skuMapper;
+
+    private final RedisService redisService;
+
+    private final OrderDonMapper orderDonMapper;
+
+    private final GptRechargeCardKeyMapper gptRechargeCardKeyMapper;
+
+    private final GptUserRechargeRecordService gptUserRechargeRecordService;
+    private final GptRechargeCardKeyChannelService gptRechargeCardKeyChannelService;
+
+
+    private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
+
+    @Override
+    public String confirmRecharge(GroupsRelation relation, String gptCardKey, CmsUser cmsUser) {
+        Long relationId = relation.getId();
+        CdkAicnmCardKeyLookupResp lookupResp;
+        String baseUrl = getBaseUrl(gptCardKey);
+        try {
+            lookupResp = validateCardKey(baseUrl, gptCardKey);
+        } catch (Exception e) {
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
+            }
+            throw BusinessRuntimeException.getInstance("卡密:{0}错误", gptCardKey);
+        }
+        if (lookupResp == null) {
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
+            }
+            throw BusinessRuntimeException.getInstance("卡密:{0}错误", gptCardKey);
+        }
+        if (!Boolean.TRUE.equals(lookupResp.getExists())) {
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
+            }
+            throw BusinessRuntimeException.getInstance("卡密:{0}不存在", gptCardKey);
+        }
+        if (!isCardKeyAvailable(lookupResp)) {
+            log.error("cdk.aicnm卡密:{}已被使用, status={}", gptCardKey, lookupResp.getStatus());
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
+            }
+            throw BusinessRuntimeException.getInstance("卡密:{0}已被使用", gptCardKey);
+        }
+        String accessToken = relation.getGptToken();
+        String rechargeAccount = relation.getAccount();
+        CdkAicnmRedeemStartResp startResp;
+        try {
+            startResp = submitTask(gptCardKey, accessToken);
+            if (startResp == null || !Boolean.TRUE.equals(startResp.getOk())) {
+                throw BusinessRuntimeException.getInstance("cdk.aicnm激活任务提交失败");
+            }
+            log.info("cdk.aicnm激活任务已提交, cardKey={}, jobId={}, done={}, message={}",
+                    gptCardKey, startResp.getJobId(), startResp.getDone(), startResp.getMessage());
+        } catch (BusinessRuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            throw BusinessRuntimeException.getInstance("充值失败,{0}", e.getMessage());
+        }
+        String taskId = startResp.getJobId();
+        if (StrUtil.isBlank(taskId)) {
+            throw BusinessRuntimeException.getInstance("cdk.aicnm激活任务缺少jobId");
+        }
+        String operator = cmsUser == null ? null : cmsUser.getNickname();
+        String password = relation.getPassword();
+        relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                .set(GroupsRelation::getAccount, rechargeAccount)
+                .set(GroupsRelation::getOperator, operator)
+                .set(StrUtil.isNotBlank(password), GroupsRelation::getPassword, password)
+                .set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging)
+                .set(GroupsRelation::getCardKey, gptCardKey)
+                .set(GroupsRelation::getGptToken, accessToken)
+                .set(GroupsRelation::getGptTaskId, taskId)
+                .eq(GroupsRelation::getId, relationId));
+        relation.setRechargeStatus(GroupsRelation.RechargeStatus.recharging);
+        relation.setCardKey(gptCardKey);
+        relation.setGptTaskId(taskId);
+        if (cmsUser != null) {
+            relation.setOperator(operator);
+        }
+        try {
+            CdkAicnmRedeemStartResp taskStatusResp = waitRechargeResult(baseUrl, taskId);
+            if (taskStatusResp == null || !Boolean.TRUE.equals(taskStatusResp.getDone())) {
+                setRechargeRelationStatusAutoError(relation);
+                throw BusinessRuntimeException.getInstance("充值失败,查询激活结果超时");
+            }
+            boolean success = Boolean.TRUE.equals(taskStatusResp.getSuccess());
+            String resultMessage = StrUtil.blankToDefault(taskStatusResp.getMessage(), success ? rechargeAccount : "激活失败");
+            resetGroupsRelationRechargeStatus(relation, success, resultMessage);
+            if (!success) {
+                if (cmsUser == null) {
+                    throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+                }
+                throw BusinessRuntimeException.getInstance("充值失败,{0}", resultMessage);
+            }
+            return taskId;
+        } catch (BusinessRuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            setRechargeRelationStatusAutoError(relation);
+            if (cmsUser == null) {
+                throw BusinessRuntimeException.getInstance("充值失败,请联系客服开通");
+            }
+            throw BusinessRuntimeException.getInstance("充值失败,{0}", e.getMessage());
+        }
+    }
+
+    public CdkAicnmCardKeyLookupResp validateCardKey(String baseUrl, String cardKey) throws Exception {
+        String url = baseUrl + "/api/public/code/lookup";
+        JSONObject params = new JSONObject();
+        params.putOpt("code", cardKey);
+
+        HttpResponse response = HttpRequest.post(url)
+                .setConnectionTimeout(10000)
+                .header("content-type", "application/json")
+                .body(params.toString())
+                .execute();
+        String body = response.body();
+        log.info("cdk.aicnm验证卡密结果:{}", body);
+        return Jsons.parseObject(body, CdkAicnmCardKeyLookupResp.class);
+    }
+
+    public CdkAicnmRedeemStartResp submitTask(String cardKey, String accessToken) throws Exception {
+        String baseUrl = getBaseUrl(cardKey);
+        String url = baseUrl + "/api/public/code/redeem/start";
+        JSONObject params = new JSONObject();
+        params.putOpt("code", cardKey);
+        params.putOpt("access_token", accessToken);
+
+        HttpResponse response = HttpRequest.post(url)
+                .setConnectionTimeout(10000)
+                .header("content-type", "application/json")
+                .body(params.toString())
+                .execute();
+        String body = response.body();
+        log.info("cdk.aicnm开始激活响应:{}", body);
+        return Jsons.parseObject(body, CdkAicnmRedeemStartResp.class);
+    }
+
+    private String getBaseUrl(String cardKey) {
+        try {
+            String baseUrl = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
+            if (StrUtil.isNotBlank(baseUrl)) {
+                return baseUrl;
+            }
+        } catch (Exception e) {
+            log.warn("获取cdk.aicnm渠道域名失败, cardKey={}, error={}", cardKey, e.getMessage());
+        }
+        return BASE_URL;
+    }
+
+
+    public CdkAicnmRedeemStartResp queryTaskResult(String baseUrl, String jobId) throws Exception {
+        String url = baseUrl + "/api/public/code/redeem/status/" + jobId;
+        HttpResponse response = HttpRequest.get(url)
+                .setConnectionTimeout(10000)
+                .execute();
+        String body = response.body();
+        log.info("cdk.aicnm查询激活结果响应, jobId={}, body={}", jobId, body);
+        return Jsons.parseObject(body, CdkAicnmRedeemStartResp.class);
+    }
+
+    private CdkAicnmRedeemStartResp waitRechargeResult(String baseUrl, String jobId) throws Exception {
+        CdkAicnmRedeemStartResp taskStatusResp = null;
+        for (int i = 0; i < MAX_POLL_TIMES; i++) {
+            taskStatusResp = queryTaskResult(baseUrl, jobId);
+            if (taskStatusResp != null && Boolean.TRUE.equals(taskStatusResp.getDone())) {
+                return taskStatusResp;
+            }
+            if (i == MAX_POLL_TIMES - 1) {
+                break;
+            }
+            try {
+                Thread.sleep(POLL_INTERVAL_MILLIS);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                throw new RuntimeException("查询激活结果被中断", e);
+            }
+        }
+        return taskStatusResp;
+    }
+
+    boolean isCardKeyAvailable(CdkAicnmCardKeyLookupResp lookupResp) {
+        return lookupResp != null
+                && Boolean.TRUE.equals(lookupResp.getExists())
+                && "unused".equalsIgnoreCase(lookupResp.getStatus());
+    }
+
+    public void setRechargeRelationStatusAutoError(GroupsRelation relation) {
+        TASK_EXECUTOR.execute(() -> relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                .set(GroupsRelation::getAccount, relation.getAccount())
+                .set(GroupsRelation::getGptToken, relation.getGptToken())
+                .set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharge_error)
+                .eq(GroupsRelation::getId, relation.getId())));
+    }
+
+    private void resetGroupsRelationRechargeStatus(GroupsRelation relation, Boolean taskStatus, String result) {
+        GroupsRelation.RechargeStatus rechargeStatus = Boolean.TRUE.equals(taskStatus)
+                ? GroupsRelation.RechargeStatus.complete
+                : GroupsRelation.RechargeStatus.recharge_error;
+        String taskId = relation.getGptTaskId();
+        if (relation != null && relation.getRechargeStatus() == GroupsRelation.RechargeStatus.recharging) {
+            Integer rechargeRemainNum = relation.getRechargeRemainNum();
+            String cardKey = relation.getCardKey();
+            GptRechargeCardKey gptRechargeCardKey = gptRechargeCardKeyMapper.selectOne(
+                    Wrappers.lambdaQuery(GptRechargeCardKey.class)
+                            .eq(GptRechargeCardKey::getCardKey, cardKey)
+                            .last("limit 1"));
+            if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error && gptRechargeCardKey != null) {
+                gptRechargeCardKeyMapper.update(null, Wrappers.lambdaUpdate(GptRechargeCardKey.class)
+                        .set(GptRechargeCardKey::getStatus, Boolean.FALSE)
+                        .set(GptRechargeCardKey::getOrderId, null)
+                        .set(GptRechargeCardKey::getOrderNo, null)
+                        .eq(GptRechargeCardKey::getId, gptRechargeCardKey.getId())
+                        .eq(GptRechargeCardKey::getStatus, Boolean.TRUE));
+            }
+            if (rechargeStatus == GroupsRelation.RechargeStatus.recharge_error) {
+                if (!redisService.setNx(RedisService.key.GPT_RECHARGE_RECOVER_KEY.getName() + taskId,
+                        taskId, RedisService.key.GPT_RECHARGE_RECOVER_KEY.getTimeout())) {
+                    return;
+                }
+            }
+            Date startTime = relation.getStartTime();
+            DateTime expiryTime = null;
+            if (rechargeStatus == GroupsRelation.RechargeStatus.complete && startTime == null) {
+                GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
+                if (groupsTrips != null) {
+                    startTime = DateTime.now();
+                    GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId());
+                    if (sku.getDays() != null && sku.getDays() > 0) {
+                        expiryTime = DateUtil.offsetDay(startTime, sku.getDays());
+                    } else {
+                        expiryTime = DateUtil.offsetMonth(startTime, sku.getMonths());
+                    }
+                }
+            }
+            Integer rechargeNum = 1;
+            String rechargeErrorInfo = rechargeStatus == GroupsRelation.RechargeStatus.recharge_error ? result : null;
+            relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+                    .set(rechargeStatus == GroupsRelation.RechargeStatus.recharge_error,
+                            GroupsRelation::getRechargeRemainNum, rechargeRemainNum + rechargeNum)
+                    .set(GroupsRelation::getRechargeStatus, rechargeStatus)
+                    .set(expiryTime != null, GroupsRelation::getStartTime, startTime)
+                    .set(expiryTime != null, GroupsRelation::getExpiryTime, expiryTime)
+                    .set(StrUtil.isNotEmpty(rechargeErrorInfo), GroupsRelation::getRechargeErrorInfo, rechargeErrorInfo)
+                    .eq(GroupsRelation::getId, relation.getId())
+                    .le(GroupsRelation::getRechargeRemainNum, relation.getRechargeNum())
+                    .eq(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging));
+            if (rechargeStatus == GroupsRelation.RechargeStatus.complete) {
+                String remark = "自动代充";
+                if (StrUtil.isNotBlank(relation.getOperator())) {
+                    remark = "后台自动代充";
+                }
+                gptUserRechargeRecordService.recordGptUserRechargeNum(
+                        relation.getCardKey(),
+                        relation.getUserId(),
+                        relation.getId(),
+                        relation.getAccount(),
+                        -rechargeNum,
+                        relation.getOperator(),
+                        remark);
+                if (gptRechargeCardKey != null) {
+                    Long orderId = gptRechargeCardKey.getOrderId();
+                    OrderDon orderDon = orderDonMapper.selectById(orderId);
+                    if (orderDon != null && orderDon.getStatus() == OrderDon.Status.hasPayment) {
+                        orderDon.setStatus(OrderDon.Status.complete);
+                        orderDonMapper.updateById(orderDon);
+                    }
+                }
+            }
+        }
+    }
+}