package com.xjrsoft.module.oa.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.utils.LocalDateTimeUtil;
import com.xjrsoft.common.utils.TreeUtil;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.config.CommonPropertiesConfig;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.entity.BaseGrade;
import com.xjrsoft.module.base.mapper.BaseClassMapper;
import com.xjrsoft.module.base.mapper.BaseGradeMapper;
import com.xjrsoft.module.oa.dto.*;
import com.xjrsoft.module.oa.entity.News;
import com.xjrsoft.module.oa.entity.NewsAppendix;
import com.xjrsoft.module.oa.entity.NewsRelation;
import com.xjrsoft.module.oa.entity.NewsRelationConfig;
import com.xjrsoft.module.oa.mapper.NewsAppendixMapper;
import com.xjrsoft.module.oa.mapper.NewsMapper;
import com.xjrsoft.module.oa.mapper.NewsRelationConfigMapper;
import com.xjrsoft.module.oa.mapper.NewsRelationMapper;
import com.xjrsoft.module.oa.service.INewsAppendixService;
import com.xjrsoft.module.oa.service.INewsRelationService;
import com.xjrsoft.module.oa.service.INewsService;
import com.xjrsoft.module.oa.vo.*;
import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
import com.xjrsoft.module.organization.entity.Department;
import com.xjrsoft.module.organization.entity.User;
import com.xjrsoft.module.organization.entity.UserDeptRelation;
import com.xjrsoft.module.organization.mapper.DepartmentMapper;
import com.xjrsoft.module.organization.mapper.UserDeptRelationMapper;
import com.xjrsoft.module.organization.mapper.UserMapper;
import com.xjrsoft.module.organization.service.IWeChatService;
import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
import com.xjrsoft.module.student.mapper.BaseStudentSchoolRollMapper;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 新闻中心表 服务实现类
 * </p>
 *
 * @author zlf
 * @since 2022-06-16
 */
@Service
@AllArgsConstructor
public class NewsServiceImpl extends MPJBaseServiceImpl<NewsMapper, News> implements INewsService {

    private final NewsMapper newsMapper;


    private final NewsAppendixMapper newsAppendixMapper;
    private final NewsRelationMapper newsRelationMapper;
    private final NewsRelationConfigMapper newsRelationConfigMapper;


    private final UserDeptRelationMapper userDeptRelationMapper;


    private final BaseStudentSchoolRollMapper baseStudentSchoolRollMapper;

    private final IWeChatService weChatService;

    private final UserMapper userMapper;

    private final BaseGradeMapper baseGradeMapper;

    private final DepartmentMapper departmentMapper;

    private final BaseClassMapper baseClassMapper;

    private final XjrUserMapper xjrUserMapper;

    private final CommonPropertiesConfig commonPropertiesConfig;

    private INewsRelationService newsRelationService;
    private INewsAppendixService newsAppendixService;

