zoujiajian пре 1 година
родитељ
комит
c0fc31c4e7
27 измењених фајлова са 1455 додато и 54 уклоњено
  1. 17 0
      netflix-dao/src/main/java/com/cyksj/mapper/BackInfoTranslationsMapper.java
  2. 26 0
      netflix-dao/src/main/java/com/cyksj/model/dto/TranslationsDto.java
  3. 54 0
      netflix-dao/src/main/java/com/cyksj/model/entity/BackInfoTranslations.java
  4. 47 0
      netflix-dao/src/main/java/com/cyksj/model/entity/UserPageLanguage.java
  5. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/GoodsDonViewer.java
  6. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonSearchView.java
  7. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDiscountPlusPurchaseRelationFrontView.java
  8. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuRenewView.java
  9. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageFrontView.java
  10. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  11. 83 0
      netflix-dao/src/main/java/com/cyksj/model/views/TicketRenewUpgradeView.java
  12. 324 0
      netflix-dao/src/main/java/com/cyksj/model/views/UserMirrorTicketView.java
  13. 16 0
      netflix-dao/src/main/resources/mapper/BackInfoTranslationsMapper.xml
  14. 69 11
      netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSpecServiceImpl.java
  15. 5 3
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  16. 182 2
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  17. 46 0
      netflix-service/src/main/java/com/cyksj/service/translations/BackInfoTranslationsFrontService.java
  18. 17 0
      netflix-service/src/main/java/com/cyksj/service/translations/BackInfoTranslationsService.java
  19. 261 0
      netflix-service/src/main/java/com/cyksj/service/translations/impl/BackInfoTranslationsFrontServiceImpl.java
  20. 70 0
      netflix-service/src/main/java/com/cyksj/service/translations/impl/BackInfoTranslationsServiceImpl.java
  21. 56 1
      netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java
  22. 32 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  23. 23 5
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonCategoryController.java
  24. 23 6
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonController.java
  25. 35 22
      netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java
  26. 20 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/home/HomeManageConfigController.java
  27. 31 0
      netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

+ 17 - 0
netflix-dao/src/main/java/com/cyksj/mapper/BackInfoTranslationsMapper.java

@@ -0,0 +1,17 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.BackInfoTranslations;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslationsMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 14:18
+ */
+public interface BackInfoTranslationsMapper extends BaseMapper<BackInfoTranslations> {
+	void batchInsertOrUpdate(@Param("funcId") Long funcId, @Param("type") Integer type, @Param("list") List<BackInfoTranslations> fields, @Param("lang") String lang);
+}

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/TranslationsDto.java

@@ -0,0 +1,26 @@
+package com.cyksj.model.dto;
+
+import com.cyksj.model.entity.BackInfoTranslations;
+import com.cyksj.model.entity.UserPageLanguage;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: TranslationsDto
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 14:38
+ */
+@Getter
+@Setter
+public class TranslationsDto {
+	private Long funcId;
+
+	private String lang = UserPageLanguage.Language.en_US.name();
+
+	private BackInfoTranslations.Type type;
+
+	private List<BackInfoTranslations> fields;
+}

+ 54 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/BackInfoTranslations.java

@@ -0,0 +1,54 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslations
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 14:13
+ */
+@Getter
+@Setter
+public class BackInfoTranslations extends BaseEntity{
+	/**
+	 * 字段名
+	 */
+	private String fieldName;
+
+	/**
+	 * 类型主键id 如平台id
+	 */
+	private Long funcId;
+
+	/**
+	 * 类型
+	 */
+	private Integer type;
+
+	private String lang;
+
+	/**
+	 * 英文表述
+	 */
+	private String desp;
+
+
+	@Getter
+	public enum Type {
+		goods("商品"),
+		sku("规格"),
+		spec("一级规格"),
+		coupon("优惠券"),
+		coupon_classification("优惠券分类"),
+		goods_category("平台分类"),
+		home_config("首页配置")
+		;
+		String remark;
+
+		Type(String remark) {
+			this.remark = remark;
+		}
+	}
+}

+ 47 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/UserPageLanguage.java

@@ -0,0 +1,47 @@
+package com.cyksj.model.entity;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.stream.Stream;
+
+/*
+ *项目名: netflix
+ *文件名: UserPageLanguage
+ *创建者: JavaZou
+ *创建时间:2022/12/7 17:41
+ */
+@Getter
+@Setter
+public class UserPageLanguage extends BaseEntity {
+
+	private Long userId;
+
+
+	private Language language;
+
+	@Getter
+	public enum Language {
+		zh_CN("中文"),
+		zh_HK("中文香港繁体"),
+		ja_JP("日语"),
+		ko_KR("韩语"),
+		en_US("英文");
+
+		String desc;
+
+		Language(String desc) {
+			this.desc = desc;
+		}
+
+		public static Boolean checkLanguage(String language) {
+			if (StrUtil.isEmpty(language)) {
+				return false;
+			}
+			return Stream.of(Language.values())
+					.filter(value -> value.name().equals(language))
+					.findFirst().isPresent();
+		}
+	}
+}

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/GoodsDonViewer.java

