2021-06-30 09:43:37(地域位置、oss导出列表...)

1.地域位置相关

package com.gongsibao.controller;

import com.gongsibao.common.util.BeanValidators;
import com.gongsibao.core.base.BaseController;
import com.gongsibao.core.base.BaseResponse;
import com.gongsibao.request.AreasRequest;
import com.gongsibao.service.AreaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author hkxie
 * @Date 2021/6/11
 * @Description
 **/
@Api(tags = "地域位置相关")
@RestController
@RequestMapping("/area")
public class AreaController extends BaseController {

    @Autowired
    private AreaService areaService;

    @ApiOperation(value = "获取政策区域列表", notes = "获取政策区域列表(筛选条件)")
    @RequestMapping(value = "/listPolicyAreas", method = RequestMethod.POST)
    public BaseResponse listPolicyAreas(@RequestBody AreasRequest vo) {
        BeanValidators.validateWithException(validator, vo);
        return areaService.listPolicyAreas(vo);
    }

    @ApiOperation(value = "获取全部城市(地级市)列表", notes = "获取全部城市(地级市)列表")
    @RequestMapping(value = "/listCities", method = RequestMethod.GET)
    public BaseResponse listCities() {
        return areaService.listCities();
    }

    @ApiOperation(value = "获取全部城市(地级市)列表(树型)", notes = "获取全部城市列表(树型)")
    @RequestMapping(value = "/listTreeCity", method = RequestMethod.GET)
    public BaseResponse listTreeCity(HttpServletRequest request) {
        return areaService.listTreeCity(request);
    }

    @ApiOperation(value = "只获取北京地区城市列表(树型)", notes = "只获取北京地区城市列表(树型)")
    @RequestMapping(value = "/listTreeCityOnlyBeijing", method = RequestMethod.GET)
    public BaseResponse listTreeCityOnlyBeijing(HttpServletRequest request) {
        return areaService.listTreeCityOnlyBeijing(request);
    }

    @ApiOperation(value = "获取地区(省份)表【拼音排序】", notes = "获取地区(省份)表")
    @RequestMapping(value = "/listProvinceByLetter", method = RequestMethod.GET)
    public BaseResponse listProvinceByLetter(HttpServletRequest request) {
        return areaService.listProvinceByLetter(request);
    }

    @ApiOperation(value = "获取地区(城市)表【拼音排序】", notes = "获取地区(城市)表")
    @RequestMapping(value = "/listCityByLetter", method = RequestMethod.GET)
    public BaseResponse listCityByLetter() {
        return areaService.listCityByLetter();
    }
}
package com.gongsibao.entity;


import lombok.Data;

import java.util.List;

/**
 * @author : huangzhanghong
 * @date : 2021-05-18 13:41
 * 构建树结构实体
 **/
@Data
public class TreeNode {

    /**
     * ID
     */
    private String id;

    /**
     * 父节点ID
     */
    private String parentId;

    /**
     * 名称
     */
    private String name;


    /**
     * 别名
     */
    private String nickname;


    private Integer level;


    List<TreeNode> children;

    /**
     * 空构造
     */
    public TreeNode() {

    }

}
package com.gongsibao.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gongsibao.common.enums.GlobalEnum;
import com.gongsibao.common.util.IpAddressUtils;
import com.gongsibao.common.util.ip.ClientIp;
import com.gongsibao.common.util.ip.IpUtil;
import com.gongsibao.core.base.BaseResponse;
import com.gongsibao.entity.Area;
import com.gongsibao.entity.Dept;
import com.gongsibao.entity.TreeNode;
import com.gongsibao.mapper.AreaMapper;
import com.gongsibao.mapper.DeptMapper;
import com.gongsibao.request.AreasRequest;
import com.gongsibao.response.AreasResponse;
import com.gongsibao.response.CityTreeListResponse;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 区域服务类
 *
 * @author huangzhanghong
 */
@Service
@Slf4j
public class AreaService {

    @Resource
    private AreaMapper areaMapper;

    @Resource
    private DeptMapper deptMapper;

    /**
     * 直辖市code
     */
    private static final String REGISTER_AREA_ZXS_CODE = "RegisterArea_ZXS";

    /**
     * 国家部委CODE
     */
    private static final String REGISTER_AREA = "RegisterArea_";

