package com.boco.nbd.wios.wx.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.bestvike.linq.Linq;
import com.boco.nbd.cams.core.constant.MessageConstant;
import com.boco.nbd.framework.common.ResponseMessage2;
import com.boco.nbd.framework.common.ResponseStatus;
import com.boco.nbd.framework.workflow.entity.SubmitTypeEnum;
import com.boco.nbd.framework.workflow.entity.constant.FlowConstants;
import com.boco.nbd.framework.workflow.entity.exception.FlowException;
import com.boco.nbd.wios.flow.entity.bo.BaseSubmitFlowBO;
import com.boco.nbd.wios.flow.entity.bo.LocalSubmitFlowBO;
import com.boco.nbd.wios.flow.entity.bo.SimpleSubmitFlowBO;
import com.boco.nbd.wios.flow.entity.bo.WorkTaskVO;
import com.boco.nbd.wios.flow.entity.po.OrderPO;
import com.boco.nbd.wios.flow.entity.qo.CamsOrderQo;
import com.boco.nbd.wios.flow.enums.FlowNodeEnum;
import com.boco.nbd.wios.flow.service.IOrderService;
import com.boco.nbd.wios.flow.util.ProcessUtil;
import com.boco.nbd.wios.manage.contants.WiosConstant;
import com.boco.nbd.wios.manage.controller.OrderController;
import com.boco.nbd.wios.manage.controller.OrderInstallController;
import com.boco.nbd.wios.manage.controller.OrderSurveyController;
import com.boco.nbd.wios.manage.entity.bo.Dictionary;
import com.boco.nbd.wios.manage.entity.bo.*;
import com.boco.nbd.wios.manage.entity.cams.enums.OrderStatus;
import com.boco.nbd.wios.manage.entity.common.bo.UploadFile;
import com.boco.nbd.wios.manage.service.impl.*;
import com.boco.nbd.wios.wx.entity.bo.MinaOrderTrack;
import com.boco.nbd.wios.wx.entity.bo.RegisterBO;
import com.boco.nbd.wios.wx.entity.qo.MinaOrderQo;
import com.boco.nbd.wios.wx.permisson.MinaPermission;
import com.boco.nbd.wios.wx.service.WxOrderService;
import com.boco.nbd.wios.wx.vo.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ihidea.component.api.v2.BaseResponse;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.support.session.SessionInfo;
import com.ihidea.core.util.BeanUtilsEx;
import com.ihidea.core.util.JSONUtilsEx;
import com.ihidea.core.util.StringUtilsEx;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author kevin
 * @create 2020/10/28 20:59
 */
@Api(tags = "微信小程序订单相关接口")
@MinaPermission
@RestController
@RequestMapping("/mina")
@Slf4j
public class MinaOrderController {

    @Autowired
    private OrderController orderController;

    @Autowired
    private OrderSurveyController orderSurveyController;

    @Autowired
    private OrderInstallController orderInstallController;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderSurveyService orderSurveyService;

    @Autowired
    private OrderInstallService orderInstallService;

    @Autowired
    private OperateLogService operateLogService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private MaterialConfigService materialConfigService;

    @Autowired
    private OemContractService oemContractService;

    @Autowired
    private ExpandPriceService expandPriceService;

    @Autowired
    private WxOrderService wxOrderService;

    @Autowired
    private IOrderService flowOrderService;


    /**
     * 安装订单环节:勘测预约、勘测完成、上传勘测资料、勘测资料审核、安装预约、安装完成、上传安装资料、安装资料审核 八个环节+电力安装
     */
    private static final Integer[] installNode = {104, 105, 106, 107, 108, 109, 110, 111, 112, 115};


    @ApiOperation("勘测 签到")
    @PostMapping(value = "/survey/register")
    public ResponseMessage2 sign(@RequestBody RegisterBO bo) {
        OrderPO po = new OrderPO();
        po.setId(bo.getId());
        po.setSurveySignLat(bo.getSignLat());
        po.setSurveySignLng(bo.getSignLng());
        po.setSurveySignOverRange(bo.getOverRange());
        po.setSurveyStartTime(new Date());
        flowOrderService.updateByPrimaryKeySelective(po);
        return ResponseMessage2.Success();
    }

    @ApiOperation("勘测 签退")
    @PostMapping(value = "/survey/unRegister")
    public ResponseMessage2 signOut(@RequestBody RegisterBO bo) {
        OrderPO po = new OrderPO();
        po.setId(bo.getId());
        po.setSurveySignOutLat(bo.getSignLat());
        po.setSurveySignOutLng(bo.getSignLng());
        po.setSurveySignOutOverRange(bo.getOverRange());
        po.setSurveyEndTime(new Date());
        flowOrderService.updateByPrimaryKeySelective(po);
        return ResponseMessage2.Success();
    }

    @ApiOperation("安装 签到")
    @PostMapping(value = "/install/register")
    public ResponseMessage2 register(@RequestBody RegisterBO bo) {
        OrderPO po = new OrderPO();
        po.setId(bo.getId());
        po.setInstallSignLat(bo.getSignLat());
        po.setInstallSignLng(bo.getSignLng());
        po.setInstallSignOverRange(bo.getOverRange());
        po.setInstallStartTime(new Date());
        flowOrderService.updateByPrimaryKeySelective(po);
        return ResponseMessage2.Success();
    }