@@ -79,6 +79,9 @@ public class GoodsDonViewer {
     @DbField("g.deleted")
     private Boolean deleted;
 
+    @DbField("gs.id")
+    private Long specId;
+
     @DbField("gs.goods_id")
     private Long goodsId;
 

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonSearchView.java

@@ -57,6 +57,9 @@ public class OrderDonSearchView {
 	@DbField("sku.is_benefits")
 	private Boolean isBenefits;
 
+	@DbField("sku.id")
+	private Long skuId;
+
 	@DbField("sku.benefits_list")
 	@JsonIgnore
 	private String benefitsList;

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDiscountPlusPurchaseRelationFrontView.java

@@ -43,6 +43,9 @@ public class GoodsDiscountPlusPurchaseRelationFrontView {
 	@DbField("g.match_img")
 	private String matchImg;
 
+	/**
+	 * 加购规格id
+	 */
 	@DbField("gpr.dis_sid")
 	private Long disSid;
 

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuRenewView.java

@@ -22,6 +22,9 @@ public class GoodsDonSkuRenewView {
 	@DbField("sku.id")
 	private Long skuId;
 
+	@DbField("sku.sub_title")
+	private String subTitle;
+
 	@DbField("sku.spec_val")
 	private String specVal;
 

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewUpgradePackageFrontView.java

@@ -49,6 +49,9 @@ public class RenewUpgradePackageFrontView {
 		@DbField("sku.id")
 		private Long skuId;
 
+		@DbField("sku.sub_title")
+		private String subTitle;
+
 		@DbField("sku.months")
 		private Integer months;
 

+ 3 - 0
netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java

@@ -32,6 +32,9 @@ public class RenewalView {
     @DbField("sku.id")
     private Long skuId;
 
+    @DbField("sku.sub_title")
+    private String subTitle;
+
     @DbField("g.status")
     private Boolean goodsStatus;
 

+ 83 - 0
netflix-dao/src/main/java/com/cyksj/model/views/TicketRenewUpgradeView.java

@@ -0,0 +1,83 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: TicketRenewUpgradeView
+ * 创建者: JavaZou
+ * 创建时间:2025/7/25 18:11
+ */
+@Getter
+@Setter
+public class TicketRenewUpgradeView {
+
+	/**
+	 * gpt 用户镜像限制次数
+	 */
+	@DbIgnore
+	private Integer gptUserLimitNum;
+
+	/**
+	 * gpt 用户镜像限制时间
+	 */
+	@DbIgnore
+	private Long gptUserLimitTime;
+
+	/**
+	 * luma 用户次数
+	 */
+	@DbIgnore
+	private Integer lumaUserNum;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbIgnore
+	private Integer userDsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbIgnore
+	private Long userDsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbIgnore
+	private Integer userOtherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbIgnore
+	private Long userOtherLimitTime;
+
+	/**
+	 * 是否是续费升级
+	 */
+	@DbIgnore
+	private Boolean isRenewPackage;
+
+	/**
+	 * 是否可升级套餐 (标准,专业)
+	 */
+	@DbIgnore
+	private Boolean upgrade;
+
+	@DbIgnore
+	private Long packageId;
+
+	/**
+	 * 目前已升级套餐价格
+	 */
+	@DbIgnore
+	private BigDecimal packagePrice;
+
+	private GoodsDonSkuRenewView renewSku;
+}

+ 324 - 0
netflix-dao/src/main/java/com/cyksj/model/views/UserMirrorTicketView.java

@@ -0,0 +1,324 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: UserMirrorTicketView
+ * 创建者: JavaZou
+ * 创建时间:2025/7/25 16:11
+ */
+@SearchBean(tables = "groups_relation gr left join groups_trips gt on gt.id = gr.groups_id " +
+		"left join goods_don_sku sku on gt.sku_id = sku.id " +
+		"left join goods_don g on g.id = sku.goods_id "
+)
+@Getter
+@Setter
+public class UserMirrorTicketView {
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("sku.id")
+	private Long skuId;
+
+	@DbField("g.status")
+	private Boolean goodsStatus;
+
+	@DbField("sku.status")
+	private Boolean skuStatus;
+
+	@DbField("sku.months")
+	private Integer months;
+
+	@DbField("sku.days")
+	private Integer days;
+
+	@DbField("sku.num")
+	private Integer skuNum;
+
+	@DbField("sku.sub_title")
+	private String subTitle;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("gr.id")
+	private Long relationId;
+
+	@DbField("gr.num")
+	private Integer num;
+
+	@DbField("gr.groups_id")
+	private Long groupId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("g.logo")
+	private String logo;
+
+	@DbField("g.img")
+	private String img;
+
+	@DbField("gt.status")
+	private String groupsStatus;
+
+	@DbField("gr.user_id")
+	@JsonIgnore
+	private Long userId;
+
+	@DbField("gr.start_time")
+	private Date startTime;
+
+	@DbField("gr.expiry_time")
+	private Date expiryTime;
+
+	@DbIgnore
+	private Long total;
+
+	@DbIgnore
+	private String expiryTimeStr;
+
+	@DbField("gr.status")
+	private String status;
+
+	/**
+	 * 店铺id
+	 */
+	@DbField("gr.yhs_id")
+	private Long yhsId;
+
+	/**
+	 * 店铺类型
+	 * 0无 1.普通店铺 2.镜像店铺
+	 */
+	@DbField("gr.cmt")
+	private Integer cmt;
+
+	/**
+	 * 车票获取类型 默认1购买,2.体验 3.镜像裂变
+	 */
+	@DbField("gr.aq_type")
+	private Integer aqType;
+
+	/**
+	 * 是否是VIP
+	 */
+	@DbField("gr.is_vip")
+	private Boolean isVip;
+
+	@DbIgnore
+	private Date payTime;
+
+	@DbIgnore
+	private String remainDays;
+
+	@DbField("sku.price")
+	private BigDecimal price;
+
+	/**
+	 * 是否为镜像服务
+	 */
+	@DbField("sku.is_mirror")
+	private Boolean isMirror;
+
+	/**
+	 * 是否为镜像车队服务
+	 */
+	@DbField("sku.is_car")
+	private Boolean isCar;
+
+
+	/**
+	 * mj fast次数
+	 */
+	@DbField("sku.mj_fast_num")
+	private Integer mjFastNum;
+
+
+	/**
+	 * mj relax次数
+	 */
+	@DbField("sku.mj_relax_num")
+	private Integer mjRelaxNum;
+
+	/**
+	 * 镜像限制次数
+	 */
+	@DbField("sku.gpt_limit_num")
+	private Integer gptLimitNum;
+
+	/**
+	 * luma 次数
+	 */
+	@DbField("sku.luma_num")
+	private Integer lumaNUm;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbField("sku.ds_limit_num")
+	private Integer dsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbField("sku.ds_limit_time")
+	private Long dsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbField("sku.other_limit_num")
+	private Integer otherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbField("sku.other_limit_time")
+	private Long otherLimitTime;
+
+	/**
+	 * mj 套餐包最低单价
+	 */
+	@DbIgnore
+	private BigDecimal mjPackagePrice;
+
+	/**
+	 * luma 套餐包最低单价
+	 */
+	@DbIgnore
+	private BigDecimal lumaPackagePrice;
+
+	/**
+	 * 用户 mj fast次数
+	 */
+	@DbIgnore
+	private Integer mjUserFastNum;
+
+	/**
+	 * 用户 mj 加量包次数
+	 */
+	@DbIgnore
+	private Integer mjUserUpgradeNum;
+
+
+	/**
+	 * 用户 mj relax次数
+	 */
+	@DbIgnore
+	private Integer mjUserRelaxNum;
+
+	/**
+	 * gpt 用户镜像限制次数
+	 */
+	@DbIgnore
+	private Integer gptUserLimitNum;
+
+	/**
+	 * gpt 用户镜像限制时间
+	 */
+	@DbIgnore
+	private Long gptUserLimitTime;
+
+	/**
+	 * luma 用户次数
+	 */
+	@DbIgnore
+	private Integer lumaUserNum;
+
+	/**
+	 * deepseek限制次数
+	 */
+	@DbIgnore
+	private Integer userDsLimitNum;
+
+	/**
+	 * deepseek限制时间
+	 */
+	@DbIgnore
+	private Long userDsLimitTime;
+
+	/**
+	 * 其他模型限制次数
+	 */
+	@DbIgnore
+	private Integer userOtherLimitNum;
+
+	/**
+	 * 其他模型限制时间
+	 */
+	@DbIgnore
+	private Long userOtherLimitTime;
+
+	/**
+	 * 镜像token
+	 */
+	@DbIgnore
+	private String userToken;
+
+	@DbIgnore
+	private Long use;
+
+	/**
+	 * 是否可升级套餐 (标准,专业)
+	 */
+	@DbIgnore
+	private Boolean upgrade;
+
+	@DbIgnore
+	private Long packageId;
+
+	/**
+	 * 目前已升级套餐价格
+	 */
+	@DbIgnore
+	private BigDecimal packagePrice;
+
+	@DbIgnore
+	private DistributePosterGoodsDetailView posterInfo;
+
+	/**
+	 * 是否是续费升级
+	 */
+	@DbIgnore
+	private Boolean isRenewPackage;
+
+	/**
+	 * 续费升级规格id
+	 */
+	@DbIgnore
+	private Long renewSkuId;
+
+	/**
+	 * 续费升级目前规格
+	 */
+	@DbIgnore
+	private GoodsDonSkuRenewView renewSku;
+
+	/**
+	 * 续费升级折扣
+	 */
+	@DbIgnore
+	private BigDecimal discount;
+
+	/**
+	 * gpt模式 0旧版 1新版
+	 */
+	@DbIgnore
+	private Integer model;
+
+	/**
+	 * 订单id
+	 */
+	@DbIgnore
+	private Long orderId;
+}

+ 16 - 0
netflix-dao/src/main/resources/mapper/BackInfoTranslationsMapper.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.cyksj.mapper.BackInfoTranslationsMapper">
+
+
+    <insert id="batchInsertOrUpdate">
+        insert into `back_info_translations`(`type`,`func_id`,`field_name`,`desp`,`lang`,`created_time`,`update_time`)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{type},#{funcId},#{item.fieldName},#{item.desp},#{lang},now(),now())
+        </foreach>
+        ON DUPLICATE KEY UPDATE `desp` = VALUES(`desp`),
+        update_time = VALUES(update_time)
+    </insert>
+</mapper>

+ 69 - 11
netflix-service/src/main/java/com/cyksj/service/mange/goods/CmsGoodsDonSpecServiceImpl.java

@@ -11,15 +11,13 @@ import com.cyksj.mapper.DistributeGoodsSkuAlertMapper;
 import com.cyksj.mapper.GoodsDonMapper;
 import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.GoodsDonSpecMapper;
-import com.cyksj.model.entity.DistributeGoodsSkuAlert;
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.GoodsDonSku;
-import com.cyksj.model.entity.GoodsDonSpec;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.request.ReqGoodsSkuInsert;
 import com.cyksj.model.manage.request.ReqGoodsSkuSpec;
 import com.cyksj.model.manage.request.ReqGoodsSpecSingle;
 import com.cyksj.model.request.CombinationSkuReq;
 import com.cyksj.service.mange.CmsGoodsDonSpecService;
+import com.cyksj.service.translations.BackInfoTranslationsService;
 import com.fasterxml.jackson.databind.JavaType;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -27,6 +25,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
@@ -47,6 +46,10 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 
 	private final DistributeGoodsSkuAlertMapper distributeGoodsSkuAlertMapper;
 
+	private final BackInfoTranslationsService backInfoTranslationsService;
+
+	private final HttpServletRequest request;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertOrUpdateSkuSpec(ReqGoodsSkuInsert insert, Boolean isUpdate) throws Exception {
@@ -54,6 +57,7 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 		if (null == goods) {
 			throw new RuntimeException("找不到商品spu.");
 		}
+		String lang = request.getHeader("lang");
 		GoodsDonSpec loveSpec = this.getOne(Wrappers.lambdaQuery(GoodsDonSpec.class).eq(GoodsDonSpec::getGoodsId, insert.getGoodsId()));
 		Map<String, List<ReqGoodsSkuSpec>> dbSpecMap = null;
 		Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap = null;
@@ -118,7 +122,7 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 					Set<GoodsDonSku> benefitsSkuIds = Jsons.parseSet(benefitsList, GoodsDonSku.class);
 					e.setBenefitsList(Jsons.toJson(benefitsSkuIds));
 				}
-				syncSpecNodeSku(goods.getId(), dbNodeMap, e);
+				syncSpecNodeSku(goods.getId(), dbNodeMap, e, lang);
 
 				ReqGoodsSpecSingle single = new ReqGoodsSpecSingle();
 				single.setId(e.getId());
@@ -139,11 +143,21 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 		spec.setSpecsJson(Jsons.toJson(specs));
 		spec.setSpecNumber(specNumber);
 		spec.setSpecMapping(Jsons.toJson(map));
-		if (insert.getId() != null) {
-			this.updateById(spec);
-			return;
+		if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			//spec
+			backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.spec, spec.getId(), spec, lang);
+			//sku
+			List<GoodsDonSku> goodsDonSkus = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
+					.eq(GoodsDonSku::getGoodsId, goods.getId()));
+			List<GoodsDonSku> resetSkuSpec = resetSkuSpec(goodsDonSkus, spec);
+			resetSkuSpec.stream().forEach(sku -> backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.sku, sku.getId(), sku, lang));
+		} else {
+			if (insert.getId() != null) {
+				this.updateById(spec);
+				return;
+			}
+			this.save(spec);
 		}
-		this.save(spec);
 	}
 
 	@Override
@@ -454,7 +468,7 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 	/**
 	 * 更新二级分类标题价格等 同步库中sku
 	 */
-	public void syncSpecNodeSku(Long goodsId, Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap, ReqGoodsSkuSpec.Node e) {
+	public void syncSpecNodeSku(Long goodsId, Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap, ReqGoodsSkuSpec.Node e, String lang) {
 		if (CollUtil.isNotEmpty(dbNodeMap)) {
 			ReqGoodsSkuSpec.Node dbNode = dbNodeMap.get(e.getId());
 			if (dbNode == null) {
@@ -504,7 +518,9 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 									}
 								}
 							}
-							goodsDonSkuMapper.updateById(sku);
+							if (StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+								goodsDonSkuMapper.updateById(sku);
+							}
 						}
 					} catch (Exception exception) {
 					}
@@ -512,4 +528,46 @@ public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper,
 			}
 		}
 	}