    /**
     * 默认当前地区北京市CODE
     */
    private static final String BEIJING_AREA_CODE = "RegisterArea_ZXS_Beijing";


    /**
     * 获取区域列表、受理部门,用作查询筛选列表
     *
     * @param vo currentArea 当前所在地区、 city 政策区域
     * @return 政策区域、受理部门
     */
    public BaseResponse<AreasResponse> listPolicyAreas(AreasRequest vo) {

        String currentAreaCode = vo.getCurrentAreaCode();
        String cityCode = vo.getCityCode();
        log.info("查询所在地区{},所在地区下属{},政策区域和受理部门信息", currentAreaCode, cityCode);

        //返回结果包装
        AreasResponse response = new AreasResponse();
        HashMap<String, String> areaMap = new LinkedHashMap<>();

        //查询出当前区域详情
        Area currentArea = areaMapper.selectOne(Wrappers.<Area>lambdaQuery()
                .eq(Area::getAreaCode, currentAreaCode)
                .eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType()));
        if (ObjectUtils.isEmpty(currentArea)) {
            return BaseResponse.error("当前区域输入无效");
        }
        //查询出当前区域所属省份
        List<Area> province = areaMapper.selectList(Wrappers.<Area>lambdaQuery()
                .eq(Area::getAreaCode, currentArea.getParentCode())
                .eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType()));
        if (CollectionUtils.isEmpty(province)) {
            return BaseResponse.error("当前区域输入无效,请检查输入是否合法");
        }

        //全局添加部委项目政策区域
        areaMap.put(REGISTER_AREA, "部委项目");

        //对于直辖市不进行返回所属省
        if (!REGISTER_AREA_ZXS_CODE.equals(province.get(0).getAreaCode())) {
            areaMap.put(province.get(0).getAreaCode(), province.get(0).getAreaName());
        }
        areaMap.put(currentArea.getAreaCode(), currentArea.getAreaName());

        LambdaQueryWrapper<Area> lambda = Wrappers.lambdaQuery();
        lambda.eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        lambda.eq(!StringUtils.isEmpty(currentAreaCode), Area::getParentCode, currentAreaCode);
        List<Area> areas = areaMapper.selectList(lambda);
        areas.forEach(x -> areaMap.put(x.getAreaCode(), x.getAreaName()));
        response.setPolicyArea(areaMap);

        //城市不为空时查询出特定市的受理部门,为空则查询出当前区域(市)下属所有受理部门
        response.setReceivingDept(listReceivingDept(StringUtils.isEmpty(cityCode) ? currentAreaCode : cityCode));
        return BaseResponse.success(response);
    }

    /**
     * 根据区域code码查询出受理部门
     *
     * @param cityCode 区域Code码
     * @return 受理部门
     */
    private HashMap<String, String> listReceivingDept(String cityCode) {
        LambdaQueryWrapper<Dept> query = Wrappers.lambdaQuery();
        query.eq(Dept::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        query.eq(!StringUtils.isEmpty(cityCode), Dept::getAreaCode, cityCode);
        List<Dept> departments = deptMapper.selectList(query);
        if (CollectionUtils.isEmpty(departments)) {
            return new HashMap<>();
        }
        HashMap<String, String> deptMap = new LinkedHashMap<>(32);
        departments.forEach(x -> deptMap.put(x.getId(), x.getDeptFullName()));
        return deptMap;
    }

    /**
     * 获取全部城市(地级市)列表
     *
     * @return 城市(地级市)列表
     */
    public BaseResponse<List<JSONObject>> listCities() {
        log.info("获取全部城市列表服务开始");
        LambdaQueryWrapper<Area> lambda = Wrappers.lambdaQuery();
        lambda.eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        //获取所有省级
        lambda.eq(Area::getLevel, GlobalEnum.CITY_LEVEL.getType());
        List<Area> areas = areaMapper.selectList(lambda);
        //返回结果处理
        List<JSONObject> jsonObjects = new LinkedList<>();
        areas.forEach(x -> {
            JSONObject object = new JSONObject();
            object.put("label", x.getAreaName());
            object.put("value", x.getAreaCode());
            jsonObjects.add(object);
        });
        return BaseResponse.success(jsonObjects);
    }


    /**
     * 获取全部城市列表(树型)
     *
     * @return 城市列表(树型)
     */
    public BaseResponse<CityTreeListResponse> listTreeCity(HttpServletRequest request) {
        log.info("获取城市列表(树型)");
        CityTreeListResponse response = new CityTreeListResponse();
        LambdaQueryWrapper<Area> lambda = Wrappers.lambdaQuery();
        lambda.eq(Area::getState, 1);
        lambda.eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        //获取所有省级以及市级
        lambda.and(q -> q.eq(Area::getLevel, GlobalEnum.PROVINCE_LEVEL.getType())
                .or().eq(Area::getLevel, GlobalEnum.CITY_LEVEL.getType()));
        List<Area> areas = areaMapper.selectList(lambda);
        List<TreeNode> list = new LinkedList<>();

        areas.forEach(x -> {
            TreeNode treeNode = new TreeNode();
            treeNode.setId(x.getAreaCode());
            treeNode.setParentId(x.getParentCode());
            treeNode.setName(x.getAreaName());
            treeNode.setNickname(x.getAreaValue());
            treeNode.setLevel(x.getLevel());
            treeNode.setChildren(new ArrayList<>());
            list.add(treeNode);
        });

        //GlobalEnum.CITY_LEVEL.getType() 设置为1 只取北京市
        //List<TreeNode> build = build(list, GlobalEnum.CITY_LEVEL.getType());
        List<TreeNode> build = build(list, GlobalEnum.PROVINCE_LEVEL.getType());
        response.setCurrentArea(getAreaCode(request));
        response.setTreeList(build);
        return BaseResponse.success(response);
    }

    /**
     * @param request
     * @return
     */
    public BaseResponse<CityTreeListResponse> listTreeCityOnlyBeijing(HttpServletRequest request) {
        log.info("只展示北京(树型)");
        CityTreeListResponse response = new CityTreeListResponse();
        LambdaQueryWrapper<Area> lambda = Wrappers.lambdaQuery();
        lambda.eq(Area::getState, 1);
        lambda.eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        //只获取北京市
        lambda.eq(Area::getAreaCode, BEIJING_AREA_CODE);
        List<Area> areas = areaMapper.selectList(lambda);
        List<TreeNode> list = new LinkedList<>();
        areas.forEach(x -> {
            TreeNode treeNode = new TreeNode();
            treeNode.setId(x.getAreaCode());
            treeNode.setParentId(x.getParentCode());
            treeNode.setName(x.getAreaName());
            treeNode.setNickname(x.getAreaValue());
            treeNode.setLevel(x.getLevel());
            treeNode.setChildren(new ArrayList<>());
            list.add(treeNode);
        });
        //GlobalEnum.CITY_LEVEL.getType() 设置为1 只取北京市
        List<TreeNode> build = build(list, GlobalEnum.CITY_LEVEL.getType());
        //默认只为北京
        ClientIp clientIp = new ClientIp();
        clientIp.setIp("");
        clientIp.setCountry("");
        clientIp.setProvince("");
        clientIp.setCity("北京市");
        clientIp.setIsp("");
        clientIp.setCityCode("RegisterArea_ZXS_Beijing");
        response.setCurrentArea(clientIp);
        response.setTreeList(build);
        return BaseResponse.success(response);
    }


    /**
     * 根据单词首字母获取地区(省份)表
     *
     * @return 省份列表按字母排序
     */
    public BaseResponse listProvinceByLetter(HttpServletRequest request) {
        Multimap<String, TreeNode> multiMap = ArrayListMultimap.create();
        List<TreeNode> data = listTreeCity(request).getData().getTreeList();
        data.forEach(x -> {
                    if (!REGISTER_AREA_ZXS_CODE.equals(x.getId())) {
                        String key = String.valueOf(x.getNickname().charAt(0)).toUpperCase();
                        multiMap.put(key, x);
                    } else {
                        //将直辖市单独排在首位
                        multiMap.put("@", x);
                    }
                }
        );
        return BaseResponse.success(multiMap);
    }

    /**
     * 按拼音首字母返回城市列表
     *
     * @return 城市列表
     */
    public BaseResponse listCityByLetter() {
        LambdaQueryWrapper<Area> lambda = Wrappers.lambdaQuery();
        lambda.eq(Area::getIsEnabled, GlobalEnum.IS_ENABLE.getType());
        //获取所有城市
        lambda.eq(Area::getLevel, GlobalEnum.CITY_LEVEL.getType());
        List<Area> areas = areaMapper.selectList(lambda);
        HashMap<String, List<JSONObject>> map = new LinkedHashMap<>(32);
        for (int i = 65; i < 91; i++) {
            //初始化返回数据结构
            map.put(String.valueOf((char) i), new ArrayList<>());
        }

        areas.forEach(x -> {
            String key = String.valueOf(x.getAreaValue().charAt(0)).toUpperCase();
            if (map.containsKey(key)) {
                JSONObject object = new JSONObject();
                object.put("label", x.getAreaName());
                object.put("value", x.getAreaCode());
                map.get(key).add(object);
            }
        });
        map.values().removeIf(ObjectUtils::isEmpty);
        return BaseResponse.success(map);
    }

    /**
     * 获取默认的地区码
     *
     * @return
     */
    public ClientIp getDefaultAreaCode() {
        ClientIp defaultClientIp = new ClientIp();
        defaultClientIp.setCityCode(BEIJING_AREA_CODE);
        defaultClientIp.setCity("北京市");
        return defaultClientIp;
    }

    /**
     * 根据当前请求的来源ip获取地区码
     *
     * @param request
     * @return ClientIp
     */
    public ClientIp getAreaCode(HttpServletRequest request) {
        // 获取默认的地区码
        ClientIp defaultClientIp = getDefaultAreaCode();
        try {
            //通过IP获取当前地区
            String ipAddress = IpAddressUtils.getIpAddress(request);
            ClientIp clientIp = IpUtil.parseClientIp(ipAddress);
            if (ObjectUtils.isEmpty(clientIp)) {
                String city = clientIp.getCity();
                if (StringUtils.isEmpty(city)) {
                    return defaultClientIp;
                }
                Area area = areaMapper.selectOne(Wrappers.lambdaQuery(Area.class)
                        .eq(Area::getLevel, GlobalEnum.CITY_LEVEL.getType())
                        .select(Area::getAreaCode).like(Area::getAreaName, city));
                if (ObjectUtils.isEmpty(area)) {
                    return defaultClientIp;
                }
                clientIp.setCityCode(area.getAreaCode());
                clientIp.setCity(area.getAreaName());
                return clientIp;
            }
            return defaultClientIp;
        } catch (Exception e) {
            log.error("通过IP获取当前地区出现异常{}", e.getMessage(), e);
        }
        return defaultClientIp;
    }

    /**
     * 构建城市树结构列表
     *
     * @param list  数据集合
     * @param level 根节点级别
     * @return 城市列表(树型)
     */
    public static List<TreeNode> build(List<TreeNode> list, Integer level) {
        final List<TreeNode> treeList = new ArrayList<>(list);
        List<TreeNode> finalTreeList = new ArrayList<>();
        for (TreeNode node : treeList) {
            //如果是根结点
            if (level.equals(node.getLevel())) {
                finalTreeList.add(node);
                innerBuild(treeList, node, 0, 2);
            }
        }
        return finalTreeList;
    }


    /**
     * 递归处理
     *
     * @param treeNodes  数据集合
     * @param parentNode 当前节点
     * @param deep       已递归深度
     * @param maxDeep    最大递归深度 可能为null即不限制
     */
    private static void innerBuild(List<TreeNode> treeNodes, TreeNode parentNode, int deep, Integer maxDeep) {
        if (CollectionUtils.isEmpty(treeNodes)) {
            return;
        }
        //maxDeep 可能为空
        if (maxDeep != null && deep >= maxDeep) {
            return;
        }
        for (TreeNode childNode : treeNodes) {
            if (parentNode.getId().equals(childNode.getParentId())) {
                List<TreeNode> children = parentNode.getChildren();
                children.add(childNode);
                innerBuild(treeNodes, childNode, deep + 1, maxDeep);
            }
        }
    }
}

