Browse Source

油管用户端售后

zoujiajian 8 months ago
parent
commit
ba9cfc8321

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

@@ -564,6 +564,11 @@ public interface Constant {
 	 */
 	List<Long> RECHARGE_INVITE_GOODS_IDS = List.of(4l, 5l);
 
+	/**
+	 * 油管平台ID
+	 */
+	Long YOUTUBE_GOODS_ID = 5L;
+
 	/**
 	 * 第三方分类id
 	 */
@@ -644,6 +649,11 @@ public interface Constant {
 	 */
 	String ERROR_NETFLIX_CHANGE_OTHER_SKU_KEY = "error_netflix_change_other_sku_key";
 
+	/**
+	 * 异常youtube车票更换其他规格key
+	 */
+	String ERROR_YOUTUBE_CHANGE_OTHER_SKU_KEY = "error_youtube_change_other_sku_key";
+
 	/**
 	 * 银河币消费返回比例
 	 */
@@ -750,4 +760,9 @@ public interface Constant {
 	 * gpt车队id
 	 */
 	String GPT_CARD_ID = "P288";
+
+	/**
+	 * 油管售后时间限制key
+	 */
+	String YOUTUBE_AFTER_SALES_TIME_KEY = "youtube_after_sales_time_key";
 }

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/OrderRefundDto.java

@@ -0,0 +1,20 @@
+package com.cyksj.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj321312312312312312
+ * 文件名: OrderRefundDto
+ * 创建者: JavaZou
+ * 创建时间:2025/12/19 17:28
+ */
+@Getter
+@Setter
+public class OrderRefundDto {
+	private BigDecimal refundMoney;
+
+	private BigDecimal refundBalance;
+}

+ 1 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserBalanceSourceRecord.java

@@ -50,6 +50,7 @@ public class UserBalanceSourceRecord extends BaseEntity {
 		vip_refund("会员退款"),
 		TICKET_REPLACE("车票替换"),
 		vip_order_close("会员订单关闭"),
+		yt_refund("油管掉会员退款")
 		;
 		String desc;
 

+ 2 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/UserTicketClearedRecord.java

@@ -69,7 +69,8 @@ public class UserTicketClearedRecord extends BaseEntity{
 		vip_deduct("会员抵扣"),
 		codex_deduct("codex抵扣"),
 		cc_deduct("claude code抵扣"),
-		recover_replace("奈飞恢复直接替换")
+		recover_replace("奈飞恢复直接替换"),
+		yt_refund("油管掉会员退款")
 		;
 		String desc;
 

+ 11 - 0
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -2,6 +2,7 @@ package com.cyksj.service.relation;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
+import com.cyksj.model.dto.OrderRefundDto;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.entity.NetflixUserAccountStatusRecord;
@@ -124,4 +125,14 @@ public interface GroupRelationFrontService {
 	NetflixRecoverReceivedGptConditionDto netflixGptMirrorCondition(long userId);
 
 	void netflixRecoverGetGptMirror(long userId);
+
+	void youtubeSubmitFrozen(ErrorNetflixChangeReq req);
+
+	void errorYoutubeChangeOtherTicket(ErrorNetflixChangeReq req) throws Exception;
+
+	void errorYoutubeRefund(ErrorNetflixChangeReq req) throws Exception;
+
+	List<GoodsCategorySkuView> getYoutubeReplaceOtherSkus() throws Exception;
+
+	OrderRefundDto getYoutubeRefundInfo(long userId, Long relationId);
 }

+ 321 - 0
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -32,6 +32,7 @@ import com.cyksj.mapper.vip.VipGoodsSkuMapper;
 import com.cyksj.mapper.vip.VipUserMapper;
 import com.cyksj.model.dto.ErrorNetflixChangeOtherSkuTicketDto;
 import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
+import com.cyksj.model.dto.OrderRefundDto;
 import com.cyksj.model.dto.TicketChangeDto;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.AccountView;
@@ -2385,6 +2386,273 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		}
 	}
 
+	@Override
+	public void youtubeSubmitFrozen(ErrorNetflixChangeReq req) {
+		Long relationId = req.getRelationId();
+		Long userId = req.getUserId();
+		//校验账号
+		GroupsRelationView netflixRelationView = checkYoutubeTime(relationId, userId);
+		if (netflixRelationView.getIsFrozen()) {
+			throw BusinessRuntimeException.getInstance("您的车票已冻结");
+		}
+		Date expiryTime = netflixRelationView.getExpiryTime();
+		OrderDon orderDon = orderDonMapper.selectById(netflixRelationView.getNfOriOrderId());
+		Long betweenDay;
+		if (expiryTime == null) {
+			//用订单时间
+			GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+			if (expiryTime == null) {
+				if (sku.getDays() != null) {
+					expiryTime = DateUtil.offsetDay(orderDon.getCreatedTime(), sku.getDays());
+				} else {
+					expiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
+				}
+			}
+		}
+		betweenDay= DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
+
+		groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+				.set(GroupsRelation::getIsFrozen, Boolean.TRUE)
+				//冻结12个月
+				.set(GroupsRelation::getUnfrozenTime, DateUtil.offsetMonth(DateTime.now(), 12))
+				.set(betweenDay != null, GroupsRelation::getReservedDays, betweenDay)
+				.eq(GroupsRelation::getId, netflixRelationView.getId())
+				.eq(GroupsRelation::getUserId, netflixRelationView.getUserId()));
+	}
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void errorYoutubeChangeOtherTicket(ErrorNetflixChangeReq req) throws Exception {
+		Long relationId = req.getRelationId();
+		Long userId = req.getUserId();
+		//校验账号
+		GroupsRelationView relationView = checkYoutubeTime(relationId, userId);
+		String key = RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getName() + relationId;
+		if (!redisService.setNx(key, relationId, RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getTimeout())) {
+			throw BusinessRuntimeException.getInstance("正在更换其他车票中..");
+		}
+		Date expiryTime = relationView.getExpiryTime();
+		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
+				.eq(SysConfig::getSysKey, Constant.ERROR_YOUTUBE_CHANGE_OTHER_SKU_KEY)
+				.last("limit 1"));
+		List<ErrorNetflixChangeOtherSkuTicketDto> errorNetflixChangeOtherSkuTicketDtos = Jsons.parseList(sysConfig.getSysValue(), ErrorNetflixChangeOtherSkuTicketDto.class);
+		//替换车票
+		ErrorNetflixChangeOtherSkuTicketDto errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(0);
+		List<Long> skuIds = errorNetflixChangeOtherSkuTicketDto.getSkuIds();
+		try {
+			for (Long skuId : skuIds) {
+				TicketChangeDto changeDto = getTicketAndGenerateOrder(userId, skuId, null, null);
+				if (changeDto == null) {
+					throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
+				}
+				//替换记录
+				NetflixUserChangeOtherTicketRecord changeOtherTicketRecord = new NetflixUserChangeOtherTicketRecord();
+				changeOtherTicketRecord.setUserId(userId);
+				changeOtherTicketRecord.setRelationId(relationId);
+				changeOtherTicketRecord.setOtherRelationId(changeDto.getOtherRelationId());
+				changeOtherTicketRecord.setRelateOrderId(changeDto.getOtherOrderId());
+				//该车票订单id
+				changeOtherTicketRecord.setOrderId(relationView.getNfOriOrderId());
+				changeOtherTicketRecord.setStartTime(relationView.getStartTime());
+				changeOtherTicketRecord.setExpiryTime(expiryTime);
+				netflixUserChangeOtherTicketRecordMapper.insert(changeOtherTicketRecord);
+			}
+			//清除车票
+			GroupsRelation clearRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+					.eq(GroupsRelation::getId, relationId)
+					.eq(GroupsRelation::getUserId, relationView.getUserId())
+					.last("limit 1"));
+			if (clearRelation != null) {
+				clearService.clearTicket(clearRelation, UserTicketClearedRecord.Source.ticket_replace);
+			}
+		} finally {
+			redisService.del(key);
+		}
+	}
+
+	@Override
+	public void errorYoutubeRefund(ErrorNetflixChangeReq req) throws Exception {
+		Long relationId = req.getRelationId();
+		Long userId = req.getUserId();
+		//校验状态
+		GroupsRelationView relationView = checkYoutubeTime(relationId, userId);
+		Long ticketUserId = relationView.getUserId();
+		OrderDon orderDon = orderDonMapper.selectById(relationView.getNfOriOrderId());
+		if (orderDon != null) {
+			//paypal 或者超过一年 联系客服退款
+			if (orderDon.getType() == OrderDon.Type.PAYPAL) {
+				throw BusinessRuntimeException.getInstance("请联系客服退款");
+			}
+			GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
+			GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+			OrderRefundDto orderRefundDto = getYoutubeRefundInfo(relationView, orderDon, sku);
+			BigDecimal refundBalance = orderRefundDto.getRefundBalance();
+			BigDecimal refundMoney = orderRefundDto.getRefundMoney();
+			//超过订单金额 让联系客服退款
+			if (refundMoney.compareTo(orderDon.getMoney()) > 0) {
+				throw BusinessRuntimeException.getInstance("请联系客服退款");
+			}
+			String outNo = StrUtil.EMPTY;
+			//金额退款
+			if (refundMoney.compareTo(BigDecimal.ZERO) > 0) {
+				//调用第三方接口退款
+				OrderRefundReq refundReq = new OrderRefundReq();
+				refundReq.setRefundMoney(refundMoney);
+				refundReq.setRefundType("money");
+				try {
+					outNo = orderRefundService.centerRefund(refundReq, orderDon);
+				} catch (Exception e) {
+					throw BusinessRuntimeException.getInstance("请联系客服退款");
+				}
+				orderDon.setRefundMoney(refundMoney);
+			}
+			//余额退款
+			if (refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+				userBenefitsService.addUserBalance(ticketUserId, refundBalance, UserBalanceSourceRecord.Source.yt_refund, 0L, orderDon.getId(), UserBalanceSourceRecord.Source.yt_refund.getDesc(), true);
+			}
+			orderDon.setStatus(OrderDon.Status.refund);
+			if (refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+				orderDon.setRefundBalance(refundBalance);
+			}
+			orderDon.setRefundDesc("油管掉会员退款");
+			orderDonMapper.updateById(orderDon);
+			//记录退款类型
+			String refundType = getRefundType(refundMoney, refundBalance, orderDon);
+			orderRefundService.refundRecord(orderDon, refundMoney, refundBalance, "系统", goodsDon, sku, outNo, refundType, null);
+			//清除车票
+			GroupsRelation clearRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+					.eq(GroupsRelation::getId, relationId)
+					.eq(GroupsRelation::getUserId, relationView.getUserId())
+					.last("limit 1"));
+			if (clearRelation != null) {
+				clearService.clearTicket(clearRelation, UserTicketClearedRecord.Source.yt_refund);
+			}
+		}
+	}
+
+	private OrderRefundDto getYoutubeRefundInfo(GroupsRelationView relationView, OrderDon orderDon, GoodsDonSku sku) {
+		OrderRefundDto orderRefundDto = new OrderRefundDto();
+		Date expiryTime = relationView.getExpiryTime();
+		DateTime now = DateTime.now();
+		if (relationView.getIsFrozen()) {
+			Integer reservedDays = relationView.getReservedDays();
+			//处理边界
+			if (relationView.getReservedDays() == 365) {
+				reservedDays = 364;
+			}
+			expiryTime = DateUtil.offsetDay(now, reservedDays);
+		}
+		if (expiryTime == null) {
+			if (sku.getDays() != null) {
+				expiryTime = DateUtil.offsetDay(orderDon.getCreatedTime(), sku.getDays());
+			} else {
+				expiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
+			}
+		}
+		//剩余几个月
+		Long remainMonths = DateUtil.betweenMonth(now, expiryTime, false) + 1;
+		BigDecimal refundBalance = BigDecimal.ZERO;
+		BigDecimal refundMoney = BigDecimal.ZERO;
+		//订单金额
+		BigDecimal money = orderDon.getMoney();
+		BigDecimal balance = Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO);
+		BigDecimal orderTotalMoney = money.add(balance);
+		//2年
+		if ((sku.getDays() != null && sku.getDays() == 730) || (sku.getMonths() != null && sku.getMonths() == 24)) {
+			if (remainMonths > 12) {
+				//兑换码订单
+				if (orderTotalMoney.compareTo(BigDecimal.ZERO) == 0) {
+					orderTotalMoney = sku.getPrice();
+				}
+				BigDecimal totalRefundMoney = orderTotalMoney.divide(BigDecimal.valueOf(2), RoundingMode.DOWN);
+				if (money.compareTo(BigDecimal.ZERO) == 0) {
+					refundBalance = refundBalance.add(totalRefundMoney);
+				} else {
+					refundMoney = totalRefundMoney;
+					if (totalRefundMoney.compareTo(money) > 0) {
+						refundMoney = money;
+						refundBalance = totalRefundMoney.subtract(money);
+					}
+				}
+				remainMonths = remainMonths - 12;
+			}
+		}
+		if (remainMonths >= 1 && remainMonths <= 6) {
+			//1-6月买的 退100余额
+			refundBalance = refundBalance.add(BigDecimal.valueOf(10000));
+		} else if (remainMonths >= 7 && remainMonths <= 11) {
+			//7-11月买的 退150余额
+			refundBalance = refundBalance.add(BigDecimal.valueOf(15000));
+		} else {
+			//12月买的 退200余额
+			refundBalance = refundBalance.add(BigDecimal.valueOf(20000));
+		}
+		//超过订单金额 计算剩余的余额 排除兑换码
+		if (orderTotalMoney.compareTo(BigDecimal.ZERO) > 0 && refundMoney.add(refundBalance).compareTo(orderTotalMoney) > 0) {
+			refundBalance = orderTotalMoney.subtract(refundMoney);
+		}
+		orderRefundDto.setRefundMoney(refundMoney);
+		orderRefundDto.setRefundBalance(refundBalance);
+		return orderRefundDto;
+	}
+
+
+	@Override
+	public List<GoodsCategorySkuView> getYoutubeReplaceOtherSkus() throws Exception {
+		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
+				.eq(SysConfig::getSysKey, Constant.ERROR_YOUTUBE_CHANGE_OTHER_SKU_KEY)
+				.last("limit 1"));
+		List<ErrorNetflixChangeOtherSkuTicketDto> errorNetflixChangeOtherSkuTicketDtos = Jsons.parseList(sysConfig.getSysValue(), ErrorNetflixChangeOtherSkuTicketDto.class);
+		ErrorNetflixChangeOtherSkuTicketDto errorNetflixChangeOtherSkuTicketDto = errorNetflixChangeOtherSkuTicketDtos.get(0);
+		List<GoodsCategorySkuView> goodsCategorySkuViews = beanSearcher.searchAll(GoodsCategorySkuView.class, MapUtils.builder()
+				.field(GoodsCategorySkuView::getSkuId, errorNetflixChangeOtherSkuTicketDto.getSkuIds()).op(Operator.InList)
+				.orderBy(GoodsCategorySkuView::getPrice).desc()
+				.build());
+		return goodsCategorySkuViews;
+	}
+
+	@Override
+	public OrderRefundDto getYoutubeRefundInfo(long userId, Long relationId) {
+		//校验状态
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		GroupsRelationView relationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
+				.field(GroupsRelationView::getId, relationId)
+				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
+				.field(GroupsRelationView::getGoodsId, Constant.YOUTUBE_GOODS_ID)
+				.build());
+		if (relationView != null) {
+			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) {
+				GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+				OrderRefundDto orderRefundDto = getYoutubeRefundInfo(relationView, orderDon, sku);
+				return orderRefundDto;
+			}
+		}
+		return null;
+	}
+
+	private GroupsRelationView checkYoutubeTime(Long relationId, Long userId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		GroupsRelationView relationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
+				.field(GroupsRelationView::getId, relationId)
+				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
+				.field(GroupsRelationView::getGoodsId, Constant.YOUTUBE_GOODS_ID)
+				.build());
+		if (relationView == null) {
+			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("订单不存在");
+		}
+		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.YOUTUBE_AFTER_SALES_TIME_KEY).last("limit 1"));
+		DateTime availableHandleTime = DateUtil.parse(sysConfig.getSysValue());
+		if (orderDon.getCreatedTime().after(availableHandleTime)) {
+			throw BusinessRuntimeException.getInstance("不可进行售后,请联系客服");
+		}
+		relationView.setNfOriOrderId(orderDon.getId());
+		return relationView;
+	}
+
 	private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user, List<Long> userIds) {
 		DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
 				.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
@@ -2795,4 +3063,57 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			}
 		}
 	}
