Sfoglia il codice sorgente

Merge branch 'distribute_func'

zoujiajian 2 anni fa
parent
commit
ac2f54d674
32 ha cambiato i file con 890 aggiunte e 84 eliminazioni
  1. 6 0
      netflix-dao/src/main/java/com/cyksj/mapper/MidjourneyUserConversationMapper.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/DistributeGeneralSkuRateMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/DistributePosterGoodsMapper.java
  4. 22 0
      netflix-dao/src/main/java/com/cyksj/model/entity/DistributeGeneralSkuRate.java
  5. 30 0
      netflix-dao/src/main/java/com/cyksj/model/entity/DistributePosterGoods.java
  6. 6 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java
  7. 5 0
      netflix-dao/src/main/java/com/cyksj/model/request/OrderRefundReq.java
  8. 42 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsDetailView.java
  9. 52 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsFrontView.java
  10. 52 0
      netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsView.java
  11. 40 0
      netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuRateView.java
  12. 18 0
      netflix-dao/src/main/java/com/cyksj/model/views/MidjourneyUserDetailView.java
  13. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  14. 19 0
      netflix-dao/src/main/resources/mapper/MidjourneyUserConversationMapper.xml
  15. 14 0
      netflix-service/src/main/java/com/cyksj/service/distribute/DistributePosterGoodsService.java
  16. 3 0
      netflix-service/src/main/java/com/cyksj/service/distribute/DistributeService.java
  17. 47 0
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributePosterGoodsServiceImp.java
  18. 20 0
      netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java
  19. 0 2
      netflix-service/src/main/java/com/cyksj/service/mange/CmsOrderDonService.java
  20. 11 0
      netflix-service/src/main/java/com/cyksj/service/mange/MirrorUserCleatService.java
  21. 16 36
      netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java
  22. 49 0
      netflix-service/src/main/java/com/cyksj/service/mange/impl/MirrorUserCleatServiceImpl.java
  23. 8 4
      netflix-service/src/main/java/com/cyksj/service/midjourney/impl/MidJourneyAccountServiceImpl.java
  24. 45 35
      netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java
  25. 4 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationClearServiceImpl.java
  26. 59 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  27. 3 3
      netflix-web/src/main/java/com/cyksj/web/controller/external/ExternalController.java
  28. 28 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java
  29. 20 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java
  30. 114 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributePosterController.java
  31. 23 4
      netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java
  32. 105 0
      netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/mapper/MidjourneyUserConversationMapper.java