2.批量导出客户列表

/**
     * 批量导出客户列表
     *
     * @param vo
     * @param
     * @return
     */
    @Override
    public BaseResponse customerBatch(CustomerListVo vo, UserInfo userInfo) throws Exception {
        String userId = userInfo.getUserId();
        log.info("{}【批量导出客户列表】...开始...CustomerListVo={}", userId, vo);

//        String filePath = aliyunOSSUtil.filePath(fileName)+".xlsx";
        String jsonString = JSONObject.toJSONString(vo);
        String idStr = IdWorker.getIdStr();
        CreateExportRecordVo exportRecordVo = new CreateExportRecordVo(idStr, 5, jsonString);
        sysExportRecordService.createExportRecord(exportRecordVo, userInfo);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    List<CustomerListResponse> customerListResponses = ptOrganizationUserMapper.selectResource(vo);
                    addItem(customerListResponses);
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    EasyExcel.write(out, CustomerListResponse.class).sheet("CustomerList").doWrite(customerListResponses);
                    //生成文件名
                    String fileName = String.format("CustomerList/%s/客户列表-%s", DateUtil.getDateYMD(), System.currentTimeMillis());
                    //返回
                    String uploadExportExcel = aliyunOSSUtil.uploadExportExcel(new ByteArrayInputStream(out.toByteArray()), fileName);
                    //修改 生成结果
                    SysExportRecord sysExportRecord = new SysExportRecord(idStr,uploadExportExcel,1,new Date());
                    sysExportRecordService.updateExportRecord(sysExportRecord);
                    log.info("{}【批量导出客户列表】...结束", userId);
                } catch (Exception e) {
                    SysExportRecord sysExportRecord = new SysExportRecord(idStr,2);
                    sysExportRecordService.updateExportRecord(sysExportRecord);
                    log.error("{}【批量导出客户列表】...异常{}", userId,e.getMessage());
                }
            }
        }).start();
        return BaseResponse.success(idStr);
    }
