package com.zhongshu.card.server.core.service.org;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.github.microservice.auth.client.content.ResultState;
import com.github.microservice.auth.client.service.OrganizationUserService;
import com.github.microservice.auth.client.service.RoleService;
import com.github.microservice.auth.security.type.AuthType;
import com.github.microservice.core.util.bean.BeanUtil;
import com.github.microservice.net.ResultContent;
import com.google.common.collect.Lists;
import com.zhongshu.card.client.model.base.ProjectOidParam;
import com.zhongshu.card.client.model.org.*;
import com.zhongshu.card.client.model.orgModel.OrgBindUserAllParam;
import com.zhongshu.card.client.model.paySetting.paySetting.OrgPayShowSettingModel;
import com.zhongshu.card.client.model.school.ExcelUserParam;
import com.zhongshu.card.client.model.school.ImportResultModel;
import com.zhongshu.card.client.model.school.RegisterBindSchoolParam;
import com.zhongshu.card.client.type.*;
import com.zhongshu.card.client.utils.DateUtils;
import com.zhongshu.card.server.core.dao.org.*;
import com.zhongshu.card.server.core.dao.school.DictInfoDao;
import com.zhongshu.card.server.core.dataConfig.CardSystemDefault;
import com.zhongshu.card.server.core.domain.org.*;
import com.zhongshu.card.server.core.domain.school.DictInfo;
import com.zhongshu.card.server.core.event.OrgUserBindUpdateSyncEvent;
import com.zhongshu.card.server.core.model.org.OrgBindUserParam;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.devices.permiss.DevicePermissEventService;
import com.zhongshu.card.server.core.service.orgManager.OrganizationManagerServiceImpl;
import com.zhongshu.card.server.core.service.paySetting.ProjectPaySettingServiceImpl;
import com.zhongshu.card.server.core.service.school.DictInfoServiceImpl;
import com.zhongshu.card.server.core.service.user.DepartmentServiceImpl;
import com.zhongshu.card.server.core.service.user.RoleServiceImpl;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import com.zhongshu.card.server.core.util.CommonUtil;
import com.zhongshu.card.server.core.util.ExcelUtils;
import com.zhongshu.card.server.core.util.excel.CommonExeclParam;
import com.zhongshu.card.server.core.util.excel.CommonExeclTd;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author TRX
 * @date 2024/9/10
 */
@Slf4j
@Service
public class OrganizationUserServiceImpl extends SuperService {

    @Autowired
    private OrganizationUserDao organizationUserDao;

    @Autowired
    private RoleServiceImpl roleServiceImpl;

    @Autowired
    private DepartmentServiceImpl departmentService;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private UserCountDao userCountDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private OrganizationManagerServiceImpl organizationManagerService;

    @Autowired
    private DictInfoDao dictInfoDao;

    @Autowired
    OrganizationUserService organizationUserService;

    @Autowired
    RoleService roleService;

    @Autowired
    UserAccountServiceImpl userAccountService;

    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    private DictInfoServiceImpl dictInfoService;

    @Autowired
    private OrganizationRelationDao organizationRelationDao;

    @Autowired
    private DevicePermissEventService devicePermissEventService;

    @Autowired
    private ProjectPaySettingServiceImpl projectPaySettingServiceImpl;

    @Autowired
    private UserInfoSyncService userInfoSyncService;

    /**
     * 添加编辑用户 添加机构用户 (包括角色 部门 职位等信息)
     * 用户可能不存在
     *
     * @param param
     * @return
     */
    public ResultContent<OrganizationUser> saveOrgUser(UserCountAddParam param) {
        String oid = param.getOid();
        if (StringUtils.isEmpty(oid)) {
            return ResultContent.buildFail("oid不能为空");
        }
        if (StringUtils.isEmpty(param.getName())) {
            return ResultContent.buildFail("name不能为空");
        }
        if (param.getState() == null) {
            param.setState(UserState.Normal);
        }

        // 机构信息
        Organization organization = organizationDao.findTopByOid(oid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format("oid不存在：%s", oid));
        }
        // 已存在的机构用户对应关系（不是项目）
        OrganizationUser temp = null;
        if (StringUtils.isNotEmpty(param.getId())) {
            temp = organizationUserDao.findTopById(param.getId());
            if (ObjectUtils.isEmpty(temp)) {
                return ResultContent.buildFail(String.format("数据不存在：%s", param.getId()));
            }
        }
        String loginName = param.getPhone();
        if (temp != null && temp.getUser() != null) {
            loginName = temp.getUser().getLoginName();
        }