+
+	//多语言设置sku
+	public List<GoodsDonSku> resetSkuSpec(List<GoodsDonSku> skus, GoodsDonSpec loveSpec) throws Exception {
+		StringBuilder builder = new StringBuilder();
+		List<ReqGoodsSpecSingle> specList = null;
+		JavaType type = Jsons.javaType().constructMapType(HashMap.class, Integer.class, ReqGoodsSpecSingle.class);
+		Map<Integer, ReqGoodsSpecSingle> map = Jsons.parseObject(loveSpec.getSpecMapping(), type);
+		int specNumber = loveSpec.getSpecNumber();
+		List<GoodsDonSku> reSkuList = new ArrayList<>();
+		GoodsDonSku reSku = null;
+		for (GoodsDonSku sku : skus) {
+			final String specIds = sku.getSpecIds();
+			if (StringUtils.isBlank(specIds)) {
+				throw new RuntimeException("请选择商品的规格.");
+			}
+			int[] ids = Jsons.parseObject(specIds, int[].class);
+
+			// init
+			builder.delete(0, builder.length());
+			if (null == specList) {
+				specList = new ArrayList<>(specNumber);
+			} else {
+				specList.clear();
+			}
+			for (int id : ids) {
+				ReqGoodsSpecSingle single = map.get(id);
+				if (null == single) {
+					throw new RuntimeException("总规格属性id中 不存在 sku中的id.");
+				}
+				builder.append(single.getName()).append(';');
+				specList.add(single);
+			}
+			reSku = new GoodsDonSku();
+			String specVal = builder.toString();
+			String specJson = Jsons.toJson(specList);
+			reSku.setId(sku.getId());
+			reSku.setSpecVal(specVal);
+			reSku.setSpecJson(specJson);
+			reSkuList.add(reSku);
+		}
+		return reSkuList;
+	}
 }

+ 5 - 3
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -11,9 +11,7 @@ import com.cyksj.model.request.TicketLoginReq;
 import com.cyksj.model.response.NetflixErrorAccountStatus;
 import com.cyksj.model.response.NetflixRecoverResp;
 import com.cyksj.model.response.NetflixRefundInfoResp;
-import com.cyksj.model.views.GoodsCategorySkuView;
-import com.cyksj.model.views.RenewalView;
-import com.cyksj.model.views.UserRecommendGoodsFrontView;
+import com.cyksj.model.views.*;
 import com.ejlchina.searcher.SearchResult;
 
 import java.util.List;
@@ -113,4 +111,8 @@ public interface GroupRelationFrontService {
 	Boolean refundNetflix(ErrorNetflixChangeReq req) throws Exception;
 
 	NetflixRefundInfoResp refundNetflixInfo(Long userId, Long relationId);
+
+	List<UserMirrorTicketView> getMirrorTicket(long userId);
+
+	TicketRenewUpgradeView getRenewUpgradeInfo(long userId, Long relationId);
 }

+ 182 - 2
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -56,7 +56,7 @@ import com.cyksj.service.order.OrderRefundService;
 import com.cyksj.service.relation.GroupRelationClearService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.relation.GroupsRelationChangeService;
-import com.cyksj.service.relation.GroupsRelationNetflixService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
 import com.cyksj.service.user.UserBenefitsService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserLoginRecordService;
@@ -144,7 +144,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final LumaService lumaService;
 
-	private final GroupsRelationNetflixService groupsRelationNetflixService;
+	private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
 
 	private final UserDistributeMapper userDistributeMapper;
 
@@ -202,6 +202,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final UserBenefitsService userBenefitsService;
 
+	private final ChatgptUserMapper chatgptUserMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo, Integer cmt) {
 		User u = userMapper.selectById(userId);
@@ -245,6 +247,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 				.orderBy(RenewalView::getExpiryTime).asc()
 				.build());
 		if (list.getDataList().size() > 0) {
+			String lang = request.getHeader("lang");
 			//过滤邀请制、已失效的车位
 			Integer size = list.getTotalCount().intValue();
 			//赠送GPT日卡 参与平台ids
@@ -344,6 +347,12 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 						ticket.setIsComplete(orderDon.getStatus() == OrderDon.Status.complete ? true : false);
 					}
 				}
+				if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+					String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(ticket.getSkuId(), lang);
+					if (StrUtil.isNotBlank(languageSpecVal)) {
+						ticket.setSpecVal(languageSpecVal);
+					}
+				}
 
 				if (size > 1 && ticket.getGoodsId() != 18) {
 					Date payTime = null;
@@ -1765,6 +1774,144 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return true;
 	}
 
