package com.zfire.mall.manager.controller.engin.order;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.PoySaleCountBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderListBean;
import com.zfire.mall.manager.bean.valid.HomeOrderGroup;
import com.zfire.mall.manager.bean.valid.TradeOrderGroup;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.constant.SysDictConstant;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.enums.OrderTypeEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.helper.ResponseHelper;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.engin.order.EnginOrderLogic;
import com.zfire.mall.manager.logic.engin.order.EnginSysLogic;
import com.zfire.mall.manager.plus.entity.EnginOrder;
import com.zfire.mall.manager.utils.excel.ExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.groups.Default;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

@Slf4j
@RestController
@Api(value = "工程订单管理", tags ={"工程订单管理"} )
@RequestMapping(value = "/engin-order", produces = "application/json; charset=utf-8")
public class EnginOrderController {

    @Resource
    EnginOrderLogic enginOrderLogic;
    @Resource
    RedisLockRegistry redisLockRegistry;
    @Resource
    EnginSysLogic enginSysLogic;
    @Resource
    CommonLogic commonLogic;


    @ApiOperation(value = "工程订单列表")
    @GetMapping("/list")
    public ResponseHelper<IPage<EnginOrderListBean>> list(
            @ApiParam(value = "客户编码/客户名称") @RequestParam(required = false) String customerKeyword,
            @ApiParam(value = "工程订单编号") @RequestParam(required = false) List<String> enginOrderNo,
            @ApiParam(value = "工程订单类型") @RequestParam(defaultValue = "HOME") String enginOrderType,
            @ApiParam(value = "工程编号") @RequestParam(required = false) String refProjectNo,
            @ApiParam(value = "登录单号") @RequestParam(required = false) String refEnginRecordNo,
            @ApiParam(value = "项目类别") @RequestParam(required = false) String refProjectCategory,
            @ApiParam(value = "项目名称") @RequestParam(required = false) String refProjectName,
            @ApiParam(value = "使用单位") @RequestParam(required = false) String refUseUnit,
            @ApiParam(value = "行业类别") @RequestParam(required = false) String refTradeCategory,
            @ApiParam(value = "创建日期-开始") @RequestParam(required = false) String startCreateTime,
            @ApiParam(value = "创建日期-结束") @RequestParam(required = false) String endCreateTime,
            @ApiParam(value = "订单日期-开始") @RequestParam(required = false) String startOrderTime,
            @ApiParam(value = "订单日期-结束") @RequestParam(required = false) String endOrderTime,
            @ApiParam(value = "销售类型") @RequestParam(required = false) String saleTypeId,
            @ApiParam(value = "创建人") @RequestParam(required = false) String createName,
            @ApiParam(value = "审核人") @RequestParam(required = false) String confirmName,
            @ApiParam(value = "状态") @RequestParam(required = false) List<String> examineStatus,
            @ApiParam(value = "业务员") @RequestParam(required = false) String serviceId,
            @ApiParam(value = "物料编码") @RequestParam(required = false) String materialNumber,
            @ApiParam(value = "物料名称") @RequestParam(required = false) String materialName,
            @ApiParam(value = "产品编码") @RequestParam(required = false) String materialOldNumber,
            @ApiParam(value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(value = "区域") @RequestParam(required = false) String refRegionWork,
            @ApiParam(value = "备注") @RequestParam(required = false) String remark,
            @ApiParam(value = "格力内部备注") @RequestParam(required = false) String geLiInerNote,
            @ApiParam(value = "跨区厂编号") @RequestParam(required = false) String refFactoryNo,
            @ApiParam(value = "购买单位名称") @RequestParam(required = false) String refBuyUnitName,
            @ApiParam(value = "保证函") @RequestParam(required = false) String refPromiseProvide,
            @ApiParam(value = "是否直调") @RequestParam(required = false) Boolean isDirectTransfer,
            @ApiParam(value = "钱包",required = false) @RequestParam(required = false) String customerWalletId,
            @ApiParam(value = "页号",required = true)@RequestParam Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam Integer pageSize
    ) throws Exception {
        IPage<EnginOrderListBean> listPage = enginOrderLogic.listPage(customerWalletId,customerKeyword, enginOrderNo, enginOrderType, refProjectNo,
                refEnginRecordNo, refProjectCategory, refProjectName, refUseUnit, refTradeCategory, startCreateTime, endCreateTime,
                startOrderTime,endOrderTime,
                saleTypeId, createName, confirmName, examineStatus, serviceId, specification, materialNumber, materialName,
                materialOldNumber, refRegionWork, remark, geLiInerNote, refFactoryNo, refBuyUnitName, refPromiseProvide,
                isDirectTransfer, pageNum, pageSize);
        return ResponseHelper.success(listPage);
    }

    @ApiOperation(value = "工程订单列表统计")
    @GetMapping("/count-list")
    public ResponseHelper<IPage<EnginOrderListBean>> countList(
            @ApiParam(value = "客户编码/客户名称") @RequestParam(required = false) String customerKeyword,
            @ApiParam(value = "工程订单编号") @RequestParam(required = false) List<String> enginOrderNo,
            @ApiParam(value = "工程订单类型") @RequestParam(defaultValue = "HOME") String enginOrderType,
            @ApiParam(value = "工程编号") @RequestParam(required = false) String refProjectNo,
            @ApiParam(value = "登录单号") @RequestParam(required = false) String refEnginRecordNo,
            @ApiParam(value = "项目类别") @RequestParam(required = false) String refProjectCategory,
            @ApiParam(value = "项目名称") @RequestParam(required = false) String refProjectName,
            @ApiParam(value = "使用单位") @RequestParam(required = false) String refUseUnit,
            @ApiParam(value = "行业类别") @RequestParam(required = false) String refTradeCategory,
            @ApiParam(value = "创建日期-开始") @RequestParam(required = false) String startCreateTime,
            @ApiParam(value = "创建日期-结束") @RequestParam(required = false) String endCreateTime,
            @ApiParam(value = "订单日期-开始") @RequestParam(required = false) String startOrderTime,
            @ApiParam(value = "订单日期-结束") @RequestParam(required = false) String endOrderTime,
            @ApiParam(value = "销售类型") @RequestParam(required = false) String saleTypeId,
            @ApiParam(value = "创建人") @RequestParam(required = false) String createName,
            @ApiParam(value = "审核人") @RequestParam(required = false) String confirmName,
            @ApiParam(value = "状态") @RequestParam(required = false) List<String> examineStatus,
            @ApiParam(value = "业务员") @RequestParam(required = false) String serviceId,
            @ApiParam(value = "物料编码") @RequestParam(required = false) String materialNumber,
            @ApiParam(value = "物料名称") @RequestParam(required = false) String materialName,
            @ApiParam(value = "产品编码") @RequestParam(required = false) String materialOldNumber,
            @ApiParam(value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(value = "区域") @RequestParam(required = false) String refRegionWork,
            @ApiParam(value = "备注") @RequestParam(required = false) String remark,
            @ApiParam(value = "格力内部备注") @RequestParam(required = false) String geLiInerNote,
            @ApiParam(value = "跨区厂编号") @RequestParam(required = false) String refFactoryNo,
            @ApiParam(value = "购买单位名称") @RequestParam(required = false) String refBuyUnitName,
            @ApiParam(value = "保证函") @RequestParam(required = false) String refPromiseProvide,
            @ApiParam(value = "是否直调") @RequestParam(required = false) Boolean isDirectTransfer,
            @ApiParam(value = "钱包",required = false) @RequestParam(required = false) String customerWalletId
    ) throws Exception {
        PoySaleCountBean bean = enginOrderLogic.countList(customerWalletId,customerKeyword, enginOrderNo, enginOrderType, refProjectNo,
                refEnginRecordNo, refProjectCategory, refProjectName, refUseUnit, refTradeCategory, startCreateTime, endCreateTime,
                startOrderTime,endOrderTime,
                saleTypeId, createName, confirmName, examineStatus, serviceId, specification, materialNumber, materialName,
                materialOldNumber, refRegionWork, remark, geLiInerNote, refFactoryNo, refBuyUnitName, refPromiseProvide,
                isDirectTransfer);
        return ResponseHelper.success(bean);
    }

    @ApiOperation(value = "工程订单列表统计")
    @GetMapping("/listCount")
    public ResponseHelper<PoySaleCountBean> listCount(
            @ApiParam(value = "客户编码/客户名称") @RequestParam(required = false) String customerKeyword,
            @ApiParam(value = "工程订单编号") @RequestParam(required = false) List<String> enginOrderNo,
            @ApiParam(value = "工程订单类型") @RequestParam(defaultValue = "HOME") String enginOrderType,
            @ApiParam(value = "登录单号") @RequestParam(required = false) String refEnginRecordNo,
            @ApiParam(value = "项目名称") @RequestParam(required = false) String refProjectName,
            @ApiParam(value = "使用单位") @RequestParam(required = false) String refUseUnit,
            @ApiParam(value = "创建日期-开始") @RequestParam(required = false) String startCreateTime,
            @ApiParam(value = "创建日期-结束") @RequestParam(required = false) String endCreateTime,
            @ApiParam(value = "销售类型") @RequestParam(required = false) String saleTypeId,
            @ApiParam(value = "创建人") @RequestParam(required = false) String createName,
            @ApiParam(value = "审核人") @RequestParam(required = false) String confirmName,
            @ApiParam(value = "状态") @RequestParam(required = false) List<String> examineStatus,
            @ApiParam(value = "业务员") @RequestParam(required = false) String serviceId

    ) throws Exception {
        PoySaleCountBean bean = enginOrderLogic.listCount(customerKeyword, enginOrderNo, enginOrderType,
                refEnginRecordNo, refProjectName, refUseUnit, startCreateTime, endCreateTime,
                saleTypeId, createName, confirmName, examineStatus, serviceId);
        return ResponseHelper.success(bean);
    }


    @ApiOperation(value = "工程订单详情")
    @GetMapping("/detail")
    public ResponseHelper<EnginOrderBean> detail(
            @ApiParam(value = "工程订单id") @RequestParam(required = false) String id
    ) throws Exception {
        EnginOrderBean enginOrderBean = enginOrderLogic.detail(id);
        return ResponseHelper.success(enginOrderBean);
    }

    @ApiOperation(value = "家用工程订单单据日期修改")
    @PostMapping("/home-upd-date")
    public ResponseHelper homeUpdDate(
            @ApiParam(required = true, value = "工程订单")
            @RequestBody EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.HOME.getKey());
                enginOrderLogic.updExamineAfterOrder(enginOrderBean);
                return ResponseHelper.success();
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("更改日期失败");
    }

    @ApiOperation(value = "商用工程订单单据日期修改")
    @PostMapping("/trade-upd-date")
    public ResponseHelper tradeUpdDate(
            @ApiParam(required = true, value = "工程订单")
            @RequestBody EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.TRADE.getKey());
                enginOrderLogic.updExamineAfterOrder(enginOrderBean);
                return ResponseHelper.success();
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("更改日期失败");
    }