        String projectOid = param.getProjectOid();
        Organization projectInfo = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(projectInfo)) {
            return ResultContent.buildFail("项目不存在");
        }
        if (projectInfo.getAuthType() != AuthType.Project) {
            return ResultContent.buildFail("projectOid机构类型不属于项目，请检查参数");
        }
        // 判断是否存在
        UserAccount userAccount = userCountDao.findTopByLoginName(loginName);

        if (ObjectUtils.isNotEmpty(userAccount)) {
            // 判断是否存在
            OrganizationUser tempOrgUser = organizationUserDao.findTopByUserAndProjectOidAndIsOrg(userAccount, projectOid, Boolean.TRUE);
            if (ObjectUtils.isNotEmpty(tempOrgUser)) {
                if (ObjectUtils.isEmpty(temp) || !temp.getId().equals(tempOrgUser.getId())) {
                    return ResultContent.buildFail(String.format("用户已加入该项目：%s", loginName));
                }
            }
        }

        // 用户基本信息维护 电话号码为登录名
        RegisterUserAccountParam userAccountParam = new RegisterUserAccountParam();
        userAccountParam.setLoginName(loginName);
        userAccountParam.setPassword(param.getPassWord());
        userAccountParam.setPhone(param.getPhone());
        userAccountParam.setName(param.getName());
        userAccountParam.setCardNumber(param.getCardNumber());
        userAccountParam.setSex(param.getSex());
        userAccountParam.setProfilePic(param.getProfilePic());
        ResultContent<String> userAccountContent = userAccountService.registerUserAccount(userAccountParam);
        if (userAccountContent.isFailed()) {
            return ResultContent.buildFail(userAccountContent.getMsg());
        }
        String userId = userAccountContent.getContent();

        OrgBindUserAllParam orgBindUserAllParam = new OrgBindUserAllParam();
        orgBindUserAllParam.setId(param.getId());
        orgBindUserAllParam.setUserId(userId);
        // 要绑定的机构
        orgBindUserAllParam.setOrgOid(organization.getOid());
        orgBindUserAllParam.setCode(param.getCode());
        orgBindUserAllParam.setPositionId(param.getPositionId());
        orgBindUserAllParam.setDepartmentId(param.getDepartmentId());
        orgBindUserAllParam.setRoleIds(param.getRoleIds());
        orgBindUserAllParam.setState(param.getState());
        orgBindUserAllParam.setIsAdmin(param.getIsAdmin());
        orgBindUserAllParam.setRemark(param.getRemark());
        orgBindUserAllParam.setProjectOid(param.getProjectOid());

        // 绑定用户到机构
        ResultContent<OrganizationUser> bindUserContent = orgBindUser(orgBindUserAllParam);
        if (bindUserContent.isFailed()) {
            return ResultContent.buildFail(bindUserContent.getMsg());
        }
        OrganizationUser organizationUser = bindUserContent.getContent();

        return ResultContent.buildSuccess(organizationUser);
    }

    /**
     * 机构绑定用户 （角色、部门、职位都以新的为准）
     * 用户基本信息已存在
     *
     * @param param
     * @return
     */
    @Transactional
    public ResultContent<OrganizationUser> orgBindUser(OrgBindUserAllParam param) {
        // 检查数据完整性
        if (StringUtils.isEmpty(param.getUserId())) {
            return ResultContent.buildFail("userId不能为空");
        }
        if (StringUtils.isEmpty(param.getOrgOid())) {
            return ResultContent.buildFail("orgOid不能为空");
        }

        UserAccount userAccount = userCountDao.findTopByUserId(param.getUserId());
        if (ObjectUtils.isEmpty(userAccount)) {
            return ResultContent.buildFail(String.format("用户信息不存在：%s", param.getUserId()));
        }
        String projectOid = param.getProjectOid();
        boolean isUpdate = false;

        // 要绑定的机构 (不是项目)
        Organization organization = organizationDao.findTopByOid(param.getOrgOid());
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format("机构信息不存在：%s", param.getOrgOid()));
        }
        String userId = userAccount.getUserId();
        OidAboutInfo oidAboutInfo = organizationManagerService.getOidAboutInfo(organization.getOid());

        OrganizationUser codeTemp = null;
        if (StringUtils.isNotEmpty(param.getCode())) {
            // code 在整个项目部重复
            codeTemp = organizationUserDao.findTopByCodeAndProjectOid(param.getCode(), projectOid);
        }
        OrganizationUser organizationUser = null;
        if (StringUtils.isNotEmpty(param.getId())) {
            organizationUser = organizationUserDao.findTopById(param.getId());
            if (ObjectUtils.isEmpty(organizationUser)) {
                return ResultContent.buildFail(String.format("数据不存在：%s", param.getId()));
            }
            if (StringUtils.isEmpty(projectOid)) {
                projectOid = organizationUser.getProjectOid();
            }
        } else {
            organizationUser = organizationUserDao.findTopByOrganizationAndUserAndProjectOid(organization, userAccount, projectOid);
        }

        if (ObjectUtils.isEmpty(organizationUser)) {
            // 添加
            if (ObjectUtils.isNotEmpty(codeTemp)) {
                return ResultContent.buildFail(String.format("code已存在：%s", param.getCode()));
            }
            organizationUser = new OrganizationUser();
            initEntity(organizationUser);
            BeanUtils.copyProperties(param, organizationUser);
            // 在机构中的用户类型
            organizationUser.setUserType(OrganizationUserType.Consumer);
        } else {
            if (ObjectUtils.isNotEmpty(codeTemp) && !codeTemp.getId().equals(organizationUser.getId())) {
                return ResultContent.buildFail(String.format("code已存在：%s", param.getCode()));
            }
            isUpdate = true;
            // 编辑
            BeanUtils.copyProperties(param, organizationUser, "id");

            // 删除以前的角色
            List<Role> oldRoles = organizationUser.getRoles();
            roleServiceImpl.userRemoveRole(userId, oldRoles);
        }

        organizationUser.setOid(organization.getOid());
        organizationUser.setOrganization(organization);
        organizationUser.setUser(userAccount);
        organizationUser.setUserId(userAccount.getUserId());
        organizationUser.setCreateUserId(getCurrentUserId());
        organizationUser.setSex(userAccount.getSex());

        List<Role> roles = new ArrayList<>();
        Department department = null;
        if (ObjectUtils.isNotEmpty(param.getRoleIds())) {
            roles = roleDao.findByIdIn(param.getRoleIds());
        }
        if (ObjectUtils.isNotEmpty(param.getDepartmentId())) {
            department = departmentDao.findTopById(param.getDepartmentId());
        }
        DictInfo position = null;
        if (StringUtils.isNotEmpty(param.getPositionId())) {
            position = dictInfoDao.findTopById(param.getPositionId());
        }

        if (organization.getAuthType() == AuthType.Platform) {
            // 判断是否是超级管理员
            if (userAccount.getUserType() == UserType.SuperAdmin) {
                List<Role> tempList = roleServiceImpl.getOrgAdminRoles(organization.getOid());
                roles.addAll(tempList);
            }
        }
        roles = roles.stream().distinct().collect(Collectors.toList());

        if (ObjectUtils.isNotEmpty(roles)) {
            //权限中心： 在角色组添加用户
            roleServiceImpl.userBindRoles(userId, roles);
        }

        organizationUser.setPosition(position);
        // 设置角色
        organizationUser.setRoles(roles);
        organizationUser.setRoleIds(roles.stream().map(Role::getId).collect(Collectors.toList()));
        // 设置部门
        organizationUser.setDepartment(department);

        organizationUser.setProjectOid(projectOid);
        organizationUser.setAboutOid(oidAboutInfo.getOid());
        organizationUser.setAboutAuthType(oidAboutInfo.getAuthType());
        organizationUser.setAuthType(organization.getAuthType());
        if (StringUtils.isNotEmpty(param.getProjectOid())) {
            organizationUser.setProjectOid(param.getProjectOid());
        }
        // 用户信息
        organizationUser.setPhone(userAccount.getPhone());
        organizationUser.setName(userAccount.getName());
        organizationUser.setCardNumber(userAccount.getCardNumber());
        organizationUser.setOid(param.getOrgOid());
        if (organization.getAuthType() == AuthType.Project || organization.getAuthType() == AuthType.Platform) {
            organizationUser.setIsOrg(Boolean.FALSE);
        } else {
            organizationUser.setIsOrg(Boolean.TRUE);
        }
        organizationUserDao.save(organizationUser);

        // 发送用户信息变更事件，用以下发用户 权限关联的用户信息
        // DevicePermissService.syncOrgUserChangeInfo
        if (isUpdate) {
            OrgUserBindUpdateSyncEvent event = new OrgUserBindUpdateSyncEvent(this, List.of(organizationUser.getId()), DataOperationType.Update);
            applicationContext.publishEvent(event);
        }

        // 权限中心 绑定用户
        com.github.microservice.auth.client.content.ResultContent<Void> resultContent = organizationUserService.update(organization.getOid(), new String[]{userId});
        if (resultContent.getState() == ResultState.Success) {
            log.info("权限中心：绑定机构和用户关系成功");
        } else {
            log.error("权限中心：绑定机构和用户关系出错：{}", resultContent.getMsg());
        }
        userInfoSyncService.updateProjectAboutInfoByOrgUserDataId(organizationUser.getId());
        return ResultContent.buildSuccess(organizationUser);
    }

    /**
     * 绑定机构管理员 （已新的为准，以前的删除掉）
     *
     * @param organization
     * @param userAccounts
     * @return
     */
    public ResultContent orgBindManager(Organization organization, List<UserAccount> userAccounts) {
        List<OrganizationUser> oldList = organizationUserDao.findByOrganizationAndIsAdmin(organization, Boolean.TRUE);

        List<String> newIds = new ArrayList<>();
        // 得到项目的管理员角色
        List<Role> adminRole = roleServiceImpl.getOrgAdminRoles(organization.getOid());
        for (UserAccount userAccount : userAccounts) {
            OrgBindUserParam _param = new OrgBindUserParam();
            _param.setOrganization(organization);
            _param.setUserAccount(userAccount);
            _param.setIsAdmin(Boolean.TRUE);
            _param.setRoleIds(adminRole.stream().map(it -> it.getId()).collect(Collectors.toList()));
            _param.setProjectOid(organization.getOid());
            OrganizationUser temp = buildProjectManagerUserInfo(_param);
            if (temp != null) {
                newIds.add(temp.getId());
            }
        }
        if (ObjectUtils.isNotEmpty(oldList)) {
            List<OrganizationUser> _tempList = oldList.stream().filter(it -> {
                return !newIds.contains(it.getId());
            }).collect(Collectors.toList());

            if (ObjectUtils.isNotEmpty(_tempList)) {
                organizationUserDao.deleteAll(_tempList);
            }
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 得到用户所在的机构简单数据
     *
     * @param userAccount
     * @param authType
     * @return
     */
    public List<OrganizationUserSimpleModel> getUserOrgans(UserAccount userAccount, AuthType authType) {
        List<OrganizationUserSimpleModel> models = new ArrayList<>();
        if (userAccount != null && authType != null) {
            List<OrganizationUser> list = organizationUserDao.findByUserAndAuthType(userAccount, authType);
            if (ObjectUtils.isNotEmpty(list)) {
                models = list.stream().map(this::toModel).collect(Collectors.toList());
            }
        }
        return models;
    }

    /**
     * 项目的管理员绑定到项目中
     *
     * @param param
     * @return
     */
    private OrganizationUser buildProjectManagerUserInfo(OrgBindUserParam param) {
        Organization organization = param.getOrganization();
        UserAccount userAccount = param.getUserAccount();
        Boolean isAdmin = param.getIsAdmin();

        OrganizationUser organizationUser = null;
        if (ObjectUtils.isNotEmpty(userAccount) && ObjectUtils.isNotEmpty(organization)) {
            organizationUser = organizationUserDao.findTopByOrganizationAndUser(organization, userAccount);
            List<Role> roles = new ArrayList<>();
            if (ObjectUtils.isEmpty(organizationUser)) {
                organizationUser = new OrganizationUser();
                organizationUser.setState(UserState.Normal);
                organizationUser.setCode("");
                initEntityNoCheckOid(organizationUser);
            } else {
                if (ObjectUtils.isNotEmpty(organizationUser.getRoles())) {
                    roles = organizationUser.getRoles();
                }
                initUpdateEntity(organizationUser);
            }
            if (ObjectUtils.isNotEmpty(param.getRoleIds())) {
                roles.addAll(roleDao.findByIdIn(param.getRoleIds()));
            }
            organizationUser.setUser(userAccount);
            organizationUser.setName(userAccount.getName());
            organizationUser.setPhone(userAccount.getPhone());
            organizationUser.setUserId(userAccount.getUserId());

            organizationUser.setOrganization(organization);
            organizationUser.setOid(organization.getOid());
            organizationUser.setAuthType(organization.getAuthType());
            organizationUser.setIsAdmin(isAdmin);

            organizationUser.setAboutOid(organization.getOid());
            organizationUser.setProjectOid(param.getProjectOid());
            if (ObjectUtils.isNotEmpty(roles)) {
                roles = roles.stream().distinct().collect(Collectors.toUnmodifiableList());
            }
            organizationUser.setRoles(roles);
            if (organization.getAuthType() == AuthType.Platform || organization.getAuthType() == AuthType.Project) {
                organizationUser.setIsOrg(Boolean.FALSE);
            } else {
                organizationUser.setIsOrg(Boolean.TRUE);
            }
            organizationUserDao.save(organizationUser);

            // 绑定角色
            roleServiceImpl.userBindRoles(organizationUser.getUserId(), roles);
        }
        return organizationUser;
    }

    /**
     * 绑定用户到机构
     *
     * @param param
     * @return
     */
    public ResultContent bindUser2School(RegisterBindSchoolParam param) {
        UserAccount userAccount = userCountDao.findTopByUserId(param.getUserId());
        if (ObjectUtils.isEmpty(userAccount)) {
            return ResultContent.buildFail(String.format("用户不存在：%s", param.getUserId()));
        }
        Organization organization = organizationDao.findTopByOid(param.getOid());
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format("机构不存在：%s", param.getOid()));
        }

        OrganizationUser schoolUser = organizationUserDao.findTopByOrganizationAndUser(organization, userAccount);
        if (ObjectUtils.isEmpty(schoolUser)) {
            OrganizationUser temp = organizationUserDao.findTopByCodeAndOrganization(param.getCode(), organization);
            if (ObjectUtils.isNotEmpty(temp)) {
                return ResultContent.buildFail(String.format("学号/工号已存在：%s", param.getCode()));
            }

            schoolUser = new OrganizationUser();
            schoolUser.setOrganization(organization);
            schoolUser.setUserId(param.getUserId());
            schoolUser.setUser(userAccount);
            schoolUser.setState(UserState.Normal);
            schoolUser.setCode(param.getCode());
            schoolUser.setPhone(userAccount.getPhone());
            schoolUser.setName(userAccount.getName());
            schoolUser.setUserType(OrganizationUserType.Consumer);
            schoolUser.setCertificateType(userAccount.getCertificateType());
            schoolUser.setCardNumber(userAccount.getCardNumber());
            schoolUser.setAuthType(organization.getAuthType());

            List<Role> roles = new ArrayList<>();
            Department department = null;
            if (ObjectUtils.isNotEmpty(param.getRoleIds())) {
                roles = roleDao.findByOidAndIdIn(organization.getOid(), param.getRoleIds());
            }
            if (ObjectUtils.isNotEmpty(param.getDepartmentId())) {
                department = departmentDao.findTopById(param.getDepartmentId());
            }
            schoolUser.setRoles(roles);
            schoolUser.setDepartment(department);
            organizationUserDao.save(schoolUser);
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 删除机构用户
     *
     * @param id
     * @return
     */
    public ResultContent deleteOrgUser(String id) {
        OrganizationUser organizationUser = organizationUserDao.findTopById(id);
        if (ObjectUtils.isNotEmpty(organizationUser)) {
            organizationUserDao.delete(organizationUser);
            OrgUserBindUpdateSyncEvent event = new OrgUserBindUpdateSyncEvent(this, List.of(id), DataOperationType.Delete);
            applicationContext.publishEvent(event);
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 得到当前用户在项目加入的机构
     *
     * @param projectOid
     * @return
     */
    public ResultContent getCurrentOrgs(String projectOid) {
        List<OrganizationAboutPayChannelModel> models = new ArrayList<>();
        String userId = getCurrentUserId();
        List<OrganizationUser> list = getUserOrgList(userId, projectOid);
        if (ObjectUtils.isNotEmpty(list)) {
            // 项目的支付渠道
            List<OrgPayShowSettingModel> payChannels = projectPaySettingServiceImpl.getProjectEnablePay(projectOid);

            models = list.stream().map(it -> {
                OrganizationAboutPayChannelModel model = new OrganizationAboutPayChannelModel();
                BeanUtils.copyProperties(it.getOrganization(), model);
                model.setPayChannels(payChannels);
                return model;
            }).collect(Collectors.toUnmodifiableList());
        }
        return ResultContent.buildSuccess(models);
    }

    /**
     * 查询用户在项目中的 绑定的机构数据列表
     *
     * @param userId
     * @param projectOid
     * @return
     */
    public List<OrganizationUser> getUserOrgList(String userId, String projectOid) {
        return organizationUserDao.findByUserIdAndProjectOidAndIsOrg(userId, projectOid, Boolean.TRUE);
    }

    /**
     * 用户所在项目下 所有机构oid
     *
     * @param userId
     * @param projectOid
     * @return
     */
    public List<String> getUserOrgListOids(String userId, String projectOid) {
        if (StringUtils.isNotEmpty(projectOid) && StringUtils.isNotEmpty(userId)) {
            List<OrganizationUser> _list = getUserOrgList(userId, projectOid);
            if (ObjectUtils.isNotEmpty(_list)) {
                return _list.stream().map(it -> {
                    return it.getOrganization().getOid();
                }).collect(Collectors.toList());
            }
        }
        return Lists.newArrayList();
    }

    /**
     * 导入 学校用户excel
     *
     * @param request
     * @param response
     * @param file
     * @return
     */
    public ResultContent<ImportResultModel> importSchoolUsers(HttpServletRequest request, HttpServletResponse response, MultipartFile file, ProjectOidParam proParam) {
        String projectOid = proParam.getProjectOid();
        Assert.hasText(projectOid, "projectOid不能为空");

        ImportResultModel model = new ImportResultModel();
        try {
            int startRow = 2;
            ImportParams params = new ImportParams();
            params.setHeadRows(1);
            params.setTitleRows(1);
            List<ExcelUserParam> list = ExcelImportUtil.importExcel(file.getInputStream(), ExcelUserParam.class, params);
            model.setTotal(list.size());

            List<String> failDetails = new ArrayList<>();
            List<UserCountAddParam> userList = new ArrayList<>();

            HashMap<String, String> name2Id = new HashMap<>();
            HashMap<String, List<String>> role2Id = new HashMap<>();
            HashMap<String, String> pos2Id = new HashMap<>();
            Organization projectInfo = organizationDao.findTopByOid(projectOid);

            if (ObjectUtils.isNotEmpty(list)) {
                for (ExcelUserParam excelUserParam : list) {
                    startRow++;

                    // 验证数据合法性
                    boolean b = true;
                    if (StringUtils.isEmpty(excelUserParam.getName())) {
                        failDetails.add(String.format("第%d行名称不能为空", startRow));
                        continue;
                    }
                    if (StringUtils.isEmpty(excelUserParam.getCode())) {
                        failDetails.add(String.format("第%d行编码不能为空", startRow));
                        continue;
                    }
                    if (StringUtils.isEmpty(excelUserParam.getPhone())) {
                        failDetails.add(String.format("第%d行电话不能为空", startRow));
                        continue;
                    }

                    if (StringUtils.isEmpty(excelUserParam.getCardNumber())) {
                        failDetails.add(String.format("第%d行身份证号不能为空", startRow));
                        continue;
                    } else if (excelUserParam.getCardNumber().length() != 18) {
                        failDetails.add(String.format("第%d行身份证号格式不正确", startRow));
                        continue;
                    }

                    // 验证通过
                    UserCountAddParam addParam = new UserCountAddParam();
                    String beLongOid = "";

                    // 验证机构信息
                    String orgName = excelUserParam.getOrgName();
                    if (StringUtils.isEmpty(orgName)) {
                        failDetails.add(String.format("第%d行机构信息不能为空", startRow));
                        continue;
                    }
                    orgName = orgName.trim();
                    if (name2Id.containsKey(orgName)) {
                        beLongOid = name2Id.get(orgName);
                    } else {
                        Organization organization = organizationDao.findTopByName(orgName);
                        if (ObjectUtils.isEmpty(organization)) {
                            failDetails.add(String.format("%s 机构信息不存在", orgName));
                            continue;
                        }
                        OrganizationRelation relation = organizationRelationDao.findTopByMainOrganizationAndRelOrganizationAndRelationType(projectInfo, organization, OrganizationRelationType.ProjectBindOrg);
                        if (ObjectUtils.isEmpty(relation)) {
                            failDetails.add(String.format("%s 机构信息未加入到项目中", orgName));
                            continue;
                        }
                        beLongOid = organization.getOid();
                        name2Id.put(orgName, organization.getOid());
                    }

                    // 部门
                    if (StringUtils.isNotEmpty(excelUserParam.getDepartmentName())) {
                        if (name2Id.containsKey(excelUserParam.getDepartmentName())) {
                            addParam.setDepartmentId(name2Id.get(excelUserParam.getDepartmentName()));
                        } else {
                            Department department = departmentService.getProjectDepartmentByName(projectOid, excelUserParam.getDepartmentName());
                            if (ObjectUtils.isNotEmpty(department)) {
                                addParam.setDepartmentId(department.getId());
                                name2Id.put(excelUserParam.getDepartmentName(), department.getId());
                            }
                        }
                    }

                    // 角色
                    if (StringUtils.isNotEmpty(excelUserParam.getRoleName())) {
                        if (role2Id.containsKey(excelUserParam.getRoleName())) {
                            addParam.setRoleIds(role2Id.get(excelUserParam.getRoleName()));
                        } else {
                            List<Role> roles = roleServiceImpl.getProjectRoleByName(projectOid, excelUserParam.getRoleName());
                            if (ObjectUtils.isNotEmpty(roles)) {
                                addParam.setRoleIds(roles.stream().map(it -> it.getId()).collect(Collectors.toList()));
                                role2Id.put(excelUserParam.getRoleName(), addParam.getRoleIds());
                            }
                        }
                    }

                    // 职位
                    if (StringUtils.isNotEmpty(excelUserParam.getPositionName())) {
                        if (pos2Id.containsKey(excelUserParam.getPositionName())) {
                            addParam.setPositionId(pos2Id.get(excelUserParam.getPositionName()));
                        } else {
                            DictInfo dictInfo = dictInfoService.getProjectDictByName(projectOid, DictInfoType.Position, excelUserParam.getPositionName());
                            if (ObjectUtils.isNotEmpty(dictInfo)) {
                                addParam.setPositionId(dictInfo.getId());
                                pos2Id.put(excelUserParam.getPositionName(), dictInfo.getId());
                            }
                        }
                    }

                    if (b) {
                        addParam.setProjectOid(projectOid);
                        addParam.setOid(beLongOid);

                        com.zhongshu.card.server.core.util.BeanUtils.copyProperties(excelUserParam, addParam);
                        if (StringUtils.isNotBlank(excelUserParam.getSexStr())) {
                            addParam.setSex(CommonUtil.getSexByStr(excelUserParam.getSexStr()));
                        }
                        String passWord = CardSystemDefault.DEFAULT_PASSWORD;
                        if (StringUtils.isNotEmpty(excelUserParam.getCardNumber())) {
                            excelUserParam.getCardNumber().substring(12, 18);
                            passWord = passWord.toLowerCase().replace("x", "0");
                        }
                        addParam.setPassWord(passWord);
                        userList.add(addParam);
                    }
                }

                // 添加到对应的机构中
                for (UserCountAddParam param : userList) {
                    ResultContent resultContent = saveOrgUser(param);
                    log.info("添加日志： {}", resultContent.getMsg());
                }
                model.setSuccess(userList.size());
                model.setFailDetails(failDetails);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultContent.buildFail(String.format("导入出错：%s", e.getMessage()));
        }
        return ResultContent.buildSuccess(model);
    }

    /**
     * 导出项目用户
     *
     * @param request
     * @param response
     * @param param
     */
    public void exportProjectUser(HttpServletRequest request, HttpServletResponse response, OrganizationUserSearch param) {
        param.setIsSearchProject(Boolean.TRUE);
        Assert.hasText(param.getProjectOid(), "projectOid不能为空");

        Organization organization = organizationDao.findTopByOid(param.getProjectOid());
        Pageable pageable = PageRequest.of(0, Integer.MAX_VALUE);
        Page<OrganizationUser> page = organizationUserDao.page(pageable, param);

        List<Map<String, Object>> maps = new ArrayList<>();
        if (page.getContent() != null) {
            List<OrganizationUser> list = page.getContent();
            maps = list.stream().map(it -> {
                Map<String, Object> map = BeanUtil.bean2Map(it);
                String sex = "";
                UserAccount userAccount = it.getUser();
                if (userAccount != null && it.getUser().getSex() != null) {
                    sex = it.getUser().getSex().getRemark();
                }
                map.put("sexStr", sex);

                Organization organization1 = it.getOrganization();
                if (ObjectUtils.isNotEmpty(organization1)) {
                    map.put("orgName", organization1.getName());
                }

                String departmentName = "";
                if (it.getDepartment() != null) {
                    departmentName = it.getDepartment().getName();
                }
                map.put("departmentName", departmentName);
                String roleNames = "";
                if (ObjectUtils.isNotEmpty(it.getRoles())) {
                    roleNames = it.getRoles().stream().map(it1 -> it1.getName()).collect(Collectors.joining("、"));
                }
                map.put("roleNames", roleNames);

                String positionName = "";
                if (ObjectUtils.isNotEmpty(it.getPosition())) {
                    DictInfo dictInfo = dictInfoService.getEntity(it.getPosition().getId());
                    if (ObjectUtils.isNotEmpty(dictInfo)) {
                        positionName = dictInfo.getName();
                    }
                }
                map.put("positionName", positionName);

                if (it.getState() != null) {
                    map.put("stateStr", it.getState().getRemark());
                }
                map.put("createTime", DateUtils.paresTime(it.getCreateTime(), DateUtils.FORMAT_LONG));
                return map;
            }).collect(Collectors.toList());
        }
        CommonExeclParam execlParam = new CommonExeclParam();
        execlParam.setTitle(String.format("%s用户列表", organization.getName()));
        execlParam.setStartRow(2);
        execlParam.setDatas(maps);

        List<CommonExeclTd> tds = new ArrayList<>();
        tds.add(CommonExeclTd.build("人员编码", "code"));
        tds.add(CommonExeclTd.build("姓名", "name"));
        tds.add(CommonExeclTd.build("性别", "sexStr"));
        tds.add(CommonExeclTd.build("手机号", "phone"));
        tds.add(CommonExeclTd.build("身份证号", "cardNumber"));

        tds.add(CommonExeclTd.build("机构", "orgName"));
        tds.add(CommonExeclTd.build("部门", "departmentName"));
        tds.add(CommonExeclTd.build("人员类型", "roleNames"));
        tds.add(CommonExeclTd.build("职位", "positionName"));
        tds.add(CommonExeclTd.build("状态", "stateStr"));
        tds.add(CommonExeclTd.build("创建时间", "createTime"));

        tds.add(CommonExeclTd.build("备注", "remark"));

        execlParam.setTds(tds);
        ExcelUtils.commonExecuteExcel(request, response, execlParam);
    }

    /**
     * 用户基础信息发送变化
     *
     * @param userId
     */
    public void changeUserBaseInfo(String userId, String projectOid) {
        if (StringUtils.isEmpty(userId)) {
            CompletableFuture.runAsync(() -> {
                List<String> projectOids = new ArrayList<>();
                if (StringUtils.isEmpty(projectOid)) {
                    List<OrganizationUser> list = organizationUserDao.findByUserId(userId);
                    if (ObjectUtils.isNotEmpty(list)) {
                        projectOids = list.stream().map(OrganizationUser::getProjectOid).distinct().collect(Collectors.toList());
                    }
                } else {
                    projectOids.add(projectOid);
                }
                try {
                    List<String> userIds = List.of(userId);
                    for (String _projectOid : projectOids) {
                        devicePermissEventService.sendUserInfoChangeEvent(userIds, _projectOid, "changeUserBaseInfo");
                        TimeUnit.SECONDS.sleep(1);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            });
        }
    }

    /**
     * 转换机构用户信息（基本信息 角色  部门）
     *
     * @param entity
     * @return
     */
    public OrganizationUserSimpleModel toModel(OrganizationUser entity) {
        OrganizationUserSimpleModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new OrganizationUserSimpleModel();

            model.setId(entity.getId());
            model.setCode(entity.getCode());
            Organization organization = entity.getOrganization();
            model.setOid(organization.getOid());
            model.setOrgName(organization.getName());

            // 角色
            model.setRoles(roleServiceImpl.toModels(entity.getRoles()));

            // 部门信息
            if (ObjectUtils.isNotEmpty(entity.getDepartment())) {
                DepartmentModel departmentModel = departmentService.toModel(entity.getDepartment());
                model.setDepartment(departmentModel);
                List<DepartmentModel> departmentModels = departmentService.getParents(entity.getDepartment().getId());
                model.setDepartments(departmentModels);
            }
        }
        return model;
    }

}