    @ApiOperation("安装 签退")
    @PostMapping(value = "/install/unRegister")
    public ResponseMessage2 unRegister(@RequestBody RegisterBO bo) {
        OrderPO po = new OrderPO();
        po.setId(bo.getId());
        po.setInstallSignOutLat(bo.getSignLat());
        po.setInstallSignOutLng(bo.getSignLng());
        po.setInstallSignOutOverRange(bo.getOverRange());
        po.setInstallEndTime(new Date());
        flowOrderService.updateByPrimaryKeySelective(po);
        return ResponseMessage2.Success();
    }

    @ApiOperation(value = "获取安装订单环节==>只是为了方便前端知晓环节标识")
    @GetMapping(value = "/install/getNode")
    public ResponseMessage2 getInstallOrderNode() {
        Map<Integer, String> items = new HashMap<>(9);
        Linq.of(installNode).forEach(s -> {
            FlowNodeEnum item = FlowNodeEnum.getEnum(s);
            if (item != null) {
                items.put(item.getKey(), item.getValue());
            }
        });

        return ResponseMessage2.Success2(items);
    }

    @ApiOperation(value = "获取安装订单订单状态")
    @GetMapping(value = "/install/getOrderStatus")
    public ResponseMessage2 getInstallOrderStatus() {
        return ResponseMessage2.Success2(ProcessUtil.getSelectBO(OrderStatus.values()));
    }

    @ApiOperation("获取订单列表")
    @PostMapping(value = "/order/list")
    public ResponseMessage2<WorkTaskVO> getInstallOrder(@RequestBody MinaOrderQo qo) {
        if (qo == null || qo.getType() == null) {
            return ResponseMessage2.Failed("查询参数缺失.");
        }
        CamsOrderQo camsOrderQo = new CamsOrderQo();
        SessionInfo currentUser = ProcessUtil.getUserInfo();
        if (currentUser == null) {
            return ResponseMessage2.Failed(ResponseStatus.ForbiddenAccess.getIndex(), ProcessUtil.RE_LOGIN);
        }
        camsOrderQo.setUserId(currentUser.getUserId());
        camsOrderQo.setLoginUserName(currentUser.getUserName());
        BeanUtil.copyProperties(qo, camsOrderQo);
        camsOrderQo.setAreMina(true);
        if (StrUtil.isEmpty(camsOrderQo.getNext())) {
            List<String> nodes = Arrays.asList(installNode).stream().map(x -> x + "").collect(Collectors.toList());
            String next = String.join(FlowConstants.COMMA, nodes);
            camsOrderQo.setNext(next);
        }
        return ResponseMessage2.Success2(flowOrderService.getWaitDealWorkTask(camsOrderQo));
    }


    @ApiOperation("获取工单轨迹")
    @GetMapping(value = "/order/track")
    public ResponseMessage2 getWorkTrack(String processInsId) {
        return ResponseMessage2.Success2(flowOrderService.getMinaWorkTrack(processInsId));
    }

    @ApiOperation("流程关闭")
    @PostMapping("/closeFlow")
    public ResponseMessage2<Boolean> closeFlow(@RequestBody BaseSubmitFlowBO submitBO) {
        LocalSubmitFlowBO flowBO = submitBO.toBo();
        flowBO.setSubmitType(SubmitTypeEnum.CloseFlow);
        return submitFlow(flowBO);
    }

    /**
     * 流转接口
     *
     * @param bo
     * @return
     */
    private ResponseMessage2<Boolean> submitFlow(LocalSubmitFlowBO bo) {
        try {
            SessionInfo currentUser = ProcessUtil.getUserInfo();
            if (currentUser == null) {
                return ResponseMessage2.Failed(ResponseStatus.ForbiddenAccess.getIndex(), ProcessUtil.RE_LOGIN);
            }
            bo.setSubmitUserId(currentUser.getUserId());
            bo.setSubmitUserName(currentUser.getUserName());
            return flowOrderService.submitFlow(bo);
        } catch (FlowException ex) {
            log.error("submitFlow FlowException:", ex);
            return ResponseMessage2.Failed(ex.getMessage());
        } catch (Exception ex) {
            log.error("submitFlow Exception:", ex);
            return ResponseMessage2.Failed(ex.getMessage());
        }
    }

    @ApiOperation("流程流转")
    @PostMapping("/submitFlow")
    public ResponseMessage2<Boolean> submitFlow(@RequestBody SimpleSubmitFlowBO submitBO) {
        LocalSubmitFlowBO flowBO = submitBO.toBo();
        if (submitBO.getUpdateBusiness() != null && submitBO.getUpdateBusiness()) {
            flowBO.setSubmitType(SubmitTypeEnum.UpdateVariable);
        } else {
            flowBO.setSubmitType(SubmitTypeEnum.TaskFlow);
        }
        return submitFlow(flowBO);
    }

    /*************************以下为原先代码**********************************/

    @ApiOperation(value = "获取字典内容")
    @GetMapping(value = "/dictionary/getByType")
    @ApiImplicitParams({@ApiImplicitParam(name = "type", value = "类型", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "name", value = "名称", dataType = "String", paramType = "query", required = false),})
    public BaseResponse<List<Dictionary>> getDictionaryByType(String type, String name) {
        if (StringUtils.isEmpty(type)) {
            throw new ServiceException(MessageConstant.MISSING_PARAM);
        }
        return new BaseResponse<>(dictionaryService.selectValidByType(type, name));
    }