@@ -2,10 +2,16 @@ package com.cyksj.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.cyksj.model.entity.MidjourneyUserConversation;
+import com.cyksj.model.views.MidjourneyUserDetailView;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
 
 /**
  * @author zwhui
  * @date 2024/4/23 16:03
  */
 public interface MidjourneyUserConversationMapper extends BaseMapper<MidjourneyUserConversation> {
+
+	MidjourneyUserDetailView getMjMirrorOrderDetail(@Param("relationId") Long relationId, @Param("startTime") Date startTime, @Param("expiryTime") Date expiryTime);
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/DistributeGeneralSkuRateMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.DistributeGeneralSkuRate;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributeGeneralSkuRateMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 14:05
+ */
+public interface DistributeGeneralSkuRateMapper extends BaseMapper<DistributeGeneralSkuRate> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/distribute/DistributePosterGoodsMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.distribute;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.DistributePosterGoods;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 13:49
+ */
+public interface DistributePosterGoodsMapper extends BaseMapper<DistributePosterGoods> {
+}

+ 22 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/DistributeGeneralSkuRate.java

@@ -0,0 +1,22 @@
+package com.cyksj.model.entity;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributeGeneralSkuRate
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 14:04
+ */
+
+@Getter
+@Setter
+public class DistributeGeneralSkuRate extends BaseEntity {
+	private Long goodsId;
+
+	private Long skuId;
+
+	private Integer rate;
+}

+ 30 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/DistributePosterGoods.java

@@ -0,0 +1,30 @@
+package com.cyksj.model.entity;
+
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoods
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 13:48
+ */
+
+@Getter
+@Setter
+public class DistributePosterGoods extends BaseEntity{
+
+	private String name;
+
+	private Long goodsId;
+
+	@TableField(updateStrategy = FieldStrategy.IGNORED)
+	private String skuIds;
+
+	private String img;
+
+	private Boolean status;
+}

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/manage/views/OrderDonBackView.java

@@ -278,4 +278,10 @@ public class OrderDonBackView {
 	 */
 	@DbIgnore
 	private String serviceName;
+
+	@DbField("sku.mj_fast_num")
+	private Integer mjFastNum;
+
+	@DbField("sku.mj_relax_num")
+	private Integer mjRelaxNum;
 }

+ 5 - 0
netflix-dao/src/main/java/com/cyksj/model/request/OrderRefundReq.java

@@ -48,4 +48,9 @@ public class OrderRefundReq {
 	 * 聊天记录截图
 	 */
 	private String chatImg;
+
+	/**
+	 * 扣除的余额
+	 */
+	private BigDecimal deductBalance;
 }

+ 42 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsDetailView.java

@@ -0,0 +1,42 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 15:32
+ */
+
+@Getter
+@Setter
+@SearchBean(tables = "distribute_poster_goods dp inner join goods_don g on g.id = dp.goods_id",
+		where = "dp.status is true and g.status is true and g.deleted is true")
+public class DistributePosterGoodsDetailView {
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("dp.name")
+	private String name;
+
+	@DbField("dp.img")
+	private String img;
+
+	@DbField("dp.sku_ids")
+	private String skuIds;
+
+	@DbIgnore
+	private String nickname;
+
+	@DbField("g.rate")
+	private Integer rate;
+}

+ 52 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsFrontView.java

@@ -0,0 +1,52 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsFrontView
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 14:36
+ */
+
+@Getter
+@Setter
+@SearchBean(tables = "distribute_poster_goods dp inner join goods_don g on g.id = dp.goods_id",
+		where = "dp.status is true and g.status is true and g.deleted is true",
+		orderBy = "dp.update_time desc")
+public class DistributePosterGoodsFrontView {
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String title;
+
+	/**
+	 * 推广名称
+	 */
+	@DbField("dp.name")
+	private String name;
+
+	@DbField("dp.img")
+	private String img;
+
+	@DbField("g.logo")
+	private String logo;
+
+	@DbField("g.rate")
+	private Integer rate;
+
+	@DbField("g.is_sku_distribute")
+	private Boolean isSkuRate;
+
+	@DbField("g.min_price")
+	private BigDecimal price;
+
+	@DbField("dp.sku_ids")
+	private String skuIds;
+}

+ 52 - 0
netflix-dao/src/main/java/com/cyksj/model/views/DistributePosterGoodsView.java

@@ -0,0 +1,52 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsView
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 15:48
+ */
+
+@Getter
+@Setter
+@SearchBean(tables = "distribute_poster_goods dp inner join goods_don g on g.id = dp.goods_id",
+		orderBy = "dp.update_time desc")
+public class DistributePosterGoodsView {
+	@DbField("dp.id")
+	private Long id;
+
+	@DbField("dp.name")
+	public String name;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("g.id")
+	private Long goodsId;
+
+	@DbField("dp.sku_ids")
+	private String skuIds;
+
+	@DbIgnore
+	private String specVal;
+
+	@DbField("dp.img")
+	private String img;
+
+	@DbField("dp.status")
+	private Boolean status;
+
+	@DbField("dp.created_time")
+	private Date createdTIme;
+
+	@DbField("dp.update_time")
+	private Date updateTime;
+}

+ 40 - 0
netflix-dao/src/main/java/com/cyksj/model/views/GoodsDonSkuRateView.java

@@ -0,0 +1,40 @@
+package com.cyksj.model.views;
+
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: GoodsDonSkuRateView
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 14:17
+ */
+
+@Getter
+@Setter
+@SearchBean(tables = "goods_don_sku sku inner join goods_don g on g.id = sku.goods_id" +
+		" left join distribute_general_sku_rate sr on sr.sku_id = sku.id",
+		where = "g.is_distribute is true and g.is_sku_distribute is true and g.type = 1 and g.status is true and g.deleted is true and sku.status is true",
+		orderBy = "sku.goods_id asc")
+public class GoodsDonSkuRateView {
+	@DbField("sr.id")
+	private Long id;
+
+	@DbField("sku.goods_id")
+	private Long goodsId;
+
+	@DbField("g.title")
+	private String title;
+
+	@DbField("sku.id")
+	private Long skuId;
+
+	@DbField("sku.spec_val")
+	private String specVal;
+
+	@DbField("sr.rate")
+	private Integer rate = 0;
+}

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/views/MidjourneyUserDetailView.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.views;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: MidjourneyUserDetailView
+ * 创建者: JavaZou
+ * 创建时间:2024/6/25 15:26
+ */
+@Getter
+@Setter
+public class MidjourneyUserDetailView {
+	private Integer useFastNum;
+
+	private Integer useRelaxNum;
+}

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

@@ -257,4 +257,7 @@ public class RenewalView {
      */
     @DbIgnore
     private Boolean qa;
+
+    @DbIgnore
+    private DistributePosterGoodsDetailView posterInfo;
 }

+ 19 - 0
netflix-dao/src/main/resources/mapper/MidjourneyUserConversationMapper.xml

@@ -0,0 +1,19 @@
+<?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.MidjourneyUserConversationMapper">
+
+
+    <select id="getMjMirrorOrderDetail" resultType="com.cyksj.model.views.MidjourneyUserDetailView">
+        select count(IF(muc.mode = 1, 1, NULL)) as useFastNum, count(if(muc.mode = 2, 1, NULL)) as useRelaxNum
+        from (select id from midjourney_user where relation_id = #{relationId} limit 1) mu
+        inner join midjourney_user_conversation muc on muc.user_id = mu.id
+        where muc.status in ('SUCCESS', 'IN_PROGRESS')
+        <if test="startTime != null">
+            and created_time > #{startTime}
+        </if>
+        <if test="expiryTime != null">
+            and created_time &lt; #{expiryTime}
+        </if>
+    </select>
+</mapper>

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/DistributePosterGoodsService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.distribute;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.DistributePosterGoods;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsService
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 15:41
+ */
+public interface DistributePosterGoodsService extends IService<DistributePosterGoods> {
+	void saveOrUpdatePo(DistributePosterGoods distributePosterGoods) throws Exception;
+}

+ 3 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/DistributeService.java

@@ -1,5 +1,6 @@
 package com.cyksj.service.distribute;
 
+import com.cyksj.model.entity.DistributeGeneralSkuRate;
 import com.cyksj.model.request.UserDistributeReq;
 
 import java.util.List;
@@ -29,4 +30,6 @@ public interface DistributeService {
 	void bindPopularizeCode(Long userId, String code);
 
 	void unbindUserDistributeShared(List<Object> userBind) throws Exception;
+
+	void setDistributeCommonSkuRate(List<DistributeGeneralSkuRate> skuRates);
 }

+ 47 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributePosterGoodsServiceImp.java

@@ -0,0 +1,47 @@
+package com.cyksj.service.distribute.impl;
+
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.mapper.GoodsDonMapper;
+import com.cyksj.mapper.manage.distribute.DistributePosterGoodsMapper;
+import com.cyksj.model.entity.DistributePosterGoods;
+import com.cyksj.model.entity.GoodsDon;
+import com.cyksj.service.distribute.DistributePosterGoodsService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterGoodsServiceImp
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 15:42
+ */
+@Service
+@RequiredArgsConstructor
+public class DistributePosterGoodsServiceImp extends ServiceImpl<DistributePosterGoodsMapper, DistributePosterGoods> implements DistributePosterGoodsService {
+
+	private final GoodsDonMapper goodsDonMapper;
+
+	@Override
+	public void saveOrUpdatePo(DistributePosterGoods distributePosterGoods) throws Exception {
+		Assert.notEmpty(distributePosterGoods.getImg(), "海报不为空");
+
+		Long goodsId = distributePosterGoods.getGoodsId();
+
+		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
+
+		if (goodsDon.getIsSkuDistribute()) {
+			if (StrUtil.isEmpty(distributePosterGoods.getSkuIds())) {
+				throw BusinessRuntimeException.getInstance("请选择对应的规格");
+			}
+			distributePosterGoods.setSkuIds(Jsons.toJson(Jsons.parseList(distributePosterGoods.getSkuIds(), String.class)));
+		} else {
+			distributePosterGoods.setSkuIds(null);
+		}
+
+		this.saveOrUpdate(distributePosterGoods);
+	}
+}

+ 20 - 0
netflix-service/src/main/java/com/cyksj/service/distribute/impl/DistributeServiceImpl.java

@@ -81,6 +81,8 @@ public class DistributeServiceImpl implements DistributeService {
 
 	private final UserDistributeSubMapper userDistributeSubMapper;
 
+	private final DistributeGeneralSkuRateMapper generalSkuRateMapper;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void insertDistribute(UserDistributeReq userDistributeReq) {
@@ -379,6 +381,24 @@ public class DistributeServiceImpl implements DistributeService {
 		}
 	}
 
+	@Override
+	public void setDistributeCommonSkuRate(List<DistributeGeneralSkuRate> skuRates) {
+		skuRates.forEach(e -> {
+			Integer rate = e.getRate();
+			if (rate == null || rate < 0 || rate > 100) {
+				throw BusinessRuntimeException.getInstance("请输入正确的比例");
+			}
+			if (e.getId() == null) {
+				try {
+					generalSkuRateMapper.insert(e);
+				} catch (DuplicateKeyException ex) {
+				}
+			} else {
+				generalSkuRateMapper.updateById(e);
+			}
+		});
+	}
+
 	public void checkDistributorAndBusinessRate(Integer distributeGoodsRate, Long goodsId, String goodsName) {
 		UserBusinessDefaultRateConfig defaultGoodsRateConfig = defaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(UserBusinessDefaultRateConfig.class)
 				.eq(UserBusinessDefaultRateConfig::getGoodsId, goodsId)

+ 0 - 2
netflix-service/src/main/java/com/cyksj/service/mange/CmsOrderDonService.java

@@ -57,6 +57,4 @@ public interface CmsOrderDonService extends IService<OrderDon> {
 	void refundPriceDiffer(OrderRefundReq orderRefundReq) throws Exception;
 
 	void clearBalanceToRefundMoney(OrderBalanceRefundReq refundReq) throws Exception;
-
-	void delMirrorUser(Long goodsId, Long relationId);
 }

+ 11 - 0
netflix-service/src/main/java/com/cyksj/service/mange/MirrorUserCleatService.java

@@ -0,0 +1,11 @@
+package com.cyksj.service.mange;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: MirrorUserCleatService
+ * 创建者: JavaZou
+ * 创建时间:2024/6/27 11:15
+ */
+public interface MirrorUserCleatService {
+	void delMirrorUser(Long goodsId, Long relationId);
+}

+ 16 - 36
netflix-service/src/main/java/com/cyksj/service/mange/impl/CmsOrderDonServiceImpl.java

@@ -51,6 +51,7 @@ import com.cyksj.service.coupon.CouponFontService;
 import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
 import com.cyksj.service.giftcard.GiftCardOrderUseRecordService;
 import com.cyksj.service.mange.CmsOrderDonService;
+import com.cyksj.service.mange.MirrorUserCleatService;
 import com.cyksj.service.mange.stock.GoodsDonStockService;
 import com.cyksj.service.market.MarketFrontService;
 import com.cyksj.service.order.OrderCommonService;
@@ -193,6 +194,8 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
     private final AccountMapper accountMapper;
 
+    private final MirrorUserCleatService mirrorUserCleatService;
+
     private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
     @Override
@@ -358,10 +361,13 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             return;
         }
         //调用第三方接口退款
-        String outNo = orderRefundService.centerRefund(refundReq, orderDon);
+        String outNo = StrUtil.EMPTY;
+        if (refundReq.getRefundMoney() != null && refundReq.getRefundMoney().compareTo(BigDecimal.ZERO) > 0) {
+            outNo = orderRefundService.centerRefund(refundReq, orderDon);
+        }
         orderDon.setRefundDesc(refundReq.getRefundDesc());
         //记录退款信息
-        commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg());
+        commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg(), refundReq.getDeductBalance());
         //修改订单状态
         orderDon.setStatus(OrderDon.Status.refund);
         orderDonMapper.updateById(orderDon);
@@ -690,11 +696,6 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         relation.setNewRelationId(newRelation.getId());
         relationClearService.clearTicket(relation, source);
 
-        //是否是GPT镜像规格
-        if (orderDon.getOrderType() == 1) {
-            delMirrorUser(orderDon.getGoodsId(), orderDon.getRelationId());
-        }
-
         //奈飞车票
         if (orderDon.getGoodsId() == 1) {
             User user = userMapper.selectById(newRelation.getUserId());
@@ -911,7 +912,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
     /**
      * 退款后 处理关联
      */
-    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg) {
+    public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg, BigDecimal deductBalance) {
         TASK_POOL.execute(() -> {
             orderRefundService.refundRecord(orderDon, refundMoney, operator, goodsDon, sku, outNo, refundType, chatImg);
             //退款一次
@@ -935,7 +936,12 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
 
             //若存在余额支付,退还余额
             if (isOnly == null && orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
-                userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getBalance(), UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true);
+                BigDecimal addBalance = orderDon.getBalance();
+                //需额外扣除余额
+                if (deductBalance != null && deductBalance.compareTo(BigDecimal.ZERO) > 0) {
+                    addBalance = addBalance.subtract(deductBalance);
+                }
+                userBenefitsService.addUserBalance(orderDon.getUserId(), addBalance, UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true);
             }
 
             try {
@@ -1051,7 +1057,7 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
             }
             //是否是GPT镜像规格
             if (orderDon.getOrderType() == 1) {
-                delMirrorUser(orderDon.getGoodsId(), orderDon.getRelationId());
+                mirrorUserCleatService.delMirrorUser(orderDon.getGoodsId(), orderDon.getRelationId());
             }
             //是否是分销订单
             //处理下级渠道分销提成
@@ -1329,30 +1335,4 @@ public class CmsOrderDonServiceImpl extends ServiceImpl<OrderDonMapper,OrderDon>
         }
         return relation;
     }
-
-    /**
-     * 删除gptUser
-     */
-    @Override
-    public void delMirrorUser(Long goodsId, Long relationId) {
-        //gpt镜像
-        if (goodsId != null && goodsId == 18) {
-            Integer selectCount = chatgptUserMapper.selectCount(Wrappers.lambdaQuery(ChatgptUser.class)
-                    .eq(ChatgptUser::getRelationId, relationId));
-            if (selectCount > 0) {
-                chatgptUserMapper.delete(Wrappers.lambdaQuery(ChatgptUser.class)
-                        .eq(ChatgptUser::getRelationId, relationId));
-            }
-        }
-        //mj镜像
-        if (goodsId != null && goodsId == 26) {
-            MidjourneyUser user = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class)
-                    .eq(MidjourneyUser::getRelationId, relationId).last("limit 1"));
-            if (user != null) {
-                midjourneyUserMapper.delete(Wrappers.lambdaQuery(MidjourneyUser.class)
-                        .eq(MidjourneyUser::getRelationId, relationId));
-                redisService.del(RedisService.key.MIDJOURNEY_USER.getName() + user.getUserToken());
-            }
-        }
-    }
 }

