Browse Source

更换车票;临时账号

zoujiajian 1 year ago
parent
commit
5fbc2e62dc
18 changed files with 650 additions and 3 deletions
  1. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/AccountMapper.java
  2. 2 0
      netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/NetflixTempAccountUserMapper.java
  4. 1 1
      netflix-dao/src/main/java/com/cyksj/model/entity/Account.java
  5. 20 0
      netflix-dao/src/main/java/com/cyksj/model/entity/NetflixTempAccountUser.java
  6. 20 1
      netflix-dao/src/main/java/com/cyksj/model/excel/ExcelPrepareAccountData.java
  7. 3 0
      netflix-dao/src/main/java/com/cyksj/model/manage/views/AccountView.java
  8. 18 0
      netflix-dao/src/main/java/com/cyksj/model/request/ChangeTicketReq.java
  9. 3 0
      netflix-dao/src/main/java/com/cyksj/model/views/RenewalView.java
  10. 12 0
      netflix-dao/src/main/resources/mapper/AccountMapper.xml
  11. 12 0
      netflix-dao/src/main/resources/mapper/GroupsMapper.xml
  12. 5 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java
  13. 16 0
      netflix-service/src/main/java/com/cyksj/service/relation/GroupsRelationChangeService.java
  14. 76 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java
  15. 139 0
      netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupsRelationChangeServiceImpl.java
  16. 35 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  17. 273 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/account/AccountTempController.java
  18. 0 1
      netflix-web/src/main/java/com/cyksj/web/controller/manage/account/CmsAccountController.java

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/mapper/AccountMapper.java