    @ApiOperation(value = "获取枚举内容")
    @GetMapping(value = "/enums")
    @ApiImplicitParams({@ApiImplicitParam(name = "enumNames", value = "枚举类名", dataType = "String", paramType = "query", required = true),})
    public BaseResponse<Object> getEnums(String enumNames) {
        if (StringUtils.isEmpty(enumNames)) {
            throw new ServiceException(MessageConstant.MISSING_PARAM);
        }
        return new BaseResponse<>(commonService.getEnumsArr(enumNames));
    }

    @ApiOperation(value = "获取合约物料增项")
    @GetMapping(value = "/getContractItems")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "物料类型 2-增项 3-充电桩", dataType = "int", paramType = "query", required = true),
    })
    public BaseResponse<Object> getContractItems(String orderId, Integer type) {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notNull(type, "物料类型不能为空");

        OrderVo orderVo = orderService.selectOwnOrderById(orderId);
        Assert.notNull(orderVo, "订单不存在");

        final String itemType = type == null ? "2" : String.valueOf(type);
        List<OemContractItemVo> itemList = oemContractService.getContractItems(orderVo.getOemId(), orderVo.getRegionId());
        if (itemList != null) {
            itemList = itemList.stream().filter((itemVo) -> StringUtils.equals(itemVo.getType(), itemType)).collect(Collectors.toList());
        }
        return new BaseResponse<>(itemList);
    }

    @ApiOperation(value = "获取增项说明")
    @GetMapping(value = "/getItemFeeDesc")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oemId", value = "经销商ID", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "regionId", value = "区域ID", dataType = "int", paramType = "query", required = false),
    })
    public BaseResponse<MaterialConfigVo> getItemFeeDesc(Integer oemId, Integer regionId) {
        Assert.notNull(oemId, "经销商ID不能为空");
        MaterialConfigBo condition = new MaterialConfigBo();
        condition.setOemId(oemId);
        condition.setType(2);
        condition.setStatus(1);
        List<MaterialConfigVo> list = materialConfigService.getList(condition);
        MaterialConfigVo vo = null;
        if (CollectionUtils.isNotEmpty(list)) {
            vo = list.get(0);
        }
        return new BaseResponse<>(vo);
    }

    private MinaOrderVO convertToMinaOrderVO(OrderVo order) throws Exception {
        MinaOrderVO minaOrderVO = BeanUtilsEx.copyPropertiesUnConvert(order, MinaOrderVO.class);
        minaOrderVO.setStatusName(OrderStatus.getText(minaOrderVO.getStatus()));
        minaOrderVO.setStatusCode(OrderStatus.get(order.getStatus()).toString());

        return minaOrderVO;
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation("订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "noLog", value = "不含日志,默认包含", dataType = "boolean", paramType = "query", required = false),
    })
    @GetMapping("/order/detail")
    public BaseResponse<MinaOrderDetailVO> orderDetailProcess(String orderId, Boolean noLog) throws Exception {
        Assert.notEmpty(orderId, WiosConstant.EMPTY_ORDER_ID);
        OrderPO orderPO = flowOrderService.getOrder(orderId);
        if (orderPO == null) {
            return new BaseResponse<>(null);
        }
        MinaOrderDetailVO detailVO = new MinaOrderDetailVO();
        MinaOrderVO minaOrderVO = BeanUtilsEx.copyPropertiesUnConvert(orderPO, MinaOrderVO.class);
        minaOrderVO.setStatusName(OrderStatus.getText(minaOrderVO.getStatus()));
        minaOrderVO.setStatusCode(OrderStatus.get(orderPO.getStatus()) + "");
        //调整成用处理时限 满足 minaOrderVO.setShowReserveExpBtn
        detailVO.setOrder(minaOrderVO);

        //账单信息
        detailVO.setBill(wxOrderService.getBill(orderId));
        if (noLog == null || !noLog) {
            List<MinaOrderTrack> tracks = flowOrderService.getMinaWorkTrack(orderPO.getProcessInsId());
            List<MinaOrderOperateLogVO> logVOList = new ArrayList<>(tracks.size());
            for (int i = 0; i < tracks.size(); i++) {
                MinaOrderTrack track = tracks.get(i);
                MinaOrderOperateLogVO logVO = MinaOrderOperateLogVO.toVo(track);
                String nextNode = (i == 0 ? orderPO.getNodeFlag() + "": tracks.get(i - 1).getNodeFlag());
                OrderStatus orderStatus = FlowNodeEnum.getOrderStatus(track.getNodeFlag(), nextNode);
                if (orderStatus != null) {
                    logVO.setCode(orderStatus.toString());
                }
                if (OrderStatus.INSTALL_FINISH.equals(orderStatus)) {
                    //110=>111
                    logVO.setShowDetail(true);
                    logVO.setInstallProcessDetail(BeanUtilsEx.copyPropertiesUnConvert(orderInstallService.getByOrderId(orderId), MinaOrderInstallVO.class));
                    List<ExpandPrice> prices = expandPriceService.getByRegionId(Integer.valueOf(orderPO.findAreaId()));
                    if (CollectionUtils.isNotEmpty(prices)) {
                        logVO.getInstallProcessDetail().setExpandPrice(prices.get(0).getPrice());
                    }
                } else {
                    logVO.buildProcessDetail(orderStatus, orderPO, track);
                    logVOList.add(logVO);
                }
            }
            detailVO.setOperateLogList(logVOList);
        }

        return new BaseResponse<>(detailVO);
    }

    /**
     * 勘测安装操作步骤显示详情
     */
    private static final Map<String, Integer> SHOW_DETAIL_OPERATE_MAP = new HashMap<String, Integer>() {{
        put(OrderStatus.SURVEY_RESERVE_EXCEPTION.toString(), OrderStatus.SURVEY_RESERVE_EXCEPTION.getType()); //勘察异常,显示异常信息
        put(OrderStatus.SURVEY_RESERVED.toString(), OrderStatus.SURVEY_RESERVED.getType()); //勘察已预约,显示预约详情
        put(OrderStatus.SURVEY_FINISH.toString(), OrderStatus.SURVEY_FINISH.getType()); //勘察完成,显示勘察报告
        put(OrderStatus.SURVEY_RECTIFYING.toString(), OrderStatus.SURVEY_RECTIFYING.getType()); //勘察整改,显示勘察审核详情
        put(OrderStatus.SURVEY_EXAMINE_SUCCESS.toString(), OrderStatus.SURVEY_EXAMINE_SUCCESS.getType()); //勘察审核通过,显示勘察审核详情
        put(OrderStatus.INSTALL_RESERVED.toString(), OrderStatus.INSTALL_RESERVED.getType()); //安装已预约,显示预约详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINING.toString(), OrderStatus.INSTALL_CHANGE_EXAMINING.getType()); //安装变更待审核,显示安装变更详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.toString(), OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.getType()); //安装变更审核通过,显示安装变更审核详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.toString(), OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.getType()); //安装变更审核不通过,显示安装变更审核详情
        put(OrderStatus.INSTALL_FINISH.toString(), OrderStatus.INSTALL_FINISH.getType()); //安装完成,显示安装报告
        put(OrderStatus.INSTALL_RECTIFYING.toString(), OrderStatus.INSTALL_RECTIFYING.getType()); //安装整改,显示安装审核详情
        put(OrderStatus.INSTALL_EXAMINE_SUCCESS.toString(), OrderStatus.INSTALL_EXAMINE_SUCCESS.getType()); //安装审核通过,显示安装审核详情
    }};

    /**
     * 移桩操作步骤显示详情
     */
    private static final Map<String, Integer> SHOW_MOVE_DETAIL_OPERATE_MAP = new HashMap<String, Integer>() {{
        put(OrderStatus.SURVEY_RESERVE_EXCEPTION.toString(), OrderStatus.SURVEY_RESERVE_EXCEPTION.getType()); //勘察异常,显示异常信息
        put(OrderStatus.SURVEY_RESERVED.toString(), OrderStatus.SURVEY_RESERVED.getType()); //勘察已预约,显示预约详情
        put(OrderStatus.SURVEY_RECTIFYING.toString(), OrderStatus.SURVEY_RECTIFYING.getType()); //勘察整改,显示勘察审核详情
        put(OrderStatus.SURVEY_EXAMINE_SUCCESS.toString(), OrderStatus.SURVEY_EXAMINE_SUCCESS.getType()); //勘察审核通过,显示勘察审核详情
        put(OrderStatus.INSTALL_RESERVED.toString(), OrderStatus.INSTALL_RESERVED.getType()); //安装已预约,显示预约详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINING.toString(), OrderStatus.INSTALL_CHANGE_EXAMINING.getType()); //安装变更待审核,显示安装变更详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.toString(), OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.getType()); //安装变更审核通过,显示安装变更审核详情
        put(OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.toString(), OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.getType()); //安装变更审核不通过,显示安装变更审核详情
        put(OrderStatus.INSTALL_RECTIFYING.toString(), OrderStatus.INSTALL_RECTIFYING.getType()); //安装整改,显示安装审核详情
        put(OrderStatus.INSTALL_EXAMINE_SUCCESS.toString(), OrderStatus.INSTALL_EXAMINE_SUCCESS.getType()); //安装审核通过,显示安装审核详情
    }};

    private OrderVo getOrderBaseAndCheck(String orderId, String operateCode) {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notBlank(operateCode, "订单操作代码不能为空");

        Assert.notNull(SHOW_DETAIL_OPERATE_MAP.get(operateCode), "不支持此操作详情查询");

        OrderVo order = orderService.selectOwnOrderById(orderId);
        Assert.notNull(order, "订单信息不存在");

        return order;
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation("订单进度-预约详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码: SURVEY_RESERVED、INSTALL_RESERVED", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query"),
    })
    @GetMapping("/order/process/reserve")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderReserveVO>> orderProcessReserve(String orderId, String operateCode, Integer operateLogId) throws Exception {
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderReserveVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));
        Integer operateName = SHOW_DETAIL_OPERATE_MAP.get(operateCode);

        MinaOrderReserveVO reserveVO = new MinaOrderReserveVO();
        if (operateName == OrderStatus.SURVEY_RESERVED.getType()) {
            reserveVO.setStaffName(order.getSurveyStaffName());
            reserveVO.setStaffPhone(order.getSurveyStaffPhone());
            reserveVO.setClientName(order.getSurveyClientName());
            reserveVO.setClientPhone(order.getSurveyClientPhone());
            reserveVO.setReserveTime(order.getSurveyReserveTime());
            reserveVO.setCamsPhone(order.getSurveyCamsPhone());
        } else if (operateName == OrderStatus.INSTALL_RESERVED.getType()) {
            reserveVO.setStaffName(order.getInstallStaffName());
            reserveVO.setStaffPhone(order.getInstallStaffPhone());
            reserveVO.setClientName(order.getInstallClientName());
            reserveVO.setClientPhone(order.getInstallClientPhone());
            reserveVO.setReserveTime(order.getInstallReserveTime());
            reserveVO.setCamsPhone(order.getInstallCamsPhone());
        }
        // 如果操作日志参数,取日志中的时点记录
        if (operateLogId != null) {
            OperateLog log = operateLogService.selectById(operateLogId);
            if (log != null && StringUtils.isNotBlank(log.getDesc())) {
                if (operateName == OrderStatus.SURVEY_RESERVE_EXCEPTION.getType()) {
                    reserveVO.setRemark(log.getDesc());
                } else {
                    BeanUtilsEx.copyProperties(JSONUtilsEx.deserialize(log.getDesc(), Map.class), reserveVO);
                }
            }
        }

        detailVO.setProcessDetail(reserveVO);
        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation("订单进度-勘察报告")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码:SURVEY_FINISH", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型 1-勘察报告 3-安装变更", dataType = "int", paramType = "query"),
    })
    @GetMapping("/order/process/survey")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderSurveyVO>> orderProcessSurvey(String orderId, String operateCode, Integer operateLogId, Integer type) throws Exception {
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderSurveyVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        type = type == null ? 1 : type;
        OrderSurveyVo orderSurveyVo = null;
        if (order.getType() == 1) {
            orderSurveyVo = orderSurveyService.getByOrderId(orderId, type);
            // 如果安装变更记录不存在,默认显示勘察报告
            if (type == 3 && orderSurveyVo == null) {
                orderSurveyVo = orderSurveyService.getByOrderId(orderId, 1);
                if (orderSurveyVo != null) {
                    orderSurveyVo.setId(null);
                    orderSurveyVo.getItemFees().stream().forEach((item) -> {
                        item.setType(3);
                    });
                    orderSurveyVo.getFiles().stream().forEach((file) -> {
                        file.setId(null);
                        file.setType(3);
                        file.setCreateBy(null);
                        file.setCreateTime(null);
                    });
                }
            }
        } else {
            if (type == 3) {
                orderSurveyVo = new OrderSurveyVo();
                OrderVo orderVo = orderService.getDetail(orderId);
                orderSurveyVo.setFiles(orderVo.getInstallChangeFiles());
            }
        }

        detailVO.setProcessDetail(BeanUtilsEx.copyPropertiesUnConvert(orderSurveyVo, MinaOrderSurveyVO.class));

        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation("订单进度-移桩订单安装变更详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码:SURVEY_FINISH", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型 3-安装变更", dataType = "int", paramType = "query"),
    })
    @GetMapping("/order/process/moveChange")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderSurveyVO>> orderProcessMoveChange(String orderId, String operateCode, Integer operateLogId, Integer type) throws Exception {
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderSurveyVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        MinaOrderMoveChangeVO moveChangeVO = new MinaOrderMoveChangeVO();
        OrderVo orderVo = orderService.getDetail(orderId);
        moveChangeVO.setOrderId(orderId);
        moveChangeVO.setFiles(orderVo.getInstallChangeFiles());

        detailVO.setProcessDetail(BeanUtilsEx.copyPropertiesUnConvert(moveChangeVO, MinaOrderSurveyVO.class));

        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation("订单进度-审核详情=>信息附加到order/detail中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码:SURVEY_RECTIFYING、SURVEY_EXAMINE_SUCCESS、INSTALL_CHANGE_EXAMINE_FAIL、INSTALL_CHANGE_EXAMINE_SUCCESS、INSTALL_RECTIFYING、INSTALL_EXAMINE_SUCCESS", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query", required = true),
    })
    @ApiIgnore
    @GetMapping("/order/process/audit")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderAuditVO>> orderProcessAudit(String orderId, String operateCode, Integer operateLogId) throws Exception {
        Assert.notNull(operateLogId, "订单操作日志编号不能为空");
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderAuditVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        Integer operateName = SHOW_DETAIL_OPERATE_MAP.get(operateCode);
        if (operateName == OrderStatus.SURVEY_RECTIFYING.getType() || operateName == OrderStatus.SURVEY_EXAMINE_SUCCESS.getType()
                || operateName == OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.getType() || operateName == OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.getType()
                || operateName == OrderStatus.INSTALL_RECTIFYING.getType() || operateName == OrderStatus.INSTALL_EXAMINE_SUCCESS.getType()) {
            OperateLog log = operateLogService.selectById(operateLogId);
            if (log != null) {
                MinaOrderAuditVO auditVO = new MinaOrderAuditVO();
                auditVO.setFailed(!StringUtils.contains(operateCode, "SUCCESS"));
                auditVO.setAuditResult(log.getValue());
                auditVO.setAuditName(log.getCreateAccountName());
                auditVO.setAuditTime(log.getCreateTime());
                auditVO.setAuditFailReason(log.getDesc());
                detailVO.setProcessDetail(auditVO);
            }
        }
        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation("订单进度-安装变更")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码:INSTALL_CHANGE_EXAMINING", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query"),
    })
    @GetMapping("/order/process/installChange")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderInstallChangeVO>> orderProcessInstallChange(String orderId, String operateCode, Integer operateLogId) throws Exception {
        Assert.notNull(operateLogId, "订单操作日志编号不能为空");
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderInstallChangeVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        Integer operateName = SHOW_DETAIL_OPERATE_MAP.get(operateCode);
        if (operateName == OrderStatus.INSTALL_CHANGE_EXAMINING.getType()) {
            detailVO.setProcessDetail(BeanUtilsEx.copyPropertiesUnConvert(orderSurveyService.getByOrderId(orderId, 1), MinaOrderInstallChangeVO.class));
        }
        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation("订单进度-安装报告")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateCode", value = "订单操作代码:INSTALL_FINISH", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "operateLogId", value = "订单操作日志编号", dataType = "int", paramType = "query"),
    })
    @GetMapping("/order/process/install")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderInstallVO>> orderProcessInstall(String orderId, String operateCode, Integer operateLogId) throws Exception {
        OrderVo order = getOrderBaseAndCheck(orderId, operateCode);
        MinaOrderProcessDetailVO<MinaOrderInstallVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        Integer operateName = SHOW_DETAIL_OPERATE_MAP.get(operateCode);

        if (operateName == OrderStatus.INSTALL_FINISH.getType()) {
            detailVO.setProcessDetail(BeanUtilsEx.copyPropertiesUnConvert(orderInstallService.getByOrderId(orderId), MinaOrderInstallVO.class));
        }
        List<ExpandPrice> prices = expandPriceService.getByRegionId(Integer.valueOf(order.getRegionId()));
        if (CollectionUtils.isNotEmpty(prices)) {
            detailVO.setExpandPrice(prices.get(0).getPrice());
        }
        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 8)
    @ApiOperation("订单进度-移桩详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单编号", dataType = "string", paramType = "query", required = true),
    })
    @GetMapping("/order/process/move")
    public BaseResponse<MinaOrderProcessDetailVO<MinaOrderInstallVO>> orderProcessMove(String orderId) throws Exception {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        OrderVo order = orderService.selectOwnOrderById(orderId);
        Assert.notNull(order, "订单信息不存在");
        MinaOrderProcessDetailVO<MinaOrderMoveVO> detailVO = new MinaOrderProcessDetailVO();
        detailVO.setOrder(convertToMinaOrderVO(order));

        MinaOrderMoveVO moveVO = new MinaOrderMoveVO();
        List<UploadFile> files = orderService.getFiles(orderId);
        moveVO.setFiles(files);
        detailVO.setProcessDetail(moveVO);
        return new BaseResponse(detailVO);
    }

    @ApiOperationSupport(order = 11)
    @ApiOperation("订单预约")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "reserveTime", value = "预约时间yyyy-MM-dd HH:mm:ss", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "clientName", value = "客户姓名", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "clientPhone", value = "客户手机号", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "camsPhone", value = "注册CAMS PLUS 手机号", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(name = "type", value = "预约类型 1-勘察 2-安装", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "reserveStatus", value = "0-预约失败,1:预约成功", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(name = "followTime", value = "下次跟进时间yyyy-MM-dd HH:mm:ss", dataType = "String", paramType = "query", required = false),
    })
    @PostMapping("/order/reserve")
    public BaseResponse<Object> reserveSurvey(String orderId, String reserveTime, String clientName, String clientPhone, String camsPhone, Integer type,
                                              Integer reserveStatus, String followTime) {
        Assert.notBlank(reserveTime, "预约时间不能空");
        Assert.notBlank(clientName, "客户姓名不能空");
        Assert.notBlank(clientPhone, "客户手机号不能空");
//        Assert.notBlank(camsPhone, "注册CAMS PLUS手机号不能空");
        Assert.isTrue(type != null && (type == 1 || type == 2), "预约类型错误");

        reserveStatus = reserveStatus == null ? 1 : reserveStatus;
        Assert.notNull(reserveStatus, "预约状态不能为空");

        followTime = followTime == null ? reserveTime : followTime;
        if (type == 1) {
            return orderController.reserveSurvey(orderId, reserveTime, clientName, clientPhone, camsPhone, null, reserveStatus, followTime);
        } else {
            return orderController.reserveInstall(orderId, reserveTime, clientName, clientPhone, camsPhone, null, reserveStatus, followTime);
        }
    }

    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "订单勘察预约异常")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "content", value = "内容", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/survey/reserveFail")
    public BaseResponse<Object> reserveSurveyFail(String orderId, String content) {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notBlank(content, "预约异常原因不能为空");
        return orderController.reserveException(orderId, content);
    }

    @ApiOperationSupport(order = 13)
    @ApiOperation(value = "订单勘察开始")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "lng", value = "经度", dataType = "Double", paramType = "query"),
            @ApiImplicitParam(name = "lat", value = "纬度", dataType = "Double", paramType = "query"),
    })
    @PostMapping(value = "/order/survey/start")
    public BaseResponse<Object> surveyStart(String orderId, Double lng, Double lat) {
        orderService.updateStatus(orderId, OrderStatus.SURVEYING.getType(), (lng != null && lat != null) ? lng + "," + lat : null);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 14)
    @ApiOperation(value = "订单勘察报告保存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/survey/save")
    public BaseResponse<Object> surveySave(MinaOrderSurveyVO orderSurvey) throws Exception {
        OrderSurveyBo surveyBo = BeanUtilsEx.copyPropertiesUnConvert(orderSurvey, OrderSurveyBo.class);
        surveyBo.setType(1);
        if (orderSurvey.getId() == null) {
            orderSurveyController.add(surveyBo);
        } else {
            orderSurveyController.update(surveyBo);
        }

        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 15)
    @ApiOperation(value = "订单勘察完成")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/survey/finish")
    public BaseResponse<Object> surveyFinish(String orderId) {
        orderService.updateStatus(orderId, OrderStatus.SURVEY_FINISH.getType());
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 16)
    @ApiOperation(value = "订单勘察提交审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/survey/auditApply")
    public BaseResponse<Object> surveyAuditApply(String orderId) {
        OrderVo order = orderService.selectOwnOrderById(orderId);
        Assert.notNull(order, "订单不存在");
        Integer status = null;
        if (order.getStatus() == OrderStatus.SURVEY_FINISH.getType()) {
            status = OrderStatus.SURVEY_EXAMINING.getType();
        } else if (order.getStatus() == OrderStatus.SURVEY_RECTIFYING.getType()) {
            status = OrderStatus.SURVEY_RECTIFIED_EXAMINING.getType();
        }
        Assert.notNull(status, "订单状态错误");
        orderService.updateStatus(orderId, status);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 17)
    @ApiOperation(value = "订单勘察审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "status", value = "状态 0:不通过 1:通过", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "reason", value = "不通过原因", dataType = "String", paramType = "query", required = false),
    })
    @PostMapping(value = "/order/survey/audit")
    public BaseResponse<Object> surveyAudit(String orderId, Integer status, String reason) {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notNull(status, "状态不能为空");
        if (status == 0) {
            Assert.notBlank(reason, "不通过原因不能为空");
        }
        orderController.surveyFinishExamine(orderId, status, reason);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 22)
    @ApiOperation(value = "订单安装变更申请")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/install/changeApply")
    public BaseResponse<Object> installChange(MinaOrderSurveyVO orderSurvey) throws Exception {
        Assert.notBlank(orderSurvey.getOrderId(), WiosConstant.EMPTY_ORDER_ID);

        OrderVo order = orderService.selectOwnOrderById(orderSurvey.getOrderId());
        Assert.notNull(order, "订单不存在");

        OrderSurveyBo surveyBo = BeanUtilsEx.copyPropertiesUnConvert(orderSurvey, OrderSurveyBo.class);
        surveyBo.setType(3);
        if (orderSurvey.getId() == null) {
            orderSurveyController.add(surveyBo);
        } else {
            orderSurveyController.update(surveyBo);
        }

        orderService.installChange(orderSurvey.getOrderId(), null, null);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 22)
    @ApiOperation(value = "移桩订单安装变更申请")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/move/changeApply")
    public BaseResponse<Object> moveChange(MinaOrderMoveChangeVO moveChange) throws Exception {
        Assert.notBlank(moveChange.getOrderId(), WiosConstant.EMPTY_ORDER_ID);

        OrderVo order = orderService.selectOwnOrderById(moveChange.getOrderId());
        Assert.notNull(order, "订单不存在");
        List<String> fileNames = new ArrayList<>();
        List<String> fileUrls = new ArrayList<>();

        List<UploadFile> fileList = JSONUtilsEx.deserializeList(moveChange.getFilesJson(), UploadFile.class);
        Assert.isTrue(CollectionUtils.isNotEmpty(fileList), "请上传变更方案");

        fileList.forEach(file -> {
            fileNames.add(file.getName());
            fileUrls.add(file.getUrl());
        });

        orderService.installChange(moveChange.getOrderId(), fileNames, fileUrls);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 23)
    @ApiOperation(value = "订单安装变更审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "status", value = "状态 0:不通过 1:通过", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "reason", value = "不通过原因", dataType = "String", paramType = "query", required = false),
    })
    @PostMapping(value = "/order/install/changeAudit")
    public BaseResponse<Object> changeAudit(String orderId, Integer status, String reason) {
        orderController.installChangeExamine(orderId, status, reason);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 24)
    @ApiOperation(value = "订单安装开始")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "lng", value = "经度", dataType = "Double", paramType = "query"),
            @ApiImplicitParam(name = "lat", value = "纬度", dataType = "Double", paramType = "query"),
    })
    @PostMapping(value = "/order/install/start")
    public BaseResponse<Object> installStart(String orderId, Double lng, Double lat) {
        orderService.updateStatus(orderId, OrderStatus.INSTALLING.getType(), (lng != null && lat != null) ? lng + "," + lat : null);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 25)
    @ApiOperation(value = "订单安装报告保存")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/install/save")
    public BaseResponse<Object> installSave(MinaOrderInstallVO installVO) throws Exception {
        OrderInstallBo orderInstall = BeanUtilsEx.copyPropertiesUnConvert(installVO, OrderInstallBo.class);
        if (orderInstall.getId() == null) {
            orderInstallController.add(orderInstall);
        } else {
            orderInstallController.update(orderInstall);
        }

        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 25)
    @ApiOperation(value = "订单保存增项和报装")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "订单类型 1-勘察 2-安装 3-安装变更", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "itemFeesJson", value = "增项Json字符串", dataType = "string", paramType = "query", required = false),
            @ApiImplicitParam(name = "electricExpand", value = "是否进行电力报装 0:否1:是", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(name = "expandMethod", value = "报装方式 1:代报装 2:自主报装", dataType = "int", paramType = "query", required = false),
            @ApiImplicitParam(name = "expandFee", value = "报装费用", dataType = "BigDecimal", paramType = "query", required = false),
    })
    @PostMapping(value = "/order/install/saveItemFees")
    public BaseResponse<Object> saveItemFees(String orderId, Integer type, String itemFeesJson, Integer electricExpand, Integer expandMethod, BigDecimal expandFee) throws Exception {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notNull(type, WiosConstant.EMPTY_ORDER_TYPE);
        itemFeesJson = StringUtilsEx.unescapeXss(itemFeesJson);
        OrderInstallBo orderInstall = new OrderInstallBo();
        orderInstall.setItemFeesJson(itemFeesJson);

        orderInstallService.saveInstallItem(orderId, type, orderInstall.getItemFees(), electricExpand, expandMethod, expandFee);

        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 26)
    @ApiOperation(value = "订单安装完成")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "signature", value = "客户签字", dataType = "String", required = false),
    })
    @PostMapping(value = "/order/install/finish")
    public BaseResponse<Object> installFinish(String orderId, String signature) {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);

        OrderVo order = orderService.selectOwnOrderById(orderId);
        Assert.notNull(order, WiosConstant.EMPTY_ORDER);
        // 如果存在报装和增项,需要先付款
        if (order.getType() == 1) {
            OrderInstallVo orderInstallVo = orderInstallService.getByOrderId(orderId);
            Assert.notNull(orderInstallVo, "请填写安装报告");

            //自建服务商必须在线支付;其他服务商线下支付,不生成账单
            if (StringUtils.equals(order.getSupplierLevel(), "A")) {
                BigDecimal predictTotalFee = orderInstallVo.getPredictTotalFee() == null ? BigDecimal.ZERO : orderInstallVo.getPredictTotalFee();
                BigDecimal expandFee = orderInstallVo.getExpandFee() == null ? BigDecimal.ZERO : orderInstallVo.getExpandFee();
                BigDecimal totalFee = predictTotalFee.add(expandFee);
                Assert.isTrue(totalFee.compareTo(BigDecimal.ZERO) == 0 || orderInstallVo.getPayStatus() == 1, "当前工单存在账单未支付");
            }
            // 更新签名
            if (StringUtils.isNotBlank(signature)) {
                OrderInstall install = new OrderInstall();
                install.setClientSignature(signature);
                orderInstallService.updateByOrderId(orderId, install);
            }
        }
        // 更新状态
        orderService.updateStatus(orderId, OrderStatus.INSTALL_FINISH.getType());
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 27)
    @ApiOperation(value = "订单安装提交审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
    })
    @PostMapping(value = "/order/install/auditApply")
    public BaseResponse<Object> installAuditApply(String orderId) {
        orderService.updateStatus(orderId, OrderStatus.INSTALL_EXAMINING.getType());
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 28)
    @ApiOperation(value = "订单安装审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "status", value = "状态 0:不通过 1:通过", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "reason", value = "不通过原因", dataType = "String", paramType = "query", required = false),
    })
    @PostMapping(value = "/order/install/audit")
    public BaseResponse<Object> installAudit(String orderId, Integer status, String reason) {
        orderController.installFinishExamine(orderId, status, reason);
        return new BaseResponse<>();
    }

    @ApiOperationSupport(order = 30)
    @ApiOperation(value = "移桩上传附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "filesJson", value = "附件Json字符串", dataType = "string", paramType = "query", required = false),
    })
    @PostMapping(value = "/order/move/uploadAttachment")
    public BaseResponse<Object> uploadAttachment(String orderId, String filesJson) throws Exception {
        Assert.notBlank(orderId, WiosConstant.EMPTY_ORDER_ID);
        Assert.notBlank(filesJson, WiosConstant.EMPTY_ORDER_TYPE);
        filesJson = StringUtilsEx.unescapeXss(filesJson);

        List<UploadFile> fileList = JSONUtilsEx.deserializeList(filesJson, UploadFile.class);
        if (CollectionUtils.isNotEmpty(fileList)) {
            List<String> fileNames = new ArrayList<>();
            List<String> fileUrls = new ArrayList<>();
            fileList.forEach(file -> {
                fileNames.add(file.getName());
                fileUrls.add(file.getUrl());
            });
            orderService.uploadFile(orderId, fileNames, fileUrls);
        }
        return new BaseResponse<>();
    }

    @ApiOperation(value = "移桩删除附件")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "文件id", dataType = "int", paramType = "query", required = true),})
    @PostMapping(value = "/order/move/deleteAttachment")
    public BaseResponse<Object> deleteFile(Integer id) {
        Assert.notNull(id, "缺少id");
        commonService.deleteUploadFile(id);
        return new BaseResponse<>();
    }

}