+ 49 - 0
netflix-service/src/main/java/com/cyksj/service/mange/impl/MirrorUserCleatServiceImpl.java

@@ -0,0 +1,49 @@
+package com.cyksj.service.mange.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.mapper.ChatgptUserMapper;
+import com.cyksj.mapper.MidjourneyUserMapper;
+import com.cyksj.model.entity.ChatgptUser;
+import com.cyksj.model.entity.MidjourneyUser;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.mange.MirrorUserCleatService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: MirrorUserCleatServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/6/27 11:15
+ */
+@Service
+@RequiredArgsConstructor
+public class MirrorUserCleatServiceImpl implements MirrorUserCleatService {
+	private final ChatgptUserMapper chatgptUserMapper;
+
+	private final MidjourneyUserMapper midjourneyUserMapper;
+
+	private final RedisService redisService;
+	@Override
+	public void delMirrorUser(Long goodsId, Long relationId) {
+		//gpt镜像
+		if (goodsId != null && goodsId == 18) {
+			Integer selectCount = chatgptUserMapper.selectCount(Wrappers.lambdaQuery(ChatgptUser.class)
+					.eq(ChatgptUser::getRelationId, relationId));
+			if (selectCount > 0) {
+				chatgptUserMapper.delete(Wrappers.lambdaQuery(ChatgptUser.class)
+						.eq(ChatgptUser::getRelationId, relationId));
+			}
+		}
+		//mj镜像
+		if (goodsId != null && goodsId == 26) {
+			MidjourneyUser user = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class)
+					.eq(MidjourneyUser::getRelationId, relationId).last("limit 1"));
+			if (user != null) {
+				midjourneyUserMapper.delete(Wrappers.lambdaQuery(MidjourneyUser.class)
+						.eq(MidjourneyUser::getRelationId, relationId));
+				redisService.del(RedisService.key.MIDJOURNEY_USER.getName() + user.getUserToken());
+			}
+		}
+	}
+}