    @ApiOperation(value = "家用工程订单单据备注")
    @PostMapping("/home-upd-note")
    public ResponseHelper homeUpdNote(
            @ApiParam(required = true, value = "工程订单")
            @RequestBody EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.HOME.getKey());
                enginOrderLogic.updExamineAfterOrder(enginOrderBean);
                return ResponseHelper.success();
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("更改日期失败");
    }

    @ApiOperation(value = "商用工程订单单据备注")
    @PostMapping("/trade-upd-note")
    public ResponseHelper tradeUpdNote(
            @ApiParam(required = true, value = "工程订单")
            @RequestBody EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.TRADE.getKey());
                enginOrderLogic.updExamineAfterOrder(enginOrderBean);
                return ResponseHelper.success();
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("更改日期失败");
    }

    @ApiOperation(value = "新增家用工程订单")
    @PostMapping("/home-add")
    public ResponseHelper homeAdd(
            @ApiParam(required = true, value = "家用工程订单")
            @RequestBody
            @Validated(value = { HomeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.HOME.getKey());
                String id = enginOrderLogic.homeAdd(enginOrderBean, "");
                return ResponseHelper.success(id);
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("新增失败");
    }

    @ApiOperation(value = "新增商用工程订单")
    @PostMapping("/trade-add")
    public ResponseHelper tradeAdd(
            @ApiParam(required = true, value = "商用工程订单")
            @RequestBody
            @Validated(value = { TradeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderBean.setEnginOrderType(OrderTypeEnum.TRADE.getKey());
                String id = enginOrderLogic.tradeAdd(enginOrderBean, SysDictConstant.SUBMIT);
                return ResponseHelper.success(id);
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.error("新增失败");
    }

    @ApiOperation(value = "编辑家用工程订单")
    @PostMapping("/home-edit")
    public ResponseHelper homeEdit(
            @ApiParam(required = true, value = "家用工程订单")
            @RequestBody
            @Validated(value = { HomeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        return getResponseHelper(enginOrderBean, OrderTypeEnum.HOME.getKey(), "");
    }

    @ApiOperation(value = "编辑商用工程订单")
    @PostMapping("/trade-edit")
    public ResponseHelper tradeEdit(
            @ApiParam(required = true, value = "商用工程订单")
            @RequestBody
            @Validated EnginOrderBean enginOrderBean
    ) throws Exception {
        return getResponseHelper(enginOrderBean, OrderTypeEnum.TRADE.getKey(), "");
    }

    @ApiOperation(value = "提交家用工程订单")
    @PostMapping("/home-submit")
    public ResponseHelper homeSubmit(
            @ApiParam(required = true, value = "家用工程订单") @RequestBody @Validated(value = { HomeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        return getResponseHelper(enginOrderBean, OrderTypeEnum.HOME.getKey(), SysDictConstant.SUBMIT);
    }

    @ApiOperation(value = "提交商用工程订单")
    @PostMapping("/trade-submit")
    public ResponseHelper tradeSubmit(
            @ApiParam(required = true, value = "商用工程订单") @RequestBody @Validated(value = { TradeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        return getResponseHelper(enginOrderBean,  OrderTypeEnum.TRADE.getKey(), SysDictConstant.SUBMIT);
    }

    @ApiOperation(value = "提交家用工程订单-列表")
    @PostMapping("/home-submit-on-list")
    public ResponseHelper homeSubmitOnList(
            @ApiParam(required = true, value = "家用工程订单") @RequestParam String id
    ) throws Exception {
        EnginOrderBean detail = enginOrderLogic.detail(id);
        return getResponseHelper(detail, OrderTypeEnum.HOME.getKey(), SysDictConstant.SUBMIT);
    }

    @ApiOperation(value = "提交商用工程订单-列表")
    @PostMapping("/trade-submit-on-list")
    public ResponseHelper tradeSubmitOnList(
            @ApiParam(required = true, value = "商用工程订单") @RequestParam String id
    ) throws Exception {
        EnginOrderBean detail = this.enginOrderLogic.detail(id);
        return getResponseHelper(detail,  OrderTypeEnum.TRADE.getKey(), SysDictConstant.SUBMIT);
    }

    @ApiOperation(value = "审批家用工程订单")
    @PostMapping("/home-examine")
    public ResponseHelper homeExamine(
            @ApiParam(required = true, value = "家用工程订单") @RequestBody @Validated(value = { HomeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        return getResponseHelper(enginOrderBean, OrderTypeEnum.HOME.getKey(), SysDictConstant.EXAMINE);
    }

    @ApiOperation(value = "审批商用工程订单")
    @PostMapping("/trade-examine")
    public ResponseHelper tradeExamine(
            @ApiParam(required = true, value = "商用工程订单") @RequestBody @Validated(value = { TradeOrderGroup.class, Default.class }) EnginOrderBean enginOrderBean
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        return getResponseHelper(enginOrderBean, OrderTypeEnum.TRADE.getKey(), SysDictConstant.EXAMINE);
    }

    @ApiOperation(value = "撤回家用工程订单")
    @PostMapping("/home-revoke")
    public ResponseHelper homeRevoke(
            @ApiParam(required = true, value = "家用工程订单id") @RequestParam String id,
            @ApiParam(required = true, value = "工程登录编号") @RequestParam String refEnginRecordNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {

            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.revokeHome(id, refEnginRecordNo, OrderTypeEnum.HOME.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "撤回商用工程订单")
    @PostMapping("/trade-revoke")
    public ResponseHelper tradeRevoke(
            @ApiParam(required = true, value = "商用工程订单id") @RequestParam String id,
            @ApiParam(required = true, value = "工程登录编号") @RequestParam String refEnginRecordNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {

            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.revokeTrade(id, refEnginRecordNo, OrderTypeEnum.TRADE.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "删除家用工程订单")
    @PostMapping("/home-del")
    public ResponseHelper homeDel(
            @ApiParam(required = true, value = "家用工程订单id") @RequestParam List<String> ids
    ) throws Exception {
        List<String> collect = ids.stream().distinct().collect(Collectors.toList());
        for (String id : collect) {
            EnginOrder order = enginOrderLogic.findOrderById(id, OrderTypeEnum.HOME.getKey());
            Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + order.getRefEnginRecordNo());
            try {
                if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                    enginOrderLogic.del(order);
                }
            } catch(Exception e) {
                log.error("【工程订单处理】失败",e);
                throw e;
            } finally {
                obtain.unlock();
            }
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "删除商用工程订单")
    @PostMapping("/trade-del")
    public ResponseHelper tradeDel(
            @ApiParam(required = true, value = "商用工程订单id") @RequestParam List<String> ids
    ) throws Exception {
        List<String> collect = ids.stream().distinct().collect(Collectors.toList());
        for (String id : collect) {
            EnginOrder order = enginOrderLogic.findOrderById(id, OrderTypeEnum.TRADE.getKey());
            Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + order.getRefEnginRecordNo());
            try {
                if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                    enginOrderLogic.del(order);
                }
            } catch(Exception e) {
                log.error("【工程订单处理】失败",e);
                throw e;
            } finally {
                obtain.unlock();
            }
        }

        return ResponseHelper.success();
    }

    private ResponseHelper<EnginOrderBean> getResponseHelper(EnginOrderBean enginOrderBean, String orderType, String operType) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                if (StringUtils.isEmpty(enginOrderBean.getEnginOrderId())) {
                    // 先保存
                    enginOrderBean.setEnginOrderType(orderType);
                    String id = "";
                    if (orderType.equals(OrderTypeEnum.HOME.getKey())) {
                        id = enginOrderLogic.homeAdd(enginOrderBean, SysDictConstant.SUBMIT);
                    } else {
                        id = enginOrderLogic.tradeAdd(enginOrderBean, SysDictConstant.SUBMIT);
                    }

                    enginOrderBean.setEnginOrderId(id);
                    return ResponseHelper.success(enginOrderLogic.nextWaitOrder(enginOrderBean, operType));
                } else {
                    // 提交或审核
                    enginOrderBean.setEnginOrderType(orderType);
                    if (operType.equals("")) {
                        enginOrderLogic.edit(enginOrderBean);
                    } else {
                        if (orderType.equals(OrderTypeEnum.HOME.getKey())) {
                            EnginOrder enginOrder = enginOrderLogic.execHandlerHome(enginOrderBean, operType);
                            if (Objects.nonNull(enginOrder)
                                    && enginOrderBean.isExamineResult()
                                    && operType.equals(SysDictConstant.EXAMINE)) {
                                enginSysLogic.updEngineSystemBill(enginOrder, null);
                            }
                        } else {
                            //商用订单提交审核
                            enginOrderLogic.execHandlerTrade(enginOrderBean, operType);
                        }
                        return ResponseHelper.success(enginOrderLogic.nextWaitOrder(enginOrderBean, operType));
                    }
                }
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "关闭家用工程订单")
    @PostMapping("/home-close")
    public ResponseHelper homeClose(
            @ApiParam(required = true, value = "家用工程订单") @RequestParam String id,
            @ApiParam(required = true, value = "工程登录编号") @RequestParam String refEnginRecordNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.closeHome(id, refEnginRecordNo, OrderTypeEnum.HOME.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "关闭商用工程订单")
    @PostMapping("/trade-close")
    public ResponseHelper tradeClose(
            @ApiParam(required = true, value = "商用工程订单") @RequestParam String id,
            @ApiParam(required = true, value = "工程登录编号") @RequestParam String refEnginRecordNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.closeTrade(id, refEnginRecordNo, OrderTypeEnum.TRADE.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

//    @ApiOperation(value = "直调发货")
//    @PostMapping("/direct-transfer")
//    public ResponseHelper directTransfer(
//            @ApiParam(required = true, value = "工程订单") @RequestBody EnginOrderBean enginOrderBean
//    ) throws Exception {
//        直调流程改到发货流程
//        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getEnginOrderId());
//        try {
//            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
//                enginOrderLogic.directTransfer(enginOrderBean);
//            }
//        } catch(Exception e) {
//            log.error("【工程订单处理】失败",e);
//            throw e;
//        } finally {
//            obtain.unlock();
//        }
//        return ResponseHelper.success();
//    }

    @ApiOperation(value = "直调完结")
    @PostMapping("/end-direct-transfer")
    public ResponseHelper endDirectTransfer(
            @ApiParam(required = true, value = "工程订单id") @RequestParam String id,
            @ApiParam(required = true, value = "工程登录编号") @RequestParam String refEnginRecordNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.endDirectTransfer(id, refEnginRecordNo);
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "家用工程订单")
    @PostMapping("/home-refund")
    public ResponseHelper homeRefund(
            @ApiParam(required = true, value = "家用工程订单")
            @RequestBody
            @Validated EnginOrderBean enginOrderBean
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.refundHome(enginOrderBean, OrderTypeEnum.HOME.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "退订商用工程订单")
    @PostMapping("/trade-refund")
    public ResponseHelper tradeRefund(
            @ApiParam(required = true, value = "商用工程订单")
            @RequestBody
            @Validated EnginOrderBean enginOrderBean
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + enginOrderBean.getRefEnginRecordNo());
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.refundTrade(enginOrderBean, OrderTypeEnum.TRADE.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @ApiOperation(value = "工程订单列表导出")
    @GetMapping("/export")
    public void export(
            @ApiParam(value = "客户编码/客户名称") @RequestParam(required = false) String customerKeyword,
            @ApiParam(value = "工程订单编号") @RequestParam(required = false) List<String> enginOrderNo,
            @ApiParam(value = "工程订单类型") @RequestParam(defaultValue = "HOME") String enginOrderType,
            @ApiParam(value = "工程编号") @RequestParam(required = false) String refProjectNo,
            @ApiParam(value = "登录单号") @RequestParam(required = false) String refEnginRecordNo,
            @ApiParam(value = "项目名称") @RequestParam(required = false) String refProjectName,
            @ApiParam(value = "项目类别") @RequestParam(required = false) String refProjectCategory,
            @ApiParam(value = "使用单位") @RequestParam(required = false) String refUseUnit,
            @ApiParam(value = "行业类别") @RequestParam(required = false) String refTradeCategory,
            @ApiParam(value = "创建日期-开始") @RequestParam(required = false) String startCreateTime,
            @ApiParam(value = "创建日期-结束") @RequestParam(required = false) String endCreateTime,
            @ApiParam(value = "订单日期-开始") @RequestParam(required = false) String startOrderTime,
            @ApiParam(value = "订单日期-结束") @RequestParam(required = false) String endOrderTime,
            @ApiParam(value = "销售类型") @RequestParam(required = false) String saleTypeId,
            @ApiParam(value = "创建人") @RequestParam(required = false) String createName,
            @ApiParam(value = "审核人") @RequestParam(required = false) String confirmName,
            @ApiParam(value = "状态") @RequestParam(required = false) List<String> examineStatus,
            @ApiParam(value = "业务员") @RequestParam(required = false) String serviceId,
            @ApiParam(value = "物料编码") @RequestParam(required = false) String materialNumber,
            @ApiParam(value = "物料名称") @RequestParam(required = false) String materialName,
            @ApiParam(value = "产品编码") @RequestParam(required = false) String materialOldNumber,
            @ApiParam(value = "规格型号") @RequestParam(required = false) String specification,
            @ApiParam(value = "区域") @RequestParam(required = false) String refRegionWork,
            @ApiParam(value = "备注") @RequestParam(required = false) String remark,
            @ApiParam(value = "格力内部备注") @RequestParam(required = false) String geLiInerNote,
            @ApiParam(value = "跨区厂编号") @RequestParam(required = false) String refFactoryNo,
            @ApiParam(value = "购买单位名称") @RequestParam(required = false) String refBuyUnitName,
            @ApiParam(value = "保证函") @RequestParam(required = false) String refPromiseProvide,
            @ApiParam(value = "是否直调") @RequestParam(required = false) Boolean isDirectTransfer,
            @ApiParam(value = "钱包",required = false) @RequestParam(required = false) String customerWalletId,

            HttpServletRequest request, HttpServletResponse response
    ) throws Exception {
        if (CollectionUtil.isNotEmpty(examineStatus) && examineStatus.size() == 1 && examineStatus.get(0).equals(ExamineStatusEnum.WAIT.toString())) {
            examineStatus.add("export");
        }
        IPage<EnginOrderListBean> listPage = enginOrderLogic.listPage(customerWalletId,customerKeyword, enginOrderNo, enginOrderType, refProjectNo,
                refEnginRecordNo, refProjectCategory, refProjectName, refUseUnit, refTradeCategory, startCreateTime, endCreateTime,
                startOrderTime,endOrderTime,
                saleTypeId, createName, confirmName, examineStatus, serviceId, specification, materialNumber, materialName,
                materialOldNumber, refRegionWork, remark, geLiInerNote, refFactoryNo, refBuyUnitName,
                refPromiseProvide, isDirectTransfer, 1, -1);
        ExcelData excelData;
        if (OrderTypeEnum.HOME.getKey().equals(enginOrderType)) {
            excelData = enginOrderLogic.exportHome(listPage.getRecords());
        } else {
            excelData = enginOrderLogic.exportTrade(listPage.getRecords());
        }
        String fileName = OrderTypeEnum.HOME.getKey().equals(enginOrderType) ? "家用工程订单" : "商用工程订单";
        ExcelUtils.exportExcel(request,response,fileName + ".xlsx",excelData);
    }

    @PostMapping("/home-abandon")
    @ApiOperation("弃审")
    public ResponseHelper homeAbandon(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "工程登录编号", required = true) @RequestParam String refEnginRecordNo
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.abandonHome(id, refEnginRecordNo, OrderTypeEnum.HOME.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @PostMapping("/trade-abandon")
    @ApiOperation("弃审")
    public ResponseHelper tradeAbandon(
            @ApiParam(value = "id", required = true) @RequestParam String id,
            @ApiParam(value = "工程登录编号", required = true) @RequestParam String refEnginRecordNo
    ) throws Exception {
        if(commonLogic.getAdminUser(true).getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.ENGIN_ORDER + refEnginRecordNo);
        try {
            if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                enginOrderLogic.abandonTrade(id, refEnginRecordNo, OrderTypeEnum.TRADE.getKey());
            }
        } catch(Exception e) {
            log.error("【工程订单处理】失败",e);
            throw e;
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @GetMapping("/query-pre-order")
    @ApiOperation("查询上一次引用单的明细")
    public ResponseHelper<List<EnginOrderListBean>> queryPreOrder(
            @ApiParam(value = "引用单号",required = true) @RequestParam String recordNo
    ) throws Exception {
        return ResponseHelper.success(enginOrderLogic.queryPreOrder(recordNo));
    }

    @PostMapping("/init-old-trade")
    @ApiOperation("初始化旧数据商用")
    public ResponseHelper initOld(
            MultipartFile file,
            @ApiParam(value = "是否生成商用工程订单") @RequestParam(defaultValue = "false") Boolean isCreateOrder
    ) throws InterruptedException, IOException {
        List<Object> objects = ExcelUtils.importExcel(file);
        enginOrderLogic.importInit(objects, isCreateOrder);
        return ResponseHelper.success();
    }
}