package com.gongsibao.request;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @Author hkxie
 * @Date 2021/6/8
 * @Description
 **/
@Data
@ApiModel("列表导出")
public class CreateExportRecordVo {

    /**
     * 导出Id
     */
    @ApiModelProperty(value="导出Id")
    private String exportId;
    /**
     * 导出类型(1.团队管理,2.用户管理,3.消费记录,4.充值列表,5.客户列表)
     */
    @ApiModelProperty(value = "导出类型(1.团队管理,2.用户管理,3.消费记录,4.充值列表,5.客户列表)")
    private Integer exportType;

    /**
     * 请求参数 json 字符串
     */
    private String exportParam;

    public CreateExportRecordVo() {
    }

    public CreateExportRecordVo(String exportId, Integer exportType, String exportParam) {
        this.exportId = exportId;
        this.exportType = exportType;
        this.exportParam = exportParam;
    }
}
package com.gongsibao.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.gongsibao.common.util.CommonUtil;
import com.gongsibao.core.base.BaseResponse;
import com.gongsibao.entity.SysExportRecord;
import com.gongsibao.entity.UserInfo;
import com.gongsibao.mapper.SysExportRecordMapper;
import com.gongsibao.request.CreateExportRecordVo;
import com.gongsibao.service.SysExportRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author hkxie
 * @Date 2021/6/8
 * @Description
 **/
