package cn.iocoder.yudao.module.tickets.controller.admin;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.common.RecordTypeEnum;
import cn.iocoder.yudao.common.RepairCons;
import cn.iocoder.yudao.common.RepairDictConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.base.service.RepairRecordsService;
import cn.iocoder.yudao.module.custom.entity.CarMain;
import cn.iocoder.yudao.module.custom.entity.CustomerMain;
import cn.iocoder.yudao.module.custom.service.CarMainService;
import cn.iocoder.yudao.module.custom.service.CustomerMainService;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTickets;
import cn.iocoder.yudao.module.tickets.service.DlRepairTicketsService;
import cn.iocoder.yudao.module.tickets.vo.*;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * 维修工单表(DlRepairTickets)表控制层
 *
 * @author 小李
 * @date 18:21 2024/9/13
 **/
@RestController
@RequestMapping("/repair/tickets")
public class DlRepairTicketsController {
    /**
     * 服务对象
     */
    @Resource
    private DlRepairTicketsService dlRepairTicketsService;
    @Resource
    private CustomerMainService customerMainService;
    @Resource
    private CarMainService carMainService;
    @Resource
    private RepairRecordsService repairRecordsService;

    @Resource
    private DictDataApi dictDataApi;

    @Resource
    private PermissionApi permissionApi;


    /**
     * 维修工单表 新增
     *
     * @param ticketsRespVO 新增对象
     * @author 小李
     * @date 11:33 2024/9/20
     **/
    @PostMapping("/create")
    @Operation(summary = "维修工单表 新增")
    public CommonResult<?> createTicket(@RequestBody DlRepairTicketsRespVO ticketsRespVO) {
        return CommonResult.success(dlRepairTicketsService.createTickets(ticketsRespVO));
    }

    /**
     * 维修工单表 分页
     *
     * @param repairTicketsReqVO 查询对象
     * @param pageNo             页码
     * @param pageSize           条数
     * @author 小李
     * @date 20:51 2024/9/20
     **/
    @GetMapping("/page")
    @Operation(summary = "维修工单表 分页")
    public CommonResult<?> getTicketsPage(DlRepairTicketsReqVO repairTicketsReqVO,
                                          @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                          @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<DlRepairTickets> page = new Page<>(pageNo, pageSize);
        return success(dlRepairTicketsService.getTicketsPage(repairTicketsReqVO, page));
    }

    /**
     * 获得一个工单的详细信息
     *
     * @param id 工单ID
     * @param ifApp 是否是APP发起的查询
     * @author 小李
     * @date 16:05 2024/9/21
     **/
    @GetMapping("/get")
    @Operation(summary = "查看一个工单的详细信息")
    public CommonResult<?> getTicketsById(@RequestParam("id") String id,@RequestParam(required = false, value = "ifApp", defaultValue = "false")Boolean ifApp) {
        return success(dlRepairTicketsService.getTicketsById(id,ifApp));
    }

    /**
     * 查工单主表信息
     * @author vinjor-M
     * @date 14:12 2025/1/8
     * @param id 工单ID
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
    **/
    @GetMapping("/getById")
    @Operation(summary = "查工单主表信息")
    public CommonResult<?> getById(@RequestParam("id") String id) {
        DlRepairTickets repairTickets = dlRepairTicketsService.getById(id);
        DlRepairTicketsRespVO respVO = new DlRepairTicketsRespVO();
        org.springframework.beans.BeanUtils.copyProperties(repairTickets,respVO);
        CustomerMain customerMain = customerMainService.getById(repairTickets.getUserId());
        respVO.setCustomerInfo(customerMain);
        return success(respVO);
    }

