package com.zzsn.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zzsn.config.Global;
import com.zzsn.constant.CacheConstant;
import com.zzsn.constant.PageConstant;
import com.zzsn.constant.SecretColorConstant;
import com.zzsn.entity.*;
import com.zzsn.entity.VO.WebTypeVo;
import com.zzsn.mapper.*;
import com.zzsn.service.DataSyncService;
import com.zzsn.service.IBaseDataWebMidService;
import com.zzsn.service.ICesSysSecretService;
import com.zzsn.service.ICesSysWebService;
import com.zzsn.utils.*;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class DataSyncServiceImpl extends ServiceImpl<BaseDataMapper,Basedata> implements DataSyncService  {
    private Logger logger = LoggerFactory.getLogger(DataSyncServiceImpl.class);
    @Autowired
    private BaseDataMapper dataMapper;
    @Autowired
    private BaseDataTypeMapper typeMapper;

    @Autowired
    private DataTypeSyncServiceImpl dataTypeSyncService;

    @Autowired
    private EsOpUtil esOpUtil;

    @Autowired
    private BaseDataImageMapper imageMapper;

    @Autowired
    private ICesSysSecretService secretService;

    @Value("${python.hanlpUrl}")
    private String hanlpUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private CesSysWebMapper webMapper;

    @Value("${proxy.url}")
    private String proxyUrl;

    @Value("${video.path}")
    private String videoPath;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private ICesSysWebService webService;

    @Autowired
    private BaseDataWebMidMapper baseDataWebMidMapper;

    @Autowired
    private IBaseDataWebMidService baseDataWebMidService;

    /**
     * 同步数据
     * @throws IOException
     */
    public void process() throws IOException {

    }
    /**
     * 同步数据
     */
    public Map<String,Object> repeat(Long maxId){
        logger.info("开始同步basedata{}",maxId);
        Map<String,Object> result = new HashMap<>();
        //1.查询数据库新增的数据
        List<Basedata> basedataList = query(maxId);
        if(!(basedataList.size()>0)){
            //如果新增加的数据为0，不处理，直接返回。
            result.put("repeat",new ArrayList<>());
            result.put("data",new ArrayList<>());
            result.put("newMaxId",null);
            return result;
        }
        //因为是ID升序序排序，所以最大的ID
        result.put("newMaxId",basedataList.get(basedataList.size()-1).getId());
        //3.处理重复数据
        List<Basedata> resultList = new ArrayList<>();
        List<String> repeatIdList = new ArrayList<>();
        List<Basedata> list = new ArrayList<>();
        if(basedataList.size()>0){
            //查询出来的新增的数据，网址是否有重复的，如果有，把id挑选出来
            Map<String,Basedata> map = new HashMap<>();
            for (Basedata basedata : basedataList) {
                if(map.containsKey(basedata.getSourceaddress())){
                    repeatIdList.add(basedata.getId());
                }else{
                    resultList.add(basedata);
                }
                map.put(basedata.getSourceaddress(),basedata);
            }
            //插入数据库之前，先看数据库中网址是否已经存在，如果已经存在，该数据不插入
            for (Basedata basedata : resultList) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(isExist(basedata)){
                    //如果存在，加入重复ID中
                    repeatIdList.add(basedata.getId());
                }else{
                    //不存在，则放入list中
                    list.add(basedata);
                }
            }
        }
        logger.info("重复的ID:{}",repeatIdList);
        result.put("repeat",repeatIdList);
        result.put("data",list);
        return  result;
    }

    /**
     * 插入数据到科工局数据库中
     * @param list
     */