+ 8 - 4
netflix-service/src/main/java/com/cyksj/service/midjourney/impl/MidJourneyAccountServiceImpl.java

@@ -19,6 +19,7 @@ import com.cyksj.service.midjourney.MidjourneyAccountService;
 import com.cyksj.service.user.UserBindRelationService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -291,11 +292,14 @@ public class MidJourneyAccountServiceImpl extends ServiceImpl<MidjourneyAccountM
             midjourneyUser.setMjRelaxNum((goodsDonSku.getMjRelaxNum() == null || goodsDonSku.getMjRelaxNum() == 0) ? null : goodsDonSku.getMjRelaxNum());
         }
         midjourneyUser.setAqType(groupsRelation.getAqType());
-        midjourneyUserMapper.insert(midjourneyUser);
-        redisService.set(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjFastNum(),RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
-        redisService.set(RedisService.key.MIDJOURNEY_USER.getName() + midjourneyUser.getUserToken(), midjourneyUser,RedisService.key.MIDJOURNEY_USER.getTimeout());
+        try {
+            midjourneyUserMapper.insert(midjourneyUser);
+        } catch (DuplicateKeyException e) {
+        }
+        redisService.set(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjFastNum(), RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
+        redisService.set(RedisService.key.MIDJOURNEY_USER.getName() + midjourneyUser.getUserToken(), midjourneyUser, RedisService.key.MIDJOURNEY_USER.getTimeout());
         if (midjourneyUser.getMjRelaxNum() != null) {
-            redisService.set(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjRelaxNum(),RedisService.key.MIDJOURNEY_RELAX_LIMIT.getTimeout());
+            redisService.set(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjRelaxNum(), RedisService.key.MIDJOURNEY_RELAX_LIMIT.getTimeout());
         }
         return midjourneyUser;
     }

+ 45 - 35
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -315,6 +315,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	private final OrderDonExceptionUserRecordMapper orderDonExceptionUserRecordMapper;
 
+	private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
+
 	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");
 
 	@Transactional(rollbackFor = Throwable.class)
@@ -1560,6 +1562,13 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 							}
 						}
 					}
