package com.palmnest.service.estateserve.airconditioner.impl;

import com.alibaba.fastjson.JSON;
import com.palmnest.application.AppConstants;
import com.palmnest.application.CodeConstants;
import com.palmnest.application.GoodsCodeConstants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.bean.Page;
import com.palmnest.application.core.util.*;
import com.palmnest.application.dto.ConditionerAddTimeOrderFeeVO;
import com.palmnest.application.dto.WechatMessageDto;
import com.palmnest.application.dto.WxMessageConfigVo;
import com.palmnest.application.dto.input.*;
import com.palmnest.application.dto.output.*;
import com.palmnest.dao.estateserve.EnterprisePermissionDao;
import com.palmnest.model.*;
import com.palmnest.model.airconditioner.*;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.model.estateserve.VirtualAccount;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.model.property.TbOrganization;
import com.palmnest.model.property.VirtualArchitecture;
import com.palmnest.service.OrganizationManager;
import com.palmnest.service.UserManager;
import com.palmnest.service.estateserve.*;
import com.palmnest.service.estateserve.airconditioner.*;
import com.palmnest.service.redis.BaseRedisService;
import com.palmnest.service.virtProject.manager.VirtualAccountManager;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

@Slf4j
@Service("conditionerAddTimeService")
public class ConditionerAddTimeServiceImpl implements ConditionerAddTimeService {


    // dev开发环境test测试
    public static final String CLIENTNO = PropertiesKit.readPropertiesValue("clientNo", "wechat.properties");
    // 2018.05.31<=
    public static String enterTime = PropertiesKit.readPropertiesValue("enterTime", "wechat.properties");

    // app空调加时推送链接
    public static String appAirApplyDetailUrl = PropertiesKit.readPropertiesValue("appAirApplyDetailUrl", "wechat.properties");

    @Autowired
    private ScWxuserManager scWxuserManager;
    @Autowired
    private ConditionerAddTimeManager conditionerAddTimeManager;
    @Autowired
    private VirtualArchManager virtualArchManager;
    @Autowired
    private VirtualAccountManager virtualAccountManager;
    @Autowired
    private BaseRedisService baseRedisService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private EnterpriseAuditManager enterpriseAuditManager;
    @Autowired
    private RoomInfoManager roomInfoManager;
    @Autowired
    private FloorInfoManager floorInfoManager;
    @Autowired
    private AirRuleManager airRuleManager;
    @Autowired
    private AirRuleService airRuleService;
    @Autowired
    private ProjectConfigManager projectConfigManager;
    @Autowired
    private SmsAuthCodeManager smsAuthCodeManager;
    @Autowired
    private AppUserManager appUserManager;
    @Autowired
    private OrganizationManager organizationManager;
    @Autowired
    private EnterprisePermissionDao enterprisePermissionDao;
    @Autowired
    private ConditionerAddTimeOrderExtendManager conditionerAddTimeOrderExtendManager;
    @Autowired
    private ConditionerAddTimeOrderAmountDetailManager conditionerAddTimeOrderAmountDetailManager;


    MathContext mc = new MathContext(2, RoundingMode.HALF_UP);

    @Override
    public AppResultDto apply(AirConditionerAddTimeInputDto dto,
                              HttpServletRequest request) {
        Integer virPermId = null;
        try {
            /**
             * 空调加时订单属性填充
             */
            AirConditionerAddTime airConditionerAddTime = new AirConditionerAddTime();
            airConditionerAddTime.setModificationDisabled(0);
            BeanUtils.copyProperties(airConditionerAddTime, dto);
            if (dto.getBillFrom().equals(CodeConstants.WECHAT)) {
                String openId = request.getParameter("openId");
                WxUser wxUser = scWxuserManager.getScWxuserByOpenId(openId);
                if (wxUser != null) {
                    airConditionerAddTime.setCreator(wxUser.getNickName());
                    airConditionerAddTime.setModifier(wxUser.getNickName());
                    airConditionerAddTime.setOrganizationId(wxUser.getOrganizationId());
                    airConditionerAddTime.setCreatorBillId(openId);
                    AppUser appUer = appUserManager.getAppUserByWxUserAndOrg(wxUser.getId(), wxUser.getOrganizationId());
                    if (null != appUer) {
                        airConditionerAddTime.setUserId(appUer.getId());
                    }
                    if (null != appUer && null != appUer.getVirPermId()) {
                        virPermId = appUer.getVirPermId().intValue();
                    }
                }
            } else if (dto.getBillFrom().equals(CodeConstants.ANDROID) || dto.getBillFrom().equals(CodeConstants.iOS)) {
                String userName = baseRedisService.get(request.getHeader("token"));
                if (userName == null) {
                    return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
                }
                User user = userManager.getUserByUsername2(userName);
                if (null != user) {
                    airConditionerAddTime.setCreator(user.getFullName() + "(空调管理员)");
                    airConditionerAddTime.setModifier(user.getFullName());
                    // appuser 对应项目ID
                    List<AppUserOrgnizationRelation> orgList = userManager.getAppUserOrgByUserId(Integer.parseInt(user.getId().toString()));
                    if (orgList != null && orgList.size() > 0) {
                        AppUserOrgnizationRelation orgRe = orgList.get(0);
                        if (orgRe != null) {
                            airConditionerAddTime.setOrganizationId(orgRe.getOrgId());
                        }
                    }
                    airConditionerAddTime.setCreatorBillId(user.getId().toString());
                }
            }
            airConditionerAddTime.setCreateTime(new Date());
            airConditionerAddTime.setModifyTime(new Date());

            if (null == airConditionerAddTime.getOrganizationId()) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能获得用户项目信息");
            }
            Integer priceType = 1;
            AirRule airRule_data = getRuleByOrgId(Long.valueOf(airConditionerAddTime.getOrganizationId()));
            if (null != airRule_data && null != airRule_data.getPriceType()) {
                priceType = airRule_data.getPriceType();
            }
            DecimalFormat df4 = new DecimalFormat();
            df4.applyPattern("0.00");
            // 单价根据 应用模块空调加时+当前日期的 日期类型(工作日\ 休息日\节假日 找到规则中单价
            BigDecimal priceHu = new BigDecimal(350);// 每户
            BigDecimal priceHour = new BigDecimal(0.15);// 小时
            // 获取当前项目 每层价格 每半层价格
            BigDecimal floorPriceHour = new BigDecimal(100);    // 每层多少钱/每小时
            BigDecimal halfFloorPriceHour = new BigDecimal(50); // 每半层多少钱/每小时
            String priceDisplay = "每户350元/每小时";
            //#应用模块 (1预定会议室\2空调加时
            //#获得日期类型 过滤 日期类型(0工作日1休息日2节假日',
            //#匹配时间段 配置的时间内
            //#获得每户\每平米 价格
            Integer dataType = 0;// 根据api 获得
            // String currentDateStr=DateUtils.getTime(new Date(),"yyyyMMdd");//换成申请日期的
            String applyTimeStr = DateUtils.getTime(airConditionerAddTime.getUseStartTime(), "yyyy-MM-dd");
            try {
                String jsonStr = HttpKit.holidayGet("https://timor.tech/api/holiday/info/" + applyTimeStr, false);
                System.out.println("节假日接口调用返回===>" + jsonStr);
                Map<String, Object> jsApiMap = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
                if (null != jsApiMap && jsApiMap.containsKey("code")) {
                    if (jsApiMap.get("code").equals(0)) {
                        // dataType = (Integer) jsApiMap.get("type");
                        Map<String, Object> jsApiMapType = (Map) jsApiMap.get("type");
                        if (jsApiMapType.containsKey("type")) {
                            dataType = (Integer) jsApiMapType.get("type");
                            if (dataType == 3) {
                                // 0, 1, 2, 3- 节假日类型，分别表示 工作日、周末、节日、调休 调休改为工作日
                                dataType = 0;
                            }
                        }
                    } else {
                        return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,节假日接口调用失败");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 勾选后非节假日的周六为工作日=================================================2018.10.17
            // 如果为 true 如果get为周六且非2节假日 将 dataType设置为0工作日
            boolean isSaturday = DateUtils.checkIsSaturday(airConditionerAddTime.getUseStartTime());
            if (isSaturday) {
                dataType = 1;
            }
            /**
             * 企业信息
             */
            VirtualArchitecture virtual = virtualArchManager.get(Integer.valueOf(dto.getVirtualId()));
            if (null != virtual && virtual.getOrganizationId() != null) {
                ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
                if (null == projectConfig) {
                    return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调部分项目配置为空,请系统管理员");
                }
                Integer satDataType = projectConfig.getSatDataType();
                if (null != satDataType && satDataType == 1) {///如果为 true
                    // boolean isSaturday = DateUtils.checkIsSaturday(repairBill.getUseStartTime());
                    if (isSaturday && dataType != 2) {// 如果get为周六且非2节假日 将 dataType设置为0工作日
                        dataType = 0;
                    }
                }
            }
            // 提前申请时间校验=================================================2018.10.17
            // 获得当前用户对项目Id 找项目规则
            String virtualId = dto.getVirtualId();
            String checkStr = checkBeforeAppApplyTime(airConditionerAddTime.getUseStartTime(), Long.decode(virtualId));
            if (StringUtils.isNotEmpty(checkStr)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, checkStr);
            }
            // 提前申请时间校验=================================================2018.10.17
            Integer applicationType = 2;// 应用模块(1预定会议室\2空调加时
            Integer applicationAirAddTime = 1;
            Date minDate = null;
            Date maxDate = null;

            /**
             * 项目的空调使用规则信息
             */
            List<AirRule> airRules = airRuleManager.getAirRule(airConditionerAddTime.getOrganizationId(), applicationType, applicationAirAddTime, dataType, "", "");
            log.info("空调加时申请,查询到到的空调加时规则为:{}", airRules);
            AirRule airRule = null;
            if (null == airRules || airRules.isEmpty()) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }
            int airRulesSize = 0;
            for (AirRule ar : airRules) {

                Date ruleStartTime = ar.getStartTime();
                Date ruleEndTime = ar.getEndTime();
                Map recodeMap = DateUtils.getIncludeTime(airConditionerAddTime.getUseStartTime(), airConditionerAddTime.getUseEndTime(), ruleStartTime, ruleEndTime);
                if (recodeMap.containsKey("minDate") && recodeMap.containsKey("maxDate")) {
                    minDate = (Date) recodeMap.get("minDate");
                    maxDate = (Date) recodeMap.get("maxDate");

                    airRule = ar;
                    ++airRulesSize;
                }
            }

            if (airRulesSize == 0) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }
            if (airRulesSize > 1) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,匹配多条空调加时规则");
            }

            // 面积数
            String applyArea = airConditionerAddTime.getApplyArea();// 申请面积

            String selectRoomNames = airConditionerAddTime.getRoomNames();

            BigDecimal calcapplyArea = BigDecimal.ZERO;// 按层申请的面积
            String[] roomNos = airConditionerAddTime.getRoomNos().split(";");
            boolean areaRuleTypeCount1 = false; // 有几种收费类型
            boolean areaRuleTypeCount2 = false; // 有几种收费类型
            boolean areaRuleTypeCount4 = false; // 有几种收费类型 一层起订
            Integer calcAreaRuleType = 1; // 用两种类型计算
            // Integer priceType = 1;//单价类型(1-平米每小时、2-层（半层）每小时) --取项目的
            List<RoomInfo> listRoomInfos = roomInfoManager.getRoomListByRoomNos(airConditionerAddTime.getRoomNos().replaceAll("[;]$", "").replace(";;", ";").replace(";", ","));

            Map<Integer, BigDecimal> floorSumAreaMap = new HashMap<>();// 每层楼的合计申请面积
            Map<Integer, Boolean> mapIsHaveFloor = new HashMap<>();// 当前楼层是有-一层起订
            Map<Integer, Boolean> mapIsHalfHaveFloor = new HashMap<>();// 当前楼层是有-半层起订

            // 根据每个房间配置的是 一层还是半层起订 计算有几个一层 有几个半层起订
            // 一层中如果累计有一层了 后继房间号不累加层数或半层数

