package com.nbclass.szxgl.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nbclass.exception.ParameterException;
import com.nbclass.exception.ServiceException;
import com.nbclass.holder.SpringContextHolder;
import com.nbclass.system.mapper.UserMapper;
import com.nbclass.system.model.User;
import com.nbclass.szxgl.constant.ActivityConstants;
import com.nbclass.szxgl.mapper.*;
import com.nbclass.szxgl.model.*;
import com.nbclass.szxgl.service.ProjectClientService;
import com.nbclass.szxgl.service.ProjectService;
import com.nbclass.util.CommonUtils;
import com.nbclass.util.DateUtil;
import com.nbclass.util.UUIDUtil;
import com.nbclass.util.Utility;
import com.nbclass.wxwork.msg.SendMsgUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.*;

@Service
public class ProjectServiceImpl implements ProjectService {
    private static final Logger logger = LoggerFactory.getLogger(ProjectServiceImpl.class);

    @Resource
    private ProjectMapper mapper;

    @Resource
    private ProjectFilesMapper projectFilesMapper;

    @Resource
    private ProjectUserMapper projectUserMapper;

    @Resource
    private ProjectTaskMapper projectTaskMapper;

    @Resource
    private ProjectTaskUserMapper projectTaskUserMapper;

    @Resource
    private ProjectTaskJournalMapper journalMapper;
    @Resource
    private ListTypeMapper listTypeMapper;
    @Resource
    private QywxUserMapper qywxUserMapper;
    @Resource
    private QywxPartyMapper qywxPartyMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    SyUsersMapper syUsersMapper;
    @Resource
    PerMsgMapper perMsgMapper;
    @Resource
    ProjectCityMapper projectCityMapper;
    @Resource
    ProjectClientService projectClientService;


