package com.ghy.web.controller.order;

import com.ghy.common.annotation.Log;
import com.ghy.common.constant.UserConstants;
import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.core.page.TableDataInfo;
import com.ghy.common.enums.*;
import com.ghy.common.utils.*;
import com.ghy.common.utils.poi.ExcelUtil;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.domain.CustomerAddress;
import com.ghy.customer.service.CustomerAddressService;
import com.ghy.customer.service.CustomerService;
import com.ghy.goods.domain.*;
import com.ghy.goods.service.*;
import com.ghy.order.domain.*;
import com.ghy.order.request.OrderProcessRequest;
import com.ghy.order.service.*;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
import com.ghy.system.service.IWxMsgService;
import com.ghy.web.pojo.vo.OrderChangePriceRequest;
import com.ghy.web.pojo.vo.OrderListResponse;
import com.ghy.web.pojo.vo.OrderStandard;
import com.ghy.web.service.InsuranceService;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.domain.WorkerCertification;
import com.ghy.worker.service.IWorkerCertificationService;
import com.ghy.worker.service.WorkerService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 详细订单API
 *
 * @author HH 2022/4/25
 */
@Controller
@RequestMapping("/order/detail")
public class OrderDetailController extends BaseController {

    private final String prefix = "order/detail";

    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderMasterService orderMasterService;
    @Resource
    private CustomerService customerService;
    @Resource
    private WorkerService workerService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private CustomerAddressService addressService;
    @Resource
    private ISysAreaService sysAreaService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private GoodsImgsService goodsImgsService;
    @Resource
    private GoodsStandardService goodsStandardService;
    @Resource
    private FinancialDetailService financialDetailService;
    @Resource
    private IAfterServiceRecordService afterServiceRecordService;
    @Resource
    private FinancialChangeRecordService financialChangeRecordService;
    @Resource
    private IWorkerCertificationService workerCertificationService;
    @Resource
    private IOrderAssessLabelService orderAssessLabelService;
    @Resource
    private FinancialMasterService financialMasterService;
    @Resource
    private OrderBehaviorService orderBehaviorService;
    @Resource
    private IWxMsgService wxMsgService;
    @Resource
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private IOrderCallRecordService orderCallRecordService;
    @Resource
    private DeptGoodsCategoryService deptGoodsCategoryService;
    @Resource
    private GoodsCategoryService goodsCategoryService;

    @Resource
    private IInsuranceManagerService insuranceManagerService;
    @Autowired
    private InsuranceService insuranceService;

    @RequiresPermissions("order:detail:view")
    @GetMapping()
    public String orderDetail() {
        return prefix;
    }