            for (RoomInfo roomInfo : listRoomInfos) {

                Integer floorId = roomInfo.getFloorId().intValue();
                String roomName = roomInfo.getName();

                BigDecimal area = roomInfo.getArea();
                Integer areaRuleType = roomInfo.getAreaRuleType();

                if (StringUtils.isNotEmpty(selectRoomNames)) {// 申请的房间号
                    if (!selectRoomNames.contains(roomName)) {
                        continue;
                    }
                }

                // 1-实际面积 2-半层起定 3-不可预定 4-一层起订
                if (null == areaRuleType) {
                    areaRuleType = 1;
                }
                if (areaRuleType == 1) {
                    areaRuleTypeCount1 = true;
                    calcAreaRuleType = 1;
                }
                if (areaRuleType == 2) {
                    areaRuleTypeCount2 = true;
                    calcAreaRuleType = 2;
                }
                if (areaRuleType == 4) {
                    areaRuleTypeCount4 = true;
                    calcAreaRuleType = 4;  // 一层起订
                }

                if (true) {
                    if (floorSumAreaMap.containsKey(floorId)) {
                        BigDecimal temp_area = (BigDecimal) floorSumAreaMap.get(floorId);
                        floorSumAreaMap.put(floorId, temp_area.add(area));
                    } else {
                        floorSumAreaMap.put(floorId, area);
                    }
                }

                if (priceType == 2) {

                    FloorInfo floorInfo = floorInfoManager.get(floorId);
                    if (null == floorInfo.getFloorArea()) {
                        return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "请在空调空间数据中配置楼层面积");
                    }
                }
                if (areaRuleType == 4 && !mapIsHaveFloor.containsKey(floorId)) {
                    mapIsHaveFloor.put(floorId, true);
                }
                if (areaRuleType == 2 && !mapIsHalfHaveFloor.containsKey(floorId)) {
                    mapIsHalfHaveFloor.put(floorId, true);
                }
            }

            // 1-实际面积 2-半层起定 3-不可预定 4-一层起订

            int haveFloorNum = 0;// 一层的数量
            int halfHaveFloorNum = 0;// 半层的数量
            applyArea = "";
            StringBuilder current_floorId = new StringBuilder();
            if (priceType == 1) { // 平米每小时
                for (Integer floorId : floorSumAreaMap.keySet()) {

                    current_floorId.append(floorId.toString()).append(";");

                    boolean isHalfHaveFloor = false;// 是否有半层起
                    boolean isHaveFloor = false;// 是否有一层起
                    if (mapIsHalfHaveFloor.containsKey(floorId)) {
                        isHalfHaveFloor = true;
                    }
                    if (mapIsHaveFloor.containsKey(floorId)) {
                        isHaveFloor = true;
                    }


                    BigDecimal sumArea = floorSumAreaMap.get(floorId);// 当层申请合计面积
                    BigDecimal floorSumArea = roomInfoManager.getSumArueByFloorId(floorId);// 整层合计面积
                    if (null == floorSumArea) {
                        floorSumArea = BigDecimal.ZERO;
                    }
                    BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                    if (isHaveFloor) {
                        calcapplyArea = calcapplyArea.add(floorSumArea);
                    } else if (isHalfHaveFloor) {
                        if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                            calcapplyArea = calcapplyArea.add(halfFloorSumArea);
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            calcapplyArea = calcapplyArea.add(floorSumArea);
                        }
                    } else {// 只有实际
                        calcapplyArea = calcapplyArea.add(sumArea);
                    }

                }
                applyArea = calcapplyArea.toString() + "m²";
            } else if (priceType == 2) { // 层（半层）每小时

                for (Integer floorId : floorSumAreaMap.keySet()) {

                    current_floorId.append(floorId.toString()).append(";");

                    boolean isHalfHaveFloor = false;// 是否有半层起
                    boolean isHaveFloor = false;// 是否有一层起
                    if (mapIsHalfHaveFloor.containsKey(floorId)) {
                        isHalfHaveFloor = true;
                    }
                    if (mapIsHaveFloor.containsKey(floorId)) {
                        isHaveFloor = true;
                    }
                    BigDecimal sumArea = (BigDecimal) floorSumAreaMap.get(floorId);// 当层申请合计面积
                    // BigDecimal  floorSumArea =  roomInfoManager.getSumArueByFloorId(floorId);//整层合计面积
                    FloorInfo floorInfo = floorInfoManager.get(floorId);
                    BigDecimal floorSumArea = floorInfo.getFloorArea();
                    BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                    if (isHaveFloor) {
                        // calcapplyArea = calcapplyArea.add(floorSumArea);
                        haveFloorNum = haveFloorNum + 1;// 一层的加1
                    } else if (isHalfHaveFloor) {
                        if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                            // calcapplyArea = calcapplyArea.add(halfFloorSumArea);
                            halfHaveFloorNum = halfHaveFloorNum + 1;
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            // calcapplyArea = calcapplyArea.add(floorSumArea);
                            haveFloorNum = haveFloorNum + 1;// 一层的加1
                        }
                    } else { // 按面积算

                        if (sumArea.compareTo(halfFloorSumArea) <= 0) { // 不足半层按半层算
                            halfHaveFloorNum = halfHaveFloorNum + 1;
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            haveFloorNum = haveFloorNum + 1;// 一层的加1
                        }
                    }

                }
                // applyArea =  calcapplyArea.toString();
                if (haveFloorNum > 0) {
                    applyArea = "层*" + haveFloorNum;
                }
                if (StringUtils.isNotEmpty(applyArea) && halfHaveFloorNum > 0) {
                    applyArea = applyArea + "," + "半层*" + halfHaveFloorNum;
                } else if (halfHaveFloorNum > 0) {
                    applyArea = "半层*" + halfHaveFloorNum;
                }
            }

            airConditionerAddTime.setFloorId(current_floorId.toString().replaceAll("[;]$", ""));
            airConditionerAddTime.setApplyArea(applyArea);
            airConditionerAddTime.setUseStartTime(minDate);
            airConditionerAddTime.setUseEndTime(maxDate);
            priceHu = airRule.getPriceHouse();
            priceHour = airRule.getPriceHour();

            floorPriceHour = airRule.getFloorPriceHour();// 每层多少钱/每小时
            halfFloorPriceHour = airRule.getHalfFloorPriceHour();// 每半层多少钱/每小时

            // deprecated
            // 空调加时最低申请1小时,半小时按1小时收取费用
            // BigDecimal UseLengthTime = DateUtils.compareStringTimesToHour(airConditionerAddTime.getUseStartTime(), airConditionerAddTime.getUseEndTime());
            // UseLengthTime = UseLengthTime.setScale(0, BigDecimal.ROUND_UP);// 向上取整

            // 20231201 空调加时最低申请半小时，不满半小时按半小时收取费用
            BigDecimal UseLengthTime = DateUtils.calculateUsageDuration(airConditionerAddTime.getUseStartTime(), airConditionerAddTime.getUseEndTime());

            airConditionerAddTime.setUseLengthTime(UseLengthTime);// 使用时长

            // 户数
            int houseNo = 1;// 申请房号IDS(ID;ID)

            boolean isCalcHouse = true;// 是否按面积来计算


            BigDecimal calcFee = BigDecimal.ZERO.setScale(2, RoundingMode.UNNECESSARY);// 费用
            String freeDetail = "";// 费用明细
            // 小时*1层*每层300元/小时
            // 1小时*半层*每半层200元/小时
            // 用面积计算
            if (priceType == 1) {

                String calc_applyArea = applyArea.replace("m²", "");

                // priceDisplay="每平米0.15元/小时";
                priceDisplay = "每平米" + df4.format(priceHour.setScale(2)) + "元/小时";


                // 费用明细：2小时*2平米*每平米0.15元/小时=1400.00元
                calcFee = UseLengthTime.multiply(new BigDecimal(calc_applyArea)).multiply(priceHour).setScale(2, 4);
                freeDetail = UseLengthTime.toPlainString() + "小时*" + calc_applyArea + "平米*" + priceDisplay;
                airConditionerAddTime.setUseAreaOrTime(1);// 使用 1面积 2 时间
            } else if (priceType == 2) {

                // 每层300元/小时、每半层200元/小时
                priceDisplay = "每层" + df4.format(floorPriceHour.setScale(2)) + "元/小时、" + "每半层" + df4.format(halfFloorPriceHour.setScale(2)) + "元/小时";

                // 1小时*1层*每层300元/小时-1小时*半层*每半层200元/小时
                // haveFloorNum 多少一层
                if (haveFloorNum > 0) {
                    calcFee = UseLengthTime.multiply(BigDecimal.valueOf(haveFloorNum)).multiply(floorPriceHour).setScale(2, 4);
                    // 1小时*1层*每层300元/小时
                    freeDetail = UseLengthTime.toPlainString() + "小时*" + haveFloorNum + "层*每层" + floorPriceHour + "元/小时";
                }
                if (halfHaveFloorNum > 0) {
                    calcFee = calcFee.add(UseLengthTime.multiply(BigDecimal.valueOf(halfHaveFloorNum)).multiply(halfFloorPriceHour).setScale(2, 4));

                    if (StringUtils.isNotBlank(freeDetail)) {
                        // 1小时*半层*每半层200元/小时
                        freeDetail = freeDetail + "," + UseLengthTime.toPlainString() + "小时*" + "半层*" + halfHaveFloorNum + "*每半层" + halfFloorPriceHour + "元/小时";
                    } else {
                        freeDetail = UseLengthTime.toPlainString() + "小时*" + "半层*" + halfHaveFloorNum + "*每半层" + halfFloorPriceHour + "元/小时";
                    }
                }

            }


            airConditionerAddTime.setPriceDisplay(priceDisplay);// 单价：每户350元/每小时
            // 工作日2018-09-18 07:00~21:00
            // 工作日根据时间获取
            String dataTypeStr = "工作日";
            if (Objects.equals(dataType, GoodsCodeConstants.DATATYPE_WORKINGDAY)) {// 工作日
                dataTypeStr = "工作日";
            } else if (Objects.equals(dataType, GoodsCodeConstants.DATATYPE_RESTDAY)) {// 休息日
                dataTypeStr = "休息日";
            } else if (Objects.equals(dataType, GoodsCodeConstants.DATATYPE_VACATIONS)) {// 节假日
                dataTypeStr = "节假日";
            }

            // 使用时间(合并显示  工作日2018-09-18 07:00~21:00
            // 使用时间(合并显示  10月25日  07:00~21:00(工作日)
            // String UseStartTimeStr=DateUtils.getDate(repairBill.getUseStartTime(), "yyyy-MM-dd HH:mm");
            String UseStartTimeStr = DateUtils.getDate(airConditionerAddTime.getUseStartTime(), "MM月dd日 HH:mm");
            String useEndTimeStr = DateUtils.getDate(airConditionerAddTime.getUseEndTime(), "HH:mm");
            airConditionerAddTime.setUseDisplayTime(UseStartTimeStr + "~" + useEndTimeStr + "(" + dataTypeStr + ")");

            airConditionerAddTime.setFreeDetail(freeDetail);// 费用明细：2小时*2户*350元=1400.00元
            airConditionerAddTime.setFreeTotal(calcFee);// 费用总计：1400.00元
            airConditionerAddTime.setMonthlyFree(calcFee);// 月结费用：1400.00元

            if (StringUtils.isEmpty(airConditionerAddTime.getFloorId())) {
                if (StringUtils.isNotEmpty(virtual.getFloorIds())) {
                    airConditionerAddTime.setFloorId(virtual.getFloorIds().split(";")[0]);
                }
            }

            String code = CodeGenerateUtils.generate("KTJS");
            airConditionerAddTime.setCode(code);


            String types = "5,6";// 空调加时
            List<Map<String, Object>> list = enterprisePermissionDao.getGoodsConfig(airConditionerAddTime.getOrganizationId().longValue(), types, "");
            if (list != null && !list.isEmpty()) {
                if (null != virPermId && virPermId.equals((Integer) list.get(0).get("roleId"))) {

                    if (list.size() >= 2) {

                        airConditionerAddTime.setType(Integer.parseInt(list.get(1).get("type").toString()));
                        airConditionerAddTime.setRoleId(Integer.parseInt(list.get(1).get("roleId").toString()));
                        airConditionerAddTime.setSort(Integer.parseInt(list.get(1).get("sort").toString()));
                    }

                } else {
                    airConditionerAddTime.setType(Integer.parseInt(list.get(0).get("type").toString()));
                    airConditionerAddTime.setRoleId(Integer.parseInt(list.get(0).get("roleId").toString()));
                    airConditionerAddTime.setSort(Integer.parseInt(list.get(0).get("sort").toString()));
                }

            }

            airConditionerAddTime.setStatus(GoodsCodeConstants.AIR_TOAUDIT);// 保存


            /**
             * 下单时保存可用的规则 修改订单时需要用
             */
            if (cn.superdesk.libs.common.util.CollectionUtils.isEmpty(airRules)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,没有可用规则,请联系系统管理员");
            }

            String allAirRulesStr = JSON.toJSONString(airRules);

            /**
             * 下单时保存所有可用房间信息 修改订单时需要用
             */
            VirtualArchitecture vir = virtualArchManager.get(Integer.valueOf(virtualId));
            String[] split = vir.getRoomIds().split(";");
            List<String> allRoomIds = Arrays.asList(split);
            if (cn.superdesk.libs.common.util.CollectionUtils.isEmpty(allRoomIds)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,没有可用房间,请联系系统管理员");
            }
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < allRoomIds.size(); i++) {
                sb.append(allRoomIds.get(i));
                if (i < allRoomIds.size() - 1) {
                    sb.append(",");
                }
            }
            List<RoomInfo> allRoomInfos = roomInfoManager.getRoomListByRoomNos(sb.toString());
            if (cn.superdesk.libs.common.util.CollectionUtils.isEmpty(allRoomInfos)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,没有可用房间,请联系系统管理员");
            }

            String allRoomInfoStr = JSON.toJSONString(allRoomInfos);

            /**
             * 保存下单时的规则和房间信息
             */
            conditionerAddTimeOrderExtendManager.save(
                    AirConditionerAddTimeOrderExtend.builder()
                            .code(code)
                            .airRules(allAirRulesStr)
                            .roomInfos(allRoomInfoStr)
                            .build()
            );

            /*
             * 保存每个房间均摊的金额
             * 1.单个房间：申请房间面积=订单总金额。
             * 2.多个房间：
             *      申请房间费用=（申请房间面积/订单申请面积）*订单总金额。
             *      最后一个申请房间的费用=订单总金额-申请房间1费用-申请房间N费用。
             */
            BigDecimal totalAmount = airConditionerAddTime.getFreeTotal();
            BigDecimal remainingAmount = totalAmount;
            BigDecimal totalArea = calcapplyArea;
            List<AirConditionerAddTimeOrderAmountDetail> airConditionerAddTimeOrderAmountDetails = new ArrayList<>();

            for (int i = 0; i < listRoomInfos.size(); i++) {
                RoomInfo roomInfo = listRoomInfos.get(i);
                BigDecimal roomArea = roomInfo.getArea();
                AirConditionerAddTimeOrderAmountDetail airConditionerAddTimeOrderAmountDetail = new AirConditionerAddTimeOrderAmountDetail();
                airConditionerAddTimeOrderAmountDetail.setCode(code);
                airConditionerAddTimeOrderAmountDetail.setRoomId(roomInfo.getId());
                if (i == listRoomInfos.size() - 1) {
                    airConditionerAddTimeOrderAmountDetail.setAmount(remainingAmount);
                } else {
                    BigDecimal roomCost = roomArea.divide(totalArea, 10, RoundingMode.HALF_UP).multiply(totalAmount).setScale(2, RoundingMode.HALF_UP);
                    airConditionerAddTimeOrderAmountDetail.setAmount(roomCost);
                    remainingAmount = remainingAmount.subtract(roomCost);
                }
                airConditionerAddTimeOrderAmountDetails.add(airConditionerAddTimeOrderAmountDetail);
            }

            if (cn.superdesk.libs.common.util.CollectionUtils.isNotEmpty(airConditionerAddTimeOrderAmountDetails)) {
                for (AirConditionerAddTimeOrderAmountDetail airConditionerAddTimeOrderAmountDetail : airConditionerAddTimeOrderAmountDetails) {
                    conditionerAddTimeOrderAmountDetailManager.save(airConditionerAddTimeOrderAmountDetail);
                }
            }

            AirConditionerAddTime bill = conditionerAddTimeManager.save(airConditionerAddTime);

            return AppResultUtil.createSuccesDto(convert(bill));

        } catch (Exception e) {
            log.error("空调加时申请失败:{}", LogExceptionStackUtil.LogExceptionStack(e));
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
        }

    }

    @Override
    public AirConditionerAddTimeOutDto convert(AirConditionerAddTime addTime) {

        DecimalFormat df4 = new DecimalFormat();
        df4.applyPattern("0.00");
        AirConditionerAddTimeOutDto dto = new AirConditionerAddTimeOutDto();
        dto.setBillId(addTime.getId());
        dto.setCode(addTime.getCode());
        dto.setCreatorOpenId(addTime.getCreatorBillId());

        VirtualArchitecture vir = virtualArchManager.get(Integer.parseInt(String.valueOf(addTime.getVirtualId().toString())));
        if (null != vir && StringUtils.isNotEmpty(vir.getName())) {
            dto.setVirtualName(vir.getName());
        } else {
            dto.setVirtualName("");
        }
        if (null != addTime.getVirAccountId() && addTime.getVirAccountId().intValue() != 0) {
            VirtualAccount virtualAccount = virtualAccountManager.get(addTime.getVirAccountId());
            if (null != virtualAccount && StringUtils.isNotEmpty(virtualAccount.getVirAccount())) {
                dto.setVirAccountNo(virtualAccount.getVirAccount());
            }
        } else {
            dto.setVirAccountNo("");
        }
        dto.setApplyUser(addTime.getApplyUser());
        dto.setApplyTel(addTime.getApplyTel());

        if (null != addTime.getFloorId() && StringUtil.isNotEmpty(addTime.getFloorId())) {

            if (addTime.getFloorId().contains(";")) {
                String[] floorIds = addTime.getFloorId().split(";");
                String floorIdName = "";
                for (String floorId : floorIds) {
                    floorIdName = floorIdName + floorInfoManager.get(Integer.valueOf(floorId)).getName() + "楼" + ";";
                }
                dto.setFloorNo(floorIdName.replaceAll("[;]$", ""));
            } else {
                dto.setFloorNo(floorInfoManager.get(Integer.valueOf(addTime.getFloorId())).getName() + "楼");
            }


        } else {
            dto.setFloorNo("");
        }

        dto.setRoomNames(addTime.getRoomNames());
        dto.setApplyTime(DateHelper.formatDate(addTime.getCreateTime(), DateHelper.DATE_STRING));
        dto.setApplyArea(addTime.getApplyArea());
        dto.setUseDisplayTime(addTime.getUseDisplayTime());
        dto.setUseLengthTime(addTime.getUseLengthTime());
        dto.setPriceDisplay(addTime.getPriceDisplay());
        dto.setFreeDetail(addTime.getFreeDetail());
        dto.setFreeTotal(df4.format(addTime.getFreeTotal().setScale(2)));
        dto.setMonthlyFree(df4.format(addTime.getMonthlyFree().setScale(2)));
        dto.setType(addTime.getType());
        dto.setRoleId(addTime.getRoleId());
        dto.setSort(addTime.getSort());

        ////使用1面积 2 时间
        if (null != addTime.getUseAreaOrTime()) {
            dto.setUseAreaOrTime(addTime.getUseAreaOrTime().toString());
        } else {
            dto.setUseAreaOrTime("");
        }
        // 会议室订单加时 会议室订单号
        dto.setMeetingCode(StringUtils.isEmpty(addTime.getMeetingCode()) ? "" : addTime.getMeetingCode());

        dto.setBillSource(addTime.getBillSource().toString());
        dto.setStatus(addTime.getStatus().toString());
        dto.setSwitchUser(StringUtils.isEmpty(addTime.getSwitchUser()) ? "" : addTime.getSwitchUser());
        dto.setSwitchTel(StringUtils.isEmpty(addTime.getSwitchTel()) ? "" : addTime.getSwitchTel());

        if (null != addTime.getIsAppManageBook()) {
            dto.setIsAppManageBook(addTime.getIsAppManageBook().toString());

            if (addTime.getIsAppManageBook() == 1) {
                dto.setPreBookUser(addTime.getCreator());
            }
        } else {
            dto.setIsAppManageBook("0");
            dto.setPreBookUser("");
        }

        dto.setCancelReason(StringUtils.isEmpty(addTime.getCancelReason()) ? "" : addTime.getCancelReason());
        if (null != addTime.getCancelTime()) {
            dto.setCancelTime(DateHelper.formatDate(addTime.getCancelTime(), DateHelper.DATE_STRING));
        } else {
            dto.setCancelTime("");
        }
        dto.setCancelUser(StringUtils.isEmpty(addTime.getCancelUser()) ? "" : addTime.getCancelUser());

        List<EnterpriseAudit> records;
        try {
            records = enterpriseAuditManager.getEnterAuditList("4", Integer.parseInt(String.valueOf(addTime.getId())));
            List<GoodsOperateDto> dtos = new ArrayList<GoodsOperateDto>();
            for (EnterpriseAudit record : records) {
                String auditResult = "";
                if (record.getReasonType() == 1) {
                    auditResult = "通过";
                } else if (record.getReasonType() == 0) {
                    auditResult = "不通过";
                }

                String auditUserName = "";
                if (StringUtils.isNotBlank(record.getAuditUserName())) {
                    auditUserName = record.getAuditUserName();
                } else {
                    int creator = record.getCreator();
                    User user = userManager.get(Long.valueOf(String.valueOf(creator)));
                    auditUserName = user.getFullName();
                }
                GoodsOperateDto dt = new GoodsOperateDto(DateHelper.formatDate(record.getCreateTime(), DateHelper.DATE_STRING), auditUserName, auditResult, record.getRemark());
                dt.setAuditStatus(record.getContent());// auditStatus
                dtos.add(dt);
            }
            dto.setOperateDto(dtos);

        } catch (Exception e) {
            e.printStackTrace();
        }


        // 全部审核流程走完
        String types = "5,6";// 两个审核流程一起算sort的
        List<Map<String, Object>> list = enterprisePermissionDao.getGoodsConfig(addTime.getOrganizationId().longValue(), types, "");

        if (null != addTime.getSort()) {
            if (list.size() == addTime.getSort()) {
                dto.setIsLastAuditStep(1);
            }
        }

        if (null != addTime.getUserId()) {
            AppUser appUser = appUserManager.get(addTime.getUserId());
            if (null != appUser) {
                dto.setLoginName(appUser.getLoginName());
            }
        }

        dto.setUseStartTime(addTime.getUseStartTime());
        dto.setUseEndTime(addTime.getUseEndTime());

        return dto;
    }

    @Override
    public AppResultDto applyConfirm(HttpServletRequest request) {

        try {
            String creatorOpenId = request.getParameter("creatorOpenId");
            String billId = request.getParameter("billId");
            AirConditionerAddTime bill = conditionerAddTimeManager.get(Long.decode(billId));
            bill.setStatus(GoodsCodeConstants.AIR_TOAUDIT);// 待客服专员审核

            // 状态校验
            // creatorOpenId校验

            AirConditionerAddTime saveBill = conditionerAddTimeManager.save(bill);


            // User user = (User) request.getSession().getAttribute("UserCache");
            // 获得当前用户 最大的角色ID
            // String airAuditRoleId = getMaxRoleIdByUser(user);
			
			
			/*//管理楼导
			String roleToFloorIds="";
			List<AppUserFloorRelation> userFloorList=userManager.getAppUserFloorByUserId(Integer.parseInt(user.getId().toString()), Integer.parseInt(airAuditRoleId));
			if(userFloorList!=null&&userFloorList.size()>0){
				for(int i=0;i<userFloorList.size();i++){
					AppUserFloorRelation userFloor=userFloorList.get(i);
					if(null!=userFloor.getFloor_id()){
						roleToFloorIds+=userFloor.getFloor_id().toString()+",";
					}
				}
			}
			if(StringUtils.isNotEmpty(roleToFloorIds)){
				roleToFloorIds=roleToFloorIds.replaceAll("[,]$", "");
			}*/

            // push(saveBill);//发app推送 是楼层
            // TODO 一步一步推送
            return AppResultUtil.createSuccesDto(convert(saveBill));
        } catch (Exception e) {
            e.printStackTrace();
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
        }
    }


    @Override
    public AppResultDto meetingApplyConfirm(HttpServletRequest request) {

        try {
            String billId = request.getParameter("billId");
            String meetingCode = request.getParameter("meetingCode");
            AirConditionerAddTime bill = conditionerAddTimeManager.get(Long.decode(billId));
            bill.setStatus(GoodsCodeConstants.AIR_WAITUSE);// 待客服专员审核
            bill.setMeetingCode(meetingCode);


            log.info("ConditionerAddTimeServiceImpl meetingApplyConfirm billId======" + billId);
            log.info("ConditionerAddTimeServiceImpl meetingApplyConfirm meetingCode======" + meetingCode);

            AirConditionerAddTime saveBill = conditionerAddTimeManager.save(bill);

            return AppResultUtil.createSuccesDto(convert(saveBill));
        } catch (Exception e) {
            e.printStackTrace();
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
        }
    }

    /**
     * 获得当前用户 最大的角色ID
     * 4121
     * 4122
     * 4123
     * @param user
     * @return
     */
    private String getMaxRoleIdByUser(User user) {
        User userAir21 = userManager.findByFunctionAndUser(CodeConstants.CSP21_PERMISSION, user.getId());
        User userAir22 = userManager.findByFunctionAndUser(CodeConstants.CSP22_PERMISSION, user.getId());
        User userAir23 = userManager.findByFunctionAndUser(CodeConstants.CSP23_PERMISSION, user.getId());

        // 空调加时审批权限
        String airAuditPermission = "0";// 待审批的数据
        String airAuditRoleId = "0";
		/*if (userAir21 != null) {
			airAuditPermission = GoodsCodeConstants.AIR_AUDITKE.toString();
			Role role = userManager.findRoleByFunctionAndUser(CodeConstants.CSP21_PERMISSION, user.getId());
			airAuditRoleId = role.getId().toString();
		}
		if (userAir22 != null) {
			//airAuditPermission=airAuditPermission+";"+GoodsCodeConstants.AIR_AUDITKEL.toString();
			airAuditPermission = GoodsCodeConstants.AIR_AUDITKEL.toString();

			Role role = userManager.findRoleByFunctionAndUser(CodeConstants.CSP22_PERMISSION, user.getId());
			airAuditRoleId = role.getId().toString();
		}
		if (userAir23 != null) {
			//airAuditPermission=airAuditPermission+";"+GoodsCodeConstants.AIR_AUDITGZL.toString();
			airAuditPermission = GoodsCodeConstants.AIR_AUDITGZL.toString();

			Role role = userManager.findRoleByFunctionAndUser(CodeConstants.CSP23_PERMISSION, user.getId());
			airAuditRoleId = role.getId().toString();
		}*/
        return airAuditRoleId;
    }

    @Override
    public Page findPageBy(Map<String, Object> params, int pageSize, int pageNo) {
        return conditionerAddTimeManager.findPageBy(params, pageSize, pageNo);
    }

    /**
     * 同意或不同意
     */
    @Override
    public AppResultDto audit(AirConditionerAddTimeInputDto dto,
                              HttpServletRequest request) {

        User user = null;
        String auditUserName = "";
        if (dto.getBillFrom().equals(CodeConstants.PC)) {
            user = (User) request.getSession().getAttribute("UserCache");
        } else if (dto.getBillFrom().equals(CodeConstants.ANDROID) || dto.getBillFrom().equals(CodeConstants.iOS)) {
            String userName = baseRedisService.get(request.getHeader("token"));
            if (userName == null) {
                return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
            }
            user = userManager.getUserByUsername2(userName);
        } else if (dto.getBillFrom().equals(CodeConstants.WECHAT)) {

            auditUserName = "企业管理员";
            if (dto.getWxUserId() != null) {
                AppUser appUser = appUserManager.get(dto.getWxUserId());

                if (StringUtils.isNotBlank(appUser.getUserName())) {
                    auditUserName = appUser.getUserName();
                }

            }
        }


        String auditResult = dto.getAuditResult();
        if (StringUtils.isEmpty(auditResult)) {
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "审核结果参数不能为空");
        }
        AirConditionerAddTime bill = conditionerAddTimeManager.get(dto.getBillId());
        Integer billStatus = bill.getStatus();
		
		/*String                functionSysNo  = "";//功能性编码 用于发信息
		AirConditionerAddTime bill           = conditionerAddTimeManager.get(dto.getBillId());
		Integer               billStatus     = bill.getStatus();
		Integer               nextbillStatus = 0;//下一个订单状态
		if (auditResult.equals("1")) { //同意
			nextbillStatus = billStatus + 1;//下一个订单状态
			if (billStatus == GoodsCodeConstants.AIR_AUDITGZL) {
				nextbillStatus = GoodsCodeConstants.AIR_WAITUSE;
			}

			if (nextbillStatus == GoodsCodeConstants.AIR_AUDITKEL) {
				functionSysNo = CodeConstants.CSP22_PERMISSION;
			} else if (nextbillStatus == GoodsCodeConstants.AIR_AUDITGZL) {
				functionSysNo = CodeConstants.CSP23_PERMISSION;
			}

			//空调开关人员ID--23状态时提交 同意才保存开关人员信息
			if (billStatus == GoodsCodeConstants.AIR_AUDITGZL) {
				String switchUserId = dto.getSwitchUserId();
				if (StringUtils.isEmpty(switchUserId)) {
					return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "请指定空调开关人员");
				} else {
					User appUser = userManager.get(Long.decode(switchUserId));
					if (null != appUser) {
						bill.setSwitchUser(appUser.getFullName());
						bill.setSwitchTel(appUser.getTelephone());
					}
				}
			}

		} else if (auditResult.equals("0")) {//不同意
			nextbillStatus = GoodsCodeConstants.AIR_YETREFUSE;//已拒绝
		} else {
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "审核结果参数无效");
		}*/
        // bill.setStatus(nextbillStatus);//前走一步

        // Integer currentBillStatus = Integer.valueOf(dto.getCurrentBillStatus());
        // if (currentBillStatus != billStatus) {
        //	return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "审核状态不匹配,请检查是否重复提交");
        //}

        // if (!(billStatus == GoodsCodeConstants.AIR_AUDITKE || billStatus == GoodsCodeConstants.AIR_AUDITKEL || billStatus == GoodsCodeConstants.AIR_AUDITGZL)) {
        //	return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "当前状态不需要审核");
        //}


        if (auditResult.equals("1")) {

            // 全部审核流程走完
            String types = "5,6";
            List<Map<String, Object>> list = enterprisePermissionDao.getGoodsConfig(bill.getOrganizationId().longValue(), types, "");

            if (null != bill.getSort() && null != list && list.size() > 0 && list.size() > bill.getSort()) {

                bill.setType(Integer.parseInt(list.get(bill.getSort()).get("type").toString()));// 下一级审批人
                bill.setRoleId(Integer.parseInt(list.get(bill.getSort()).get("roleId").toString()));
                bill.setSort(Integer.parseInt(list.get(bill.getSort()).get("sort").toString()));

            } else {

                bill.setType(null);
                bill.setRoleId(null);
                bill.setSort(null);
                billStatus = GoodsCodeConstants.AIR_WAITUSE; // 待使用
            }
        } else if (auditResult.equals("0")) {
            billStatus = GoodsCodeConstants.AIR_YETREFUSE; // 已拒绝
        }

        if (billStatus == GoodsCodeConstants.AIR_WAITUSE) {
            String switchUserId = dto.getSwitchUserId();
            if (StringUtils.isEmpty(switchUserId)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "请指定空调开关人员");
            } else {
                User appUser = userManager.get(Long.decode(switchUserId));
                if (null != appUser) {
                    bill.setSwitchUserId(appUser.getId());
                    bill.setSwitchUser(appUser.getFullName());
                    bill.setSwitchTel(appUser.getTelephone());
                }
            }
        }


        EnterpriseAudit record = new EnterpriseAudit();
        record.setAuditUserName(auditUserName);
        if (StringUtils.isEmpty(auditUserName)) {// 用户姓名为空时 为pc或app
            record.setCreator(Integer.parseInt(String.valueOf(user.getId())));
        }
        record.setContent(billStatus.toString());// 根据状态来判断人


        record.setCreateTime(new Date());
        record.setType("4");// 类型1企业入驻2企业迁出3物品放行4空调加时
        record.setSourseId(Integer.parseInt(String.valueOf(bill.getId())));

        record.setReasonType(Integer.valueOf(auditResult));// 审批操作类型
        record.setRemark(dto.getAuditOpinion());

        bill.setStatus(billStatus);
        conditionerAddTimeManager.save(bill);

        enterpriseAuditManager.save(record);


        try {

            // 发app推送
            // TODO
            // if (StringUtils.isNotEmpty(functionSysNo)) {
            //	 push(bill, functionSysNo);//发app推送 是楼层
            //}

            push(bill);

            if (billStatus == GoodsCodeConstants.AIR_WAITUSE && auditResult.equals("1")) {// 同意

                if (StringUtils.isNotEmpty(bill.getSwitchTel())) {
                    String smsContent = "你好,你有新的空调开启关闭任务:空调加时申请位置：" + bill.getRoomNames() + ",申请使用时间：" + bill.getUseDisplayTime() + ",请按时开启关闭空调";
                    // smsAuthCodeManager.smsSend(bill.getSwitchTel(), smsContent);
                    // smsAuthCodeManager.smsSendByOrgId(bill.getOrganizationId().toString(), smsContent, bill.getSwitchTel(), "", CodeConstants.SMS_AIR_TYPE);

                    WxMessageConfigVo configVo = smsAuthCodeManager.getWxMessageConfig(bill.getOrganizationId(), CodeConstants.CODE_AIR_DO);
                    log.info("空调审批发短息smsAuthCodeManager. configVo ======>" + JSON.toJSONString(configVo));
                    if (null != configVo) {

                        // String params=configVo.getBusinessParam();//[DATE],[ROOM]
                        Map<String, String> paramMap = new HashMap<String, String>();
                        paramMap.put("[DATE]", bill.getUseDisplayTime());
                        paramMap.put("[ROOM]", bill.getRoomNames());
                        WechatMessageDto msgDto = new WechatMessageDto();
                        msgDto.setOrgId(bill.getOrganizationId());
                        msgDto.setBusinessCode(configVo.getBusinessCode());
                        msgDto.setMobils(bill.getSwitchTel());
                        msgDto.setParamMap(paramMap);
                        msgDto.setSmsType(2);
                        msgDto.setType(configVo.getType());
                        String result = smsAuthCodeManager.smsSendByOrgId(msgDto);
                        log.info("空调审批发短息返回 ======>" + result);
                    } else {
                        // smsAuthCodeManager.smsSend(bill.getSwitchTel(), smsContent);
                        smsAuthCodeManager.smsSendByOrgId(bill.getOrganizationId().toString(), smsContent, bill.getSwitchTel(), "", CodeConstants.SMS_AIR_TYPE);

                    }

                }

                conditionerAddTimeManager.sendAgreeWechat(bill, "");// 同意发微信模板消息
            } else if (auditResult.equals("0")) {// 拒绝发微信模板消息

                conditionerAddTimeManager.sendRefuseWechat(bill, dto.getAuditOpinion());
            }

        } catch (Exception e) {
            log.info("ConditionerAddTimeServiceImpl audit 空调审批发app消息错误 ======>" + e.getMessage());
            e.printStackTrace();
        }

        return AppResultUtil.createSuccesDto(convert(bill));
    }

    @Override
    public AppResultDto cancel(AirConditionerAddTimeInputDto dto,
                               HttpServletRequest request) {

        User user = null;
        if (dto.getBillFrom().equals(CodeConstants.PC)) {
            user = (User) request.getSession().getAttribute("UserCache");
        } else if (dto.getBillFrom().equals(CodeConstants.ANDROID) || dto.getBillFrom().equals(CodeConstants.iOS)) {
            String userName = baseRedisService.get(request.getHeader("token"));
            if (userName == null) {
                return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
            }
            user = userManager.getUserByUsername2(userName);
        } else if (dto.getBillFrom().equals(CodeConstants.WECHAT)) {
            user = new User();
            user.setFullName("客户");
        }

        AirConditionerAddTime bill = conditionerAddTimeManager.get(dto.getBillId());
        Integer billStatus = bill.getStatus();

        // 提前取消时间=================================================2018.10.17
        // 设置提前取消时间：单位为小时，用于控制空调加时的取消订单操作权限，如设置为2小时，使用时间为9点的订单只能在7点之前取消
        // 提前取消时间
        String checkStr = checBeforeCancelTime(bill.getUseStartTime(), bill.getVirtualId(), dto.getBillFrom());
        if (StringUtils.isNotEmpty(checkStr)) {
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, checkStr);
        }
        // 提前取消时间=================================================2018.10.17


        String cancelReason = dto.getCancelReason();
        if (StringUtils.isEmpty(cancelReason)) {
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "取消原因不能为空");
        }

        // Integer currentBillStatus = Integer.valueOf(dto.getCurrentBillStatus());
        // if (currentBillStatus != billStatus) {
        //	return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "审核状态不匹配,请检查是否重复提交");
        //}

        // 待使用 iso 或 android
        if (dto.getBillFrom().equals(CodeConstants.ANDROID) || dto.getBillFrom().equals(CodeConstants.iOS)) {
            if (billStatus != GoodsCodeConstants.AIR_WAITUSE) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "待使用状态才可以取消订单");
            }
        }

        if (dto.getBillFrom().equals(CodeConstants.WECHAT)) {
            if (!(billStatus == GoodsCodeConstants.AIR_WAITUSE || billStatus == GoodsCodeConstants.AIR_TOAUDIT)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "待使用或待审核状态才可以取消订单");
            }
        }


        bill.setCancelTime(new Date());
        if (null != user && StringUtils.isNotEmpty(user.getFullName())) {
            bill.setCancelUser(user.getFullName());
        } else {
            bill.setCancelUser("");
        }
        bill.setCancelReason(cancelReason);
        bill.setStatus(GoodsCodeConstants.AIR_YETCANCEL);// 取消
        conditionerAddTimeManager.save(bill);

        try {
            if (StringUtils.isNotEmpty(bill.getSwitchTel())) {
                // String smsContent = "你好,空调加时申请位置：" + bill.getRoomNames() + ",申请使用时间：" + bill.getUseDisplayTime() + "的订单取消了,请知悉";
                // smsAuthCodeManager.smsSend(bill.getSwitchTel(), smsContent);


                WxMessageConfigVo configVo = smsAuthCodeManager.getWxMessageConfig(bill.getOrganizationId(), CodeConstants.CODE_AIR_CANCEL);
                log.info("空调审批发短息smsAuthCodeManager. configVo ======>" + JSON.toJSONString(configVo));
                if (null != configVo) {

                    // String params=configVo.getBusinessParam();//[DATE],[ROOM]
                    Map<String, String> paramMap = new HashMap<String, String>();
                    paramMap.put("[DATE]", bill.getUseDisplayTime());
                    WechatMessageDto msgDto = new WechatMessageDto();
                    msgDto.setOrgId(bill.getOrganizationId());
                    msgDto.setBusinessCode(configVo.getBusinessCode());
                    msgDto.setMobils(bill.getSwitchTel());
                    msgDto.setParamMap(paramMap);
                    msgDto.setSmsType(2);
                    msgDto.setType(configVo.getType());
                    String result = smsAuthCodeManager.smsSendByOrgId(msgDto);
                    log.info("空调审批发短息返回 ======>" + result);
                } else {
                    String smsContent = "你好,空调加时申请位置：" + bill.getRoomNames() + ",申请使用时间：" + bill.getUseDisplayTime() + "的订单取消了,请知悉";
                    // smsAuthCodeManager.smsSend(bill.getSwitchTel(), smsContent);
                    smsAuthCodeManager.smsSendByOrgId(bill.getOrganizationId().toString(), smsContent, bill.getSwitchTel(), "", CodeConstants.SMS_AIR_TYPE);
                }


            }
            // 取消发微信消息
            //			if(!dto.getBillFrom().equals(CodeConstants.PC)){
            conditionerAddTimeManager.sendCancelWechat(bill, bill.getCancelReason());
            //			}
        } catch (Exception e) {
            e.printStackTrace();
        }


        return AppResultUtil.createSuccesDto(convert(bill));
    }


    @Override
    public AirConditionerAddTimeOutDto findById(Long id) {

        return this.convert(conditionerAddTimeManager.get(id));
    }

    @Override
    public AirRule getRuleByOrgId(Long orgId) {

        return airRuleManager.getRuleByOrgId(orgId);
    }

    // 根据企业账号获得房号、面积信息
    @Override
    public AppResultDto getRoomsAndAreaByVirtualId(
            AirConditionerAddTimeInputDto dto, HttpServletRequest request) throws Exception {


        Integer isSelectRoom = dto.getIsSelectRoom();
        String selectRoomNames = dto.getSelectRoomNames();

        String virtualId = dto.getVirtualId();
        VirtualArchitecture vir = virtualArchManager.get(Integer.valueOf(String.valueOf(virtualId)));
        // String              roomNames  = vir.getRoomNames().replaceAll("[;]$", "");
        String roomNames = "";
        String roomIdsStr = vir.getRoomIds().replaceAll("[;]$", "");

        String floorIdsStr = vir.getFloorIds().replaceAll("[;]$", "");
        String floorIdStr = floorIdsStr.split(";")[0];// 楼层ID 用于发app消息 --有可能在多个楼层

        Map floorSumAreaMap = new HashMap<Integer, BigDecimal>();// 每层楼的合计申请面积
        Map mapIsHaveFloor = new HashMap<Integer, Boolean>();// 当前楼层是有-一层起订
        Map mapIsHalfHaveFloor = new HashMap<Integer, Boolean>();// 当前楼层是有-半层起订


        Integer priceType = 1;
        AirRule airRule_data = getRuleByOrgId(Long.valueOf(vir.getOrganizationId()));
        if (null != airRule_data && null != airRule_data.getPriceType()) {
            priceType = airRule_data.getPriceType();
        }

        String[] roomIds = roomIdsStr.split(";");
        // BigDecimal applyArea = BigDecimal.ZERO;
        for (int i = 0; i < roomIds.length; i++) {
            String roomId = roomIds[i];
            if (StringUtils.isEmpty(roomId)) {
                continue;
            }
            RoomInfo roomInfo = roomInfoManager.get(Integer.valueOf(roomId));
            BigDecimal area = roomInfo.getArea();
            if (null == area) {
                area = BigDecimal.ZERO;
            }
            String roomName = roomInfo.getName();

            Integer floorId = roomInfo.getFloorId().intValue();
            Integer areaRuleType = roomInfo.getAreaRuleType();


            // 不可预定 不统计
			/*if(!(roomInfo.getAreaRuleType().equals(1) || roomInfo.getAreaRuleType().equals(2) || roomInfo.getAreaRuleType().equals(4))){
				continue;
			}*/

            if (1 == isSelectRoom && StringUtils.isNotEmpty(selectRoomNames)) {
                if (!selectRoomNames.contains(roomName)) {
                    continue;
                }
            }

            roomNames = roomNames + roomName + ";";

			/*if (null != area) {
				applyArea = applyArea.add(area).setScale(2, 4);
			}*/

            // 申请-每楼面积合计
            // if(areaRuleType == 1 || areaRuleType == 2 || areaRuleType == 4){
            if (true) {
                if (floorSumAreaMap.containsKey(floorId)) {
                    BigDecimal temp_area = (BigDecimal) floorSumAreaMap.get(floorId);
                    floorSumAreaMap.put(floorId, temp_area.add(area));
                } else {
                    floorSumAreaMap.put(floorId, area);
                }
            }

            if (priceType == 2) {
                FloorInfo floorInfo = floorInfoManager.get(floorId);
                if (null == floorInfo.getFloorArea()) {
                    return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "请在空调空间数据中配置楼层面积");
                }
            }


            // 楼层面积根据 楼层配置的来
			/*if(!floorSumAreaMap.containsKey(floorId)){ //没有保存时 处理
				
				FloorInfo floorInfo = floorInfoManager.get(floorId);
				if(null == floorInfo.getFloorArea()){
					return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "请在空调空间数据中配置楼层面积");
				}else{
					floorSumAreaMap.put(floorId, floorInfo.getFloorArea());
				}
			}*/

            if (null != areaRuleType && areaRuleType == 4 && !mapIsHaveFloor.containsKey(floorId)) {
                mapIsHaveFloor.put(floorId, true);
            }
            if (null != areaRuleType && areaRuleType == 2 && !mapIsHalfHaveFloor.containsKey(floorId)) {
                mapIsHalfHaveFloor.put(floorId, true);
            }

        }


        String applyArea = "";
        Integer haveFloorNum = 0;// 一层的数量
        BigDecimal calcapplyArea = BigDecimal.ZERO;// 按层申请的面积
        Integer halfHaveFloorNum = 0;// 半层的数量


        // applyArea = "";
        if (StringUtils.isNotEmpty(selectRoomNames)) { // 选择后 在算价格
            applyArea = this.getApplyArea(floorSumAreaMap, mapIsHaveFloor, mapIsHalfHaveFloor, applyArea, haveFloorNum, calcapplyArea, halfHaveFloorNum, priceType);
        }


        JSONObject returnMap = new JSONObject();
        returnMap.put("floorId", floorIdStr);
        // returnMap.put("roomNos", roomIdsStr);
        returnMap.put("roomNos", roomIdsStr);
        returnMap.put("settleType", vir.getSettleType());// 企业结算方式(1现结2月结)
        returnMap.put("roomNames", "");


        returnMap.put("applyArea", applyArea);
        returnMap.put("applyMaxWeekNo", 2);// 提前申请最大周数

        returnMap.put("isSelectRoom", 0);
        Integer organizationId = vir.getOrganizationId();
        if (null != organizationId) {
            ProjectConfig pf = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(organizationId));

            if (null != pf && null != pf.getBeforeApplyTime()) {
                returnMap.put("beforeApplyTime", pf.getBeforeApplyTime().intValue());
            } else {
                returnMap.put("beforeApplyTime", 1);
            }

            if (null != pf && null != pf.getIsSelectRoom()) {
                returnMap.put("isSelectRoom", pf.getIsSelectRoom());
            }


        } else {
            returnMap.put("beforeApplyTime", 1);// 提前申请小时数
        }

        returnMap.put("applyUser", "");
        returnMap.put("applyTel", "");
        TbOrganization org = organizationManager.getOrganizationById(organizationId);
        if (null != org && org.getAccountType() == 1) {// 项目为个人类型 返回申请人信息不能编辑
            WxUser wxUser = scWxuserManager.getScWxuserByOpenId(dto.getOpenId());
            if (null != wxUser) {
                AppUser appUer = appUserManager.getAppUserByWxUserAndOrg(wxUser.getId(), organizationId);
                if (null != appUer && StringUtils.isNotEmpty(appUer.getUserName()) && StringUtils.isNotEmpty(appUer.getUserMobile())) {
                    returnMap.put("applyUser", appUer.getUserName());
                    returnMap.put("applyTel", appUer.getUserMobile());
                }

            }
        }


        return AppResultUtil.createSuccesDto(returnMap);
    }

    private String getApplyArea(Map floorSumAreaMap, Map mapIsHaveFloor,
                                Map mapIsHalfHaveFloor, String applyArea, Integer haveFloorNum,
                                BigDecimal calcapplyArea, Integer halfHaveFloorNum,
                                Integer priceType) throws Exception {

        if (priceType == 1) { // 平米每小时
            Iterator it = floorSumAreaMap.keySet().iterator();
            while (it.hasNext()) {

                Integer floorId = (Integer) it.next();

                boolean isHalfHaveFloor = false;// 是否有半层起
                boolean isHaveFloor = false;// 是否有一层起
                if (mapIsHalfHaveFloor.containsKey(floorId)) {
                    isHalfHaveFloor = true;
                }
                if (mapIsHaveFloor.containsKey(floorId)) {
                    isHaveFloor = true;
                }


                BigDecimal sumArea = (BigDecimal) floorSumAreaMap.get(floorId);// 当层申请合计面积
                BigDecimal floorSumArea = roomInfoManager.getSumArueByFloorId(floorId);// 整层合计面积

                // FloorInfo floorInfo = floorInfoManager.get(floorId);
                // BigDecimal  floorSumArea = floorInfo.getFloorArea();


                BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                if (isHaveFloor) {
                    calcapplyArea = calcapplyArea.add(floorSumArea);
                } else if (isHalfHaveFloor) {
                    if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                        calcapplyArea = calcapplyArea.add(halfFloorSumArea);
                    } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                        calcapplyArea = calcapplyArea.add(floorSumArea);
                    }
                } else {// 只有实际
                    calcapplyArea = calcapplyArea.add(sumArea);
                }

            }
            applyArea = calcapplyArea.toString() + "m²";
        } else if (priceType == 2) { // 层（半层）每小时

            Iterator it = floorSumAreaMap.keySet().iterator();
            // BigDecimal calApplyArea = BigDecimal.ZERO;
            while (it.hasNext()) {

                Integer floorId = (Integer) it.next();

                boolean isHalfHaveFloor = false;// 是否有半层起
                boolean isHaveFloor = false;// 是否有一层起
                if (mapIsHalfHaveFloor.containsKey(floorId)) {
                    isHalfHaveFloor = true;
                }
                if (mapIsHaveFloor.containsKey(floorId)) {
                    isHaveFloor = true;
                }
                BigDecimal sumArea = (BigDecimal) floorSumAreaMap.get(floorId);// 当层申请合计面积
                // BigDecimal  floorSumArea =  roomInfoManager.getSumArueByFloorId(floorId);//整层合计面积
                FloorInfo floorInfo = floorInfoManager.get(floorId);
                BigDecimal floorSumArea = floorInfo.getFloorArea();


                BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                if (isHaveFloor) {
                    // calcapplyArea = calcapplyArea.add(floorSumArea);
                    haveFloorNum = haveFloorNum + 1;// 一层的加1
                } else if (isHalfHaveFloor) {
                    if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                        // calcapplyArea = calcapplyArea.add(halfFloorSumArea);
                        halfHaveFloorNum = halfHaveFloorNum + 1;
                    } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                        // calcapplyArea = calcapplyArea.add(floorSumArea);
                        haveFloorNum = haveFloorNum + 1;// 一层的加1
                    }
                } else {// 只有实际
                    // calApplyArea = calApplyArea.add(sumArea);

                    if (sumArea.compareTo(halfFloorSumArea) <= 0) { // 不足半层按半层算
                        halfHaveFloorNum = halfHaveFloorNum + 1;
                    } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                        haveFloorNum = haveFloorNum + 1;// 一层的加1
                    }

                }

            }
            // applyArea =  calcapplyArea.toString();
            if (haveFloorNum > 0) {
                applyArea = "层*" + haveFloorNum.toString();
            }
            if (StringUtils.isNotEmpty(applyArea) && halfHaveFloorNum > 0) {
                applyArea = applyArea + "," + "半层*" + halfHaveFloorNum.toString();
            } else if (halfHaveFloorNum > 0) {
                applyArea = "半层*" + halfHaveFloorNum.toString();
            }
        }

        return applyArea;
    }

    @Override
    public AppResultDto getAirSwitchUser(HttpServletRequest request) {
        return null;
    }

    @Async
    public void push(AirConditionerAddTime airBill) throws Exception {

        // 查询有物品审批权限的人
        // 最大角色对应的人员
        // List<User>          users = userManager.findByFunAndRoleAndFloor(CSPPERMISSION, airBill.getFloorId());
        // String              title = "您有一个空调加时需要审核";
        // VirtualArchitecture vir   = virtualArchManager.get(Integer.parseInt(String.valueOf(airBill.getVirtualId())));

        // String content = "申请人姓名：" + airBill.getApplyUser() + "," + "申请企业:" + vir.getName();
        // PushMessageHelper.pushMessage(airBill.getId(), CSPPERMISSION, users, title, content);


        if (airBill.getType() != null && airBill.getRoleId() != null && airBill.getSort() != null) {

            if (airBill.getType().equals(6)) {

                List<User> users = new ArrayList<>();

                users = userManager.findByRoleId(airBill.getRoleId(), airBill.getOrganizationId());
                //		List<User> users = userManager.findByFunction(bill.getOrgId(),CodeConstants.RELEASEAD_PERMISSION);

                String title = "您有一个空调加时需要审核";

                VirtualArchitecture vir = virtualArchManager.get(Integer.parseInt(String.valueOf(airBill.getVirtualId())));

                String sendUrl = appAirApplyDetailUrl.replace("@id", airBill.getId().toString());

                String content = "申请人姓名：" + airBill.getApplyUser() + "," + "申请企业:" + vir.getName();

                PushMessageHelper helper = new PushMessageHelper();
                helper.pushMessage(airBill.getId(), CodeConstants.AIR_SEND_MEG_CODE, sendUrl, users, title, content);
            }
        }

    }

    /**
     * 会议室模块加时申请
     */
	/*@Override
	public AppResultDto meetingApply(AirConditionerAddTimeMeetingInputDto dto,
									 HttpServletRequest request) {

		//MathContext mc=new MathContext(2,RoundingMode.HALF_UP);

		try {
			AirConditionerAddTime repairBill = new AirConditionerAddTime();
			BeanUtils.copyProperties(repairBill, dto);

			repairBill.setCreateTime(new Date());
			repairBill.setModifyTime(new Date());

			DecimalFormat df4 = new DecimalFormat();
			df4.applyPattern("0.00");

			//单价根据 应用模块空调加时+当前日期的 日期类型(工作日\ 休息日\节假日 找到规则中单价
			BigDecimal priceHu   = new BigDecimal(350);//每户
			BigDecimal priceHour = new BigDecimal(0.15);//小时
			//BigDecimal price=new BigDecimal(350);//每户
			String priceDisplay = "每户350元/每小时";
			//String priceDisplay="每平米0.15元/小时";


			//#应用模块 (1预定会议室\2空调加时
			//#获得日期类型 过滤 日期类型(0工作日1休息日2节假日',
			//#匹配时间段 配置的时间内
			//#获得每户\每平米 价格
			Integer dataType = 0;//根据api 获得
			//String currentDateStr=DateUtils.getTime(new Date(),"yyyyMMdd");//换成申请日期的
			String              applyTimeStr = DateUtils.getTime(repairBill.getUseStartTime(), "yyyyMMdd");
			String              jsonStr      = HttpKit.get("http://api.goseek.cn/Tools/holiday?date=" + applyTimeStr, false);
			Map<String, Object> jsApiMap     = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
			if (null != jsApiMap && jsApiMap.containsKey("code")) {
				if (jsApiMap.get("code").equals(10000)) {
					dataType = (Integer) jsApiMap.get("data");
				} else {
					return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,节假日接口调用失败");
				}
			}

			//勾选后非节假日的周六为工作日=================================================2018.10.17
			//如果为 true 如果get为周六且非2节假日 将 dataType设置为0工作日			
			VirtualArchitecture virtual = virtualArchManager.get(dto.getVirtualId().intValue());
			if (null != virtual && virtual.getOrganizationId() != null) {
				repairBill.setOrganizationId(virtual.getOrganizationId());//项目Id 重要参数

				ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
				Integer       satDataType   = projectConfig.getSatDataType();
				if (null != satDataType && satDataType == 1) {///如果为 true
					boolean isSaturday = DateUtils.checkIsSaturday(repairBill.getUseStartTime());
					if (isSaturday && dataType != 2) {//如果get为周六且非2节假日 将 dataType设置为0工作日
						dataType = 0;
					}
				}
			}
			//勾选后非节假日的周六为工作日=================================================2018.10.17


			//提前申请时间校验=================================================2018.10.17
			//获得当前用户对项目Id 找项目规则
			Long   virtualId = dto.getVirtualId();
			String checkStr  = checkBeforeAppApplyTime(repairBill.getUseStartTime(), virtualId);
			if (StringUtils.isNotEmpty(checkStr)) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, checkStr);
			}
			//提前申请时间校验=================================================2018.10.17

			if (null == repairBill.getOrganizationId()) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能获得用户项目信息");
			}


			Integer applicationType    = 1;//应用模块(1预定会议室\2空调加时
			Integer applicationMeeting = 1;
			Date    minDate            = null;
			Date    maxDate            = null;

			List<AirRule> airRules = airRuleManager.getAirRule(repairBill.getOrganizationId(), applicationType, applicationMeeting, dataType, "", "");
			AirRule       airRule  = null;
			if (null == airRules || (null != airRules && airRules.size() == 0)) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
			}
			int airRulesSize = 0;
			for (AirRule ar : airRules) {

				Date ruleStartTime = ar.getStartTime();
				Date ruleEndTime   = ar.getEndTime();
				Map  recodeMap     = DateUtils.getIncludeTime(repairBill.getUseStartTime(), repairBill.getUseEndTime(), ruleStartTime, ruleEndTime);
				if (recodeMap.containsKey("minDate") && recodeMap.containsKey("maxDate")) {
					minDate = (Date) recodeMap.get("minDate");
					maxDate = (Date) recodeMap.get("maxDate");
					airRule = ar;
					++airRulesSize;
				}
			}

			if (airRulesSize == 0) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
			}
			if (airRulesSize > 1) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,匹配多条空调加时规则");
			}

			repairBill.setUseStartTime(minDate);
			repairBill.setUseEndTime(maxDate);
			priceHu = airRule.getPriceHouse();
			priceHour = airRule.getPriceHour();


			BigDecimal UseLengthTime = DateUtils.compareStringTimesToHour(repairBill.getUseStartTime(), repairBill.getUseEndTime());
			UseLengthTime = UseLengthTime.setScale(0, BigDecimal.ROUND_UP);//向上取整
			repairBill.setUseLengthTime(UseLengthTime);//使用时长


			//户数
			//int houseNo=repairBill.getRoomNos().split(";").length;//申请房号IDS(ID;ID)
			int houseNo = 1;//申请房号IDS(ID;ID)
			//面积数
			BigDecimal applyArea = repairBill.getApplyArea();//申请面积

			//2018-6以前按每平米0.15元/每小时，2018-6后入驻按每户350元/每小时
			//查询企业的入驻时间 来算确定 用户还是 每平米算  (
			//Date virEnterDate=new Date();
			Date virEnterDate = virtual.getEnterTime();
			if (null == virEnterDate) {
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,请设置企业入驻时间");
			}
			boolean isCalcHouse = false;//按户计算
			if (virEnterDate.after(DateUtils.getDateByString(enterTime, "yyyy.MM.dd"))) {//精确到天
				isCalcHouse = true;
			}

			BigDecimal calcFee    = BigDecimal.ZERO.setScale(2);
			String     freeDetail = "";//
			if (isCalcHouse) {//按户计算

				//priceDisplay="每户350元/每小时";
				priceDisplay = "每户" + df4.format(priceHu.setScale(2)) + "元/每小时";

				//费用明细：2小时*2户*每户350元/每小时=1400.00元
				calcFee = UseLengthTime.multiply(new BigDecimal(houseNo)).multiply(priceHu).setScale(2, 4);
				freeDetail = UseLengthTime.toPlainString() + "小时*" + houseNo + "户*" + priceDisplay;
				repairBill.setUseAreaOrTime(2);//使用 1面积 2 时间


			} else {//用面积计算
				//priceDisplay="每平米0.15元/小时";
				priceDisplay = "每平米" + df4.format(priceHour.setScale(2)) + "元/小时";

				//费用明细：2小时*2平米*每平米0.15元/小时=1400.00元
				calcFee = UseLengthTime.multiply(applyArea).multiply(priceHour).setScale(2, 4);
				freeDetail = UseLengthTime.toPlainString() + "小时*" + applyArea + "平米*" + priceDisplay;
				repairBill.setUseAreaOrTime(1);//使用 1面积 2 时间
			}

			repairBill.setPriceDisplay(priceDisplay);//单价：每户350元/每小时
			//工作日2018-09-18 07:00~21:00
			//工作日根据时间获取
			String dataTypeStr = "工作日";
			if (dataType == GoodsCodeConstants.DATATYPE_WORKINGDAY) {//工作日
				dataTypeStr = "工作日";
			} else if (dataType == GoodsCodeConstants.DATATYPE_RESTDAY) {//休息日
				dataTypeStr = "休息日";
			} else if (dataType == GoodsCodeConstants.DATATYPE_VACATIONS) {//节假日
				dataTypeStr = "节假日";
			}

			//使用时间(合并显示  10月25日  07:00~21:00(工作日)
			//String UseStartTimeStr=DateUtils.getDate(repairBill.getUseStartTime(), "yyyy-MM-dd HH:mm");
			String UseStartTimeStr = DateUtils.getDate(repairBill.getUseStartTime(), "MM月dd日 HH:mm");
			String useEndTimeStr   = DateUtils.getDate(repairBill.getUseEndTime(), "HH:mm");
			repairBill.setUseDisplayTime(UseStartTimeStr + "~" + useEndTimeStr + "(" + dataTypeStr + ")");

			repairBill.setFreeDetail(freeDetail);//费用明细：2小时*2户*350元=1400.00元
			repairBill.setFreeTotal(calcFee);//费用总计：1400.00元
			repairBill.setMonthlyFree(calcFee);//月结费用：1400.00元

			String code = CodeGenerateUtils.generate("KTJS");
			repairBill.setCode(code);
			repairBill.setStatus(GoodsCodeConstants.AIR_SAVE);//保存
			AirConditionerAddTime bill = conditionerAddTimeManager.save(repairBill);

			return AppResultUtil.createSuccesDto(convert(bill));

		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (Exception e) {
			e.printStackTrace();
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败:" + LogExceptionStackUtil.LogExceptionStack(e));
		}

	}*/

    /**
     * 校验提前申请时间
     * @param useStartTime
     * @param virtualId
     * @return
     */
    private String checkBeforeAppApplyTime(Date useStartTime, Long virtualId) {

        String checkStr = "";
        VirtualArchitecture virtual = virtualArchManager.get(virtualId.intValue());
        if (null != virtual && virtual.getOrganizationId() != null) {
            ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
            BigDecimal beforeApplyTime = projectConfig.getBeforeApplyTime();
            if (null != beforeApplyTime && beforeApplyTime.compareTo(BigDecimal.ZERO) == 1) {//>0

                // 需要格式化
                Date currentDate = new Date();
                String currentDateStr = DateUtils.formatDate(currentDate, "yyyy-MM-dd HH:mm");
                currentDate = DateUtils.getDateByString(currentDateStr, "yyyy-MM-dd HH:mm");
                // 当前时间大于申请的结束使用时间 相差小时数 和项目配的 提前申请时间 比较
                // BigDecimal currentDateBigEndDateHourNo=DateUtils.compareStringTimesToHour(useStartTime, currentDate);
                // currentDateBigEndDateHourNo=currentDateBigEndDateHourNo.abs();//取绝对值

                Date nowDate = DateUtils.addHour(currentDate, beforeApplyTime.intValue(), DateUtils.YYYY_MM_DD_MM_HH_SS);

                if (useStartTime.compareTo(nowDate) != -1) {// useStartTime>=currentDate+beforeApplyTime
                    // return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,需要提前"+beforeApplyTime.doubleValue()+"小时申请");
                } else {
                    checkStr = "空调加时申请失败,需要提前" + beforeApplyTime.doubleValue() + "小时申请";
                }
            }
        }
        return checkStr;
    }


    private String checBeforeCancelTime(Date useStartTime, Long virtualId, Integer billFrom) {
        String checkStr = "";
        VirtualArchitecture virtual = virtualArchManager.get(virtualId.intValue());
        if (null != virtual && virtual.getOrganizationId() != null) {
            ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
            BigDecimal beforeCancelTime = projectConfig.getBeforeCancelTime();
            if (null != beforeCancelTime && beforeCancelTime.compareTo(BigDecimal.ZERO) == 1) {//>0

                // 需要格式化
                Date currentDate = new Date();
                String currentDateStr = DateUtils.formatDate(currentDate, "yyyy-MM-dd HH:mm");
                currentDate = DateUtils.getDateByString(currentDateStr, "yyyy-MM-dd HH:mm");
                // 设置提前取消时间：单位为小时，用于控制空调加时的取消订单操作权限，如设置为2小时，使用时间为9点的订单只能在7点之前取消；

                Date newUseStartTime = DateUtils.addHour(useStartTime, -beforeCancelTime.intValue(), DateUtils.YYYY_MM_DD_MM_HH_SS);
                // useStartTime-beforeCancelTime.intValue()>currentDate
                if (!billFrom.equals(CodeConstants.PC)) {
                    if (newUseStartTime.compareTo(currentDate) == 1) {// currentDateBigEndDateHourNo<beforeApplyTime

                    } else {
                        checkStr = "需提前" + beforeCancelTime.doubleValue() + "小时取消申请";
                    }
                }

            }
        }
        return checkStr;
    }

    @Override
    public Page reportFindPageBy(Map<String, Object> params, int pageSize,
                                 int pageNo) {
        return conditionerAddTimeManager.reportFindPageBy(params, pageSize, pageNo);
    }

    @Override
    public Page reportDetailFindPageBy(Map<String, Object> params,
                                       int pageSize, int pageNo) {
        return conditionerAddTimeManager.reportDetailFindPageBy(params, pageSize, pageNo);
    }

    @Override
    public AppResultDto getIsShowSelectBox(
            AirConditionerAddTimeMeetingInputDto dto, HttpServletRequest request) {


        try {

            Long virtualId = dto.getVirtualId();
            Long virAccountId = dto.getVirAccountId();
            Date useStartTime = dto.getUseStartTime();
            Date useEndTime = dto.getUseEndTime();
            Integer isFree = dto.getIsFree();

            // 会议室是否免费版 1是 0否
            if (null != isFree && 1 == isFree) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "会议室免费,暂不提供申请空调加时");
            }


            if (null != virAccountId) {
                VirtualAccount virtualAccount = virtualAccountManager.get(virAccountId);
                if (null != virtualAccount) {
                    if (virtualAccount.getIsEnable().equals("0")) {
                        return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "该企业账号已被禁用");
                    }
                }
            }

            // 企业结算方式(1现结2月结)
            VirtualArchitecture virtual = virtualArchManager.get(virtualId.intValue());
            if (null != virtual && virtual.getSettleType() == 1) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "该企业结算方式为现结,不能申请空调加时");
            }

            //#应用模块 (1预定会议室\2空调加时
            //#获得日期类型 过滤 日期类型(0工作日1休息日2节假日',
            //#匹配时间段 配置的时间内
            //#获得每户\每平米 价格
            Integer dataType = 0;// 根据api 获得
            // String currentDateStr=DateUtils.getTime(new Date(),"yyyyMMdd");
            String applyTimeStr = DateUtils.getTime(useStartTime, "yyyyMMdd");
            String jsonStr;

            jsonStr = HttpKit.get("http://api.goseek.cn/Tools/holiday?date=" + applyTimeStr, false);
            Map<String, Object> jsApiMap = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
            if (null != jsApiMap && jsApiMap.containsKey("code")) {
                if (jsApiMap.get("code").equals(10000)) {
                    dataType = (Integer) jsApiMap.get("data");
                } else {
                    return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,节假日接口调用失败");
                }
            }

            // 勾选后非节假日的周六为工作日=================================================2018.10.17
            // 如果为 true 如果get为周六且非2节假日 将 dataType设置为0工作日
            if (null != virtual && virtual.getOrganizationId() != null) {
                ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
                Integer satDataType = projectConfig.getSatDataType();
                if (null != satDataType && satDataType == 1) {///如果为 true
                    boolean isSaturday = DateUtils.checkIsSaturday(useStartTime);
                    if (isSaturday && dataType != 2) {// 如果get为周六且非2节假日 将 dataType设置为0工作日
                        dataType = 0;
                    }
                }
            } else {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能获得用户项目信息");
            }
            // 勾选后非节假日的周六为工作日=================================================2018.10.17


            // 提前申请时间校验=================================================2018.10.17
            // 获得当前用户对项目Id 找项目规则
            String checkStr = checkBeforeAppApplyTime(useStartTime, virtualId);
            if (StringUtils.isNotEmpty(checkStr)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, checkStr);
            }
            // 提前申请时间校验=================================================2018.10.17

            // String startTimeStr="07:00";
            // String endTimeStr="08:00";
            String startTimeStr = DateUtils.getDate(useStartTime, "HH:mm");
            String endTimeStr = DateUtils.getDate(useEndTime, "HH:mm");
            Integer applicationType = 1;// 应用模块(1预定会议室\2空调加时
            Integer applicationMeeting = 1;
			/*List<AirRule> airRules=airRuleManager.getAirRule(applicationType,applicationMeeting, dataType, startTimeStr, endTimeStr);
			AirRule airRule=null;
			if(null!=airRules && airRules.size()==1){
				airRule=airRules.get(0);
			}else if(null==airRules || (null!=airRules && airRules.size()==0)){
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则");
			}else if(null!=airRules && airRules.size()>1){
				return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,匹配多条空调加时规则");
			}*/
            List<AirRule> airRules = airRuleManager.getAirRule(virtual.getOrganizationId(), applicationType, applicationMeeting, dataType, "", "");
            AirRule airRule = null;
            if (null == airRules || (null != airRules && airRules.size() == 0)) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }
            int airRulesSize = 0;
            for (AirRule ar : airRules) {

                Date ruleStartTime = ar.getStartTime();
                Date ruleEndTime = ar.getEndTime();
                Map recodeMap = DateUtils.getIncludeTime(useStartTime, useEndTime, ruleStartTime, ruleEndTime);
                if (recodeMap.containsKey("minDate") && recodeMap.containsKey("maxDate")) {
                    Date minDate = (Date) recodeMap.get("minDate");
                    Date maxDate = (Date) recodeMap.get("maxDate");
                    airRule = ar;
                    ++airRulesSize;
                }
            }

            if (airRulesSize == 0) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }
            if (airRulesSize > 1) {
                return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "空调加时申请失败,匹配多条空调加时规则");
            }


            DecimalFormat df4 = new DecimalFormat();
            df4.applyPattern("0.00");
            JSONObject returnMap = new JSONObject();
            returnMap.put("ruleName", airRule.getRuleName());
            returnMap.put("priceHouse", df4.format(airRule.getPriceHouse().setScale(2)));
            returnMap.put("priceHour", df4.format(airRule.getPriceHour().setScale(2)));
            returnMap.put("priceDisplay", airRule.getPriceDisplay());

            return AppResultUtil.createSuccesDto("会议室加时申请查询成功", returnMap);

        } catch (Exception e) {
            e.printStackTrace();
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "会议室加时申请查询失败:" + LogExceptionStackUtil.LogExceptionStack(e));
        }
    }

    @Override
    public void airConditioningOrder() {
        Map map = new HashMap();
        map.put("timeName", "useStartTime");
        map.put("type", "previousState");
        map.put("name", "开启");
        // 开始时间的前10分钟推送
        airConditioningOrder(map);
        ////结束时间的前10分钟推送
        map.put("timeName", "useEndTime");
        map.put("type", "afterState");
        map.put("name", "关闭");
        airConditioningOrder(map);
    }

    public void airConditioningOrder(Map<String, Object> params) {
        List<Map<String, Object>> list = conditionerAddTimeManager.airConditioningOrder(params);
        if (list != null && list.size() > 0) {
            for (Map<String, Object> ma : list) {
                if (ma.get("switchTel") != null && !ma.get("switchTel").equals("")) {

                    String[] useStartTime = ma.get("useStartTime").toString().split("\\.");
                    String[] useEndTime = ma.get("useEndTime").toString().split("\\.");

                    StringBuilder sb = new StringBuilder("你好，你有新的空调" + params.get("name") + "任务，房间号：");
                    sb.append(ma.get("name").toString() + ma.get("roomNames").toString());
                    sb.append("室，" + params.get("name").toString() + "时间：");
                    sb.append(params.get("name").toString().equals("开启") ? useStartTime[0] : useEndTime[0]);
                    sb.append("，请及时" + params.get("name") + "空调。");
                    log.info("ConditionerAddTimeServiceImpl airConditioningOrder ======" + sb.toString());

                    System.out.println(sb.toString());

                    WxMessageConfigVo configVo = smsAuthCodeManager.getWxMessageConfig(Integer.decode(ma.get("organizationId").toString()), CodeConstants.CODE_SWITCH_AIR);
                    log.info("空调审批发短息smsAuthCodeManager. configVo ======>" + JSON.toJSONString(configVo));
                    if (null != configVo) {

                        //【短信签名】你好，你有新的空调{开启}任务，房间号：{深圳测试大厦301、302、402室}，开启时间：{2021-08-26 18:00}，请及时{开启}空调。

                        log.info("空调审批发短息. configVo ======>");
                        // String params=configVo.getBusinessParam();//[DATE],[ROOM]
                        Map<String, String> paramMap = new HashMap<String, String>();
                        paramMap.put("[DATE]", params.get("name").toString().equals("开启") ? useStartTime[0] : useEndTime[0]);
                        paramMap.put("[ROOM]", ma.get("roomNames").toString());
                        paramMap.put("[TASK]", params.get("name").toString());
                        WechatMessageDto msgDto = new WechatMessageDto();
                        msgDto.setOrgId(Integer.decode(ma.get("organizationId").toString()));
                        msgDto.setBusinessCode(configVo.getBusinessCode());
                        msgDto.setMobils(ma.get("switchTel").toString());
                        msgDto.setParamMap(paramMap);
                        msgDto.setSmsType(2);
                        msgDto.setType(configVo.getType());
                        String result = smsAuthCodeManager.smsSendByOrgId(msgDto);
                        log.info("空调审批发短息返回 ======>" + result);
                    } else {
                        smsAuthCodeManager.smsSendByOrgId(ma.get("organizationId").toString(), sb.toString(), ma.get("switchTel").toString(), "", CodeConstants.SMS_AIR_TYPE);
                    }


                    params.put("id", ma.get("id"));
                    conditionerAddTimeManager.updateAirConditioningOrder(params);
                }
            }
        }
    }

    /**
     * 加时单 申请时间大于当前时间  把状态改为已完成
     * 条件:待使用状态
     */
    @Override
    public void airAddTimeDoTimerTask() {
        List<Map<String, Object>> list = conditionerAddTimeManager.findMeeting();
        if (list != null && list.size() > 0) {
            for (Map<String, Object> map : list) {
                conditionerAddTimeManager.airAddTimeDoTimerTask(map.get("id").toString());
                StringBuilder sb = new StringBuilder("你好，您的房间号：");
                sb.append(map.get("name").toString() + map.get("roomNames").toString());
                sb.append("室 于");
                sb.append(map.get("useDisplayTime").toString());
                sb.append("加开空调的订单已服务完成,如有疑问请及时联系物业客！");
                log.info("ConditionerAddTimeServiceImpl airAddTimeDoTimerTask======" + sb.toString());
                System.out.println(sb.toString());
                AirConditionerAddTime bill = conditionerAddTimeManager.get(Long.valueOf(String.valueOf(map.get("id"))).longValue());

                conditionerAddTimeManager.sendCancelWechat(map.get("id").toString(), map.get("creatorBillId").toString(), sb.toString(), bill);
            }
        }


    }

    @Override
    public void airAddTimeAuditOverTimeTask() {
        conditionerAddTimeManager.airAddTimeAuditOverTimeTask();
    }

    @Override
    public AppResultDto meetingCancel(HttpServletRequest request) {

        User user = null;
        user = new User();
        user.setFullName("会议室客户");

        String billId = request.getParameter("billId");
        AirConditionerAddTime bill = conditionerAddTimeManager.get(Long.decode(billId));
        Integer billStatus = bill.getStatus();

        log.info("ConditionerAddTimeServiceImpl meetingCancel billId======" + billId);

		/*//提前取消时间=================================================2018.10.17
        //设置提前取消时间：单位为小时，用于控制空调加时的取消订单操作权限，如设置为2小时，使用时间为9点的订单只能在7点之前取消
		//提前取消时间
		String checkStr=checBeforeCancelTime(bill.getUseStartTime(),bill.getVirtualId());
		if(StringUtils.isNotEmpty(checkStr)){
			return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, checkStr);
		}
		//提前取消时间=================================================2018.10.17*/


        String cancelReason = "取消会议室";


        if (!(billStatus == GoodsCodeConstants.AIR_WAITUSE)) {
            return AppResultUtil.createErrorDto(AppConstants.ERROR_CODE, "待使用状态才可以取消订单");
        }


        bill.setCancelTime(new Date());
        if (null != user && StringUtils.isNotEmpty(user.getFullName())) {
            bill.setCancelUser(user.getFullName());
        } else {
            bill.setCancelUser("");
        }
        bill.setCancelReason(cancelReason);
        bill.setStatus(GoodsCodeConstants.AIR_YETCANCEL);// 取消
        conditionerAddTimeManager.save(bill);

        if (StringUtils.isNotEmpty(bill.getSwitchTel())) {
            String smsContent = "你好,会议室申请的空调加时申请位置：" + bill.getRoomNames() + ",申请使用时间：" + bill.getUseDisplayTime() + "的订单取消了,请知悉";
            smsAuthCodeManager.smsSend(bill.getSwitchTel(), smsContent);
        }
        // 取消发微信消息 可能按企业账号申请的 这里不推送微信消息
        // conditionerAddTimeManager.sendCancelWechat(bill, bill.getCancelReason());

        return AppResultUtil.createSuccesDto(convert(bill));
    }

    @Override
    public AppResultDto selectCompany(AirSelectCompanyInputDto dto, HttpServletRequest request) {

        int organizationId = 10;
        // String companyName=request.getParameter("companyName");
        if (StringUtils.isNotEmpty(dto.getOrganizationId())) {
            organizationId = Integer.valueOf(dto.getOrganizationId());
        }

        if (dto.getBillFrom().equals(CodeConstants.ANDROID) || dto.getBillFrom().equals(CodeConstants.iOS)) {
            String userName = baseRedisService.get(request.getHeader("token"));
            if (userName == null) {
                return AppResultUtil.createErrorDto(AppConstants.TOKEN_EXPIRED, "token已过期");
            }
            User user = userManager.getUserByUsername2(userName);
            if (null != user) {

                // appuser 对应项目ID
                List<AppUserOrgnizationRelation> orgList = userManager.getAppUserOrgByUserId(Integer.parseInt(user.getId().toString()));
                if (orgList != null && orgList.size() > 0) {
                    AppUserOrgnizationRelation orgRe = orgList.get(0);
                    if (orgRe != null) {
                        organizationId = orgRe.getOrgId();
                    }
                }
            }
        }


        List<Map<String, Object>> returnMap = null;

        try {
            returnMap = virtualArchManager.getFloorCompanyAndSettleMonth(organizationId, dto.getCompanyName(), dto.isAir());
        } catch (Exception e) {
            log.info("ConditionerAddTimeServiceImpl selectCompany ======");
            e.printStackTrace();
        }

        return AppResultUtil.createSuccesDto(returnMap);
    }

    /**
     * 空调加时报表导出excel
     */
    @Override
    public AppResultDto exportReportList(Map<String, Object> params) {
        List<Map<String, Object>> list = conditionerAddTimeManager.reportFind(params);
        HSSFWorkbook wb = new HSSFWorkbook();
        String sheetName = "空调加时报表";
        String[] titles = {"企业名称", "订单数", "统计时间", "空调加时费用总计"};
        String[] fieldNames = {"virtualName", "billNo", "applyTime", "freeTotal"};
        try {
            File file = getFile();
            ExcelUtils.exportExcel(file, wb, sheetName, list, titles, fieldNames);
            return AppResultUtil.createSuccesDto(file.getPath());
        } catch (Exception e) {
            log.info("ConditionerAddTimeServiceImpl exportReportList ======");
            e.printStackTrace();
            return AppResultUtil.createErrorDto("100", "导出数据失败");
        }
    }

    public File getFile() throws IOException {
        String classpath = getClass().getResource("/").getPath();
        log.info("begin exportExcel  classpath:" + classpath);
        if (StringUtils.isNotEmpty(classpath)) {
            log.info("begin exportExcel  CLIENTNO:" + CLIENTNO);
            if ("dev".equals(CLIENTNO)) {
                String str = classpath.substring(0, 1);
                if ("/".equals(str)) {
                    classpath = classpath.replaceFirst("/", "");
                }
            }
        }
        log.info("path:" + classpath);
        String webappRoot = classpath.replaceAll("WEB-INF/classes", "");
        log.info("path:" + webappRoot);
        String path = webappRoot + "upload/AirAddTime.xls";
        if (StringUtils.isNotEmpty(path)) {
            path = path.replace("//", "/");
        }

        log.info("path:" + path);
        File file = new File(new ExcelUtils().getPath(path));
        System.out.println("path:" + path);
        return file;
    }


    /**
     * 给客服发app审批消息
     */
    @Async
    public void push(String id) throws Exception {

        log.info("===>推送 push====== start");

        // 查询有物品审批权限的人
        AirConditionerAddTime bill = conditionerAddTimeManager.get(Long.decode(id));

        if (bill.getType() != null && bill.getRoleId() != null && bill.getSort() != null) {

            if (bill.getType().equals(6)) {

                List<User> users = new ArrayList<>();

                users = userManager.findByRoleId(bill.getRoleId(), bill.getOrganizationId());
                //		List<User> users = userManager.findByFunction(bill.getOrgId(),CodeConstants.RELEASEAD_PERMISSION);

                String title = "您有一个空调加时申请单需要审核";

                VirtualArchitecture vir = virtualArchManager.get(Integer.parseInt(String.valueOf(bill.getVirtualId())));

                String content = "申请人姓名：" + bill.getApplyUser() + "," + "申请企业:" + vir.getName();

                String sendUrl = appAirApplyDetailUrl.replace("@id", bill.getId().toString());

                PushMessageHelper helper = new PushMessageHelper();
                helper.pushMessage(bill.getId(), CodeConstants.AIR_SEND_MEG_CODE, sendUrl, users, title, content);
            } else {

                List<WxUser> wxUsers = new ArrayList<>();

                wxUsers = scWxuserManager.getWxUserByPermId(bill.getRoleId(), bill.getVirtualId().intValue(), "");

                for (WxUser wxUser : wxUsers) {
                    log.info("===>推送  conditionerAddTimeManager.sendNextAgreeWechat====== start");
                    conditionerAddTimeManager.sendNextAgreeWechat(bill, wxUser);
                    log.info("===>推送  conditionerAddTimeManager.sendNextAgreeWechat====== end");
                }

            }
        }
    }

    @Override
    public AppResultDto exportDetailList(Map<String, Object> params) {

        // return goodsReleaseManager.reportExcel(params);


        // List<Map<String, Object>> list      = goodsReleaseManager.reportExcel(params);
        Page page = conditionerAddTimeManager.reportDetailFindPageBy(params, 10000, 1);
        List<Map<String, Object>> list = page.getItems();
        HSSFWorkbook wb = new HSSFWorkbook();
        String sheetName = "空调费用明细";
        String[] titles = {"订单来源", "申请房号", "申请面积", "使用时间", "使用时长",
                "单价", "申请人", "订单金额"};
        String[] fieldNames = {"billSourceName", "roomNames", "applyArea", "useDisplayTime", "useLengthTime",
                "priceDisplay", "applyUser", "freeTotal"};
        try {
            File file = getApplyPassManageFile();


            // 汇总数据处理 start
            BigDecimal freeTotal = BigDecimal.ZERO;
            for (Map<String, Object> map : list) {
                System.out.println("===>" + map.get("freeTotal"));
                BigDecimal temp_freeTotal = (BigDecimal) map.get("freeTotal");
                freeTotal = freeTotal.add(temp_freeTotal);
            }


            JSONObject ob = new JSONObject();
            ob.put("virName", "");
            ob.put("roomNo", "");
            VirtualArchitecture virInfo = virtualArchManager.get(Integer.valueOf((String) params.get("virtualId")));
            if (null != virInfo) {
                ob.put("virName", virInfo.getName());
                ob.put("roomNo", virInfo.getRoomNames());
            }

            ob.put("queryDate", params.get("reportTime"));
            ob.put("billNum", page.getTotalCount());
            ob.put("totalFree", freeTotal.setScale(2, 4));

            Map<String, Object> tempMap = new HashMap<String, Object>();
            tempMap.put("freeTotal", "企业名称: " + ob.get("virName"));
            list.add(tempMap);

            tempMap = new HashMap<String, Object>();
            tempMap.put("freeTotal", "房间号: " + ob.get("roomNo"));
            list.add(tempMap);

            tempMap = new HashMap<String, Object>();
            tempMap.put("freeTotal", "时间: " + ob.get("queryDate"));
            list.add(tempMap);

            tempMap = new HashMap<String, Object>();
            tempMap.put("freeTotal", "订单数: " + ob.get("billNum"));
            list.add(tempMap);


            tempMap = new HashMap<String, Object>();
            tempMap.put("freeTotal", "总金额: " + ob.get("totalFree"));
            list.add(tempMap);
            // 汇总数据处理 end


            ExcelUtils.exportExcel(file, wb, sheetName, list, titles, fieldNames, "1");
            return AppResultUtil.createSuccesDto(file.getPath());
        } catch (Exception e) {
            log.info("ConditionerAddTimeServiceImpl exportReportList ======");
            e.printStackTrace();
            return AppResultUtil.createErrorDto("100", "导出数据失败");
        }


    }


    public File getApplyPassManageFile() throws IOException {
        String classpath = getClass().getResource("/").getPath();
        log.info("begin exportExcel  classpath:" + classpath);
        if (StringUtils.isNotEmpty(classpath)) {
            log.info("begin exportExcel  CLIENTNO:" + CLIENTNO);
            if ("dev".equals(CLIENTNO)) {
                String str = classpath.substring(0, 1);
                if ("/".equals(str)) {
                    classpath = classpath.replaceFirst("/", "");
                }
            }
        }
        log.info("path:" + classpath);
        String webappRoot = classpath.replaceAll("WEB-INF/classes", "");
        log.info("path:" + webappRoot);
        String path = webappRoot + "upload/AddTimeDetailList.xls";
        if (StringUtils.isNotEmpty(path)) {
            path = path.replace("//", "/");
        }

        log.info("path:" + path);
        File file = new File(new ExcelUtils().getPath(path));
        System.out.println("path:" + path);
        return file;
    }

    @Override
    public AppResultDto getBusinessData(AirAddTimeBusinessInputDto dto) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("beginDate", dto.getBeginDate());
        params.put("endDate", dto.getEndDate());

        List returnList = new ArrayList<>();

        Map mapAddtime = new HashMap<>();
        List<Map<String, Object>> airAddTimeMap = conditionerAddTimeManager.getAirAddTimeBusinessData(params);
        mapAddtime.put("type", CodeConstants.BusinessState.AIR.type);
        mapAddtime.put("list", airAddTimeMap);
        returnList.add(mapAddtime);


        Map mapGoodsRelease = new HashMap<>();
        List<Map<String, Object>> goodsReleaseMap = conditionerAddTimeManager.getGoodsReleaseBusinessData(params);
        mapGoodsRelease.put("type", CodeConstants.BusinessState.RELEASE.type);
        mapGoodsRelease.put("list", goodsReleaseMap);
        returnList.add(mapGoodsRelease);

        Map mapNotice = new HashMap<>();
        List<Map<String, Object>> noticeMapList = conditionerAddTimeManager.getNoticeBusinessData(params);
        mapNotice.put("type", CodeConstants.BusinessState.NOTICE.type);
        mapNotice.put("list", noticeMapList);
        returnList.add(mapNotice);

        Map mapRrpair = new HashMap<>();
        List<Map<String, Object>> repairMapList = conditionerAddTimeManager.getRepairBusinessData(params);
        mapRrpair.put("type", CodeConstants.BusinessState.REPAIR.type);
        mapRrpair.put("list", repairMapList);
        returnList.add(mapRrpair);

        Map visitorMap = new HashMap<>();
        List<Map<String, Object>> visitorMapList = conditionerAddTimeManager.getVisitorBusinessData(params);
        visitorMap.put("type", CodeConstants.BusinessState.VISITOR.type);
        visitorMap.put("list", visitorMapList);
        returnList.add(visitorMap);

        return AppResultUtil.createSuccesDto(returnList);
    }

    /**
     * 获取空调加时订单下单时 所有可用的房间信息
     * @param orderNo 空调加时订单编号
     * @return 房间信息列表
     */
    @Override
    public List<RoomInfo> getAddTimeOrderHistoryRooms(String orderNo) {
        AirConditionerAddTimeOrderExtend extend = conditionerAddTimeOrderExtendManager.getByOrderNo(orderNo);
        if (extend == null) {
            throw new RuntimeException("空调加时订单不存在");
        }
        String roomIds = extend.getRoomInfos();
        return JSON.parseArray(roomIds, RoomInfo.class);
    }

    @Override
    public ConditionerAddTimeOrderFeeVO calcAddTimeOrderFee(ConditionerAddTimeOrderUpdateParam order) {
        try {
            AirConditionerAddTimeOrderExtend extend = conditionerAddTimeOrderExtendManager.getByOrderNo(order.getOrderNo());
            if (extend == null) {
                throw new RuntimeException("空调加时订单不存在");
            }
            List<RoomInfo> roomInfos = JSON.parseArray(extend.getRoomInfos(), RoomInfo.class);
            if (cn.superdesk.libs.common.util.CollectionUtils.isEmpty(roomInfos)) {
                throw new RuntimeException("空调加时订单可用房间信息不存在");
            }
            Set<Integer> allRoomIds = new HashSet<>();
            for (RoomInfo roomInfo : roomInfos) {
                allRoomIds.add(roomInfo.getId());
            }
            if (!allRoomIds.containsAll(order.getRoomIds())) {
                throw new RuntimeException("参数异常，可用房间信息不存在");
            }
            AirConditionerAddTime airConditionerAddTime = conditionerAddTimeManager.get(order.getOrderId());
            if (airConditionerAddTime == null || !order.getOrderNo().equalsIgnoreCase(airConditionerAddTime.getCode())) {
                log.error("空调加时订单参数异常，订单编号不匹配, orderNo: {}, orderId: {}, entity:{}", order.getOrderNo(), order.getOrderId(), JSON.toJSONString(airRuleManager));
                throw new RuntimeException("空调加时订单id、编号参数异常");
            }

            List<AirRule> airRules = JSON.parseArray(extend.getAirRules(), AirRule.class);
            log.info("空调加时订单计算费用，订单编号：{}，订单id：{}，空调加时规则：{}", order.getOrderNo(), order.getOrderId(), JSON.toJSONString(airRules));

            AirRule airRule = null;
            if (null == airRules || airRules.isEmpty()) {
                throw new RuntimeException("空调加时费用计算失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }

            Date minDate = null;
            Date maxDate = null;
            int airRulesSize = 0;
            for (AirRule ar : airRules) {
                Date ruleStartTime = ar.getStartTime();
                Date ruleEndTime = ar.getEndTime();
                Map<String, Date> recodeMap = DateUtils.getIncludeTime(order.getUseStartTime(), order.getUseEndTime(), ruleStartTime, ruleEndTime);
                if (recodeMap.containsKey("minDate") && recodeMap.containsKey("maxDate")) {
                    minDate = recodeMap.get("minDate");
                    maxDate = recodeMap.get("maxDate");

                    airRule = ar;
                    ++airRulesSize;
                }
            }

            if (airRulesSize == 0) {
                throw new RuntimeException("空调加时费用计算失败,不能匹配到空调加时规则或该时段有免费的空调加时无需申请");
            }
            if (airRulesSize > 1) {
                throw new RuntimeException("空调加时费用计算失败,匹配多条空调加时规则");
            }

            if (minDate == null || maxDate == null) {
                throw new RuntimeException("空调加时费用计算失败,使用时间无法匹配");
            }


            Integer priceType = airRule.getPriceType();

            /*
             *	使用面积
             */
            String applyArea;

            List<Integer> roomIds = order.getRoomIds();

            BigDecimal calcapplyArea = BigDecimal.ZERO;// 按层申请的面积
            Map<Integer, BigDecimal> floorSumAreaMap = new HashMap<>();// 每层楼的合计申请面积
            Map<Integer, Boolean> mapIsHaveFloor = new HashMap<>();// 当前楼层是有-一层起订
            Map<Integer, Boolean> mapIsHalfHaveFloor = new HashMap<>();// 当前楼层是有-半层起订
            // 根据每个房间配置的是 一层还是半层起订 计算有几个一层 有几个半层起订
            // 一层中如果累计有一层了 后继房间号不累加层数或半层数
            for (RoomInfo roomInfo : roomInfos) {

                Integer floorId = roomInfo.getFloorId().intValue();

                BigDecimal area = roomInfo.getArea();
                Integer areaRuleType = roomInfo.getAreaRuleType();
                // 选择的房间不包含当前房间则跳过
                if (!roomIds.contains(roomInfo.getId())) {
                    continue;
                }

                if (floorSumAreaMap.containsKey(floorId)) {
                    BigDecimal temp_area = floorSumAreaMap.get(floorId);
                    floorSumAreaMap.put(floorId, temp_area.add(area));
                } else {
                    floorSumAreaMap.put(floorId, area);
                }

                if (priceType == 2) {
                    FloorInfo floorInfo = floorInfoManager.get(floorId);
                    if (null == floorInfo.getFloorArea()) {
                        log.info("空调加时费用计算失败,楼层面积为空,楼层id:{}", floorId);
                        throw new RuntimeException("请在空调空间数据中配置楼层面积");
                    }
                }
                if (areaRuleType == 4 && !mapIsHaveFloor.containsKey(floorId)) {
                    mapIsHaveFloor.put(floorId, true);
                }
                if (areaRuleType == 2 && !mapIsHalfHaveFloor.containsKey(floorId)) {
                    mapIsHalfHaveFloor.put(floorId, true);
                }
            }
            // 1-实际面积 2-半层起定 3-不可预定 4-一层起订
            int haveFloorNum = 0;// 一层的数量
            int halfHaveFloorNum = 0;// 半层的数量
            applyArea = "";
            StringBuilder current_floorId = new StringBuilder();
            if (priceType == 1) { // 平米每小时
                for (Integer floorId : floorSumAreaMap.keySet()) {
                    current_floorId.append(floorId.toString()).append(";");

                    boolean isHalfHaveFloor = false;// 是否有半层起
                    boolean isHaveFloor = false;// 是否有一层起
                    if (mapIsHalfHaveFloor.containsKey(floorId)) {
                        isHalfHaveFloor = true;
                    }
                    if (mapIsHaveFloor.containsKey(floorId)) {
                        isHaveFloor = true;
                    }

                    BigDecimal sumArea = floorSumAreaMap.get(floorId);// 当层申请合计面积
                    BigDecimal floorSumArea = roomInfoManager.getSumArueByFloorId(floorId);// 整层合计面积
                    if (null == floorSumArea) {
                        floorSumArea = BigDecimal.ZERO;
                    }
                    BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                    if (isHaveFloor) {
                        calcapplyArea = calcapplyArea.add(floorSumArea);
                    } else if (isHalfHaveFloor) {
                        if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                            calcapplyArea = calcapplyArea.add(halfFloorSumArea);
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            calcapplyArea = calcapplyArea.add(floorSumArea);
                        }
                    } else {// 只有实际
                        calcapplyArea = calcapplyArea.add(sumArea);
                    }

                }
                applyArea = calcapplyArea + "m²";
            } else if (priceType == 2) { // 层（半层）每小时
                for (Integer floorId : floorSumAreaMap.keySet()) {
                    current_floorId.append(floorId.toString()).append(";");

                    boolean isHalfHaveFloor = false;// 是否有半层起
                    boolean isHaveFloor = false;// 是否有一层起
                    if (mapIsHalfHaveFloor.containsKey(floorId)) {
                        isHalfHaveFloor = true;
                    }
                    if (mapIsHaveFloor.containsKey(floorId)) {
                        isHaveFloor = true;
                    }
                    BigDecimal sumArea = floorSumAreaMap.get(floorId);// 当层申请合计面积
                    FloorInfo floorInfo = floorInfoManager.get(floorId);
                    BigDecimal floorSumArea = floorInfo.getFloorArea();
                    BigDecimal halfFloorSumArea = floorSumArea.divide(BigDecimal.valueOf(2)).setScale(2, 4);// 半层面积

                    if (isHaveFloor) {
                        haveFloorNum = haveFloorNum + 1;// 一层的加1
                    } else if (isHalfHaveFloor) {
                        if (sumArea.compareTo(halfFloorSumArea) <= 0) {// 不足半层按半层算
                            halfHaveFloorNum = halfHaveFloorNum + 1;
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            haveFloorNum = haveFloorNum + 1;// 一层的加1
                        }
                    } else { // 按面积算
                        if (sumArea.compareTo(halfFloorSumArea) <= 0) { // 不足半层按半层算
                            halfHaveFloorNum = halfHaveFloorNum + 1;
                        } else if (sumArea.compareTo(floorSumArea) <= 0) {// 不足整层按整层算
                            haveFloorNum = haveFloorNum + 1;// 一层的加1
                        }
                    }

                }
                if (haveFloorNum > 0) {
                    applyArea = "层*" + haveFloorNum;
                }
                if (StringUtils.isNotEmpty(applyArea) && halfHaveFloorNum > 0) {
                    applyArea = applyArea + "," + "半层*" + halfHaveFloorNum;
                } else if (halfHaveFloorNum > 0) {
                    applyArea = "半层*" + halfHaveFloorNum;
                }
            }

            /*
             * 使用时长
             * 空调加时最低申请半小时,不到半小时按半小时收取费用
             */
            BigDecimal useLengthTime = DateUtils.calculateUsageDuration(airConditionerAddTime.getUseStartTime(), airConditionerAddTime.getUseEndTime());

            airConditionerAddTime.setUseLengthTime(useLengthTime);

            /*
             *	价格
             */
            String priceDisplay = null;
            BigDecimal priceHour = airRule.getPriceHour();// 每小时单价
            BigDecimal priceHouse = airRule.getPriceHouse();// 每户价格
            BigDecimal floorPriceHour = airRule.getFloorPriceHour();// 整层/小时价格
            BigDecimal halfFloorPriceHour = airRule.getHalfFloorPriceHour();// 半层/小时价格
            DecimalFormat df4 = new DecimalFormat();
            df4.applyPattern("0.00");

            BigDecimal calcFee = BigDecimal.ZERO.setScale(2, RoundingMode.UNNECESSARY);// 费用
            String freeDetail = "";// 费用明细

            if (priceType == 1) {

                String calc_applyArea = applyArea.replace("m²", "");

                // priceDisplay="每平米0.15元/小时";
                priceDisplay = "每平米" + df4.format(priceHour.setScale(2)) + "元/小时";


                // 费用明细：2小时*2平米*每平米0.15元/小时=1400.00元
                calcFee = useLengthTime.multiply(new BigDecimal(calc_applyArea)).multiply(priceHour).setScale(2, 4);
                freeDetail = useLengthTime.toPlainString() + "小时*" + calc_applyArea + "平米*" + priceDisplay;
                airConditionerAddTime.setUseAreaOrTime(1);// 使用 1面积 2 时间
            } else if (priceType == 2) {

                // 每层300元/小时、每半层200元/小时
                priceDisplay = "每层" + df4.format(floorPriceHour.setScale(2)) + "元/小时、" + "每半层" + df4.format(halfFloorPriceHour.setScale(2)) + "元/小时";

                // 1小时*1层*每层300元/小时-1小时*半层*每半层200元/小时
                // haveFloorNum 多少一层
                if (haveFloorNum > 0) {
                    calcFee = useLengthTime.multiply(BigDecimal.valueOf(haveFloorNum)).multiply(floorPriceHour).setScale(2, 4);
                    // 1小时*1层*每层300元/小时
                    freeDetail = useLengthTime.toPlainString() + "小时*" + haveFloorNum + "层*每层" + floorPriceHour + "元/小时";
                }
                if (halfHaveFloorNum > 0) {
                    calcFee = calcFee.add(useLengthTime.multiply(BigDecimal.valueOf(halfHaveFloorNum)).multiply(halfFloorPriceHour).setScale(2, 4));

                    if (StringUtils.isNotBlank(freeDetail)) {
                        // 1小时*半层*每半层200元/小时
                        freeDetail = freeDetail + "," + useLengthTime.toPlainString() + "小时*" + "半层*" + halfHaveFloorNum + "*每半层" + halfFloorPriceHour + "元/小时";
                    } else {
                        freeDetail = useLengthTime.toPlainString() + "小时*" + "半层*" + halfHaveFloorNum + "*每半层" + halfFloorPriceHour + "元/小时";
                    }
                }

            }

            Integer dataType = 0;// 根据api 获得
            // String currentDateStr=DateUtils.getTime(new Date(),"yyyyMMdd");//换成申请日期的
            String applyTimeStr = DateUtils.getTime(airConditionerAddTime.getUseStartTime(), "yyyy-MM-dd");

            String jsonStr = HttpKit.holidayGet("https://timor.tech/api/holiday/info/" + applyTimeStr, false);
            System.out.println("节假日接口调用返回===>" + jsonStr);
            Map<String, Object> jsApiMap = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
            if (null != jsApiMap && jsApiMap.containsKey("code")) {
                if (jsApiMap.get("code").equals(0)) {
                    // dataType = (Integer) jsApiMap.get("type");
                    Map<String, Object> jsApiMapType = (Map) jsApiMap.get("type");
                    if (jsApiMapType.containsKey("type")) {
                        dataType = (Integer) jsApiMapType.get("type");
                        if (dataType == 3) {
                            // 0, 1, 2, 3- 节假日类型，分别表示 工作日、周末、节日、调休 调休改为工作日
                            dataType = 0;
                        }
                    }
                } else {
                    throw new RuntimeException("空调加时订单请求失败,节假日API异常");
                }
            }

            // 勾选后非节假日的周六为工作日=================================================2018.10.17
            // 如果为 true 如果get为周六且非2节假日 将 dataType设置为0工作日
            boolean isSaturday = DateUtils.checkIsSaturday(airConditionerAddTime.getUseStartTime());
            if (isSaturday) {
                dataType = 1;
            }

            VirtualArchitecture virtual = virtualArchManager.get(airConditionerAddTime.getVirtualId().intValue());
            if (null != virtual && virtual.getOrganizationId() != null) {
                ProjectConfig projectConfig = projectConfigManager.getProjectConfigByOrganizationId(Long.valueOf(virtual.getOrganizationId()));
                if (null == projectConfig) {
                    throw new RuntimeException("空调部分项目配置为空,请系统管理员");
                }
                Integer satDataType = projectConfig.getSatDataType();
                if (null != satDataType && satDataType == 1) {///如果为 true
                    if (isSaturday && dataType != 2) {// 如果get为周六且非2节假日 将 dataType设置为0工作日
                        dataType = 0;
                    }
                }
            }
            String dataTypeStr = "工作日";
            if (dataType == GoodsCodeConstants.DATATYPE_WORKINGDAY) {// 工作日
                dataTypeStr = "工作日";
            } else if (dataType == GoodsCodeConstants.DATATYPE_RESTDAY) {// 休息日
                dataTypeStr = "休息日";
            } else if (dataType == GoodsCodeConstants.DATATYPE_VACATIONS) {// 节假日
                dataTypeStr = "节假日";
            }

            // 使用时间(合并显示  工作日2018-09-18 07:00~21:00
            // 使用时间(合并显示  10月25日  07:00~21:00(工作日)
            // String UseStartTimeStr=DateUtils.getDate(repairBill.getUseStartTime(), "yyyy-MM-dd HH:mm");
            String UseStartTimeStr = DateUtils.getDate(minDate, "MM月dd日 HH:mm");
            String useEndTimeStr = DateUtils.getDate(maxDate, "HH:mm");


            return ConditionerAddTimeOrderFeeVO.builder()
                    .priceDisplay(priceDisplay)// 单价
                    .useLengthTime(useLengthTime)// 使用时长
                    .feeDetail(freeDetail)// 费用明细
                    .feeTotal(calcFee)// 费用总计
                    .monthlyFee(calcFee)// 月结费用
                    .applyArea(applyArea)// 申请面积
                    .useDisplayTime(UseStartTimeStr + "~" + useEndTimeStr + "(" + dataTypeStr + ")")// 使用时间段
                    .roomInfos(roomInfos)// 房间信息
                    .build();
        } catch (Exception e) {
            log.error("计算空调加时费用异常", e);
            throw new RuntimeException("计算空调加时费用异常");
        }
    }

    /**
     * 更新空调加时订单
     * @param order 订单参数
     * @param user  用户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddTimeOrder(ConditionerAddTimeOrderUpdateParam order, User user) {
        AirConditionerAddTime airConditionerAddTime = conditionerAddTimeManager.get(order.getOrderId());
        if (airConditionerAddTime == null || !airConditionerAddTime.getCode().equalsIgnoreCase(order.getOrderNo())) {
            throw new RuntimeException("订单不存在");
        }
        if (airConditionerAddTime.getModificationDisabled() != 0) {
            throw new RuntimeException("订单不允许修改");
        }
        log.info("更新前订单信息:{}", JSON.toJSONString(airConditionerAddTime));
        String history = JSON.toJSONString(airConditionerAddTime);

        ConditionerAddTimeOrderFeeVO conditionerAddTimeOrderFeeVO = calcAddTimeOrderFee(order);
        log.info("计算空调加时修改订单费用:{}", JSON.toJSONString(conditionerAddTimeOrderFeeVO));

        // 更新前

        /**
         * 更新订单信息
         */
        StringBuilder roomNos = new StringBuilder();
        for (Integer roomId : order.getRoomIds()) {
            roomNos.append(roomId).append(";");
        }
        List<RoomInfo> roomInfos = conditionerAddTimeOrderFeeVO.getRoomInfos();
        Map<Integer, RoomInfo> map = new HashMap<>();
        for (RoomInfo roomInfo : roomInfos) {
            map.put(roomInfo.getId(), roomInfo);
        }
        StringBuilder roomNames = new StringBuilder();
        HashSet<Integer> floorSet = new HashSet<>();
        for (Integer roomId : order.getRoomIds()) {
            roomNames.append(map.get(roomId).getName()).append(";");
            floorSet.add(map.get(roomId).getFloorId().intValue());
        }

        StringBuilder floorIds = new StringBuilder();
        for (Integer floorId : floorSet) {
            floorIds.append(floorId).append(";");
        }


        airConditionerAddTime.setRoomNos(roomNos.substring(0, roomNos.length() - 1));// 申请房间id
        airConditionerAddTime.setRoomNames(roomNames.substring(0, roomNames.length() - 1));// 申请房间名称
        airConditionerAddTime.setApplyArea(conditionerAddTimeOrderFeeVO.getApplyArea());// 申请面积
        airConditionerAddTime.setUseLengthTime(conditionerAddTimeOrderFeeVO.getUseLengthTime()); // 使用时长
        airConditionerAddTime.setUseStartTime(order.getUseStartTime());// 使用开始时间
        airConditionerAddTime.setUseEndTime(order.getUseEndTime());// 使用结束时间
        airConditionerAddTime.setUseDisplayTime(conditionerAddTimeOrderFeeVO.getUseDisplayTime());// 使用时间段
        airConditionerAddTime.setPriceDisplay(conditionerAddTimeOrderFeeVO.getPriceDisplay());// 单价
        airConditionerAddTime.setFreeDetail(conditionerAddTimeOrderFeeVO.getFeeDetail());// 费用明细
        airConditionerAddTime.setFreeTotal(conditionerAddTimeOrderFeeVO.getFeeTotal());// 费用总计
        airConditionerAddTime.setMonthlyFree(conditionerAddTimeOrderFeeVO.getMonthlyFee());// 月结费用
        airConditionerAddTime.setModifier(user.getFullName());// 修改人
        airConditionerAddTime.setModifyTime(new Date());// 修改时间
        airConditionerAddTime.setFloorId(floorIds.substring(0, floorIds.length() - 1));// 楼层id
        airConditionerAddTime.setModificationDisabled(order.getModificationDisabled());// 是否关闭修改功能

        // 保存修改记录
        conditionerAddTimeOrderExtendManager.saveHistory(
                AirConditionerAddTimeOrderHistory.builder()
                        .orderNo(airConditionerAddTime.getCode())// 订单号
                        .beforeUpdate(history)// 更新前
                        .afterUpdate(JSON.toJSONString(airConditionerAddTime)) // 更新后
                        .createTime(new Date())
                        .createUser(user.getFullName())
                        .remark(order.getRemark())// 备注
                        .modificationDisabled(order.getModificationDisabled()) // 是否关闭修改功能
                        .build()
        );

        // 更新原订单
        conditionerAddTimeManager.updateModel(airConditionerAddTime);
        log.info("空调加时订单更新后信息:{}", JSON.toJSONString(airConditionerAddTime));
    }

    /**
     * 空调加时订单WEB端需要展示修改历史记录
     * @param dto
     * @return
     */
    @Override
    public AirConditionerAddTimeOutWebVO assembleOrderHistory(AirConditionerAddTimeOutDto dto) {
        String code = dto.getCode();// 订单号
        List<AirConditionerAddTimeOrderHistory> list = conditionerAddTimeOrderExtendManager.getHistoryListByOrderNo(code);

        List<AirConditionerAddTimeHistoryVO> history = new ArrayList<>();

        if (list != null && !list.isEmpty()) {
            for (AirConditionerAddTimeOrderHistory airConditionerAddTimeOrderHistory : list) {
                history.add(
                        AirConditionerAddTimeHistoryVO.builder()
                                .createUser(airConditionerAddTimeOrderHistory.getCreateUser())
                                .createTime(DateUtils.getDate(airConditionerAddTimeOrderHistory.getCreateTime(), "yyyy-MM-dd HH:mm:ss"))
                                .remark(airConditionerAddTimeOrderHistory.getRemark())
                                .modificationDisabled(airConditionerAddTimeOrderHistory.getModificationDisabled())
                                .beforeUpdate(JSON.parseObject(airConditionerAddTimeOrderHistory.getBeforeUpdate(), AirConditionerAddTimeHistoryRecord.class))
                                .afterUpdate(JSON.parseObject(airConditionerAddTimeOrderHistory.getAfterUpdate(), AirConditionerAddTimeHistoryRecord.class))
                                .build()
                );
            }
        }

        return AirConditionerAddTimeOutWebVO.builder()
                .dto(dto)
                .historyList(history)
                .build();
    }

}
