AccountBizService.java 15.7 KB
package cn.fw.dalaran.service.biz;

import cn.fw.common.page.AppPage;
import cn.fw.common.web.annotation.DisLock;
import cn.fw.dalaran.common.constants.DalaranConstants;
import cn.fw.dalaran.common.exception.BusinessException;
import cn.fw.dalaran.common.utils.DateUtil;
import cn.fw.dalaran.domain.db.Account;
import cn.fw.dalaran.domain.db.TodoHistory;
import cn.fw.dalaran.domain.dto.AccountDTO;
import cn.fw.dalaran.domain.dto.AccountQueryDTO;
import cn.fw.dalaran.domain.dto.UpdateAccountParam;
import cn.fw.dalaran.domain.enums.PlatformEnum;
import cn.fw.dalaran.domain.vo.AccountStatusVo;
import cn.fw.dalaran.domain.vo.AccountVO;
import cn.fw.dalaran.domain.vo.CommonAccountVO;
import cn.fw.dalaran.rpc.erp.UserRoleRpcService;
import cn.fw.dalaran.rpc.erp.dto.UserInfoDTO;
import cn.fw.dalaran.service.data.AccountService;
import cn.fw.dalaran.service.data.TodoHistoryService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static cn.fw.common.businessvalidator.Validator.BV;

@Service
@Slf4j
@RequiredArgsConstructor
public class AccountBizService {

    private final AccountService accountService;
    private final TodoHistoryService todoHistoryService;
    private final UserRoleRpcService userRoleRpcService;