    @Override
    public boolean hasUpdateProject(String pid) {
        Project p = mapper.findById(pid);
        if (p == null) {
            return false;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        if (user == null) {
            return false;
        }
        // 项目创建者 或者 管理员
        if (p.getCreateUserId().equals(user.getUsername()) || ActivityConstants.isAdmin(user.getUsername())) {
            return true;
        }
        // 项目负责人
        Integer count = projectUserMapper.selectProjectUser(pid, user.getUsername());
        if (count != null && count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean hasPowerForFile(String pid) {
        Project p = mapper.findById(pid);
        if (p == null) {
            return false;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        if (user == null) {
            return false;
        }
        // 项目创建者 或者 管理员
        if (user != null && p.getCreateUserId().equals(user.getUsername()) || ActivityConstants.isAdmin(user.getUsername())) {
            return true;
        }
        // 项目负责人
        Integer count = projectUserMapper.selectProjectUser(pid, user.getUsername());
        if (count != null && count > 0) {
            return true;
        }
        // 项目任务执行人
        count = projectTaskUserMapper.selectProjectTaskUser(pid, user.getUsername());
        if (count != null && count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean hasPowerForTask(String pid) {
        Project p = mapper.findById(pid);
//		logger.info("查询项目信息："+JSON.toJSONString(p));
        if (p == null) {
            return false;
        }
        if (p.getStatus() == 0 || p.getStatus() == 3) {
            return false; // 项目状态为作废状态或结束状态
        }

        User user = (User) SecurityUtils.getSubject().getPrincipal();
//		logger.info("查询用户信息："+JSON.toJSONString(user));
        if (user == null) {
            return false;
        }
        // 项目创建者
        if (p.getCreateUserId().equals(user.getUsername())) {
            return true;
        }
        // 项目负责人
        Integer count = projectUserMapper.selectProjectUser(pid, user.getUsername());
        if (count != null && count > 0) {
            return true;
        }
        return false;
    }

    @Override
    public List<Project> getList(Project project) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        if (user == null && SpringContextHolder.isProd()) {
            throw new ParameterException("登录失效，请重新登录!");
        }
        if (user != null) {
            String isAdmin = ActivityConstants.isAdmin(user.getUsername()) ? "Y" : "N";
            project.setIsAdmin(isAdmin);
            project.setLoginName(user.getUsername());
        }
        if (user == null && !SpringContextHolder.isProd()) project.setIsAdmin("Y"); // 测试默认用管理员权限查询

        return mapper.getList(project);
    }

    @Override
    public List<String> selectUserIdsByDeptId(String deptId) {
        if (StringUtils.isBlank(deptId))
            return null;
        String deptIds = mapper.queryDeptIdsByDeptId(deptId); // 递归查询所有子部门id
        if (StringUtils.isBlank(deptIds))
            return null;
        List<Integer> deptIdList = CommonUtils.toIntList(deptIds);
        String strUserIds = mapper.queryUserIdsByDeptIds(deptIdList); // 根据部门id查询用户id
        if (StringUtils.isBlank(strUserIds))
            return null;
        List<String> list = Arrays.asList(strUserIds.split(","));
        return list;
    }

    @Override
    public JSONObject findById(String pid) {
        if (StringUtils.isBlank(pid)) {
            throw new ParameterException("参数不能为空");
        }
        Project project = mapper.findById(pid);
        if (project == null) {
            throw new ParameterException("记录不存在或已被删除");
        }

        User user = (User) SecurityUtils.getSubject().getPrincipal(); //上线时放开
        if (user == null) {
            throw new ServiceException("登陆失败，请重新登陆！");
        }

        List<String> fzrIds = StringUtils.isNotBlank(project.getFzrIds()) ? Arrays.asList(project.getFzrIds().split(",")) : new ArrayList<>();
        List<String> csrIds = StringUtils.isNotBlank(project.getCsrIds()) ? Arrays.asList(project.getCsrIds().split(",")) : new ArrayList<>();

        boolean allowModify = (project != null && project.getStatus() != null && project.getStatus() != 0); // 0为作废状态，不给修改
        if (allowModify)
            allowModify = StringUtils.equals(user.getUsername(), project.getCreateUserId()) || fzrIds.contains(user.getUsername());
        project.setAllowModify(allowModify); // 是否有修改权限

        List<Map<String, Object>> fzrMap = qywxUserMapper.getUserInfoByUserIds(fzrIds);
        List<Map<String, Object>> csrMap = qywxUserMapper.getUserInfoByUserIds(csrIds);
        JSONObject obj = new JSONObject();
        obj.put("fzrData", fzrMap); // 负责人数据
        obj.put("csrData", csrMap); // 抄送人数据
        obj.put("project", project); // 项目详情
        List<ProjectFiles> list = projectFilesMapper.getList(pid);
        obj.put("fileList", list);
        return obj;
    }

    @Override
    public List<ProjectFiles> getFileList(String pid) {
        if (StringUtils.isBlank(pid)) {
            throw new ParameterException("参数不能为空");
        }
        return projectFilesMapper.getList(pid);
    }

    @Override
    public List<ProjectTask> getTaskList(String pid) {
        if (StringUtils.isBlank(pid)) {
            throw new ParameterException("参数不能为空");
        }
        return projectTaskMapper.getList(pid);
    }

    @Override
    public List<ProjectTaskJournal> getTaskJournalList(String taskId) {
        if (StringUtils.isBlank(taskId)) {
            throw new ParameterException("参数[taskId]不能为空");
        }
        return journalMapper.getList(taskId);
    }

    @Override
    public List<ListType> getListValues(String listType) {
        if (StringUtils.isBlank(listType)) {
            throw new ParameterException("参数[listType]不能为空");
        }
        return listTypeMapper.getList(listType);
    }

    /**
     * 添加项目
     *
     * @param p         项目
     * @param isSendMsg
     * @param deptIds
     * @return
     */
    @Transactional
    public String addProject(Project p, Integer isSendMsg, String[] deptIds, List<ProjectFiles> filesList) {
        if (p.getStartTime().getTime() > p.getPlanTime().getTime()) {
            throw new ParameterException("项目时间范围不对！");
        }

        String[] fzrIds = null, csrIds = null;
        if (StringUtils.isNotBlank(p.getFzrIds())) fzrIds = p.getFzrIds().split(",");
        if (StringUtils.isNotBlank(p.getCsrIds())) csrIds = p.getCsrIds().split(",");

        if (fzrIds == null || fzrIds.length == 0) {
            throw new ParameterException("请选择项目负责人！");
        }

        if (deptIds == null)
            deptIds = new String[]{};
        if (csrIds == null)
            csrIds = new String[]{};
        User user = (User) SecurityUtils.getSubject().getPrincipal(); //上线时放开
        if (user == null) {
            throw new ServiceException("登陆失败，请重新登陆！");
        }
        p.setId(UUIDUtil.uuid());
        p.setCreateUserId(user.getUsername());
        p.setNotify((short) 0);
        p.setCreateTime(DateUtil.currentTimestamp());
        p.setUpdateTime(DateUtil.currentTimestamp());
        mapper.insert(p);
        // 等待保存的对象集合
        List<ProjectUser> c = new ArrayList<ProjectUser>();
        Set<String> sendIds = new HashSet<String>();// 需要发送消息提醒的用户

        // 关联用户类型 1:负责人，2:参与人.3:批注领导,4:发布部门,5:发布人员
        // 负责人 参与人 批注领导 会发送消息提醒
        if (fzrIds != null && fzrIds.length > 0) {
            // 自动加上所有上级到抄送人员
            Map<String, List<String>> map = selectLeaderUsers(Utility.strArrayToString(fzrIds), true);
            if (map != null && map.size() > 0) {
                List<String> csList = map.get("userIds");
                csList.addAll(Arrays.asList(csrIds));
                HashSet<String> hs = new HashSet<String>(csList);
                csList.clear();
                csList.addAll(hs);
                csrIds = csList.toArray(new String[csList.size()]);
            }

            for (String id : fzrIds) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 1);
                pu.setTableId(id);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
                sendIds.add(id);
            }
        }
        if (deptIds != null && deptIds.length > 0) {
            for (String id : deptIds) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 2);
                pu.setTableId(id);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
            }
        }
        if (csrIds != null && csrIds.length > 0) {
            for (String id : csrIds) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 3);
                pu.setTableId(id);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
            }
        }
        if (isSendMsg != null && isSendMsg == 1) {
            Byte type = 31;
            saveMsgWarn(type, p.getId(), sendIds, null);// 发送消息提醒
        }
        // 批量添加
        // projectUserMapper.insertList(c);---此方法只适合id自增长
        for (ProjectUser projectUser : c) {
            projectUserMapper.insert(projectUser);
        }