+	@Override
+	public List<UserMirrorTicketView> getMirrorTicket(long userId) {
+		User u = userMapper.selectById(userId);
+		if (u == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
+		if (u.getIsBlack()) {
+			return null;
+		}
+		List<Long> userIds = userBindRelationService.getRelationUserIdList(userId, u);
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+		DateTime now = DateTime.now();
+		String lang = request.getHeader("lang");
+		List<UserMirrorTicketView> list = beanSearcher.searchAll(UserMirrorTicketView.class, builder
+				.field(UserMirrorTicketView::getUserId, userIds).op(Operator.InList)
+				.field(UserMirrorTicketView::getIsMirror, Boolean.TRUE)
+				//过期7天内的镜像车票都展示
+				.field(UserMirrorTicketView::getExpiryTime, DateUtil.offsetDay(now, -7)).op(Operator.GreaterThan)
+				.orderBy(RenewalView::getExpiryTime).asc()
+				.build());
+		list.forEach(ticket -> {
+			if (ticket.getExpiryTime() != null) {
+				String remainDays = DateUtil.formatBetween(now, ticket.getExpiryTime(), BetweenFormater.Level.DAY);
+				if ("0天".equals(remainDays)) {
+					remainDays = "小于1天";
+				} else {
+					//当天也算
+					int days = Integer.parseInt(remainDays.substring(0, remainDays.indexOf("天")));
+					remainDays = days + 1 + "天";
+				}
+				ticket.setRemainDays(remainDays);
+				ticket.setTotal(DateUtil.betweenDay(ticket.getStartTime(), ticket.getExpiryTime(), false) + 1);
+			}
+			if (ticket.getExpiryTime() != null) {
+				ticket.setExpiryTimeStr(DateUtil.format(ticket.getExpiryTime(), "yyyy-MM-dd"));
+			}
+			//续费升级折扣
+			BigDecimal renewDiscount = getRenewDiscount(ticket.getGoodsId(), ticket.getSkuId(), ticket.getIsMirror(), ticket.getSkuNum());
+			ticket.setDiscount(renewDiscount);
+			setAIZoneMirrorTicketInfo(ticket);
+
+			if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+				String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(ticket.getSkuId(), lang);
+				if (StrUtil.isNotBlank(languageSpecVal)) {
+					ticket.setSpecVal(languageSpecVal);
+				}
+			}
+
+			OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+					.eq(OrderDon::getRelationId, ticket.getRelationId())
+					.eq(OrderDon::getUserId, ticket.getUserId())
+					.eq(OrderDon::getOrderType, 1)
+					.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+					.orderByDesc(OrderDon::getId)
+					.last("limit 1"));
+			if (orderDon != null) {
+				ticket.setOrderId(orderDon.getId());
+			}
+		});
+		userLoginRecordService.saveUserLoginDayRecord(userId);
+		return list;
+	}
+
+	@Override
+	public TicketRenewUpgradeView getRenewUpgradeInfo(long userId, Long relationId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder()
+				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
+				.field(GroupsRelationView::getId, relationId)
+				.field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+				.build());
+		TicketRenewUpgradeView ticketRenewUpgradeView = new TicketRenewUpgradeView();
+		if (groupsRelationView != null) {
+			String lang = request.getHeader("lang");
+			//clause pro
+			if (groupsRelationView.getGoodsId() == 75l) {
+				try {
+					ClaudeUserView userInfo = claudeService.getUserInfo(groupsRelationView.getUserId(), groupsRelationView.getId());
+					Long renewSkuId = userInfo.getRenewSkuId();
+					if (renewSkuId != null) {
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build());
+						ticketRenewUpgradeView.setRenewSku(renewSku);
+					}
+					ticketRenewUpgradeView.setGptUserLimitNum(userInfo.getLimitNum());
+					ticketRenewUpgradeView.setGptUserLimitTime(userInfo.getLimitTime());
+				} catch (Exception e) {
+				}
+			}
+
+			if (groupsRelationView.getGoodsId() == 18) {
+				try {
+					//gpt用户镜像
+					ChatGptUserView userInfo = chatGptAccountService.getUserInfo(groupsRelationView.getUserId(), groupsRelationView.getId());
+					Integer count = upgradePackageMapper.selectCount(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + groupsRelationView.getSkuId() + "\"')")
+							.gt(UpgradePackage::getNum, userInfo.getLimitNum())
+							.eq(UpgradePackage::getStatus, Boolean.TRUE)
+							.eq(UpgradePackage::getGptType, 0)
+							.eq(UpgradePackage::getDeleted, Boolean.TRUE));
+					ticketRenewUpgradeView.setUpgrade(count > 0 ? true : false);
+					ticketRenewUpgradeView.setPackageId(userInfo.getPackageId());
+					ticketRenewUpgradeView.setGptUserLimitNum(userInfo.getLimitNum());
+					ticketRenewUpgradeView.setGptUserLimitTime(userInfo.getLimitTime());
+					ticketRenewUpgradeView.setUserDsLimitNum(userInfo.getDsLimitNum());
+					ticketRenewUpgradeView.setUserDsLimitTime(userInfo.getDsLimitTime());
+					ticketRenewUpgradeView.setUserOtherLimitNum(userInfo.getOtherLimitNum());
+					ticketRenewUpgradeView.setUserOtherLimitTime(userInfo.getOtherLimitTime());
+					if (userInfo.getPackageId() != 0) {
+						UpgradePackage upgradePackage = upgradePackageMapper.selectById(userInfo.getPackageId());
+						ticketRenewUpgradeView.setPackagePrice(upgradePackage.getPrice());
+						Long upgradeOrderDonSkuId = upgradePackage.getUpgradeSkuId();
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, upgradeOrderDonSkuId).build());
+						renewSku.setPackageId(userInfo.getPackageId());
+						ticketRenewUpgradeView.setRenewSku(renewSku);
+					}
+					ticketRenewUpgradeView.setIsRenewPackage(userInfo.getIsRenewPackage());
+					Long renewSkuId = userInfo.getRenewSkuId();
+					if (renewSkuId != null) {
+						GoodsDonSkuRenewView upgradeSkuRenewView = ticketRenewUpgradeView.getRenewSku();
+						GoodsDonSkuRenewView renewSku = beanSearcher.searchFirst(GoodsDonSkuRenewView.class, MapUtils.builder().field(GoodsDonSkuRenewView::getSkuId, renewSkuId).build());
+						//续费升级是更高级规格
+						if (upgradeSkuRenewView == null || (renewSku.getGptUserLimitNum() >= upgradeSkuRenewView.getGptUserLimitNum() && renewSku.getMonths() >= userInfo.getMonths())) {
+							Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
+									.eq(OrderDonRenewRecord::getOrderId, userInfo.getRenewOrderId())
+									.last("limit 1"))).ifPresent(e -> renewSku.setOriginalOrderId(e.getOrderId()));
+							if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+								String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(renewSku.getSkuId(), lang);
+								if (StrUtil.isNotBlank(languageSpecVal)) {
+									renewSku.setSpecVal(languageSpecVal);
+								}
+							}
+							ticketRenewUpgradeView.setRenewSku(renewSku);
+						}
+					}
+				} catch (Exception e) {
+				}
+			}
+		}
+		return ticketRenewUpgradeView;
+	}
+
 	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());
@@ -1829,6 +1976,24 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		}
 	}
 
+	private BigDecimal getRenewDiscount(Long goodsId, Long skuId, Boolean isMirror, Integer skuNum) {
+		//镜像或者独立规格
+		if (isMirror || (skuNum != null && skuNum == 1)) {
+			RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
+					.eq(RenewUpgradePackage::getGoodsId, goodsId)
+					.eq(RenewUpgradePackage::getStatus, 1)
+					.eq(RenewUpgradePackage::getDeleted, 1)
+					.eq(RenewUpgradePackage::getSkuId, skuId)
+					.orderByAsc(RenewUpgradePackage::getDiscount)
+					.last("limit 1")
+					.select(RenewUpgradePackage::getId, RenewUpgradePackage::getDiscount));
+			if (renewUpgradePackage != null) {
+				return renewUpgradePackage.getDiscount();
+			}
+		}
+		return null;
+	}
+
 	private void setMirrorTicketInfo(RenewalView ticket) {
 		//设置MJ镜像信息
 		setMjMirrorInfo(ticket);
@@ -2106,4 +2271,19 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		orderDonMapper.insert(orderDon);
 		return orderDon;
 	}
+
+	private void setAIZoneMirrorTicketInfo(UserMirrorTicketView ticket) {
+		setAIZoneGptMirrorInfo(ticket);
+	}
+
+	private void setAIZoneGptMirrorInfo(UserMirrorTicketView ticket) {
+		if (ticket.getGoodsId() != null && ticket.getGoodsId() == Constant.GPT_PLUS_GID) {
+			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+					.eq(ChatgptUser::getRelationId, ticket.getRelationId())
+					.last("limit 1"));
+			if (chatgptUser != null) {
+				ticket.setModel(chatgptUser.getModel());
+			}
+		}
+	}
 }

+ 46 - 0
netflix-service/src/main/java/com/cyksj/service/translations/BackInfoTranslationsFrontService.java

@@ -0,0 +1,46 @@
+package com.cyksj.service.translations;
+
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.manage.views.GoodsDonViewer;
+import com.cyksj.model.views.*;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslationsFrontService
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 15:07
+ */
+public interface BackInfoTranslationsFrontService {
+	void setGoodsDetailLanguage(GoodsFrontListView views, String lang);
+
+	void setCategoryGoodsLanguage(GoodsFrontListCategoryView data, String lang);
+
+	String getLanguagePayTitle(Long goodsId, Long skuId, String language);
+
+	void setGoodsBackLanguage(GoodsDonViewer goodsDonViewer, String lang);
+
+	void setSkuBackLanguage(List<GoodsDonSku> goodsDonSkus, String lang);
+
+	String getLanguageSpecVal(Long skuId, String lang);
+
+	String getGoodsTitleLanguage(Long goodsId, String lang);
+
+	void setCouponLanguage(CouponView couponView, String lang);
+
+	void setFieldLanguage(Class<?> tclass, Object obj, Integer type, Long funcId, String lang);
+
+	/**
+	 * 设置优惠券规格展示多语言
+	 */
+	String setCouponGoodsSkuStrLanguage(Long couponId, String lang);
+
+	void setListCategoryNameLanguage(List<GoodsDonCategoryFrontView> list, String lang);
+
+	String getCategoryNameLanguage(Long category, String lang);
+
+	String getLanguagePayDesc(Long goodsId, String lang);
+
+	void getHomeConfigRealGoodsLanguage(List<HomeManagementFrontView> homeManagementFrontViews, String lang);
+}

+ 17 - 0
netflix-service/src/main/java/com/cyksj/service/translations/BackInfoTranslationsService.java

@@ -0,0 +1,17 @@
+package com.cyksj.service.translations;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.dto.TranslationsDto;
+import com.cyksj.model.entity.BackInfoTranslations;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslationsService
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 14:19
+ */
+public interface BackInfoTranslationsService extends IService<BackInfoTranslations> {
+	void saveOrUpdateTranslations(TranslationsDto dto);
+
+	void saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type type, Long funcId, Object obj, String lang);
+}

+ 261 - 0
netflix-service/src/main/java/com/cyksj/service/translations/impl/BackInfoTranslationsFrontServiceImpl.java