    //    @RequiresPermissions("order:detail:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(OrderDetail orderDetail) {
        if (orderDetail.getSearchAfterList() !=null && orderDetail.getSearchAfterList()) {
            List<?> rows = this.afterServiceList(orderDetail).getRows();
            StringBuilder detailIds = new StringBuilder();
            if(CollectionUtils.isNotEmpty(rows)){
                rows.forEach(model->{
                    OrderListResponse response = (OrderListResponse)model;
                    detailIds.append(response.getOrderDetailId()).append(",");
                });
            }
            String ids = detailIds.toString();
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(ids)) {
                orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1));
            }
        }

        if(StringUtils.isNotEmpty(orderDetail.getWorkerName()) || StringUtils.isNotEmpty(orderDetail.getWorkerPhone())){
            Worker param = new Worker();
            param.setName(orderDetail.getWorkerName());
            param.setPhone(orderDetail.getWorkerPhone());
            List<Worker> workList = workerService.getWorkList(param);
            List<Long> ids = workList.stream().map(Worker::getWorkerId).collect(Collectors.toList());
            orderDetail.setWorkerIds(ids);
            if(CollectionUtils.isEmpty(ids)){
                return getDataTable(new ArrayList<>());
            }
        }
        if(orderDetail.getSysPayStatus() != null){
            FinancialMaster param = new FinancialMaster();
            param.setPayStatus(orderDetail.getSysPayStatus());
            List<FinancialMaster> financialMasters = financialMasterService.selectFinancialMasterList(param);
            List<Long> masterIds = financialMasters.stream().map(FinancialMaster::getOrderMasterId).collect(Collectors.toList());
            orderDetail.setMasterIds(masterIds);
            if(CollectionUtils.isEmpty(masterIds)){
                return getDataTable(new ArrayList<>());
            }
        }
        startPage();
        if (this.getSysUser().getDept().getParentId() != 101) {
            orderDetail.setDeptId(this.getSysUser().getDept().getParentId());
        }
        List<OrderDetail> orderDetails = orderDetailService.selectOrderDetailList(orderDetail);

        Set<Long> customerIds = orderDetails.stream().map(OrderDetail::getCustomerId).collect(Collectors.toSet());
        Map<Long, Customer> customerMap = customerService.selectByIds(customerIds)
                .stream().collect(Collectors.toMap(Customer::getCustomerId, x -> x, (x, y) -> y));

        Set<Long> orderMasterIds = orderDetails.stream().map(OrderDetail::getOrderMasterId).collect(Collectors.toSet());
        List<OrderMaster> orderMasters = orderMasterService.selectByIds(orderMasterIds);
        Map<Long, OrderMaster> orderMasterMap = orderMasters.stream().collect(Collectors.toMap(OrderMaster::getId, x -> x, (x, y) -> y));

        List<FinancialMaster> financialMasters = financialMasterService.selectByOrderMasterIds(orderMasterIds);
        Map<Long, FinancialMaster> financialMasterMap = financialMasters
                .stream().collect(Collectors.toMap(FinancialMaster::getOrderMasterId, x -> x, (x, y) -> y));

        Set<Long> orderDetailIds = orderDetails.stream().map(OrderDetail::getId).collect(Collectors.toSet());
        Map<Long, FinancialDetail> financialDetailMap = financialDetailService.selectByOrderDetailIds(orderDetailIds)
                .stream().collect(Collectors.toMap(FinancialDetail::getOrderDetailId, x -> x, (x, y) -> y));

        Map<Long, FinancialChangeRecord> fcMap = financialChangeRecordService.selectByOrderDetailIds(orderDetailIds)
                .stream().collect(Collectors.toMap(FinancialChangeRecord::getOrderDetailId, x -> x, (x, y) -> y));


        Set<Long> goodsIds = orderMasters.stream().map(OrderMaster::getGoodsId).collect(Collectors.toSet());
        List<Goods> goods = goodsService.selectByIds(goodsIds);
        Map<Long, Goods> goodsMap = goods.stream().collect(Collectors.toMap(Goods::getGoodsId, x -> x, (x, y) -> y));

        Set<Long> workerIds = orderDetails.stream().map(OrderDetail::getWorkerId).collect(Collectors.toSet());
        workerIds.addAll(goods.stream().map(Goods::getWorkerId).collect(Collectors.toSet()));
        Map<Long, Worker> workerMap = workerService.selectByIds(workerIds)
                .stream().collect(Collectors.toMap(Worker::getWorkerId, x -> x, (x, y) -> y));

        for (OrderDetail detail : orderDetails) {
            if(StringUtils.isNotEmpty(orderDetail.getOrderStatusName())){
                detail.setOrderStatusName(orderDetail.getOrderStatusName());
            }
            Customer customer = customerMap.get(detail.getCustomerId());
            detail.setWorker(workerMap.get(detail.getWorkerId()));
            if (customer != null) {
                detail.setCustomerName(customer.getName());
                detail.setCustomerPhone(customer.getPhone());
            }
            OrderMaster orderMaster = orderMasterMap.get(detail.getOrderMasterId());
            if(orderMaster.getExpectTimeStart() != null && orderMaster.getExpectTimeEnd() != null){
                detail.setMixExpectTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",orderMaster.getExpectTimeStart()) +"-"+ DateUtils.parseDateToStr("HH:mm",orderMaster.getExpectTimeEnd()));
            }
            if (orderMaster != null) {
                detail.setPayStatus(orderMaster.getPayStatus());
                detail.setPayType(orderMaster.getPayType());
                detail.setPayTime(orderMaster.getPayTime());
                FinancialMaster fm = financialMasterMap.get(detail.getOrderMasterId());
                if (fm != null) {
                    detail.setFinancialMasterMoney(fm.getPayMoney());
                }
                Goods good = goodsMap.get(orderMaster.getGoodsId());
                if (good != null) {
                    detail.setGoods(good);
                    // 填充商品三级类目
                    if(good.getDeptGoodsCategoryId() != null){
                        Long categoryId = null;
                        // 前端发单和后台派单
                        if(StringUtils.isEmpty(orderMaster.getOrderMode())){
                            DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(good.getDeptGoodsCategoryId());
                            if(deptGoodsCategory != null){
                                categoryId = deptGoodsCategory.getGoodsCategoryId();
                            }
                        }else {
                            DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(good.getDeptGoodsCategoryId());
                            if(deptGoodsCategory != null){
                                categoryId = deptGoodsCategory.getGoodsCategoryId();
                            }
                        }
                        if(categoryId != null){
                            GoodsCategory one = goodsCategoryService.selectById(categoryId);
                            if(one != null && one.getParentCategoryId() != null){
                                GoodsCategory two = goodsCategoryService.selectById(one.getParentCategoryId());
                                if(two != null && two.getParentCategoryId() != null){
                                    GoodsCategory three = goodsCategoryService.selectById(two.getParentCategoryId());
                                    if(three != null){
                                        int totalNum = orderGoodsService.selectByOrderDetailId(detail.getId()).stream().mapToInt(OrderGoods::getGoodsNum).sum();
                                        detail.setConsoleGoodsName("【" + three.getGoodsCategoryName()
                                                + "-" + two.getGoodsCategoryName()
                                                + "-" + one.getGoodsCategoryName() + "】x" + totalNum);
                                    }
                                }
                            }
                        }
                    }
                    detail.setGoodsWorker(workerMap.get(orderMaster.getWorkerId()));
                }
                // 地址信息
                CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
                if (customerAddress != null) {
                    SysArea sysArea;
                    if(customerAddress.getStreetId()!=null){
                        sysArea = sysAreaService.selectById(customerAddress.getStreetId());
                    }else {
                        sysArea = sysAreaService.selectById(customerAddress.getCountryId());
                    }
                    String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();
                    detail.setAddressName(customerAddress.getName());
                    detail.setAddressPhone(customerAddress.getPhone());
                    detail.setAddress(completeAddress);
                }
            }
            FinancialDetail fd = financialDetailMap.get(detail.getId());
            if (fd != null) {
                detail.setFinancialDetailMoney(fd.getPayMoney());
            }
            OrderCallRecord orderCallRecordParam = new OrderCallRecord();
            orderCallRecordParam.setOrderType("01");
            orderCallRecordParam.setOrderId(detail.getOrderMasterId());
            List<OrderCallRecord> orderCallRecords = orderCallRecordService.selectOrderCallRecordList(orderCallRecordParam);
            if(CollectionUtils.isNotEmpty(orderCallRecords)){
                OrderCallRecord newOne = orderCallRecords.stream().sorted(Comparator.comparing(OrderCallRecord::getCallTime).reversed()).collect(Collectors.toList()).get(0);
                detail.setLastCallTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",newOne.getCallTime()) + " 拨号次数x" + orderCallRecords.size());
            }
            FinancialChangeRecord fc = fcMap.get(detail.getId());
            if (fc != null) {
                detail.setChangeMoney(fc.getChangeMoney());
            }
            // 完单图片
            GoodsImgs param = new GoodsImgs();
            param.setRemark(String.valueOf(detail.getId()));
            param.setImgType(ImgType.FINISH_IMG.getId());
            List<GoodsImgs> imgsList = goodsImgsService.qryGoodsImgs(param);
            StringBuilder stringBuilder = new StringBuilder();
            imgsList.forEach(model->{
                stringBuilder.append("<a target='_blank' href='").append(model.getImgUrl()).append("' >查看图片<a/>");
            });
            detail.setOrderImgs(stringBuilder.toString());
        }

        return getDataTable(orderDetails);
    }

    /**
     * 查询每种订单状态有多少数量
     */
    @GetMapping("/status/count")
    @ResponseBody
    public AjaxResult statusCount() {
        List<OrderStatusCount> statusCount = orderDetailService.statusCount();
        return AjaxResult.success(statusCount);
    }

    @PostMapping("/app/detail")
    @ResponseBody
    public AjaxResult appDetail(@RequestBody OrderDetail request) {
        try {
            // 子单信息
            OrderDetail detail = orderDetailService.selectById(request.getId());
            // 主单信息
            OrderMaster orderMaster = orderMasterService.selectById(detail.getOrderMasterId());
            FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = workerService.selectById(detail.getWorkerId());
            WorkerCertification workerRealInfo = null;
            String workerName = "";
            String masterWorkerName = "";
            String masterCompanyName = "";
            if (worker != null) {
                // 师傅实名信息
                workerRealInfo = workerCertificationService.selectByWorkerId(orderMaster.getWorkerId());
                workerName = workerRealInfo == null ? worker.getName() : workerRealInfo.getSurname()+ workerRealInfo.getName();
            }
            workerRealInfo = null;
            // 大师傅信息
            Worker masterWorker = workerService.selectById(orderMaster.getWorkerId());
            if (masterWorker != null) {
                // 大师傅实名信息
                workerRealInfo = workerCertificationService.selectByWorkerId(orderMaster.getWorkerId());
                masterWorkerName = workerRealInfo == null ? masterWorker.getName() : workerRealInfo.getSurname()+ workerRealInfo.getName();
                masterCompanyName = workerRealInfo == null ? null : workerRealInfo.getCompanyName();
            }

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(detail.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderDetailId(detail.getId());

            // 商品信息
//            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(orderMaster.getGoodsId());
            if (goods != null) {
                // 填充商品三级类目
                if(goods.getDeptGoodsCategoryId() != null){
                    Long categoryId = null;
                    // 前端发单和后台派单
                    if(StringUtils.isEmpty(orderMaster.getOrderMode())){
                        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(goods.getDeptGoodsCategoryId());
                        if(deptGoodsCategory != null){
                            categoryId = deptGoodsCategory.getGoodsCategoryId();
                        }
                    }else {
                        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(goods.getDeptGoodsCategoryId());
                        if(deptGoodsCategory != null){
                            categoryId = deptGoodsCategory.getGoodsCategoryId();
                        }
                    }
                    if(categoryId != null){
                        GoodsCategory one = goodsCategoryService.selectById(categoryId);
                        if(one != null && one.getParentCategoryId() != null){
                            GoodsCategory two = goodsCategoryService.selectById(one.getParentCategoryId());
                            if(two != null && two.getParentCategoryId() != null){
                                GoodsCategory three = goodsCategoryService.selectById(two.getParentCategoryId());
                                if(three != null){
                                    goods.setGoodsName(three.getGoodsCategoryName()
                                            + "-" + two.getGoodsCategoryName()
                                            + "-" + one.getGoodsCategoryName());
                                    orderListResponse.setTotalName(goods.getGoodsName());
                                }
                            }
                        }
                    }
                }
            }

            // 财务信息
            FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(detail.getId());
            BigDecimal detailPayMoney = financialDetail.getPayMoney();
            // 查询子单加价记录
//            FinancialChangeRecord changeRecordQry = new FinancialChangeRecord();
//            changeRecordQry.setOrderDetailId(detail.getId());
//            List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectFinancialChangeRecordList(changeRecordQry);
//            if (CollectionUtils.isNotEmpty(financialChangeRecords)) {
//                detailPayMoney = detailPayMoney.add(financialChangeRecords.get(0).getChangeMoney());
//            }

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
            SysArea sysArea;
            if(customerAddress.getStreetId()!=null){
                sysArea = sysAreaService.selectById(customerAddress.getStreetId());
            }else {
                sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            }
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            // 完工图片
            List<String> finishImgList = null;
            if (detail.getOrderStatus() > 3) {
                GoodsImgs qryImgsObj = new GoodsImgs();
                qryImgsObj.setRemark(request.getId().toString());
                qryImgsObj.setImgType(ImgType.FINISH_IMG.getId());
                qryImgsObj.setGoodsId(0L);
                List<GoodsImgs> goodsImgs = goodsImgsService.qryGoodsImgs(qryImgsObj);
                finishImgList = goodsImgs.stream().map(GoodsImgs::getImgUrl).collect(Collectors.toList());
            }

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                orderStandard.setServerNum(orderGoods.getServerGoodsNum() == null ? 0 : orderGoods.getServerGoodsNum());
                orderStandard.setWaitServerNum(orderStandard.getStandardNum() - orderStandard.getServerNum());
                standardList.add(orderStandard);
            }
            if (this.checkIsOnlyServer(orderMaster.getId(), orderMaster.getWorkerId())) {
                BigDecimal workerFee = financialMaster.getPayMoney();
                List<FinancialDetail> financialDetailList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
                for (FinancialDetail param : financialDetailList) {
                    if (!detail.getWorkerId().equals(param.getPayeeId())) {
                        workerFee = workerFee.subtract(param.getPayMoney());
                    }
                }
                orderListResponse.setPayMoney(workerFee);
                orderListResponse.setPayAddMoney(workerFee);
                orderListResponse.setIsOnlyServ(Boolean.TRUE);
            } else {
                orderListResponse.setPayMoney(detailPayMoney);
                orderListResponse.setPayAddMoney(detailPayMoney);
                orderListResponse.setIsOnlyServ(Boolean.FALSE);
            }

            // 售后记录
            AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
            afterServiceRecord.setOrderDetailId(detail.getId());
            List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);

            // 查询加价记录
            FinancialChangeRecord changeRecordQry = new FinancialChangeRecord();
            changeRecordQry.setOrderDetailId(detail.getId());
            List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectFinancialChangeRecordList(changeRecordQry);

            // 编辑返回属性
            orderListResponse.setOrderDetailId(detail.getId());
            orderListResponse.setOrderDetailCode(detail.getCode());
            orderListResponse.setOrderMasterId(detail.getOrderMasterId());
            orderListResponse.setOrderMasterCode(detail.getOrderMasterCode());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialDetail.getDiscountMoney());
            orderListResponse.setTotalMoney(financialDetail.getTotalMoney());
            orderListResponse.setWorkerName(workerName);
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setMasterWorkerName(masterWorkerName);
            orderListResponse.setMasterCompanyName(masterCompanyName);
            orderListResponse.setMasterWorkerPhone(masterWorker == null ? "" : masterWorker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setOrderStatus(detail.getOrderStatus());
            orderListResponse.setPayStatus(orderMaster.getPayStatus());
            orderListResponse.setPayType(orderMaster.getPayType());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setServerTime(detail.getRevTime());
            orderListResponse.setExpectTimeStart(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(detail.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(detail.getExpectTimeEnd());
            orderListResponse.setCreateTime(detail.getCreateTime());
            orderListResponse.setWorkBeginTime(detail.getWorkBeginTime());
            orderListResponse.setWorkFinishTime(detail.getWorkFinishTime());
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(orderMaster.getRemark());
            orderListResponse.setFinishImgList(finishImgList);
            orderListResponse.setWorkerRemark(detail.getRemark());
            orderListResponse.setAfterServiceRecordList(afterServiceRecordList);
            orderListResponse.setTimeout(detail.getTimeout());
            orderListResponse.setTimeoutFineTimes(detail.getTimeoutFineTimes());
            // TODO: 超时扣费
            orderListResponse.setFinancialChangeRecords(financialChangeRecords);
            orderListResponse.setInsuranceId(orderMaster.getInsuranceId());
            if(orderMaster.getInsuranceId() != null){
                InsuranceManager manager = insuranceManagerService.selectInsuranceManagerById(orderMaster.getInsuranceId());
                if(manager != null){
                    orderListResponse.setInsuranceManager(manager);
                }
            }

            if(!CollectionUtils.isEmpty(financialChangeRecords)){
                BigDecimal totalAdd = financialChangeRecords.stream().map(FinancialChangeRecord::getChangeMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
                Long goodsStandardId = orderStandardList.get(0).getGoodsStandardId();
                GoodsStandard standard = goodsStandardService.selectById(goodsStandardId);
                // 第四级规格
                DeptGoodsCategory childCategory = deptGoodsCategoryService.get(standard.getDeptGoodsCategoryId());
                // 需要找第三级规格
                DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(childCategory.getParentCategoryId());

                // 一级分销追加扣点
                BigDecimal saleRateOne = new BigDecimal(deptGoodsCategory.getOneRate());
                saleRateOne = MoneyUtil.lt0(saleRateOne) ? BigDecimal.ZERO : saleRateOne;

                // 二级分销追加扣点
                BigDecimal saleRateTwo = new BigDecimal(deptGoodsCategory.getTwoRate());
                saleRateTwo = MoneyUtil.lt0(saleRateTwo) ? BigDecimal.ZERO : saleRateTwo;

                // 三级分销追加扣点
                BigDecimal saleRateThree = new BigDecimal(deptGoodsCategory.getThreeRate());
                saleRateThree = MoneyUtil.lt0(saleRateThree) ? BigDecimal.ZERO : saleRateThree;

                // 分销扣点合计
                saleRateOne = saleRateOne.add(saleRateTwo).add(saleRateThree);

                // 大师傅提成
                BigDecimal teamRete = new BigDecimal(masterWorker.getLeaderTeamRate());
                teamRete = MoneyUtil.lt0(teamRete) ? BigDecimal.ZERO : teamRete;
                BigDecimal teamMoney = new BigDecimal(masterWorker.getLeaderTeamMoney());
                teamMoney = MoneyUtil.lt0(teamMoney) ? BigDecimal.ZERO : teamMoney;

                // 平台加价抽成
                BigDecimal deptRate = new BigDecimal(deptGoodsCategory.getDeptRate());
                deptRate = MoneyUtil.lt0(deptRate) ? BigDecimal.ZERO : deptRate;
                BigDecimal deptMoney = MoneyUtil.lt0(deptGoodsCategory.getDeptMoney()) ? BigDecimal.ZERO : deptGoodsCategory.getDeptMoney();

                // 分销抽成
                BigDecimal customerFee = totalAdd.multiply(saleRateOne).setScale(2, RoundingMode.UP);
                // 平台抽成
                BigDecimal platformFee = totalAdd.multiply(deptRate).add(deptMoney).setScale(2, RoundingMode.UP);
                // 大师傅抽成
                BigDecimal masterFee = totalAdd.multiply(teamRete).add(teamMoney).setScale(2, RoundingMode.UP);
                // 如果提成>追加金额 则去掉固定提成 只计算比例提成
                if (MoneyUtil.lt(masterFee.add(platformFee), totalAdd)) {
                    platformFee = totalAdd.multiply(deptRate).setScale(2, RoundingMode.UP);
                    masterFee = totalAdd.multiply(teamRete).setScale(2, RoundingMode.UP);
                }
                // 如果是大师傅自己接单,则不需要抽成
                if(detail.getWorkerId().equals(orderMaster.getWorkerId())){
                    masterFee = BigDecimal.ZERO;
                }
                // 上门师傅应得加价的报酬
                BigDecimal workerFee = totalAdd.subtract(platformFee).subtract(masterFee).subtract(customerFee);
                orderListResponse.setPayAddMoney(orderListResponse.getPayMoney().add(workerFee));
            }

            return AjaxResult.success(orderListResponse);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(ExceptionUtil.getExceptionMessage(e));
            return AjaxResult.error();
        }
    }

    @PostMapping("/app/list")
    @ResponseBody
    public TableDataInfo appList(@RequestBody OrderDetail orderDetail) {

        startPage();
        List<OrderListResponse> orderListResponses = new ArrayList<>();
        List<OrderDetail> list = orderDetailService.selectOrderDetailList(orderDetail);
        list.forEach(detail -> {

            // 主单信息
            OrderMaster orderMaster = orderMasterService.selectById(detail.getOrderMasterId());
            FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(orderMaster.getId());
            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = workerService.selectById(detail.getWorkerId());
            WorkerCertification workerRealInfo = null;
            String workerName = "";
            if (worker != null) {
                // 师傅实名信息
                workerRealInfo = workerCertificationService.selectByWorkerId(orderMaster.getWorkerId());
                workerName = workerRealInfo == null ? worker.getName() : workerRealInfo.getSurname()+ workerRealInfo.getName();
            }

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(detail.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderDetailId(detail.getId());

            Goods goods = goodsService.selectById(orderMaster.getGoodsId());
            // 填充商品三级类目
            if(goods.getDeptGoodsCategoryId() != null){
                Long categoryId = null;
                // 前端发单和后台派单
                if(StringUtils.isEmpty(orderMaster.getOrderMode())){
                    DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.selectOneByGoodsCategoryId(goods.getDeptGoodsCategoryId());
                    if(deptGoodsCategory != null){
                        categoryId = deptGoodsCategory.getGoodsCategoryId();
                    }
                }else {
                    DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(goods.getDeptGoodsCategoryId());
                    if(deptGoodsCategory != null){
                        categoryId = deptGoodsCategory.getGoodsCategoryId();
                    }
                }
                if(categoryId != null){
                    GoodsCategory one = goodsCategoryService.selectById(categoryId);
                    if(one != null && one.getParentCategoryId() != null){
                        GoodsCategory two = goodsCategoryService.selectById(one.getParentCategoryId());
                        if(two != null && two.getParentCategoryId() != null){
                            GoodsCategory three = goodsCategoryService.selectById(two.getParentCategoryId());
                            if(three != null){
                                goods.setGoodsName(three.getGoodsCategoryName()
                                        + "-" + two.getGoodsCategoryName()
                                        + "-" + one.getGoodsCategoryName());
                            }
                        }
                    }
                }
            }
            // 财务信息
            FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(detail.getId());
            BigDecimal detailPayMoney = financialDetail.getPayMoney();

            // 查询子单加价记录
            FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(detail.getId());
            BigDecimal changeMoney = financialChangeRecord == null ? BigDecimal.ZERO : financialChangeRecord.getChangeMoney();

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
            SysArea sysArea;
            if(customerAddress.getStreetId()!=null){
                sysArea = sysAreaService.selectById(customerAddress.getStreetId());
            }else {
                sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            }
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                orderStandard.setServerNum(orderGoods.getServerGoodsNum());
                orderStandard.setFinishTime(orderGoods.getFinishTime());
                orderStandard.setWaitServerNum(orderGoods.getGoodsNum() - orderGoods.getServerGoodsNum());
                standardList.add(orderStandard);
            }

            if (this.checkIsOnlyServer(orderMaster.getId(), detail.getWorkerId())) {
                BigDecimal workerFee = financialMaster.getPayMoney();
                List<FinancialDetail> financialDetailList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
                for (FinancialDetail param : financialDetailList) {
                    if (!detail.getWorkerId().equals(param.getPayeeId())) {
                        workerFee = workerFee.subtract(param.getPayMoney());
                    }
                }
                orderListResponse.setPayMoney(workerFee);
                orderListResponse.setIsOnlyServ(Boolean.TRUE);
            } else {
                orderListResponse.setPayMoney(detailPayMoney);
                orderListResponse.setIsOnlyServ(Boolean.FALSE);
            }

            // 售后记录
//            AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
//            afterServiceRecord.setOrderDetailId(detail.getId());
//            List<AfterServiceRecord> afterServiceRecordList  =afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);

            // 编辑返回属性
            orderListResponse.setGoodsBrand(orderMaster.getGoodsBrand());
            orderListResponse.setGoodsSpecification(orderMaster.getGoodsSpecification());
            orderListResponse.setOrderDetailId(detail.getId());
            orderListResponse.setOrderDetailCode(detail.getCode());
            orderListResponse.setOrderMasterId(detail.getOrderMasterId());
            orderListResponse.setOrderMasterCode(detail.getOrderMasterCode());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialDetail.getDiscountMoney());
            orderListResponse.setTotalMoney(financialDetail.getTotalMoney());
            orderListResponse.setWorkerName(workerName);
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setOrderStatus(detail.getOrderStatus());
            orderListResponse.setPayStatus(orderMaster.getPayStatus());
            orderListResponse.setPayType(orderMaster.getPayType());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setServerTime(detail.getRevTime());
            orderListResponse.setExpectTimeStart(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(detail.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(detail.getExpectTimeEnd());
            orderListResponse.setWorkBeginTime(detail.getWorkBeginTime());
            orderListResponse.setWorkFinishTime(detail.getWorkFinishTime());
            orderListResponse.setClockInLocation(detail.getClockInLocation());
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(orderMaster.getRemark());
            orderListResponse.setOrderType(detail.getOrderType());
            orderListResponse.setTimeout(detail.getTimeout());
            orderListResponse.setChangeMoney(changeMoney);
//            orderListResponse.setAfterServiceRecordList(afterServiceRecordList);
            orderListResponse.setUpdateTime(detail.getUpdateTime());
            orderListResponse.setShelveStatus(detail.getShelveStatus());
            orderListResponse.setLedgerAccountStatus(detail.getLedgerAccountStatus());
//            orderListResponse.setDrawCashId(detail.getDrawCashId());
            orderListResponse.setDrawCashTime(detail.getDrawCashTime());
            orderListResponse.setDrawCashStatus(detail.getDrawCashStatus());
            orderListResponse.setArrivalTime(detail.getArrivalTime());
            orderListResponse.setConsultMode(orderMaster.getConsultMode());
            orderListResponse.setInsuranceId(orderMaster.getInsuranceId());
            if(orderMaster.getInsuranceId() != null){
                InsuranceManager manager = insuranceManagerService.selectInsuranceManagerById(orderMaster.getInsuranceId());
                if(manager != null){
                    orderListResponse.setInsuranceManager(manager);
                }
            }
            orderListResponses.add(orderListResponse);
        });
        return voDataTable(orderListResponses, list);
    }

    @PostMapping("/after/list")
    @ResponseBody
    public TableDataInfo afterServiceList(@RequestBody OrderDetail orderDetail) {
        AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
        afterServiceRecord.setExcludeAfterServiceFinished(Boolean.TRUE);
        List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);
        Map<Long, List<AfterServiceRecord>> detailRecordMap = afterServiceRecordList.stream().collect(Collectors.groupingBy(record -> record.getOrderDetailId()));
        // 踢重后的子单ids
        List<Long> detailIds = afterServiceRecordList.stream().map(AfterServiceRecord::getOrderDetailId).distinct().collect(Collectors.toList());
        StringBuilder orderDetailIds = new StringBuilder();
        detailIds.forEach(id -> {
            orderDetailIds.append(id).append(",");
        });
        String ids = orderDetailIds.toString();
        if (StringUtils.isNotEmpty(ids)) {
            orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1));
        } else {
            orderDetail.setOrderDetailIds("0");
        }
        startPage();
        List<OrderListResponse> orderListResponses = new ArrayList<>();
        List<OrderDetail> list = orderDetailService.selectOrderDetailList(orderDetail);
        list.forEach(detail -> {

            // 主单信息
            OrderMaster orderMaster = orderMasterService.selectById(detail.getOrderMasterId());
            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = workerService.selectById(detail.getWorkerId());
            WorkerCertification workerRealInfo = null;
            String workerName = "";
            if (worker != null) {
                // 师傅实名信息
                workerRealInfo = workerCertificationService.selectByWorkerId(orderMaster.getWorkerId());
                workerName = workerRealInfo == null ? worker.getName() : workerRealInfo.getSurname()+ workerRealInfo.getName();
            }

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(detail.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderDetailId(detail.getId());

            // 商品信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(goodsStandard.getGoodsId());

            // 财务信息
            FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(detail.getId());
            BigDecimal detailPayMoney = financialDetail.getPayMoney();

            // 查询子单加价记录
            FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(detail.getId());
            BigDecimal changeMoney = financialChangeRecord == null ? BigDecimal.ZERO : financialChangeRecord.getChangeMoney();
            // 查询子单加价记录
//            FinancialChangeRecord changeRecordQry = new FinancialChangeRecord();
//            changeRecordQry.setOrderDetailId(detail.getId());
//            List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectFinancialChangeRecordList(changeRecordQry);
//            if (CollectionUtils.isNotEmpty(financialChangeRecords)) {
//                detailPayMoney = detailPayMoney.add(financialChangeRecords.get(0).getChangeMoney());
//            }

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
            SysArea sysArea;
            if(customerAddress.getStreetId()!=null){
                sysArea = sysAreaService.selectById(customerAddress.getStreetId());
            }else {
                sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            }
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                orderStandard.setServerNum(orderGoods.getServerGoodsNum());
                orderStandard.setFinishTime(orderGoods.getFinishTime());
                orderStandard.setWaitServerNum(orderGoods.getGoodsNum() - orderGoods.getServerGoodsNum());
                standardList.add(orderStandard);
            }

            if (this.checkIsOnlyServer(orderMaster.getId(), detail.getWorkerId())) {
                FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(detail.getOrderMasterId());
                BigDecimal workerFee = financialMaster.getPayMoney();
                List<FinancialDetail> financialDetailList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
                for (FinancialDetail param : financialDetailList) {
                    if (!detail.getWorkerId().equals(param.getPayeeId())) {
                        workerFee = workerFee.subtract(param.getPayMoney());
                    }
                }
                orderListResponse.setPayMoney(workerFee);
                orderListResponse.setIsOnlyServ(Boolean.TRUE);
            } else {
                orderListResponse.setPayMoney(detailPayMoney);
                orderListResponse.setIsOnlyServ(Boolean.FALSE);
            }


            // 编辑返回属性
            orderListResponse.setOrderDetailId(detail.getId());
            orderListResponse.setOrderDetailCode(detail.getCode());
            orderListResponse.setOrderMasterId(detail.getOrderMasterId());
            orderListResponse.setOrderMasterCode(detail.getOrderMasterCode());
            orderListResponse.setGoods(goods);
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialDetail.getDiscountMoney());
            orderListResponse.setTotalMoney(financialDetail.getTotalMoney());
            orderListResponse.setWorkerName(workerName);
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setOrderStatus(detail.getOrderStatus());
            orderListResponse.setPayStatus(orderMaster.getPayStatus());
            orderListResponse.setPayType(orderMaster.getPayType());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setServerTime(detail.getRevTime());
            orderListResponse.setExpectTimeStart(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(detail.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(detail.getExpectTimeEnd());
            orderListResponse.setWorkBeginTime(detail.getWorkBeginTime());
            orderListResponse.setWorkFinishTime(detail.getWorkFinishTime());
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(orderMaster.getRemark());
            orderListResponse.setOrderType(detail.getOrderType());
            orderListResponse.setTimeout(detail.getTimeout());
            orderListResponse.setAfterServiceRecordList(detailRecordMap.get(detail.getId()));
            orderListResponse.setChangeMoney(changeMoney);
            orderListResponses.add(orderListResponse);
        });
        return voDataTable(orderListResponses, list);
    }

    @Log(title = "详细订单管理", businessType = BusinessType.EXPORT)
    @RequiresPermissions("order:detail:export")
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(OrderDetail orderDetail) {
        List<OrderDetail> list = orderDetailService.selectOrderDetailList(orderDetail);
        ExcelUtil<OrderDetail> util = new ExcelUtil<>(OrderDetail.class);
        return util.exportExcel(list, "详细订单数据");
    }

    @RequiresPermissions("order:detail:remove")
    @Log(title = "详细订单管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        try {
            return toAjax(orderDetailService.deleteOrderDetailByIds(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 修改详细订单
     */
    @RequiresPermissions("order:detail:edit")
    @GetMapping("/edit/{orderDetailId}")
    public String edit(@PathVariable("orderDetailId") Long orderDetailId, ModelMap mmap) {
        mmap.put("orderDetail", orderDetailService.selectById(orderDetailId));
        return prefix + "/edit";
    }

    /**
     * 修改详细订单
     */
    @GetMapping("/payQrcode/{orderId}")
    public String payQrcode(@PathVariable("orderId") Long orderId, ModelMap mmap) {
        mmap.put("orderId", orderId);
        return "/order/pay-qrcode";
    }

    @GetMapping("/orderWorker/{orderId}")
    public String orderWorker(@PathVariable("orderId") Long orderId, ModelMap mmap) {
        List<Worker> workList = workerService.getWorkList(new Worker());
        mmap.put("orderId", orderId);
        mmap.put("workers", workList);
        return "order/orderWorker";
    }

    /**
     * 修改保存详细订单
     */
    @RequiresPermissions("order:detail:edit")
    @Log(title = "详细订单管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@Validated OrderDetail orderDetail) {
        if (UserConstants.ORDER_CODE_NOT_UNIQUE.equals(orderDetailService.checkOrderDetailCodeUnique(orderDetail))) {
            return error("修改详细订单'" + orderDetail.getCode() + "'失败，详细订单编码已存在");
        }
        orderDetail.setUpdateBy(getLoginName());
        return toAjax(orderDetailService.updateOrderDetail(orderDetail));
    }

    /**
     * 修改保存详细订单
     */
    @PostMapping("/app/edit")
    @ResponseBody
    public AjaxResult appEdit(@RequestBody OrderDetail orderDetail) {
        if (UserConstants.ORDER_CODE_NOT_UNIQUE.equals(orderDetailService.checkOrderDetailCodeUnique(orderDetail))) {
            return error("修改详细订单'" + orderDetail.getCode() + "'失败，详细订单编码已存在");
        }
        if (StringUtils.isNotEmpty(orderDetail.getClockInLocation())) {
            OrderDetail model = orderDetailService.selectById(orderDetail.getId());
            Customer customer = customerService.selectByCustomerId(model.getCustomerId());
            // 更新订单状态为上门
            try {
                insuranceService.clockInsurance(model.getId());
            }catch (Exception e){
                logger.error("订单上门返回异常:{}", e.getMessage());
                e.printStackTrace();
            }
            // 通知师傅新订单
            try {
                Map<String, Object> params = new HashMap<>();
                params.put("thing1", "师傅打卡通知");
                params.put("thing5", "请确认师傅已到达!");
                wxMsgService.sendWxMsg(customer.getOpenId(), WxMsgEnum.CUSTOMER_ORDER, params);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return toAjax(orderDetailService.updateOrderDetail(orderDetail));
    }

    /**
     * 校验详细订单编码
     */
    @PostMapping("/checkOrderDetailCodeUnique")
    @ResponseBody
    public String checkOrderDetailCodeUnique(OrderDetail orderDetail) {
        return orderDetailService.checkOrderDetailCodeUnique(orderDetail);
    }

    /**
     * 消费者确认完成子订单
     *
     * @param orderDetailId 子订单ID
     */
    @PostMapping("/finish")
    @ResponseBody
    public AjaxResult finish(Long orderDetailId) {
        logger.info("消费者确认完成子订单,orderDetailId={}", orderDetailId);
        try {
            orderDetailService.finish(orderDetailId);
        } catch (BaseAdaPayException e) {
            logger.error(e.getMessage(), e);
            return AjaxResult.error("操作失败，请稍后重试");
        }
        return AjaxResult.success();
    }

    /**
     * 消费者申请取消子订单
     *
     * @param orderDetailId 子订单ID
     */
    @PostMapping("/cancel")
    @ResponseBody
    public AjaxResult applyForCancel(Long orderDetailId) throws BaseAdaPayException {
        logger.info("消费者申请取消子订单,orderDetailId={}", orderDetailId);
        orderDetailService.applyForCancel(orderDetailId);
        return AjaxResult.success();
    }

    /**
     * 师傅审核取消子订单申请
     *
     * @param orderDetailId 子订单ID
     * @param agree         0=不同意 1=同意
     */
    @PostMapping("/cancel/agree")
    @ResponseBody
    public AjaxResult cancelAgree(Long orderDetailId, Integer agree) throws BaseAdaPayException {
        logger.info("师傅审核取消子订单申请,orderDetailId={},agree={}", orderDetailId, agree);
        orderDetailService.cancelAgree(orderDetailId, agree);
        return AjaxResult.success();
    }

    /**
     * 师傅发起完单
     *
     * @param request 完单发起请求对象
     */
    @PostMapping("/app/applyFinishOrder")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult applyFinishOrder(@RequestBody OrderProcessRequest request) {
        logger.info("师傅发起完单,orderDetailId={}", request.getOrderDetailId());
        // 判断是否有未完成的售后记录,如果有则不允许完单
        AfterServiceRecord unfinishedByOrderDetailId = afterServiceRecordService.getUnfinishedByOrderDetailId(request.getOrderDetailId());
        if (unfinishedByOrderDetailId != null) {
            return AjaxResult.error("存在未处理完的售后,不允许申请完单!");
        }
        // 判断工单状态是否为服务中以及是否已支付
        OrderDetail orderDetail = orderDetailService.selectById(request.getOrderDetailId());
        OrderMaster orderMaster = orderMasterService.selectById(orderDetail.getOrderMasterId());
        if (orderDetail.getOrderStatus().equals(OrderStatus.FINISH_CHECK.code())) {
            return AjaxResult.success("发起成功");
        }
        if (!"01".equals(orderMaster.getConsultMode()) && (orderDetail.getOrderStatus() != OrderStatus.SERVER.code()
                || !orderMaster.getPayStatus().equals(PayStatus.PAID.getCode()))) {
            return AjaxResult.error("未支付订单或非服务中订单，发起完单失败");
        }

        Worker worker = workerService.selectById(orderDetail.getWorkerId());
        Assert.notNull(worker, "师傅不存在 workerId=" + orderDetail.getWorkerId());
        WorkerCertification wcc = workerCertificationService.selectByWorkerId(orderDetail.getWorkerId());
        if (wcc == null || wcc.getStatus() == null || wcc.getStatus() != 1) {
            return AjaxResult.error("师傅未认证，请先去认证哦！");
        }

        // 存储完单图
        List<GoodsImgs> finishImgObjList = new ArrayList<>();
        for (String imgUrl : request.getFinishImgList()) {
            GoodsImgs finishImgObj = new GoodsImgs();
            finishImgObj.setGoodsId(0L);
            finishImgObj.setImgType(ImgType.FINISH_IMG.getId());
            finishImgObj.setImgUrl(imgUrl);
            finishImgObj.setRemark(String.valueOf(request.getOrderDetailId()));
            finishImgObjList.add(finishImgObj);
        }
        int insertedRows = goodsImgsService.batchInsert(finishImgObjList);
        Assert.isTrue(insertedRows > 0, "完单图入库失败，request=" + request);

        // 存储评价标签
        if (CollectionUtils.isNotEmpty(request.getAssessLabels())) {
            request.getAssessLabels().forEach(label -> {
                OrderAssessLabel orderAssessLabel = new OrderAssessLabel();
                orderAssessLabel.setLabelId(label);
                orderAssessLabel.setOrderId(request.getOrderDetailId());
                int insertLabelRow = orderAssessLabelService.insertOrderAssessLabel(orderAssessLabel);
                Assert.isTrue(insertLabelRow > 0, "，labelId=" + label);
            });
        }

        // 修改子单状态为完单待确认状态，更新完单时间
        OrderDetail updateOrderDetail = new OrderDetail();
        updateOrderDetail.setId(request.getOrderDetailId());
        updateOrderDetail.setWorkFinishTime(new Date());
        updateOrderDetail.setOrderStatus(OrderStatus.FINISH_CHECK.code());
        updateOrderDetail.setRemark(request.getRemark());
        int affectedRow = orderDetailService.updateOrderDetail(updateOrderDetail);
        Assert.isTrue(affectedRow == 1, "子订单修改失败，orderDetail=" + orderDetail);

        OrderBehavior orderBehavior = new OrderBehavior()
                .setOrderMasterId(orderMaster.getId()).setOrderMasterCode(orderMaster.getCode())
                .setOrderDetailId(orderDetail.getId()).setOrderDetailCode(orderDetail.getCode())
                .setWorkerId(worker.getWorkerId()).setWorkerName(worker.getName())
                .setBehavior(OrderBehaviorEnum.FINISH_ORDER);
        orderBehaviorService.insert(orderBehavior);

        Customer customer = customerService.selectByCustomerId(orderDetail.getCustomerId());
        // 通知师傅新订单
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("thing1", "师傅完单通知");
            params.put("thing5", "请确认师傅工作已完成!");
            wxMsgService.sendWxMsg(customer.getOpenId(), WxMsgEnum.CUSTOMER_ORDER, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success("发起成功");
    }

    /**
     * 拒绝订单
     * 后台管理系统使用，可控制权限
     */
    @PostMapping("/reject")
    @ResponseBody
    public AjaxResult reject(OrderDetail orderDetail) {
        return rejectDetailOrder(orderDetail);
    }

    @PostMapping("/callCustomer")
    @ResponseBody
    public AjaxResult callCustomer(@RequestBody OrderDetail orderDetail) {
        try {
            OrderDetail result = orderDetailService.selectById(orderDetail.getId());
            if (result.getTimeout() == 1 && OrderStatus.PLAIN.code() == result.getOrderStatus()) {
                orderDetail.setTimeout(0);
            }
            int i = orderDetailService.updateOrderDetail(orderDetail);
            if(i > 0){
                OrderCallRecord param = new OrderCallRecord();
                param.setOrderId(orderDetail.getId());
                param.setCallTime(new Date());
                param.setOrderType("01");
                orderCallRecordService.insertOrderCallRecord(param);
            }
            return AjaxResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
    }

    /**
     * 拒绝订单
     */
    @PostMapping("/app/order/reject")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult rejectDetailOrder(@RequestBody OrderDetail orderDetail) {
        // 查询订单信息
        OrderDetail od = this.orderDetailService.selectById(orderDetail.getId());
        OrderMaster om = orderMasterService.selectById(od.getOrderMasterId());
        Worker masterWorker = workerService.selectById(om.getWorkerId());
        Worker worker = workerService.selectById(od.getWorkerId());
        // 删除子单
        orderDetailService.deleteOrderDetailByIds(orderDetail.getId().toString());
        FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(od.getId());
        // 财务子单金额返还给主单
        FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(od.getOrderMasterId());
        financialMaster.setServerMoney(financialMaster.getServerMoney().add(financialDetail.getPayMoney()));
        financialMasterService.updateFinancialMaster(financialMaster);
        // 删除子财务单
        financialDetailService.deleteFinancialDetailByOrderDetailId(orderDetail.getId());
        // 退换加价费用
        List<FinancialChangeRecord> fcrList = financialChangeRecordService.selectByDetailIds(orderDetail.getId().toString());
        // 先把这个子单的加价单全退了
        // 主订单金额=订单原价+加价
        BigDecimal payMoney = financialMaster.getPayMoney();
        for (FinancialChangeRecord fcr : fcrList) {
            if (PayStatus.PAID.getCode().equals(fcr.getPayStatus()) || PayStatus.PAYED_ADD.getCode().equals(fcr.getPayStatus())) {
                executor.execute(() -> financialChangeRecordService.refund(om.getDeptId(), fcr.getId()));
                payMoney = payMoney.subtract(fcr.getChangeMoney());
            }
        }
        financialMaster.setPayMoney(payMoney);
        financialMasterService.updateFinancialMaster(financialMaster);
        // 退回旧商品
//        List<OrderGoods> goodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId());
//        goodsList.forEach(orderGoods -> {
//            List<OrderGoods> masterGoods = orderGoodsService.selectByOrderMasterId(od.getOrderMasterId());
//            masterGoods.forEach(master->{
//                if(master.getGoodsStandardId().equals(orderGoods.getGoodsStandardId())){
//                    master.setServerGoodsNum(master.getServerGoodsNum()-orderGoods.getGoodsNum());
//                }
//                orderGoodsService.updateOrderGoods(master);
//            });
//        });
        // 删除派单记录
        orderGoodsService.deleteByOrderDetailId(orderDetail.getId());
        OrderMaster orderMaster2Update = new OrderMaster();
        orderMaster2Update.setId(od.getOrderMasterId());
        orderMaster2Update.setOrderStatus(OrderStatus.PLAIN.code());
        // 查询是否还有派单记录，没有的话需要重置主单是否自己承接的字段为NULL
        List<OrderGoods> existOrderGoods = orderGoodsService.selectByOrderMasterId(od.getOrderMasterId());
        if (CollectionUtils.isNotEmpty(existOrderGoods)) {
            orderMaster2Update.setResetAllSelfAssigned(true);
        }
        // 更新主单是否全部派完
        orderMaster2Update.setHasDispatchedAll(0);
        orderMasterService.updateOrderMaster(orderMaster2Update);

        OrderBehavior orderBehavior = new OrderBehavior()
                .setOrderMasterId(om.getId()).setOrderMasterCode(om.getCode())
                .setWorkerId(worker.getWorkerId()).setWorkerName(worker.getName())
                .setBehavior(OrderBehaviorEnum.REFUSE_ORDER);
        orderBehaviorService.insert(orderBehavior);

        // 拒单
      
        logger.info("师傅资料{}",masterWorker);
        WorkerCertification  workerRealInfo = workerCertificationService.selectByWorkerId(od.getWorkerId());
        logger.info("认证师傅资料{}",workerRealInfo);
        try {
            // 推送公众号通知数据。
            // 消息组装。
            Map<String, Object> paramsNew = new HashMap<>();
            // 订单编号
            paramsNew.put("thing11", "您有派出的订单被拒接/退单，已退回");
            // 名称
            paramsNew.put("thing12", "请进入【我的订单--未约未排】查看");
            CustomerAddress address = addressService.selectByCustomerAddressId(om.getAddressId());

            //拒单人员
            paramsNew.put("thing13",workerRealInfo.getSurname()+ workerRealInfo.getName());
            paramsNew.put("thing7", address.getName());
            // 预约时间
            paramsNew.put("time5", com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date()));
            WechatMsgUtils.sendWeChatMsg(WechatMsgUtils.getToken(), masterWorker.getWxOpenId(), WxMsgEnum.REJECT_ORDER, paramsNew);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return AjaxResult.success();
    }

    @PostMapping("/app/change/price")
    @ResponseBody
    public AjaxResult changePrice(@Valid @RequestBody OrderChangePriceRequest request) {
        try {
            Assert.notNull(request.getChangeMoney(), "报价不能为空");
            return toAjax(orderDetailService.changePrice(request.getOrderDetailId(), request.getChangeMoney(), request.getType(), request.getRemark()));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(ExceptionUtil.getExceptionMessage(e));
            return AjaxResult.error("改价失败!");
        }
    }

    @PostMapping("/app/getChangePrice")
    @ResponseBody
    public AjaxResult getChangePrice(@Valid @RequestBody OrderChangePriceRequest request) {
        try {
            return AjaxResult.success(orderDetailService.getChangedPriceRecord(request.getOrderDetailId()));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(ExceptionUtil.getExceptionMessage(e));
            return AjaxResult.error("查询改价失败!");
        }
    }

    private boolean checkIsOnlyServer(Long orderMasterId, Long workId) {
        // 找出原单的数量
        List<OrderGoods> orderGoodsList = orderGoodsService.selectByOrderMasterId(orderMasterId);
        // 找出原单关联的细单的商品数量
        List<OrderDetail> orderDetailList = orderDetailService.selectByOrderMasterId(orderMasterId);
        for (OrderDetail detail : orderDetailList) {
            // 非一个师傅接单
            if (!workId.equals(detail.getWorkerId())) {
                return false;
            }
            // 子单数量
            List<OrderGoods> orderDetailGoodsList = orderGoodsService.selectByOrderDetailId(detail.getId());
            // 计算剩余未分配的商品数量
            for (OrderGoods detailGoods : orderDetailGoodsList) {
                for (OrderGoods masterGoods : orderGoodsList) {
                    if (Objects.equals(masterGoods.getGoodsStandardId(), detailGoods.getGoodsStandardId())) {
                        masterGoods.setGoodsNum(masterGoods.getGoodsNum() - detailGoods.getGoodsNum());
                    }
                }
            }
        }
        // 有单派完.
        for (OrderGoods orderGoods : orderGoodsList) {
            if (orderGoods.getGoodsNum() > 0) {
                return false;
            }
        }
        return true;
    }

    @PostMapping("/add-subtract/insert")
    @ResponseBody
    public AjaxResult addOrSubtract(@Valid @RequestBody OrderAddSubtract body) {
        body.setCreateBy(getLoginName());
        int i = orderDetailService.insertOrderAddSubtract(body);
        return AjaxResult.success(i);
    }

    @GetMapping("/differentStatus/count")
    @ResponseBody
    public AjaxResult differentStatusOrderCount(OrderDetail orderDetail) {
        return AjaxResult.success(orderDetailService.differentStatusOrderCount(orderDetail));
    }

    @GetMapping("/count")
    @ResponseBody
    public AjaxResult orderDetailCount(OrderDetail orderDetail) {
        if(StringUtils.isNotEmpty(orderDetail.getWorkerName()) || StringUtils.isNotEmpty(orderDetail.getWorkerPhone())){
            Worker param = new Worker();
            param.setName(orderDetail.getWorkerName());
            param.setPhone(orderDetail.getWorkerPhone());
            List<Worker> workList = workerService.getWorkList(param);
            List<Long> ids = workList.stream().map(Worker::getWorkerId).collect(Collectors.toList());
            orderDetail.setWorkerIds(ids);
            if(CollectionUtils.isEmpty(ids)){
                return AjaxResult.success(0);
            }
        }
        if(orderDetail.getSysPayStatus() != null){
            FinancialMaster param = new FinancialMaster();
            param.setPayStatus(orderDetail.getSysPayStatus());
            List<FinancialMaster> financialMasters = financialMasterService.selectFinancialMasterList(param);
            List<Long> masterIds = financialMasters.stream().map(FinancialMaster::getOrderMasterId).collect(Collectors.toList());
            orderDetail.setMasterIds(masterIds);
            if(CollectionUtils.isEmpty(masterIds)){
                return AjaxResult.success(0);
            }
        }
        if (this.getSysUser().getDept().getParentId() != 101) {
            orderDetail.setDeptId(this.getSysUser().getDept().getParentId());
        }
        return AjaxResult.success(orderDetailService.countOrderDetailList(orderDetail));
    }

    @GetMapping("/after/count")
    @ResponseBody
    public AjaxResult afterDetailOrderCount(OrderDetail orderDetail) {
        return AjaxResult.success(orderDetailService.afterDetailOrderCount(orderDetail));
    }

    @ResponseBody
    @Operation(summary = "获取当天订单统计数据", method = "GET")
    @GetMapping(path = "/statistics/now", produces = MediaType.APPLICATION_JSON_VALUE)
    public AjaxResult statisticsNow() {
        return AjaxResult.success(orderDetailService.orderStatisticsReturnByNow());
    }

    @ResponseBody
    @Operation(summary = "获取全部订单统计数据", method = "GET")
    @GetMapping(path = "/statistics", produces = MediaType.APPLICATION_JSON_VALUE)
    public AjaxResult statistics() {
        return AjaxResult.success(orderDetailService.orderStatisticsReturn());
    }
}