@@ -26,4 +26,6 @@ public interface AccountMapper extends BaseMapper<Account> {
 	List<ExcelAccountData> getExpiredAccountViewNoPage(@Param("isCorpWx") Boolean isCorpWx, @Param("customerService") String customerService, @Param("goodsId") Long goodsId, @Param("skuId") Long skuId, @Param("account") String account, @Param("renewStatus") Boolean renewStatus, @Param("handleStatus") Boolean handleStatus, @Param("cnAccount") String cnAccount, @Param("usAccount") String usAccount, @Param("userId") Integer userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("now") String now);
 
 	List<AccountView> getExpiredAllAccount();
+
+	Account selectNetflixTempAccount();
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GroupsMapper.java

@@ -43,4 +43,6 @@ public interface GroupsMapper extends BaseMapper<GroupsTrips> {
 	GroupsTrips selectTicketGroups(@Param("skuId") Long skuId, @Param("status") GroupsTrips.Status status, @Param("maxNum") Integer maxNum, @Param("ip") String ip);
 
 	GroupsTrips selectCollegeStudentUserGptTicket(Long skuId);
+
+	Long selectRandomGroupsTripsBySkuId(@Param("groupId") Long groupId, @Param("skuId") Long skuId, @Param("expiryTime") Date expiryTime);
 }

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/NetflixTempAccountUserMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.NetflixTempAccountUser;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: NetflixTempAccountUserMapper
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 17:16
+ */
+public interface NetflixTempAccountUserMapper extends BaseMapper<NetflixTempAccountUser> {
+}

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

@@ -99,7 +99,7 @@ public class Account extends BaseEntity {
     private String preSkuIds;
 
     /**
-     * 类型 1通用 2备用
+     * 类型 1通用 2备用 3临时账号
      */
     private Integer type;
 

+ 20 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/NetflixTempAccountUser.java

@@ -0,0 +1,20 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: NetflixTempAccountUser
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 17:16
+ */
+@Getter
+@Setter
+public class NetflixTempAccountUser extends BaseEntity{
+	private Long userId;
+
+	private Long relationId;
+
+	private Long accountId;
+}

+ 20 - 1
netflix-dao/src/main/java/com/cyksj/model/excel/ExcelPrepareAccountData.java

@@ -24,4 +24,23 @@ public class ExcelPrepareAccountData {
      */
     @ExcelProperty("银行卡号")
     private String bankCard;
-}
+
+
+    /**
+     * 到期日期
+     */
+    @ExcelProperty("到期日期")
+    private String expiryTime;
+
+    /**
+     * 辅助邮箱
+     */
+    @ExcelProperty("辅助邮箱")
+    private String secondEmail;
+
+    /**
+     * 辅助邮箱
+     */
+    @ExcelProperty("关联邮箱")
+    private String relateEmail;
+}

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

@@ -170,4 +170,7 @@ public class AccountView {
 
     @DbField("a.relate_email")
     private String relateEmail;
+
+    @DbField("a.type")
+    private Integer type;
 }

+ 18 - 0
netflix-dao/src/main/java/com/cyksj/model/request/ChangeTicketReq.java

@@ -0,0 +1,18 @@
+package com.cyksj.model.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: ChangeTicketReq
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 17:10
+ */
+@Getter
+@Setter
+public class ChangeTicketReq {
+	private List<Long> relationIds;
+}

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

@@ -92,6 +92,9 @@ public class RenewalView {
     @DbField("g.special_type")
     private GoodsDon.SpecialType specialType;
 
+    @DbField("gt.status")
+    private String groupsStatus;
+
     @DbField("gr.user_id")
     @JsonIgnore
     private Long userId;

+ 12 - 0
netflix-dao/src/main/resources/mapper/AccountMapper.xml

@@ -187,4 +187,16 @@
                  left join goods_don g on g.id = a.goods_id
         where s.num >= gt.num
     </select>
+
+    <select id="selectNetflixTempAccount" resultType="com.cyksj.model.entity.Account">
+        select a.*
+        from account a
+        where goods_id = 1
+          and type = 3
+          and (select count(1)
+               from netflix_temp_account_user ntu
+                        inner join groups_relation gr on gr.id = ntu.relation_id and ntu.user_id = gr.user_id
+               where ntu.account_id = a.id) &lt; 20
+            limit 1
+    </select>
 </mapper>

+ 12 - 0
netflix-dao/src/main/resources/mapper/GroupsMapper.xml

@@ -107,4 +107,16 @@
           and gt.available_num > 0
         order by rand() limit 1
     </select>
+
+    <select id="selectRandomGroupsTripsBySkuId" resultType="java.lang.Long">
+        select gt.id
+        from `groups_trips` gt
+                 inner join account a on a.id = gt.account_id
+        where gt.id != #{groupId}
+          and gt.sku_id = #{skuId}
+          and gt.status = 'validity'
+          and a.expiry_time >= #{expiryTime}
+          and gt.available_num > 0
+        order by a.expiry_time asc limit 1
+    </select>
 </mapper>

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

@@ -3,6 +3,7 @@ package com.cyksj.service.relation;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
+import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
 import com.cyksj.model.request.TicketLoginReq;
 import com.cyksj.model.views.RenewalView;
@@ -68,4 +69,8 @@ public interface GroupRelationFrontService {
 	String getNfHouseholdDevice(long userId, Long relationId) throws Exception;
 
 	String getVerifyCode(String account) throws Exception;
+
+	void changeTicket(long userId, Long relationId);
+
+	AccountView getTempAccount(long userId, Long relationId);
 }

+ 16 - 0
netflix-service/src/main/java/com/cyksj/service/relation/GroupsRelationChangeService.java

@@ -0,0 +1,16 @@
+package com.cyksj.service.relation;
+
+import com.cyksj.model.entity.GroupsRelation;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GroupsRelationChangeService
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 14:14
+ */
+public interface GroupsRelationChangeService {
+
+	GroupsRelation changeTicket(Long userId, Long oriRelationId, Long itemGroupsId, Long skuId);
+
+	GroupsRelation getEmptyGroupsRelation(Long userId, Long oriRelationId, Long skuId);
+}

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

@@ -25,6 +25,7 @@ import com.cyksj.mapper.manage.distribute.UserPlatSkuDistributeRateMapper;
 import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
 import com.cyksj.mapper.sys.SysEmailMapper;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.request.SpecialGoodsTicketReq;
 import com.cyksj.model.request.TicketLoginReq;
 import com.cyksj.model.views.*;
@@ -40,6 +41,7 @@ import com.cyksj.service.mail.YhMailService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
 import com.cyksj.service.midjourney.MidjourneyAccountService;
 import com.cyksj.service.relation.GroupRelationFrontService;
+import com.cyksj.service.relation.GroupsRelationChangeService;
 import com.cyksj.service.relation.GroupsRelationNetflixService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.service.user.UserLoginRecordService;
@@ -157,6 +159,10 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 
 	private final UserBenefitsMapper userBenefitsMapper;
 
+	private final GroupsRelationChangeService changeTickerRelation;
+
+	private final NetflixTempAccountUserMapper netflixTempAccountUserMapper;
+
 	@Override
 	public SearchResult<RenewalView> getMyTicket(long userId, Boolean isLoginPopularize, String customId, String account, String orderNo) {
 		User u = userMapper.selectById(userId);
@@ -998,6 +1004,76 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 		return code;
 	}
 
+	@Override
+	public void changeTicket(long userId, Long relationId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
+				.field(RenewalView::getUserId, userIdList).op(Operator.InList)
+				.field(RenewalView::getRelationId, relationId)
+				.field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+				.build());
+		if (renewalView == null) {
+			throw BusinessRuntimeException.getInstance("车票不存在");
+		}
+		if (renewalView.getGoodsId() != 1) {
+			throw BusinessRuntimeException.getInstance("只针对奈飞车票");
+		}
+		Long groupId = renewalView.getGroupId();
+		Long skuId = renewalView.getSkuId();
+		Date expiryTime = renewalView.getExpiryTime();
+		//随机选择同规格得车票
+		Long item_groupsId = groupsMapper.selectRandomGroupsTripsBySkuId(groupId, skuId, expiryTime);
+		GroupsRelation newRelation = null;
+		if (item_groupsId != null) {
+			//存在就随机分配一个,没有就不做处理
+			newRelation = changeTickerRelation.changeTicket(renewalView.getUserId(), relationId, item_groupsId, renewalView.getSkuId());
+		}
+		//若无移至空车队
+		if (newRelation == null) {
+			newRelation = changeTickerRelation.getEmptyGroupsRelation(renewalView.getUserId(), renewalView.getRelationId(), renewalView.getSkuId());
+		}
+		if (newRelation == null) {
+			throw BusinessRuntimeException.getInstance("更换异常,请重新提交");
+		}
+	}
+
+	@Override
+	public AccountView getTempAccount(long userId, Long relationId) {
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
+				.field(RenewalView::getRelationId, relationId)
+				.field(RenewalView::getUserId, userIdList).op(Operator.InList)
+				.field(RenewalView::getGroupsStatus, GroupsTrips.Status.down.name())
+				.field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+				.build());
+		if (renewalView == null) {
+			throw BusinessRuntimeException.getInstance("车票不存在");
+		}
+		NetflixTempAccountUser netflixTempAccountUser = netflixTempAccountUserMapper.selectOne(Wrappers.lambdaQuery(NetflixTempAccountUser.class)
+				.eq(NetflixTempAccountUser::getRelationId, relationId)
+				.in(NetflixTempAccountUser::getUserId, userIdList)
+				.last("limit 1"));
+		AccountView accountView = new AccountView();
+		Account account;
+		if (netflixTempAccountUser == null) {
+			account = accountMapper.selectNetflixTempAccount();
+			if (account != null) {
+				netflixTempAccountUser = new NetflixTempAccountUser();
+				netflixTempAccountUser.setAccountId(account.getId());
+				netflixTempAccountUser.setRelationId(relationId);
+				netflixTempAccountUser.setUserId(renewalView.getUserId());
+				netflixTempAccountUserMapper.insert(netflixTempAccountUser);
+			}
+		} else {
+			account = accountMapper.selectById(netflixTempAccountUser.getAccountId());
+		}
+		if (account != null) {
+			accountView.setAccount(account.getAccount());
+			accountView.setPassword(account.getPassword());
+		}
+		return accountView;
+	}
+
 	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());