+					//该平台是否开启规格分销
+					if (goodsDon.getIsSkuDistribute()) {
+						//是否设置对应规格分销比例
+						DistributeGeneralSkuRate skuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
+								.eq(DistributeGeneralSkuRate::getSkuId, goodsDonSku.getId()).last("limit 1"));
+						if (skuRate != null) rate = skuRate.getRate();
+					}
 					returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
 				} else {
 					businessId = userDistribute.getBusinessId();
@@ -2272,49 +2281,50 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		//特殊渠道推广优惠. 360
 		if (subsidyId == null && orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
 			String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
-			//使用了优惠券 不再使用360渠道 折扣
-			if (couponUser == null && goodsType == 1) {
-				if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
-					String key;
-					if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
-						//百度渠道 专门优惠链接
-						key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
-					} else {
-						//抖音
-						key = Constant.CHANNEL_DY_DISCOUNT_KEY;
-					}
-					SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
-							.eq(SysConfig::getSysKey, key).last("limit 1"));
-					if (channelNoSignConfig != null) {
-						String sysValue = channelNoSignConfig.getSysValue();
-						if (StrUtil.isNotBlank(sysValue)) {
-							try {
-								ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
-								List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
-								BigDecimal discount = baiDuDiscountDto.getDiscount();
-								if (CollUtil.isNotEmpty(baiduPopularizeIds) && discount != null && discount.compareTo(BigDecimal.ZERO) > 0) {
-									if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
-										BigDecimal discountMoney = orderDon.getMoney().multiply(discount);
-										orderDon.setMoney(discountMoney);
+			if (StrUtil.isNotBlank(name)) {
+				//使用了优惠券 不再使用360渠道 折扣
+				if (couponUser == null && goodsType == 1) {
+					if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
+						String key;
+						if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
+							//百度渠道 专门优惠链接
+							key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
+						} else {
+							//抖音
+							key = Constant.CHANNEL_DY_DISCOUNT_KEY;
+						}
+						SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
+								.eq(SysConfig::getSysKey, key).last("limit 1"));
+						if (channelNoSignConfig != null) {
+							String sysValue = channelNoSignConfig.getSysValue();
+							if (StrUtil.isNotBlank(sysValue)) {
+								try {
+									ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
+									List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
+									BigDecimal discount = baiDuDiscountDto.getDiscount();
+									if (CollUtil.isNotEmpty(baiduPopularizeIds) && discount != null && discount.compareTo(BigDecimal.ZERO) > 0) {
+										if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
+											BigDecimal discountMoney = orderDon.getMoney().multiply(discount);
+											orderDon.setMoney(discountMoney);
+										}
 									}
-								}
 
-							} catch (Exception e) {
+								} catch (Exception e) {
+								}
 							}
 						}
 					}
-				}
-			} else {
-				//360
-				if (Constant.CHANNEL_NAME_360.equals(name)) {
-					SysConfig sysConfig = sysConfigService.getBaseMapper().selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.CHANNEL_360_DISCOUNT));
-					if (sysConfig != null) {
-						BigDecimal discountMoney = orderDon.getMoney().multiply(BigDecimal.valueOf(Double.valueOf(sysConfig.getSysValue())));
-						orderDon.setMoney(discountMoney);
+				} else {
+					//360
+					if (Constant.CHANNEL_NAME_360.equals(name)) {
+						SysConfig sysConfig = sysConfigService.getBaseMapper().selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.CHANNEL_360_DISCOUNT));
+						if (sysConfig != null) {
+							BigDecimal discountMoney = orderDon.getMoney().multiply(BigDecimal.valueOf(Double.valueOf(sysConfig.getSysValue())));
+							orderDon.setMoney(discountMoney);
+						}
 					}
 				}
 			}
-
 		}
 		//存在余额
 		deductBalancePayOrderMoney(orderDon, balance, user);

+ 4 - 0
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationClearServiceImpl.java

@@ -8,6 +8,7 @@ import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
 import com.cyksj.model.entity.UserTicketClearedRecord;
 import com.cyksj.model.manage.views.GroupsRelationView;
+import com.cyksj.service.mange.MirrorUserCleatService;
 import com.cyksj.service.relation.GroupRelationClearService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.util.MapUtils;
@@ -38,6 +39,8 @@ public class GroupRelationClearServiceImpl implements GroupRelationClearService
 
 	private final GoodsDonSkuMapper goodsDonSkuMapper;
 
+	private final MirrorUserCleatService mirrorUserCleatService;
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public void clearTicket(GroupsRelation relation, UserTicketClearedRecord.Source source) {
@@ -125,6 +128,7 @@ public class GroupRelationClearServiceImpl implements GroupRelationClearService
 //						log.info("ChatGPT 独立会员账号车票过期,删除原先车队id:{}并生成一个10人月付规格的车队id:{}", groupsRelation.getId(), gt.getId());
 //					}
 //				}
+				mirrorUserCleatService.delMirrorUser(groupsRelation.getGoodsId(), groupsRelation.getId());
 			}
 		}
 	}

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

@@ -21,6 +21,10 @@ import com.cyksj.common.util.StringUtil;
 import com.cyksj.common.util.TicketCodeCommonUtil;
 import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.mapper.*;
+import com.cyksj.mapper.manage.distribute.DistributeGeneralSkuRateMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
+import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper;
+import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper;
 import com.cyksj.mapper.sys.SysEmailMapper;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
@@ -127,6 +131,16 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final GroupsRelationNetflixService groupsRelationNetflixService;
 