@Service
@Slf4j
public class SysExportRecordServiceImpl implements SysExportRecordService {

    @Autowired
    private SysExportRecordMapper sysExportRecordMapper;


    @Override
    public void createExportRecord(CreateExportRecordVo createExportRecordVo, UserInfo userInfo) throws Exception {
        SysExportRecord sysExportRecord = new SysExportRecord();
        BeanUtils.copyProperties(createExportRecordVo, sysExportRecord);
        sysExportRecord.setCreatedBy(userInfo.getUserId());
        sysExportRecord.setCreatedByName(userInfo.getUsername());
        int count = sysExportRecordMapper.insert(sysExportRecord);
        Assert.isTrue(count == 1, "数据插入失败!!!");
    }

    @Override
    public void updateExportRecord(SysExportRecord sysExportRecord) {
        sysExportRecordMapper.updateById(sysExportRecord);
    }

    @Override
    public BaseResponse getExportRecord(String id) {
        log.info("根据id={}获取 导出url", id);
        SysExportRecord sysExportRecord = sysExportRecordMapper.selectById(id);
        Assert.isTrue(CommonUtil.isNotEmpty(sysExportRecord), "传入的id不存在!!");
        String exportUrl = sysExportRecord.getExportUrl();
        Integer exportState = sysExportRecord.getExportState();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("exportState", exportState);
        if (StringUtils.isNotBlank(exportUrl) && exportState == 1) {
            jsonObject.put("exportUrl", exportUrl);
            return BaseResponse.success("文件生成成功!", jsonObject);
        }
        if (exportState == 2) {
            return BaseResponse.success("文件生成失败!", jsonObject);
        }
        return BaseResponse.success("文件正在生成…", jsonObject);
    }


