package com.liquidnet.client.admin.zhengzai.slime.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.slime.service.*;
import com.liquidnet.client.admin.zhengzai.slime.utils.SlimeMongoUtil;
import com.liquidnet.client.admin.zhengzai.slime.utils.SlimeRedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.slime.constant.SlimeAuthorizationConst;
import com.liquidnet.service.slime.dto.vo.*;
import com.liquidnet.service.slime.entity.*;
import com.liquidnet.service.slime.mapper.SlimeAuthorizationRecordsMapper;
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 SlimeAuthorizationRecordsAdminServiceImpl extends ServiceImpl<SlimeAuthorizationRecordsMapper, SlimeAuthorizationRecords> implements ISlimeAuthorizationRecordsAdminService {

    @Autowired
    SlimeRedisUtil slimeRedisUtil;

    @Autowired
    SlimeMongoUtil slimeMongoUtil;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    ISlimeFieldsAdminService fieldsAdminService;

    @Autowired
    ISlimeFieldCheckersAdminService fieldCheckersAdminService;

    @Autowired
    ISlimeSponsorsAdminService sponsorsAdminService;

    @Autowired
    ISlimeAuthorizationPermissionsAdminService authorizationPermissionsAdminService;

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

        // 审核员（场地方审核）
        List<String> updatedUids2 = this.performanceAuditor(performanceId, fieldId);
        updatedUids.addAll(updatedUids2);

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

    @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 mongo
        for (String uid: updatedUids) {
            slimeMongoUtil.getAndSyncAuthorizationPerformanceVo(performanceId, uid);
        }
    }

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

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

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

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

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

        // 授权记录 entity
        SlimeAuthorizationRecords creatorAuthorizationRecords = new SlimeAuthorizationRecords();
        creatorAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
        creatorAuthorizationRecords.setPerformanceId(performanceId);
        creatorAuthorizationRecords.setUidRole(SlimeAuthorizationConst.PerformanceRole.CREATOR.getRole());
        creatorAuthorizationRecords.setUid(cuid);
        creatorAuthorizationRecords.setMobile("");
        creatorAuthorizationRecords.setName("");
        creatorAuthorizationRecords.setCuid("");
        creatorAuthorizationRecords.setCuidRole("");
        creatorAuthorizationRecords.setCreatedAt(now);
        authorizationRecordsArrayList.add(creatorAuthorizationRecords);

        // 授权权限 entity vo
        List<SlimeAuthorizationPermissionsVo> creatorAuthorizationPermissionsVos = new ArrayList<>();
        String[] fielderPermissionIds = {
                SlimeAuthorizationConst.PerformancePermission.READ.getId(),
                SlimeAuthorizationConst.PerformancePermission.EDIT.getId(),
                SlimeAuthorizationConst.PerformancePermission.LINE.getId(),
                SlimeAuthorizationConst.PerformancePermission.CHECK.getId(),
                SlimeAuthorizationConst.PerformancePermission.SALES.getId(),
                SlimeAuthorizationConst.PerformancePermission.GRANT.getId()
        };
        for (String permissionId : fielderPermissionIds) {
            // entity
            SlimeAuthorizationPermissions creatorAuthorizationPermissions = new SlimeAuthorizationPermissions();
            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
            SlimeAuthorizationPermissionsVo authorizationPermissionsVo = SlimeAuthorizationPermissionsVo.getNew();
            authorizationPermissionsVo.copy(creatorAuthorizationPermissions);
            creatorAuthorizationPermissionsVos.add(authorizationPermissionsVo);
        }

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

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

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

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

        return updatedUids;
    }

    // 授权审核员（场地方审核）
    private List<String> performanceAuditor(String performanceId, String fieldId) {
        LocalDateTime now = LocalDateTime.now();

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

        // 查询已有权限
        LambdaQueryWrapper<SlimeAuthorizationRecords> authorizationRecordsLambdaQueryWrapper = Wrappers.lambdaQuery(SlimeAuthorizationRecords.class);
        authorizationRecordsLambdaQueryWrapper.eq(SlimeAuthorizationRecords::getPerformanceId, performanceId);
        authorizationRecordsLambdaQueryWrapper.eq(SlimeAuthorizationRecords::getUidRole, SlimeAuthorizationConst.PerformanceRole.AUDITOR.getRole());
        authorizationRecordsLambdaQueryWrapper.isNull(SlimeAuthorizationRecords::getDeletedAt);
        SlimeAuthorizationRecords authorizationRecords = getOne(authorizationRecordsLambdaQueryWrapper);

        // 查询审核员
        LambdaQueryWrapper<SlimeFields> fieldsLambdaQueryWrapper = Wrappers.lambdaQuery(SlimeFields.class);
        fieldsLambdaQueryWrapper.eq(SlimeFields::getFieldId, fieldId);
        SlimeFields 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<SlimeAuthorizationRecords> authorizationRecordsLambdaUpdateWrapper = Wrappers.lambdaUpdate(SlimeAuthorizationRecords.class);
            authorizationRecordsLambdaUpdateWrapper
                    .eq(SlimeAuthorizationRecords::getPerformanceId, performanceId)
                    .isNull(SlimeAuthorizationRecords::getDeletedAt)
                    .eq(SlimeAuthorizationRecords::getAuthorizationRecordId, authorizationRecords.getAuthorizationRecordId());
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getUpdatedAt, authorizationRecords.getUpdatedAt());
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getDeletedAt, authorizationRecords.getDeletedAt());
            boolean success = update(authorizationRecordsLambdaUpdateWrapper);
            if (!success) {
                throw new LiquidnetServiceException();
            }

            // 查询删除 旧权限 mongo
            Criteria criteria = Criteria.where("performanceId").is(performanceId).and("deletedAt").is(null).and("authorizationRecordId").is(authorizationRecords.getAuthorizationRecordId());
            Query query = Query.query(criteria);
            mongoTemplate.remove(query, SlimeAuthorizationRecordsVo.class, SlimeAuthorizationRecordsVo.class.getSimpleName());

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

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

            // 授权记录 entity
            SlimeAuthorizationRecords auditorAuthorizationRecords = new SlimeAuthorizationRecords();
            auditorAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
            auditorAuthorizationRecords.setPerformanceId(performanceId);
            auditorAuthorizationRecords.setUidRole(SlimeAuthorizationConst.PerformanceRole.AUDITOR.getRole());
            auditorAuthorizationRecords.setUid(fields.getUid());
            auditorAuthorizationRecords.setMobile("");
            auditorAuthorizationRecords.setName("");
            auditorAuthorizationRecords.setCuid("");
            auditorAuthorizationRecords.setCuidRole("");
            auditorAuthorizationRecords.setCreatedAt(now);
            authorizationRecordsArrayList.add(auditorAuthorizationRecords);
            // 授权权限 entity vo
            List<SlimeAuthorizationPermissionsVo> auditorAuthorizationPermissionsVos = new ArrayList<>();
            String[] fielderPermissionIds = {
                    SlimeAuthorizationConst.PerformancePermission.AUDIT.getId()
            };
            for (String permissionId : fielderPermissionIds) {
                SlimeAuthorizationPermissions auditorAuthorizationPermissions = new SlimeAuthorizationPermissions();
                auditorAuthorizationPermissions.setAuthorizationPermissionId(IDGenerator.nextSnowId());
                auditorAuthorizationPermissions.setAuthorizationRecordId(auditorAuthorizationRecords.getAuthorizationRecordId());
                auditorAuthorizationPermissions.setPermissionId(permissionId);
                auditorAuthorizationPermissions.setStartTime(now);
                auditorAuthorizationPermissions.setEndTime(now.plusYears(10));
                auditorAuthorizationPermissions.setCreatedAt(now);
                authorizationPermissionsArrayList.add(auditorAuthorizationPermissions);

                SlimeAuthorizationPermissionsVo sponsorAuthorizationPermissionsVo = SlimeAuthorizationPermissionsVo.getNew();
                sponsorAuthorizationPermissionsVo.copy(auditorAuthorizationPermissions);
                auditorAuthorizationPermissionsVos.add(sponsorAuthorizationPermissionsVo);
            }
            // 授权记录 vo
            SlimeAuthorizationRecordsVo auditorAuthorizationRecordsVo = SlimeAuthorizationRecordsVo.getNew();
            auditorAuthorizationRecordsVo.copy(auditorAuthorizationRecords);
            auditorAuthorizationRecordsVo.setPermissionsVos(auditorAuthorizationPermissionsVos);

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

            // mongo
            mongoTemplate.insert(auditorAuthorizationRecordsVo, SlimeAuthorizationRecordsVo.class.getSimpleName());

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

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

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

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

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

        // 查询主办方
        LambdaQueryWrapper<SlimeSponsors> sponsorsLambdaQueryWrapper = Wrappers.lambdaQuery(SlimeSponsors.class);
        sponsorsLambdaQueryWrapper.eq(SlimeSponsors::getSponsorId, sponsorId);
        SlimeSponsors 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<SlimeAuthorizationRecords> authorizationRecordsLambdaUpdateWrapper = Wrappers.lambdaUpdate(SlimeAuthorizationRecords.class);
            authorizationRecordsLambdaUpdateWrapper
                    .eq(SlimeAuthorizationRecords::getPerformanceId, performanceId)
                    .isNull(SlimeAuthorizationRecords::getDeletedAt);
            authorizationRecordsLambdaUpdateWrapper.and(wrapper -> wrapper
                    .eq(SlimeAuthorizationRecords::getAuthorizationRecordId, authorizationRecords.getAuthorizationRecordId())
                    .or(wrapper1 -> wrapper1
                            .eq(SlimeAuthorizationRecords::getCuid, authorizationRecords.getUid())
                            .eq(SlimeAuthorizationRecords::getCuidRole, SlimeAuthorizationConst.PerformanceRole.SPONSOR.getRole()))
            );
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getUpdatedAt, authorizationRecords.getUpdatedAt());
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getDeletedAt, authorizationRecords.getDeletedAt());
            boolean success = update(authorizationRecordsLambdaUpdateWrapper);
            if (!success) {
                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(SlimeAuthorizationConst.PerformanceRole.SPONSOR.getRole())
            );
            Query query = Query.query(criteria);
            // 查询旧权限 及 旧权限角色的授权 mongo
            List<String> uids = mongoTemplate.findDistinct(query, "uid", SlimeAuthorizationRecordsVo.class.getSimpleName(), SlimeAuthorizationRecordsVo.class, String.class);
            // 删除旧权限 及 旧权限角色的授权 mongo
            mongoTemplate.remove(query, SlimeAuthorizationRecordsVo.class, SlimeAuthorizationRecordsVo.class.getSimpleName());

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

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

            // 授权记录 entity
            SlimeAuthorizationRecords sponsorAuthorizationRecords = new SlimeAuthorizationRecords();
            sponsorAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
            sponsorAuthorizationRecords.setPerformanceId(performanceId);
            sponsorAuthorizationRecords.setUidRole(SlimeAuthorizationConst.PerformanceRole.SPONSOR.getRole());
            sponsorAuthorizationRecords.setUid(sponsors.getUid());
            sponsorAuthorizationRecords.setMobile("");
            sponsorAuthorizationRecords.setName("");
            sponsorAuthorizationRecords.setCuid("");
            sponsorAuthorizationRecords.setCuidRole("");
            sponsorAuthorizationRecords.setCreatedAt(now);
            authorizationRecordsArrayList.add(sponsorAuthorizationRecords);
            // 授权权限 entity vo
            List<SlimeAuthorizationPermissionsVo> sponsorAuthorizationPermissionsVos = new ArrayList<>();
            String[] fielderPermissionIds = {
                    SlimeAuthorizationConst.PerformancePermission.READ.getId(),
                    SlimeAuthorizationConst.PerformancePermission.CHECK.getId(),
                    SlimeAuthorizationConst.PerformancePermission.SALES.getId(),
                    SlimeAuthorizationConst.PerformancePermission.GRANT.getId()
            };
            for (String permissionId : fielderPermissionIds) {
                SlimeAuthorizationPermissions sponsorAuthorizationPermissions = new SlimeAuthorizationPermissions();
                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);

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

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

            // mongo
            mongoTemplate.insert(sponsorAuthorizationRecordsVo, SlimeAuthorizationRecordsVo.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<SlimeAuthorizationRecords> authorizationRecordsLambdaQueryWrapper = Wrappers.lambdaQuery(SlimeAuthorizationRecords.class);
        authorizationRecordsLambdaQueryWrapper.eq(SlimeAuthorizationRecords::getPerformanceId, performanceId);
        authorizationRecordsLambdaQueryWrapper.eq(SlimeAuthorizationRecords::getUidRole, SlimeAuthorizationConst.PerformanceRole.FIELDER.getRole());
        authorizationRecordsLambdaQueryWrapper.isNull(SlimeAuthorizationRecords::getDeletedAt);
        SlimeAuthorizationRecords authorizationRecords = getOne(authorizationRecordsLambdaQueryWrapper);

        // 查询场地方
        LambdaQueryWrapper<SlimeFields> fieldsLambdaQueryWrapper = Wrappers.lambdaQuery(SlimeFields.class);
        fieldsLambdaQueryWrapper.eq(SlimeFields::getFieldId, fieldId);
        SlimeFields 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<SlimeAuthorizationRecords> authorizationRecordsLambdaUpdateWrapper = Wrappers.lambdaUpdate(SlimeAuthorizationRecords.class);
            authorizationRecordsLambdaUpdateWrapper
                    .eq(SlimeAuthorizationRecords::getPerformanceId, performanceId)
                    .isNull(SlimeAuthorizationRecords::getDeletedAt);
            authorizationRecordsLambdaUpdateWrapper.and(wrapper -> wrapper
                    .eq(SlimeAuthorizationRecords::getAuthorizationRecordId, authorizationRecords.getAuthorizationRecordId())
                    .or(wrapper1 -> wrapper1
                            .eq(SlimeAuthorizationRecords::getCuid, authorizationRecords.getUid())
                            .eq(SlimeAuthorizationRecords::getCuidRole, SlimeAuthorizationConst.PerformanceRole.FIELDER.getRole()))
            );
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getUpdatedAt, authorizationRecords.getUpdatedAt());
            authorizationRecordsLambdaUpdateWrapper.set(SlimeAuthorizationRecords::getDeletedAt, authorizationRecords.getDeletedAt());
            boolean success = update(authorizationRecordsLambdaUpdateWrapper);
            if (!success) {
                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(SlimeAuthorizationConst.PerformanceRole.FIELDER.getRole())
            );
            Query query = Query.query(criteria);
            // 查询旧权限 及 旧权限角色的授权 mongo
            List<String> uids = mongoTemplate.findDistinct(query, "uid", SlimeAuthorizationRecordsVo.class.getSimpleName(), SlimeAuthorizationRecordsVo.class, String.class);
            // 删除旧权限 及 旧权限角色的授权 mongo
            mongoTemplate.remove(query, SlimeAuthorizationRecordsVo.class, SlimeAuthorizationRecordsVo.class.getSimpleName());

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

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

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

            // 授权记录 entity
            SlimeAuthorizationRecords fielderAuthorizationRecords = new SlimeAuthorizationRecords();
            fielderAuthorizationRecords.setAuthorizationRecordId(IDGenerator.nextSnowId());
            fielderAuthorizationRecords.setPerformanceId(performanceId);
            fielderAuthorizationRecords.setUidRole(SlimeAuthorizationConst.PerformanceRole.FIELDER.getRole());
            fielderAuthorizationRecords.setUid(fields.getUid());
            fielderAuthorizationRecords.setMobile("");
            fielderAuthorizationRecords.setName("");
            fielderAuthorizationRecords.setCuid("");
            fielderAuthorizationRecords.setCuidRole("");
            fielderAuthorizationRecords.setCreatedAt(now);
            authorizationRecordsArrayList.add(fielderAuthorizationRecords);
            // 授权权限 entity vo
            List<SlimeAuthorizationPermissionsVo> fielderAuthorizationPermissionsVos = new ArrayList<>();
            String[] fielderPermissionIds = {
                    SlimeAuthorizationConst.PerformancePermission.READ.getId(),
                    SlimeAuthorizationConst.PerformancePermission.CHECK.getId(),
                    SlimeAuthorizationConst.PerformancePermission.GRANT.getId()
            };
            for (String permissionId : fielderPermissionIds) {
                SlimeAuthorizationPermissions fielderAuthorizationPermissions = new SlimeAuthorizationPermissions();
                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);

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

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

                    // 验票员 授权权限 entity vo
                    List<SlimeAuthorizationPermissionsVo> checkerAuthorizationPermissionsVos = new ArrayList<>();
                    for (String permissionId : checkerPermissionIds) {
                        SlimeAuthorizationPermissions checkerAuthorizationPermissions = new SlimeAuthorizationPermissions();
                        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);

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

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

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

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

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

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