        //导入附件信息
        if (filesList != null && filesList.size() > 0) {
            for (ProjectFiles projectFiles : filesList) {
                projectFiles.setProjectId(p.getId());
                projectFilesMapper.insert(projectFiles);
            }
        }

        //导入城市信息
        String area = p.getArea();
        ProjectCity projectCity = null;
        if (StringUtils.isNotBlank(area)) {
            String[] cityTypes = area.split(",");
            for (String type : cityTypes) {
                projectCity = new ProjectCity();
                projectCity.setId(UUIDUtil.uuid());
                projectCity.setType(type);
                projectCity.setProjectId(p.getId());
                projectCityMapper.insert(projectCity);
            }
        }

        // 发送企业微信消息
        List<String> fzNames = new ArrayList<String>();// 负责人姓名
        if (fzrIds != null && fzrIds.length > 0) {
            for (String userid : fzrIds) {
                SyUsers syUsers = syUsersMapper.findByUserName(userid);
                if (syUsers != null) fzNames.add(syUsers.getTrueName());
            }
        }
        String toUser = "";
        if (fzrIds != null && fzrIds.length > 0) {
            toUser = StringUtils.join(fzrIds, "|");
        }
        if (csrIds != null && csrIds.length > 0) {
            toUser += (StringUtils.isBlank(toUser) ? "" : "|") + StringUtils.join(csrIds, "|");
        }
        sendWxMsgByCreateProject(p, StringUtils.trimToEmpty(StringUtils.join(fzNames, ",")), toUser);