    @Override
    public BaseResponse getExportRecordList(String userId) {
        List<SysExportRecord> sysExportRecords = sysExportRecordMapper.selectList(new LambdaQueryWrapper<SysExportRecord>()
                .eq(SysExportRecord::getIsDeleted, 0)
                .eq(SysExportRecord::getCreatedBy, userId)
                .orderByDesc(SysExportRecord::getFinishedAt)
                .last(" limit 10 "));
        return BaseResponse.success(sysExportRecords);
    }
}

在导出表中存入记录(id) --> [开启另一个线程 --> 查出要导出的内容List --> 把内容写入ByteArrayOutputStream --> 上传oss获取url --> 根据id修改导出表(加上url,修改状态、日期) ] --> 返回导出表的id --> 前端根据id发请求获取oss的url

3.政策产业类别同步

package com.gongsibao.service.policy;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.gongsibao.common.chacewang.CCWHttpUtil;
import com.gongsibao.core.base.BaseResponse;
import com.gongsibao.entity.policy.Dict;
import com.gongsibao.mapper.policy.DictMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 政策产业类别同步
 *
 * @Author YangBin
 * @Date 2021/6/11
 **/
@Slf4j
@Service
public class IndustryParse {

    @Resource
    private CCWHttpUtil ccwHttpUtil;

    @Resource
    private DictMapper dictMapper;

    private static final String DICT_TYPE = "Industry";

    private static final String URI = "/api/ccw/projectsearch/GetAllIndustry";

    private static final String FULL_NAME = "FullName";

    private static final String VALUE = "Value";

    private static final String CODE = "Code";

    private static final int MAX_ITEM = 100;

    //数据库为空时,爬取上游数据填充数据库
    private static List<Dict> dictCacheList = new ArrayList<>();

    //存储上游数据,key为code
    private static Map<String, JSONObject> upperDataMap = new HashMap<>();

    //存储本地数据的code
    private static Set<String> localCodeSet = new HashSet<>();

    @Transactional(rollbackFor = Exception.class)
    public BaseResponse run() {
        log.info("IndustryParse 解析开始");
        getLocalData();
        //本地数据库为空,初始化
        if (CollectionUtils.isEmpty(localCodeSet)) {
            init();
            log.info("IndustryParse 解析完成");
            return BaseResponse.SUCCESS;
        }
//        log.info("#####no init#####");
        //不为空则进行增加、修改、删除操作
        getUpperDataMap();
        Set<String> upperCodeSet = upperDataMap.keySet();
        Set<String> tempSet = null;
        //增加:upper中有local中没有的code
        (tempSet = new HashSet<>(upperCodeSet)).removeAll(localCodeSet);
        for (String upperCode : tempSet) {
//            log.info("##### add {} #####", upperCode);
            insertUpperBatch(upperCode);
        }
        insertBatch();
        //删除:local中有upper中没有的code
        (tempSet = new HashSet<>(localCodeSet)).removeAll(upperCodeSet);
        for (String localCode : tempSet) {
//            log.info("##### delete {}#####", localCode);
            dictMapper.delete(Wrappers.<Dict>lambdaQuery().eq(Dict::getCode, localCode).eq(Dict::getIsDeleted, 0));
        }
        //修改:upper和local共有的code
        (tempSet = new HashSet<>(upperCodeSet)).retainAll(localCodeSet);
        if (CollectionUtils.isNotEmpty(tempSet)) {
            batchUpdateByCode(tempSet);
        }
        log.info("IndustryParse 解析完成");
        return BaseResponse.SUCCESS;
    }

    /**
     * 获取本地数据
     */
    private void getLocalData() {
        localCodeSet.clear();
        List<String> localDictCode = dictMapper.selectList(Wrappers.<Dict>lambdaQuery().select(Dict::getCode)
                .eq(Dict::getType, DICT_TYPE).eq(Dict::getIsDeleted, 0).eq(Dict::getIsEnabled, 1))
                .stream().map(Dict::getCode).collect(Collectors.toList());
        localCodeSet.addAll(localDictCode);
    }