    /**
     * 维修工单表 更新
     * @author vinjor-M
     * @date 14:42 2025/1/8
     * @param repairTickets 工单ID
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
    **/
    @PostMapping("/updateById")
    @Operation(summary = "维修工单表 更新")
    public CommonResult<?> updateById(@RequestBody DlRepairTicketsRespVO repairTickets) {
        //更新客户表
        CustomerMain customerMain = new CustomerMain();
        customerMain.setId(repairTickets.getUserId());
        customerMain.setCusName(repairTickets.getUserName());
        customerMain.setDataFrom(repairTickets.getCusFrom());
        customerMain.setPhoneNumber(repairTickets.getUserMobile());
        customerMainService.updateById(customerMain);
        //更新车辆表
        CarMain carMain = new CarMain();
        carMain.setId(repairTickets.getCarId());
        //保养日期
        if(null!=repairTickets.getMaintenanceDate()){
            carMain.setMaintenanceDate(repairTickets.getMaintenanceDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        }
        //保养里程
        if(null!=repairTickets.getMaintenanceMileage()) {
            carMain.setMaintenanceMileage(repairTickets.getMaintenanceMileage());
        }
        //下次年检日期
        if(null!=repairTickets.getNextInspectionDate()) {
            carMain.setNextInspectionDate(repairTickets.getNextInspectionDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        }
        //保险到期日期
        if(null!=repairTickets.getInsuranceExpiryDate()) {
            carMain.setInsuranceExpiryDate(repairTickets.getInsuranceExpiryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        }
        //保险公司名称
        if(null!=repairTickets.getInsuranceName()) {
            carMain.setInsuranceName(repairTickets.getInsuranceName());
        }
        //承保险种,多个英文逗号隔开
        if(null!=repairTickets.getInsuranceType()) {
            carMain.setInsuranceType(repairTickets.getInsuranceType());
        }
        if(null!=repairTickets.getJiaoqiang()) {
            carMain.setJiaoqiang(repairTickets.getJiaoqiang());
        }
        if(null!=repairTickets.getShangye()) {
            carMain.setShangye(repairTickets.getShangye());
        }
        carMainService.updateById(carMain);
        //最后记录操作日志--创建工单
        repairRecordsService.saveRepairRecord(repairTickets.getId(), null, RecordTypeEnum.XGGD.getCode(), "修改工单", repairTickets.getImage());
        return CommonResult.success(dlRepairTicketsService.updateById(repairTickets));
    }

    /**
     * 维修工单表 作废
     *
     * @param repairTicketsReqVO 工单对象
     * @author 小李
     * @date 19:46 2024/9/22
     **/
    @PostMapping("/void")
    @Operation(summary = "维修工单表 作废")
    public CommonResult<?> setTicketsVoid(@RequestBody DlRepairTicketsReqVO repairTicketsReqVO) {
        dlRepairTicketsService.setTicketsVoid(repairTicketsReqVO);
        return CommonResult.ok();
    }

    /**
     * 维修工单表 收款
     *
     * @param repairTicketsRespVO 工单
     * @author 小李
     * @date 8:50 2024/9/23
     **/
    @PostMapping("/paid")
    @Operation(summary = "维修工单表 收款")
    public CommonResult<?> setTicketsPaid(@RequestBody DlRepairTicketsRespVO repairTicketsRespVO) {
        dlRepairTicketsService.setTicketsPaid(repairTicketsRespVO);
        return CommonResult.ok();
    }

    /**
     * 维修工单表 结算
     *
     * @param vo 工单
     * @author 小李
     * @date 8:50 2024/9/23
     **/
    @PostMapping("/settlement")
    @Operation(summary = "维修工单表 结算")
    public CommonResult<?> setTicketsSettlement(@RequestBody TicketsSettlementVO vo) {
        dlRepairTicketsService.setTicketsSettlement(vo);
        return CommonResult.ok();
    }

    /**
     * @Author 许
     * @Description 结算审批
     * @Date 13:43 2025/8/20
     * @Param [vo]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/

    @PostMapping("/settlementReview")
    @Operation(summary = "维修工单表 结算")
    public CommonResult<?> settlementReview(@RequestBody TicketsSettlementVO vo) {
        dlRepairTicketsService.settlementReview(vo);
        return CommonResult.ok();
    }

    /**
     * @Author 许
     * @Description 查询审批金额
     * @Date 14:20 2025/8/20
     * @Param [repairTicketsReqVO]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/getSettlement")
    public CommonResult<?> getSettlement(DlRepairTicketsReqVO repairTicketsReqVO) {
        return CommonResult.success(dlRepairTicketsService.getSettlement(repairTicketsReqVO));
    }

//    /**
//     * 维修工单表 导出
//     *
//     * @param file 导出文件
//     * @author lzt
//     * @date 2024年10月11日
//     */
//    @PostMapping("/print")
//    @Operation(summary = "维修工单表 导出")
//    public ResponseEntity<Result<FileInfo>> printDocument(@RequestParam("file") MultipartFile file) {
//        if (file.isEmpty()) {
//            return ResponseEntity.badRequest().body(new Result<>(null, "文件不能为空"));
//        }
//
//        try {
//            FileDO fileInfo = fileService.createFileDetail(file.getOriginalFilename(), "/ticket", IoUtil.readBytes(file.getInputStream()));
//            return ResponseEntity.ok(new Result<>(fileInfo, "文件上传成功"));
//        } catch (Exception e) {
//            return ResponseEntity.status(500).body(new Result<>(null, "文件上传失败: " + e.getMessage()));
//        }
//    }

    /**
     * 维修工单打印
     *
     * @param response HttpServletResponse
     * @param id       维修工单id
     * @author PQZ
     * @date 13:48 2024/10/12
     **/
    @GetMapping("/print/{id}")
    @Operation(summary = "维修工单打印")
    public void printDocument(HttpServletResponse response, @PathVariable String id) {
        dlRepairTicketsService.print(response, id);
    }

    /**
     * 客户信息和车辆信息 新增、修改
     *
     * @param customerAndCarVO 用户信息和车辆信息
     * @author 小李
     * @date 9:25 2024/10/8
     **/
    @PostMapping("/updateUserAndCar")
    @Operation(summary = "客户信息和车辆信息 新增、修改")
    public CommonResult<?> updateCustomerAndCar(@RequestBody CustomerAndCarVO customerAndCarVO) {
        dlRepairTicketsService.updateCustomerAndCar(customerAndCarVO);
        return CommonResult.ok();
    }

    /**
     * 分类查询工单分页
     *
     * @param repairTicketsReqVO 查询对象
     * @param pageNo             页码
     * @param pageSize           条数
     * @author 小李
     * @date 16:26 2024/10/12
     **/
    @GetMapping("/pageType")
    @Operation(summary = "分类查询工单分页")
    public CommonResult<?> getPageType(DlRepairTicketsReqVO repairTicketsReqVO,
                                       @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<DlRepairTickets> page = new Page<>(pageNo, pageSize);
        if (StringUtils.isEmpty(repairTicketsReqVO.getSelectType())) {
            //查询类型为空，默认查待处理的
            repairTicketsReqVO.setSelectType(RepairCons.TICKETS_WAITING);
        }
        return success(dlRepairTicketsService.getPageType(repairTicketsReqVO, page));
    }

    /**
     * 判断登录用户的角色，针对维修工单中的四个角色
     *
     * @author 小李
     * @date 9:28 2024/10/14
     **/
    @GetMapping("/userRole")
    @Operation(summary = "判断登录用户的角色，针对维修工单中的四个角色")
    public CommonResult<?> getUserRole() {
        return success(dlRepairTicketsService.getUserRole());
    }

    /**
     * 接单
     *
     * @param id 工单ID
     * @author 小李
     * @date 11:48 2024/10/14
     **/
    @GetMapping("/take")
    @Operation(summary = "接单")
    public CommonResult<?> updateTake(@RequestParam("id") String id,
                                      @RequestParam(value="image",required = false) String image,
                                      @RequestParam(value="remark",required = false) String remark) {
        dlRepairTicketsService.updateTake(id,image);
        return CommonResult.ok();
    }

    /**
     * 指派员工，通知施工
     *
     * @param reqVO 请求对象
     * @author 小李
     * @date 15:34 2024/10/14
     **/
    @PostMapping("/notify")
    @Operation(summary = "指派员工，通知施工")
    public CommonResult<?> updateRepair(@RequestBody DlRepairTicketsReqVO reqVO) {
        dlRepairTicketsService.updateRepair(reqVO);
        return CommonResult.ok();
    }

    /**
     * 更新工单状态
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 15:46 2024/10/18
     **/
    @PostMapping("/updateStatus")
    @Operation(summary = "更新工单状态")
    public CommonResult<?> updateStatus(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.updateStatus(respVO);
        return CommonResult.ok();
    }

    /**
     * 配件客户是否可见
     *
     * @param id   工单ID
     * @param show 是否可见
     * @author 小李
     * @date 21:52 2024/10/18
     **/
    @GetMapping("/show")
    @Operation(summary = "配件客户是否可见")
    public CommonResult<?> updateShow(@RequestParam("id") String id, @RequestParam("show") String show) {
        dlRepairTicketsService.updateShow(id, show);
        return CommonResult.ok();
    }

    /**
     * 查待总检或待出厂检验的工单
     * 维修服务顾问和总检用的
     *
     * @param repairTicketsReqVO 请求对象
     * @param pageNo             页码
     * @param pageSize           条数
     * @author 小李
     * @date 11:40 2024/10/23
     **/
    @GetMapping("/pageByRole")
    @Operation(summary = "查待总检或待出厂检验的工单")
    public CommonResult<?> getPageByRole(DlRepairTicketsReqVO repairTicketsReqVO,
                                         @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                         @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<DlRepairTickets> page = new Page<>(pageNo, pageSize);
        return success(dlRepairTicketsService.getPageByRole(repairTicketsReqVO, page));
    }

    /**
     * 维修总检完成总检
     *
     * @author 小李
     * @date 16:48 2024/10/23
     * @param respVO 请求对象
    **/
    @PostMapping("/inspection")
    @Operation(summary = "维修总检完成总检")
    public CommonResult<?> inspection(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.inspection(respVO);
        return CommonResult.ok();
    }

    /**
     * 服务顾问上传出厂检验日志
     *
     * @author 小李
     * @date 17:47 2024/10/23
     * @param respVO 请求对象
    **/
    @PostMapping("/confirm")
    @Operation(summary = "服务顾问上传出厂检验日志")
    public CommonResult<?> confirm(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.confirm(respVO);
        return CommonResult.ok();
    }

    /**
     * 服务顾问交车
     * @author vinjor-M
     * @date 16:51 2024/11/13
     * @param respVO
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
    **/
    @PostMapping("/overOrder")
    @Operation(summary = "服务顾问交车")
    public CommonResult<?> overOrder(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.overOrder(respVO);
        return CommonResult.ok();
    }
    /**
     * 从总检的角度查进场数、维修中、已完成、已交车、在厂的工单数量
     * @author vinjor-M
     * @date 11:29 2024/10/24
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
    **/
    @GetMapping("/getBossNum")
    @Operation(summary = "从总检的角度查进场数、维修中、已完成、已交车、在厂的工单数量")
    public CommonResult<?> getBossNum(String selectType,String startDate,String endDate) {
        return success(dlRepairTicketsService.getBossNum(selectType, startDate, endDate));
    }

    /**
     * @Author 许
     * @Description  数据统计-新版
     * @Date 10:53 2025/9/1
     * @Param [startDate, endDate]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/getBossNumNew")
    @Operation(summary = "从总检的角度查进场数、维修中、已完成、已交车、在厂的工单数量")
    public CommonResult<?> getBossNumNew(@RequestParam(value = "dateRange[0]", required = false) String startDate,
                                         @RequestParam(value = "dateRange[1]", required = false) String endDate) {
        return success(dlRepairTicketsService.getBossNum(startDate, endDate));
    }

    /**
     * @Author 许
     * @Description  统计详情-细分工单类型
     * @Date 14:14 2025/9/3
     * @Param [startDate, endDate]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/getBossNumStatistics")
    public CommonResult<?> getBossNumStatistics(@RequestParam(value = "dateRange[0]", required = false) String startDate,
                                         @RequestParam(value = "dateRange[1]", required = false) String endDate) {
        return success(dlRepairTicketsService.getBossNumStatistics(startDate, endDate));
    }

    /**
     * 获取日期范围
     * @author vinjor-M
     * @date 11:29 2024/10/24
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/getDateRange")
    @Operation(summary = "获取日期范围")
    public CommonResult<?> getDateRange(String selectType) {
        Map<String,String> rtnMap = new HashMap<>();
        // 获取当前日期
        Date currentDate = new Date();
        String nowDay = DateUtil.formatDate(new Date());
        rtnMap.put("endDate",nowDay);
        if("threeMonth".equals(selectType)){
            //近3个月
            // 使用Hutool的DateUtil推移3个月
            Date threeMonthsAgo = DateUtil.offsetMonth(currentDate, -3);
            String startDay = DateUtil.formatDate(threeMonthsAgo);
            rtnMap.put("startDate",startDay);
        }else {
            //近6个月
            // 使用Hutool的DateUtil推移6个月
            Date threeMonthsAgo = DateUtil.offsetMonth(currentDate, -6);
            String startDay = DateUtil.formatDate(threeMonthsAgo);
            rtnMap.put("startDate",startDay);
        }
        return success(rtnMap);
    }

    /**
     * 服务顾问通知客户取车
     *
     * @author 小李
     * @date 22:40 2024/10/23
     * @param noticeCusVO 请求对象
    **/
    @PostMapping("/noticeCus")
    @Operation(summary = "服务顾问通知客户取车")
    public CommonResult<?> noticeCus(@RequestBody NoticeCusVO noticeCusVO) {
        dlRepairTicketsService.noticeCus(noticeCusVO);
        return CommonResult.ok();
    }

    /**
     * 判断是否工单子表的任何一个类目没有价格或价格为0
     *
     * @param id 工单ID
     * @author 小李
     * @date 15:00 2024/11/16
     **/
    @GetMapping("/hasPrice")
    @Operation(summary = "判断是否工单子表的任何一个类目没有价格或价格为0")
    public CommonResult<?> hasPrice(@RequestParam("id")String id){
        return success(dlRepairTicketsService.hasPrice(id));
    }

    /**
     * 新增工单子项
     *
     * @author 小李
     * @date 19:59 2024/10/24
     * @param respVO 主要有两个参数，主表ID,itemList(这个需要前端处理成子表的对象能接收的数据)
    **/
    @PostMapping("/addItems")
    @Operation(summary = "新增工单子项")
    public CommonResult<?> addItems(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.addItems(respVO);
        return CommonResult.ok();
    }

    /**
     * 修改工单主表，只是主表
     *
     * @author 小李
     * @date 10:25 2024/10/30
     * @param respVO 请求对象
    **/
    @PostMapping("/updateTicket")
    @Operation(summary = "修改工单主表，只是主表")
    public CommonResult<?> updateTicket(@RequestBody DlRepairTicketsRespVO respVO) {
        dlRepairTicketsService.updateTicket(respVO);
        return CommonResult.ok();
    }

    /**
     * 删除工单
     *
     * @author 小李
     * @date 20:05 2024/11/1
     * @param id 工单ID
    **/
    @DeleteMapping("/remove")
    @Operation(summary = "删除工单")
    public CommonResult<?> removeTicketById(@RequestParam("id") String id) {
        dlRepairTicketsService.removeTicketById(id);
        return CommonResult.ok();
    }

    /**
     * 根据工单ID查客户和车辆信息
     *
     * @author 小李
     * @date 19:07 2024/11/18
     * @param id id
    **/
    @GetMapping("/getCusAndCarById")
    @Operation(summary = "根据工单ID查客户和车辆信息")
    public CommonResult<?> getCusAndCarById(@RequestParam("id") String id) {
        return success(dlRepairTicketsService.getCusAndCarById(id));
    }

    /**
     * @Author 许
     * @Description  工单统计
     * @Date 15:53 2025/8/19
     * @Param [repairTicketsReqVO]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/getStatistics")
    public CommonResult<?> getStatistics(DlRepairTicketsReqVO repairTicketsReqVO) {
        return success(dlRepairTicketsService.getStatistics(repairTicketsReqVO));
    }

    /**
     * 导出数据
     *
     * @author 小李
     * @date 14:51 2024/12/3
     * @param repairTicketsReqVO 请求对象
    **/
    @GetMapping("/export")
    @Operation(summary = "导出数据")
    public void exportData(DlRepairTicketsReqVO repairTicketsReqVO, HttpServletResponse response)throws IOException {
        int pageNo = 1, pageSize = 1000;
        Page<DlRepairTickets> page = new Page<>(pageNo, pageSize);
        if (StringUtils.isEmpty(repairTicketsReqVO.getSelectType())) {
            //查询类型为空，默认查待处理的
            repairTicketsReqVO.setSelectType(RepairCons.TICKETS_WAITING);
        }
        List<TicketsExportVO> list = new ArrayList<>();
        do {
            IPage<DlRepairTickets> pageType = dlRepairTicketsService.getPageType(repairTicketsReqVO, page);
            List<DlRepairTickets> records = pageType.getRecords();
            if (CollUtil.isEmpty(records)){
                break;
            }
            List<TicketsExportVO> convertedRecords = records.stream().map(item -> BeanUtils.toBean(item, TicketsExportVO.class)).collect(Collectors.toList());
            list.addAll(convertedRecords);
            pageNo++;
            page.setCurrent(pageNo);
        }while (true);
        if (CollUtil.isEmpty(list)){
            throw exception0(500, "没有数据可以导出");
        }

        Map<String, Object> statistics = dlRepairTicketsService.getStatistics(repairTicketsReqVO);

        List<DictDataRespDTO> dictDataList = dictDataApi.getDictDataList(RepairDictConstants.REPAIR_TYPE);
        // 转换map
        Map<String, String> repairTypeMap = dictDataList.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));

        List<List<String>> rows = new ArrayList<>();

        // 第一行可以写汇总信息或标题行
        String totalLaborPartsMoney = statistics.get("totalLaborPartsMoney") != null ? statistics.get("totalLaborPartsMoney").toString() : "0";
        String totalProfit = statistics.get("totalProfit") != null ? statistics.get("totalProfit").toString() : "0";
        String profitRateWithLabor = statistics.get("profitRateWithLabor") != null ? formatPercentage(statistics.get("profitRateWithLabor").toString()) : "0%";
        String profitRateWithoutLabor = statistics.get("profitRateWithoutLabor") != null ? formatPercentage(statistics.get("profitRateWithoutLabor").toString()) : "0%";


        boolean hasAnyPermissions = permissionApi.hasAnyPermissions(SecurityFrameworkUtils.getLoginUserId(), "repair:tick:profit");
        if (hasAnyPermissions) {
            rows.add(CollUtil.newArrayList(
                    "产值：", totalLaborPartsMoney,
                    "毛利：", totalProfit,
                    "含工时毛利率：", profitRateWithLabor,
                    "不含工时毛利率：", profitRateWithoutLabor));
        }

        // 第二行写表头
        rows.add(CollUtil.newArrayList("订单编号","维修类别", "客户名称", "车牌号", "车系", "手机号", "经办人姓名", "经办人电话"));

        // 后面循环写数据
        for (TicketsExportVO item : list) {
            rows.add(CollUtil.newArrayList(
                    item.getTicketNo(),
                    repairTypeMap.get(item.getRepairType()),
                    item.getUserName(),
                    item.getCarNo(),
                    item.getCarBrandName(),
                    item.getUserMobile(),
                    item.getHandleName(),
                    item.getHandleMobile()
            ));
        }

        ExcelUtils.exportExcel("维修工单", rows, CollUtil.newArrayList(3), response);
    }


    /**
     * 导出数据 根据工单状态
     *
     * @author 小李
     * @date 15:19 2024/12/3
     * @param repairTicketsReqVO 请求对象
    **/
    @GetMapping("/exportByStatus")
    @Operation(summary = "导出数据 根据工单状态")
    public void exportByStatus(DlRepairTicketsReqVO repairTicketsReqVO, HttpServletResponse response)throws IOException{
        int pageNo = 1, pageSize = 1000;
        List<TicketExportByStatusVO> list = new ArrayList<>();
        Page<DlRepairTickets> page = new Page<>(pageNo, pageSize);
        do {
            IPage<DlRepairTickets> ticketsPage = dlRepairTicketsService.getTicketsPage(repairTicketsReqVO, page);
            List<DlRepairTickets> records = ticketsPage.getRecords();
            if (CollUtil.isEmpty(records)){
                break;
            }
            List<TicketExportByStatusVO> convertedRecords = records.stream().map(item -> BeanUtils.toBean(item, TicketExportByStatusVO.class)).collect(Collectors.toList());
            list.addAll(convertedRecords);
            pageNo++;
            page.setCurrent(pageNo);
        }while (true);
        if (CollUtil.isEmpty(list)){
            throw exception0(500, "没有数据可以导出");
        }
        String name = "";
        switch (repairTicketsReqVO.getTicketsStatus()){
            case "01":
                name = "待结算工单数据.xls";
                break;
            case "02":
                name = "已结算工单数据.xls";
                break;
            case "03":
                name = "已作废工单数据.xls";
                break;
        }
        ExcelUtils.write(response, name, "数据", TicketExportByStatusVO.class, list);
    }

    /**
     * @Author 许
     * @Description //TODO 接车
     * @Date 14:06 2025/8/13
     * @Param [id, image, remark]
     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
     **/
    @GetMapping("/pickCar")
    public CommonResult<?> pickCar(@RequestParam("id") String id,
                                   @RequestParam(value="image",required = false) String image,
                                   @RequestParam(value="remark",required = false) String remark){
        dlRepairTicketsService.pickCar(id,image,remark);
        return CommonResult.ok();
    }

    /**
     * 格式化为百分比字符串
     * @param value 值
     * @return 百分比格式字符串
     */
    private String formatPercentage(String value) {
        try {
            double rate = Double.parseDouble(value);
            return String.format("%.2f%%", rate * 100);
        } catch (NumberFormatException e) {
            return "0.00%";
        }
    }
}

