package com.heketai.website.web;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.heketai.website.common.result.BaseResult;
import com.heketai.website.common.result.HttpCode;
import com.heketai.website.common.utils.ExcelUtil;
import com.heketai.website.common.utils.ListUtils;
import com.heketai.website.common.utils.StringUtils;
import com.heketai.website.common.vo.AllProductRequest;
import com.heketai.website.entity.Product;
import com.heketai.website.entity.ProductCategory;
import com.heketai.website.entity.ProductCategoryAttr;
import com.heketai.website.entity.ProductSearchRecord;
import com.heketai.website.entity.dto.ProductAttrsDto;
import com.heketai.website.entity.dto.ProductDto;
import com.heketai.website.entity.dto.ProductSortQueryVo;
import com.heketai.website.entity.dto.SearchDto;
import com.heketai.website.mapper.ProductMapper;
import com.heketai.website.service.IProductCategoryAttrService;
import com.heketai.website.service.IProductCategoryService;
import com.heketai.website.service.IProductSearchRecordService;
import com.heketai.website.service.IProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author xjl
 * @since 2019-12-17
 */
@RestController
@RequestMapping("/product")
@Api(value = "产品管理页面", tags = "产品管理")
public class ProductController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    IProductService productService;
    @Autowired
    ProductMapper productMapper;
    @Autowired
    IProductCategoryService productCategoryService;
    @Autowired
    IProductCategoryAttrService attrService;

    @Autowired
    private IProductSearchRecordService productSearchRecordService;

    @Autowired
    private RedisTemplate redisTemplate;
    private String fKey = "43AF2D04-4B1F-1DEC-11B9-431BCC8F6E7C";

    //导入锁
    static ReentrantLock importLock = new ReentrantLock();

    /**
     * 批量导入数据
     */
    @ApiOperation(value = "商品列表导入", notes = "商品列表导入", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "file文件", required = true),
            @ApiImplicitParam(name = "id", value = "商品分类对象id", required = true),
    })
    @RequestMapping(value = "/importExcel", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Object importExcel(@RequestParam("file") MultipartFile file, @RequestParam("id") Integer id, HttpServletRequest request) {
        //批量导入数据
        //文件为空
        if (file.isEmpty()) {
            return BaseResult.fail(HttpCode.FAIL.getCode(), "文件不能为空");
        }


        InputStream is = null;
        StringBuffer sb = new StringBuffer();
        //判断是否有线程占用此锁
        if (importLock.isLocked()) {
            return BaseResult.fail(HttpCode.FAIL.getCode(), "导入任务正在执行中,请等待数分钟...");
        }
        //清除redis数据
        redisTemplate.delete(fKey);

        //线程锁开启
        importLock.lock();
        try {
            //得到时间戳
            long CountTime1 = System.currentTimeMillis();
            //用分类ID判断是否有此分类
            ProductCategory category = new ProductCategory();
            category.setId(id);
            category = productCategoryService.selectById(category);
            if (category == null) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "分类参数错误");
            }
            //得到sort数据
            Integer sort = category.getSort();
            long CountTime2 = System.currentTimeMillis();
            //把运行时间戳的时间返回给日志
            logger.info("11111运行:" + (CountTime2 - CountTime1));
            //获取商品分类属性参数
            ProductCategoryAttr productCategoryAttr = new ProductCategoryAttr();
            productCategoryAttr.setCategoryId(id);
            EntityWrapper<ProductCategoryAttr> wrapper = new EntityWrapper<>();
            wrapper.setEntity(productCategoryAttr);
            List<ProductCategoryAttr> categoryAttrs = attrService.selectList(wrapper);

            //得到io对象流
            is = file.getInputStream();
            // 由数字和26个英文字母组成的字符串
            Workbook workBook = WorkbookFactory.create(is);
            Sheet sheet = workBook.getSheetAt(0);
            Row titleRow = sheet.getRow(0);
            int cols = titleRow.getLastCellNum();
            int rows = sheet.getLastRowNum() + 1;
            long CountTime3 = System.currentTimeMillis();
            logger.info("222222运行:" + (CountTime3 - CountTime2));
            //获取标题
            List<String> keyWorlds = new ArrayList<>();
            for (int i = 0; i < cols; i++) {
                Cell c = titleRow.getCell(i);
                // 判断是否具有合并单元格
                String value = ExcelUtil.getCellValue(c);
                keyWorlds.add(value);
            }

            List<String> k3ids = new ArrayList<>();
            for (int i = 2; i < rows; i++) {
                titleRow = sheet.getRow(i);
                if (titleRow == null) {
                    rows--;
                    continue;
                }
                Cell c = titleRow.getCell(0);
                String value = ExcelUtil.getCellValue(c);
                if (StringUtils.isNull(value)) {
                    continue;
                }
                //判断goods_type（商品类别）是否有重复，如果有重复就停止，没有就插入
                if (!k3ids.contains(value)) {
                    k3ids.add(value);
                } else {
                    return BaseResult.fail(HttpCode.FAIL.getCode(), "编码有重复:" + value);
                }
            }
            //查出商品主表内容，判断goods_type（商品类别）在数据库主表是否有重复
            List<Product> goodsList = productMapper.queryByK3ids(k3ids);
            Map<String, Product> goodsMap = new HashMap<>();
            k3ids.clear();
            for (Product g : goodsList) {
                goodsMap.put(g.getGoodsType(), g);
                k3ids.add(g.getGoodsType());
            }

            long CountTime4 = System.currentTimeMillis();
            logger.info("333333运行:" + (CountTime4 - CountTime3));

            List<Product> TempInsertList = new ArrayList<>();
            List<Product> TempUpdateList = new ArrayList<>();

            for (int i = 2; i < rows; i++) {
                titleRow = sheet.getRow(i);

                Product goods = null;

                String k3id = "";
                for (int j = 0; j < cols; j++) {
                    Cell c = titleRow.getCell(j);
                    String value = ExcelUtil.getCellValue(c);

                    if (StringUtils.isNull(value)) {
                        //数据未填写
                        sb.append("第" + i + "行 第" + j + "列为空");
                        continue;
                    }

                    String key = keyWorlds.get(j);
                    switch (key) {
                        case "型号":
                            k3id = value;
                            if (goodsMap.containsKey(k3id)) {
                                goods = goodsMap.get(k3id);
                            } else {
                                //todo 怎么把这个数据对象取出来
                                goods = new Product();
                                goods.setGoodsType(k3id);
                                goods.setCategoryId(id);
                                goods.setPackageSpecification("-");
                            }
                            break;
                        case "合科泰型号":
                            goods.setGoodsSn(value);
                            break;
                        case "封装形式":
                            goods.setPackageSpecification(value);
                            break;
                        case "规格书":
                            goods.setManual(value);
                            break;
                        default:
                            for (ProductCategoryAttr attr : categoryAttrs) {
                                if (key.equals(attr.getNameCh())) {
                                    goods.SetAttr(attr.getSort(), value);
                                    break;
                                }
                            }
                            break;
                    }
                }

                if (goods == null){ continue;}
                //todo 这里
                if (StringUtils.isNull(goods.getGoodsType())) {continue;}
                if (StringUtils.isNull(goods.getId())) {
                    goods.setSort(sort);
                    TempInsertList.add(goods);
                } else {
                    goods.setSort(sort);
                    TempUpdateList.add(goods);
                }
            }

            long CountTime5 = System.currentTimeMillis();
            logger.info("444444运行:" + (CountTime5 - CountTime4));

            boolean IsOk = true;
            if (TempInsertList.size() > 0) {
                try {
                    productService.insertBatch(TempInsertList);
                } catch (Exception ex) {
                    IsOk = false;
                    ex.printStackTrace();
                    logger.error("批量插入失败");
                }
            }
            if (TempUpdateList.size() > 0) {
                try {
                    productService.updateAllColumnBatchById(TempUpdateList);
                } catch (Exception ex) {
                    IsOk = false;
                    ex.printStackTrace();
                }
            }
            if (IsOk) {
                return BaseResult.success();
            }
            long CountTime6 = System.currentTimeMillis();
            logger.info("555555运行:" + (CountTime6 - CountTime5));
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.info("异常:" + ex.getMessage());
        } finally {
            importLock.unlock();
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        return BaseResult.fail(HttpCode.FAIL.getCode(), "插入异常!");
    }


    @RequestMapping("/findPage")
    @ApiOperation(value = "商品分页查询", notes = "商品分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", value = "产品分类", required = true)
    })
    @Transactional(propagation = Propagation.SUPPORTS)
    public BaseResult findPage(@RequestBody Page<ProductSortQueryVo> page) {
        try {
            String key = "9E2B8D46-5B19E6E3D61D" + JSON.toJSONString(page);
            Object obj = redisTemplate.boundHashOps(fKey).get(key);
            if (null != obj) {
                Map<String, Object> map = JSON.parseObject(obj.toString(), Map.class);
                return BaseResult.successWithData(map);
            }

            ProductSortQueryVo p = page.getRecords().get(0);
            if (StringUtils.isNull(p.getCategoryId())) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id不可为空");
            }

            ProductCategory category = new ProductCategory();
            category.setId(p.getCategoryId());
            category = productCategoryService.selectById(category);
            if (category == null) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id错误");
            }
            ProductCategoryAttr findAttr = new ProductCategoryAttr();
            findAttr.setCategoryId(p.getCategoryId());
            EntityWrapper<ProductCategoryAttr> wrapper = new EntityWrapper<>();
            wrapper.setEntity(findAttr);
            List<ProductCategoryAttr> attrs = attrService.selectList(wrapper);

            Map<Integer, Boolean> tempMap = new HashedMap();
            Collections.sort(attrs, (ProductCategoryAttr a, ProductCategoryAttr b) -> b.getSort().compareTo(a.getSort()));

            for (ProductCategoryAttr attr : attrs) {
                tempMap.put(attr.getSort(), true);
            }

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

            Product Head1 = new Product();
            Product Head2 = new Product();

            Head1.setImg("产品图片");
            Head2.setImg("Picture");

            Head1.setManual("规格书");
            Head2.setManual("Datasheet");

            Head1.setPackageSpecification("封装形式");
            Head2.setPackageSpecification("Package");

            Head1.setManualCh("英文网站规格书");
            Head2.setManualCh("Datasheet");

            Head1.setSilkScreen("丝印");
            Head2.setSilkScreen("Marking");

            Head1.setRemarks("备注");
            Head2.setRemarks("Datasheet");
            Product Head3 = new Product();

            if (category.getIsSummary() == 1) {
                //汇总报表
                map.put("Summary", true);
                Head1.setGoodsType("名称");
                Head2.setGoodsType("Name");

                for (ProductCategoryAttr attr : attrs) {
                    Head1.SetAttr(attr.getSort(), attr.getNameCh());
                    Head2.SetAttr(attr.getSort(), attr.getNameEn());
                    Head3.SetAttr(attr.getSort(), attr.getUnits());
                }

                Product PT = new Product();
                PT.setCategoryId(p.getCategoryId());
                EntityWrapper<Product> productEntityWrapper = new EntityWrapper<>();
                productEntityWrapper.setEntity(PT);
                Product product = productService.selectOne(productEntityWrapper);

                Page<Product> productPage = new Page<>();

                if (product != null) {
                    product.setGoodsType(product.getGoodsType().replace("|", "<br/>"));
                    product.setPackageSpecification(product.getPackageSpecification().replace("|", "<br/>"));

                    for (Map.Entry<Integer, Boolean> entry : tempMap.entrySet()) {
                        product.SetAttr(entry.getKey(), product.GetAttr(entry.getKey()).replace("|", "<br/>"));
                    }

                    if (StringUtils.isNull(product.getImg())) {
                        product.setImg(category.getImg());
                    }


                    productPage.setTotal(1);
                    productPage.setCurrent(1);
                    productPage.setSize(1);
                    List<Product> tempList = new ArrayList<>();
                    tempList.add(product);
                    productPage.setRecords(tempList);
                }

                map.put("page", productPage);
            } else {
                //产品明细
                map.put("Summary", false);

                Head1.setGoodsType("型号");
                Head2.setGoodsType("Type");

                Head1.setGoodsSn("合科泰型号");
                Head2.setGoodsSn("Hottech Type");

                List<Product> pDict = productMapper.queryDistint(p.getCategoryId());


                Map<String, List<String>> tempMapList = new HashedMap();
                for (ProductCategoryAttr attr : attrs) {
                    Head1.SetAttr(attr.getSort(), attr.getNameCh());
                    Head2.SetAttr(attr.getSort(), attr.getNameEn());
                    Head3.SetAttr(attr.getSort(), attr.getUnits());
                    tempMapList.put("attr" + attr.getSort(), new ArrayList<>());
                }
                tempMapList.put("packageSpecification", new ArrayList<>());
                tempMapList.put("goodsType", new ArrayList<>());

                //代表所有数字的正则表达式
                String regex = "^(-?\\d+)(\\.\\d+)?$";
                for (Product pr : pDict) {
                    //把所有封装放入tempMapList中
                    String temp = pr.getPackageSpecification();
                    List<String> tempList1 = tempMapList.get("packageSpecification");
                    if (!tempList1.contains(temp)) {
                        tempList1.add(temp);
                    }
                    //把所有型号放入tempMapList中
                    String goodsType = pr.getGoodsType();
                    List<String> goodsTypes = tempMapList.get("goodsType");
                    if (!goodsTypes.contains(goodsType)) {
                        goodsTypes.add(goodsType);
                    }
                    //把所有arrt数据放入tempMapList中
                    for (ProductCategoryAttr attr : attrs) {
                        temp = pr.GetAttr(attr.getSort());
                        String keyCode = "attr" + attr.getSort();
                        tempList1 = tempMapList.get(keyCode);
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(temp)
                                && temp.matches(regex)) {
                            if (!tempList1.contains(temp)) tempList1.add(temp);
                            ListUtils.sortList(tempList1);
                        }else {
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(temp)){
                                if (!tempList1.contains(temp)) tempList1.add(temp);
                                Collections.sort(tempList1);
                            }
                        }

                    }

                }
                map.put("SortData", tempMapList);

                Page<Product> productPage = new Page<>();
                productPage.setTotal(productMapper.queryCountByVo(p));
                productPage.setCurrent(page.getCurrent());
                productPage.setSize(page.getSize());

                List<Product> tempList = productMapper.queryValueByVo(p, (page.getCurrent() - 1) * page.getSize(), page.getSize());

                for (Product pp : tempList) {
                    if (StringUtils.isNull(pp.getImg())) {
                        pp.setImg(category.getImg());
                    }
                }

                productPage.setRecords(tempList);
                map.put("page", productPage);