    /**
     * 添加账号
     *
     * @param accountDTO
     * @return 操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    @DisLock(prefix = "':' + #this.getClass().getSimpleName()", key = "#accountDTO.groupId + ':' + #accountDTO.account", message = "请勿重复提交")
    public boolean saveAccount(AccountDTO accountDTO) {
        checkExist(accountDTO);
        Account db = new Account();
        BeanUtils.copyProperties(accountDTO, db);
        if (Objects.equals(accountDTO.getType(), PlatformEnum.KS) && Objects.isNull(accountDTO.getPlaybackSearchKey())) {
            final List<Account> collect = accountService.getByUserAccountNo(accountDTO.getAccount())
                    .stream()
                    .filter(item -> Objects.equals(item.getType(), PlatformEnum.KS) &&
                            Objects.nonNull(item.getPlaybackSearchKey()))
                    .collect(Collectors.toList());// 找到快手平台历史账号记录有直播搜索关键词的
            if (!CollectionUtils.isEmpty(collect))
                db.setPlaybackSearchKey(collect.get(0).getPlaybackSearchKey());
            else {
                Pattern p = Pattern.compile("^[0-9].*");
                Matcher m = p.matcher(accountDTO.getAccount());
                if (m.matches() && Objects.equals(accountDTO.getType(), PlatformEnum.KS))
                    throw new BusinessException("添加快手账号失败, 必须指定直播搜索关键词");
            }
        }
        db.setYn(Boolean.TRUE);
        db.setId(accountDTO.getId());
        if (Objects.isNull(accountDTO.getId())) {
            db.setCreateTime(DateUtil.localDateTime2Date(LocalDateTime.now().plusDays(-1)));
        }
        return accountService.saveOrUpdate(db);
    }

    /**
     * 上报cookie失效账号
     *
     * @param account
     * @param type
     * @return 操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    @DisLock(prefix = "':' + #this.getClass().getSimpleName()", key = "#type + ':' + #account", message = "请勿重复提交")
    public boolean reportInvalidAccount(String account, Integer type) {
        PlatformEnum platformEnum = PlatformEnum.ofValue(type);
        BV.notNull(platformEnum, () -> "平台类型不能为空");
        List<Account> list = accountService.list(Wrappers.<Account>lambdaQuery()
                .eq(Account::getAccount, account)
                .eq(Account::getType, platformEnum)
                .eq(Account::getValid, Boolean.TRUE)
                .eq(Account::getAffirm, Boolean.TRUE)
                .eq(Account::getYn, Boolean.TRUE)
        );// 找到失效的账号
        if (CollectionUtils.isEmpty(list))
            return true;
        boolean result = accountService.updateBatchById(list.stream()
                .peek(item -> item.setValid(Boolean.FALSE))
                .collect(Collectors.toList())
        );// 更新账号状态为失效
        List<TodoHistory> todos = new ArrayList<>();
        for (Account account1 : list) {
            TodoHistory history = new TodoHistory();
            history.setSend(Boolean.FALSE);
            history.setDone(Boolean.FALSE);
            history.setDataId(account1.getId());
            history.setShopId(account1.getShopId());
            history.setUserId(account1.getUserId());
            history.setTodoCode(DalaranConstants.ACCOUNT_INVALID);
            todos.add(history);
            List<UserInfoDTO> users = userRoleRpcService.getUsers(account1.getShopId(), DalaranConstants.ZHSZ_ROLE_CODE);
            if (!CollectionUtils.isEmpty(users)) {
                Long managerId = users.get(0).getUserId();
                TodoHistory manageTodo = new TodoHistory();
                BeanUtils.copyProperties(history, manageTodo);
                manageTodo.setUserId(managerId);
                history.setExtra(String.valueOf(managerId));
                todos.add(manageTodo);
            }
        }
        List<Long> waitSendIds = list.stream()
                .map(Account::getId)
                .collect(Collectors.toList());// 失败账号id
        List<TodoHistory> todayHasSendList = todoHistoryService.lambdaQuery()
                .eq(TodoHistory::getTodoCode, DalaranConstants.ACCOUNT_INVALID)
                .in(!CollectionUtils.isEmpty(waitSendIds), TodoHistory::getDataId, waitSendIds)
                .last(" and DATEDIFF(create_time, NOW()) = 0")
                .list();
        if (todayHasSendList.stream().noneMatch(item -> waitSendIds.contains(item.getDataId())))
            todoHistoryService.saveBatch(todos);// 如果今天之内没有发送过待办, 才保存todo_history
        return result;
    }

    /**
     * 上报账号状态
     *
     * @param accountId 账号id
     * @param valid     状态
     * @return 操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    @DisLock(prefix = "':' + #this.getClass().getSimpleName()", key = "'accountReport:' + #accountId", message = "请勿重复提交")
    public boolean reportAccount(Long accountId, Boolean valid) {
        Account account = accountService.getById(accountId);
        if (Objects.isNull(account))
            return true;
        if (Objects.equals(valid, account.getValid()))
            return true;
        account.setValid(valid);
        account.setAffirm(Boolean.TRUE);
        boolean result = accountService.updateById(account);// 修改账号状态为指定状态
        List<TodoHistory> userList = todoHistoryService.lambdaQuery()
                .eq(TodoHistory::getDone, Boolean.FALSE)
                .eq(TodoHistory::getDataId, accountId)
                .list();
        List<String> collect = userList.stream()
                .map(TodoHistory::getExtra)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());// 查找是否有管理人员
        if (!CollectionUtils.isEmpty(collect)) {
            List<TodoHistory> managerList = todoHistoryService.lambdaQuery()
                    .eq(TodoHistory::getDone, Boolean.FALSE)
                    .eq(TodoHistory::getDataId, accountId)
                    .in(TodoHistory::getUserId, collect)
                    .list();
            userList.addAll(managerList);
        }
        todoHistoryService.updateBatchById(new HashSet<>(userList).stream()
                .peek(item -> item.setDone(true))
                .collect(Collectors.toList())
        );
        return result;
    }

    /**
     * 保存账户信息
     *
     * @param account
     * @param type
     * @param fans
     * @param accountName
     */
    public void saveAccountMsg(String account, Integer type, Long fans, String accountName) {
        PlatformEnum platformEnum = PlatformEnum.ofValue(type);
        if (Objects.isNull(platformEnum) || Objects.isNull(fans)) {
            return;
        }
        List<Account> list = accountService.list(Wrappers.<Account>lambdaQuery()
                .eq(Account::getAccount, account)
                .eq(Account::getType, platformEnum)
                .eq(Account::getYn, Boolean.TRUE)
                .eq(Account::getValid, Boolean.TRUE)
        );
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        list.forEach(item -> {
            item.setFansNum(fans);
            item.setAccountName(accountName);
        });
        accountService.updateBatchById(list);
    }

    /**
     * 分页查询账号信息
     *
     * @param groupId
     * @param query
     * @return
     */
    public AppPage<AccountVO> page(Long groupId, AccountQueryDTO query) {
        Page<Account> dbPageList = new Page<>(query.getCurrent(), query.getPageSize());
        dbPageList = accountService.page(dbPageList, Wrappers.<Account>lambdaQuery()
                .eq(Account::getGroupId, groupId)
                .eq(Objects.nonNull(query.getType()), Account::getType, query.getType())
                .eq(Objects.nonNull(query.getValid()), Account::getValid, query.getValid())
                .eq(Objects.nonNull(query.getShopId()), Account::getShopId, query.getShopId())
                .eq(Objects.nonNull(query.getUserId()), Account::getUserId, query.getUserId())
                .like(Objects.nonNull(query.getUserName()), Account::getUserName, query.getUserName())
                .eq(Account::getYn, Boolean.TRUE)
        );
        AppPage<AccountVO> pageList = AppPage.empty(query);
        pageList.setTotal(dbPageList.getTotal());
        List<Account> dbList = dbPageList.getRecords();
        if (CollectionUtils.isEmpty(dbList)) {
            return pageList;
        }
        List<AccountVO> list = new ArrayList<>();
        for (Account account : dbList) {
            AccountVO vo = new AccountVO();
            BeanUtils.copyProperties(account, vo);
            vo.setId(account.getId());
            vo.setCreateTime(account.getCreateTime());
            list.add(vo);
        }
        pageList.setData(list);
        return pageList;
    }