+
+
+	public OrderRefundDto getRefundInfo(GroupsRelationView netflixRelationView) {
+		OrderDon orderDon = orderDonMapper.selectById(netflixRelationView.getNfOriOrderId());
+		Long betweenDay = Long.valueOf(netflixRelationView.getReservedDays());
+		//未冻结时,使用车票时长
+		if (!netflixRelationView.getIsFrozen()) {
+			Date expiryTime = netflixRelationView.getExpiryTime();
+			if (expiryTime == null) {
+				//用订单时间
+				GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+				expiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
+			}
+			betweenDay= DateUtil.betweenDay(DateTime.now(), expiryTime, false) + 1;
+		}
+		GoodsDonSku oriTicketSku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+		//每天单价
+		BigDecimal dayPrice = oriTicketSku.getPrice().divide(BigDecimal.valueOf(oriTicketSku.getMonths() * 30), RoundingMode.DOWN);
+		//需要退款金额
+		BigDecimal totalRefundMoney = dayPrice.multiply(BigDecimal.valueOf(betweenDay));
+		BigDecimal refundBalance = BigDecimal.ZERO;
+		BigDecimal refundMoney = BigDecimal.ZERO;
+		String outNo = StrUtil.EMPTY;
+		//订单金额为0 直接退款余额
+		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
+			refundBalance = totalRefundMoney;
+		} else {
+			BigDecimal remainRefundBalanceMoney = null;
+			if (orderDon.getMoney().compareTo(totalRefundMoney) < 0) {
+				remainRefundBalanceMoney = totalRefundMoney.subtract(orderDon.getMoney());
+				refundMoney = orderDon.getMoney();
+			}
+			if (remainRefundBalanceMoney != null) {
+				refundBalance = refundBalance.add(remainRefundBalanceMoney);
+			}
+		}
+		OrderRefundDto orderRefundDto = new OrderRefundDto();
+		orderRefundDto.setRefundBalance(refundBalance);
+		orderRefundDto.setRefundMoney(refundMoney);
+		return orderRefundDto;
+	}
+
+	private String getRefundType(BigDecimal refundMoney, BigDecimal refundBalance, OrderDon orderDon) {
+		String refundType;
+		if (refundMoney.compareTo(BigDecimal.ZERO) > 0 && refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			refundType = "bxj";
+		} else if (refundMoney.compareTo(BigDecimal.ZERO) == 0 && refundBalance.compareTo(BigDecimal.ZERO) > 0) {
+			refundType = "balance";
+		} else {
+			refundType = orderDon.getType().name();
+		}
+		return refundType;
+	}
 }