    /**
     * 获取上游数据存入upperDataMap
     */
    private void getUpperDataMap() {
        upperDataMap.clear();
        JSONArray upperDate = getUpperDate();
        for (int i = 0; i < upperDate.size(); i++) {
            JSONObject jsonObject = upperDate.getJSONObject(i);
            upperDataMap.put(jsonObject.getString(CODE), jsonObject);
        }
    }

    /**
     * 初始化本地数据库
     */
    private void init() {
//        log.info("#####init#####");
        JSONArray upperDate = getUpperDate();
        for (int i = 0; i < upperDate.size(); i++) {
            JSONObject jsonObject = upperDate.getJSONObject(i);
            String fullName = jsonObject.getString(FULL_NAME);
            String value = jsonObject.getString(VALUE);
            String code = jsonObject.getString(CODE);
            Dict dict = new Dict().setId(IdWorker.getIdStr()).setType(DICT_TYPE).setCode(code).setValue(value).setName(fullName).setFullName(fullName);
            dictCacheList.add(dict);
            if (MAX_ITEM <= dictCacheList.size()) {
                insertBatch();
            }
        }
        insertBatch();
    }

    private void insertBatch() {
        if (CollectionUtils.isNotEmpty(dictCacheList)) {
            dictMapper.insertBatch(dictCacheList);
            dictCacheList.clear();
        }
    }

    private void insertUpperBatch(String upperCode) {
        JSONObject jsonObject = upperDataMap.get(upperCode);
        String fullName = jsonObject.getString(FULL_NAME);
        String value = jsonObject.getString(VALUE);
        String code = jsonObject.getString(CODE);
        Dict dict = new Dict().setId(IdWorker.getIdStr()).setType(DICT_TYPE).setCode(code).setValue(value).setName(fullName).setFullName(fullName);
        dictCacheList.add(dict);
        if (MAX_ITEM <= dictCacheList.size()) {
            insertBatch();
        }
    }

    private void batchUpdateByCode(Set<String> codeSet) {
        for (String code : codeSet) {
//            log.info("##### update {} #####", code);
            JSONObject jsonObject = upperDataMap.get(code);
            String fullName = jsonObject.getString(FULL_NAME);
            String value = jsonObject.getString(VALUE);
            Dict dict = new Dict().setValue(value).setName(fullName).setFullName(fullName);
            dictMapper.update(dict, Wrappers.<Dict>lambdaUpdate().eq(Dict::getCode, code));
        }
    }

    /**
     * 获取上游数据
     *
     * @return
     */
    private JSONArray getUpperDate() {
        String res = ccwHttpUtil.get(URI, null);
        JSONArray jsonArray = JSONObject.parseArray(res);
        Assert.isTrue(StringUtils.isNotBlank(jsonArray.toJSONString()), "ChaPlateParse 调用上游获取数据为空");
        return jsonArray;
    }

}

4.上传tag关键词