    /**
     * 获取有效账号
     *
     * @param type
     * @return
     */
    public List<CommonAccountVO> getValidAccount(Integer type) {
        PlatformEnum platformEnum = PlatformEnum.ofValue(type);
        BV.notNull(platformEnum, () -> "账号类型不正确");
        List<Account> list = accountService.list(Wrappers.<Account>lambdaQuery()
                .eq(Account::getAffirm, Boolean.TRUE)
                .eq(Account::getValid, Boolean.TRUE)
                .eq(Account::getType, platformEnum)
                .ne(Account::getAccountStatus, -1)
                //.eq(Account::getAccountStatus, 1)
                .eq(Account::getYn, Boolean.TRUE)
        );
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream()
                .map(item -> CommonAccountVO.builder()
                        .account(item.getAccount())// 账号
                        .playbackSearchKey(item.getPlaybackSearchKey())// 回播搜索关键词
                        .groupId(item.getGroupId())// 集团id
                        .build()
                )
                .collect(Collectors.toList());
    }

    /**
     * 删除账号
     *
     * @param id
     * @return 操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAccount(Long id) {
        return accountService.lambdaUpdate()
                .eq(Account::getId, id)
                .set(Account::getYn, 0)
                .set(Account::getUpdateTime, new Date())
                .update();
    }

    /**
     * 检查账户是否已经存在
     *
     * @param accountDTO
     */
    private void checkExist(AccountDTO accountDTO) {
        if (Objects.nonNull(accountDTO.getId())) {
            Account account = accountService.getById(accountDTO.getId());
            BV.notNull(account, () -> "该账号不存在,修改失败");
            BV.isFalse(account.getAffirm(), () -> "已认证授权的账号不允许修改");
            return;
        }
        int count = accountService.count(Wrappers.<Account>lambdaQuery()
                .eq(Account::getAccount, accountDTO.getAccount())
                .eq(Account::getType, accountDTO.getType())
                .eq(Account::getGroupId, accountDTO.getGroupId())
                .eq(Account::getYn, Boolean.TRUE)
        );
        BV.isFalse(count > 0, () -> "该账号已存在,不允许重复添加");
    }

    /**
     * 查询个每个门店账号状态详情
     *
     * @param groupId 集团id
     * @return 每个门店账号状态详情视图
     */
    public List<AccountStatusVo.ShopDetails> status(Long groupId) {
        final AccountStatusVo vo = new AccountStatusVo();
        final List<Account> accountList = accountService.lambdaQuery()
                .eq(Account::getGroupId, groupId)
                .list();
        final Map<Long, List<Account>> shopAccountsMap = accountList.stream()
                .collect(Collectors.groupingBy(Account::getShopId));// 根据门店分组账号
        List<AccountStatusVo.ShopDetails> shopDetailsList = new ArrayList<>();
        shopAccountsMap.forEach((k, v) -> {
            AccountStatusVo.ShopDetails shopDetails = new AccountStatusVo.ShopDetails();
            shopDetails.setShopId(k);// 门店id
            shopDetails.setShopName(v.get(0).getShopName());// 门店名
            shopDetails.setAdvisorCnt((int) v.stream()
                    .map(Account::getUserName)
                    .distinct()
                    .count());// 销售顾问人数
            List<AccountStatusVo.PlatformDetails> accountTypeList = new ArrayList<>();
            v.stream()
                    .collect(Collectors.groupingBy(Account::getType))
                    .forEach((k1, v1) -> {
                        AccountStatusVo.PlatformDetails platFormDetails = new AccountStatusVo.PlatformDetails();
                        platFormDetails.setPlatform(k1);// 平台
                        platFormDetails.setPlatformName(k1.getName());// 平台名
                        v1.stream()
                                .collect(Collectors.groupingBy(Account::getValid))
                                .forEach((k2, v2) -> {
                                    if (!k2) {
                                        platFormDetails.setHasExpireCnt(v2.size());// 授权失效账号数
                                    } else {
                                        platFormDetails.setHasLoginCnt(v2.size());// 登陆成功账号数
                                    }
                                });
                        accountTypeList.add(platFormDetails);
                    });
            shopDetails.setPlatformDetailsList(accountTypeList);
            shopDetailsList.add(shopDetails);
        });
        vo.setShopDetailsList(shopDetailsList);
        //return vo;
        return shopDetailsList;
    }

    public boolean alert(UpdateAccountParam param) {
        final String auth = param.getAuth();
        if (Objects.equals(auth, "fw@2017")) {
            param.getAccounts().forEach(item -> {
                if (Objects.isNull(item.getId()))
                    return;
                accountService.alertAccount(item);
            });
            return true;
        }
        return false;
    }

}