+ 139 - 0
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupsRelationChangeServiceImpl.java

@@ -0,0 +1,139 @@
+package com.cyksj.service.relation.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.dto.RedisKey;
+import com.cyksj.mapper.GoodsDonSkuMapper;
+import com.cyksj.mapper.GroupsMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.mapper.OrderDonMapper;
+import com.cyksj.model.entity.*;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.groups.GroupsFuncService;
+import com.cyksj.service.relation.GroupRelationClearService;
+import com.cyksj.service.relation.GroupsRelationChangeService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 项目名: yhlxj2
+ * 文件名: GroupsRelationChangeServiceImpl
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 14:15
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class GroupsRelationChangeServiceImpl implements GroupsRelationChangeService {
+	private final GroupsRelationMapper relationMapper;
+
+	private final RedisService redisService;
+
+	private final GroupsMapper groupsMapper;
+
+	private final GroupsFuncService groupsFuncService;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	private final OrderDonMapper orderDonMapper;
+
+	private final GroupRelationClearService relationClearService;
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public GroupsRelation changeTicket(Long userId, Long oriRelationId, Long itemGroupsId, Long skuId) {
+		GroupsRelation relation = getRelationThisTrips(userId, itemGroupsId, 1);
+		if (relation == null) {
+			return relation;
+		}
+		syncGroupsRelation(oriRelationId, relation);
+		return relation;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public GroupsRelation getEmptyGroupsRelation(Long userId, Long oriRelationId, Long skuId) {
+		return getEmptyGroupsRelationIfRetry(userId, oriRelationId, skuId, 1);
+	}
+
+	public GroupsRelation getEmptyGroupsRelationIfRetry(Long userId, Long oriRelationId, Long skuId, Integer retryNum) {
+		GroupsTrips groupsTrips = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
+				.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
+				.eq(GroupsTrips::getSkuId, skuId)
+				.last("limit 1"));
+		GroupsRelation relation = null;
+		if (groupsTrips != null) {
+			relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+					.eq(GroupsRelation::getGroupsId, groupsTrips.getId())
+					.eq(GroupsRelation::getStatus, GroupsRelation.Status.none)
+					.last("limit 1"));
+		}
+		if (relation == null) {
+			//新增空车队
+			GoodsDonSku sku = skuMapper.selectById(skuId);
+			relation = groupsFuncService.createNewGroupsTrips(sku);
+		}
+		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId(), userId, 60 * 2L)) {
+			retryNum++;
+			if (retryNum >= 7) {
+				return null;
+			}
+			return getEmptyGroupsRelationIfRetry(userId, oriRelationId, skuId, retryNum);
+		}
+		syncGroupsRelation(oriRelationId, relation);
+		return relation;
+	}
+
+
+	/**
+	 * 寻找该车队空余车位
+	 */
+	public GroupsRelation getRelationThisTrips(Long userId, Long groupsId, Integer retryNum) {
+		//寻找快满编车队进行占座
+		GroupsRelation relation = relationMapper.selectRandomOneRelationByGroupsId(groupsId);
+		if (relation == null) {
+			log.error("该车队人员已满,请选择另一车队");
+			return null;
+		}
+		Long relationId = relation.getId();
+		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 2L)) {
+			if (retryNum == 7){
+				log.error("该车队人员已满,请选择另一车队");
+				return null;
+			}
+			retryNum++;
+			return getRelationThisTrips(userId, groupsId, retryNum);
+		}
+		int count = groupsMapper.decrAvailableNum(relation.getGroupsId());
+		if (count == 0) {
+			log.error("车位异常 groupId:{}", groupsId);
+			groupsMapper.updateAvailableNum(groupsId);
+			log.error("车位异常");
+			return null;
+		}
+		return relation;
+	}
+
+	public void syncGroupsRelation(Long oriRelationId, GroupsRelation newRelation) {
+		GroupsRelation oriRelation = relationMapper.selectById(oriRelationId);
+		newRelation.setStartTime(oriRelation.getStartTime());
+		newRelation.setExpiryTime(oriRelation.getExpiryTime());
+		newRelation.setStatus(oriRelation.getStatus());
+		newRelation.setUserId(oriRelation.getUserId());
+		newRelation.setYhsId(oriRelation.getYhsId());
+		relationMapper.updateById(newRelation);
+		relationClearService.clearTicket(oriRelation, UserTicketClearedRecord.Source.change_ticket);
+		OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+				.eq(OrderDon::getRelationId, oriRelationId)
+				.eq(OrderDon::getUserId, newRelation.getUserId())
+				.notIn(OrderDon::getStatus, Constant.noOrderStatus)
+				.orderByDesc(OrderDon::getId)
+				.last("limit 1"));
+		if (orderDon != null) {
+			orderDon.setRelationId(newRelation.getId());
+			orderDonMapper.updateById(orderDon);
+		}
+	}
+}

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