//                map.put("totalPackage",list);
            }


            if (StringUtils.isNull(p.getLanguage())) {
                map.put("typeHead1", Head1);
                map.put("typeHead2", Head2);
                map.put("typeHead3", Head3);
                map.put("category", category);
            } else {
                if (p.getLanguage() == 1) {
                    map.put("typeHead", Head1);
                    map.put("typeHead3", Head3);
                } else {
                    map.put("typeHead", Head2);
                    map.put("typeHead3", Head3);
                }
                map.put("category", category.getId());
            }

            redisTemplate.boundHashOps(fKey).put(key, JSON.toJSONString(map));
            return BaseResult.successWithData(map);
        } catch (Exception ex) {
            logger.error("/product/findPage商品分页查询,失败原因：[{}]", ex.getMessage(), page, ex);
            return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误");
        }
    }

    @RequestMapping("/findMap")
    @ApiOperation(value = "商品分类分页查询", notes = "商品分类分页查询")
    @Transactional(propagation = Propagation.SUPPORTS)
    public BaseResult findMapPage(@RequestBody Page<ProductDto> page) {
        try {
            //判断分类id是否为空
            ProductDto p = page.getRecords().get(0);
            if (StringUtils.isNull(p.getCategoryId())) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id不可为空");
            }
            //判断是否有此分类
            ProductCategory category = new ProductCategory();
            category.setId(p.getCategoryId());
            category = productCategoryService.selectById(category);
            if (category == null) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id错误");
            }
            //拿到所有数据
            List<Product> pDict = productMapper.queryProductAll(p);
            //拿到attr介绍数据
            ProductCategoryAttr findAttr = new ProductCategoryAttr();
            findAttr.setCategoryId(p.getCategoryId());
            EntityWrapper<ProductCategoryAttr> wrapper = new EntityWrapper<>();
            wrapper.setEntity(findAttr);
            List<ProductCategoryAttr> attrs = attrService.selectList(wrapper);

            //创建判断是否有attrMap
            Map<Integer, Boolean> tempMap = new HashedMap();
            Collections.sort(attrs, (ProductCategoryAttr a, ProductCategoryAttr b) -> b.getSort().compareTo(a.getSort()));

            for (ProductCategoryAttr attr : attrs) {
                tempMap.put(attr.getSort(), true);
            }

            //创建返回map
            Map<String, Object> map = new HashMap<>();

            Product Head1 = new Product();
            Product Head2 = new Product();

            Head1.setImg("产品图片");
            Head2.setImg("Picture");

            Head1.setManual("规格书");
            Head2.setManual("Datasheet");

            Head1.setPackageSpecification("封装形式");
            Head2.setPackageSpecification("Package");

            Head1.setManualCh("英文网站规格书");
            Head2.setManualCh("Datasheet");

            Head1.setSilkScreen("丝印");
            Head2.setSilkScreen("Marking");

            Head1.setRemarks("备注");
            Head2.setRemarks("Datasheet");
            Product Head3 = new Product();

            if (category.getIsSummary() == 1) {
                //汇总报表
                map.put("Summary", true);
                Head1.setGoodsType("名称");
                Head2.setGoodsType("Name");

                for (ProductCategoryAttr attr : attrs) {
                    Head1.SetAttr(attr.getSort(), attr.getNameCh());
                    Head2.SetAttr(attr.getSort(), attr.getNameEn());
                    Head3.SetAttr(attr.getSort(), attr.getUnits());
                }

                Product PT = new Product();
                PT.setCategoryId(p.getCategoryId());
                EntityWrapper<Product> productEntityWrapper = new EntityWrapper<>();
                productEntityWrapper.setEntity(PT);
                Product product = productService.selectOne(productEntityWrapper);

                Page<Product> productPage = new Page<>();
                if (product != null) {
                    product.setGoodsType(product.getGoodsType().replace("|", "<br/>"));
                    product.setPackageSpecification(product.getPackageSpecification().replace("|", "<br/>"));

                    for (Map.Entry<Integer, Boolean> entry : tempMap.entrySet()) {
                        product.SetAttr(entry.getKey(), product.GetAttr(entry.getKey()).replace("|", "<br/>"));
                    }

                    if (StringUtils.isNull(product.getImg())) {
                        product.setImg(category.getImg());
                    }


                    productPage.setTotal(1);
                    productPage.setCurrent(1);
                    productPage.setSize(1);
                    List<Product> tempList = new ArrayList<>();
                    tempList.add(product);
                    productPage.setRecords(tempList);
                }

                map.put("page", productPage);
            } else {
                //产品明细
                map.put("Summary", false);

                Head1.setGoodsType("型号");
                Head2.setGoodsType("Type");

                Head1.setGoodsSn("合科泰型号");
                Head2.setGoodsSn("Hottech Type");
                Map<String, List<String>> tempMapList = new HashedMap();
                for (ProductCategoryAttr attr : attrs) {
                    Head1.SetAttr(attr.getSort(), attr.getNameCh());
                    Head2.SetAttr(attr.getSort(), attr.getNameEn());
                    Head3.SetAttr(attr.getSort(), attr.getUnits());
                    tempMapList.put("attr" + attr.getSort(), new ArrayList<>());
                }
                tempMapList.put("packageSpecification", new ArrayList<>());
                tempMapList.put("goodsType", new ArrayList<>());

                //代表所有数字的正则表达式
                String regex = "^(-?\\d+)(\\.\\d+)?$";
                for (Product pr : pDict) {
                    //把所有封装放入tempMapList中
                    String temp = pr.getPackageSpecification();
                    List<String> tempList1 = tempMapList.get("packageSpecification");
                    if (!tempList1.contains(temp)) {
                        tempList1.add(temp);
                    }
                    //把所有型号放入tempMapList中
                    String goodsType = pr.getGoodsType();
                    List<String> goodsTypes = tempMapList.get("goodsType");
                    if (!goodsTypes.contains(goodsType)) {
                        goodsTypes.add(goodsType);
                    }
                    //把所有arrt数据放入tempMapList中
                    for (ProductCategoryAttr attr : attrs) {
                        temp = pr.GetAttr(attr.getSort());
                        String keyCode = "attr" + attr.getSort();
                        tempList1 = tempMapList.get(keyCode);
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(temp)
                                && temp.matches(regex)) {
                            if (!tempList1.contains(temp)) tempList1.add(temp);
                            ListUtils.sortList(tempList1);
                        }else {
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(temp)){
                                if (!tempList1.contains(temp)) tempList1.add(temp);
                                Collections.sort(tempList1);
                            }
                        }
                    }

                }
                map.put("SortData", tempMapList);

                Page<Product> productPage = new Page<>();
                productPage.setTotal(pDict.size());
                productPage.setCurrent(page.getCurrent());
                productPage.setSize(page.getSize());

                //拿到分页数据
                List<Product> tempList = productService.findProducts(page);