//    @DS("master")
    @Transactional
    public void insertBatch(List<Basedata> list, List<BasedataType> typeList,List<BaseDataImage> imageList, List<CesSysWeb> exitWebList, List<CesSysWeb> newWebList,List<BaseDataWebMid> baseDataWebList){
//        logger.info("批量插入新的数据到科工局数据库中,baseData表[{}],baseType表[{}]",list,typeList);
        logger.info("批量插入新的数据到科工局数据库中,baseData表,baseType表,image表");
        //批量插入新的数据到科工局basedata表中
        if(list!=null&&list.size()>0){
            int i = dataMapper.insertList(list);
            logger.info("同步到basedata表成功，共{}条",i);
            //批量插入返回的成功条数
            if(i<1){
                logger.info("插入科工局basedata表失败");
                throw new RuntimeException("插入科工局basedata表失败");
            }
        }
        //批量插入新的数据到科工局Type表中
        if(typeList != null&&typeList.size()>0){
            int i1 = typeMapper.insertList(typeList);
            logger.info("同步到basedataType表成功，共{}条",i1);
            if(i1<1){
                logger.info("插入科工局basedataType表失败");
                throw new RuntimeException("插入科工局basedataType表失败");
            }
        }
        //插入图片数据到image表中
        if(imageList !=null && imageList.size()>0){
            //先查询数据库中是否存在一些数据
            Map<String, BaseDataImage> map = imageList.stream().collect(Collectors.toMap(BaseDataImage::getId, baseDataImage -> baseDataImage, (k1, k2) -> k2));
            if(map!=null){
                Set<String> keySet = map.keySet();
                if(keySet!=null && keySet.size()>0){
                    List<BaseDataImage> repeatList = imageMapper.selectByIds(new ArrayList<>(keySet));
                    if(repeatList!=null && repeatList.size()>0){
                        //剔除数据库中已经存在的数据
                        for (BaseDataImage baseDataImage : repeatList) {
                            map.remove(baseDataImage.getId());
                            keySet.remove(baseDataImage.getId());
                        }
                    }
                    List<BaseDataImage> images = new ArrayList<>();
                    for (String s : keySet) {
                        BaseDataImage baseDataImage = map.get(s);
                        if(baseDataImage!=null){
                            images.add(baseDataImage);
                        }
                    }
                    if(images !=null && images.size()>0){
                        //插入的数据不为空时候换，插入数据库
                        int i = imageMapper.insertList(images);
                        logger.info("同步到baseImage表成功，共{}条",i);
                        if(i<1){
                            logger.info("插入科工局baseImage表失败");
                            throw new RuntimeException("插入科工局baseImage表失败");
                        }
                    }
                }
            }
        }
        //批量更新ces_sys_web表，插入文章中相关联的地区，进行关联爬取用，更新时间
        if(CollectionUtils.isNotEmpty(exitWebList)){
            boolean b = webService.updateBatchById(exitWebList);
            if(!b){
                logger.info("更新科工局ces_sys_web表失败");
                throw new RuntimeException("更新科工局ces_sys_web表失败");
            }
        }
        //批量插入ces_sys_web表，插入文章中相关联的地区，进行关联爬取用
        if(CollectionUtils.isNotEmpty(newWebList)){
           int i = webMapper.insertBatch(newWebList);
            logger.info("同步到ces_sys_web表成功，共{}条",i);
            if(i<1){
                logger.info("插入科工局ces_sys_web表失败");
                throw new RuntimeException("插入科工局ces_sys_web表失败");
            }
        }
        //插入baseData和网站关联表
        if(CollectionUtils.isNotEmpty(baseDataWebList)){
            boolean b = baseDataWebMidService.saveBatch(baseDataWebList);
//            int i = baseDataWebMidMapper.insertBatch(baseDataWebList);
            logger.info("同步到CIS_BASEDATA_WEB_MID表成功，共{}条");
            if(!b){
                logger.info("插入科工局CIS_BASEDATA_WEB_MID表失败");
                throw new RuntimeException("插入科工局CIS_BASEDATA_WEB_MID表失败");
            }
        }

    }
    /**
     * 查询公司数据库中新增的数据
     * @param maxId
     * @return
     */
//    @DS("slave")
    public List<Basedata> query(Long maxId){
        logger.info("查询公司数据库basedata表中的新增数据,{}",maxId);
        PageHelper.startPage(PageConstant.page, PageConstant.pageSize);
        List<Basedata> basedataList = dataMapper.queryByCondition(maxId);
        return basedataList;
    }
    /**
     * 查询科工局数据库中该网址是否已经存在
     * @param basedata
     * @return
     */
