package com.cyksj.service.mange.group; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cyksj.common.EnvCommonService; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.task.GlobalThreadPoolTaskExecutor; import com.cyksj.mapper.*; import com.cyksj.mapper.manage.GroupsTripsAccountReplaceRecordMapper; import com.cyksj.mapper.manage.cms.CmsUserMapper; import com.cyksj.model.entity.*; import com.cyksj.model.request.ReplaceTripsAccountReq; import com.cyksj.model.views.GroupsAccountView; import com.cyksj.service.mange.CmsGroupService; import com.cyksj.service.sms.SmsService; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.util.MapUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * @author chan * @date 2022/9/27 6:27 PM */ @Slf4j @Service @RequiredArgsConstructor public class CmsGroupServiceImpl extends ServiceImpl implements CmsGroupService { private final GoodsDonSkuMapper skuMapper; private final GroupsRelationMapper relationMapper; private final OrderDonMapper orderDonMapper; private final AccountMapper accountMapper; private final BeanSearcher beanSearcher; private final GroupsTripsAccountReplaceRecordMapper replaceRecordMapper; private final CmsUserMapper cmsUserMapper; private final GoodsDonMapper goodsDonMapper; private final SmsService smsService; private final EnvCommonService envCommonService; private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance(); @Override public GroupsTrips issuance(GroupsTrips groups, String verifyCodes) { GoodsDonSku sku = skuMapper.selectById(groups.getSkuId()); if (sku == null) { throw new BusinessRuntimeException("该商品规格不存在!"); } List verifyCodeList = null; if (StrUtil.isNotBlank(verifyCodes)) { verifyCodes = verifyCodes.replaceAll("\n", ""); String[] verifyCodeArray = verifyCodes.split("\\*"); verifyCodeList = Arrays.stream(verifyCodeArray).filter(str -> StrUtil.isNotBlank(str)).map(str -> str.trim()).collect(Collectors.toList()); } groups.setNum(sku.getNum()); groups.setAvailableNum(sku.getNum()); if (groups.getAccountId() == null || accountMapper.selectById(groups.getAccountId()) == null) { throw new BusinessRuntimeException("该账号不存在"); } groups.setStatus(GroupsTrips.Status.validity); this.save(groups); for (Integer i = 1; i <= groups.getNum(); i++) { GroupsRelation relation = new GroupsRelation(); relation.setGroupsId(groups.getId()); relation.setStatus(GroupsRelation.Status.none); relation.setNum(i); if (verifyCodeList != null && verifyCodeList.size() > 0 && verifyCodeList.size() >= i) { relation.setVerifyCode(verifyCodeList.get(i - 1)); } relationMapper.insert(relation); } return groups; } @Override public void close(Long groupId) { GroupsTrips groupsTrips = this.getById(groupId); if(groupsTrips == null){ throw new BusinessRuntimeException("非法参数.车队不存在"); } Integer count = relationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getGroupsId, groupId) .in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.locking, GroupsRelation.Status.validity))); if (count > 0) { throw new BusinessRuntimeException("该车队已有用户购买或锁定.无法删除"); }else { relationMapper.delete(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId,groupId)); this.removeById(groupId); } } @Override @Transactional(rollbackFor = Throwable.class) public void setAccount(GroupsTrips groupsTrips) { int count = count(Wrappers.lambdaQuery(GroupsTrips.class).eq(GroupsTrips::getAccountId, groupsTrips.getAccountId())); if (count > 0) { throw new BusinessRuntimeException("该账号已发车.请选择未发车账户"); } List groupsRelations = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsTrips.getId()).eq(GroupsRelation::getStatus, GroupsRelation.Status.validity)); GroupsTrips trips = beanSearcher.searchFirst(GroupsTrips.class, MapUtils.builder().field(GroupsTrips::getId, groupsTrips.getId()).onlySelect(GroupsTrips::getTitle).build()); String title = "车票"; if (trips != null && StrUtil.isNotBlank(trips.getTitle())) { title = trips.getTitle(); } String msg = String.format(Constant.CHANGE_GROUPS_TRIPS_ACCOUNT, title); //配置midJourney安全码 String verifyCodes = groupsTrips.getVerifyCodes(); List verifyCodeList = null; if (StrUtil.isNotBlank(verifyCodes)) { verifyCodes = verifyCodes.replaceAll("\n", ""); String[] verifyCodesArray = verifyCodes.split("\\*"); verifyCodeList = Arrays.stream(verifyCodesArray).filter(str -> StrUtil.isNotBlank(str)).map(str -> str.trim()).collect(Collectors.toList()); } Boolean isPrdEnv = envCommonService.isPrdEnv(); for (int i = 0; i < groupsRelations.size(); i++) { GroupsRelation relation = groupsRelations.get(i); if (relation.getExpiryTime() == null) { List orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, relation.getUserId()).eq(OrderDon::getRelationId, relation.getId()).eq(OrderDon::getStatus, OrderDon.Status.hasPayment)); orderDonList.forEach((orderDon) -> { //如果续费增加时间,如果首次则设置当前时间为初始时间 Date expiryTime = Optional.ofNullable(relation.getExpiryTime()).orElse(new Date()); log.info("设置账号,该用户 {} 初始时间:{} ", orderDon.getUserId(), DateUtil.format(expiryTime, "yyyy-MM-dd HH:mm:ss")); GoodsDonSku donSku = skuMapper.selectById(orderDon.getSkuId()); Date newDate = DateUtil.offset(expiryTime, DateField.MONTH, donSku.getMonths() * orderDon.getNum()); relation.setExpiryTime(newDate); log.info("设置账号,该用户 {} 过期时间:{} ", orderDon.getUserId(), DateUtil.format(newDate, "yyyy-MM-dd HH:mm:ss")); relation.setStartTime(relation.getStartTime() == null ? new Date() : null); relationMapper.updateById(relation); orderDon.setStatus(OrderDon.Status.complete); orderDonMapper.updateById(orderDon); }); } if (relation.getUserId() != 0 && isPrdEnv) { //发送短信 smsService.sendSmsToRelationUser(relation.getUserId(), msg); } if (verifyCodeList != null && verifyCodeList.size() > 0 && i < verifyCodeList.size()) { relation.setVerifyCode(verifyCodeList.get(i)); relationMapper.updateById(relation); } } if (groupsRelations.isEmpty() && verifyCodeList != null && verifyCodeList.size() > 0) { groupsRelations = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsTrips.getId())); for (int i = 0; i < groupsRelations.size(); i++) { GroupsRelation relation = groupsRelations.get(i); if (i < verifyCodeList.size()) { relation.setVerifyCode(verifyCodeList.get(i)); relationMapper.updateById(relation); } } } groupsTrips.setStatus(GroupsTrips.Status.validity); updateById(groupsTrips); } @Override @Transactional(rollbackFor = Throwable.class) public void replaceTripsAccount(ReplaceTripsAccountReq req) { Long groupsId = req.getGroupsId(); String account = req.getAccount().trim(); String password = req.getPassword().trim(); String remark = req.getRemark(); Date afterStartTime = req.getStartTime(); Date afterExpiryTime = req.getExpiryTime(); GroupsAccountView groupsAccountView = beanSearcher.searchFirst(GroupsAccountView.class, MapUtils.builder() .field(GroupsAccountView::getGroupsId, groupsId) .build()); if (groupsId == null) { throw BusinessRuntimeException.getInstance("车队已不存在"); } Long accountId = groupsAccountView.getAccountId(); if (accountId == null) { throw BusinessRuntimeException.getInstance("该车队暂未配置账号"); } Long goodsId = groupsAccountView.getGoodsId(); if (!account.contains("客服")) { int count = accountMapper.selectCount(Wrappers.lambdaQuery(Account.class) .eq(Account::getAccount, account) .eq(Account::getGoodsId, goodsId)); if (count > 0) { throw BusinessRuntimeException.getInstance("该平台下已生成该账号"); } } //替换账号 accountMapper.update(null, Wrappers.lambdaUpdate(Account.class) .set(Account::getAccount, account) .set(Account::getPassword, password) .set(Account::getRemark, remark) .set(Account::getStartTime, afterStartTime) .set(Account::getExpiryTime, afterExpiryTime) .eq(Account::getId, accountId)); //保存替换记录 GroupsTripsAccountReplaceRecord replaceRecord = new GroupsTripsAccountReplaceRecord(); replaceRecord.setGroupsId(groupsId); replaceRecord.setOldAccountId(accountId); replaceRecord.setOldAccount(groupsAccountView.getAccount()); replaceRecord.setOldPassword(groupsAccountView.getPassword()); replaceRecord.setOldStartTime(groupsAccountView.getStartTime()); replaceRecord.setOldExpiryTime(groupsAccountView.getExpiryTime()); Long adminId = req.getAdminId(); Optional.ofNullable(cmsUserMapper.selectById(adminId)).ifPresent(admin -> replaceRecord.setOperator(admin.getNickname())); replaceRecord.setNewAccount(account); replaceRecord.setNewPassword(password); replaceRecord.setNewStartTime(afterStartTime); replaceRecord.setNewExpiryTime(afterExpiryTime); replaceRecord.setRemark(remark); replaceRecordMapper.insert(replaceRecord); TASK_EXECUTOR.execute(() -> sendChangeAccountMsg(groupsId, goodsId));; } private void sendChangeAccountMsg(Long groupsId, Long goodsId) { GoodsDon goodsDon = goodsDonMapper.selectById(goodsId); String title = goodsDon != null ? goodsDon.getTitle() : "车票"; DateTime now = DateTime.now(); Boolean isPrd = envCommonService.isPrdEnv(); List groupsRelations = beanSearcher.searchAll(GroupsRelation.class, MapUtils.builder().field(GroupsRelation::getGroupsId, groupsId).build()); groupsRelations.forEach(relation -> { if (relation.getExpiryTime() == null) { return; } //账号有效期小于5天的人,不发账号替换/改密码短信提醒 if (now.after(DateUtil.offsetDay(relation.getExpiryTime(), -5))) { return; } if (Constant.CHANGE_ACCOUNT_PWD_FILTER_GIDS.contains(goodsId)) { return; } if (relation.getUserId() != 0 && isPrd) { String msg = String.format(Constant.CHANGE_GROUPS_TRIPS_ACCOUNT, title); smsService.sendSmsToRelationUser(relation.getUserId(), msg); } }); } }