@@ -19,6 +19,7 @@ import com.cyksj.common.snowflake.Sequence;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.GoogleGenerator;
 import com.cyksj.common.util.Jsons;
+import com.cyksj.common.util.StringUtil;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.*;
@@ -27,6 +28,7 @@ import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
 import com.cyksj.model.dto.DoubleVerifyDto;
 import com.cyksj.model.dto.QuestionnaireView;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.manage.views.AccountView;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.*;
 import com.cyksj.model.response.GptStandbyResp;
@@ -1068,4 +1070,37 @@ public class GroupRelationController {
         data.setRenewCount(renewCount);
         return GatewayResponse.SUCCESS.newBuilder().toResult(data);
     }
+
+    /**
+     * 申请更换车票
+     */
+    @PostMapping("/change/ticket")
+    public Result<String> changeTicket(@RequestBody ChangeTicketReq changeTicketReq) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<Long> relationIds = changeTicketReq.getRelationIds();
+        if (CollUtil.isEmpty(relationIds)) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult();
+        }
+        relationIds.forEach(relationId -> {
+            try {
+                groupRelationFrontService.changeTicket(userId, relationId);
+            } catch (Exception e) {
+                log.error("更换车票失败:{}", StringUtil.getErrorText(e));
+                if (relationIds.size() == 1) {
+                    throw BusinessRuntimeException.getInstance(e.getMessage());
+                }
+            }
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * 查看临时账号
+     */
+    @GetMapping("/get/temp/account/{relationId}")
+    public Result<AccountView> getTempAccount(@PathVariable Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        AccountView accountView = groupRelationFrontService.getTempAccount(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(accountView);
+    }
 }

+ 273 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/account/AccountTempController.java

@@ -0,0 +1,273 @@
+package com.cyksj.web.controller.manage.account;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.*;
+import com.cyksj.model.entity.*;
+import com.cyksj.model.excel.ExcelPrepareAccountData;
+import com.cyksj.model.manage.views.AccountView;
+import com.cyksj.model.request.OrderRefundReq;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.mange.AccountCommonService;
+import com.cyksj.service.order.OrderCommonService;
+import com.cyksj.service.order.OrderRefundService;
+import com.cyksj.service.user.UserBenefitsService;
+import com.cyksj.web.util.EasyExcelUtils;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * 项目名: yhlxj
+ * 文件名: AccountTempController
+ * 创建者: JavaZou
+ * 创建时间:2024/10/28 17:17
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RequestMapping("/manage/account/temp")
+@RestController
+public class AccountTempController {
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	private final AccountMapper accountMapper;
+
+	private final AccountCommonService accountCommonService;
+
+	private final NetflixTempAccountUserMapper netflixTempAccountUserMapper;
+
+	private final GroupsMapper groupsMapper;
+
+	private final GroupsRelationMapper relationMapper;
+
+	private final OrderDonMapper orderDonMapper;
+
+	private final GoodsDonSkuMapper skuMapper;
+
+	private final OrderRefundService orderRefundService;
+
+	private final RedisService redisService;
+
+	private final OrderCommonService orderCommonService;
+
+	private final GoodsDonMapper goodsDonMapper;
+
+	private final UserBenefitsService userBenefitsService;
+
+	/**
+	 * 新增临时账号
+	 */
+	@PostMapping("/post")
+	public Result<String> post(@RequestBody Account account) {
+		accountMapper.insert(account);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 编辑临时账号
+	 */
+	@PutMapping("/update")
+	public Result<String> update(@RequestBody Account account) {
+		accountMapper.updateById(account);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除
+	 */
+	@DeleteMapping("/delete/{id}")
+	public Result<String> deletedById(@PathVariable Long id) {
+		Account account = accountMapper.selectById(id);
+		if (account != null && account.getType() == 3) {
+			accountMapper.deleteById(id);
+			netflixTempAccountUserMapper.delete(Wrappers.lambdaQuery(NetflixTempAccountUser.class)
+					.eq(NetflixTempAccountUser::getAccountId, account.getId()));
+		}
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 临时账号模板
+	 */
+	@GetMapping("/export/temp/template")
+	public void getTempTemplate(HttpServletResponse response) {
+		EasyExcelUtils.createTemplateExcel(response, ExcelPrepareAccountData.class, "临时账号导入模板", "临时账号导入模板", ExcelTypeEnum.XLSX, null);
+	}
+
+	/**
+	 * 批量导入临时账号
+	 */
+	@PostMapping("/import")
+	public Result<String> batchImport(@RequestParam(defaultValue = "1") Long goodsId, MultipartFile file) throws IOException {
+		if (goodsId == null) {
+			throw BusinessRuntimeException.getInstance("请选择对应平台");
+		}
+		EasyExcel.read(file.getInputStream(), ExcelPrepareAccountData.class, new AnalysisEventListener<ExcelPrepareAccountData>() {
+			@Override
+			public void invoke(ExcelPrepareAccountData data, AnalysisContext analysisContext) {
+				String account = data.getAccount();
+				String password = data.getPassword();
+				if (StrUtil.isEmpty(account) || StrUtil.isEmpty(password)) {
+					return;
+				}
+				Account insert = new Account();
+				insert.setAccount(account.trim());
+				insert.setPassword(password.trim());
+				insert.setGoodsId(goodsId);
+				//临时账号
+				insert.setType(3);
+				insert.setStartTime(DateTime.now());
+				if (data.getExpiryTime() != null) {
+					insert.setExpiryTime(DateUtil.parse(data.getExpiryTime()));
+				} else {
+					insert.setExpiryTime(DateUtil.offsetMonth(DateTime.now(), 1));
+				}
+				insert.setBankCard(data.getBankCard());
+				//辅助邮箱
+				insert.setEmail(data.getSecondEmail());
+				//关联邮箱
+				insert.setRelateEmail(data.getRelateEmail());
+				//账号是否已经添加过
+				if (!insert.getAccount().contains("客服")) {
+					if (accountCommonService.checkIsDupAccount(insert.getGoodsId(), insert.getAccount())) {
+						return;
+					}
+				}
+				accountMapper.insert(insert);
+			}
+
+			@Override
+			public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+
+			}
+		}).sheet().doRead();
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 临时账号列表
+	 */
+	@GetMapping("/get")
+	public Result<SearchResult<AccountView>> get() {
+		SearchResult<AccountView> search = beanSearcher.search(AccountView.class, MapUtils.flatBuilder(request.getParameterMap()).field(AccountView::getType, 3).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * excel奈飞退款
+	 */
+	@PutMapping("/refund")
+	public void excelRefund(MultipartFile file) throws IOException {
+		if (!file.getOriginalFilename().contains(".xls")) {
+			throw BusinessRuntimeException.getInstance("请导入excel文件");
+		}
+		List<Object> accountList = EasyExcel.read(file.getInputStream()).sheet().headRowNumber(0).doReadSync();
+		accountList.forEach(account->{
+			Account dbAccount = accountMapper.selectOne(Wrappers.lambdaQuery(Account.class)
+					.eq(Account::getGoodsId, 1)
+					.eq(Account::getAccount, account)
+					.last("limit 1"));
+			if (dbAccount != null) {
+				GroupsTrips groupsTrips = groupsMapper.selectById(dbAccount.getId());
+				if (groupsTrips.getSkuId() != 4) {
+					return;
+				}
+				if (groupsTrips != null) {
+					//15天以内的自动退款
+					List<GroupsRelation> groupsRelations = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class)
+							.eq(GroupsRelation::getGroupsId, groupsTrips.getId())
+							.gt(GroupsRelation::getExpiryTime, DateTime.now())
+							.le(GroupsRelation::getExpiryTime, DateUtil.offsetDay(DateTime.now(), 15)));
+					GoodsDon goodsDon = goodsDonMapper.selectById(1);
+					groupsRelations.forEach(relation->{
+						OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
+								.eq(OrderDon::getRelationId, relation.getId())
+								.eq(OrderDon::getUserId, relation.getUserId())
+								.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
+								.orderByDesc(OrderDon::getId)
+								.last("limit 1"));
+						BigDecimal money = orderDon.getMoney();
+						GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
+						Integer months = sku.getMonths();
+						BigDecimal single = sku.getPrice().divide(BigDecimal.valueOf(months * 30), 2, RoundingMode.DOWN);
+						long betDay = DateUtil.between(DateTime.now(), relation.getExpiryTime(), DateUnit.DAY);
+						BigDecimal refundMoney = single.multiply(BigDecimal.valueOf(betDay));
+						//退款
+						OrderRefundReq orderRefundReq = new OrderRefundReq();
+						orderRefundReq.setOrderId(orderDon.getId());
+						orderRefundReq.setRefundMoney(refundMoney);
+						orderDon.setRefundDesc("奈飞15天内过期自动退款");
+						String outNo = null;
+						try {
+							orderRefundReq.setRefundType("ALI_PAY");
+							outNo = orderRefundService.centerRefund(orderRefundReq, orderDon);
+							orderDon.setStatus(OrderDon.Status.refund);
+							orderDon.setRefundMoney(orderRefundReq.getRefundMoney());
+							orderDonMapper.updateById(orderDon);
+							clearUserLockingRelation(relationMapper.selectById(orderDon.getRelationId()), orderDon);
+							//记录退款
+							orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), null, goodsDon, sku, outNo, orderDon.getType().getType(), null);
+						} catch (Exception e) {
+							orderRefundReq.setRefundType("balance");
+							userBenefitsService.addUserBalance(relation.getUserId(), refundMoney, UserBalanceSourceRecord.Source.clear_valid, relation.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.clear_valid.getDesc(), true);
+							//修改订单状态 为退款
+							orderDon.setStatus(OrderDon.Status.refund);
+							orderDon.setRefundBalance(refundMoney);
+							orderDon.setRefundMoney(BigDecimal.ZERO);
+							orderDonMapper.updateById(orderDon);
+							orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), null, goodsDon, sku, outNo, "balance", null);
+						}
+					});
+
+				}
+			}
+		});
+
+	}
+
+	private void clearUserLockingRelation(GroupsRelation groupsRelation, OrderDon orderDon) {
+		if (groupsRelation == null) {
+			return;
+		}
+		if (GroupsRelation.Status.locking == groupsRelation.getStatus()) {
+			log.info("清理用户userId:{}未支付订单", orderDon.getUserId());
+			groupsRelation.setUserId(0L);
+			Long groupsId = groupsRelation.getGroupsId();
+			GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
+			if (groupsRelation.getNum() > groupsTrips.getNum()) {
+				groupsRelation.setStatus(GroupsRelation.Status.outside);
+
+				redisService.del(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, groupsRelation.getNum()));
+			} else {
+				groupsRelation.setStatus(GroupsRelation.Status.none);
+			}
+			groupsRelation.setYhsId(0l);
+			relationMapper.updateById(groupsRelation);
+			orderCommonService.delRelation(groupsRelation);
+		}
+	}
+}

+ 0 - 1
netflix-web/src/main/java/com/cyksj/web/controller/manage/account/CmsAccountController.java

@@ -1140,7 +1140,6 @@ public class CmsAccountController {
 						return;
 					}
 				}
-				insert.setType(2);
 				accountService.save(insert);
 			}