@@ -0,0 +1,261 @@
+package com.cyksj.service.translations.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.mapper.BackInfoTranslationsMapper;
+import com.cyksj.mapper.manage.coupon.CouponMapper;
+import com.cyksj.mapper.manage.coupon.CouponSkuMapper;
+import com.cyksj.model.entity.BackInfoTranslations;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.UserPageLanguage;
+import com.cyksj.model.manage.views.GoodsDonViewer;
+import com.cyksj.model.views.*;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslationsFrontServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 15:07
+ */
+@Service
+@RequiredArgsConstructor
+public class BackInfoTranslationsFrontServiceImpl implements BackInfoTranslationsFrontService {
+	private final BackInfoTranslationsMapper backInfoTranslationsMapper;
+
+	private final CouponMapper couponMapper;
+
+	private final CouponSkuMapper couponSkuMapper;
+
+	@Override
+	public void setGoodsDetailLanguage(GoodsFrontListView views, String lang) {
+		if (views == null) {
+			return;
+		}
+		//平台
+		setFieldLanguage(views.getClass(), views, BackInfoTranslations.Type.goods.ordinal(), views.getId(), lang);
+		//规格
+		List<GoodsDonSkuFrontView> skuList = views.getSkuList();
+		if (CollUtil.isNotEmpty(skuList)) {
+			skuList.forEach(sku -> setFieldLanguage(sku.getClass(), sku, BackInfoTranslations.Type.sku.ordinal(), sku.getId(), lang));
+		}
+		GoodsDonSpecFrontView specs = views.getSpecs();
+		if (specs != null) {
+			setFieldLanguage(specs.getClass(), specs, BackInfoTranslations.Type.spec.ordinal(), specs.getId(), lang);
+		}
+	}
+
+	@Override
+	public void setCategoryGoodsLanguage(GoodsFrontListCategoryView data, String lang) {
+		if (data == null) {
+			return;
+		}
+		//平台
+		setFieldLanguage(data.getClass(), data, BackInfoTranslations.Type.goods.ordinal(), data.getId(), lang);
+	}
+
+	@Override
+	public String getLanguagePayTitle(Long goodsId, Long skuId, String lang) {
+		if (StrUtil.isEmpty(lang)) {
+			return null;
+		}
+		BackInfoTranslations goodsL = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.goods.ordinal())
+				.eq(BackInfoTranslations::getFuncId, goodsId)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFieldName, "title"));
+		StringBuilder payTitle = new StringBuilder();
+		if (goodsL != null) {
+			payTitle.append(goodsL.getDesp());
+		}
+		if (skuId != null) {
+			BackInfoTranslations skuL = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+					.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.sku.ordinal())
+					.eq(BackInfoTranslations::getFuncId, skuId)
+					.eq(BackInfoTranslations::getLang, lang)
+					.eq(BackInfoTranslations::getFieldName, "specVal"));
+			if (skuL != null) {
+				if (payTitle.length() > 0) {
+					payTitle.append(" ");
+				}
+				payTitle.append(skuL.getDesp());
+			}
+		}
+		if (payTitle.length() > 0) {
+			return payTitle.toString();
+		}
+		return null;
+	}
+
+	@Override
+	public void setGoodsBackLanguage(GoodsDonViewer goodsDonViewer, String lang) {
+		//sku
+		setFieldLanguage(goodsDonViewer.getClass(), goodsDonViewer, BackInfoTranslations.Type.goods.ordinal(), goodsDonViewer.getId(), lang);
+		//spec
+		setFieldLanguage(goodsDonViewer.getClass(), goodsDonViewer, BackInfoTranslations.Type.spec.ordinal(), goodsDonViewer.getSpecId(), lang);
+	}
+
+	@Override
+	public void setSkuBackLanguage(List<GoodsDonSku> goodsDonSkus, String lang) {
+		goodsDonSkus.forEach(sku -> setFieldLanguage(sku.getClass(), sku, BackInfoTranslations.Type.sku.ordinal(), sku.getId(), lang));
+	}
+
+	@Override
+	public String getLanguageSpecVal(Long skuId, String lang) {
+		if (skuId == null) {
+			return null;
+		}
+		BackInfoTranslations skuL = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.sku.ordinal())
+				.eq(BackInfoTranslations::getFuncId, skuId)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFieldName, "specVal"));
+		if (skuL != null) return skuL.getDesp();
+		return null;
+	}
+
+	@Override
+	public String getGoodsTitleLanguage(Long goodsId, String lang) {
+		BackInfoTranslations goodsL = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.goods.ordinal())
+				.eq(BackInfoTranslations::getFuncId, goodsId)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFieldName, "title"));
+		if (goodsL != null) return goodsL.getDesp();
+		return null;
+	}
+
+	@Override
+	public void setCouponLanguage(CouponView couponView, String lang) {
+		setFieldLanguage(couponView.getClass(), couponView, BackInfoTranslations.Type.coupon.ordinal(), couponView.getId(), lang);
+		if (couponView.getClassificationId() != null) {
+			BackInfoTranslations classificationTranslation = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+					.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.coupon_classification.ordinal())
+					.eq(BackInfoTranslations::getLang, lang)
+					.eq(BackInfoTranslations::getFuncId, couponView.getClassificationId())
+					.eq(BackInfoTranslations::getFieldName, "name"));
+			if (classificationTranslation != null) {
+				couponView.setCouponClassificationName(classificationTranslation.getDesp());
+			}
+		}
+	}
+
+	@Override
+	public void setFieldLanguage(Class<?> tclass, Object obj, Integer type, Long funcId, String lang) {
+		if (StrUtil.isEmpty(lang) || StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			return;
+		}
+		List<BackInfoTranslations> backInfoTranslations = backInfoTranslationsMapper.selectList(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, type)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFuncId, funcId));
+
+		if (CollUtil.isNotEmpty(backInfoTranslations)) {
+			backInfoTranslations.forEach(tanslate -> {
+				String fieldName = tanslate.getFieldName();
+				try {
+					Field declaredField = tclass.getDeclaredField(fieldName);
+					declaredField.setAccessible(true);
+					declaredField.set(obj, tanslate.getDesp());
+				} catch (IllegalAccessException e) {
+				} catch (NoSuchFieldException e) {
+				}
+			});
+		}
+	}
+
+
+	@Override
+	public String setCouponGoodsSkuStrLanguage(Long couponId, String lang) {
+		if (StrUtil.isEmpty(lang) || StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			String str = couponSkuMapper.selectGoodsSkuStr(couponId);
+			str = str.replaceAll(",", "/").replaceAll(";", "");
+			return str;
+		}
+
+		List<GoodsDonSku> goodsDonSkus = new ArrayList<>();
+		StringBuilder skuGoodsStrSb = new StringBuilder(128);
+		Map<Long, String> map = new HashMap<>();
+		goodsDonSkus.forEach(sku -> {
+			String title = map.get(sku.getGoodsId());
+			if (StrUtil.isEmpty(title)) {
+				BackInfoTranslations backGoodsInfoTranslations = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+						.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.goods.ordinal())
+						.eq(BackInfoTranslations::getLang, lang)
+						.eq(BackInfoTranslations::getFieldName, "title")
+						.eq(BackInfoTranslations::getFuncId, sku.getGoodsId()));
+				if (backGoodsInfoTranslations != null) {
+					title = backGoodsInfoTranslations.getDesp();
+					map.put(sku.getGoodsId(), title);
+				}
+			}
+			BackInfoTranslations backSkuInfoTranslations = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+					.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.sku.ordinal())
+					.eq(BackInfoTranslations::getLang, lang)
+					.eq(BackInfoTranslations::getFieldName, "specVal")
+					.eq(BackInfoTranslations::getFuncId, sku.getId()));
+			if (skuGoodsStrSb.length() > 0) {
+				skuGoodsStrSb.append("/");
+			}
+			if (backSkuInfoTranslations != null) {
+				skuGoodsStrSb.append(title).append(" ").append(backSkuInfoTranslations.getDesp());
+			}
+		});
+
+		return skuGoodsStrSb.toString();
+	}
+
+	@Override
+	public void setListCategoryNameLanguage(List<GoodsDonCategoryFrontView> list, String lang) {
+		if (list == null) {
+			return;
+		}
+		list.forEach(category -> setFieldLanguage(category.getClass(), category, BackInfoTranslations.Type.goods_category.ordinal(), category.getId(), lang));
+	}
+
+	@Override
+	public String getCategoryNameLanguage(Long category, String lang) {
+		BackInfoTranslations categoryName = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.goods_category.ordinal())
+				.eq(BackInfoTranslations::getFuncId, category)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFieldName, "name"));
+		if (categoryName != null) return categoryName.getDesp();
+		return null;
+	}
+
+	@Override
+	public String getLanguagePayDesc(Long goodsId, String lang) {
+		if (StrUtil.isEmpty(lang)) {
+			return null;
+		}
+		BackInfoTranslations goodsL = backInfoTranslationsMapper.selectOne(Wrappers.lambdaQuery(BackInfoTranslations.class)
+				.eq(BackInfoTranslations::getType, BackInfoTranslations.Type.goods.ordinal())
+				.eq(BackInfoTranslations::getFuncId, goodsId)
+				.eq(BackInfoTranslations::getLang, lang)
+				.eq(BackInfoTranslations::getFieldName, "payDesc"));
+		if (goodsL != null) {
+			return goodsL.getDesp();
+		}
+		return null;
+	}
+
+	@Override
+	public void getHomeConfigRealGoodsLanguage(List<HomeManagementFrontView> homeManagementFrontViews, String lang) {
+		if (homeManagementFrontViews == null) {
+			return;
+		}
+		if (CollUtil.isNotEmpty(homeManagementFrontViews)) {
+			homeManagementFrontViews.forEach(rg -> setFieldLanguage(rg.getClass(), rg, BackInfoTranslations.Type.home_config.ordinal(), rg.getHomeManageConfigId(), lang));
+		}
+	}
+}

+ 70 - 0
netflix-service/src/main/java/com/cyksj/service/translations/impl/BackInfoTranslationsServiceImpl.java

