package com.yeejoin.equipmanage.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.dto.OrgMenuDto;
import com.yeejoin.amos.boot.biz.common.interceptors.PermissionInterceptorContext;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentDetailDownloadVO;
import com.yeejoin.equipmanage.common.enums.EquipQrcodeColorEnum;
import com.yeejoin.equipmanage.common.enums.ExcelEnums;
import com.yeejoin.equipmanage.common.enums.SourceTypeEnum;
import com.yeejoin.equipmanage.common.utils.*;
import com.yeejoin.equipmanage.common.vo.EquipmentDate;
import com.yeejoin.equipmanage.dto.ExcelDto;
import com.yeejoin.equipmanage.mapper.*;
import com.yeejoin.equipmanage.service.*;
import com.yeejoin.equipmanage.service.impl.FireFightingSystemServiceImpl;
import com.yeejoin.equipmanage.service.impl.SourcesStatisticsImpl;
import com.yeejoin.equipmanage.utils.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author wujiang
 * @date 2020-07-07
 */
@Slf4j
@RestController
@Api(tags = "装备详情 Api")
@RequestMapping(value = "/equipment-detail", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class EquipmentDetailController extends AbstractBaseController {

    @Autowired
    IEquipmentDetailService iEquipmentDetailService;

    @Autowired
    IFireFightingSystemService fireFightingSystemService;
    @Autowired
    EquipmentDetailMapper equipmentDetailMapper;
    @Autowired
    private StockDetailMapper stockDetailMapper;
    @Autowired
    @Lazy
    IStockService iStockService;
    @Autowired
    private ManufacturerInfoMapper manufacturerInfoMapper;
    @Autowired
    private IEquipmentSpecificIndexSerivce equipmentSpecificIndexSerivce;

    @Autowired
    IEquipmentSpecificSerivce equipmentSpecificSerivce;

    @Autowired
    EquipmentSpecificMapper equipmentSpecificMapper;

    @Value("${redis_equip_type_count}")
    private String equipTypeAndCount;

    @Value("${redis_car_type_count}")
    private String carTypeAndCount;

    @Autowired
    private IExcelService excelService;

    @Autowired
    EquipQrcodeRecordMapper equipQrcodeRecordMapper;

    @Autowired
    private IWarehouseStructureService warehouseStructureService;

    @Autowired
    private ISyncDataService syncDataService;

    @Value("${systemctl.sync.switch}")
    private Boolean syncSwitch;

    @Autowired
    FireFightingSystemServiceImpl fireFightingSystemServiceImpl;

    @Autowired
    ISourceStatistics iSourceStatistics;

    @Autowired
    private RedisUtils redisUtils;
    @Value("${equip.enabled}")
    private Boolean enabled;

    @Autowired
    IEquipmentIndexService equipmentIndexService;


    @Value("${iot.code.prefix.have.used:20210003,20210004,20210005}")
    private String haveUsedIotPrefix;

    /**
     * 新增
     *
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "新增", notes = "新增")
    public EquipmentDetail saveEquipmentDetail(HttpServletRequest request, @RequestBody EquipmentDetail equipmentDetail) {
        EquipmentDetail detail = iEquipmentDetailService.saveOne(equipmentDetail);
        return detail;
    }

    @Async("equipAsyncExecutor")
    public void refreshCount(String ...bizOrgCodes) {
        try {
            equipmentSpecificSerivce.refreshStaData();
            // 去重逻辑,目的时资源调整归属单位后 新单元和就单位都刷新单位分类数量统计
            Set<String> repeatBizOrgCodes = new HashSet<>(Arrays.asList(bizOrgCodes));
            repeatBizOrgCodes.forEach(bizOrgCode->{
                fireFightingSystemServiceImpl.refreshEquipmentTypeAndCount(bizOrgCode);
            });
        } catch (Exception e) {
            log.error("刷新装备分类树缓存失败" + e.getMessage());
        }
    }

    /**
     * 设备新增带打码入库
     ***/
    @RequestMapping(value = "/saveEquipment", method = RequestMethod.POST)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "新增", notes = "新增")
    public EquipmentDate saveEquipmentDetail(@RequestBody EquipmentDate equipmentDate) {

        if (equipmentDate.getEquipmentSpecific().getSingle() == null) {
            throw new BadRequest("管理方式未输入");
        }
        EquipmentSpecific vo = equipmentDate.getEquipmentSpecific();
        String sysCode = vo.getCode();
        if (StringUtils.isNotEmpty(sysCode) && StringUtils.isNotEmpty(sysCode.trim())) {
            int code = equipmentSpecificSerivce.count(new QueryWrapper<EquipmentSpecific>().eq("code", sysCode.trim()));
            if (code != 0) {
                throw new BadRequest("设备编码填写重复，请重新输入！");
            }
        }
        String iot = vo.getIotCode();
        if (StringUtils.isNotEmpty(iot) && StringUtils.isNotEmpty(iot.trim())) {
            int iot_code = equipmentSpecificSerivce.count(new QueryWrapper<EquipmentSpecific>().eq("iot_code", iot.trim()));
            if (iot_code != 0) {
                throw new BadRequest("物联编码填写重复，请重新输入！");
            }
        }
        EquipmentDate date = equipmentSpecificSerivce.equipmentSpecificCreate(equipmentDate, getSelectedOrgInfo(), getUserInfo());
        // TODO 后续判断成功，执行同步
        Long equipmentId = date.getEquipmentDetail().getEquipmentId();
        // 编辑同步redis装备iotcode数据
        syncDataService.saveOrUpdateEquipIotCodeRedisData(null);
        if (syncSwitch) {
            equipmentSpecificSerivce.equipSpecificDataSync(date.getEquipmentSpecific().getId());
        }
        EquipmentDetailController controllerProxy = SpringUtils.getBean(EquipmentDetailController.class);
        controllerProxy.refreshCount(vo.getBizOrgCode());
        return date;
    }

    /***
     *
     * 根id查询
     *
     * **/
    @RequestMapping(value = "equipment/{code}", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "根据二维码查询", notes = "根据二维码查询")
    public EquipmentDate selectByCode(HttpServletRequest request, @PathVariable String code) {
        EquipmentDate equipmentDate = new EquipmentDate();
        EquipmentSpecific equipmentSpecific = equipmentSpecificSerivce.equipmentByQrcode(code);
        EquipmentDetail equipmentDetail = iEquipmentDetailService.getOneById(equipmentSpecific.getEquipmentDetailId());
        equipmentDate.setEquipmentDetail(equipmentDetail);
        equipmentDate.setEquipmentSpecific(equipmentSpecific);
        return equipmentDate;
    }

    /***
     *
     * 根id查询
     *
     * **/
    @RequestMapping(value = "/selectequipmentDateById", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
    public EquipmentDate selectequipmentDateById(@RequestParam Long id,
                                                 @RequestParam(required = false) Long stockDetailId) {
        EquipmentDate equipmentDate = new EquipmentDate();
        EquipmentSpecific equipmentSpecific = equipmentSpecificSerivce.getById(id);
        equipmentSpecific.setFullqrCode("01#" + equipmentSpecific.getQrCode());
        EquipmentDetail equipmentDetail = iEquipmentDetailService.getOneById(equipmentSpecific.getEquipmentDetailId());
        StockDetail stockDetail = null;
        if (stockDetailId != null) {
            //解决灭火药剂，有多个货位状态问题
            stockDetail = stockDetailMapper.selectById(stockDetailId);
            equipmentSpecific.setStockDetail(stockDetail);
        } else {
            //消防装备默认分支
            List<StockDetail> stockDetails = stockDetailMapper.selectList(new LambdaQueryWrapper<StockDetail>().eq(StockDetail::getEquipmentSpecificId, id));
            if (!stockDetails.isEmpty()) {
                stockDetail = stockDetails.get(0);
                equipmentSpecific.setStockDetail(stockDetail);
            }
        }
        if (stockDetail != null) {
            equipmentSpecific.setStock(iStockService.getById(stockDetail.getStockId()));
        }
        equipmentDate.setEquipmentDetail(equipmentDetail);
        equipmentDate.setEquipmentSpecific(equipmentSpecific);
        return equipmentDate;
    }

    @RequestMapping(value = "/selectequipmentDateByCode", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY, needAuth = false)
    @ApiOperation(httpMethod = "GET", value = "根据code查询", notes = "根据code查询")
    public EquipmentDate selectequipmentDateByCode(@RequestParam String code,
                                                   @RequestParam(required = false) Long stockDetailId) {
        EquipmentDate equipmentDate = new EquipmentDate();
        EquipmentSpecific equipmentSpecific = equipmentSpecificMapper.getEquipSpecificEntityByCode(code);
        if(!ObjectUtils.isEmpty(equipmentSpecific.getRealtimeIotIndexId())){
        	EquipmentIndex equipmentIndex = equipmentIndexService.getById(equipmentSpecific.getRealtimeIotIndexId());
            equipmentSpecific.setIsTrend(equipmentIndex.getIsTrend());
            equipmentSpecific.setUnit(equipmentIndex.getUnit());
        }
        FireFightingSystemEntity fightingSystemEntity = new FireFightingSystemEntity();
        if(!ObjectUtils.isEmpty(equipmentSpecific.getSystemId())){
            fightingSystemEntity = fireFightingSystemService.getOneById(Long.valueOf(equipmentSpecific.getSystemId()));
            equipmentSpecific.setSystemId(fightingSystemEntity.getName());
        } else {
            equipmentSpecific.setSystemId("");
        }
        equipmentSpecific.setSystemId(fightingSystemEntity.getName());
        equipmentSpecific.setFullqrCode("01#" + equipmentSpecific.getQrCode());
        EquipmentDetail equipmentDetail = iEquipmentDetailService.getOneById(equipmentSpecific.getEquipmentDetailId());
        StockDetail stockDetail = null;
        if (stockDetailId != null) {
            //解决灭火药剂，有多个货位状态问题
            stockDetail = stockDetailMapper.selectById(stockDetailId);
            equipmentSpecific.setStockDetail(stockDetail);
        } else {
            //消防装备默认分支
            List<StockDetail> stockDetails = stockDetailMapper.selectList(new LambdaQueryWrapper<StockDetail>().eq(StockDetail::getEquipmentSpecificId, equipmentSpecific.getId()));
            if (!stockDetails.isEmpty()) {
                stockDetail = stockDetails.get(0);
                equipmentSpecific.setStockDetail(stockDetail);
            }
        }
        if (stockDetail != null) {
            equipmentSpecific.setStock(iStockService.getById(stockDetail.getStockId()));
        }
        equipmentDate.setEquipmentDetail(equipmentDetail);
        equipmentDate.setEquipmentSpecific(equipmentSpecific);
        return equipmentDate;
    }
    /***
     *
     * 修改
     * **/
    @RequestMapping(value = "equipment/updateById", method = RequestMethod.PUT)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "PUT", value = "修改", notes = "修改")
    public EquipmentDate updateByIdEquipmentDetail(HttpServletRequest request, @RequestBody EquipmentDate equipmentDate) {

        EquipmentSpecific vo = equipmentDate.getEquipmentSpecific();
        EquipmentSpecific oldEquipmentSpecific = equipmentSpecificSerivce.getById(vo.getId());
        String oldBizOrgCode = oldEquipmentSpecific.getBizOrgCode();
        String sysCode = vo.getCode();
        if (StringUtils.isNotEmpty(sysCode) && StringUtils.isNotEmpty(sysCode.trim())) {
            int code = equipmentSpecificSerivce.count(new QueryWrapper<EquipmentSpecific>().eq("code", vo.getCode()).ne("id", vo.getId()));
            if (code > 0) {
                throw new BadRequest("设备编码重复");
            }
        }
        String iotCode = vo.getIotCode();
        if (StringUtils.isNotEmpty(iotCode) && StringUtils.isNotEmpty(iotCode.trim())) {
            int exists = equipmentSpecificSerivce.count(new QueryWrapper<EquipmentSpecific>().eq("iot_code", iotCode).ne("id", vo.getId()));
            if (exists > 0) {
                throw new BadRequest("设备物联编码重复");
            }
            if(StringUtils.isNotEmpty(sysCode) && StringUtils.isNotEmpty(sysCode.trim())) {
                if (sysCode.startsWith("20210003") || sysCode.startsWith("20210004") || sysCode.startsWith("20210005")) {
                    throw new BadRequest("物联编码航班已占用");
                }
            }
        }

        //1.更新装备实例Detail数据
        EquipmentDetail equipmentDetail = equipmentDate.getEquipmentDetail();

        if (equipmentDetail.getProductionDate() != null && equipmentDetail.getExpiryDate()!= null){
            try {
                //设备发生修改后 计算设备报废日期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(equipmentDetail.getProductionDate() );
                calendar.add(Calendar.YEAR,Integer.parseInt(equipmentDetail.getExpiryDate()) );
                Date now = new Date();
                int day  = DateUtils.dateBetween(now,calendar.getTime());
                if (day > -1){

                    //消除设备二维码记录时间
                    LambdaQueryWrapper<EquipQrcodeRecord> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(EquipQrcodeRecord::getEquipid, vo.getId());
                    wrapper.eq(EquipQrcodeRecord::getSource,"scrap");
                    wrapper.isNull(EquipQrcodeRecord::getCleanTime);
                    EquipQrcodeRecord equipQrcodeRecord = equipQrcodeRecordMapper.selectOne(wrapper);
                    if (!ObjectUtils.isEmpty(equipQrcodeRecord)){
                        equipQrcodeRecord.setCleanTime(new Date());
                        equipQrcodeRecord.setCleanReason("设备报废日期更新后消除");
                        equipQrcodeRecordMapper.updateById(equipQrcodeRecord);
                    }


                    //查询二维码事件记录表中该设备的历史数据
                    LambdaQueryWrapper<EquipQrcodeRecord> query = new LambdaQueryWrapper<>();
                    query.eq(EquipQrcodeRecord::getEquipid,  vo.getId());
                    query.isNull(EquipQrcodeRecord::getCleanTime);
                    List<EquipQrcodeRecord> equipQrcodeRecords = equipQrcodeRecordMapper.selectList(query);
                    String status = equipQrcodeRecords.stream().sorted(Comparator.comparing(EquipQrcodeRecord::getStatus)).findFirst().get().getStatus();
                    if (equipQrcodeRecords.size() > 0) {  //如果记录表中还存在未消除的其他事件 则按照优先级赋码
                        equipmentSpecificSerivce.updateEquipSpecificStatus(status, String.valueOf(vo.getId()));
                    } else {
                        equipmentSpecificSerivce.updateEquipSpecificStatus(EquipQrcodeColorEnum.GREEN.getCode(), String.valueOf(vo.getId()));
                    }
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }



        final EquipmentDetail dateEquipmentDetail = equipmentDate.getEquipmentDetail();
        iEquipmentDetailService.updateOneById(equipmentDate.getEquipmentSpecific().getId(), dateEquipmentDetail);
        //2.更新装备实例主表数据
        Long detailId = dateEquipmentDetail.getId();
        equipmentDate.getEquipmentSpecific().setEquipmentDetailId(detailId);
        EquipmentSpecific equipmentSpecific = equipmentDate.getEquipmentSpecific();
        equipmentSpecific.setName(equipmentDetail.getName());
        EquipmentDetail bean = iEquipmentDetailService.getById(dateEquipmentDetail.getId());
        if (!ObjectUtils.isEmpty(bean)) {
            equipmentSpecific.setEquipmentCode(bean.getCode());
        }
        Long warehouseStructureId = ObjectUtils.isEmpty(equipmentSpecific.getStockDetail()) ? null : equipmentSpecific.getStockDetail().getWarehouseStructureId();
        if (warehouseStructureId != null) {
            WarehouseStructure warehouseStructure = warehouseStructureService.getById(warehouseStructureId);
            if (!ObjectUtils.isEmpty(warehouseStructure)) {
                equipmentSpecific.setPosition(warehouseStructure.getFullName());
            }
        }
        if (!ObjectUtils.isEmpty(equipmentSpecific.getStockDetail())) {
            equipmentSpecific.getStockDetail().setDescription(equipmentDetail.getArea());
        }
        equipmentSpecificSerivce.updateEquipmentSpecific(equipmentSpecific, getSelectedOrgInfo(), getUserInfo());
        // TODO 后续判断成功，执行同步
        // 编辑同步redis装备iotcode数据
        syncDataService.saveOrUpdateEquipIotCodeRedisData(null);
        if (syncSwitch) {
            equipmentSpecificSerivce.equipSpecificDataSync(equipmentSpecific.getId());
        }
        // 刷新缓存，新的单位和之前的单位都刷新
        EquipmentDetailController controllerProxy = SpringUtils.getBean(EquipmentDetailController.class);
        controllerProxy.refreshCount(vo.getBizOrgCode(),oldBizOrgCode);
        return equipmentDate;
    }


    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
    public boolean deleteById(HttpServletRequest request, @PathVariable Long id) {
        boolean falg = iEquipmentDetailService.removeOneById(id);
        if (falg) {
            equipmentSpecificSerivce.refreshStaData();
        }
        return falg;
    }

    @RequestMapping(value = "/updatequota", method = RequestMethod.PUT)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "PUT", value = "修改", notes = "修改")
    public boolean quotaUpdate(HttpServletRequest request, @RequestBody List<EquProperty> e) {
        boolean falg = iEquipmentDetailService.quotaUpdate(e);
        if (falg) {
            equipmentSpecificSerivce.refreshStaData();
        }
        return falg;
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
    public EquipmentDetail selectById(HttpServletRequest request, @PathVariable Long id) {
        return iEquipmentDetailService.getOneById(id);
    }


    @RequestMapping(value = "/listDate", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
    public Page listPage(@RequestParam(value = "current") int pageNum,
                         @RequestParam(value = "size") int pageSize,
                         @RequestParam(required = false) String name,
                         @RequestParam(required = false) String standard,
                         @RequestParam(required = false) String manufacturerName) {
        int start = (pageNum - 1) * pageSize;
        List<Map<String, Object>> list = equipmentSpecificIndexSerivce.selectEquList(start, pageSize, name, standard, manufacturerName);
        List<Map<String, Object>> list2 = equipmentSpecificIndexSerivce.selectEquListcount(name, standard, manufacturerName);

        Page psge = new Page(pageNum, pageSize, list2 == null ? 0 : list2.size());
        psge.setRecords(list);
        return psge;

    }

    /**
     * 列表分页查询
     *
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
    public IPage<EquipmentDetail> listPage(String pageNum, String pageSize, EquipmentDetail equipmentDetail) {

        Page<EquipmentDetail> pageBean;
        QueryWrapper<EquipmentDetail> equipmentDetailQueryWrapper = new QueryWrapper<>();
        Class<? extends EquipmentDetail> aClass = equipmentDetail.getClass();
        Arrays.stream(aClass.getDeclaredFields()).forEach(field -> {
            try {
                field.setAccessible(true);
                Object o = field.get(equipmentDetail);
                if (o != null) {
                    Class<?> type = field.getType();
                    String name = NameUtils.camel2Underline(field.getName());
                    if (type.equals(Integer.class)) {
                        Integer fileValue = (Integer) field.get(equipmentDetail);
                        equipmentDetailQueryWrapper.eq(name, fileValue);
                    } else if (type.equals(Long.class)) {
                        Long fileValue = (Long) field.get(equipmentDetail);
                        equipmentDetailQueryWrapper.eq(name, fileValue);
                    } else if (type.equals(String.class)) {
                        String fileValue = (String) field.get(equipmentDetail);
                        equipmentDetailQueryWrapper.eq(name, fileValue);
                    } else {
                        String fileValue = (String) field.get(equipmentDetail);
                        equipmentDetailQueryWrapper.eq(name, fileValue);
                    }
                }
            } catch (Exception e) {
            }
        });
        IPage<EquipmentDetail> page;
        if (StringUtils.isBlank(pageNum) || StringUtils.isBlank(pageSize)) {
            pageBean = new Page<>(0, Long.MAX_VALUE);
        } else {
            pageBean = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        }
        page = iEquipmentDetailService.page(pageBean, equipmentDetail);
        return page;
    }

    /**
     * 列表分类查询
     *
     * @return
     */
    @RequestMapping(value = "/list/category/{category}", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "列表分类查询", notes = "列表分类查询")
    public IPage<EquipmentDetail> list(String pageNum, String pageSize, @PathVariable String category) {
        Page<EquipmentDetail> pageBean;
        IPage<EquipmentDetail> page;
        if (StringUtils.isBlank(pageNum) || StringUtils.isBlank(pageSize)) {
            pageBean = new Page<>(0, Long.MAX_VALUE);
        } else {
            pageBean = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        }
        page = iEquipmentDetailService.page(pageBean, category);
        return page;
    }

    /**
     * <pre>
     * 装备补码操作
     * </pre>
     *
     * @return CommonResponse
     * @throws @version: 1.0
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "装备补码操作", notes = "装备补码操作，根据条件查询")
    @RequestMapping(value = "/complement_code", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public IPage<StockDetail> ComplementCode(String pageNum, String pageSize, String equipmentDetailId, String qrCode,
                                             String status) {
        try {

            Page<StockDetail> pageBean;
            IPage<StockDetail> page;
            if (StringUtils.isBlank(pageNum) || StringUtils.isBlank(pageSize)) {
                pageBean = new Page<>(0, Long.MAX_VALUE);
            } else {
                pageBean = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
            }
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.isNotNull("qr_code");
            queryWrapper.ne("qr_code", "");
            if (qrCode != null && !"".equals(qrCode)) {
                queryWrapper.like("qr_code", qrCode);
            }
            if (equipmentDetailId != null && !"".equals(equipmentDetailId)) {
                queryWrapper.eq("equipment_detail_id", equipmentDetailId);
            }
            if (status != null && !"".equals(status)) {
                queryWrapper.eq("status", status);
            }

            IPage<StockDetail> stockDetail = stockDetailMapper.selectPage(pageBean, queryWrapper);
            List<StockDetail> list = stockDetail.getRecords();
            for (int i = 0; i < list.size(); i++) {

                EquipmentDetail equipmentDetail = equipmentDetailMapper.selectById(list.get(i).getEquipmentDetailId());

                list.get(i).setEquipmentDetail(equipmentDetail);

            }
            stockDetail.setRecords(list);
            return stockDetail;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("系统异常！");
        }
    }

    /**
     * 批量删除
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
    public boolean delete(HttpServletRequest request, @RequestBody List<Long> idList) throws Exception {
        return iEquipmentDetailService.removeBatchById(idList);
    }

    /**
     * 设备信息下载
     *
     * @return
     */
    @PostMapping(value = "/downList")
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "下载模板", notes = "下载模板")
    public void downList(HttpServletResponse response, @RequestBody List<Long> ids) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
        QueryWrapper<EquipmentDetail> equipmentDetailQueryWrapper = new QueryWrapper<>();
        if (ids.size() > 0) {
            equipmentDetailQueryWrapper.in("id", ids);
        }
        List<EquipmentDetail> equipmentDetails = iEquipmentDetailService.list(equipmentDetailQueryWrapper);
        List<EquipmentDetailDownloadVO> equipmentDetailDownloads = new ArrayList<>();
        equipmentDetails.forEach(x -> {
            EquipmentDetailDownloadVO equipmentDetailDownloadVO = new EquipmentDetailDownloadVO();
            equipmentDetailDownloadVO.setId(x.getId());
            equipmentDetailDownloadVO.setName(x.getName());
            equipmentDetailDownloadVO.setStandard(x.getStandard());
            equipmentDetailDownloadVO.setManufacturerName(manufacturerInfoMapper.selectById(x.getManufacturerId()).getName());
            equipmentDetailDownloads.add(equipmentDetailDownloadVO);
        });
        ExcelUtils.exportExcel(equipmentDetailDownloads, "设备信息", "设备信息", EquipmentDetailDownloadVO.class, simpleDateFormat.format(new Date()) + ".xlsx", response);
    }

    /**
     * 下载模板
     *
     * @return
     * @Since 2021-3-10
     */
    @GetMapping(value = "/downTemplate")
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "下载模板", notes = "下载模板")
    public void downTemplate(HttpServletResponse response) throws ClassNotFoundException {
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
//        List<EquipmentDetailDownloadTemplateVO> equipmentDetailDownloads = new ArrayList<>();
//        ExcelUtils.exportExcel(equipmentDetailDownloads, "设备信息", "设备信息", EquipmentDetailDownloadTemplateVO.class, simpleDateFormat.format(new Date()) + ".xls", response);

//        try {
//            // 判读机场服务是否在线
//            ExcelEnums excelEnums;
//            ResponseModel<String[]> result = jcsFeign.getEquipmentInfo(getAppKey(), getProduct(), getToken(), null, "getEquipCompany");
//            if (200 == result.getStatus()) {
//                excelEnums = ExcelEnums.getByKey(ExcelEnums.XFZB.getType());
//                ExcelDto excelDto = new ExcelDto(excelEnums.getFileName(), excelEnums.getSheetName(), excelEnums.getClassUrl(), excelEnums.getType());
//                String url = excelDto.getClassUrl();
//                Class<?> clz = Class.forName(url);
//                ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), null, clz, getToken(),
//                        getAppKey(), getProduct(), true);
//            }
//
//        } catch (Exception e) {
           ExcelEnums excelEnums =  null;
            if (!enabled){
                excelEnums = ExcelEnums.getByKey(ExcelEnums.XFZBSINGLE.getType());
            }else {
                excelEnums = ExcelEnums.getByKey(ExcelEnums.XFZB.getType());
            }

            ExcelDto excelDto = new ExcelDto(excelEnums.getFileName(), excelEnums.getSheetName(), excelEnums.getClassUrl(), excelEnums.getType());
            String url = excelDto.getClassUrl();
            Class<?> clz = Class.forName(url);
            ExcelUtil.createTemplate(response, excelDto.getFileName(), excelDto.getSheetName(), null, clz, getToken(),
                    getAppKey(), getProduct(), true);
       // }
    }

    /**
     * 单个设备信息导入
     *
     * @return
     * @Since 2021-3-10
     */
    @PostMapping(value = "/uploadListByTemplate")
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "单个设备信息导入", notes = "单个设备信息导入")
    public ResponseModel<Object> uploadListByTemplate(MultipartFile file, @RequestParam(value = "type") String type) throws Exception {
//        try {
//            InputStream inputStream = null;
//            Workbook workbook = null;
//            inputStream = file.getInputStream();
//            workbook = WorkbookFactory.create(inputStream);
//            inputStream.close();
//            Sheet sheet = workbook.getSheetAt(0);
//            String b = sheet.getRow(0).getCell(1).getStringCellValue();
//            if ( !"器材编码（从装备定义中获取）".equals(b)){
//                throw new Exception();
//            }
//        } catch (Exception e) {
//            throw new BadRequest("请使用指定模板进行上传");
//        }

        // List<EquipmentDetailDownloadTemplateVO> equipmentDetailDownloadS = ExcelUtils.importExcel(file, 1, 1, EquipmentDetailDownloadTemplateVO.class);


            String key="";
        try {
             UUID uuid = UUID.randomUUID();
             key= uuid.toString();
            ExcelEnums excelEnums =  null;
            if (!enabled){
                excelEnums = ExcelEnums.getByKey(ExcelEnums.XFZBSINGLE.getType());
            }else {
                excelEnums = ExcelEnums.getByKey(ExcelEnums.XFZB.getType());
            }
            ExcelDto excelDto = new ExcelDto(excelEnums.getFileName(), excelEnums.getSheetName(), excelEnums.getClassUrl(), excelEnums.getType());
           // date= excelService.commonUpload(file, excelDto, getSelectedOrgInfo(), getUserInfo());
            EquipmentDetailController controllerProxy1 = SpringUtils.getBean(EquipmentDetailController.class);
            controllerProxy1.commonUpload(file, excelDto,key, getSelectedOrgInfo(), getUserInfo());
            EquipmentDetailController controllerProxy = SpringUtils.getBean(EquipmentDetailController.class);
            controllerProxy.refreshAllCount();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadRequest(e.getMessage());
        }
           return ResponseHelper.buildResponse(key);
    }



    @Async("equipAsyncExecutor")
    public void commonUpload(MultipartFile file, ExcelDto excelDto, String key, ReginParams reginParams, AgencyUserModel user) {
        Object date="";
       Map<String,Object> map=new HashMap();
        try {
            synchronized(this.getClass()){

                date= excelService.commonUpload(file, excelDto, reginParams,user);
                map.put("flag","0");
                map.put("date",date);
                redisUtils.set(key, map);
            }
        } catch (Exception e) {
            map.put("flag","1");
            map.put("date",e.getMessage());
            redisUtils.set(key, map);
            e.printStackTrace();
        }

    }




     @RequestMapping(value = "/getUpload/{key}", method = RequestMethod.GET)
     @TycloudOperation(ApiLevel = UserType.AGENCY)
     @ApiOperation(httpMethod = "GET", value = "根据id查询上传进度", notes = "根据id查询上传进度")
     public ResponseModel<Object> getUpload( @PathVariable String key) {

             if(redisUtils.hasKey(key)){
                 return ResponseHelper.buildResponse(redisUtils.get(key));
             } else{
                 return ResponseHelper.buildResponse(null);
             }
     }
    @Async("equipAsyncExecutor")
    public void refreshAllCount() {
        // 清空单位装备分类树缓存
        redisUtils.getAndDeletePatternKeys(carTypeAndCount + "*");
        // 清空车辆分类树缓存
        redisUtils.getAndDeletePatternKeys(equipTypeAndCount + "*");
        redisUtils.getAndDeletePatternKeys("iotTypeAndCount" + "*");
        // 清空单位分类数量统计缓存
        redisUtils.getAndDeletePatternKeys(SourcesStatisticsImpl.PREFIX_CATEGORY_COUNT + "*");
        // 刷新装备单位分类数量缓存
        iSourceStatistics.initAllCategoryStatisticsData(SourceTypeEnum.EQUIPMENT);
        // 刷新车辆单位分类数量缓存
        iSourceStatistics.initAllCategoryStatisticsData(SourceTypeEnum.CAR);

        iSourceStatistics.initAllCategoryStatisticsData(SourceTypeEnum.IOT);
    }

    /**
     * 设备信息导入
     *
     * @return
     */
    @PostMapping(value = "/uploadList")
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "POST", value = "导入", notes = "导入")
    public List<EquipmentSpecific> uploadList(MultipartFile file) {
        List<EquipmentDetailDownloadVO> equipmentDetailDownloadS = ExcelUtils.importExcel(file, 1, 1, EquipmentDetailDownloadVO.class);
        return iStockService.uploadList(equipmentDetailDownloadS, getSelectedOrgInfo(), getUserInfo());
    }

    @RequestMapping(value = "/getPref", method = RequestMethod.GET)
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
    public String getPref(@RequestParam(value = "id") String id) {
        String temp = iEquipmentDetailService.getPref(id);
        return StringUtil.isNotEmpty(temp) ? temp : "";
    }

    @RequestMapping(value = "/checkDelete", method = RequestMethod.DELETE, produces = "application/json;charset=UTF-8")
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
    public String checkDelete(HttpServletRequest request,
                              @ApiParam(value = "装备定义idList", required = true) @RequestBody List<Long> ids) {
        return iEquipmentDetailService.checkDelete(ids);
    }

//    @PostMapping(value = "/getEquipmentSpecificPage")
//    @TycloudOperation(ApiLevel = UserType.AGENCY)
//    @ApiOperation(httpMethod = "POST", value = "传字段类型（car 或 equipment）装备列表带模板返回", notes = "根据id删除")
//    public String getEquipmentSpecificAndDetailList() {
//
//        return ;
//    }

    /**
     * 消防装备单位部门树
     *
     * @param
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/companyTreeByUserAndType")
    @ApiOperation(httpMethod = "GET", value = "消防装备单位部门树", notes = "消防装备单位部门树")
    public ResponseModel<List<OrgMenuDto>> companyTreeByUserAndType() {
        return ResponseHelper.buildResponse(iEquipmentDetailService.companyDeptTree());
    }

    /**
     * 消防装备权限获取
     *
     * @param
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @GetMapping(value = "/permissions/export")
    @ApiOperation(httpMethod = "GET", value = "获取权限", notes = "获取权限")
    public ResponseModel<ReginParams> getPermissions() {
        // 导出模板增加权限
        ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule("fire_equip_info");
        return ResponseHelper.buildResponse(reginParams);
    }

}