        return p.getId();
    }

    /**
     * 发送新建项目通知
     *
     * @param p        项目参数
     * @param fzrNames 负责人姓名，多个用英文逗号分隔
     * @param toUser   接收人的userId, 多个用|隔开
     */
    private void sendWxMsgByCreateProject(Project p, String fzrNames, String toUser) {
        String name = StringUtils.trimToEmpty(p.getName());
        if (name.length() > 20) {
            name = name.substring(0, 20) + " ...";
        }

        String description = "<div class=\"gray\">" + DateUtil.date2String(new Date(), "yyyy年MM月dd日 HH:mm")
                + "</div><br><br>" + "项目名称：" + name
                + "<br>" + "客户单位："
                + projectClientService.getNamesById(p.getProjectClientId()) + "<br>" + "项目时间："
                + DateUtil.date2String(p.getStartTime(), "MM-dd") + " ~ " + DateUtil.date2String(p.getEndTime() != null ? p.getEndTime() : p.getPlanTime(), "MM-dd")
                + "<br>" + "负责人：" + fzrNames  // StringUtils.trimToEmpty(StringUtils.join(fzrNames, ","))
                + "<br>" + "创建人：" + syUsersMapper.findByUserName(p.getCreateUserId()).getTrueName();
        if (StringUtils.isNotBlank(toUser)) {
            SendMsgUtil.sendWxMsgByNewProject(toUser, p.getId(), description);
        }
    }

    /**
     * 修改项目
     *
     * @param p         项目
     * @param isSendMsg
     * @param deptIds
     * @return
     */
    @SuppressWarnings("unchecked")
    @Transactional
    public void updateProject(Project p, Integer isSendMsg, String[] deptIds, List<ProjectFiles> filesList) {
        if (p == null) {
            throw new ParameterException("项目信息不能为空！");
        }
        if (p.getStartTime() == null) {
            throw new ParameterException("开始时间不能为空！");
        }
        if (p.getPlanTime() == null) {
            throw new ParameterException("计划时间不能为空！");
        }
        if (p.getStartTime().getTime() > p.getPlanTime().getTime()) {
            throw new ParameterException("项目时间范围不对！");
        }
        //修改项目不能修改结束时间
        p.setEndTime(null);
        String[] fzrIds = null, csrIds = null;
        if (StringUtils.isNotBlank(p.getFzrIds())) fzrIds = p.getFzrIds().split(",");
        if (StringUtils.isNotBlank(p.getCsrIds())) csrIds = p.getCsrIds().split(",");

        if (fzrIds == null || fzrIds.length == 0) {
            throw new ParameterException("请选择项目负责人！");
        }
        if (deptIds == null)
            deptIds = new String[]{};
        if (csrIds == null)
            csrIds = new String[]{};

        // 自动加上所有上级到抄送人员
        Map<String, List<String>> map = selectLeaderUsers(Utility.strArrayToString(fzrIds), true);
        if (map != null && map.size() > 0) {
            List<String> csList = map.get("userIds");
            csList.addAll(Arrays.asList(csrIds));
            HashSet<String> hs = new HashSet<String>(csList);
            csList.clear();
            csList.addAll(hs);
            csrIds = csList.toArray(new String[csList.size()]);
        }
        Project oldPro = mapper.findById(p.getId());
        Map<String, Object> param = new HashMap<String, Object>();
        if (oldPro == null) {
            throw new ParameterException("项目不存在，修改失败！");
        }

        if (oldPro.getStatus() != null && oldPro.getStatus() == 0) {
            throw new ParameterException("项目已作废，不可修改！");
        }

        // 判断是否有修改权限
        if (!hasUpdateProject(p.getId())) {
            throw new ServiceException("无修改权限，修改失败！");
        }

        oldPro.setName(p.getName());
        oldPro.setContent(p.getContent());
        oldPro.setStartTime(p.getStartTime());
        //oldPro.setEndTime(p.getEndTime());
        oldPro.setPlanTime(p.getPlanTime());
        oldPro.setType(p.getType());
        oldPro.setStatus(p.getStatus());
        oldPro.setImportance(p.getImportance());
        oldPro.setArea(p.getArea());
        oldPro.setCustomer(p.getCustomer());
        oldPro.setContractno(p.getContractno());
        oldPro.setUpdateTime(DateUtil.currentTimestamp());
        oldPro.setProjectClientId(p.getProjectClientId());
        oldPro.setProjectClienArray(p.getProjectClienArray());
        //更新项目
        mapper.updateByPrimaryKeySelective(oldPro);
        Set<String> sendIds = new HashSet<String>();// 需要发送消息提醒的用户

        // 负责人处理
        List<String> deptIdsOld = new ArrayList<String>();// 部门
        List<String> fzrIdsOld = new ArrayList<String>(); // 之前数据库的负责人用户ID
        List<String> csrIdsOld = new ArrayList<String>(); // 之前数据库的抄送人用户ID
        List<ProjectUser> list = projectUserMapper.selectProjectUserList(oldPro.getId());
        for (ProjectUser pu : list) {
            if (1 == pu.getType()) {// 负责人
                fzrIdsOld.add(pu.getTableId());
                boolean has = false;
                for (int i = 0, k = fzrIds.length; i < k; i++) {
                    if (pu.getTableId().equals(fzrIds[i])) {
                        has = true;
                        break;
                    }
                }
                if (!has) {
                    // 删除
                    projectUserMapper.delete(pu);
                } else {
                    sendIds.add(pu.getTableId());
                }

            } else if (2 == pu.getType()) {// 部门
                deptIdsOld.add(pu.getTableId());
                boolean has = false;
                for (int i = 0, k = deptIds.length; i < k; i++) {
                    if (pu.getTableId().equals(deptIds[i])) {
                        has = true;
                        break;
                    }
                }
                if (!has) {
                    // 删除
                    projectUserMapper.delete(pu);
                }
            } else {// 用户
                csrIdsOld.add(pu.getTableId());
                boolean has = false;
                for (int i = 0, k = csrIds.length; i < k; i++) {
                    if (pu.getTableId().equals(csrIds[i])) {
                        has = true;
                        break;
                    }
                }
                if (!has) {
                    // 删除
                    projectUserMapper.delete(pu);
                }
            }
        }
        // 新增加
        // 等待保存的对象集合
        List<ProjectUser> c = new ArrayList<ProjectUser>();
        for (int i = 0, k = fzrIds.length; i < k; i++) {// 负责人
            boolean has = false;
            for (String id : fzrIdsOld) {
                if (id.equals(fzrIds[i])) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 1);
                pu.setTableId(fzrIds[i]);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
                sendIds.add(pu.getTableId());
            }
        }
        for (int i = 0, k = deptIds.length; i < k; i++) {// 部门
            boolean has = false;
            for (String id : deptIdsOld) {
                if (id.equals(deptIds[i])) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 4);
                pu.setTableId(deptIds[i]);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
            }
        }

        for (int i = 0, k = csrIds.length; i < k; i++) {// 用户
            boolean has = false;
            for (String id : csrIdsOld) {
                if (id.equals(csrIds[i])) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                ProjectUser pu = new ProjectUser();
                pu.setId(UUIDUtil.uuid());
                pu.setType((byte) 5);
                pu.setTableId(csrIds[i]);
                pu.setProjectId(p.getId());
                pu.setCreateTime(DateUtil.currentTimestamp());
                pu.setUpdateTime(DateUtil.currentTimestamp());
                c.add(pu);
            }
        }
        if (isSendMsg != null && isSendMsg == 1) {
            // 发送消息提醒
            // saveMsgWarn(31,p.getId() , sendIds,null); // 修改暂时不提醒，不然会收到多条同样的消息
        }
        for (ProjectUser projectUser : c) {
            projectUserMapper.insertOrUpdate(projectUser.getId(), projectUser.getProjectId(), projectUser.getType(),
                    projectUser.getTableId(), projectUser.getUpdateTime(), projectUser.getCreateTime());
        }

        //导入附件信息前，先删除原有附件信息
        projectFilesMapper.deleteByProjectId(p.getId());
        if (filesList != null && filesList.size() > 0) {
            for (ProjectFiles projectFiles : filesList) {
                projectFiles.setProjectId(p.getId());
                projectFilesMapper.insert(projectFiles);
            }
        }

        //导入城市信息前，先删除原有城市信息
        projectCityMapper.deleteByProjectId(p.getId());
        String area = p.getArea();
        ProjectCity projectCity = null;
        if (StringUtils.isNotBlank(area)) {
            String[] cityTypes = area.split(",");
            for (String type : cityTypes) {
                projectCity = new ProjectCity();
                projectCity.setId(UUIDUtil.uuid());
                projectCity.setType(type);
                projectCity.setProjectId(p.getId());
                projectCityMapper.insert(projectCity);
            }
        }

        // 发送企业微信消息
        List<String> fzNames = new ArrayList<String>();// 负责人姓名
        if (fzrIds != null && fzrIds.length > 0) {
            for (String userid : fzrIds) {
                SyUsers syUsers = syUsersMapper.findByUserName(userid);
                if (syUsers != null) fzNames.add(syUsers.getTrueName());
            }
        }
        String toUser = ""; // 修改项目只发送给新增的负责人和抄送人
        if (fzrIds != null && fzrIds.length > 0) {
            for (String fzr : fzrIds) {
                if (!fzrIdsOld.contains(fzr) && !toUser.contains(fzr)) {
                    toUser += (StringUtils.isBlank(toUser) ? "" : "|") + fzr;
                }
            }
        }
        if (csrIds != null && csrIds.length > 0) {
            for (String csr : csrIds) {
                if (!csrIdsOld.contains(csr) && !toUser.contains(csr)) {
                    toUser += (StringUtils.isBlank(toUser) ? "" : "|") + csr;
                }
            }
        }
        p = mapper.findById(p.getId()); // 重新查出最新数据，因为发送消息需要CreateUserId，没有这个报空指针异常
        sendWxMsgByCreateProject(p, StringUtils.trimToEmpty(StringUtils.join(fzNames, ",")), toUser);

    }

    @Override
    public Map<String, List<String>> selectLeaderUsers(String userIds, boolean toTop) {
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        if (StringUtils.isBlank(userIds))
            return map;
        User loginuser = (User) SecurityUtils.getSubject().getPrincipal();
        String myUserId = "";
        if (loginuser != null) loginuser.getUsername();
        userIds += ("," + myUserId); // 自动加上本人的上级
        String sql = null;
        List<String> retUserIds = new ArrayList<String>();
        List<String> retUserNames = new ArrayList<String>();
        List<String> params = Arrays.asList(userIds.split(","));
        while (StringUtils.isNotBlank(userIds)) { // 循环遍历出所有上级
            List<String> paramUserIdList = Arrays.asList(userIds.split(","));
            userIds = "";
            for (String userid : paramUserIdList) {
                List<Map<String, Object>> userList = qywxUserMapper.findByUserId(userid);
                if (userList == null || userList.isEmpty())
                    continue;
                Map<String, Object> user = userList.get(0);
                String depId = (String) user.get("Department");
                Short isLeader = Short.parseShort(user.get("IsLeader").toString());
                if (isLeader != null && isLeader == 1) {
                    // 上级用户可能包含多个部门
                    userList = qywxUserMapper.findAllByDepartment(depId);
                } else {
                    // 非上级一般不会同时属于两个部门，所以查询上级用户的部门包含这个部门id就好了 (普通员工有多个部门的情况，所以FIND_IN_SET不实用了)
                    userList = qywxUserMapper.findByDepartment(depId);
                    if (userList == null || userList.isEmpty()) {
                        // 有些用户所在部门没有主管，所以直接查上级部门的主管
                        userList = qywxUserMapper.findSuperiorLeadersByDepartment(depId);
                    }
                }

                if (userList == null || userList.isEmpty())
                    continue;
                for (Map<String, Object> user2 : userList) {
                    user = user2;
                    String uid = (String) user.get("UserID");
                    if (params.contains(uid) || retUserIds.contains(uid))
                        continue; // 过滤掉重复的用户
                    retUserIds.add(uid);
                    retUserNames.add((String) user.get("NAME"));
                    userIds += StringUtils.isBlank(userIds) ? uid : ("," + uid);
                }
            }
            if (!toTop) break;
        }

        map.put("userIds", retUserIds);
        map.put("userNames", retUserNames);
        return map;
    }

    @Override
    public JSONArray selectLeaderUserObj(String userIds, boolean toTop) {
        JSONArray retArray = new JSONArray();
        if (StringUtils.isBlank(userIds)) return retArray;

        Map<String, List<String>> map = new HashMap<String, List<String>>();

        User loginuser = (User) SecurityUtils.getSubject().getPrincipal();
        if (loginuser != null) {
            userIds += ("," + loginuser.getUsername()); // 自动加上本人的上级
        }

        String sql = null;
        List<String> retUserIds = new ArrayList<String>();

        List<String> params = Arrays.asList(userIds.split(","));
        while (StringUtils.isNotBlank(userIds)) { // 循环遍历出所有上级
            List<String> paramUserIdList = Arrays.asList(userIds.split(","));
            userIds = "";
            for (String userid : paramUserIdList) {
                List<Map<String, Object>> userList = qywxUserMapper.findByUserId(userid);
                if (userList == null || userList.isEmpty())
                    continue;
                Map<String, Object> user = userList.get(0);
                String depId = (String) user.get("Department");
                Short isLeader = Short.parseShort(user.get("IsLeader").toString());
                if (isLeader != null && isLeader == 1) {
                    // 上级用户可能包含多个部门
                    userList = qywxUserMapper.findAllByDepartment(depId);
                } else {
                    // 非上级用户，查询出当前部门的所有上级
                    userList = qywxUserMapper.findByDepartment(depId);
                    if (userList == null || userList.isEmpty()) {
                        // 有些用户所在部门没有主管，所以直接查上级部门的主管
                        userList = qywxUserMapper.findSuperiorLeadersByDepartment(depId);
                    }
                }

                if (userList == null || userList.isEmpty()) {
                    continue;
                }

                for (Map<String, Object> user2 : userList) {
                    user = user2;
                    String uid = (String) user.get("UserID");
                    if (params.contains(uid) || retUserIds.contains(uid)) {
                        continue; // 过滤掉重复的用户
                    }
                    retUserIds.add(uid);
                    userIds += StringUtils.isBlank(userIds) ? uid : ("," + uid);

                    JSONObject userObj = new JSONObject();
                    userObj.put("userId", uid);
                    userObj.put("userName", (String) user.get("NAME"));
                    userObj.put("avatar", (String) user.get("Avatar"));
                    retArray.add(userObj);

                }
            }
            if (!toTop) break;
        }

        return retArray;
    }

    /**
     * 添加消息提醒
     *
     * @param type    消息类型
     * @param tableId 信息表id
     * @param userIds 提醒用户id集合
     * @param deptIds 提醒部门id集合
     */
    protected void saveMsgWarn(Byte type, String tableId, Collection<String> userIds, Collection<String> deptIds) {

        Set<String> addUserIds = new HashSet<String>();
        if (userIds != null) {
            for (String id : userIds) {
                addUserIds.add(id);
            }
        }
        if (deptIds != null) {
            // 查询出此部门所有的用户id
            for (String id : deptIds) {
                // 通过部门id查询该部门下所有的员工id
                List<String> uid = syUsersMapper.findIdByDeptId(id);
                addUserIds.addAll(uid);
            }
        }
        if (!addUserIds.isEmpty()) {
            List<PerMsg> c = new ArrayList<PerMsg>();
            for (String id : addUserIds) {
                PerMsg msg = new PerMsg();
                msg.setId(UUIDUtil.uuid());
                msg.setMsgTime(DateUtil.currentTimestamp());
                msg.setMsgType(type);
                msg.setReadState((short) 0);
                msg.setTableId(tableId);
                msg.setUserId(id);
                c.add(msg);
            }
            // 批量添加或更新
            // perMsgMapper.insertList(c);
//			projectUserMapper.insertList(c);---此方法只适合id自增长
            for (PerMsg perMsg : c) {
                perMsgMapper.insert(perMsg);
            }
        }
    }

    @Override
    public void deleteProject(String[] ids) {
        logger.info("*******" + JSON.toJSONString(ids));
        if (ids == null || ids.length < 1) {
            throw new ParameterException("删除项目id不能为空！");
        }

        for (String id : ids) {
            Project p = mapper.findById(id);
            if (p == null) continue;
            // 非创建人或管理员不能删除项目,测试阶段放开
            if (!hasUpdateProject(p.getId())) {
                throw new ServiceException("你没有权限删除此项目！");
            }

            //删除城市信息
            projectCityMapper.deleteByProjectId(p.getId());

            // 删除项目文件
            projectFilesMapper.deleteByProjectId(p.getId());

            // 删除项目任务日志
            List<String> projectTaskIds = projectTaskMapper.getProjectTaskIds(p.getId());
            if (projectTaskIds != null && projectTaskIds.size() > 0) {
                for (String taskId : projectTaskIds) {
                    journalMapper.deleteByTaskId(taskId);
                }
            }

            // 删除项目任务
            projectTaskMapper.deleteByProjectId(p.getId());

            // 删除项目任务人员关联表
            projectTaskUserMapper.deleteByProjectId(p.getId());

            // 删除项目人员关联表
            projectUserMapper.deleteByProjectId(p.getId());

            //删除项目
            mapper.delete(p);
        }
    }

    @Override
    public Map<String, Set<String>> selectCityByUserIds(String userIds) {
        if (StringUtils.isBlank(userIds)) {
            return null;
        }
//		logger.info("接收参数："+userIds);
        List<String> paramUserIdList = Arrays.asList(userIds.split(","));

        Set<String> depIds = new HashSet<String>();
        for (String userid : paramUserIdList) {
            List<Map<String, Object>> userList = qywxUserMapper.findByUserId(userid);
//			logger.info("获取部门Id="+userList.toString());
            if (userList == null || userList.isEmpty())
                continue;
            Map<String, Object> user = userList.get(0);
            if (user == null || user.isEmpty() || user.get("Department") == null)
                continue;
            String depId = (String) user.get("Department");
            String[] depIdArray = depId.split(",");
            if (depIdArray.length == 1) {
                // 只挂在一个部门
                depIds.add(depId);
            } else {
                // 挂在多个部门下面
                for (String dep : depIds) {
                    depIds.add(dep);
                }
            }
        }
        Map<String, Set<String>> resultMap = new HashMap<>();
        // 通过部门id去查询地域
        Set<String> city = new HashSet<String>();
        Set<String> cityId = new HashSet<String>();
        List<Map<String, Object>> depList = qywxPartyMapper.findAll();
//		logger.info("获取部门信息="+depList.toString());
        for (String depId : depIds) {
            Map<String, String> dep = new HashMap<String, String>();
            if (depId != null && (!depId.equals("1"))) {
                boolean flag = true;
                int i = 0;
                //找到一级机构或者循环超过5次
                while (flag || i > 5) {
                    dep = queryParentId(depId, depList);
                    i++;
                    if (dep != null && dep.get("ParentId") != null && dep.get("ParentId").equals("1")) {
                        flag = false;
                    } else {
                        depId = String.valueOf(dep.get("ParentId"));
                    }
                }

                // 已经到一级部门，判断此部门属于哪个地域
                if (dep.get("Id") != null && (dep.get("Id").equals("3") || dep.get("Id").equals("7")
                        || dep.get("Id").equals("17") || dep.get("Id").equals("29"))) {
                    // 深圳
                    city.add("深圳");
                    cityId.add(listTypeMapper.getAreaIdByName("深圳"));
                } else if ((dep.get("Id").equals("2"))) {
                    // 上海
                    city.add("上海");
                    cityId.add(listTypeMapper.getAreaIdByName("上海"));
                } else if ((dep.get("Id").equals("16"))) {
                    // 武汉
                    city.add("武汉");
                    cityId.add(listTypeMapper.getAreaIdByName("武汉"));
                } else if ((dep.get("Id").equals("36"))) {
                    // 北京
                    city.add("北京");
                    cityId.add(listTypeMapper.getAreaIdByName("北京"));
                }
            }
        }
        resultMap.put("city", city);
        resultMap.put("cityId", cityId);
        return resultMap;
    }

    /**
     * 通过部门id获取父部门id
     *
     * @param depId
     * @param depList
     * @return
     */
    Map<String, String> queryParentId(String depId, List<Map<String, Object>> depList) {
        for (Map<String, Object> dep : depList) {
            if (dep != null && dep.get("Id") != null && depId.equals(String.valueOf(dep.get("Id")))) {
                Map<String, String> map = new HashMap<String, String>();
                map.put("ParentId", String.valueOf(dep.get("ParentId")));
                map.put("Id", String.valueOf(dep.get("Id")));
                return map;
            }
        }
        return null;
    }

    @Override
    public void updateProjectStatus(String id, String contractno, String status) {
        if (StringUtils.isBlank(id)) {
            throw new ParameterException("项目id不能为空");
        }
        if (StringUtils.isBlank(status)) {
            throw new ParameterException("状态不能为空");
        }
        if (Integer.parseInt(status) == 3 && StringUtils.isBlank(contractno)) {
            throw new ParameterException("合同号不能为空");
        }
        Date endTime = null;
        String setuptime = null;
        String updatetime = null;
        if (status.equals("1")) {
            //如果任务已经结束，改成运行中，重置结束时间
            setuptime = "1";
        } else if (status.equals("3")) {
            //任务结束，修改时间
            updatetime = "1";
        }
        mapper.updateProjectStatus(setuptime, id, contractno, Integer.parseInt(status),updatetime);
    }

    @Override
    public List<Map<String, Object>> selectZxrUserObj(String userIds) {
        List<Map<String, Object>> resultMap = new ArrayList<>();
        if (StringUtils.isBlank(userIds)) return resultMap;
        List<String> retUserIds = new ArrayList<String>();

        List<String> params = Arrays.asList(userIds.split(","));
        List<Map<String, Object>> userInfoByUserIds = qywxUserMapper.getUserInfoByUserIds(params);
        return userInfoByUserIds;
    }
}
