package com.ycwl.basic.biz; import com.ycwl.basic.model.mobile.order.IsBuyBatchRespVO; import com.ycwl.basic.model.pc.coupon.entity.CouponEntity; import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordQueryResp; import com.ycwl.basic.model.pc.face.entity.FaceEntity; import com.ycwl.basic.model.pc.order.entity.OrderEntity; import com.ycwl.basic.model.pc.price.entity.PriceConfigEntity; import com.ycwl.basic.model.pc.price.resp.GoodsListRespVO; import com.ycwl.basic.model.pc.price.resp.SimpleGoodsRespVO; import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity; import com.ycwl.basic.product.capability.ProductTypeCapability; import com.ycwl.basic.product.service.IProductTypeCapabilityManagementService; import com.ycwl.basic.puzzle.entity.PuzzleTemplateEntity; import com.ycwl.basic.puzzle.mapper.PuzzleTemplateMapper; import com.ycwl.basic.repository.FaceRepository; import com.ycwl.basic.repository.MemberRelationRepository; import com.ycwl.basic.repository.PriceRepository; import com.ycwl.basic.repository.ScenicRepository; import com.ycwl.basic.repository.TemplateRepository; import com.ycwl.basic.service.pc.FaceService; import org.apache.commons.lang3.Strings; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @Component public class PriceBiz { @Autowired private TemplateRepository templateRepository; @Autowired private ScenicRepository scenicRepository; @Autowired private PriceRepository priceRepository; @Autowired private OrderBiz orderBiz; @Autowired private FaceRepository faceRepository; @Autowired @Lazy private FaceService faceService; @Autowired private CouponBiz couponBiz; @Autowired private MemberRelationRepository memberRelationRepository; @Autowired private PuzzleTemplateMapper puzzleTemplateMapper; @Autowired private IProductTypeCapabilityManagementService productTypeCapabilityManagementService; public List listGoodsByScenic(Long scenicId) { List goodsList = new ArrayList<>(); // 景区视频 List templateList = templateRepository.getTemplateListByScenicId(scenicId); templateList.stream().map(template -> { GoodsListRespVO goods = new GoodsListRespVO(); goods.setGoodsId(template.getId()); goods.setGoodsName(template.getName()); goods.setGoodsType(0); return goods; }).forEach(goodsList::add); ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId); if (scenicConfig != null) { if (!Boolean.TRUE.equals(scenicConfig.getDisableSourceVideo())) { goodsList.add(new GoodsListRespVO(1L, "录像集", 1)); } if (!Boolean.TRUE.equals(scenicConfig.getDisableSourceImage())) { goodsList.add(new GoodsListRespVO(2L, "照片集", 2)); } } return goodsList; } /** * 根据景区ID和商品类型查询简化的商品列表 * * @param scenicId 景区ID * @param productType 商品类型(可选,为空时返回所有商品) * @return 简化的商品列表 */ public List listSimpleGoodsByScenic(Long scenicId, String productType) { List goodsList = new ArrayList<>(); // 如果 productType 为空,兼容旧逻辑 if (productType == null || productType.isEmpty()) { return listAllSimpleGoods(scenicId); } // 根据 productType 查询不同数据源 switch (productType) { case "VLOG_VIDEO": // 从 template 表查询视频模板 List templateList = templateRepository.getTemplateListByScenicId(scenicId); templateList.stream() .map(template -> new SimpleGoodsRespVO(template.getId(), template.getName(), productType)) .forEach(goodsList::add); break; case "PHOTO_VLOG": // TODO goodsList.add(new SimpleGoodsRespVO(scenicId, "【待实现】pLog视频", productType)); break; case "PHOTO": goodsList.add(new SimpleGoodsRespVO(scenicId, "单张照片", productType)); break; case "PHOTO_SET": // 返回固定的照片集条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "照片集", productType)); break; case "AI_CAM_PHOTO_SET": // 返回固定的照片集条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "AI微单照片集", productType)); break; case "PHOTO_LOG": // 从 template 表查询pLog模板 List puzzleList = puzzleTemplateMapper.list(scenicId, null, null); puzzleList.stream() .map(template -> new SimpleGoodsRespVO(template.getId(), template.getName(), productType)) .forEach(goodsList::add); break; case "RECORDING_SET": // 返回固定的录像集条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "录像集", productType)); break; case "PHOTO_PRINT": // 打印类返回单一通用条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "照片打印", productType)); break; case "PHOTO_PRINT_MU": // 打印类返回单一通用条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "手机照片打印", productType)); break; case "PHOTO_PRINT_FX": // 打印类返回单一通用条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "效果图片打印", productType)); break; case "MACHINE_PRINT": // 打印类返回单一通用条目 goodsList.add(new SimpleGoodsRespVO(scenicId, "一体机打印", productType)); break; default: // 不支持的 productType,返回空列表 break; } return goodsList; } /** * 兼容旧逻辑:返回所有商品 * 通过查询系统中所有已知的 productType,将结果综合到一起 */ private List listAllSimpleGoods(Long scenicId) { List goodsList = new ArrayList<>(); // 从 ProductTypeCapability 服务查询所有已知的商品类型(仅包含启用的) List capabilities = productTypeCapabilityManagementService.queryAll(false); // 轮询每个商品类型,获取对应的商品列表 for (ProductTypeCapability capability : capabilities) { String productType = capability.getProductType(); List typeGoodsList = listSimpleGoodsByScenic(scenicId, productType); goodsList.addAll(typeGoodsList); } return goodsList; } public List queryGoodsList(Integer configId) { PriceConfigEntity priceConfig = priceRepository.getPriceConfig(configId); if (priceConfig == null) { return Collections.emptyList(); } List goodsList = listGoodsByScenic(priceConfig.getScenicId()); if (Integer.valueOf(-1).equals(priceConfig.getType())) { return goodsList; } String[] goodsIds = priceConfig.getGoodsIds().split(","); return goodsList.stream().filter(goods -> { for (String goodsId : goodsIds) { if (Strings.CS.equals(goods.getGoodsId().toString(), goodsId)) { return true; } } return false; }).collect(Collectors.toList()); } public IsBuyBatchRespVO isOnePriceBuy(Long userId, Long faceId, Long scenicId, Integer type, String goodsIds) { IsBuyBatchRespVO respVO = new IsBuyBatchRespVO(); PriceConfigEntity priceConfig = priceRepository.getPriceConfigByScenicTypeGoods(scenicId, type, goodsIds); if (priceConfig == null) { return null; } FaceEntity face = faceRepository.getFace(faceId); if (face != null && !face.getMemberId().equals(userId)) { return null; } ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId); if (scenicConfig != null) { if (Boolean.TRUE.equals(scenicConfig.getAllFree())) { // 景区全免 respVO.setFree(true); respVO.setSlashPrice(BigDecimal.ZERO); return respVO; } } switch (type) { case 0: // 单个定价 CouponRecordQueryResp recordQueryResp = couponBiz.queryUserCouponRecord(scenicId, userId, faceId, goodsIds); if (recordQueryResp.isUsable()) { respVO.setCouponId(recordQueryResp.getCouponId()); respVO.setCouponRecordId(recordQueryResp.getId()); CouponEntity coupon = recordQueryResp.getCoupon(); if (coupon != null) { respVO.setCouponPrice(coupon.calculateDiscountPrice(priceConfig.getPrice())); } } break; case -1: CouponRecordQueryResp oneCouponRecordQueryResp = couponBiz.queryUserCouponRecord(scenicId, userId, faceId, "-1"); if (oneCouponRecordQueryResp.isUsable()) { respVO.setCouponId(oneCouponRecordQueryResp.getCouponId()); respVO.setCouponRecordId(oneCouponRecordQueryResp.getId()); CouponEntity coupon = oneCouponRecordQueryResp.getCoupon(); if (coupon != null) { respVO.setCouponPrice(coupon.calculateDiscountPrice(priceConfig.getPrice())); } } break; } respVO.setConfigId(priceConfig.getId()); respVO.setGoodsIds(goodsIds); respVO.setType(type); respVO.setOrigPrice(priceConfig.getPrice()); respVO.setSlashPrice(priceConfig.getSlashPrice()); // 查询用户是否有此类订单 respVO.setBuy(false); if (userId != null) { OrderEntity orderEntity = orderBiz.hasTypeOrder(userId, faceId, scenicId, type, priceConfig.getId()); if (orderEntity != null) { respVO.setOrderId(orderEntity.getId()); respVO.setBuy(Integer.valueOf(1).equals(orderEntity.getStatus())); } } if (type == -1 && !respVO.isBuy()) { // 直接查询用户购买状态,避免调用faceContentList造成循环调用 boolean allContentsPurchased = true; // 检查视频模板购买状态 List templateList = templateRepository.getTemplateListByScenicId(scenicId); for (TemplateRespVO template : templateList) { // 使用OrderRepository直接检查是否购买了该模板下的内容 List videoEntities = memberRelationRepository.listRelationByFaceAndTemplate(faceId, template.getId()); if (videoEntities == null || videoEntities.isEmpty()) { allContentsPurchased = false; break; } boolean hasPurchasedTemplate = orderBiz.checkUserBuyItem(userId, -1, videoEntities.getFirst().getVideoId()); if (!hasPurchasedTemplate) { allContentsPurchased = false; break; } } // 检查源文件购买状态(录像集和照片集) if (allContentsPurchased) { if (scenicConfig != null) { // 检查录像集 if (!Boolean.TRUE.equals(scenicConfig.getDisableSourceVideo())) { boolean hasPurchasedRecording = orderBiz.checkUserBuyItem(userId, 1, faceId); if (!hasPurchasedRecording) { allContentsPurchased = false; } } // 检查照片集 if (allContentsPurchased && !Boolean.TRUE.equals(scenicConfig.getDisableSourceImage())) { boolean hasPurchasedPhoto = orderBiz.checkUserBuyItem(userId, 2, faceId); if (!hasPurchasedPhoto) { allContentsPurchased = false; } } } } // 如果所有内容都已购买,则认为已购买套餐 if (allContentsPurchased) { respVO.setBuy(true); } } respVO.setShare(false); if (face == null || !face.getMemberId().equals(userId)) { respVO.setShare(true); } return respVO; } }