+ 58 - 3
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -27,9 +27,7 @@ import com.cyksj.mapper.*;
 import com.cyksj.mapper.manage.form.FormFieldsDataMapper;
 import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
 import com.cyksj.mapper.shop.YhShopMapper;
-import com.cyksj.model.dto.DoubleVerifyDto;
-import com.cyksj.model.dto.GalaxyCoinPayConfigDto;
-import com.cyksj.model.dto.NetflixRecoverReceivedGptConditionDto;
+import com.cyksj.model.dto.*;
 import com.cyksj.model.dto.QuestionnaireView;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.AccountView;
@@ -1570,4 +1568,61 @@ public class GroupRelationController {
         groupRelationFrontService.netflixRecoverGetGptMirror(userId);
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+
+
+    //=====================================================youtube===================================================================
+
+    /**
+     * youtube可替换其他规格车票列表
+     */
+    @GetMapping("/get/youtube/replace/other/skus")
+    public Result<List<GoodsCategorySkuView>> getYoutubeReplaceOtherSkus() throws Exception {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<GoodsCategorySkuView> goodsCategorySkuViews = groupRelationFrontService.getYoutubeReplaceOtherSkus();
+        return GatewayResponse.SUCCESS.newBuilder().toResult(goodsCategorySkuViews);
+    }
+
+    /**
+     * 油管申请冻结
+     */
+    @PostMapping("/youtube/submit/frozen")
+    public Result<String> youtubeSubmitFrozen(@RequestBody ErrorNetflixChangeReq req) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        req.setUserId(userId);
+        groupRelationFrontService.youtubeSubmitFrozen(req);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * youtube更换其他车票
+     */
+    @PostMapping("/youtube/change/otherTicket")
+    public Result<Integer> errorYoutubeChangeOtherTicket(@RequestBody ErrorNetflixChangeReq req) throws Exception {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        req.setUserId(userId);
+        groupRelationFrontService.errorYoutubeChangeOtherTicket(req);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * youtube 退款
+     */
+    @PostMapping("/youtube/refund")
+    public Result<Integer> errorYoutubeRefund(@RequestBody ErrorNetflixChangeReq req) throws Exception {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        req.setUserId(userId);
+        groupRelationFrontService.errorYoutubeRefund(req);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * youtube 退款详情
+     */
+    @GetMapping("/youtube/refund/info")
+    public Result<OrderRefundDto> getYoutubeRefundInfo(Long relationId) throws Exception {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        OrderRefundDto orderRefundDto = groupRelationFrontService.getYoutubeRefundInfo(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(orderRefundDto);
+    }
 }