package com.liquidnet.client.admin.zhengzai.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.zhengzai.merchant.service.*;
import com.liquidnet.client.admin.zhengzai.merchant.utils.MerchantMongoUtil;
import com.liquidnet.client.admin.zhengzai.merchant.utils.MerchantRedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.merchant.constant.MerchantAuthorizationConst;
import com.liquidnet.service.merchant.dto.vo.*;
import com.liquidnet.service.merchant.entity.*;
import com.liquidnet.service.merchant.mapper.MerchantAuthorizationRecordsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MerchantAuthorizationRecordsAdminServiceImpl extends ServiceImpl<MerchantAuthorizationRecordsMapper, MerchantAuthorizationRecords> implements IMerchantAuthorizationRecordsAdminService {

    @Autowired
    MerchantRedisUtil merchantRedisUtil;

    @Autowired
    MerchantMongoUtil merchantMongoUtil;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    IMerchantFieldsAdminService fieldsAdminService;

    @Autowired
    IMerchantFieldCheckersAdminService fieldCheckersAdminService;

    @Autowired
    IMerchantSponsorsAdminService sponsorsAdminService;

    @Autowired
    IMerchantAuthorizationPermissionsAdminService authorizationPermissionsAdminService;

    @Override
    @Transactional
    public void authorizationInit(String performanceId, String cuid, String fieldId, String sponsorId) {
        // 创建者
        List<String> updatedUids1 = this.performanceCreator(performanceId, cuid);
        Set<String> updatedUids = new HashSet<>(updatedUids1);

        // 主办方
        List<String> updatedUids2 = this.performanceSponsor(performanceId, sponsorId);
        updatedUids.addAll(updatedUids2);

        // 场地方
        List<String> updatedUids3 = this.performanceFielder(performanceId, fieldId);
        updatedUids.addAll(updatedUids3);

        // 聚合角色及权限 vo
        for (String uid: updatedUids) {
            merchantMongoUtil.syncAndSetAuthorizationPerformanceVo(performanceId, uid);
        }
    }

    // 创建者
    private List<String> performanceCreator(String performanceId, String cuid) {
        LocalDateTime now = LocalDateTime.now();

        List<String> updatedUids = new ArrayList<>();

        // 查询已有权限
        LambdaQueryWrapper<MerchantAuthorizationRecords> authorizationRecordsLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantAuthorizationRecords.class);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getPerformanceId, performanceId);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getUidRole, MerchantAuthorizationConst.PerformanceRole.CREATOR.getRole());
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getDeletedAt, null);
        MerchantAuthorizationRecords authorizationRecords = getOne(authorizationRecordsLambdaQueryWrapper);

        // 是否已存在权限
        if (null == cuid) {
            throw new LiquidnetServiceException();
        }
        if (null != authorizationRecords) {
            if (!authorizationRecords.getUid().equals(cuid)) {
                // 前后 创建方一致 不处理
                return updatedUids;
            }
            // 前后 创建方不一致的情况不存在
            throw new LiquidnetServiceException();
        }

        // 添加权限
        List<MerchantAuthorizationRecords> authorizationRecordsArrayList = new ArrayList<>();
        List<MerchantAuthorizationPermissions> authorizationPermissionsArrayList = new ArrayList<>();

        // 授权记录 entity
        // todo 用户信息
        MerchantAuthorizationRecords creatorAuthorizationRecords = new MerchantAuthorizationRecords();
        creatorAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
        creatorAuthorizationRecords.setPerformanceId(performanceId);
        creatorAuthorizationRecords.setUidRole(MerchantAuthorizationConst.PerformanceRole.CREATOR.getRole());
        creatorAuthorizationRecords.setUid(cuid);
        creatorAuthorizationRecords.setMobile("");
        creatorAuthorizationRecords.setName("");
        creatorAuthorizationRecords.setCuid("");
        creatorAuthorizationRecords.setCuidRole("");
        creatorAuthorizationRecords.setCreatedAt(now);
        authorizationRecordsArrayList.add(creatorAuthorizationRecords);

        // 授权权限 entity vo
        List<MerchantAuthorizationPermissionsVo> creatorAuthorizationPermissionsVos = new ArrayList<>();
        String[] fielderPermissionIds = {
                MerchantAuthorizationConst.PerformancePermission.READ.getId(),
                MerchantAuthorizationConst.PerformancePermission.EDIT.getId(),
                MerchantAuthorizationConst.PerformancePermission.LINE.getId(),
                MerchantAuthorizationConst.PerformancePermission.CHECK.getId(),
                MerchantAuthorizationConst.PerformancePermission.SALES.getId(),
                MerchantAuthorizationConst.PerformancePermission.ACCREDIT.getId()
        };
        for (String permissionId : fielderPermissionIds) {
            // entity
            MerchantAuthorizationPermissions creatorAuthorizationPermissions = new MerchantAuthorizationPermissions();
            creatorAuthorizationPermissions.setAuthorizationPermissionId(IDGenerator.nextSnowId());
            creatorAuthorizationPermissions.setAuthorizationRecordId(creatorAuthorizationRecords.getAuthorizationRecordId());
            creatorAuthorizationPermissions.setPermissionId(permissionId);
            creatorAuthorizationPermissions.setStartTime(now);
            creatorAuthorizationPermissions.setEndTime(now.plusYears(10));
            creatorAuthorizationPermissions.setCreatedAt(now);
            authorizationPermissionsArrayList.add(creatorAuthorizationPermissions);
            // vo
            MerchantAuthorizationPermissionsVo authorizationPermissionsVo = MerchantAuthorizationPermissionsVo.getNew();
            authorizationPermissionsVo.copy(creatorAuthorizationPermissions);
            creatorAuthorizationPermissionsVos.add(authorizationPermissionsVo);
        }

        // 授权记录 vo
        MerchantAuthorizationRecordsVo authorizationRecordsVo = MerchantAuthorizationRecordsVo.getNew();
        authorizationRecordsVo.copy(creatorAuthorizationRecords);
        authorizationRecordsVo.setPermissionsVos(creatorAuthorizationPermissionsVos);

        // mysql
        boolean success = saveBatch(authorizationRecordsArrayList);
        if (!success) {
            // todo error
            throw new LiquidnetServiceException();
        }
        success = authorizationPermissionsAdminService.saveBatch(authorizationPermissionsArrayList);
        if (!success) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // mongo
        mongoTemplate.insert(authorizationRecordsVo, MerchantAuthorizationRecordsVo.class.getSimpleName());

        // updated uid
        updatedUids.add(authorizationRecordsVo.getUid());

        return updatedUids;
    }

    // 授权主办方
    private List<String> performanceSponsor(String performanceId, String sponsorId) {
        LocalDateTime now = LocalDateTime.now();

        List<String> updatedUids = new ArrayList<>();

        // 查询已有权限
        LambdaQueryWrapper<MerchantAuthorizationRecords> authorizationRecordsLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantAuthorizationRecords.class);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getPerformanceId, performanceId);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getUidRole, MerchantAuthorizationConst.PerformanceRole.SPONSOR.getRole());
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getDeletedAt, null);
        MerchantAuthorizationRecords authorizationRecords = getOne(authorizationRecordsLambdaQueryWrapper);

        // 查询主办方
        LambdaQueryWrapper<MerchantSponsors> sponsorsLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantSponsors.class);
        sponsorsLambdaQueryWrapper.eq(MerchantSponsors::getSponsorId, sponsorId);
        MerchantSponsors sponsors = sponsorsAdminService.getOne(sponsorsLambdaQueryWrapper);

        // 是否已存在权限
        if (null != authorizationRecords) {
            if (null != sponsors && authorizationRecords.getUid().equals(sponsors.getUid())) {
                // 前后 主办方一致 不处理
                return updatedUids;
            }

            // 前后 主办方不一致 删除旧权限 及 我的授权
            authorizationRecords.setUpdatedAt(now);
            authorizationRecords.setDeletedAt(now);

            // 查询删除 旧权限 及 旧权限角色的授权 mysql
            LambdaUpdateWrapper<MerchantAuthorizationRecords> authorizationRecordsLambdaUpdateWrapper = Wrappers.lambdaUpdate(MerchantAuthorizationRecords.class);
            authorizationRecordsLambdaUpdateWrapper
                    .eq(MerchantAuthorizationRecords::getPerformanceId, performanceId)
                    .eq(MerchantAuthorizationRecords::getDeletedAt, null);
            authorizationRecordsLambdaUpdateWrapper.and(wrapper -> wrapper
                    .eq(MerchantAuthorizationRecords::getAuthorizationRecordId, authorizationRecords.getAuthorizationRecordId())
                    .or(wrapper1 -> wrapper1
                            .eq(MerchantAuthorizationRecords::getCuid, authorizationRecords.getUid())
                            .eq(MerchantAuthorizationRecords::getCuidRole, MerchantAuthorizationConst.PerformanceRole.SPONSOR.getRole()))
            );
            authorizationRecordsLambdaUpdateWrapper.set(MerchantAuthorizationRecords::getUpdatedAt, authorizationRecords.getUpdatedAt());
            authorizationRecordsLambdaUpdateWrapper.set(MerchantAuthorizationRecords::getDeletedAt, authorizationRecords.getDeletedAt());
            boolean success = update(authorizationRecordsLambdaUpdateWrapper);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }

            // 查询删除 旧权限 及 旧权限角色的授权 mongo query
            Criteria criteria = Criteria.where("performanceId").is(performanceId).and("deletedAt").is(null);
            criteria.orOperator(
                    Criteria.where("authorizationRecordId").is(authorizationRecords.getAuthorizationRecordId()),
                    Criteria.where("cuid").is(authorizationRecords.getUid()).and("cuidRole").is(MerchantAuthorizationConst.PerformanceRole.SPONSOR.getRole())
            );
            Query query = Query.query(criteria);
            // 查询旧权限 及 旧权限角色的授权 mongo
            List<String> uids = mongoTemplate.findDistinct(query, "uid", MerchantAuthorizationRecordsVo.class.getSimpleName(), MerchantAuthorizationRecordsVo.class, String.class);
            // 删除旧权限 及 旧权限角色的授权 mongo
            mongoTemplate.remove(query, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());

            // updated uid
            updatedUids.addAll(uids);
        }

        // 是否添加权限
        if (null != sponsors && !sponsors.getUid().isEmpty()) {
            List<MerchantAuthorizationRecords> authorizationRecordsArrayList = new ArrayList<>();
            List<MerchantAuthorizationPermissions> authorizationPermissionsArrayList = new ArrayList<>();

            // 授权记录 entity
            // todo 用户信息
            MerchantAuthorizationRecords sponsorAuthorizationRecords = new MerchantAuthorizationRecords();
            sponsorAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
            sponsorAuthorizationRecords.setPerformanceId(performanceId);
            sponsorAuthorizationRecords.setUidRole(MerchantAuthorizationConst.PerformanceRole.SPONSOR.getRole());
            sponsorAuthorizationRecords.setUid(sponsors.getUid());
            sponsorAuthorizationRecords.setMobile("");
            sponsorAuthorizationRecords.setName("");
            sponsorAuthorizationRecords.setCuid("");
            sponsorAuthorizationRecords.setCuidRole("");
            sponsorAuthorizationRecords.setCreatedAt(now);
            authorizationRecordsArrayList.add(sponsorAuthorizationRecords);
            // 授权权限 entity vo
            List<MerchantAuthorizationPermissionsVo> sponsorAuthorizationPermissionsVos = new ArrayList<>();
            String[] fielderPermissionIds = {
                    MerchantAuthorizationConst.PerformancePermission.READ.getId(),
                    MerchantAuthorizationConst.PerformancePermission.CHECK.getId(),
                    MerchantAuthorizationConst.PerformancePermission.SALES.getId(),
                    MerchantAuthorizationConst.PerformancePermission.ACCREDIT.getId()
            };
            for (String permissionId : fielderPermissionIds) {
                MerchantAuthorizationPermissions sponsorAuthorizationPermissions = new MerchantAuthorizationPermissions();
                sponsorAuthorizationPermissions.setAuthorizationPermissionId(IDGenerator.nextSnowId());
                sponsorAuthorizationPermissions.setAuthorizationRecordId(sponsorAuthorizationRecords.getAuthorizationRecordId());
                sponsorAuthorizationPermissions.setPermissionId(permissionId);
                sponsorAuthorizationPermissions.setStartTime(now);
                sponsorAuthorizationPermissions.setEndTime(now.plusYears(10));
                sponsorAuthorizationPermissions.setCreatedAt(now);
                authorizationPermissionsArrayList.add(sponsorAuthorizationPermissions);

                MerchantAuthorizationPermissionsVo sponsorAuthorizationPermissionsVo = MerchantAuthorizationPermissionsVo.getNew();
                sponsorAuthorizationPermissionsVo.copy(sponsorAuthorizationPermissions);
                sponsorAuthorizationPermissionsVos.add(sponsorAuthorizationPermissionsVo);
            }
            // 授权记录 vo
            MerchantAuthorizationRecordsVo sponsorAuthorizationRecordsVo = MerchantAuthorizationRecordsVo.getNew();
            sponsorAuthorizationRecordsVo.copy(sponsorAuthorizationRecords);
            sponsorAuthorizationRecordsVo.setPermissionsVos(sponsorAuthorizationPermissionsVos);

            // mysql
            boolean success = saveBatch(authorizationRecordsArrayList);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }
            success = authorizationPermissionsAdminService.saveBatch(authorizationPermissionsArrayList);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }

            // mongo
            mongoTemplate.insert(sponsorAuthorizationRecordsVo, MerchantAuthorizationRecordsVo.class.getSimpleName());

            // updated uid
            updatedUids.add(sponsorAuthorizationRecordsVo.getUid());
        }

        return updatedUids.stream().distinct().collect(Collectors.toList());
    }

    // 授权场地方
    private List<String> performanceFielder(String performanceId, String fieldId) {
        LocalDateTime now = LocalDateTime.now();

        List<String> updatedUids = new ArrayList<>();

        // 查询已有权限
        LambdaQueryWrapper<MerchantAuthorizationRecords> authorizationRecordsLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantAuthorizationRecords.class);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getPerformanceId, performanceId);
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getUidRole, MerchantAuthorizationConst.PerformanceRole.FIELDER.getRole());
        authorizationRecordsLambdaQueryWrapper.eq(MerchantAuthorizationRecords::getDeletedAt, null);
        MerchantAuthorizationRecords authorizationRecords = getOne(authorizationRecordsLambdaQueryWrapper);

        // 查询场地方
        LambdaQueryWrapper<MerchantFields> fieldsLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantFields.class);
        fieldsLambdaQueryWrapper.eq(MerchantFields::getFieldId, fieldId);
        MerchantFields fields = fieldsAdminService.getOne(fieldsLambdaQueryWrapper);

        // 是否已存在权限
        if (null != authorizationRecords) {
            if (null != fields && authorizationRecords.getUid().equals(fields.getUid())) {
                // 前后 场地方一致 不处理
                return updatedUids;
            }

            // 前后 场地方不一致 删除旧权限 及 我的授权
            authorizationRecords.setUpdatedAt(now);
            authorizationRecords.setDeletedAt(now);

            // 查询 删除 旧权限 及 旧权限角色的授权 mysql
            LambdaUpdateWrapper<MerchantAuthorizationRecords> authorizationRecordsLambdaUpdateWrapper = Wrappers.lambdaUpdate(MerchantAuthorizationRecords.class);
            authorizationRecordsLambdaUpdateWrapper
                    .eq(MerchantAuthorizationRecords::getPerformanceId, performanceId)
                    .eq(MerchantAuthorizationRecords::getDeletedAt, null);
            authorizationRecordsLambdaUpdateWrapper.and(wrapper -> wrapper
                    .eq(MerchantAuthorizationRecords::getAuthorizationRecordId, authorizationRecords.getAuthorizationRecordId())
                    .or(wrapper1 -> wrapper1
                            .eq(MerchantAuthorizationRecords::getCuid, authorizationRecords.getUid())
                            .eq(MerchantAuthorizationRecords::getCuidRole, MerchantAuthorizationConst.PerformanceRole.FIELDER.getRole()))
            );
            authorizationRecordsLambdaUpdateWrapper.set(MerchantAuthorizationRecords::getUpdatedAt, authorizationRecords.getUpdatedAt());
            authorizationRecordsLambdaUpdateWrapper.set(MerchantAuthorizationRecords::getDeletedAt, authorizationRecords.getDeletedAt());
            boolean success = update(authorizationRecordsLambdaUpdateWrapper);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }

            // 查询 删除 旧权限 及 旧权限角色的授权 mongo query
            Criteria criteria = Criteria.where("performanceId").is(performanceId).and("deletedAt").is(null);
            criteria.orOperator(
                    Criteria.where("authorizationRecordId").is(authorizationRecords.getAuthorizationRecordId()),
                    Criteria.where("cuid").is(authorizationRecords.getUid()).and("cuidRole").is(MerchantAuthorizationConst.PerformanceRole.FIELDER.getRole())
            );
            Query query = Query.query(criteria);
            // 查询旧权限 及 旧权限角色的授权 mongo
            List<String> uids = mongoTemplate.findDistinct(query, "uid", MerchantAuthorizationRecordsVo.class.getSimpleName(), MerchantAuthorizationRecordsVo.class, String.class);
            // 删除旧权限 及 旧权限角色的授权 mongo
            mongoTemplate.remove(query, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());

            // updated uid
            updatedUids.addAll(uids);
        }

        // 是否添加权限
        if (null != fields && 1 == fields.getClaimStatus()) {
            List<MerchantAuthorizationRecords> authorizationRecordsArrayList = new ArrayList<>();
            List<MerchantAuthorizationPermissions> authorizationPermissionsArrayList = new ArrayList<>();

            List<MerchantAuthorizationRecordsVo> authorizationRecordsVoArrayList = new ArrayList<>();

            // 授权记录 entity
            // todo 用户信息
            MerchantAuthorizationRecords fielderAuthorizationRecords = new MerchantAuthorizationRecords();
            fielderAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
            fielderAuthorizationRecords.setPerformanceId(performanceId);
            fielderAuthorizationRecords.setUidRole(MerchantAuthorizationConst.PerformanceRole.FIELDER.getRole());
            fielderAuthorizationRecords.setUid(fields.getUid());
            fielderAuthorizationRecords.setMobile("");
            fielderAuthorizationRecords.setName("");
            fielderAuthorizationRecords.setCuid("");
            fielderAuthorizationRecords.setCuidRole("");
            fielderAuthorizationRecords.setCreatedAt(now);
            authorizationRecordsArrayList.add(fielderAuthorizationRecords);
            // 授权权限 entity vo
            List<MerchantAuthorizationPermissionsVo> fielderAuthorizationPermissionsVos = new ArrayList<>();
            String[] fielderPermissionIds = {
                    MerchantAuthorizationConst.PerformancePermission.READ.getId(),
                    MerchantAuthorizationConst.PerformancePermission.CHECK.getId(),
                    MerchantAuthorizationConst.PerformancePermission.ACCREDIT.getId()
            };
            for (String permissionId : fielderPermissionIds) {
                MerchantAuthorizationPermissions fielderAuthorizationPermissions = new MerchantAuthorizationPermissions();
                fielderAuthorizationPermissions.setAuthorizationPermissionId(IDGenerator.nextSnowId());
                fielderAuthorizationPermissions.setAuthorizationRecordId(fielderAuthorizationRecords.getAuthorizationRecordId());
                fielderAuthorizationPermissions.setPermissionId(permissionId);
                fielderAuthorizationPermissions.setStartTime(now);
                fielderAuthorizationPermissions.setEndTime(now.plusYears(10));
                fielderAuthorizationPermissions.setCreatedAt(now);
                authorizationPermissionsArrayList.add(fielderAuthorizationPermissions);

                MerchantAuthorizationPermissionsVo fielderAuthorizationPermissionsVo = MerchantAuthorizationPermissionsVo.getNew();
                fielderAuthorizationPermissionsVo.copy(fielderAuthorizationPermissions);
                fielderAuthorizationPermissionsVos.add(fielderAuthorizationPermissionsVo);
            }
            // 授权记录 vo
            MerchantAuthorizationRecordsVo fielderAuthorizationRecordsVo = MerchantAuthorizationRecordsVo.getNew();
            fielderAuthorizationRecordsVo.copy(fielderAuthorizationRecords);
            fielderAuthorizationRecordsVo.setPermissionsVos(fielderAuthorizationPermissionsVos);
            authorizationRecordsVoArrayList.add(fielderAuthorizationRecordsVo);

            // 查询默认验票员
            LambdaQueryWrapper<MerchantFieldCheckers> fieldCheckersLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantFieldCheckers.class);
            fieldCheckersLambdaQueryWrapper.eq(MerchantFieldCheckers::getFieldId, fieldId);
            fieldCheckersLambdaQueryWrapper.eq(MerchantFieldCheckers::getDeletedAt, null);
            List<MerchantFieldCheckers> fieldCheckersList = fieldCheckersAdminService.list(fieldCheckersLambdaQueryWrapper);
            if (!CollectionUtil.isEmpty(fieldCheckersList)) {
                // 验票员 授权权限
                String[] checkerPermissionIds = {
                        MerchantAuthorizationConst.PerformancePermission.CHECK.getId()
                };
                for (MerchantFieldCheckers fieldCheckers: fieldCheckersList) {
                    // 验票员 授权记录 entity
                    MerchantAuthorizationRecords checkerAuthorizationRecords = new MerchantAuthorizationRecords();
                    checkerAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
                    checkerAuthorizationRecords.setPerformanceId(performanceId);
                    checkerAuthorizationRecords.setUidRole(MerchantAuthorizationConst.PerformanceRole.CHECKER.getRole());
                    checkerAuthorizationRecords.setUid(fieldCheckers.getUid());
                    checkerAuthorizationRecords.setMobile(fieldCheckers.getMobile());
                    checkerAuthorizationRecords.setName(fieldCheckers.getName());
                    checkerAuthorizationRecords.setCuid(fields.getUid());
                    checkerAuthorizationRecords.setCuidRole(MerchantAuthorizationConst.PerformanceRole.FIELDER.getRole());
                    checkerAuthorizationRecords.setCreatedAt(now);
                    authorizationRecordsArrayList.add(checkerAuthorizationRecords);

                    // 验票员 授权权限 entity vo
                    List<MerchantAuthorizationPermissionsVo> checkerAuthorizationPermissionsVos = new ArrayList<>();
                    for (String permissionId : checkerPermissionIds) {
                        MerchantAuthorizationPermissions checkerAuthorizationPermissions = new MerchantAuthorizationPermissions();
                        checkerAuthorizationPermissions.setAuthorizationPermissionId(IDGenerator.nextSnowId());
                        checkerAuthorizationPermissions.setAuthorizationRecordId(checkerAuthorizationRecords.getAuthorizationRecordId());
                        checkerAuthorizationPermissions.setPermissionId(permissionId);
                        checkerAuthorizationPermissions.setStartTime(now);
                        checkerAuthorizationPermissions.setEndTime(now.plusYears(10));
                        checkerAuthorizationPermissions.setCreatedAt(now);
                        authorizationPermissionsArrayList.add(checkerAuthorizationPermissions);

                        MerchantAuthorizationPermissionsVo checkerAuthorizationPermissionsVo = MerchantAuthorizationPermissionsVo.getNew();
                        checkerAuthorizationPermissionsVo.copy(checkerAuthorizationPermissions);
                        checkerAuthorizationPermissionsVos.add(checkerAuthorizationPermissionsVo);
                    }

                    // 验票员 授权记录 vo
                    MerchantAuthorizationRecordsVo checkerAuthorizationRecordsVo = MerchantAuthorizationRecordsVo.getNew();
                    checkerAuthorizationRecordsVo.copy(checkerAuthorizationRecords);
                    checkerAuthorizationRecordsVo.setPermissionsVos(checkerAuthorizationPermissionsVos);
                    authorizationRecordsVoArrayList.add(checkerAuthorizationRecordsVo);
                }
            }

            // mysql
            boolean success = saveBatch(authorizationRecordsArrayList);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }
            success = authorizationPermissionsAdminService.saveBatch(authorizationPermissionsArrayList);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }

            // mongo
            mongoTemplate.insert(authorizationRecordsVoArrayList, MerchantAuthorizationRecordsVo.class.getSimpleName());

            // updated uid
            for (MerchantAuthorizationRecordsVo authorizationRecordsVo : authorizationRecordsVoArrayList) {
                updatedUids.add(authorizationRecordsVo.getUid());
            }
        }

        return updatedUids.stream().distinct().collect(Collectors.toList());
    }
}