    @Override
    public List<NewsGradeClassTreeVo> getGradeClassTree() {
        List<NewsGradeClassTreeVo> treeVoList = new ArrayList<NewsGradeClassTreeVo>();

        //虚拟父级
        treeVoList.add(new NewsGradeClassTreeVo() {{
            setId(666666L);
            setName("班级");
        }});

        //获取所有班级的年级作为树的父级
        MPJLambdaWrapper<BaseClass> queryGrade = new MPJLambdaWrapper<>();
        queryGrade
                .distinct()
                .selectAs(BaseGrade::getId, BaseGrade::getId)
                .selectAs(BaseGrade::getName, BaseGrade::getName)
                .leftJoin(BaseGrade.class, BaseGrade::getId, BaseClass::getGradeId);
        List<BaseGrade> gradeList = baseClassMapper.selectJoinList(BaseGrade.class, queryGrade);
        gradeList.forEach((node) -> {
            treeVoList.add(new NewsGradeClassTreeVo() {{
                setId(node.getId());
                setName(node.getName());
                setParentId(666666L);
            }});
        });


        List<BaseClass> classList = baseClassMapper.selectList(new QueryWrapper<BaseClass>());
        //获取班级荣誉中出现的学期下的所有班级作为树的子级
        classList.forEach((node) -> {
            treeVoList.add(new NewsGradeClassTreeVo() {{
                setId(node.getId());
                setName(node.getName());
                setParentId(node.getGradeId());
            }});
        });

        List<NewsGradeClassTreeVo> resultTreeVoList = TreeUtil.build(treeVoList);
        return resultTreeVoList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addProclamation(AddProclamationDto addProclamationDto) {
        News news = BeanUtil.toBean(addProclamationDto, News.class);
        news.setTypeId(2);
        news.setEnabledMark(EnabledMark.ENABLED.getCode());
        //LambdaQueryWrapper<News> queryWrapperSortcode = new LambdaQueryWrapper<>();
        //queryWrapperSortcode.select("SELECT IFNULL(MAX(sort_code),1)");
        newsMapper.insert(news);

        //添加附件子表
        if (addProclamationDto.getAppendixList() != null) {
            for (AddNewsAppendixDto appendixDto : addProclamationDto.getAppendixList()) {
                NewsAppendix newsAppendix = BeanUtil.toBean(appendixDto, NewsAppendix.class);
                newsAppendix.setNewsId(news.getId());
                newsAppendixMapper.insert(newsAppendix);
            }
        }

        //公告需要添加阅读关系配置，关系类型 1=部门 2=人员 3=班级
        if (addProclamationDto.getSendRange() == 3 && addProclamationDto.getRelationList() != null && addProclamationDto.getRelationList().size() > 0) {
            addRelationConfig(news, addProclamationDto);
        }

        //如果状态是2，表示立即发布的公告，需要将阅读人添加进阅读关系表
        if(addProclamationDto.getStatus() == 2){
            addRelation(news, addProclamationDto, 2);
            return news.getId();
        }
        //没有任何问题返回
        return -1L;
    }

    @Override
    public ProclamationVo getProclamationById(Long id) {
        MPJLambdaWrapper<News> queryWrapperNews = new MPJLambdaWrapper<>();
        queryWrapperNews
                .select(News::getId)
                .selectAs(Department::getName, ProclamationVo::getSendDeptIdCN)
                .select(News.class, x -> VoToColumnUtil.fieldsToColumns(ProclamationVo.class).contains(x.getProperty()))
                .leftJoin(Department.class, Department::getId, News::getSendDeptId)
                .eq(News::getId, id);
        ProclamationVo proclamationVo = this.selectJoinOne(ProclamationVo.class, queryWrapperNews);
        if (proclamationVo == null) {
            return null;
        }

        //添加阅读关系集合
        List<NewsRelationConfigVo> newsRelationConfigVoList = new ArrayList<>();
        //公告在草稿状态还没有阅读状态，只有阅读关系
        if (proclamationVo.getStatus() == 1) {
            MPJLambdaWrapper<NewsRelationConfig> queryWrapperNewsRelationConfig = new MPJLambdaWrapper<>();
            queryWrapperNewsRelationConfig
                    .select(NewsRelationConfig.class, x -> VoToColumnUtil.fieldsToColumns(NewsRelationConfigVo.class).contains(x.getProperty()))
                    .eq(NewsRelationConfig::getNewsId, proclamationVo.getId());
            newsRelationConfigVoList = newsRelationConfigMapper.selectJoinList(NewsRelationConfigVo.class, queryWrapperNewsRelationConfig);
        }
        proclamationVo.setNewsRelationConfigVoList(newsRelationConfigVoList);

        //添加阅读状态集合
        List<NewsRelationVo> newsRelationVoList = new ArrayList<>();
        //公告在发布状态或下架状态
        if (proclamationVo.getStatus() == 2 || proclamationVo.getStatus() == 3) {
            MPJLambdaWrapper<NewsRelation> queryWrapper = new MPJLambdaWrapper<>();
            queryWrapper
                    .select(NewsRelation::getId)
                    .selectAs(XjrUser::getName, NewsRelationVo::getUserName)
                    .select(NewsRelation.class, x -> VoToColumnUtil.fieldsToColumns(NewsRelationVo.class).contains(x.getProperty()))
                    .leftJoin(XjrUser.class, XjrUser::getId, NewsRelation::getUserId)
                    .eq(NewsRelation::getNewsId, proclamationVo.getId())
                    .disableSubLogicDel();
            //当是发布人点击了该公告可以看到其下所有人的回复
            if (ObjectUtil.isNotNull(proclamationVo.getCreateUserId()) && StpUtil.getLoginIdAsLong() == proclamationVo.getCreateUserId()) {
                newsRelationVoList = newsRelationService.selectJoinList(NewsRelationVo.class, queryWrapper);
            } else {//当不是发布人点击了该公告只能看到自己的回复
                queryWrapper.eq(NewsRelation::getUserId, StpUtil.getLoginIdAsLong());
                NewsRelationVo newsRelationVo = newsRelationService.selectJoinOne(NewsRelationVo.class, queryWrapper);
                if (ObjectUtil.isNotNull(newsRelationVo)) {
                    newsRelationVoList.add(newsRelationVo);
                }
            }
        }

        proclamationVo.setRelationList(newsRelationVoList);

        //添加附件
        List<NewsAppendixVo> newsAppendixVoList = newsAppendixService.selectJoinList(NewsAppendixVo.class,
                new MPJLambdaWrapper<NewsAppendix>().eq(NewsAppendix::getNewsId, id)
                        .select(NewsRelation::getId)
                        .select(NewsAppendix.class, x -> VoToColumnUtil.fieldsToColumns(NewsAppendixVo.class).contains(x.getProperty()))
                        .leftJoin(File.class, File::getFolderId, NewsAppendix::getFileId, ext -> ext.selectAs(File::getFileName, NewsAppendixVo::getFileName)
                                .selectAs(File::getFolderId, NewsAppendixVo::getFolderId)
                                .selectAs(File::getFileUrl, NewsAppendixVo::getFileUrl))
        );
        if (newsAppendixVoList.size() > 0) {
            proclamationVo.setAppendixList(newsAppendixVoList);
        }

        return proclamationVo;
    }

    @Override
    public IPage<ProclamationPageVo> proclamationManageBox(ProclamationPageDto dto) {
        MPJLambdaWrapper<News> queryNews = new MPJLambdaWrapper<>();
        queryNews
                .select(News::getId)
                .selectAs(Department::getName, ProclamationPageVo::getSendDeptIdCN)
                .select(News.class, x -> VoToColumnUtil.fieldsToColumns(ProclamationPageVo.class).contains(x.getProperty()))
                .leftJoin(Department.class, Department::getId, News::getSendDeptId)
                .eq(News::getCreateUserId, StpUtil.getLoginIdAsLong())
                .eq(News::getTypeId, 2)
                .like(dto.getFullHead() != null, News::getFullHead, dto.getFullHead())
                .like(dto.getKeyword() != null, News::getNewsContent, dto.getKeyword())
                .orderByDesc(News::getId)
                .disableSubLogicDel();
        IPage<ProclamationPageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), ProclamationPageVo.class, queryNews);
        return page;
    }

    @Override
    public IPage<ProclamationPageVo> proclamationReceiptBox(ProclamationPageDto dto) {
        MPJLambdaWrapper<News> queryNews = new MPJLambdaWrapper<>();
        queryNews
                .select(News::getId)
                .selectAs(Department::getName, ProclamationPageVo::getSendDeptIdCN)
                .select(News.class, x -> VoToColumnUtil.fieldsToColumns(ProclamationPageVo.class).contains(x.getProperty()))
                .leftJoin(Department.class, Department::getId, News::getSendDeptId)
                .leftJoin(NewsRelation.class, NewsRelation::getNewsId, News::getId)
                .eq(News::getTypeId, 2)
                .eq(News::getStatus, 2)
                .gt(News::getSendEndDate, new Date())
                .eq(NewsRelation::getUserId, StpUtil.getLoginIdAsLong())
                .or()
                .eq(News::getSendRange, 2)
                .orderByDesc(News::getId)
                .disableSubLogicDel();
        ;
        IPage<ProclamationPageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), ProclamationPageVo.class, queryNews);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean changeStatus(ChangeNewsDto changeNewsDto) {
        News xjrNews = this.getById(changeNewsDto.getId());
        if (changeNewsDto.getStatus() == null || xjrNews == null) {
            throw new MyException("参数异常");
        }
        if (changeNewsDto.getStatus().equals(xjrNews.getStatus())) {
            if (changeNewsDto.getStatus() == 2) {
                throw new MyException("公告已发布!!!");
            } else if (changeNewsDto.getStatus() == 3) {
                throw new MyException("公告已下架!!!");
            }
        }

        xjrNews.setStatus(changeNewsDto.getStatus());
        //发布公告，将阅读关系中选择的阅读人添加到关系表
        if (xjrNews.getStatus() == 2) {
            //将发布时间改为当前时间
            xjrNews.setReleaseTime(LocalDateTime.now());
            //将张贴时间改为当前时间
            xjrNews.setSendStartDate(LocalDateTime.now());
            xjrNews.setModifyUserId(StpUtil.getLoginIdAsLong());
            xjrNews.setModifyDate(LocalDateTime.now());
            addRelation(xjrNews, null, 1);
        }

        if (xjrNews.getStatus() == 3) {
            //应该将关系配置表和关系表的数据设置为删除
        }
        return this.updateById(xjrNews);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProclamation(UpdateProclamationDto updateProclamationDto) {
        News news = BeanUtil.toBean(updateProclamationDto, News.class);
        news.setModifyDate(LocalDateTime.now());
        news.setModifyUserId(StpUtil.getLoginIdAsLong());
        newsMapper.updateById(news);

        newsAppendixMapper.delete(Wrappers.lambdaQuery(NewsAppendix.class).eq(NewsAppendix::getNewsId, news.getId()));
        if (updateProclamationDto.getAppendixList() != null) {
            for (AddNewsAppendixDto appendixDto : updateProclamationDto.getAppendixList()) {
                NewsAppendix newsAppendix = BeanUtil.toBean(appendixDto, NewsAppendix.class);
                newsAppendix.setNewsId(news.getId());
                newsAppendixMapper.insert(newsAppendix);
            }
        }

        if (updateProclamationDto.getSendRange() == 3 && updateProclamationDto.getRelationList() != null) {
            newsRelationMapper.delete(Wrappers.lambdaQuery(NewsRelation.class).eq(NewsRelation::getNewsId, news.getId()));
            newsRelationConfigMapper.delete(Wrappers.lambdaQuery(NewsRelationConfig.class).eq(NewsRelationConfig::getNewsId, news.getId()));
            updateRelationConfig(news, updateProclamationDto);
        }
        return true;
    }

    /**
     * 添加阅读关系配置表
     * @param news
     * @return
     */
    private Boolean updateRelationConfig(News news, UpdateProclamationDto updateProclamationDto){
        AddProclamationDto addProclamationDto = BeanUtil.toBean(updateProclamationDto, AddProclamationDto.class);
        return addRelationConfig(news, addProclamationDto);
    }

    private Boolean addRelationConfig(News news, AddProclamationDto addProclamationDto){
        for (AddNewsRelationDto relationDto : addProclamationDto.getRelationList()) {
            if (relationDto.getRelationType() == 1) {
                Department department = departmentMapper.selectById(relationDto.getRelationId());
                newsRelationConfigMapper.insert(new NewsRelationConfig() {{
                    setNewsId(news.getId());
                    setRelationId(relationDto.getRelationId());
                    setRelationType(relationDto.getRelationType());
                    if (department != null) {
                        setRelationName(department.getName());
                        //setRelationName("中小微企业是经济发展的“毛细血管，十二条措施明确推进破产审判全域智治集成改革，通过推广智慧破产平台、推动执破融合机制改革、推行小微企业破产特别保护，力求在涉企破产纠纷办理中提质效、降成本。扬州中院党组成员、副院长沈红表示，将以提升经营主体司法获得感和满意度为出发点和落脚点，让法治成为扬州营商环境核心竞争力。中小微企业是经济发展的毛细血管，十二条措施明确推进破产审判全域智治集成改革，通过推广智慧破产平台、推动执破融合机制改革、推行小微企业破产特别保护，力求在涉企破产纠纷办理中提质效、降成本。扬州中院党组成员、副院长沈红表示，将以提升经营主体司法获得感和满意度为出发点和落脚点，让法治成为扬州营商环境核心竞争力。");
                    }
                }});
            }
            if (relationDto.getRelationType() == 2) {
                XjrUser xjrUser = xjrUserMapper.selectById(relationDto.getRelationId());
                newsRelationConfigMapper.insert(new NewsRelationConfig() {{
                    setNewsId(news.getId());
                    setRelationId(relationDto.getRelationId());
                    setRelationType(relationDto.getRelationType());
                    if (xjrUser != null) {
                        setRelationName(xjrUser.getName());
                    }
                }});
            }
            if (relationDto.getRelationType() == 3) {
                BaseClass baseClass = baseClassMapper.selectById(relationDto.getRelationId());
                BaseGrade baseGrade = null;
                if (baseClass == null) {
                    baseGrade = baseGradeMapper.selectById(relationDto.getRelationId());
                }
                BaseGrade finalBaseGrade = baseGrade;
                newsRelationConfigMapper.insert(new NewsRelationConfig() {{
                    setNewsId(news.getId());
                    setRelationId(relationDto.getRelationId());
                    setRelationType(relationDto.getRelationType());
                    if (baseClass != null) {
                        setRelationName(baseClass.getName());
                    }
                    if (finalBaseGrade != null) {
                        setRelationName(finalBaseGrade.getName());
                    }
                }});
            }
        }
        return true;
    }

    /**
     * 添加阅读关系到关系表
     * @param xjrNews
     * @return
     */
    private Boolean addRelation(News xjrNews ,AddProclamationDto addProclamationDto, int flag){
        if (xjrNews.getSendRange() == 3) {
            List<Long> deptIdList = new ArrayList<>();
            List<Long> personalIdList = new ArrayList<>();
            List<Long> classIdList = new ArrayList<>();
            if(flag == 1) {
                //查出当前公告的关系配置
                //部门
                LambdaQueryWrapper<NewsRelationConfig> queryDeptList = new LambdaQueryWrapper<>();
                queryDeptList
                        .eq(NewsRelationConfig::getNewsId, xjrNews.getId())
                        .eq(NewsRelationConfig::getRelationType, 1);
                List<NewsRelationConfig> deptList = newsRelationConfigMapper.selectList(queryDeptList);
                for (NewsRelationConfig newsRelationConfig : deptList) {
                    deptIdList.add(newsRelationConfig.getRelationId());
                }

                //人员
                LambdaQueryWrapper<NewsRelationConfig> queryPersonalList = new LambdaQueryWrapper<>();
                queryPersonalList
                        .eq(NewsRelationConfig::getNewsId, xjrNews.getId())
                        .eq(NewsRelationConfig::getRelationType, 2);
                List<NewsRelationConfig> personalList = newsRelationConfigMapper.selectList(queryPersonalList);
                for (NewsRelationConfig newsRelationConfig : personalList) {
                    personalIdList.add(newsRelationConfig.getRelationId());
                }

                //班级
                LambdaQueryWrapper<NewsRelationConfig> queryClassList = new LambdaQueryWrapper<>();
                queryClassList
                        .eq(NewsRelationConfig::getNewsId, xjrNews.getId())
                        .eq(NewsRelationConfig::getRelationType, 3);
                List<NewsRelationConfig> classList = newsRelationConfigMapper.selectList(queryClassList);
                for (NewsRelationConfig newsRelationConfig : classList) {
                    classIdList.add(newsRelationConfig.getRelationId());
                }
            }

            if(flag == 2){
                for (AddNewsRelationDto addNewsRelationDto : addProclamationDto.getRelationList()) {
                    if(addNewsRelationDto.getRelationType() == 1){
                        deptIdList.add(addNewsRelationDto.getRelationId());
                    }
                    if(addNewsRelationDto.getRelationType() == 2){
                        personalIdList.add(addNewsRelationDto.getRelationId());
                    }
                    if(addNewsRelationDto.getRelationType() == 3){
                        classIdList.add(addNewsRelationDto.getRelationId());
                    }
                }
            }

            //对人员进行筛选,避免重复添加
            List<Long> userIdList = new ArrayList<>();
            if (personalIdList.size() > 0) {
                //获取人员的班级或者部门
                List<DeptIdOrClassIdVo> deptIdOrClassIdVoList = newsMapper.getDeptIdOrClassId(personalIdList);
                for (DeptIdOrClassIdVo deptIdOrClassIdVo : deptIdOrClassIdVoList) {
                    if (deptIdOrClassIdVo.getClassId() != null) {//有班级是学生
                        if (!classIdList.contains(deptIdOrClassIdVo.getClassId())) {
                            userIdList.add(deptIdOrClassIdVo.getUserId());
                        }
                    } else {
                        if (!deptIdList.contains(deptIdOrClassIdVo.getDeptId())) {
                            userIdList.add(deptIdOrClassIdVo.getUserId());
                        }
                    }
                }
            }
            //添加部门人员
            if (deptIdList.size() > 0) {
                newsRelationMapper.insertDeptUser(xjrNews.getId(), deptIdList);
            }

            //添加部门人员
            if (classIdList.size() > 0) {
                newsRelationMapper.insertClassUser(xjrNews.getId(), classIdList);
            }

            //添加部门人员
            if (userIdList.size() > 0) {
                newsRelationMapper.insertPersonl(xjrNews.getId(), userIdList);
            }

        }

        //遍历所有关系配置
           /* for (NewsRelationConfig newsRelationConfig : newsRelationConfigList) {
                //阅读关系是部门
                if (newsRelationConfig.getRelationType() == 1) {
                    // 获取部门下的人员添加
                    Long deptId = newsRelationConfig.getRelationId();
                    MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
                    queryUser
                            .leftJoin(UserDeptRelation.class, UserDeptRelation::getUserId, XjrUser::getId)
                            .leftJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
                            .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
                            .leftJoin(Role.class, Role::getId, UserRoleRelation::getRoleId)
                            .eq(Department::getId, deptId)
                            .eq(Role::getId, 2);
                    List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class, queryUser);
                    for (XjrUser user : userList) {
                        if (!userMap.containsKey(user.getId())) {
                            userMap.put(user.getId(), user);
                            newsRelationMapper.insert(new NewsRelation() {{
                                setNewsId(xjrNews.getId());
                                setUserId(user.getId());
                                setReadMark(0);
                                setCreateDate(LocalDateTime.now());
                            }});
                        }
                    }
                }
                //阅读关系是人员
                if (newsRelationConfig.getRelationType() == 2) {
                    if (!userMap.containsKey(newsRelationConfig.getRelationId())) {
                        userMap.put(newsRelationConfig.getRelationId(), new XjrUser() {{
                            setId(newsRelationConfig.getRelationId());
                        }});
                        newsRelationMapper.insert(new NewsRelation() {{
                            setNewsId(xjrNews.getId());
                            setUserId(newsRelationConfig.getRelationId());
                            setReadMark(0);
                            setCreateDate(LocalDateTime.now());
                        }});
                    }
                }
                //阅读关系是班级
                if (newsRelationConfig.getRelationType() == 3) {
                    // 获取班级下的人员添加
                    Long classId = newsRelationConfig.getRelationId();
                    MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
                    queryUser
                            .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId)
                            .eq(BaseStudentSchoolRoll::getClassId, classId);
                    List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class, queryUser);
                    for (XjrUser user : userList) {
                        if (!userMap.containsKey(user.getId())) {
                            userMap.put(user.getId(), user);
                            newsRelationMapper.insert(new NewsRelation() {{
                                setNewsId(xjrNews.getId());
                                setUserId(user.getId());
                                setReadMark(0);
                                setCreateDate(LocalDateTime.now());
                            }});
                        }
                    }
                }
            }*/
        if (xjrNews.getSendRange() == 2) {
//                MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
//                queryUser
//                        .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
//                        .leftJoin(Role.class, Role::getId, UserRoleRelation::getRoleId)
//                        .eq(Role::getId, 2);
//                List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class, queryUser);
//                for (XjrUser user : userList) {
//                    newsRelationMapper.insert(new NewsRelation() {{
//                        setNewsId(xjrNews.getId());
//                        setUserId(user.getId());
//                        setReadMark(0);
//                        setCreateDate(LocalDateTime.now());
//                    }});
//                }
            newsRelationMapper.insertAllTeaStaff(xjrNews.getId());
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddNewsDto addNewsDto) {

        News news = BeanUtil.toBean(addNewsDto, News.class);
        news.setEnabledMark(EnabledMark.ENABLED.getCode());

        newsMapper.insert(news);
        //添加附件子表
        if (addNewsDto.getAppendixList() != null) {
            for (AddNewsAppendixDto appendixDto : addNewsDto.getAppendixList()) {
                NewsAppendix newsAppendix = BeanUtil.toBean(appendixDto, NewsAppendix.class);
                newsAppendix.setNewsId(news.getId());
                newsAppendixMapper.insert(newsAppendix);
            }
        }

        //公告需要添加阅读关系，发送范围 1=全校教职工 2=全校师生 3=指定人员
        //1=全校教职工,添加全校教职工到关系表
//        if(addNewsDto.getTypeId() == 2 && addNewsDto.getSendRange() == 1){
//            MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
//            queryUser
//                    .leftJoin(UserRoleRelation.class, UserRoleRelation::getUserId, XjrUser::getId)
//                    .leftJoin(Role.class, Role::getId, UserRoleRelation::getRoleId)
//                    .eq(Role::getId, 2);
//            List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class,queryUser);
//            for (XjrUser user: userList) {
//                newsRelation.setUserId(user.getId());
//                newsRelationMapper.insert(newsRelation);
//            }

//        }

        if (addNewsDto.getTypeId() == 2 && addNewsDto.getSendRange() == 1) {
            for (AddNewsRelationDto relationDto : addNewsDto.getRelationList()) {

                NewsRelationConfig newsRelationConfig = BeanUtil.toBean(relationDto, NewsRelationConfig.class);
                newsRelationConfig.setNewsId(news.getId());
                newsRelationConfigMapper.insert(newsRelationConfig);

                NewsRelation newsRelation = BeanUtil.toBean(relationDto, NewsRelation.class);
                newsRelation.setNewsId(news.getId());
                newsRelation.setReadMark(0);
                if (relationDto.getRelationType() == 1) {
                    // 获取部门下的人员添加
                    Long deptId = relationDto.getRelationId();
                    MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
                    queryUser
                            .leftJoin(UserDeptRelation.class, UserDeptRelation::getUserId, XjrUser::getId)
                            .leftJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
                            .eq(Department::getId, deptId);
                    List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class, queryUser);
                    for (XjrUser user : userList) {
                        newsRelation.setUserId(user.getId());
                        newsRelationMapper.insert(newsRelation);
                    }
                }
                if (relationDto.getRelationType() == 2) {
                    newsRelation.setUserId(relationDto.getRelationId());
                    newsRelationMapper.insert(newsRelation);
                }
                if (relationDto.getRelationType() == 3) {
                    // 获取班级下的人员添加
                    Long deptId = relationDto.getRelationId();
                    MPJLambdaWrapper<XjrUser> queryUser = new MPJLambdaWrapper<>();
                    queryUser
                            .leftJoin(UserDeptRelation.class, UserDeptRelation::getUserId, XjrUser::getId)
                            .leftJoin(Department.class, Department::getId, UserDeptRelation::getDeptId)
                            .eq(Department::getId, deptId);
                    List<XjrUser> userList = xjrUserMapper.selectJoinList(XjrUser.class, queryUser);
                    List<Long> userIdList = new ArrayList<>();
                    for (XjrUser user : userList) {
                        userIdList.add(user.getId());
                    }
                    for (Long userId : userIdList) {
                        newsRelation.setUserId(userId);
                        newsRelationMapper.insert(newsRelation);
                    }
                }
            }
        }

        //添加新闻和公告的时候，如果状态是2，表示新闻和公告实时发布了，张贴开始时间就应该是发布时间需要发送消息
        if (ObjectUtil.isNotNull(addNewsDto.getStatus()) && addNewsDto.getStatus() == 2) {
            SendMessage(news.getId());
        }

        return true;
    }

    @Override
    public IPage<NewsPageVo> manageBox(NewsPageDto dto) {
        dto.setLoginId(StpUtil.getLoginIdAsLong());
        IPage<NewsPageVo> page = newsMapper.manageBox(ConventPage.getPage(dto), dto);
        return page;
    }

    @Override
    public IPage<NewsPageVo> receiptBox(NewsPageDto dto) {
        dto.setLoginId(StpUtil.getLoginIdAsLong());
        IPage<NewsPageVo> page = newsMapper.receiptBox(ConventPage.getPage(dto), dto);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(UpdateNewsDto updateNewsDto) {
        News news = BeanUtil.toBean(updateNewsDto, News.class);
        newsMapper.updateById(news);

        newsAppendixMapper.delete(Wrappers.lambdaQuery(NewsAppendix.class).eq(NewsAppendix::getNewsId, news.getId()));
        if (updateNewsDto.getAppendixList() != null) {
            for (AddNewsAppendixDto appendixDto : updateNewsDto.getAppendixList()) {
                NewsAppendix newsAppendix = BeanUtil.toBean(appendixDto, NewsAppendix.class);
                newsAppendix.setNewsId(news.getId());
                newsAppendixMapper.insert(newsAppendix);
            }
        }

        if (updateNewsDto.getRelationList() != null) {
            newsRelationMapper.delete(Wrappers.lambdaQuery(NewsRelation.class).eq(NewsRelation::getNewsId, news.getId()));
            newsRelationConfigMapper.delete(Wrappers.lambdaQuery(NewsRelationConfig.class).eq(NewsRelationConfig::getNewsId, news.getId()));

            for (AddNewsRelationDto relationDto : updateNewsDto.getRelationList()) {

                NewsRelationConfig newsRelationConfig = BeanUtil.toBean(relationDto, NewsRelationConfig.class);
                newsRelationConfig.setNewsId(news.getId());
                newsRelationConfigMapper.insert(newsRelationConfig);

                NewsRelation newsRelation = BeanUtil.toBean(relationDto, NewsRelation.class);
                newsRelation.setNewsId(news.getId());
                newsRelation.setReadMark(0);
                if (relationDto.getRelationType() == 1) {
                    // 获取部门下的人员添加
                } else {
                    newsRelation.setUserId(relationDto.getRelationId());
                    newsRelationMapper.insert(newsRelation);
                }
            }
        }

        return true;
    }

    /**
     * 设置新闻阅读权限
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRelation(UpdateNewsRelationDto updateRelationDto) {

        if (updateRelationDto.getRelationList() != null) {
            for (NewsRelationConfigDto newsRelationConfigDto : updateRelationDto.getRelationList()) {
                NewsRelationConfig newsRelationConfig = new NewsRelationConfig();
                newsRelationConfig.setNewsId(updateRelationDto.getId());
                newsRelationConfig.setRelationId(newsRelationConfigDto.getRelationId());
                newsRelationConfig.setRelationName(newsRelationConfigDto.getRelationName());
                newsRelationConfig.setRelationType(updateRelationDto.getRelationType());
                newsRelationConfigMapper.insert(newsRelationConfig);

                // 部门
                if (updateRelationDto.getRelationType() == 1) {
                    List<UserDeptRelation> userDeptRelationList = userDeptRelationMapper.selectList(Wrappers.<UserDeptRelation>query().lambda()
                            .eq(UserDeptRelation::getDeptId, newsRelationConfigDto.getRelationId()));
                    for (UserDeptRelation userDeptRelation : userDeptRelationList) {
                        NewsRelation newsRelation = new NewsRelation();
                        newsRelation.setUserId(userDeptRelation.getUserId());
                        newsRelation.setNewsId(updateRelationDto.getId());
                        newsRelation.setReadMark(0);
                        newsRelationMapper.insert(newsRelation);
                    }
                }

                // 人员
                if (updateRelationDto.getRelationType() == 2) {
                    NewsRelation newsRelation = new NewsRelation();
                    newsRelation.setUserId(newsRelationConfigDto.getRelationId());
                    newsRelation.setNewsId(updateRelationDto.getId());
                    newsRelation.setReadMark(0);
                    newsRelationMapper.insert(newsRelation);
                }

                // 班级
                if (updateRelationDto.getRelationType() == 3) {
                    List<BaseStudentSchoolRoll> baseStudentSchoolRollList = baseStudentSchoolRollMapper.selectList(Wrappers.<BaseStudentSchoolRoll>query().lambda()
                            .eq(BaseStudentSchoolRoll::getClassId, newsRelationConfigDto.getRelationId()));

                    for (BaseStudentSchoolRoll baseStudentSchoolRoll : baseStudentSchoolRollList) {
                        NewsRelation newsRelation = new NewsRelation();
                        newsRelation.setUserId(baseStudentSchoolRoll.getUserId());
                        newsRelation.setNewsId(updateRelationDto.getId());
                        newsRelation.setReadMark(0);
                        newsRelationMapper.insert(newsRelation);
                    }
                }
            }
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRelation(DeleteNewsRelationDto deleteNewsRelationDto) {

        if (deleteNewsRelationDto.getRelationId() != null) {
            List<NewsRelationConfig> newsRelationConfigList = newsRelationConfigMapper.selectList(Wrappers.<NewsRelationConfig>query().lambda()
                    .eq(NewsRelationConfig::getNewsId, deleteNewsRelationDto.getNewsId())
                    .in(NewsRelationConfig::getId, deleteNewsRelationDto.getRelationId())
            );
            for (NewsRelationConfig newsRelationConfig : newsRelationConfigList) {
                // 部门
                if (newsRelationConfig.getRelationType() == 1) {
                    List<UserDeptRelation> userDeptRelationList = userDeptRelationMapper.selectList(Wrappers.<UserDeptRelation>query().lambda()
                            .eq(UserDeptRelation::getDeptId, newsRelationConfig.getRelationId()));

                    List<Long> userIdList = userDeptRelationList.stream().map(UserDeptRelation::getUserId).collect(Collectors.toList());

                    newsRelationMapper.delete(Wrappers.<NewsRelation>query().lambda()
                            .eq(NewsRelation::getNewsId, deleteNewsRelationDto.getNewsId())
                            .in(NewsRelation::getUserId, userIdList));
                }

                // 人员
                if (newsRelationConfig.getRelationType() == 2) {
                    newsRelationMapper.delete(Wrappers.<NewsRelation>query().lambda()
                            .eq(NewsRelation::getNewsId, deleteNewsRelationDto.getNewsId())
                            .eq(NewsRelation::getUserId, newsRelationConfig.getRelationId()));
                }

                // 班级
                if (newsRelationConfig.getRelationType() == 3) {
                    List<BaseStudentSchoolRoll> baseStudentSchoolRollList = baseStudentSchoolRollMapper.selectList(Wrappers.<BaseStudentSchoolRoll>query().lambda()
                            .eq(BaseStudentSchoolRoll::getClassId, newsRelationConfig.getRelationId()));

                    List<Long> userIdList = baseStudentSchoolRollList.stream().map(BaseStudentSchoolRoll::getUserId).collect(Collectors.toList());

                    newsRelationMapper.delete(Wrappers.<NewsRelation>query().lambda()
                            .eq(NewsRelation::getNewsId, deleteNewsRelationDto.getNewsId())
                            .in(NewsRelation::getUserId, userIdList));
                }
            }

            newsRelationConfigMapper.deleteBatchIds(deleteNewsRelationDto.getRelationId());
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> ids) {
        newsMapper.deleteBatchIds(ids);
        return true;
    }

    @Override
    public boolean SendMessage(Long id) {
        try {
            News news = newsMapper.selectById(id);
            Department department = departmentMapper.selectById(news.getSendDeptId());
            if (news.getSendRange() == 1) {
                List<User> userList = userMapper.selectList(Wrappers.<User>query().lambda().isNotNull(User::getOpenId).ne(User::getOpenId, ""));
                if (userList.size() > 0) {
                    for (User user : userList) {
                        WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                        weChatSendMessageDto.setUserId(user.getOpenId());
                        weChatSendMessageDto.setTemplateId("qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4");
                        weChatSendMessageDto.setUrl(StrUtil.format("{}/pages/message/notice/detail?id={}", commonPropertiesConfig.getDomainApp(), id));
                        weChatSendMessageDto.setMsgId(id.toString());
                        JSONObject data = new JSONObject();

                        JSONObject data1 = new JSONObject();
                        String hValue = news.getFullHead().replace("“", "").replace("”", "").replace("\"", "").replace("\n", "").replace("\r", "").replace("\t", "");
                        data1.put("value", hValue);
                        data.put("thing23", data1);

                        JSONObject data2 = new JSONObject();
                        data2.put("value", (department == null) ? "重庆铜梁职业教育中心" : department.getName());
                        data.put("thing18", data2);

                        JSONObject data3 = new JSONObject();
                        data3.put("value", LocalDateTimeUtil.format(news.getReleaseTime(), "yyyy-MM-dd HH:mm:ss"));
                        data.put("time17", data3);
                        weChatSendMessageDto.setContent(data);
                        weChatService.sendTemplateMessage(weChatSendMessageDto);
                    }
                }
            } else {
                List<NewsRelationVo> newsRelationVoList = newsRelationMapper.selectJoinList(NewsRelationVo.class,
                        new MPJLambdaWrapper<NewsRelation>().distinct()
                                .eq(NewsRelation::getNewsId, id)
                                .select(NewsRelation.class, x -> VoToColumnUtil.fieldsToColumns(NewsRelationVo.class).contains(x.getProperty()))
                                .innerJoin(User.class, onWrapper -> onWrapper.eq(NewsRelation::getUserId, User::getId).isNotNull(User::getOpenId).ne(User::getOpenId, ""))
                                .selectAs(User::getOpenId, NewsRelationVo::getUserName)
                );
                if (newsRelationVoList.size() > 0) {
                    for (NewsRelationVo newsRelationVo : newsRelationVoList) {
                        WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                        weChatSendMessageDto.setUserId(newsRelationVo.getUserName());
                        weChatSendMessageDto.setTemplateId("qmpXORPM1Cocqn503Qa4OkNNQ0uxlj2-ed9m6uWO-v4");
                        weChatSendMessageDto.setUrl(StrUtil.format("{}/pages/message/notice/detail?id={}", commonPropertiesConfig.getDomainApp(), id));
                        weChatSendMessageDto.setMsgId(id.toString());
                        JSONObject data = new JSONObject();

                        JSONObject data1 = new JSONObject();
                        data1.put("value", news.getFullHead());
                        data.put("thing23", data1);

                        JSONObject data2 = new JSONObject();
                        data2.put("value", (department == null) ? "重庆铜梁职业教育中心" : department.getName());
                        data.put("thing18", data2);

                        JSONObject data3 = new JSONObject();
                        data3.put("value", LocalDateTimeUtil.format(news.getReleaseTime(), "yyyy-MM-dd HH:mm:ss"));
                        data.put("time17", data3);
                        weChatSendMessageDto.setContent(data);
                        weChatService.sendTemplateMessage(weChatSendMessageDto);
                    }
                }
            }
        } catch (Exception ex) {
        }
        return true;
    }

    @Override
    public boolean dataHandle(Long id) {
        CompletableFuture.runAsync(() -> {
            this.SendMessage(id);
        });
        return true;
    }
}