+	private final UserDistributeMapper userDistributeMapper;
+
+	private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;
+
+	private final GoodsDonMapper goodsDonMapper;
+
+	private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;
+
+	private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account) {
 		User u = userMapper.selectById(userId);
@@ -296,6 +310,8 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 			}
 			Long qaId = groupsRelationMapper.selectGoodsDonQaByGoodsId(ticket.getGoodsId());
 			ticket.setQa(qaId > 0 ? true : false);
+			//是否存在海报
+			ticket.setPosterInfo(setGoodsPoster(ticket, u));
 		});
 		userLoginRecordService.saveUserLoginDayRecord(userId);
 		return list;
@@ -859,4 +875,47 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		}
 		return renewalView;
 	}
+
+	private DistributePosterGoodsDetailView setGoodsPoster(RenewalView ticket, User user) {
+		DistributePosterGoodsDetailView distributePosterGoodsDetailView = beanSearcher.searchFirst(DistributePosterGoodsDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(DistributePosterGoodsFrontView::getGoodsId, ticket.getGoodsId()).build());
+		if (distributePosterGoodsDetailView == null) {
+			return null;
+		}
+		distributePosterGoodsDetailView.setNickname(user.getNickname());
+		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
+				.eq(UserDistribute::getUserId, user.getId())
+				.eq(UserDistribute::getDeleted, 1)
+				.last("limit 1"));
+		if (userDistribute != null) {
+			UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
+					.eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
+					.eq(UserPlatDistributeRate::getGoodsId, ticket.getGoodsId())
+					.last("limit 1"));
+			if (userPlatDistributeRate != null) {
+				distributePosterGoodsDetailView.setRate(userPlatDistributeRate.getRate());
+			}
+		}
+		GoodsDon goodsDon = goodsDonMapper.selectById(ticket.getGoodsId());
+		if (goodsDon.getIsSkuDistribute()) {
+			if (userDistribute != null) {
+				UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
+						.eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
+						.eq(UserPlatSkuDistributeRate::getSkuId, ticket.getSkuId())
+						.last("limit 1"));
+				if (userPlatSkuDistributeRate != null) {
+					distributePosterGoodsDetailView.setRate(userPlatSkuDistributeRate.getRate());
+				}
+			} else {
+				DistributeGeneralSkuRate distributeGeneralSkuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
+						.eq(DistributeGeneralSkuRate::getSkuId, ticket.getSkuId())
+						.last("limit 1"));
+				if (distributeGeneralSkuRate != null) {
+					distributePosterGoodsDetailView.setRate(distributeGeneralSkuRate.getRate());
+				}
+			}
+		}
+		return distributePosterGoodsDetailView;
+	}
+
 }

+ 3 - 3
netflix-web/src/main/java/com/cyksj/web/controller/external/ExternalController.java

@@ -20,7 +20,7 @@ import com.cyksj.model.entity.OrderDon;
 import com.cyksj.model.request.ExchangeCodeReq;
 import com.cyksj.model.views.ExternalExchangeCodeView;
 import com.cyksj.service.exchange.ExchangeCodeService;
-import com.cyksj.service.mange.CmsOrderDonService;
+import com.cyksj.service.mange.MirrorUserCleatService;
 import com.cyksj.service.order.OrderCommonService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.SearchResult;
@@ -57,7 +57,7 @@ public class ExternalController {
 
 	private final ExchangeCodeService exchangeCodeService;
 
-	private final CmsOrderDonService cmsOrderDonService;
+	private final MirrorUserCleatService mirrorUserCleatService;
 
 	/**
 	 * 知乎 特殊镜像规格 兑换码列表
@@ -117,7 +117,7 @@ public class ExternalController {
 
 				//清除gtpUser
 				if (orderDon.getOrderType() == 1) {
-					cmsOrderDonService.delMirrorUser(goodsDon.getId(), orderDon.getRelationId());
+					mirrorUserCleatService.delMirrorUser(goodsDon.getId(), orderDon.getRelationId());
 				}
 
 				//重新生成兑换码

+ 28 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/CmsOrderController.java

@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.excel.EasyExcel;
@@ -106,6 +107,8 @@ public class CmsOrderController {
 
 	private final OrderDonCustomerServiceRelateMapper orderDonCustomerServiceRelateMapper;
 
+	private final MidjourneyUserConversationMapper midjourneyUserConversationMapper;
+
 
 	@GetMapping("/get")
 	@SaCheckPermission("order:view")
@@ -242,6 +245,31 @@ public class CmsOrderController {
 		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
 	}
 
+	/**
+	 * 镜像规格使用详情
+	 */
+	@GetMapping("/get/order/mj/mirror/detail/{orderId}")
+	public Result<MidjourneyUserDetailView> getMjMirrorOrderDetail(@PathVariable Long orderId) {
+		OrderDon orderDon = orderDonMapper.selectById(orderId);
+		//续费订单
+		Date startTime = null;
+		Date expiryTime = null;
+		if (orderDon.getOrderType() == 2) {
+			GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
+			GroupsRelation relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+					.eq(GroupsRelation::getId, orderDon.getRelationId())
+					.eq(GroupsRelation::getUserId, orderDon.getUserId()).last("limit 1"));
+			if (relation == null) {
+				return GatewayResponse.SUCCESS.newBuilder().toResult();
+			}
+			startTime = relation.getStartTime();
+			startTime = DateUtil.offsetMonth(startTime, sku.getMonths());
+			expiryTime = relation.getExpiryTime();
+		}
+		MidjourneyUserDetailView midjourneyUserDetailView = midjourneyUserConversationMapper.getMjMirrorOrderDetail(orderDon.getRelationId(), startTime, expiryTime);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(midjourneyUserDetailView);
+	}
+
 	/**
 	 * 订单导出
 	 */

+ 20 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributeController.java