/**
     * 上传tag关键词
     *
     * @param file
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse uploadTagKw(MultipartFile file) {
        try {
            List<TagKeywordResponse> tagKeywordResponseList = EasyExcel.read(file.getInputStream()).head(TagKeywordResponse.class).sheet().doReadSync();
            tagKeywordResponseList.forEach(System.out::println);
            if (CollectionUtils.isEmpty(tagKeywordResponseList)) {
                return BaseResponse.error("上传的数据不能为空");
            }
            Set<Long> tagKwIdSet = new HashSet<>();
            Set<String> tagKwNameSet = new HashSet<>();
            List<TagKeyword> tempList = tagKeywordMapper.selectList(new QueryWrapper<TagKeyword>().lambda()
                    .select(TagKeyword::getTagKwId, TagKeyword::getTagKwName).eq(TagKeyword::getBeactive, 1));
            List<Long> tagKwIds = tempList.stream().map(TagKeyword::getTagKwId).collect(Collectors.toList());
            List<String> tagKwNames = tempList.stream().map(TagKeyword::getTagKwName).collect(Collectors.toList());
            List<Long> tagIds = tagMapper.selectList(new QueryWrapper<Tag>().lambda()
                    .select(Tag::getTagId).eq(Tag::getBeactive, 1))
                    .stream().map(Tag::getTagId).collect(Collectors.toList());
            ArrayList<TagKeyword> updateList = new ArrayList<>();
            ArrayList<TagKeyword> insertList = new ArrayList<>();
            for (int i = 0; i < tagKeywordResponseList.size(); i++) {
                TagKeywordResponse tagKeywordResponse = tagKeywordResponseList.get(i);
                //非空参数校验
                if (StringUtils.isBlank(tagKeywordResponse.getTagKwName())) {
                    return BaseResponse.error("导入失败,第" + (i + 1) + "行tag关键词名称不能为空!");
                }
                //判断tag关键词id是否重复(传入0或空为增加,传入数据库已有的id为修改)
                Long tagKwId = tagKeywordResponse.getTagKwId();
                if (null != tagKwId && !Long.valueOf(0).equals(tagKwId) && tagKwIdSet.contains(tagKwId)) {
                    return BaseResponse.error("导入失败,tag关键词id[" + tagKwId + "]不能重复!");
                } else {
                    tagKwIdSet.add(tagKwId);
                }
                //判断tag关键词是否重复
                String tagKwName = tagKeywordResponse.getTagKwName();
                if (tagKwNameSet.contains(tagKwName)) {
                    return BaseResponse.error("导入失败,tag关键词名称[" + tagKwName + "]不能重复!");
                } else {
                    tagKwNameSet.add(tagKwName);
                }
                //判断传入的所属id是否存在
                Long tagId = tagKeywordResponse.getTagId();
                if (null != tagId && !Long.valueOf(0).equals(tagId) && !tagIds.contains(tagId)) {
                    return BaseResponse.error("导入失败,所属类目id[" + tagId + "]在tag类目中不存在!");
                }
                //判断传入的tag关键词id是否存在,存在为修改,不存在为增加
                if (tagKwIds.contains(tagKwId)) {
                    TagKeyword tagKeyword = new TagKeyword() {{
                        setTagKwId(tagKwId);
                        setTagKwName(tagKwName);
                        setTdkTitle(tagKeywordResponse.getTdkTitle());
                        setTdkDesc(tagKeywordResponse.getTdkDesc());
                        setTdkKw(tagKeywordResponse.getTdkKw());
                        setSort(tagKeywordResponse.getSort());
                        if (null != tagId && !Long.valueOf(0).equals(tagId)) {
                            setTagId(tagId);
                        }
                    }};
//                    log.info("修改:" + tagKeyword);
                    updateList.add(tagKeyword);
                } else if (null == tagKwId || Long.valueOf(0).equals(tagKwId)) {
                    if (tagKwNames.contains(tagKwName)) {
                        return BaseResponse.error("tag关键词[" + tagKwName + "]已存在,不能重复添加!");
                    }
                    TagKeyword tagKeyword = new TagKeyword() {{
                        setTagKwName(tagKwName);
                        setTdkTitle(tagKeywordResponse.getTdkTitle());
                        setTdkDesc(tagKeywordResponse.getTdkDesc());
                        setTdkKw(tagKeywordResponse.getTdkKw());
                        setSort(tagKeywordResponse.getSort());
                        if (null != tagId && !Long.valueOf(0).equals(tagId)) {
                            setTagId(tagId);
                        }
                    }};
//                    log.info("增加:" + tagKeyword);
                    insertList.add(tagKeyword);
                } else {
                    return BaseResponse.error("增加tag关键字异常,异常tag关键词id:" + tagKwId);
                }
            }
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.submit(() -> {
                for (TagKeyword tagKeyword : updateList) {
                    tagKeywordMapper.updateById(tagKeyword);
                }
            });
            executorService.submit(() -> {
                for (TagKeyword tagKeyword : insertList) {
                    tagKeywordMapper.insert(tagKeyword);
                }
            });
            executorService.shutdown();
            return BaseResponse.success("上传tag关键词成功");
        } catch (Exception e) {
            log.info("上传tag关键词异常:" + e);
            return BaseResponse.error("上传tag关键词异常");
        }
    }
posted @ 2021-07-01 01:13  no1486  阅读(111)  评论(0编辑  收藏  举报