//    @DS("master")
    public boolean isExist(Basedata basedata){
//        logger.info("查询网址是否已经存在科工局数据库中{}",basedata);
        logger.info("查询网址是否已经存在科工局数据库中{}",basedata.getId());
        int i=0;
        try {
            i = dataMapper.queryByAddress(basedata.getSourceaddress());
        }catch (Exception e){
            i=1;
        }
//        QueryWrapper<Basedata> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("sourceaddress",basedata.getSourceaddress());
        if(i>0){
//            logger.info("该网址已经存在科工局数据库中{}",basedata.getId());
            logger.info("该网址已经存在科工局数据库中{}",basedata.getSourceaddress());
        }else {
            try {
                i = dataMapper.queryByTitle(basedata.getTitle());
            } catch (Exception e) {
                i=1;
            }
            if(i>0){
                logger.info("该新闻已经存在科工局数据库中{}",basedata.getTitle());
            }

        }
        return i>0;
    }

    public Map<String, Object> imgHandler(List<Basedata> data) {
//        logger.info("对content中的img图片进行处理:{}",data);
        logger.info("对content中的img图片进行处理");
        Map<String, Object> map = new HashMap<>();
        List<Basedata> result = new ArrayList<>();
        List<BaseDataImage> imageList =new ArrayList<>();
        if(data!=null&&data.size()>0){
            for (Basedata basedata : data) {
                Map<String, FileTag> contentFileTag = null;
                try{
                    try {
                        contentFileTag = ContentFileFinder.getContentFileTag(basedata.getContent(), basedata.getSourceaddress());
                    }catch (Exception e){
                        result.add(basedata);
                    }
                    if(contentFileTag==null || contentFileTag.size()<1){
                        result.add(basedata);
                        continue;
                    }
                    Basedata base = new Basedata();
                    BeanUtils.copyProperties(basedata,base);
                    //遍历map
                    contentFileTag.forEach((key,value)->{
                        //使用MD5加密：ID+图片的原网址
                        String md5 = DigestUtils.md5DigestAsHex((base.getId() + value.getAbsolutePath()).getBytes(StandardCharsets.UTF_8));
                        logger.info("加密后的md5值{}",md5);
                        //图片保存到本地先关闭
                        //图片保存路径：
                        //                    String savePath = Global.getProfile() +md5+"."+value.getSuffix();

                        //保存图片到本地，本地路径文件夹
                        //先获取网络图片的大小，如果获取到的数据是0，在获取1次,最多三次
                        //                    int i =1;
                        //                    byte[] bytesFromHost = ImgBaseUtil.getBytesFromHost(value.getAbsolutePath());
                        //                    if(bytesFromHost==null || !(bytesFromHost.length>0)){
                        //                        while(i<3){
                        //                            logger.info(base.getId()+"第"+i+"次获取图片为空:{}",value.getAbsolutePath());
                        //                            bytesFromHost = ImgBaseUtil.getBytesFromHost(value.getAbsolutePath());
                        //                            i++;
                        //                            if(bytesFromHost!=null&&bytesFromHost.length>0){
                        //                                i=3;
                        //                            }
                        //                        }
                        //                    }
                        String newImg ="";
                        //                    if(bytesFromHost!=null && bytesFromHost.length>0){
                        //图片保存到本地先关闭
                        //                        ImgBaseUtil.writeImageToDisk(ImgBaseUtil.getBytesFromHost(value.getAbsolutePath()),savePath);
                        //暂不替换原content中的内容
                        //                        newImg = HtmlUtils.replaceHtmlTag(key, "img", "src", "src=\"", "\"", FileConstant.IMG_VIR_PATH+md5+"."+value.getSuffix());
                        //替换img便签中的alt内容，要不然过滤密点的时候，会加span会报错
                        //                        newImg = HtmlUtils.replaceHtmlTag(key, "img", "alt", "alt=\"", "\"","");
//                            newImg="<img style=\"width: 600px;\" src=\""+value.getAbsolutePath()+"\" />";
                        newImg="<img style=\"width: 600px;\" src=\"/adminser/image/base/"+md5+"\" />";
                        //压缩图片到50k转base64保存到数据库
                        System.out.println(111);
                        String imgUrlToBase64 = null;
                        try {
                            imgUrlToBase64 = ImgBaseUtil.compressPicForScale(value.getAbsolutePath(),50,base.getId()+key);
                        } catch (Exception e) {
                            System.out.println("图片失败"+value.getAbsolutePath());
                            // e.printStackTrace();
                        }
                        BaseDataImage baseDataImage = new BaseDataImage();
                        baseDataImage.setId(md5);
                        baseDataImage.setDataImage(imgUrlToBase64);
                        baseDataImage.setBid(base.getId());

                        System.out.println(1112222);
                        //                        int i1 = imageMapper.save(baseDataImage);
                        //                        if(i1!=1){
                        //                            logger.info("插入表cis_basedata_image失败,[{}]",base.getId(),key);
                        //                            throw new RuntimeException("插入表cis_basedata_image失败");
                        //                        }
                        //                    String newImg = HtmlUtils.replaceHtmlTag(key, "img", "src", "src=\"/" + value.getSuffix() + ";base64,", "\"", imgUrlToBase64);
                        //                    }else{
                        //                        //图片为空，说明原图片地址失效
                        //                        newImg ="";
                        //                    }

                        //暂不替换原content中的内容
                        if(StringUtils.isNotBlank(imgUrlToBase64)){
                            logger.info("替换[{}]中的原图片[{}]为[{}]",base.getId(),key,newImg);
                            System.out.println("tihuanchenggong");
                            imageList.add(baseDataImage);
                            base.setContent(base.getContent().replace(key,newImg));
                        }else{
                            System.out.println("kongtupianweipaqu");
                            base.setContent(base.getContent().replace(key,""));
                        }
                    });
                    result.add(base);
                }catch (Exception e){
                    logger.info("[{}]提取img报错：[{}]",basedata.getId(),e.getMessage());
                    continue;
                }
            }
        }
        map.put("basedata",result);
        map.put("imageList",imageList);
        return map;
    }

    /**
     * 对content中的img图片进行处理
     * @param data
     * @return
     */
    public Map<String, Object> imgHandlerbak(List<Basedata> data) {
        logger.info("对content中的img图片进行处理:{}",data);
        Map<String, Object> map = new HashMap<>();
        List<Basedata> result = new ArrayList<>();
        List<BaseDataImage> imageList =new ArrayList<>();
        if(data!=null&&data.size()>0){
            for (Basedata basedata : data) {
                Map<String, FileTag> contentFileTag = null;
                try{
                    contentFileTag =ContentFileFinder.getContentFileTag(basedata.getContent(), basedata.getSourceaddress());
                    if(contentFileTag==null || contentFileTag.size()<1){
                        result.add(basedata);
                        continue;
                    }
                    Basedata base = new Basedata();
                    BeanUtils.copyProperties(basedata,base);
                    //遍历map
                    contentFileTag.forEach((key,value)->{
                        //使用MD5加密：ID+图片的原网址
                        String md5 = DigestUtils.md5DigestAsHex((base.getId() + value.getAbsolutePath()).getBytes(StandardCharsets.UTF_8));
                        logger.info("加密后的md5值{}",md5);
                        //图片保存到本地先关闭
                        //图片保存路径：
    //                    String savePath = Global.getProfile() +md5+"."+value.getSuffix();
                        //保存图片到本地，本地路径文件夹
                        //先获取网络图片的大小，如果获取到的数据是0，在获取1次,最多三次
    //                    int i =1;
    //                    byte[] bytesFromHost = ImgBaseUtil.getBytesFromHost(value.getAbsolutePath());
    //                    if(bytesFromHost==null || !(bytesFromHost.length>0)){
    //                        while(i<3){
    //                            logger.info(base.getId()+"第"+i+"次获取图片为空:{}",value.getAbsolutePath());
    //                            bytesFromHost = ImgBaseUtil.getBytesFromHost(value.getAbsolutePath());
    //                            i++;
    //                            if(bytesFromHost!=null&&bytesFromHost.length>0){
    //                                i=3;
    //                            }
    //                        }
    //                    }
                        String newImg ="";
    //                    if(bytesFromHost!=null && bytesFromHost.length>0){
                            //图片保存到本地先关闭
    //                        ImgBaseUtil.writeImageToDisk(ImgBaseUtil.getBytesFromHost(value.getAbsolutePath()),savePath);
                            //暂不替换原content中的内容
    //                        newImg = HtmlUtils.replaceHtmlTag(key, "img", "src", "src=\"", "\"", FileConstant.IMG_VIR_PATH+md5+"."+value.getSuffix());
                            //替换img便签中的alt内容，要不然过滤密点的时候，会加span会报错
    //                        newImg = HtmlUtils.replaceHtmlTag(key, "img", "alt", "alt=\"", "\"","");
//                            newImg="<img style=\"width: 600px;\" src=\""+value.getAbsolutePath()+"\" />";
                        if(key.contains("<img")) {
                            newImg = "<img style=\"width: 600px;\" src=\"/adminser/image/base/" + md5 + "\" />";
                            //压缩图片到50k转base64保存到数据库
                            System.out.println(111);
                            String imgUrlToBase64 = null;
                            try {
                                imgUrlToBase64 = ImgBaseUtil.compressPicForScale(value.getAbsolutePath(),50,base.getId()+key);
                            } catch (Exception e) {
                                System.out.println("图片失败"+value.getAbsolutePath());
                                // e.printStackTrace();
                            }
                            BaseDataImage baseDataImage = new BaseDataImage();
                            baseDataImage.setId(md5);
                            baseDataImage.setDataImage(imgUrlToBase64);
                            baseDataImage.setBid(base.getId());
                            System.out.println(1112222);
                            //暂不替换原content中的内容
                            if(StringUtils.isNotBlank(imgUrlToBase64)){
                                logger.info("替换[{}]中的原图片[{}]为[{}]",base.getId(),key,newImg);
                                System.out.println("tihuanchenggong");
                                imageList.add(baseDataImage);
                                base.setContent(base.getContent().replace(key,newImg));
                            }else{
                                System.out.println("kongtupianweipaqu");
                                base.setContent(base.getContent().replace(key,""));
                            }
                            result.add(base);
                        }else if(key.contains("<video")){
                            newImg = "<video style=\"width: 600px;\" src=\"/adminser/image/base/" + md5 + "\" />";
                            //压缩图片到50k转base64保存到数据库
                            String imgUrlToBase64 = null;
                            try {
                                imgUrlToBase64 = ImgBaseUtil.compressVideoForScale(value.getAbsolutePath());
                            } catch (Exception e) {
                                System.out.println("视频下载失败"+value.getAbsolutePath());
                                // e.printStackTrace();
                            }
                            BaseDataImage baseDataImage = new BaseDataImage();
                            baseDataImage.setId("video_"+md5);
                            baseDataImage.setDataImage(imgUrlToBase64);
                            baseDataImage.setBid(base.getId());
                            //暂不替换原content中的内容
                            if(StringUtils.isNotBlank(imgUrlToBase64)){
                                logger.info("替换[{}]中的原视频[{}]为[{}]",base.getId(),key,newImg);
                                System.out.println("tihuanchenggong");
                                imageList.add(baseDataImage);
                                base.setContent(base.getContent().replace(key,newImg));
                            }else{
                                System.out.println("kongtupianweipaqu");
                                base.setContent(base.getContent().replace(key,""));
                            }
                        }

                    });
                    result.add(base);
                }catch (Exception e){
                    logger.info("[{}]提取img报错：[{}]",basedata.getId(),e.getMessage());
                    continue;
                }
            }
        }
        map.put("basedata",result);
        map.put("imageList",imageList);
        return map;
    }

    /**
     * 对content中的视频进行处理
     * @param map1
     * @return
     */
    public Map<String, Object> videoHandler(Map<String, Object> map) {
        List<Basedata> data=(List<Basedata>)map.get("basedata");
        logger.info("对content中的视频图片进行处理:{}",data.size());
//        Map<String, Object> map = new HashMap<>();
        List<Basedata> result = new ArrayList<>();
        List<BaseDataImage> videoList =new ArrayList<>();
        if(data!=null&&data.size()>0){
            for (Basedata basedata : data) {
                Map<String, FileTag> contentFileTag = null;
                try{
                    contentFileTag =ContentFileFinder.getContentVideoFileTag(basedata.getContent(), basedata.getSourceaddress());
                    if(contentFileTag==null || contentFileTag.size()<1){
                        result.add(basedata);
                        continue;
                    }
                    try {
                        Basedata base = new Basedata();
                        BeanUtils.copyProperties(basedata, base);
                        logger.info("对处理数据的标题:{}",base.getTitle());
                        //遍历map
                        Document document = Jsoup.parse(basedata.getContent());
                        for (String key : contentFileTag.keySet()) {
                            FileTag value = contentFileTag.get(key);
                            //使用MD5加密：ID+图片的原网址
                            String md5 = DigestUtils.md5DigestAsHex((value.getAbsolutePath()).getBytes(StandardCharsets.UTF_8));
                            logger.info("加密后的md5值{}" + md5);
                            String savePath = videoPath;
                            String id = basedata.getId() + "";
                            String url = value.getAbsolutePath();
                            String referer = basedata.getSourceaddress();
                            String path = savePath;
                            String vname = md5 + ".mp4";
                            ImgBaseUtil.sendDownloadInfo(id, url, referer, path, vname);
                            //保存图片到本地，本地路径文件夹
                            Document keyDoc = Jsoup.parse(key);
                            String src = keyDoc.select("video").attr("src");
                            Elements elements = document.select("*[src=\"" + src + "\"]");
                            for (Element e : elements) {
                                e.attr("src", "/video/" + vname);
                            }
                            BaseDataImage baseDataImage = new BaseDataImage();
                            baseDataImage.setId(md5);
                            baseDataImage.setDataImage(vname);
                            baseDataImage.setBid(base.getId());
                            //暂不替换原content中的内容
                            if(StringUtils.isNotBlank(vname)){
                                logger.info("替换[{}]中的原图片[{}]为[{}]",base.getId(),key,md5);
                                System.out.println("视频tihuanchenggong");
                                videoList.add(baseDataImage);
                                base.setContent(base.getContent().replace(key,md5));
                            }else{
                                System.out.println("视频weipaqu");
                                base.setContent(base.getContent().replace(key,""));
                            }
                        }
                        base.setContent(document.outerHtml());
                        result.add(base);
                    }catch (Exception e){
                        result.add(basedata);
                        logger.info("视频处理解析失败");
                    }
                }catch (Exception e){
                    logger.info("[{}]提取img报错：[{}]",basedata.getId(),e.getMessage());
                    result.add(basedata);
                    continue;
                }
            }
        }
        List<BaseDataImage> imageList=new ArrayList<>();
        try {
            imageList = (List<BaseDataImage>) map.get("imageList");
            if (videoList.size() > 0) {
                imageList.addAll(videoList);
            }
            map.put("basedata", result);
            map.put("imageList", imageList);
        }catch (Exception e){
            map.put("basedata", result);
            map.put("imageList", imageList);
        }
        return map;
    }



    public Basedata getContent() {
        return baseMapper.getContent();
    }
    /**
     * 保存到es库中
     */
    public void syncEsData(List<Basedata> list){
//        logger.info("同步到es库中{}",list);
        logger.info("同步到es库中");
        if(list!=null&&list.size()>0){
            List<Basedata> collect = list.stream().map(basedata -> {
                basedata.setContent(null);
                basedata.setFeaturewords(null);
                basedata.setPublishDate(EsDateUtil.esFieldDateFormat(basedata.getPublishDate()));
                basedata.setCreateDate(EsDateUtil.esFieldDateFormat(basedata.getCreateDate()));
                return basedata;
            }).collect(Collectors.toList());
//            esOpUtil.docSavaBulkAsync("kgj",collect);
            for (Basedata basedata :
                    collect) {
                esOpUtil.docSavaByEntity("kgj",basedata.getId(),basedata);
            }
        }
    }

    /**
     * 通过密点库进行过滤，有密点的都标记为疑似信息
     * @param data
     * @return
     */
    public Map<String, Object> secret(List<Basedata> data,List<BasedataType> typeList) {
//        logger.info("过滤密点信息data:[{}],typeData:[{}]",data,typeList);
        logger.info("过滤密点信息");
//        long l = System.currentTimeMillis();
//        System.out.println("密点过滤开始时间："+l);
        Map<String, Object> result = new HashMap<>();
        //查询所有的密点
        QueryWrapper<CesSysSecret> wrapper = new QueryWrapper<>();
        //关键字
        wrapper.eq("type",0);
        List<CesSysSecret> secretList = secretService.list(wrapper);
        List<Basedata> dataResult = new ArrayList<>();
        List<BasedataType> typeDataResult = new ArrayList<>();
        //密点等级
        Map<String,Long> secretLevelMap = new HashMap<>();
        if(secretList!=null && secretList.size()>0){
            //按照密点内容的大小进行排序
            Collections.sort(secretList, new Comparator<CesSysSecret>() {
                @Override
                public int compare(CesSysSecret o1, CesSysSecret o2) {
                    if(o1.getContent().length()<o2.getContent().length()){
                        return 1;
                    }else if(o1.getContent().length() == o2.getContent().length()){
                        return 0;
                    }
                    return -1;
                }
            });
            if(data!=null && data.size()>0){
                Map<Long, BasedataType> typeMap = typeList.stream().collect(Collectors.toMap(BasedataType::getBid, BasedataType -> BasedataType));
                for (Basedata datum : data) {
                    boolean b = false;
                    if(StringUtils.isBlank(datum.getContentNoTag())){
                        //如果contentNoTag字段为空，则把content里边的内容拿出来，去标签存进去
                        logger.info("{}没有contentNoTag内容",datum.getId());
                        if(StringUtils.isNotBlank(datum.getContent())){
                            String text = Jsoup.parse(datum.getContent()).text();
                            if(StringUtils.isNotBlank(text)){
                                datum.setContentNoTag(text);
                            }else{
                                datum.setContentNoTag("");
                            }
                        }else{
                            //如果内容字段也为空
                            datum.setContentNoTag("");
                        }
                    }
                    //所包含的密点内容
                    StringBuilder containSecret =new StringBuilder();
                    //密点等级
                    Long secretLevel=null;
                    for (CesSysSecret cesSysSecret : secretList) {
                        //密点内容可能为：航母 战斗机  中间有空格，只有同时符合这两个内容的时候才算是符合密点
                        if(StringUtils.isBlank(cesSysSecret.getContent())){
                            //密点内容为空，直接进行下一个
                            continue;
                        }
                        //通过空格拆分
                        String[] secretArray = cesSysSecret.getContent().split(" ");
                        boolean contain =true;
                        for (String s : secretArray) {
                            if(StringUtils.isNotBlank(s)){
                                //防止有多个空格在一起，拆分后还是存在空格，所以做判断
                                if(!(datum.getContentNoTag().contains(s))){
                                    //如果不包含单个密点
                                    contain = false;
                                }
                            }
                        }
                        if(contain){
                           //说明都包含
                            b = true;
                            //外网同步程序不加颜色

                            //改回加颜色
                            for (String s : secretArray) {
                                datum.setContent(datum.getContent().replaceAll(s,
                                        SecretColorConstant.SPAN_COLOR_START+s+SecretColorConstant.SPAN_COLOR_END));
                            }
                            containSecret.append(cesSysSecret.getContent()).append(";");
                            if(cesSysSecret.getSecretLevel()!=null){
                                //密点等级不为空
                                if(secretLevel==null){
                                    //直接赋值密点等级
                                    secretLevel=cesSysSecret.getSecretLevel();
                                }else{
                                    //不等于空，则判断两者大小
//                                    if(cesSysSecret.getSecretLevel().compareTo(secretLevel)>0){
//                                        //该密点等级比较大，则以最高的密点等级为主
//                                        secretLevel=cesSysSecret.getSecretLevel();
//                                    }

                                    //modify Lihuawei 2022 4.11
                                    //重写分数计算方式 相加
                                    secretLevel=secretLevel+cesSysSecret.getSecretLevel();
                                }
                            }                        }
                    }
                    if(b){
                        //处理type表中的数据，标记为疑似信息
                        BasedataType basedataType = typeMap.get(new Long(datum.getId()));
                        if(basedataType!=null){
                            basedataType.setDelflag(2L);
                            typeMap.put(new Long(datum.getId()),basedataType);
                        }
                        datum.setDelflag(2L);

                        //ES 索引增加分数字段 add lihuawei 22 4 11
                        Integer wordscount=1;
                        try {

                            wordscount=secretLevel.intValue();
                        }catch (Exception e){

                        }
                        datum.setWordsCount(wordscount);
                    }
                    String s = containSecret.toString();
                    //如果有包含的密点内容
                    if(containSecret.length()>0){
                        //如果长度大于1000，则截取到1000
                        if(containSecret.length()>1000){
                            s = containSecret.substring(0,1000);
                        }
                        //把最后一个分号去掉
                        s = s.substring(0,s.lastIndexOf(";"));
//                        containSecret.deleteCharAt(containSecret.length()-1);
                    }
                    datum.setReliability(s);
                    dataResult.add(datum);
                    secretLevelMap.put(datum.getId(),secretLevel);
                }
                typeDataResult = new ArrayList<>(typeMap.values());
            }
            result.put("data",dataResult);
            result.put("typeData",typeDataResult);
            result.put("secretLevelMap",secretLevelMap);
        }else{
            //密点库没有密点，直接返回之前的data和typedata
            result.put("data",data);
            result.put("typeData",typeList);
            result.put("secretLevelMap",secretLevelMap);
        }
        long l1 = System.currentTimeMillis();
//        System.out.println("密点过滤结束时间："+l1);
//        System.out.println("密点过滤花费时间"+(l1-l));
        return result;
    }

    /**
     * 获取疑似文章内容中相关地区
     * @param basedataList
     * @param secretLevelMap
     * @return
     */
    public Map<String, Object> getLocal(List<Basedata> basedataList, Map<String, Long> secretLevelMap){
        Map<String, Object> result = new HashMap<>();
        if(secretLevelMap==null){
            secretLevelMap=new HashMap<>();
        }
        result.put("baseDataList",basedataList);
        Set<String> set = new HashSet<>();
        List<CesSysWeb> cesSysWebList =new ArrayList<>();
        List<CesSysWeb> newWebList = new ArrayList<>();
        List<BaseDataWebMid> baseDataWebList =new ArrayList<>();
        if(CollectionUtils.isEmpty(basedataList)){
            logger.info("所需过滤的文章数量为空");
            //返回传过来的数据
            result.put("baseDataList",basedataList);
            result.put("exitWebList",cesSysWebList);
            result.put("newWebList",newWebList);
            result.put("baseDataWebList",baseDataWebList);
            return result;
        }
        //先查所有网站
        QueryWrapper<CesSysWeb> cesSysWebQueryWrapper = new QueryWrapper<>();
        List<CesSysWeb> cesSysWebs = webMapper.selectList(cesSysWebQueryWrapper);
        for (Basedata basedata : basedataList) {
            try {
                if (StringUtils.isNotBlank(basedata.getSourceaddress())) {
                    int i = StringUtils.ordinalIndexOf(basedata.getSourceaddress(), "/", 3);
                    String substring = basedata.getSourceaddress().substring(0, i);


                    if(substring.contains("mp.weixin")){
                        //微信网站
                        //判断作者的
                        String author=basedata.getAuthor().trim();
                        if(StringUtils.isNotEmpty(author)){

                            for (int j = 0; j < cesSysWebs.size(); j++) {
                                CesSysWeb cesSysWeb =  cesSysWebs.get(j);
                                //如果要系统内设置的网站str输入在这个信息URL中，则判断为是这个网站的信息
                                //例如 sina.com  在 http://www.sina.com/123.html
                                //int indexnum=StringUtils.ordinalIndexOf(cesSysWeb.getUrl(), "/", 2);
                                String urlstr = cesSysWeb.getUrl().replace("https://","").replace("http://","");

                                if(author.equals(urlstr.trim())){
                                    BaseDataWebMid baseDataWebMid = new BaseDataWebMid();
                                    baseDataWebMid.setBId(new Long(basedata.getId()));
                                    baseDataWebMid.setWebId(cesSysWeb.getId());
                                    baseDataWebMid.setSecretLevel(secretLevelMap.get(basedata.getId()));
                                    baseDataWebList.add(baseDataWebMid);
                                }
                            }

                        }


                    }else{

                        //普通网站
                        for (int j = 0; j < cesSysWebs.size(); j++) {
                            CesSysWeb cesSysWeb =  cesSysWebs.get(j);
                            //如果要系统内设置的网站str输入在这个信息URL中，则判断为是这个网站的信息
                            //例如 sina.com  在 http://www.sina.com/123.html
                            //int indexnum=StringUtils.ordinalIndexOf(cesSysWeb.getUrl(), "/", 2);
                            String urlstr = cesSysWeb.getUrl().replace("https://","").replace("http://","");

                            if(substring.contains(urlstr)){
                                BaseDataWebMid baseDataWebMid = new BaseDataWebMid();
                                baseDataWebMid.setBId(new Long(basedata.getId()));
                                baseDataWebMid.setWebId(cesSysWeb.getId());
                                baseDataWebMid.setSecretLevel(secretLevelMap.get(basedata.getId()));
                                baseDataWebList.add(baseDataWebMid);
                            }
                        }
                    }
//                    int i = StringUtils.ordinalIndexOf(basedata.getSourceaddress(), "/", 3);
//                    String substring = basedata.getSourceaddress().substring(0, i);
//                    if (cesSysWeb != null && cesSysWeb.getId() != null) {
//                        BaseDataWebMid baseDataWebMid = new BaseDataWebMid();
//                        baseDataWebMid.setBId(new Long(basedata.getId()));
//                        baseDataWebMid.setWebId(cesSysWeb.getId());
//                        baseDataWebMid.setSecretLevel(secretLevelMap.get(basedata.getId()));
//                        baseDataWebList.add(baseDataWebMid);
//                    }
                    //判断该条信息的来源是否是科工局下边的子机构，如果是政府网站，则不进行抽取
                    WebTypeVo webTypeVo = webMapper.isKgj(substring);
                    if (webTypeVo != null && webTypeVo.getWebTypeId() == 1L) {
                        //网站分类是1代表是政府网站，说明不是科工局下边的子机构，所以不处理，不调用百度
                        continue;
                    }
                    if (basedata.getDelflag() != null && basedata.getDelflag() == 2L) {
                        //该条信息是疑似信息，才进行文章内容相关地区的获取
                        String contentNoTag = basedata.getContentNoTag();
                        if (StringUtils.isBlank(contentNoTag)) {
                            //不带标签的内容为空，把带标签的内容转换出来
                            String text = Jsoup.parse(basedata.getContent()).text();
                            basedata.setContentNoTag(text);
                        }
                        //文章内容不为空
                        //1.先调用python接口，通过hanlp提取地区
                        //String hanlpResult = getHanlpResult(basedata.getContentNoTag());
                        String hanlpResult = "";
                        if (StringUtils.isBlank(hanlpResult)) {
                            //地区内容为空,说明文章内容没有关联地区政府名称
                            continue;
                        }
                        String[] split = hanlpResult.split(",");
                        if (split == null || split.length == 0) {
                            continue;
                        }
                        for (String s : split) {
                            if (s.endsWith("省")) {
                                set.add(s);
                            } else if (s.endsWith("市")) {
                                set.add(s);
                            } else if (s.endsWith("县")) {
                                set.add(s);
                            } else if (s.endsWith("自治区")) {
                                set.add(s);
                            } else if (s.endsWith("自治州")) {
                                set.add(s);
                            }
                        }
                    }
                }
            }catch(Exception e ){
                logger.info("获取文章内容地区出错");
                continue;
            }
        }
        if(set.size()==0){
            logger.info("过滤的文章关联政府地区为空");
            result.put("baseDataList",basedataList);
            result.put("exitWebList",cesSysWebList);
            result.put("newWebList",newWebList);
            result.put("baseDataWebList",baseDataWebList);
            return result;
        }
        //2.查询数据库中，这些政府网站是否已经存在，存在则更新，不存在则调用百度存入数据库
        QueryWrapper<CesSysWeb> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("NAME",set);
        queryWrapper.eq("URL_TYPE",2L);
         cesSysWebList = webMapper.selectList(queryWrapper);
        //获取当前日期7天后的时间。
        //当前日期
        Date date = new Date();
        //7天后的日期
        Date sevenDate = new Date();
        try {
            sevenDate = TimeUtil.afterDate(date, 7);
        } catch (Exception e) {
            logger.info("获取7天后时间失败");
            e.printStackTrace();
        }
        for (CesSysWeb cesSysWeb : cesSysWebList) {
            //移除数据库中已经存在的网址
            set.remove(cesSysWeb.getName());
            cesSysWeb.setEndTime(sevenDate);
        }
        if(set.size()==0){
            result.put("baseDataList",basedataList);
            result.put("exitWebList",cesSysWebList);
            result.put("newWebList",newWebList);
            result.put("baseDataWebList",baseDataWebList);
            return result;
        }

        //3.调用百度搜索，查询政府网站的网址
        for (String s : set) {
            String baiDuResult ="";
            try{
                 baiDuResult = getBaiDuResult(s);
            }catch (Exception e ){
                logger.info("抽取文章内容地区，调用百度出错");
                continue;
            }
            if(StringUtils.isNotBlank(baiDuResult)){
                //网址内容不为空
                if(baiDuResult.endsWith("/")){
                    baiDuResult =baiDuResult.substring(0,baiDuResult.length()-1);
                }
                CesSysWeb cesSysWeb = new CesSysWeb();
                cesSysWeb.setName(s);
                cesSysWeb.setUrl(baiDuResult);
                cesSysWeb.setUrlType(2L);
                cesSysWeb.setStartTime(date);
                cesSysWeb.setEndTime(sevenDate);
                cesSysWeb.setCreateBy("admin");
                cesSysWeb.setCreateTime(date);
                newWebList.add(cesSysWeb);
            }
        }
        result.put("baseDataList",basedataList);
        result.put("exitWebList",cesSysWebList);
        result.put("newWebList",newWebList);
        result.put("baseDataWebList",baseDataWebList);
        return result;
    }

    /**
     * 调用python接口，获取hanlp分词后的结果
     * @param text
     * @return
     */
    public String getHanlpResult(String text){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
        map.add("text", text);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<String> response = restTemplate.postForEntity( hanlpUrl, request , String.class );
        String body = response.getBody();
        //JSON对象转为map类型
        Map hanlpMap = JSON.parseObject(body, Map.class);
        if(hanlpMap==null){
            return null;
        }
        if(hanlpMap.get("location")==null){
            return null;
        }
        return (String) hanlpMap.get("location");
    }
    /**
     * 从配置文件读取需要筛选的地区
     * @return
     */
    public  List<String> readFile() {
        List<String> names = new ArrayList<>();
        Properties properties = System.getProperties();
        String path = PageConstant.LOCATION_PATH;
        String s = properties.getProperty("user.dir");
        if (properties.getProperty("os.name").toLowerCase().contains("win")) {
            s += "\\";
        }else {
            s += "/";
        }
//        将符号“\\”和“\”替换成“/”,有时候便于统一的处理路径的分隔符,避免同一个路径出现两个或三种不同的分隔符
        path = (s+path).replace("\\", "/").replace("\\\\", "/");
        logger.info("local.txt的path路径为{}",path);
        if (StringUtils.isBlank(path)) {
            logger.info("文件路径为空");
            return names;
        }
        //防止文件建立或读取失败，用catch捕捉错误并打印，也可以throw;
        //不关闭文件会导致资源的泄露，读写文件都同理
        //try-with-resources可以优雅关闭文件，异常时自动关闭文件；详细解读https://stackoverflow.com/a/12665271
        try (
                FileInputStream reader = new FileInputStream(path);
                BufferedReader br = new BufferedReader(new InputStreamReader(reader,"UTF-8")) // 建立一个对象，它把文件内容转成计算机能读懂的语言
        ) {
            String line;
            //网友推荐更加简洁的写法
            while ((line = br.readLine()) != null) {
                // 一次读入一行数据
                // System.out.println("===="+line);
                names.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return names;
    }
    /**
     * 调用百度搜索接口，获取政府网站的url结果
     * @param name
     * @return
     */
    public String getBaiDuResult(String name){
        //设置代理
        //先从redis获取代理的ip和端口，如果redis没有，在调用代理服务器生成新的ip和端口
//        String proxy = redisTemplate.opsForValue().get(CacheConstant.PROXY_KEY);
//        if(StringUtils.isBlank(proxy)){
//            //缓存中没有调用代理服务器获取代理IP和端口
//            ResponseEntity<String> forEntity = restTemplate.getForEntity(proxyUrl, String.class);
//            if(!"200".equals(forEntity.getStatusCodeValue())){
//                //调用代理服务器失败
//                logger.info("调用代理服务器失败");
//                return "";
//            }
//            //调用成功，获取到代理服务器返回的IP和端口是这样格式的123.73.208.164:32223
//            String body = forEntity.getBody();
//            redisTemplate.opsForValue().set(CacheConstant.PROXY_KEY,body,3, TimeUnit.MINUTES);
//            proxy=body;
//        }
//        String[] split = proxy.split(":");
//        String proxyIp =split[0];
//        String proxyPort =split[1];
//        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
//        requestFactory.setProxy(
//                new Proxy(
//                        Proxy.Type.HTTP,
//                        new InetSocketAddress(proxyIp, proxyPort)  //设置代理服务
//                )
//        );
//        RestTemplate restTemplate = new RestTemplate(requestFactory);
        Map<String, String> map = new HashMap<>();
        map.put("name", name+CacheConstant.BAIDU_NAME);
        ResponseEntity response  = restTemplate.getForEntity(CacheConstant.BAIDU_URL+"{name}", String.class,map);
        if(!(200==response.getStatusCodeValue())){
            //调用百度接口，状态码不是200，不成功
            logger.info("调用百度搜索不成功");
            return "";
        }
        String body = (String) response.getBody();
        Document parse = Jsoup.parse(body);
        Elements elementsByClass = parse.getElementsByClass("OP_LOG_LINK c-text c-text-public c-text-mult c-gap-left-small");
        if(!(elementsByClass.size()>0)){
            //带官方的元素为空，说明没有
            logger.info(name+"没有带官方的网站");
            return "";
        }
        //获取第一个带官方的元素
        Element element = elementsByClass.get(0);
        //获取带官方的元素前一个兄弟元素
        Element element2 = element.previousElementSibling();
        String href = element2.attr("href");
        System.out.println("href"+href);
        String href1 = href.replace("http","https")+"&wd=&eqid=";
        System.out.println("href1"+href1);
        ResponseEntity response1 = restTemplate.getForEntity(href1, String.class);
        String body1 = (String) response1.getBody();
        Document parse1 = Jsoup.parse(body1);
        Elements noscript = parse1.getElementsByTag("noscript");
        Element element3 = noscript.get(0);
        Elements meta = element3.getElementsByTag("meta");
        String url = meta.attr("content");
        String s = "";
        if(StringUtils.isNotBlank(url)){
            int i = url.indexOf("'");
            if(i!=-1 && i+1<url.length()-1){
                s = url.substring(i + 1, url.length() - 1);
            }
        }
        return s;
    }
}