@@ -352,6 +352,26 @@ public class DistributeController {
 				.select(GoodsDon::getId, GoodsDon::getType, GoodsDon::getTitle, GoodsDon::getRate, GoodsDon::getSecondRate)));
 	}
 
+	/**
+	 * 平台开启规格分销
+	 */
+	@GetMapping("/get/sku/rate")
+	public Result<List<GoodsDonSkuRateView>> getSkuRate() {
+		List<GoodsDonSkuRateView> goodsDonSkuRateViews = beanSearcher.searchAll(GoodsDonSkuRateView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.orderBy(GoodsDonSkuRateView::getGoodsId).asc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDonSkuRateViews);
+	}
+
+	/**
+	 * 设置普通分销平台规格比例
+	 */
+	@PutMapping("/set/common/sku/rate")
+	public Result<String> setDistributeCommonSkuRate(@RequestBody List<DistributeGeneralSkuRate> skuRates) {
+		distributeService.setDistributeCommonSkuRate(skuRates);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
 	/**
 	 * 获取推广者分销订单详情
 	 */

+ 114 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/distribute/DistributePosterController.java

@@ -0,0 +1,114 @@
+package com.cyksj.web.controller.manage.distribute;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.util.Jsons;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.model.entity.DistributePosterGoods;
+import com.cyksj.model.entity.GoodsDonSku;
+import com.cyksj.model.views.DistributePosterGoodsView;
+import com.cyksj.service.distribute.DistributePosterGoodsService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: DistributePosterController
+ * 创建者: JavaZou
+ * 创建时间:2024/6/24 15:38
+ */
+
+@RestController
+@RequestMapping("/manage/distribute/poster")
+@RequiredArgsConstructor
+public class DistributePosterController {
+	private final DistributePosterGoodsService distributePosterGoodsService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	/**
+	 * 新增海报
+	 */
+	@PostMapping("/post")
+	public Result<String> post(@RequestBody DistributePosterGoods distributePosterGoods) throws Exception {
+		distributePosterGoodsService.saveOrUpdatePo(distributePosterGoods);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除海报
+	 */
+	@DeleteMapping("/del/{id}")
+	public Result<String> del(@PathVariable Long id) {
+		distributePosterGoodsService.removeById(id);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 编辑海报
+	 */
+	@PutMapping("/update")
+	public Result<String> update(@RequestBody DistributePosterGoods distributePosterGoods) throws Exception {
+		distributePosterGoodsService.saveOrUpdatePo(distributePosterGoods);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 海报列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<DistributePosterGoodsView>> get() {
+		SearchResult<DistributePosterGoodsView> search = beanSearcher.search(DistributePosterGoodsView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
+		search.getDataList().forEach(e -> {
+			if (StrUtil.isNotBlank(e.getSkuIds())) {
+				try {
+					String specVal = skuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
+									.in(GoodsDonSku::getId, Jsons.parseSet(e.getSkuIds(), Long.class)))
+							.stream().map(GoodsDonSku::getSpecVal).collect(Collectors.joining(","));
+					e.setSpecVal(specVal);
+				} catch (Exception ex) {
+				}
+			}
+		});
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 海报上下架
+	 */
+	@PutMapping("/update/status/{id}")
+	public Result<String> updateStatus(@PathVariable Long id) {
+		Optional.ofNullable(distributePosterGoodsService.getById(id))
+				.ifPresent(e -> {
+					e.setStatus(!e.getStatus());
+					distributePosterGoodsService.updateById(e);
+				});
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 关联平台
+	 */
+	@GetMapping("/get/relate/goods")
+	public Result<List<DistributePosterGoodsView>> getRelateGoods() {
+		List<DistributePosterGoodsView> distributePosterGoodsViews = beanSearcher.searchAll(DistributePosterGoodsView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.onlySelect(DistributePosterGoodsView::getGoodsId, DistributePosterGoodsView::getTitle)
+				.orderBy(DistributePosterGoodsView::getGoodsId).asc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(distributePosterGoodsViews);
+	}
+}

+ 23 - 4
netflix-web/src/main/java/com/cyksj/web/controller/manage/statistics/StatisticsDataController.java

@@ -14,10 +14,7 @@ import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.BusinessType;
 import com.cyksj.enums.GatewayResponse;
-import com.cyksj.mapper.CustomerServiceRenewOrderRecordMapper;
-import com.cyksj.mapper.GroupsRelationMapper;
-import com.cyksj.mapper.OrderDonMapper;
-import com.cyksj.mapper.UserMapper;
+import com.cyksj.mapper.*;
 import com.cyksj.mapper.corp.CorpUserAuthMapper;
 import com.cyksj.mapper.manage.CustomerServiceEveryMonthDetailMapper;
 import com.cyksj.mapper.manage.RealGoodsOrderHandleMapper;
@@ -87,6 +84,10 @@ public class StatisticsDataController {
 
 	private final OrderDonMapper orderDonMapper;
 
+	private final MidjourneyUserMapper midjourneyUserMapper;
+
+	private final ChatgptUserMapper chatgptUserMapper;
+
 	/**
 	 * 查询头部统计数据
 	 */
@@ -207,6 +208,24 @@ public class StatisticsDataController {
 		incrExpiryTimeRecord.setRemark(renewTimeUpReq.getRemark());
 		relation.setExpiryTime(DateUtil.offsetDay(relation.getExpiryTime(), renewTimeUpReq.getDays()));
 		groupsRelationMapper.updateById(relation);
+
+		//扣除镜像过期时间
+		ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
+				.eq(ChatgptUser::getRelationId, relation.getId())
+				.last("limit 1"));
+		if (chatgptUser != null) {
+			chatgptUser.setExpireTime(DateUtil.offsetDay(chatgptUser.getExpireTime(), renewTimeUpReq.getDays()));
+			chatgptUserMapper.updateById(chatgptUser);
+		} else {
+			MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class)
+					.eq(MidjourneyUser::getRelationId, relation.getId())
+					.last("limit 1"));
+			if (midjourneyUser != null) {
+				midjourneyUser.setExpireTime(DateUtil.offsetDay(midjourneyUser.getExpireTime(), renewTimeUpReq.getDays()));
+				midjourneyUserMapper.updateById(midjourneyUser);
+			}
+		}
+
 		//记录操作日志
 		incrExpiryTimeRecord.setUserId(relation.getUserId());
 		incrExpiryTimeRecord.setRelationId(relation.getId());

+ 105 - 0
netflix-web/src/main/java/com/cyksj/web/controller/user/UserController.java

@@ -8,8 +8,13 @@ import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayApiCode;
 import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.GoodsDonSkuMapper;
 import com.cyksj.mapper.OrderDonMapper;
 import com.cyksj.mapper.manage.coupon.CouponUserMapper;
+import com.cyksj.mapper.manage.distribute.DistributeGeneralSkuRateMapper;
+import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
+import com.cyksj.mapper.manage.distribute.UserPlatDistributeRateMapper;
+import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper;
 import com.cyksj.model.dto.UserWhoami;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
@@ -73,6 +78,16 @@ public class UserController {
 
     private final CorpInteractiveReaderFrontService corpInteractiveReaderFrontService;
 
+    private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;
+
+    private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;
+
+    private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;
+
+    private final GoodsDonSkuMapper skuMapper;
+
+    private final UserDistributeMapper userDistributeMapper;
+
     @GetMapping(value = "/wx/whoami")
     public Result<UserWhoami> whoami() {
         long userId = StpUserUtil.getLoginIdAsLong();
@@ -426,4 +441,94 @@ public class UserController {
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
 
+    /**
+     * 推广平台海报列表
+     */
+    @GetMapping("/get/ds/poster/goods")
+    public Result<List<DistributePosterGoodsFrontView>> getPosterGoods() {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
+                .eq(UserDistribute::getUserId, userId)
+                .eq(UserDistribute::getDeleted, 1)
+                .last("limit 1"));
+        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
+        List<DistributePosterGoodsFrontView> searchAll = beanSearcher.searchAll(DistributePosterGoodsFrontView.class, builder.build());
+        searchAll.forEach(e -> {
+            if (userDistribute != null) {
+                UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
+                        .eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
+                        .eq(UserPlatDistributeRate::getGoodsId, e.getGoodsId())
+                        .last("limit 1"));
+                if (userPlatDistributeRate != null) {
+                    e.setRate(userPlatDistributeRate.getRate());
+                }
+            }
+            if (e.getIsSkuRate()) {
+                GoodsDonSku sku = skuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
+                        .eq(GoodsDonSku::getGoodsId, e.getGoodsId())
+                        .eq(GoodsDonSku::getStatus, 1)
+                        .orderByAsc(GoodsDonSku::getPrice)
+                        .last("limit 1"));
+                //先获取价格最低的规格对应的 比例
+                //渠道
+                if (userDistribute != null) {
+                    UserPlatSkuDistributeRate minPriceSkuRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
+                            .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
+                            .eq(UserPlatSkuDistributeRate::getGoodsId, e.getGoodsId())
+                            .eq(UserPlatSkuDistributeRate::getSkuId, sku.getId())
+                            .last("limit 1"));
+                    if (minPriceSkuRate != null && minPriceSkuRate.getRate() != 0) {
+                        e.setRate(minPriceSkuRate.getRate());
+                    } else {
+                        UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
+                                .eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
+                                .eq(UserPlatSkuDistributeRate::getGoodsId, e.getGoodsId())
+                                .ne(UserPlatSkuDistributeRate::getRate, 0)
+                                //上架
+                                .apply("exists (select 1 from goods_don_sku sku where sku.id = sku_id and sku.status is true limit 1)")
+                                .orderByAsc(UserPlatSkuDistributeRate::getRate)
+                                .last("limit 1"));
+                        if (userPlatSkuDistributeRate != null) {
+                            e.setRate(userPlatSkuDistributeRate.getRate());
+                            sku = skuMapper.selectById(userPlatSkuDistributeRate.getSkuId());
+                            e.setPrice(sku.getPrice());
+                        }
+                    }
+                } else {
+                    //普通
+                    DistributeGeneralSkuRate minPriceRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
+                            .eq(DistributeGeneralSkuRate::getGoodsId, e.getGoodsId())
+                            .eq(DistributeGeneralSkuRate::getSkuId, sku.getId())
+                            .last("limit 1"));
+                    if (minPriceRate != null && minPriceRate.getRate() > 0) {
+                        e.setRate(minPriceRate.getRate());
+                    } else {
+                        DistributeGeneralSkuRate distributeGeneralSkuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
+                                .eq(DistributeGeneralSkuRate::getGoodsId, e.getGoodsId())
+                                .apply("exists (select 1 from goods_don_sku sku where sku.id = sku_id and sku.status is true limit 1)")
+                                .ne(DistributeGeneralSkuRate::getRate, 0)
+                                .orderByAsc(DistributeGeneralSkuRate::getRate)
+                                .last("limit 1"));
+                        if (distributeGeneralSkuRate != null) {
+                            e.setRate(distributeGeneralSkuRate.getRate());
+                            sku = skuMapper.selectById(distributeGeneralSkuRate.getSkuId());
+                            e.setPrice(sku.getPrice());
+                        }
+                    }
+                }
+            }
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult(searchAll);
+    }
+
+    /**
+     * 海报详情
+     */
+    @GetMapping("/get/poster/{goodsId}")
+    public Result<DistributePosterGoodsFrontView> getPosterDetail(@PathVariable Long goodsId) {
+        DistributePosterGoodsFrontView distributePosterGoodsView = beanSearcher.searchFirst(DistributePosterGoodsFrontView.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(DistributePosterGoodsFrontView::getGoodsId, goodsId)
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(distributePosterGoodsView);
+    }
 }