//                List<Product> tempList = productMapper.queryValueByVo(p, (page.getCurrent() - 1) * page.getSize(), page.getSize());

                for (Product pp : tempList) {
                    if (StringUtils.isNull(pp.getImg())) {
                        pp.setImg(category.getImg());
                    }
                }

                productPage.setRecords(tempList);
                map.put("page", productPage);
//                map.put("totalPackage",list);
            }


            if (StringUtils.isNull(p.getLanguage())) {
                map.put("typeHead1", Head1);
                map.put("typeHead2", Head2);
                map.put("typeHead3", Head3);
                map.put("category", category);
            } else {
                if (p.getLanguage() == 1) {
                    map.put("typeHead", Head1);
                    map.put("typeHead3", Head3);
                } else {
                    map.put("typeHead", Head2);
                    map.put("typeHead3", Head3);
                }
                map.put("category", category.getId());
            }
            return BaseResult.successWithData(map);
        } catch (Exception e) {
            logger.error("/product/findMap商品分页查询,失败原因：[{}]", e.getMessage(), page, e);
            return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误");
        }

    }


    @RequestMapping("/findScope")
    @ApiOperation(value = "筛选器取值范围得到数据查询", notes = "筛选器取值范围得到数据查询")
    @Transactional(propagation = Propagation.SUPPORTS)
    public BaseResult findAttrScope(@RequestBody Page<ProductAttrsDto> page) {
        try {
            ProductAttrsDto p = page.getRecords().get(0);
            //判断分类id是否为空
            if (StringUtils.isNull(p.getCategoryId())) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id不可为空");
            }
            //判断是否有此分类
            ProductCategory category = new ProductCategory();
            category.setId(p.getCategoryId());
            category = productCategoryService.selectById(category);
            if (category == null) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id错误");
            }
            Map<String, Object> map = productService.findAllScope(page);
            return BaseResult.successWithData(map);

        } catch (Exception e) {
            logger.error("/product/findScope商品分页查询,失败原因：[{}]", e.getMessage(), page, e);
            return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误");
        }
    }

    @RequestMapping("/updateApplication")
    @ApiOperation(value = "修改 商品应用关联数据", notes = "商品应用关联数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "商品id", required = true),
            @ApiImplicitParam(name = "appIds", value = "应用ids,以','分割", required = true),
    })
    public BaseResult updateApplication(@RequestBody Product product) {

        Product p = new Product();
        p.setId(product.getId());
        p.setAppIds("," + product.getAppIds() + ",");

        productService.updateById(p);
        redisTemplate.delete(fKey);
        return BaseResult.success();
    }

    @RequestMapping("/findApplicationPage")
    @ApiOperation(value = "商品 应用分页查询", notes = "商品 应用分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appIds", value = "应用", required = true),
    })
    public BaseResult findApplicationPage(@RequestBody Page<Product> page) {
        try {
            String key = "DD65DFDE-63FB516EFC77" + JSON.toJSONString(page);
            Object obj = redisTemplate.boundHashOps(fKey).get(key);
            if (null != obj) {
                Page<Object> objectPage = JSON.parseObject(obj.toString(), Page.class);
                return BaseResult.successWithData(objectPage);
            }

            Product p = page.getRecords().get(0);

            Product product = new Product();
            if (!StringUtils.isNull(p.getAppIds())) {
                product.setAppIds("," + p.getAppIds() + ",");
            } else if (!StringUtils.isNull(p.getGoodsType())) {
                product.setGoodsType(p.getGoodsType());
            } else {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，应用不可为空");
            }
            Page<Object> objectPage = new Page<>();
            int count = productMapper.queryByAppIdCount(product);
            objectPage.setSize(page.getSize());
            objectPage.setCurrent(page.getCurrent());
            objectPage.setTotal(count);
            List<Product> list = productMapper.queryByAppId(product, (page.getCurrent() - 1) * page.getSize(), page.getSize());

            EntityWrapper<ProductCategory> entityWrapper = new EntityWrapper<>();
            entityWrapper.setEntity(new ProductCategory());

            List<ProductCategory> categories = productCategoryService.selectList(entityWrapper);
            Map<Integer, ProductCategory> mapCate = new HashedMap();
            for (ProductCategory c : categories) {
                mapCate.put(c.getId(), c);
            }
            List<Object> outList = new ArrayList<>();
            for (Product pd : list) {
                Map<String, Object> map = new HashMap<>();

                map.put("type", pd.getGoodsType());
                String replace = pd.getPackageSpecification().replace("|", "<br/>");
                map.put("package", replace);
                map.put("category", pd.getCategoryId());
                map.put("pdf", pd.getManual());
                map.put("isSummary", pd.getIsSummary());
                ProductCategory category = mapCate.get(pd.getCategoryId());

                map.put("categoryNameCh", category.getNameCh());
                map.put("categoryNameEn", category.getNameEn());
                outList.add(map);
            }
            objectPage.setRecords(outList);
            redisTemplate.boundHashOps(fKey).put(key, JSON.toJSONString(objectPage));
            return BaseResult.successWithData(objectPage);
        } catch (
                Exception ex) {
            return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误");
        }
    }

    /**
     * 用es全局查询
     */
    @RequestMapping("/es-find-device")
    @ApiOperation(value = "产品全局查询", notes = "产品全局查询")
    public BaseResult findByDevice(@RequestBody AllProductRequest request) {
        try {
            //把所有搜索内容记录到数据库
            addProductSearchRecord(request);

            String key = "3C2BBFCE-0CA33D29CCDE" + JSON.toJSONString(request);
            Object obj = redisTemplate.boundHashOps(fKey).get(key);
            if (null != obj) {
                BaseResult byDevice = JSON.parseObject(obj.toString(), BaseResult.class);
                return byDevice;
            }
            BaseResult byDevice = productService.findByDevice(request);
            redisTemplate.boundHashOps(fKey).put(key, JSON.toJSONString(byDevice));
            return byDevice;
        } catch (Exception e) {
            logger.error("ES全局查询分离器件失败，失败原因：[{}]", e.getLocalizedMessage());
            return BaseResult.fail("Es全局查询分离器件失败");
        }
    }

    @RequestMapping("/find-fz")
    @ApiOperation(value = "查询分离器件所有封装", notes = "查询分离器件所有封装")
    public BaseResult findByFz(@RequestParam(value = "sort", required = false) Integer sort) {
        String key = "B1A001E1-7E79-DD9E-5F03-386EAC1516E8" + sort;
        Object obj = redisTemplate.boundHashOps(fKey).get(key);
        if (null != obj) {
            BaseResult byDevice = JSON.parseObject(obj.toString(), BaseResult.class);
            return byDevice;
        }
        BaseResult byDevice = productService.findByFz(sort);
        redisTemplate.boundHashOps(fKey).put(key, JSON.toJSONString(byDevice));
        return byDevice;
    }

    @RequestMapping("/find-jd")
    @ApiOperation(value = "查询阻容所有精度", notes = "查询阻容所有精度")
    public BaseResult findByJd(@RequestParam(value = "sort", required = false) Integer sort) {
        String key = "D9C2328C-3743-4478-EEFC-0FDEC322ABBC" + sort;
        Object obj = redisTemplate.boundHashOps(fKey).get(key);
        if (null != obj) {
            BaseResult byDevice = JSON.parseObject(obj.toString(), BaseResult.class);
            return byDevice;
        }
        BaseResult byDevice = productService.findByJd(sort);
        redisTemplate.boundHashOps(fKey).put(key, JSON.toJSONString(byDevice));
        return byDevice;
    }


    @RequestMapping("/update-sort")
    @ApiOperation(value = "更改分离器件还是阻容", notes = "更改分离器件还是阻容")
    public BaseResult updateSort(@RequestParam(value = "sort", required = false) Integer sort) {
        int i = productMapper.updateSort(sort);
        redisTemplate.delete(fKey);
        return BaseResult.successWithData(i);
    }

    /**
     * 用多线程把所有搜索内容记录到数据库
     */
    public void addProductSearchRecord(AllProductRequest request) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                if (org.apache.commons.lang3.StringUtils.isBlank(request.getCategoryId())) {
                    ProductSearchRecord record = new ProductSearchRecord();
                    record.setCreateTime(new Date());
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(request.getSeek())) {
                        record.setSearchBoxContents(request.getSeek());
                    }
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(request.getSeekFields())) {
                        record.setComboOxContents(request.getSeekFields());
                    }
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(request.getSeekType())) {
                        record.setSeekType(request.getSeekType());
                    }
                    productSearchRecordService.insert(record);
                }
            }
        });
        executorService.shutdown();

    }

    @RequestMapping("/findMaxAttr")
    @ApiOperation(value = "查询筛选器取值范围", notes = "查询筛选器取值范围")
    @ApiImplicitParam(name = "id", value = "分类id", required = true)
    public BaseResult findMaxAttr(@RequestParam Integer id) {
        try {
            if (StringUtils.isNull(id)) {
                return BaseResult.fail(HttpCode.FAIL.getCode(), "参数错误，分类id不可为空");
            }
            Product attrUnitsName = new Product();
            ProductCategoryAttr findAttr = new ProductCategoryAttr();
            findAttr.setCategoryId(id);
            EntityWrapper<ProductCategoryAttr> wrapper = new EntityWrapper<>();
            wrapper.setEntity(findAttr);
            List<ProductCategoryAttr> attrs = attrService.selectList(wrapper);
            for (ProductCategoryAttr attr : attrs) {
                 attrUnitsName.SetAttr(attr.getSort(), attr.getUnits());
            }
            Page<ProductAttrsDto> page = productService.onsetScope(id);
            Map<String,Object> map = new HashMap<>();
            map.put("attrUnitsName",attrUnitsName);
            map.put("page", page);
            return BaseResult.successWithData(map);
        } catch (Exception e) {
            logger.error("筛选器取值范围查询失败，失败原因：[{}]", e.getLocalizedMessage());
            return BaseResult.fail("筛选器取值范围查询失败");
        }
    }



    /**
     * 用es全局查询
     */
    @RequestMapping("/search")
    @ApiOperation(value = "产品查询2022/8/22", notes = "产品查询2022/8/22")
    public BaseResult search(@RequestBody Page<SearchDto> page) {
        try {
            if (page == null) {
                throw new RuntimeException("传参为空");
            }
            if (CollectionUtils.isEmpty(page.getRecords())){
                throw new RuntimeException("没有搜索数据");
            }
            Map<String, Map<String,Object>> map= productService.search(page);
            return BaseResult.successWithData(map);
        } catch (Exception e) {
            logger.error("搜索，全局查询分离器件失败，失败原因：[{}]", e.getLocalizedMessage());
            return BaseResult.fail("搜索，全局查询分离器件失败");
        }
    }
}