@@ -0,0 +1,70 @@
+package com.cyksj.service.translations.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.BackInfoTranslationsMapper;
+import com.cyksj.model.dto.TranslationsDto;
+import com.cyksj.model.entity.BackInfoTranslations;
+import com.cyksj.service.translations.BackInfoTranslationsService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: BackInfoTranslationsServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/7/16 14:20
+ */
+@Service
+@RequiredArgsConstructor
+public class BackInfoTranslationsServiceImpl extends ServiceImpl<BackInfoTranslationsMapper, BackInfoTranslations> implements BackInfoTranslationsService {
+	private final BackInfoTranslationsMapper backInfoTranslationsMapper;
+
+	@Override
+	public void saveOrUpdateTranslations(TranslationsDto dto) {
+		List<BackInfoTranslations> fields = dto.getFields();
+		if (CollUtil.isEmpty(fields)) {
+			return;
+		}
+		backInfoTranslationsMapper.batchInsertOrUpdate(dto.getFuncId(), dto.getType().ordinal(), dto.getFields(), dto.getLang());
+	}
+
+	@Override
+	public void saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type type, Long funcId, Object obj, String lang) {
+		if (StrUtil.isEmpty(lang) || funcId == null) {
+			return;
+		}
+		TranslationsDto translationsDto = new TranslationsDto();
+		translationsDto.setType(type);
+		translationsDto.setLang(lang);
+		translationsDto.setFuncId(funcId);
+		List<BackInfoTranslations> fields = new ArrayList<>();
+		for (Field declaredField : obj.getClass().getDeclaredFields()) {
+			try {
+				declaredField.setAccessible(true);
+				Optional.ofNullable(declaredField.get(obj)).ifPresent(val -> {
+					if (val instanceof String) {
+						BackInfoTranslations backInfoTranslations = new BackInfoTranslations();
+						backInfoTranslations.setFieldName(declaredField.getName());
+						backInfoTranslations.setDesp(val.toString());
+						fields.add(backInfoTranslations);
+					}
+				});
+			} catch (IllegalAccessException e) {
+			}
+		}
+		if (CollUtil.isNotEmpty(fields)) {
+			translationsDto.setFields(fields);
+			saveOrUpdateTranslations(translationsDto);
+		} else {
+			backInfoTranslationsMapper.delete(Wrappers.lambdaQuery(BackInfoTranslations.class).eq(BackInfoTranslations::getType, type.ordinal()).eq(BackInfoTranslations::getFuncId, funcId).eq(BackInfoTranslations::getLang, lang));
+		}
+	}
+}

+ 56 - 1
netflix-web/src/main/java/com/cyksj/web/controller/goods/GoodsDonController.java

@@ -26,6 +26,7 @@ import com.cyksj.redis.RedisService;
 import com.cyksj.service.goods.GoodsDonFrontService;
 import com.cyksj.service.home.ClickRecordFrontService;
 import com.cyksj.service.shop.YhShopFrontService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.web.util.StpUserUtil;
@@ -87,7 +88,7 @@ public class GoodsDonController {
 
 	private final GiftCardGoodsSkuMapper giftCardGoodsSkuMapper;
 
-	private final GoodsDonCategoryRelateMapper goodsDonCategoryRelateMapper;
+	private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
 
 	/**
      * 获取平台商品分类
@@ -102,6 +103,12 @@ public class GoodsDonController {
 	    if (yhsId != null) {
 		    key += ":yhShop:" + yhsId;
 	    }
+	    String lang = request.getHeader("lang");
+	    AtomicBoolean language = new AtomicBoolean(false);
+	    if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+		    key += ":" + lang;
+		    language.set(true);
+	    }
 	    Object o = redisService.get(key);
 	    List<GoodsDonCategoryFrontView> list;
 	    MapBuilder mapBuilder = MapUtils.flatBuilder(request.getParameterMap());
@@ -115,6 +122,10 @@ public class GoodsDonController {
 	    if (o == null) {
 		    list = beanSearcher.searchAll(GoodsDonCategoryFrontView.class, mapBuilder
 				    .build());
+		    //多语言
+		    if (language.get()) {
+			    backInfoTranslationsFrontService.setListCategoryNameLanguage(list, lang);
+		    }
 		    redisService.setNx(key, list, 30 * 60l);
 		    o = redisService.get(key);
 	    }
@@ -357,6 +368,12 @@ public class GoodsDonController {
 		String goodsDetailKey = RedisService.key.YH_HOME_PAGHE_CACHE.getName() + "goods_detail:" + id;
 		//List<Long> filter_goodsIds = getFilterGoodsIds();
 		List<Long> filter_goodsIds = null;
+		String lang = request.getHeader("lang");
+		AtomicBoolean language = new AtomicBoolean(false);
+		if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			goodsDetailKey += ":" + lang;
+			language.set(true);
+		}
 		//存在过滤平台 商品详情不返回
 		if (CollUtil.isNotEmpty(filter_goodsIds) && filter_goodsIds.contains(id)) {
 			return GatewayResponse.SUCCESS.newBuilder().toResult();
@@ -377,6 +394,10 @@ public class GoodsDonController {
 			}
 			views.setSkuList(beanSearcher.searchAll(GoodsDonSkuFrontView.class, builder.build()));
 			views.setSold(getGoodsSold(views.getId(), views.getSold()));
+			//多语言
+			if (language.get()) {
+				backInfoTranslationsFrontService.setGoodsDetailLanguage(views, lang);
+			}
 			List<Long> gptBuyGids = getGptMirrorGiveawayBuyGids();
 			if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(views.getId())) {
 				views.setIsGptGift(true);
@@ -415,6 +436,19 @@ public class GoodsDonController {
 				sku.setDpSkuViews(beanSearcher.searchAll(GoodsDiscountPlusPurchaseRelationFrontView.class, MapUtils.builder()
 						.field(GoodsDiscountPlusPurchaseRelationFrontView::getSkuId, sku.getId())
 						.build()));
+				//多语言
+				if (language.get()) {
+					for (GoodsDiscountPlusPurchaseRelationFrontView dpSkuView : sku.getDpSkuViews()) {
+						String languageGoodsTitle = backInfoTranslationsFrontService.getGoodsTitleLanguage(dpSkuView.getDisGid(), lang);
+						if (StrUtil.isNotBlank(languageGoodsTitle)) {
+							dpSkuView.setTitle(languageGoodsTitle);
+						}
+						String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(dpSkuView.getDisSid(), lang);
+						if (StrUtil.isNotBlank(languageSpecVal)) {
+							dpSkuView.setSpecVal(languageSpecVal);
+						}
+					}
+				}
 			}
 			if (views.getIsSp()) {
 				if (fUid == null) {
@@ -587,6 +621,12 @@ public class GoodsDonController {
 //			key += ":hz-ip";
 //			isRemoveRg.set(true);
 //		}
+		String lang = request.getHeader("lang");
+		AtomicBoolean language = new AtomicBoolean(false);
+		if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			key += ":" + lang;
+			language.set(true);
+		}
 		Long fUid = StpUserUtil.getUserIdAfterLogin();
 		Object o = redisService.get(key);
 		if (o == null) {
@@ -610,6 +650,10 @@ public class GoodsDonController {
 							}
 						}
 						List<HomeManagementFrontView> homeManagementFrontViews = beanSearcher.searchAll(HomeManagementFrontView.class, builder.build());
+						//实物推荐多语言
+						if (language.get() && type == HomeManagementConfig.Type.rg) {
+							backInfoTranslationsFrontService.getHomeConfigRealGoodsLanguage(homeManagementFrontViews, lang);
+						}
 						map.putIfAbsent(type.name(), homeManagementFrontViews);
 					});
 			redisService.setNx(key, map, 50 * 60l);
@@ -877,6 +921,7 @@ public class GoodsDonController {
 	 */
 	public void setHomeManageSpecific(List<HomeManagementFrontView> list, Long fUid, Long dsUserId, BigDecimal discount) {
 		DateTime now = DateTime.now();
+		String lang = request.getHeader("lang");
 		list.forEach(data -> {
 			if (data.getIsSp() != null && data.getIsSp() && fUid != null) {
 				//查找所有特定规格最小价格 满足条件
@@ -1029,6 +1074,12 @@ public class GoodsDonController {
 		if (CollUtil.isNotEmpty(filter_goodsIds)) {
 			categoryGoodsKey += ":hz-ip";
 		}
+		String lang = request.getHeader("lang");
+		AtomicBoolean language = new AtomicBoolean(false);
+		if (lang != null && UserPageLanguage.Language.en_US.name().equals(lang)) {
+			categoryGoodsKey += ":" + lang;
+			language.set(true);
+		}
 		Object o = redisService.get(categoryGoodsKey);
 		if (o == null) {
 			DateTime now = DateTime.now();
@@ -1048,6 +1099,10 @@ public class GoodsDonController {
 				if (CollUtil.isNotEmpty(gptBuyGids) && gptBuyGids.contains(data.getId())) {
 					data.setIsGptGift(true);
 				}
+				if (language.get()) {
+					//多语言
+					backInfoTranslationsFrontService.setCategoryGoodsLanguage(data, lang);
+				}
 			});
 			redisService.setNx(categoryGoodsKey, goodsFrontListViews, RedisService.key.YH_HOME_PAGHE_CACHE.getTimeout() + 10 * 60);
 			o = redisService.get(categoryGoodsKey);

+ 32 - 0
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -44,6 +44,7 @@ import com.cyksj.service.mange.ticket.TicketAdvertiseConfigClickRecordService;
 import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.relation.GroupRelationFrontService;
 import com.cyksj.service.relation.GroupsRelationNetflixService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserService;
 import com.cyksj.web.util.StpUserUtil;
@@ -142,6 +143,8 @@ public class GroupRelationController {
 
     private final ClaudeUserMapper claudeUserMapper;
 
+    private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
     private final static Sequence SEQUENCE = new Sequence(0);
 
     @RequestMapping("/get/renewal")
@@ -1006,6 +1009,7 @@ public class GroupRelationController {
                 }
             }
         }
+        String lang = request.getHeader("lang");
         List<RenewUpgradePackageFrontView> renewUpgradePackageFrontViews = beanSearcher.searchAll(RenewUpgradePackageFrontView.class, MapUtils.builder().field(RenewUpgradePackageFrontView::getSkuId, skuId).build());
         renewUpgradePackageFrontViews.forEach(renew -> {
             try {
@@ -1037,6 +1041,14 @@ public class GroupRelationController {
                             .field(RenewUpgradePackageFrontView.RenewSkuView::getGptLimitTime, minTime.get()).op(LessEqual.class)
                             .field(RenewUpgradePackageFrontView.RenewSkuView::getSkuId, upgradeSkuIds).op(Operator.InList)
                             .build());
+                    if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+                        renewSkuViews.forEach(renewSku->{
+                            String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(renewSku.getSkuId(), lang);
+                            if (StrUtil.isNotBlank(languageSpecVal)) {
+                                renewSku.setSpecVal(languageSpecVal);
+                            }
+                        });
+                    }
                 }
                 renew.setRenewSkus(renewSkuViews);
             } catch (Exception e) {
@@ -1280,4 +1292,24 @@ public class GroupRelationController {
         Boolean flag = groupRelationFrontService.getMirrorPopups(userId);
         return GatewayResponse.SUCCESS.newBuilder().toResult(flag);
     }
+
+    /**
+     * 镜像车票列表
+     */
+    @GetMapping("/get/mirror/ticket")
+    public Result<List<UserMirrorTicketView>> getMirrorTicket() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<UserMirrorTicketView> list = groupRelationFrontService.getMirrorTicket(userId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(list);
+    }
+
+    /**
+     * 镜像车票续费升级信息
+     */
+    @GetMapping("/get/renewInfo")
+    public Result<TicketRenewUpgradeView> getRenewUpgradeInfo(Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        TicketRenewUpgradeView renewView = groupRelationFrontService.getRenewUpgradeInfo(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(renewView);
+    }
 }

+ 23 - 5
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonCategoryController.java

@@ -2,21 +2,21 @@ package com.cyksj.web.controller.manage.goods;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GoodsClickUserRecordMapper;
-import com.cyksj.model.entity.GoodsClickUserRecord;
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.GoodsDonCategory;
-import com.cyksj.model.entity.GoodsDonCategoryRelate;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.views.GoodsDonCategoryGoodsView;
 import com.cyksj.model.views.GoodsDonCategoryView;
 import com.cyksj.service.mange.CmsGoodsDonService;
 import com.cyksj.service.mange.GoodsDonCategoryRelateService;
 import com.cyksj.service.mange.GoodsDonCategoryService;
 import com.cyksj.service.mange.RefreshCacheService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
+import com.cyksj.service.translations.BackInfoTranslationsService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.util.MapBuilder;
@@ -53,6 +53,10 @@ public class CmsGoodsDonCategoryController {
 
 	private final RefreshCacheService refreshCacheService;
 
+	private final BackInfoTranslationsService backInfoTranslationsService;
+
+	private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
 	/**
 	 * 新增分类
 	 */
@@ -67,7 +71,13 @@ public class CmsGoodsDonCategoryController {
 	 */
 	@PutMapping("/put")
 	public Result<String> updateGoodsDonCategory(@RequestBody List<GoodsDonCategory> categorys) {
-		categorys.forEach(category -> goodsDonCategoryService.saveOrUpdateGoods(category));
+		String lang = request.getHeader("lang");
+		//多语言
+		if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			categorys.forEach(category -> backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.goods_category, category.getId(), category, lang));
+		} else {
+			categorys.forEach(category -> goodsDonCategoryService.saveOrUpdateGoods(category));
+		}
 		refreshCacheService.refreshYhHomeCategoryPageCache();
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
@@ -121,11 +131,19 @@ public class CmsGoodsDonCategoryController {
 	 */
 	@GetMapping("/get")
 	public Result<SearchResult<GoodsDonCategoryView>> getCategory() {
+		String lang = request.getHeader("lang");
 		SearchResult<GoodsDonCategoryView> search = beanSearcher.search(GoodsDonCategoryView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
 		search.getDataList().forEach(data->{
 			Integer count = goodsClickUserRecordMapper.selectCount(Wrappers.lambdaQuery(GoodsClickUserRecord.class)
 					.eq(GoodsClickUserRecord::getCategory, data.getId()));
 			data.setClick(count);
+			//多语言
+			if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+				String categoryNameLanguage = backInfoTranslationsFrontService.getCategoryNameLanguage(data.getId(), lang);
+				if (StrUtil.isNotBlank(categoryNameLanguage)) {
+					data.setName(categoryNameLanguage);
+				}
+			}
 		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}

+ 23 - 6
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonController.java

@@ -12,9 +12,7 @@ import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.GoodsDonSkuMapper;
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.GoodsDonCategory;
-import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.request.ReqGoodsSpuInsert;
 import com.cyksj.model.manage.views.GoodsDonViewer;
 import com.cyksj.model.views.CategoryGoodsCascadeView;
@@ -23,6 +21,8 @@ import com.cyksj.model.views.GoodsDonCategoryDetailView;
 import com.cyksj.service.mange.CmsGoodsDonService;
 import com.cyksj.service.mange.GoodsDonCategoryService;
 import com.cyksj.service.mange.RefreshCacheService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
+import com.cyksj.service.translations.BackInfoTranslationsService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.param.Operator;
@@ -60,6 +60,10 @@ public class CmsGoodsDonController {
 
     private final GoodsDonSkuMapper skuMapper;
 
+    private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
+    private final BackInfoTranslationsService backInfoTranslationsService;
+
     @GetMapping("/get")
     public Result<SearchResult<GoodsDonCategoryDetailView>> get(){
         SearchResult<GoodsDonCategoryDetailView> search = beanSearcher.search(GoodsDonCategoryDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
@@ -80,6 +84,10 @@ public class CmsGoodsDonController {
         }
         List<GoodsDonCategory> categoryView = goodsDonCategoryService.getCateGoryViewByGoodsId(id);
         goodsDonViewer.setCategoryList(categoryView.stream().map(GoodsDonCategory::getId).collect(Collectors.toList()));
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+            backInfoTranslationsFrontService.setGoodsBackLanguage(goodsDonViewer, lang);
+        }
         return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonViewer);
     }
 
@@ -91,6 +99,10 @@ public class CmsGoodsDonController {
         List<GoodsDonSku> goodsDonSkus = beanSearcher.searchAll(GoodsDonSku.class, MapUtils.flatBuilder(request.getParameterMap()).field(GoodsDonSku::getGoodsId, id)
                 .orderBy(GoodsDonSku::getSorted).asc()
                 .build());
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+            backInfoTranslationsFrontService.setSkuBackLanguage(goodsDonSkus, lang);
+        }
         return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonSkus);
     }
 
@@ -157,9 +169,14 @@ public class CmsGoodsDonController {
             re_goodsIds.remove(spu.getId());
             goods.setRecommendGoods(Jsons.toJson(re_goodsIds));
         }
-        //平台 分类关系
-        goodsDonCategoryService.handleGoodsRelate(goods.getId(), spu.getCategoryList());
-        goodsDonService.updateById(goods);
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+            backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.goods, goods.getId(), goods, lang);
+        } else {
+            //平台 分类关系
+            goodsDonCategoryService.handleGoodsRelate(goods.getId(), spu.getCategoryList());
+            goodsDonService.updateById(goods);
+        }
         refreshCacheService.refreshYhHomePageCache();
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }

+ 35 - 22
netflix-web/src/main/java/com/cyksj/web/controller/manage/goods/CmsGoodsDonSkuController.java

@@ -10,9 +10,7 @@ import com.cyksj.common.util.Jsons;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.model.entity.GoodsDiscountPlusPurchaseRelation;
-import com.cyksj.model.entity.GoodsDon;
-import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.request.ReqGoodsSkuInsert;
 import com.cyksj.model.request.CombinationSkuReq;
 import com.cyksj.model.views.DistributeSearchView;
@@ -20,6 +18,8 @@ import com.cyksj.service.mange.CmsGoodsDonService;
 import com.cyksj.service.mange.CmsGoodsDonSkuService;
 import com.cyksj.service.mange.CmsGoodsDonSpecService;
 import com.cyksj.service.mange.RefreshCacheService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
+import com.cyksj.service.translations.BackInfoTranslationsService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.param.Operator;
@@ -59,6 +59,10 @@ public class CmsGoodsDonSkuController {
 
     private final RefreshCacheService refreshCacheService;
 
+    private final BackInfoTranslationsService backInfoTranslationsService;
+
+    private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
 
     /**
      * 新增 商品spec & sku
@@ -156,26 +160,31 @@ public class CmsGoodsDonSkuController {
                 sku.setUserOwns(userOwnsList.toString());
             }
         }
-        //优惠加购
-        goodsDonSkuService.handleDiscountPurchaseGoods(sku, sku.getDpSku());
-
-        String benefitsList = sku.getBenefitsList();
-        if (StrUtil.isNotBlank(benefitsList)) {
-            Set<GoodsDonSku> benefitsSkuIds = Jsons.parseSet(benefitsList, GoodsDonSku.class);
-            sku.setBenefitsList(Jsons.toJson(benefitsSkuIds));
+        //多语言
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+            backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.sku, sku.getId(), sku, lang);
+        } else {
+            //优惠加购
+            goodsDonSkuService.handleDiscountPurchaseGoods(sku, sku.getDpSku());
+            String benefitsList = sku.getBenefitsList();
+            if (StrUtil.isNotBlank(benefitsList)) {
+                Set<GoodsDonSku> benefitsSkuIds = Jsons.parseSet(benefitsList, GoodsDonSku.class);
+                sku.setBenefitsList(Jsons.toJson(benefitsSkuIds));
+            }
+            goodsDonSkuService.updateMirrorCarUserNum(sku);
+            goodsDonSkuService.saveOrUpdate(sku);
+            //给平台更新额外属性
+            goodsDonService.updateGoodsSkuPrice(sku.getGoodsId(), null);
+            //前后两次价格不同 下架店铺低于这个折扣最低价格
+            BigDecimal oldPrice = dbSku.getPrice();
+            BigDecimal newPrice = sku.getPrice();
+            //规格新价 变高
+            //下架店铺低于这个规格价格的品
+            goodsDonSkuService.setBelowPriceShopSkuDown(skuId, newPrice);
+            //套餐包关联规格
+            goodsDonSkuService.handleGptPackageSku(dbSku, sku);
         }
-        goodsDonSkuService.updateMirrorCarUserNum(sku);
-        goodsDonSkuService.saveOrUpdate(sku);
-        //给平台更新额外属性
-        goodsDonService.updateGoodsSkuPrice(sku.getGoodsId(), null);
-        //前后两次价格不同 下架店铺低于这个折扣最低价格
-        BigDecimal oldPrice = dbSku.getPrice();
-        BigDecimal newPrice = sku.getPrice();
-        //规格新价 变高
-        //下架店铺低于这个规格价格的品
-        goodsDonSkuService.setBelowPriceShopSkuDown(skuId, newPrice);
-        //套餐包关联规格
-        goodsDonSkuService.handleGptPackageSku(dbSku,sku);
         refreshCacheService.refreshYhHomePageCache();
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
@@ -234,6 +243,10 @@ public class CmsGoodsDonSkuController {
                 }
             }
         });
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(lang, UserPageLanguage.Language.zh_CN.name())) {
+            backInfoTranslationsFrontService.setSkuBackLanguage(skuViewList.getDataList(), lang);
+        }
         return GatewayResponse.SUCCESS.newBuilder().toResult(skuViewList);
     }
 

+ 20 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/home/HomeManageConfigController.java

@@ -1,12 +1,11 @@
 package com.cyksj.web.controller.manage.home;
 
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.model.entity.GoodsDonCategory;
-import com.cyksj.model.entity.HomeManagementConfig;
-import com.cyksj.model.entity.HomeManagementConfigUserClickRecord;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.request.HomeConfigTimingReq;
 import com.cyksj.model.request.HomeManageConfigReq;
 import com.cyksj.model.views.HomeManagementAvailableGoodsView;
@@ -14,6 +13,8 @@ import com.cyksj.model.views.HomeManagementConfigView;
 import com.cyksj.service.home.HomeManagementConfigService;
 import com.cyksj.service.mange.GoodsDonCategoryService;
 import com.cyksj.service.mange.RefreshCacheService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
+import com.cyksj.service.translations.BackInfoTranslationsService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
 import com.ejlchina.searcher.util.MapUtils;
@@ -43,6 +44,10 @@ public class HomeManageConfigController {
 
 	private final GoodsDonCategoryService goodsDonCategoryService;
 
+	private final BackInfoTranslationsService backInfoTranslationsService;
+
+	private final BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
 	/**
 	 * 新增首页配置
 	 */
@@ -57,7 +62,12 @@ public class HomeManageConfigController {
 	 */
 	@PutMapping("/put")
 	public Result<String> updateConfig(@RequestBody HomeManageConfigReq config) {
-		homeManagementConfigService.saveOrUpdateConfig(config);
+		String lang = request.getHeader("lang");
+		if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+			backInfoTranslationsService.saveOrUpdateBackInfoTranslations(BackInfoTranslations.Type.home_config, config.getId(), config, lang);
+		} else {
+			homeManagementConfigService.saveOrUpdateConfig(config);
+		}
 		refreshCacheService.refreshYhHomePageCache();
 		return GatewayResponse.SUCCESS.newBuilder().toResult();
 	}
@@ -144,10 +154,16 @@ public class HomeManageConfigController {
 		SearchResult<HomeManagementConfigView> search = beanSearcher.search(HomeManagementConfigView.class, MapUtils.flatBuilder(request.getParameterMap())
 				.field(HomeManagementConfigView::getType, type.name())
 				.build());
+		String lang = request.getHeader("lang");
 		search.getDataList().forEach(data -> {
 			Number number = beanSearcher.searchCount(HomeManagementConfigUserClickRecord.class, MapUtils.builder()
 					.field(HomeManagementConfigUserClickRecord::getConfigId, data.getId()).build());
 			data.setClick(number.intValue());
+			if (data.getType() == HomeManagementConfig.Type.rg) {
+				if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+					backInfoTranslationsFrontService.setFieldLanguage(data.getClass(), data, BackInfoTranslations.Type.home_config.ordinal(), data.getId(), lang);
+				}
+			}
 		});
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}

+ 31 - 0
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -42,6 +42,7 @@ import com.cyksj.service.paypal.PaypalPayConfigService;
 import com.cyksj.service.paypal.PaypalV2Service;
 import com.cyksj.service.stripe.StripePayConfigService;
 import com.cyksj.service.stripe.StripeService;
+import com.cyksj.service.translations.BackInfoTranslationsFrontService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
@@ -142,6 +143,9 @@ public class OrderController {
     @Autowired
     private GroupsRelationMapper relationMapper;
 
+    @Autowired
+    private BackInfoTranslationsFrontService backInfoTranslationsFrontService;
+
     /**
      * 支付
      * @author chan
@@ -470,6 +474,7 @@ public class OrderController {
                 .field(OrderDonView::getUserId, userIds).op(Operator.InList)
                 .orderBy(OrderDonView::getId).desc()
                 .build());
+        String lang = request.getHeader("lang");
         search.getDataList().forEach(data->{
             Integer count = availableBenefitsMapper.selectCount(Wrappers.lambdaQuery(UserPayEquipmentAvailableBenefits.class)
                     .eq(UserPayEquipmentAvailableBenefits::getRealOrderId, data.getId())
@@ -499,6 +504,16 @@ public class OrderController {
                         .last("limit 1"));
                 data.setIsRenewPackage(orderDonRenewRecord != null ? true : false);
             }
+            if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+                String languagePayTitle = backInfoTranslationsFrontService.getLanguagePayTitle(data.getGoodsId(), data.getSkuId(), lang);
+                if (StrUtil.isNotBlank(languagePayTitle)) {
+                    data.setPayTitle(languagePayTitle);
+                }
+                String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(data.getSkuId(), lang);
+                if (StrUtil.isNotBlank(languageSpecVal)) {
+                    data.setSpecVal(languageSpecVal);
+                }
+            }
         });
         return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
@@ -546,6 +561,22 @@ public class OrderController {
                         orderDonView.setOriSpecVal(sku.getSpecVal());
                     });
         }
+        String lang = request.getHeader("lang");
+        if (lang != null && !StrUtil.equals(UserPageLanguage.Language.zh_CN.name(), lang)) {
+            String languagePayTitle = backInfoTranslationsFrontService.getLanguagePayTitle(orderDonView.getGoodsId(), orderDonView.getSkuId(), lang);
+            if (StrUtil.isNotBlank(languagePayTitle)) {
+                orderDonView.setPayTitle(languagePayTitle);
+            }
+            String languageSpecVal = backInfoTranslationsFrontService.getLanguageSpecVal(orderDonView.getSkuId(), lang);
+            if (StrUtil.isNotBlank(languageSpecVal)) {
+                orderDonView.setSpecVal(languageSpecVal);
+            }
+            String languagePayDesc = backInfoTranslationsFrontService.getLanguagePayDesc(orderDonView.getGoodsId(), lang);
+            if (StrUtil.isNotBlank(languagePayDesc)) {
+                orderDonView.setPayDesc(languagePayDesc);
+            }
+        }
+
         return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonView);
     }