package org.dromara.work.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.lakala.zf.laop.java.sdk.demo.utils.KlkConstant;
import com.lakala.zf.laop.java.sdk.demo.utils.LakalaUtils;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysRole;
import org.dromara.system.domain.SysRoleDept;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysRoleDeptMapper;
import org.dromara.system.mapper.SysRoleMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.work.domain.*;
import org.dromara.work.domain.bo.*;
import org.dromara.work.domain.vo.*;
import org.dromara.work.mapper.*;
import org.dromara.work.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单管理Service业务层处理
 *
 * @author Maosw
 * @date 2024-08-12
 */
@RequiredArgsConstructor
@Service
public class TpOrderServiceImpl extends MPJBaseServiceImpl<TpOrderMapper,TpOrder> implements ITpOrderService {

    private final TpOrderMapper baseMapper;

    private final TpOrderSmallMapper smallMapper;

    private final TpOrderBigMapper bigMapper;

    private final TpOrderModelMapper modelMapper;

    private final TpOrderRecordMapper recordMapper;

    private final TpClientMapper clientMapper;

    private final TpClientStaffMapper clientStaffMapper;

    private final SysUserMapper sysUserMapper;

    private final SysDeptMapper deptMapper;

    private final SysRoleMapper roleMapper;

    private final SysRoleDeptMapper roleDeptMapper;

    private final TpStaffPayMapper staffPayMapper;

    private final ITpOrderPayService tpOrderPayService;

    private final TpOrderPayMapper paymentMapper;

    private final ITpUserRecordService tpUserRecordService;

    private final TpCategoryServiceImpl tpCategoryService;

    private final ITpMessageService tpMessageService;


    /**
     * 查询订单管理
     *
     * @param id 主键
     * @return 订单管理
     */
    @Override
    public TpOrderVo queryById(Long id){
        LoginUser loginUser = LoginHelper.getLoginUser();
        MPJLambdaWrapper<TpOrder> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(TpOrder.class);
        if(LoginHelper.isSuperAdmin()){
            wrapper.selectAs(TpClient::getName,TpOrderVo::getCname);
        }else {
            if (loginUser.getIdentity() == 3 || loginUser.getIdentity() == 1){
                wrapper.selectAs(TpClientStaff::getName,TpOrderVo::getCname);
            }
        }
        wrapper.selectAs("s.nick_name",TpOrderVo::getSname)
            .selectAs("f.nick_name",TpOrderVo::getFname)
            .selectAs("b.nick_name",TpOrderVo::getBname)
            .selectAs(TpWechat::getCode,TpOrderVo::getWname)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid);
        wrapper.eq(id != null, TpOrder::getId, id);
        return baseMapper.selectJoinOne(TpOrderVo.class,wrapper);
    }

    /**
     * 回收站导出订单
     *
     * @param bo
     * @return
     */
    @Override
    public List<TpOrderVo> queryList(TpOrderBo bo) {
        bo.setIsDel(2);
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapper(bo)
            .selectAll(TpOrder.class)
            .selectAs("s.nick_name",TpOrderVo::getSname)
            .selectAs("f.nick_name",TpOrderVo::getFname)
            .selectAs("b.nick_name",TpOrderVo::getBname)
            .selectAs(TpClient::getName,TpOrderVo::getCname)
            .selectAs(TpWechat::getCode,TpOrderVo::getWname)
            .selectAs("concat(round(t.pay_price/t.price * 100),'%')",TpOrderVo::getBili)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid)
            .orderByDesc(TpOrder::getId);
        return baseMapper.selectJoinList(TpOrderVo.class,wrapper);
    }

    /**
     * 客服订单导出
     * @param bo
     * @return
     */
    @Override
    public List<TpOrderVo> queryListKF(TpOrderBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser != null && loginUser.getIdentity() == 2){
            throw new ServiceException("您无权限导出客服订单列表");
        }
        bo.setIsDel(1);
        bo.setKfOrjs(1);
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapper(bo);
        if(LoginHelper.isSuperAdmin()){
            wrapper.selectAll(TpOrder.class);
            wrapper.selectAs(TpClient::getName,CustomerOrderVo::getCname);
        }else {
            if (loginUser.getIdentity() == 3 || loginUser.getIdentity() == 1){
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getRemark,TpOrder::getType,TpOrder::getAddTime,TpOrder::getNum,TpOrder::getJsRemark,TpOrder::getPrice,TpOrder::getPayState,TpOrder::getPayPrice,TpOrder::getEndPrice,TpOrder::getKfpay,TpOrder::getState,TpOrder::getGjPrice,TpOrder::getGpay,TpOrder::getIsCd,TpOrder::getDtTime);
                wrapper.selectAs(TpClientStaff::getName,CustomerOrderVo::getCname);
            }else {
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getRemark,TpOrder::getType,TpOrder::getAddTime,TpOrder::getNum,TpOrder::getJsRemark,TpOrder::getPrice,TpOrder::getPayState,TpOrder::getPayPrice,TpOrder::getEndPrice,TpOrder::getGjPrice,TpOrder::getGpay,TpOrder::getIsCd,TpOrder::getState,TpOrder::getDtTime);
            }
        }
        wrapper.selectAs("s.nick_name",CustomerOrderVo::getSname)
            .selectAs("f.nick_name",CustomerOrderVo::getFname)
            .selectAs("b.nick_name",CustomerOrderVo::getBname)
            .selectAs(TpWechat::getCode,CustomerOrderVo::getWname)
            .selectAs("concat(round(t.pay_price/t.price * 100),'%')",CustomerOrderVo::getBili)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid)
            .orderByDesc(TpOrder::getId);
        return baseMapper.selectJoinList(TpOrderVo.class,wrapper);
    }

    /**
     * 导出技术订单
     *
     * @param bo
     * @return
     */
    @Override
    public List<TpOrderVo> queryListJS(TpOrderBo bo) {
        if (isNotBeforeToday9AM(bo.getParams().get("addEndTime").toString())){
            throw new ServiceException("查询时间不能是今天");
        }
        bo.setIsDel(1);
        bo.setKfOrjs(2);
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser != null && loginUser.getIdentity() == 3){
            throw new ServiceException("您无权限查看技术订单列表");
        }
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapper(bo);
        if(LoginHelper.isSuperAdmin()){
            wrapper.selectAll(TpOrder.class);
        }else {
            if (loginUser.getIdentity() == 2 || loginUser.getIdentity() == 1){
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getType,TpOrder::getNum,TpOrder::getAddTime,TpOrder::getJsRemark,TpOrder::getPayState,TpOrder::getJsPrice,TpOrder::getJsPayPrice,TpOrder::getState,TpOrder::getDtTime);
                wrapper.eq(TpOrder::getBid,loginUser.getUserId());
            }else {
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getType,TpOrder::getNum,TpOrder::getAddTime,TpOrder::getJsRemark,TpOrder::getPayState,TpOrder::getJsPrice,TpOrder::getJsPayPrice,TpOrder::getState,TpOrder::getDtTime);
            }
        }
        wrapper.selectAs("s.nick_name",SkillOrderVo::getSname)
            .selectAs("f.nick_name",SkillOrderVo::getFname)
            .selectAs("b.nick_name",SkillOrderVo::getBname)
            .selectAs(TpClient::getName,SkillOrderVo::getCname)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .isNotNull(TpOrder::getBid)
            .orderByDesc(TpOrder::getId);

        return baseMapper.selectJoinList(TpOrderVo.class,wrapper);
    }

    /**
     * 分页查询订单管理列表(订单回收站)
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 订单管理分页列表
     */
    @Override
    public TableDataInfo<TpOrderVo> queryPageList(TpOrderBo bo, PageQuery pageQuery) {
        bo.setIsDel(2);
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapper(bo)
            .selectAll(TpOrder.class)
            .selectAs("s.nick_name",TpOrderVo::getSname)
            .selectAs("f.nick_name",TpOrderVo::getFname)
            .selectAs("b.nick_name",TpOrderVo::getBname)
            .selectAs(TpClient::getName,TpOrderVo::getCname)
            .selectAs(TpWechat::getCode,TpOrderVo::getWname)
            .selectAs("concat(round(t.pay_price/t.price * 100),'%')",TpOrderVo::getBili)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid)
            .orderByDesc(TpOrder::getId);

        //分页查询 （需要启用 mybatis plus 分页插件）
        IPage<TpOrderVo> listPage = baseMapper.selectJoinPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), TpOrderVo.class, wrapper);
        return TableDataInfo.build(listPage);
    }

    /**
     * 客服订单查询
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<CustomerOrderVo> queryCustomerPageList(TpOrderBo bo, PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setIsDel(1);
        bo.setKfOrjs(1);
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapperKF(bo);
        if(LoginHelper.isSuperAdmin()){
            wrapper.selectAll(TpOrder.class);
            wrapper.selectAs(TpClientStaff::getName,CustomerOrderVo::getCname);
        }else {
            if (loginUser.getIdentity() == 3 || loginUser.getIdentity() == 1){
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getRemark,TpOrder::getType,TpOrder::getAddTime,TpOrder::getNum,TpOrder::getJsRemark,TpOrder::getPrice,TpOrder::getPayState,TpOrder::getPayPrice,TpOrder::getEndPrice,TpOrder::getKfpay,TpOrder::getState,TpOrder::getGjPrice,TpOrder::getGpay,TpOrder::getIsCd,TpOrder::getDtTime,TpOrder::getSid);
                wrapper.selectAs(TpClientStaff::getName,CustomerOrderVo::getCname);
            }else {
                wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getRemark,TpOrder::getType,TpOrder::getAddTime,TpOrder::getNum,TpOrder::getJsRemark,TpOrder::getPrice,TpOrder::getPayState,TpOrder::getPayPrice,TpOrder::getEndPrice,TpOrder::getGjPrice,TpOrder::getGpay,TpOrder::getIsCd,TpOrder::getState,TpOrder::getDtTime);
                wrapper.selectAs(TpClientStaff::getName,CustomerOrderVo::getCname);
            }
        }
        wrapper.selectAs("s.nick_name",CustomerOrderVo::getSname)
        .selectAs("f.nick_name",CustomerOrderVo::getFname)
        .selectAs("b.nick_name",CustomerOrderVo::getBname)
        .selectAs(TpWechat::getCode,CustomerOrderVo::getWname)
        .selectAs("concat(round(t.pay_price/t.price * 100),'%')",CustomerOrderVo::getBili)
        .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
        .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
        .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
        .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
        .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
        .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid)
        .orderByDesc(TpOrder::getId);

        //分页查询 （需要启用 mybatis plus 分页插件）
        IPage<CustomerOrderVo> listPage = baseMapper.selectJoinPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), CustomerOrderVo.class, wrapper);
        return TableDataInfo.build(listPage);
    }

    /**
     * 技术订单查询
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<SkillOrderVo> querySkillPageList(TpOrderBo bo, PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser != null && loginUser.getIdentity() == 2){
            if (isNotBeforeToday9AM(bo.getParams().get("addEndTime").toString())){
                throw new ServiceException("查询时间不能是今天");
            }
        }
        bo.setIsDel(1);
        bo.setKfOrjs(2);
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpOrder> wrapper = buildQueryMPJWrapper(bo);
        if(LoginHelper.isSuperAdmin()){
            wrapper.selectAll(TpOrder.class);
        }else {
            wrapper.select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getType,TpOrder::getNum,TpOrder::getAddTime,TpOrder::getRemark,TpOrder::getJsRemark,TpOrder::getPayState,TpOrder::getJsPrice,TpOrder::getJsPayPrice,TpOrder::getState,TpOrder::getDtTime);
        }
        wrapper.selectAs("s.nick_name",SkillOrderVo::getSname)
            .selectAs("f.nick_name",SkillOrderVo::getFname)
            .selectAs("b.nick_name",SkillOrderVo::getBname)
            .selectAs(TpClient::getName,SkillOrderVo::getCname)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .isNotNull(TpOrder::getBid)
            .orderByDesc(TpOrder::getId);

        //分页查询 （需要启用 mybatis plus 分页插件）
        IPage<SkillOrderVo> listPage = baseMapper.selectJoinPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), SkillOrderVo.class, wrapper);
        return TableDataInfo.build(listPage);
    }

    private MPJLambdaWrapper<TpOrder> buildQueryMPJWrapperKF(TpOrderBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        Map<String, Object> params = bo.getParams();
        MPJLambdaWrapper<TpOrder> lqw = new MPJLambdaWrapper<>();
        lqw.eq(StringUtils.isNotBlank(bo.getOrderId()), TpOrder::getOrderId, bo.getOrderId());

        if(!LoginHelper.isSuperAdmin()){
            if (loginUser != null){
                if(bo.getDeptIds() != null && bo.getDeptIds().size() > 0){
                    List<Long> userIds = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, bo.getDeptIds()).eq(SysUser::getIdentity, 2)).stream().map(SysUser::getUserId).collect(Collectors.toList());
                    if(userIds != null && userIds.size() > 0){
                        lqw.and(i -> i.and(j -> j.in(TpOrder::getDeptId,bo.getDeptIds()).in(TpOrder::getDeptIdJs, bo.getDeptIds())));
                    }else {
                        lqw.in(TpOrder::getDeptId,bo.getDeptIds());
                    }
                }else {
                    int scope = getDataScope();
                    if(scope == 2){
                        List<Long> deptIds = getDeptIds();
                        lqw.in(TpOrder::getDeptId,deptIds);
                    }else if(scope == 3){
                        lqw.eq(TpOrder::getDeptId,loginUser.getDeptId());
                    }else if(scope == 4){
                        List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().like(SysDept::getAncestors, loginUser.getDeptId())).stream().map(SysDept::getDeptId).collect(Collectors.toList());
                        deptIds.add(loginUser.getDeptId());
                        lqw.in(TpOrder::getDeptId,deptIds);
                    }else if(scope == 5){
                        lqw.eq(TpOrder::getSid,loginUser.getUserId());
                    }
                }
                lqw.like(StringUtils.isNotBlank(bo.getCname()), TpClientStaff::getName, bo.getCname());
            }
            List<Long> orderTypeIds = getOrderTypeIds();
            if(orderTypeIds != null && orderTypeIds.size() > 0){
                lqw.in(TpOrder::getType, orderTypeIds);
            }
        }else {
            if(bo.getDeptIds() != null && bo.getDeptIds().size() > 0){
                if(bo.getKfOrjs() == 1){
                    List<Long> userIds = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, bo.getDeptIds()).eq(SysUser::getIdentity, 2)).stream().map(SysUser::getUserId).collect(Collectors.toList());
                    if(userIds != null && userIds.size() > 0){
                        lqw.and(i -> i.and(j -> j.in(TpOrder::getDeptId,bo.getDeptIds()).in(TpOrder::getDeptIdJs, bo.getDeptIds())));
                    }else {
                        lqw.in(TpOrder::getDeptId,bo.getDeptIds());
                    }
                }else {
                    List<Long> userIds = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, bo.getDeptIds()).eq(SysUser::getIdentity, 2)).stream().map(SysUser::getUserId).collect(Collectors.toList());
                    if(userIds != null && userIds.size() > 0){
                        lqw.and(i -> i.and(j -> j.in(TpOrder::getDeptId,bo.getDeptIds()).in(TpOrder::getDeptIdJs, bo.getDeptIds())));
                    }else {
                        lqw.in(TpOrder::getDeptIdJs,bo.getDeptIds());
                    }
                }
            }
            lqw.like(StringUtils.isNotBlank(bo.getCname()), TpClient::getName, bo.getCname());
        }

        lqw.eq(bo.getPhone() != null, TpClient::getPhone, bo.getPhone());
        lqw.like(StringUtils.isNotBlank(bo.getWcode()), TpWechat::getCode, bo.getWcode());
        lqw.like(StringUtils.isNotBlank(bo.getScode()), "s.nick_name", bo.getScode());
        lqw.like(StringUtils.isNotBlank(bo.getBcode()), "b.nick_name", bo.getBcode());
        lqw.like(StringUtils.isNotBlank(bo.getFcode()), "f.nick_name", bo.getFcode());
        if(bo.getAssignState() != null){
            lqw.isNull(bo.getAssignState() == 1, TpOrder::getBid);
            lqw.isNotNull(bo.getAssignState() == 2, TpOrder::getBid);
        }
        lqw.eq(bo.getStyle() != null, TpOrder::getStyle, bo.getStyle());
        lqw.like(StringUtils.isNotBlank(bo.getSpace()), TpOrder::getSpace, bo.getSpace());
        lqw.eq(bo.getQuality() != null, TpOrder::getQuality, bo.getQuality());
        lqw.eq(bo.getType() != null, TpOrder::getType, bo.getType());
        lqw.eq(bo.getState() != null, TpOrder::getState, bo.getState());
        lqw.like(StringUtils.isNotBlank(bo.getRemark()), TpOrder::getRemark, bo.getRemark());
        lqw.like(StringUtils.isNotBlank(bo.getJsRemark()), TpOrder::getJsRemark, bo.getJsRemark());
        lqw.eq(bo.getPayState() != null, TpOrder::getPayState, bo.getPayState());
        lqw.eq(bo.getIsDel() != null, TpOrder::getIsDel, bo.getIsDel());
        lqw.between(params.get("addBeginTime") != null && params.get("addEndTime") != null,
            TpOrder::getAddTime, params.get("addBeginTime"), params.get("addEndTime"));
        lqw.between(params.get("dtBeginTime") != null && params.get("dtEndTime") != null,
            TpOrder::getDtTime, params.get("dtBeginTime"), params.get("dtEndTime"));
        lqw.eq(bo.getIsC() != null, TpOrder::getIsC, bo.getIsC());
        lqw.eq(bo.getIsCd() != null, TpOrder::getIsCd, bo.getIsCd());
        return lqw;
    }

    private MPJLambdaWrapper<TpOrder> buildQueryMPJWrapper(TpOrderBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        Map<String, Object> params = bo.getParams();
        MPJLambdaWrapper<TpOrder> lqw = new MPJLambdaWrapper<>();
        lqw.eq(StringUtils.isNotBlank(bo.getOrderId()), TpOrder::getOrderId, bo.getOrderId());

        if(!LoginHelper.isSuperAdmin()){
            if (loginUser != null){
                if (loginUser.getIdentity() == 2){
                    if(bo.getDeptIds() != null && bo.getDeptIds().size() > 0){
                        lqw.in(TpOrder::getDeptIdJs, bo.getDeptIds());
                    }else {
                        int scope = getDataScope();
                        if(scope == 2){
                            List<Long> deptIds = getDeptIds();
                            lqw.in(TpOrder::getDeptIdJs,deptIds);
                        }else if(scope == 3){
                            lqw.eq(TpOrder::getDeptIdJs,loginUser.getDeptId());
                        }else if(scope == 4){
                            List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().like(SysDept::getAncestors, loginUser.getDeptId())).stream().map(SysDept::getDeptId).collect(Collectors.toList());
                            deptIds.add(loginUser.getDeptId());
                            lqw.in(TpOrder::getDeptIdJs,deptIds);
                        }else if(scope == 5){
                            lqw.eq(TpOrder::getBid,loginUser.getUserId());
                        }
                    }
                }else{
                    if(bo.getDeptIds() != null && bo.getDeptIds().size() > 0){
                        List<Long> userIds = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, bo.getDeptIds()).eq(SysUser::getIdentity, 2)).stream().map(SysUser::getUserId).collect(Collectors.toList());
                        if(userIds != null && userIds.size() > 0){
                            lqw.and(i -> i.and(j -> j.in(TpOrder::getDeptId,bo.getDeptIds()).in(TpOrder::getDeptIdJs, bo.getDeptIds())));
                        }else {
                            lqw.in(TpOrder::getDeptId,bo.getDeptIds());
                        }
                    }else {
                        int scope = getDataScope();
                        if(scope == 2){
                            List<Long> deptIds = getDeptIds();
                            lqw.in(TpOrder::getDeptIdJs,deptIds);
                        }else if(scope == 3){
                            lqw.eq(TpOrder::getDeptIdJs,loginUser.getDeptId());
                        }else if(scope == 4){
                            List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().like(SysDept::getAncestors, loginUser.getDeptId())).stream().map(SysDept::getDeptId).collect(Collectors.toList());
                            deptIds.add(loginUser.getDeptId());
                            lqw.in(TpOrder::getDeptIdJs,deptIds);
                        }else if(scope == 5){
                            lqw.eq(TpOrder::getSid,loginUser.getUserId());
                        }
                    }
                    lqw.like(StringUtils.isNotBlank(bo.getCname()), TpClientStaff::getName, bo.getCname());
                }
            }
            List<Long> orderTypeIds = getOrderTypeIds();
            if(orderTypeIds != null && orderTypeIds.size() > 0){
                lqw.in(TpOrder::getType, orderTypeIds);
            }
        }else{
            if(bo.getDeptIds() != null && bo.getDeptIds().size() > 0){
                if(bo.getKfOrjs() == 1){
                    List<Long> userIds = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getDeptId, bo.getDeptIds()).eq(SysUser::getIdentity, 2)).stream().map(SysUser::getUserId).collect(Collectors.toList());
                    if(userIds != null && userIds.size() > 0){
                        lqw.and(i -> i.and(j -> j.in(TpOrder::getDeptId,bo.getDeptIds()).in(TpOrder::getDeptIdJs, bo.getDeptIds())));
                    }else {
                        lqw.in(TpOrder::getDeptId,bo.getDeptIds());
                    }
                }else {
                    lqw.in(TpOrder::getDeptIdJs,bo.getDeptIds());
                }
            }
            lqw.like(StringUtils.isNotBlank(bo.getCname()), TpClient::getName, bo.getCname());
        }

        lqw.eq(bo.getPhone() != null, TpClient::getPhone, bo.getPhone());
        lqw.like(StringUtils.isNotBlank(bo.getWcode()), TpWechat::getCode, bo.getWcode());
        lqw.like(StringUtils.isNotBlank(bo.getScode()), "s.nick_name", bo.getScode());
        lqw.like(StringUtils.isNotBlank(bo.getBcode()), "b.nick_name", bo.getBcode());
        lqw.like(StringUtils.isNotBlank(bo.getFcode()), "f.nick_name", bo.getFcode());
        if(bo.getAssignState() != null){
            lqw.isNull(bo.getAssignState() == 1, TpOrder::getBid);
            lqw.isNotNull(bo.getAssignState() == 2, TpOrder::getBid);
        }
        lqw.eq(bo.getStatus() != null, TpOrder::getStatus, bo.getStatus());
        lqw.eq(bo.getStyle() != null, TpOrder::getStyle, bo.getStyle());
        lqw.like(StringUtils.isNotBlank(bo.getSpace()), TpOrder::getSpace, bo.getSpace());
        lqw.eq(bo.getQuality() != null, TpOrder::getQuality, bo.getQuality());
        lqw.eq(bo.getType() != null, TpOrder::getType, bo.getType());
        lqw.eq(bo.getState() != null, TpOrder::getState, bo.getState());
        lqw.like(StringUtils.isNotBlank(bo.getRemark()), TpOrder::getRemark, bo.getRemark());
        lqw.like(StringUtils.isNotBlank(bo.getJsRemark()), TpOrder::getJsRemark, bo.getJsRemark());
        lqw.eq(bo.getPayState() != null, TpOrder::getPayState, bo.getPayState());
        lqw.eq(bo.getIsDel() != null, TpOrder::getIsDel, bo.getIsDel());
        lqw.between(params.get("addBeginTime") != null && params.get("addEndTime") != null,
            TpOrder::getAddTime, params.get("addBeginTime"), params.get("addEndTime"));
        lqw.between(params.get("dtBeginTime") != null && params.get("dtEndTime") != null,
            TpOrder::getDtTime, params.get("dtBeginTime"), params.get("dtEndTime"));
        lqw.eq(bo.getIsC() != null, TpOrder::getIsC, bo.getIsC());
        lqw.eq(bo.getIsCd() != null, TpOrder::getIsCd, bo.getIsCd());
        return lqw;
    }

    /**
     * 新增订单管理
     *
     * @param bo 订单管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TpOrderBo bo) {
        if(bo.getCategoryId() != null){
            TpCategoryVo tpCategoryVo = tpCategoryService.queryById(bo.getCategoryId());
            bo.setCategoryName(tpCategoryVo.getName());
        }
        //生成订单号
        String orderNum = genItemId();
        bo.setOrderId(orderNum);
        bo.setSid(bo.getSid());
        bo.setAddTime(new Date());
        bo.setEndPrice(bo.getPrice());
        bo.setJsPrice(bo.getPrice());
//        bo.setDeptId(loginUser.getDeptId());
//        bo.setAncestors(dept.getAncestors());

        TpOrder add = MapstructUtils.convert(bo, TpOrder.class);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            boolean res =  saveOrderRecord(add.getId(),"创建订单","创建订单:"+orderNum+" 成功",1,null);
            if(!res){
                throw new ServiceException("创建订单失败");
            }
        }
        return flag;
    }

    /**
     * 修改订单管理
     *
     * @param bo 订单管理
     * @return 是否修改成功
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean updateByBo(TpOrderBo bo) {
        TpOrder order = baseMapper.selectById(bo.getId());
        if(StringUtils.isNotEmpty(bo.getOrderId()) && !Objects.equals(bo.getOrderId(), order.getOrderId())){
            throw new ServiceException("订单编号不可以修改");
        }
        BigDecimal endPrice = bo.getPrice().subtract(order.getPayPrice());
        if(endPrice.compareTo(BigDecimal.ZERO) < 0){
            throw new ServiceException("订单金额不可以小于已支付金额");
        }
        if(order.getPayState() == 2){
            if (bo.getPrice().compareTo(order.getPayPrice()) == 0) {
                bo.setPayState(3);
            }
        }
        if(order.getPayState() == 3){
            if(bo.getPrice().compareTo(order.getPayPrice()) > 0){
                bo.setPayState(2);
            }
        }
        bo.setEndPrice(endPrice);
        bo.setJsPrice(bo.getPrice().subtract(order.getGjPrice()).subtract(order.getCdPrice()));
        TpOrder update = MapstructUtils.convert(bo, TpOrder.class);
        boolean res =  saveOrderRecord(order.getId(),"修改订单","订单:"+order.getOrderId()+" 修改成功",1,bo.getRecord());
        if(!res){
            throw new ServiceException("订单修改失败");
        }
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 校验并批量删除订单管理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        List<TpOrder> list = baseMapper.selectByIds(ids);
        for (TpOrder tpOrder : list) {
            if(tpOrder.getPayState() != 1){
                throw new ServiceException("该订单已支付，不可删除");
            }
            tpOrder.setIsDel(2);
            boolean res =  saveOrderRecord(tpOrder.getId(),"删除订单","删除订单:"+tpOrder.getOrderId()+" 成功",1,null);
            if(!res){
                throw new ServiceException("删除订单失败");
            }
        }
        return baseMapper.updateBatchById(list);
    }

    /**
     * 订单指派技术
     * @param orderIds
     * @param userId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateOrderAssign(List<Long> orderIds, Long userId) {
        SysUser user = sysUserMapper.selectById(userId);

        List<TpOrder> orderList = new ArrayList<>();
        for (Long orderId : orderIds){
            TpOrder order = baseMapper.selectById(orderId);
            order.setBid(userId);
            order.setStatus(4);

            SysDept dept = deptMapper.selectById(user.getDeptId());
            order.setDeptIdJs(dept.getDeptId());
            order.setAncestorsJs(dept.getAncestors());

            TpMessageBo tpMessageBo = new TpMessageBo();
            tpMessageBo.setUserId(order.getSid());
            tpMessageBo.setToUserId(userId);
            tpMessageBo.setOrderId(order.getId());
            tpMessageBo.setOrderNum(order.getOrderId());
            tpMessageBo.setContent("客户已将订单:"+order.getOrderId()+" 指派给你");
            tpMessageBo.setType(1);
            tpMessageBo.setCreateTime(new Date());
            tpMessageService.insertByBo(tpMessageBo);

            boolean res =  saveOrderRecord(order.getId(),"订单分图","订单:"+order.getOrderId()+" 指派给"+user.getNickName()+" 成功",1,null);
            if(!res){
                throw new ServiceException("订单指派失败");
            }
            orderList.add(order);
        }
        return baseMapper.updateBatchById(orderList);
    }

    /**
     * 订单取消指派
     * @param orderId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int orderCancelAssign(Long orderId) {
        TpOrder order = baseMapper.selectById(orderId);
        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getSid());
        tpMessageBo.setToUserId(order.getBid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("客户已将订单:"+order.getOrderId()+" 取消指派");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        order.setBid(null);
        order.setStatus(2);
        boolean res =  saveOrderRecord(order.getId(),"取消指派","订单:"+order.getOrderId()+" 取消指派",1,null);
        if(!res){
            throw new ServiceException("订单取消指派失败");
        }
        return baseMapper.updateById(order);
    }

    /**
     * 订单支付获取订单和余额信息
     * @param orderId
     * @return
     */
    @Override
    public TpOrderVo queryOrderPay(Long orderId) {
        MPJLambdaWrapper<TpOrder> wrapper = new MPJLambdaWrapper<TpOrder>()
            .select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getPrice,TpOrder::getPayPrice)
            .selectAs(SysUser::getYue,TpOrderVo::getKfYue)
//            .selectAs(TpClientStaff::getYue,TpOrderVo::getKhYue)
//            .selectAs("(SELECT yue from tp_client_staff c where  c.kid = t.kid and c.sid = t.sid)",TpOrderVo::getKhYue)
            .leftJoin(SysUser.class,SysUser::getUserId,TpOrder::getSid)
//            .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
            .eq(TpOrder::getId,orderId);

        TpOrderVo tpOrderVo = baseMapper.selectJoinOne(TpOrderVo.class, wrapper);
        tpOrderVo.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return tpOrderVo;
    }

    /**
     * 订单支付
     * @param orderId
     * @param type
     * @param price
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public JSONObject orderPay(Long orderId, Integer type, BigDecimal price) throws Exception {
        TpOrder order = baseMapper.selectById(orderId);
        if(order.getPayState() == 3){
            throw new ServiceException("该订单已付清,不可再支付");
        }
        SysUser sysUser = sysUserMapper.selectById(order.getSid());

        //订单剩余支付
        BigDecimal payPrice = order.getPrice().subtract(order.getPayPrice());
        //差额
        BigDecimal cePrice = payPrice.subtract(price);
        if(cePrice.compareTo(BigDecimal.ZERO) < 0){
            throw new ServiceException("支付金额不能大于订单尾款");
        } else if (cePrice.compareTo(BigDecimal.ZERO) > 0) {
            order.setDjPrice(order.getDjPrice().add(price));
            order.setDjpTime(new Date());
        } else if (cePrice.compareTo(BigDecimal.ZERO) == 0) {
            order.setDjPrice(order.getDjPrice().add(price));
            order.setEndpTime(new Date());
        }

        JSONObject jsonObject = new JSONObject();
        BigDecimal newPayPrice = null;

        if(type.equals(1)){
            String uuid = UUID.randomUUID().toString().replace("-", "");

            jsonObject = LakalaUtils.createOrderPay(uuid, price, KlkConstant.DDHT_ORDER);
            if ("000000".equals(jsonObject.get("code"))) {
                System.out.println(jsonObject.get("resp_data").toString());
                JSONObject respData = jsonObject.getJSONObject("resp_data");
                String payOrderNo = respData.getString("pay_order_no");

                TpOrderPayBo orderPay = new TpOrderPayBo();
                orderPay.setOrderId(order.getId());
                orderPay.setOrderNum(order.getOrderId());
                orderPay.setUserId(order.getSid());
                orderPay.setUserName(sysUser.getRealName());
                orderPay.setUserPhone(sysUser.getPhonenumber());
                orderPay.setAmount(price);
                orderPay.setStatus(1);
                orderPay.setMethod(1);
                orderPay.setType(1);
                orderPay.setOrderNo(uuid);
                orderPay.setTransactionId(payOrderNo);
                orderPay.setCreateTime(new Date());
                orderPay.setRemark("订单拉卡拉支付");
                if (!tpOrderPayService.insertByBo(orderPay)){
                    throw new ServiceException("创建支付订单失败");
                }
            } else {
                throw new ServiceException("拉卡拉拉发起支付失败");
            }
            return jsonObject;
        }else if(type.equals(2)){
            if(sysUser.getYue().subtract(price).compareTo(BigDecimal.ZERO) < 0){
                throw new ServiceException("账户余额不足");
            }

            if(order.getCdPrice().compareTo(BigDecimal.ZERO) > 0){
                if(price.subtract(order.getCdPrice()).compareTo(BigDecimal.ZERO) >= 0){
                    newPayPrice = price.subtract(order.getCdPrice()).add(order.getPayPrice());
                    order.setKfpay(order.getKfpay().add(price.subtract(order.getCdPrice())));
                    order.setCdPrice(new BigDecimal(0));
                }else {
                    order.setCdPrice(order.getCdPrice().subtract(price));
                    order.setKfpay(new BigDecimal(0));
                    newPayPrice = order.getPayPrice();
                }
            }else {
                order.setKfpay(order.getKfpay().add(price));
                newPayPrice = price.add(order.getPayPrice());
            }

            sysUser.setYue(sysUser.getYue().subtract(price));
            sysUserMapper.updateById(sysUser);

            TpUserRecordBo bo = new TpUserRecordBo();
            bo.setUserId(order.getSid());
            bo.setUserName(sysUser.getUserName());
            bo.setUserPhone(sysUser.getPhonenumber());
            bo.setAmount(order.getPayPrice());
            bo.setBalance(sysUser.getYue());
            bo.setType(2);
            bo.setOrderId(order.getId());
            bo.setOrderNum(order.getOrderId());
            bo.setRemark("订单订单支付");
            bo.setCreateTime(new Date());
            if (!tpUserRecordService.insertByBo(bo)){
                throw new ServiceException("资金记录添加失败");
            }

            boolean res =  saveOrderRecord(order.getId(),"订单余额支付","订单:"+order.getOrderId()+" 支付金额："+price+" 成功",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }
        }

        if(order.getGjPrice() != null || order.getGjPrice().compareTo(BigDecimal.ZERO) > 0){
            order.setGpay(getGjPayPrice(order.getPrice(),newPayPrice,order.getGjPrice()));
        }
        order.setJsPayPrice(getJsPayPrice(order.getPrice(),newPayPrice,order.getPrice().subtract(order.getGjPrice()).subtract(order.getCdPrice())));
//        order.setState(2);
        order.setPayPrice(newPayPrice);
        order.setStatus(2);
        BigDecimal endPrice = order.getPrice().subtract(newPayPrice);
        order.setEndPrice(endPrice);
        if(endPrice.compareTo(BigDecimal.ZERO) > 0){
            order.setPayState(2);
        }else {
            order.setPayState(3);
        }
        if(baseMapper.updateById(order) > 0){
            jsonObject.put("code", "1");
            return jsonObject;
        }
        jsonObject.put("code", "-1");
        return jsonObject;
    }

    /**
     * 支付回调处理订单信息
     *
     * @param id
     * @param tradeNo
     * @param logNo
     * @param respData
     * @return
     */
    @Override
    public Boolean callbackOrder(Long id, TpOrderPay orderPay, String tradeNo, String logNo, JSONObject respData) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 3){
            throw new ServiceException("该订单已付清,不可再支付");
        }

        BigDecimal newPayPrice = orderPay.getAmount().add(order.getPayPrice());
        if(order.getGjPrice() != null || order.getGjPrice().compareTo(BigDecimal.ZERO) > 0){
            order.setGpay(getGjPayPrice(order.getPrice(),newPayPrice,order.getGjPrice()));
        }
        order.setJsPayPrice(getJsPayPrice(order.getPrice(),newPayPrice,order.getPrice().subtract(order.getGjPrice()).subtract(order.getCdPrice())));
//        order.setState(2);
        order.setPayPrice(newPayPrice);
        order.setStatus(2);
        BigDecimal endPrice = order.getPrice().subtract(newPayPrice);
        order.setEndPrice(endPrice);
        if(endPrice.compareTo(BigDecimal.ZERO) > 0){
            order.setPayState(2);
        }else {
            order.setPayState(3);
        }
        orderPay.setStatus(2);
        orderPay.setPayerInfo(String.valueOf(respData));
        if (paymentMapper.insert(orderPay) > 0){
            throw new ServiceException("更新支付订单失败");
        }
        boolean res =  saveOrderRecord(order.getId(),"订单拉卡拉支付","订单:"+order.getOrderId()+" 客户支付金额："+orderPay.getAmount()+" 成功",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单回退获取订单和退款金额信息
     * @param orderId
     * @return
     */
    @Override
    public TpOrderVo orderFallback(Long orderId) {
        LambdaQueryWrapper<TpOrder> lwq = new LambdaQueryWrapper<TpOrder>()
            .select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getPrice,TpOrder::getPayPrice,TpOrder::getKhpay,TpOrder::getKfpay,TpOrder::getCdPrice,TpOrder::getSid,TpOrder::getKid)
            .eq(TpOrder::getId,orderId);
        return baseMapper.selectVoOne(lwq);
    }

    /**
     * 订单回退
     * @param orderId
     * @param type
     * @param price
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int fallback(Long orderId, Integer type, BigDecimal price) {
        TpOrder order = baseMapper.selectById(orderId);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可回退");
        }
        //已支付减去回退金额
        BigDecimal payPrice = order.getPayPrice().subtract(price);
        if(payPrice.compareTo(BigDecimal.ZERO) < 0){
            throw new ServiceException("回退金额不可以大于已支付金额");
        } else if (payPrice.compareTo(BigDecimal.ZERO) > 0) {
            order.setPayState(2);
            order.setDjPrice(payPrice);
            order.setEndPrice(order.getPrice().subtract(payPrice));
        }else if (payPrice.compareTo(BigDecimal.ZERO) == 0) {
//            order.setState(1);
            order.setPayState(1);
            order.setStatus(1);
            order.setDjPrice(payPrice);
            order.setEndPrice(order.getPrice().subtract(payPrice));
        }
        if(type.equals(1)){
            if(order.getKhpay().subtract(order.getCdPrice()).subtract(price).compareTo(BigDecimal.ZERO) < 0){
                throw new ServiceException("回退金额不可以大于已支付金额");
            }
            TpClientStaff clientStaff = clientStaffMapper.selectById(order.getSkid());
            clientStaff.setYue(clientStaff.getYue().add(price));
            clientStaffMapper.updateById(clientStaff);
            TpClient client = clientMapper.selectById(clientStaff.getKid());
            client.setYue(client.getYue().add(price));
            clientMapper.updateById(client);
            order.setKhpay(order.getKhpay().subtract(price));

            boolean res =  saveOrderRecord(order.getId(),"订单回退","订单:"+order.getOrderId()+" 客户回退金额："+price+" 成功",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }
        }else if(type.equals(2)){
            if(order.getKfpay().subtract(order.getCdPrice()).subtract(price).compareTo(BigDecimal.ZERO) < 0){
                throw new ServiceException("回退金额不可以大于已支付金额");
            }
            SysUser sysUser = sysUserMapper.selectById(order.getSid());
            sysUser.setYue(sysUser.getYue().add(price));
            sysUserMapper.updateById(sysUser);
            order.setKfpay(order.getKfpay().subtract(price));

            boolean res =  saveOrderRecord(order.getId(),"订单回退","订单:"+order.getOrderId()+" 客服回退金额："+price+" 成功",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }
        }

        if(order.getGjPrice() != null || order.getGjPrice().compareTo(BigDecimal.ZERO) > 0){
            order.setGpay(getGjPayPrice(order.getPrice(),payPrice,order.getGjPrice()));
        }
        order.setJsPayPrice(getJsPayPrice(order.getPrice(),payPrice,order.getPrice().subtract(order.getGjPrice()).subtract(order.getCdPrice())));

        order.setPayPrice(payPrice);
        return baseMapper.updateById(order);
    }

    /**
     * 技术人员订单取消
     *
     * @param id
     * @return
     */
    @Override
    public Boolean jsOrderFallback(Long id) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可回退");
        }

        SysUser sysUser = sysUserMapper.selectById(order.getSid());
        sysUser.setYue(sysUser.getYue().add(order.getPayPrice()));
        if(sysUserMapper.updateById(sysUser) <= 0){
            throw new ServiceException("回退金额回退失败");
        }

        boolean res =  saveOrderRecord(order.getId(),"技术订单取消","订单:"+order.getOrderId()+" 回退金额："+order.getPayPrice()+" 成功",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }

        TpUserRecordBo bo = new TpUserRecordBo();
        bo.setUserId(order.getSid());
        bo.setUserName(sysUser.getUserName());
        bo.setUserPhone(sysUser.getPhonenumber());
        bo.setAmount(order.getPayPrice());
        bo.setBalance(sysUser.getYue());
        bo.setType(1);
        bo.setOrderId(order.getId());
        bo.setOrderNum(order.getOrderId());
        bo.setRemark("订单取消");
        bo.setCreateTime(new Date());
        if (!tpUserRecordService.insertByBo(bo)){
            throw new ServiceException("资金记录添加失败");
        }

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getBid());
        tpMessageBo.setToUserId(order.getSid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("技术已将订单:"+order.getOrderId()+" 取消");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        order.setStatus(7);
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单取消
     *
     * @param id
     * @return
     */
    @Override
    public Boolean orderCancel(Long id) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() != 1){
            if(order.getStatus() == 4 || order.getStatus() == 5 || order.getStatus() == 6 || order.getStatus() == 7){
                throw new ServiceException("该订单状态不可取消");
            }
            SysUser sysUser = sysUserMapper.selectById(order.getSid());
            sysUser.setYue(sysUser.getYue().add(order.getPayPrice()));
            if(sysUserMapper.updateById(sysUser) <= 0){
                throw new ServiceException("回退金额回退失败");
            }

            boolean res =  saveOrderRecord(order.getId(),"客户订单取消","订单:"+order.getOrderId()+" 回退金额："+order.getPayPrice()+" 成功",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }

            TpUserRecordBo bo = new TpUserRecordBo();
            bo.setUserId(order.getSid());
            bo.setUserName(sysUser.getUserName());
            bo.setUserPhone(sysUser.getPhonenumber());
            bo.setAmount(order.getPayPrice());
            bo.setBalance(sysUser.getYue());
            bo.setType(1);
            bo.setOrderId(order.getId());
            bo.setOrderNum(order.getOrderId());
            bo.setRemark("订单取消");
            bo.setCreateTime(new Date());
            if (!tpUserRecordService.insertByBo(bo)){
                throw new ServiceException("资金记录添加失败");
            }
        }
        if(order.getBid() != null){
            TpMessageBo tpMessageBo = new TpMessageBo();
            tpMessageBo.setUserId(order.getSid());
            tpMessageBo.setToUserId(order.getBid());
            tpMessageBo.setOrderId(order.getId());
            tpMessageBo.setOrderNum(order.getOrderId());
            tpMessageBo.setContent("订单:"+order.getOrderId()+" ，已被客户取消");
            tpMessageBo.setType(1);
            tpMessageBo.setCreateTime(new Date());
            tpMessageService.insertByBo(tpMessageBo);
        }
        order.setStatus(7);
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单退款
     *
     * @param id
     * @return
     */
    @Override
    public Boolean orderRefund(Long id) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可退款");
        }
        if(order.getState() == 2){
            throw new ServiceException("该订单已申请退款,不可退款");
        }
        if(order.getState() == 3){
            throw new ServiceException("该订单已退款,不可退款");
        }
        if(order.getStatus() == 6){
            throw new ServiceException("该订单已完成,不可退款");
        }
        if(order.getStatus() == 7){
            throw new ServiceException("该订单已取消,不可退款");
        }
        if(order.getStatus() == 1){
            throw new ServiceException("该订单未支付,不可退款");
        }
        order.setState(2);

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getSid());
        tpMessageBo.setToUserId(order.getBid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("订单:"+order.getOrderId()+" ，客户已申请退款");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        boolean res =  saveOrderRecord(order.getId(),"客户申请退款","订单:"+order.getOrderId()+" 申请退款金额："+order.getPayPrice()+" 元",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 技术人员订单处理退款
     *
     * @param bo
     * @return
     */
    @Override
    public Boolean orderRefundJs(TpOrderBo bo) {
        TpOrder order = baseMapper.selectById(bo.getId());
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可回退");
        }

        if(bo.getState() == 3){
            SysUser sysUser = sysUserMapper.selectById(order.getSid());
            sysUser.setYue(sysUser.getYue().add(order.getPayPrice()));
            if(sysUserMapper.updateById(sysUser) <= 0){
                throw new ServiceException("回退金额回退失败");
            }

            TpMessageBo tpMessageBo = new TpMessageBo();
            tpMessageBo.setUserId(order.getBid());
            tpMessageBo.setToUserId(order.getSid());
            tpMessageBo.setOrderId(order.getId());
            tpMessageBo.setOrderNum(order.getOrderId());
            tpMessageBo.setContent("订单:"+order.getOrderId()+" ，技术已同意退款");
            tpMessageBo.setType(1);
            tpMessageBo.setCreateTime(new Date());
            tpMessageService.insertByBo(tpMessageBo);

            TpUserRecordBo userRecordBo = new TpUserRecordBo();
            userRecordBo.setUserId(order.getSid());
            userRecordBo.setUserName(sysUser.getUserName());
            userRecordBo.setUserPhone(sysUser.getPhonenumber());
            userRecordBo.setAmount(order.getPayPrice());
            userRecordBo.setBalance(sysUser.getYue());
            userRecordBo.setType(1);
            userRecordBo.setOrderId(order.getId());
            userRecordBo.setOrderNum(order.getOrderId());
            userRecordBo.setRemark("订单取消");
            userRecordBo.setCreateTime(new Date());
            if (!tpUserRecordService.insertByBo(userRecordBo)){
                throw new ServiceException("资金记录添加失败");
            }

            boolean res =  saveOrderRecord(order.getId(),"技术同意退款","订单:"+order.getOrderId()+" 退款金额："+order.getPayPrice()+" 元",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }

            order.setStatus(7);
            order.setState(3);
        }else if(bo.getState() == 4){

            TpMessageBo tpMessageBo = new TpMessageBo();
            tpMessageBo.setUserId(order.getBid());
            tpMessageBo.setToUserId(order.getSid());
            tpMessageBo.setOrderId(order.getId());
            tpMessageBo.setOrderNum(order.getOrderId());
            tpMessageBo.setContent("订单:"+order.getOrderId()+" ，技术已拒绝退款");
            tpMessageBo.setType(1);
            tpMessageBo.setCreateTime(new Date());
            tpMessageService.insertByBo(tpMessageBo);

            order.setState(4);
            boolean res =  saveOrderRecord(order.getId(),"技术拒绝退款","订单:"+order.getOrderId()+" 退款金额："+order.getPayPrice()+" 元",1,null);
            if(!res){
                throw new ServiceException("操作记录添加失败");
            }
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单接单
     *
     * @param id
     * @param userId
     * @return
     */
    @Override
    public Boolean orderAccept(Long id, Long userId) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可操作");
        }
        if(order.getStatus() != 2){
            throw new ServiceException("该订单不是待接单状态,不可接单");
        }
        order.setStatus(3);

        SysUser sysUser = sysUserMapper.selectById(order.getBid());

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getBid());
        tpMessageBo.setToUserId(order.getSid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("订单:"+order.getOrderId()+" ，技术已被技术"+sysUser.getUserName()+"接单");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        boolean res =  saveOrderRecord(order.getId(),"技术订单","订单:"+order.getOrderId()+" 技术已接单",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单取消退款
     *
     * @param id
     * @return
     */
    @Override
    public Boolean orderCancelRefund(Long id) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可操作");
        }
        if(order.getState() != 2){
            throw new ServiceException("该订单不是申请退款状态");
        }
        order.setState(1);

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getSid());
        tpMessageBo.setToUserId(order.getBid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("订单:"+order.getOrderId()+" ，客户已取消退款");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        boolean res =  saveOrderRecord(order.getId(),"客户取消退款","订单:"+order.getOrderId()+" 取消退款，金额："+order.getPayPrice()+" 元",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单评价
     *
     * @param bo
     * @return
     */
    @Override
    public Boolean addComment(TpAppealsBo bo) {
        TpOrder order = baseMapper.selectById(bo.getId());
        if(order.getStatus() != 5){
            throw new ServiceException("该订单不是待评价状态,不可评价");
        }
        order.setStatus(6);

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getSid());
        tpMessageBo.setToUserId(order.getBid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("订单:"+order.getOrderId()+" ，客户已对此订单进行评价");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        boolean res =  saveOrderRecord(order.getId(),"客户评价订单","订单:"+order.getOrderId()+" 客户评价成功",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        baseMapper.updateById(order);

        //计算该技术平均评分，更到用户表
        SysUser user = sysUserMapper.selectById(order.getSid());
        List<TpOrder> list = baseMapper.selectList(new LambdaQueryWrapper<TpOrder>().eq(TpOrder::getSid, order.getSid()).eq(TpOrder::getStatus, 6));
        if(list.size() > 0){
            //总评分
            BigDecimal scoreSum = list.stream().map(f -> new BigDecimal(String.valueOf(f.getScore()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal score = new BigDecimal(0);
            score = scoreSum.divide(new BigDecimal(list.size()),2,BigDecimal.ROUND_HALF_UP);
            user.setScore(score.doubleValue());
            return sysUserMapper.updateById(user) > 0;
        }
        return true;
    }

    /**
     * 订单确认
     *
     * @param id
     * @return
     */
    @Override
    public Boolean orderConfirm(Long id) {
        TpOrder order = baseMapper.selectById(id);
        if(order.getPayState() == 1){
            throw new ServiceException("该订单未支付,不可操作");
        }
        if(order.getStatus() != 3){
            throw new ServiceException("该订单不是待确认状态,不可操作");
        }
        order.setStatus(4);

        TpMessageBo tpMessageBo = new TpMessageBo();
        tpMessageBo.setUserId(order.getSid());
        tpMessageBo.setToUserId(order.getBid());
        tpMessageBo.setOrderId(order.getId());
        tpMessageBo.setOrderNum(order.getOrderId());
        tpMessageBo.setContent("订单:"+order.getOrderId()+" ，客户已确认由你去完成订单");
        tpMessageBo.setType(1);
        tpMessageBo.setCreateTime(new Date());
        tpMessageService.insertByBo(tpMessageBo);

        boolean res =  saveOrderRecord(order.getId(),"客户确认订单","订单:"+order.getOrderId()+" 已确认技术接单",1,null);
        if(!res){
            throw new ServiceException("操作记录添加失败");
        }
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 订单统计
     *
     * @param userId
     * @return
     */
    @Override
    public OrderCountVo orderCount(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        OrderCountVo orderCountVo = new OrderCountVo();
        Long orderCount = null;
        BigDecimal orderPrice = null;
        BigDecimal orderMonthPrice = null;
        BigDecimal orderAvgPrice = null;
        if(sysUser.getIdentity() == 2){
            orderCount = baseMapper.selectCount(new LambdaQueryWrapper<TpOrder>()
                .eq(TpOrder::getBid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1));

            orderPrice = baseMapper.selectList(new LambdaQueryWrapper<TpOrder>()
                .select(TpOrder::getPrice)
                .eq(TpOrder::getBid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1)).stream().map(TpOrder::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

            orderMonthPrice = baseMapper.selectList(new LambdaQueryWrapper<TpOrder>()
                .select(TpOrder::getPrice)
                .eq(TpOrder::getBid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1)
                .between(TpOrder::getAddTime, DateUtil.beginOfMonth(new Date()), DateUtil.endOfMonth(new Date()))).stream().map(TpOrder::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

            orderAvgPrice = orderPrice.divide(new BigDecimal(orderCount),2,BigDecimal.ROUND_HALF_UP);
        }else if(sysUser.getIdentity() == 5){
            orderCount = baseMapper.selectCount(new LambdaQueryWrapper<TpOrder>()
                .eq(TpOrder::getSid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1));

            orderPrice = baseMapper.selectList(new LambdaQueryWrapper<TpOrder>()
                .select(TpOrder::getPrice)
                .eq(TpOrder::getSid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1)).stream().map(TpOrder::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

            orderMonthPrice = baseMapper.selectList(new LambdaQueryWrapper<TpOrder>()
                .select(TpOrder::getPrice)
                .eq(TpOrder::getSid, userId)
                .ne(TpOrder::getPayState, 1)
                .eq(TpOrder::getIsDel, 1)
                .between(TpOrder::getAddTime, DateUtil.beginOfMonth(new Date()), DateUtil.endOfMonth(new Date()))).stream().map(TpOrder::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);

            orderAvgPrice = orderPrice.divide(new BigDecimal(orderCount),2,BigDecimal.ROUND_HALF_UP);
        }
        orderCountVo.setOrderCount(orderCount);
        orderCountVo.setOrderPrice(orderPrice);
        orderCountVo.setOrderMonthPrice(orderMonthPrice);
        orderCountVo.setOrderAvgPrice(orderAvgPrice);
        return orderCountVo;
    }

    /**
     * 订单拆单获取订单和金额信息
     * @param orderId
     * @return
     */
    @Override
    public TpOrderVo cdOrderInfo(Long orderId) {
        LambdaQueryWrapper<TpOrder> lwq = new LambdaQueryWrapper<TpOrder>()
            .select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getPrice,TpOrder::getPayPrice,TpOrder::getCdPrice,TpOrder::getKhpay,TpOrder::getSid,TpOrder::getKid,TpOrder::getAddTime)
            .eq(TpOrder::getId,orderId);
        TpOrderVo orderVo = baseMapper.selectVoOne(lwq);
        orderVo.setJsPrice(orderVo.getPrice().subtract(orderVo.getCdPrice()));
        return orderVo;
    }

    /**
     * 订单拆单
     * @param orderId
     * @param price
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int cdOrder(Long orderId, BigDecimal price) {
        TpOrder order = baseMapper.selectById(orderId);
        if (order.getIsCd() == 2) {
            throw new ServiceException("该订单已拆单");
        }
        if(order.getKfpay().compareTo(BigDecimal.ZERO) > 0){
            throw new ServiceException("该订单客服已用余额支付,不可拆单");
        }
        //已支付减去拆单金额
        BigDecimal payPrice = order.getKhpay().subtract(price);
        if(payPrice.compareTo(BigDecimal.ZERO) < 0){
            throw new ServiceException("拆单金额不能大于客户已付金额");
        }
        if(order.getPayState() != 1){
            order.setCdPrice(price);
            order.setJsPrice(order.getPrice().subtract(order.getGjPrice()).subtract(price));
            if(order.getGjPrice() != null || order.getGjPrice().compareTo(BigDecimal.ZERO) > 0){
                order.setGpay(getGjPayPrice(order.getPrice(),order.getPayPrice(),order.getGjPrice()));
            }
            order.setJsPayPrice(getJsPayPrice(order.getPrice(),order.getPayPrice(),order.getPrice().subtract(order.getGjPrice()).subtract(price)));
        }
        boolean res =  saveOrderRecord(order.getId(),"订单拆单","订单:"+order.getOrderId()+"拆单成功！拆单金额："+price,1,null);
        if(!res){
            throw new ServiceException("订单拆单失败");
        }
        order.setIsCd(2);

        SysUser sysUser = sysUserMapper.selectById(order.getSid());
        sysUser.setYue(sysUser.getYue().add(price));
        sysUserMapper.updateById(sysUser);

        return baseMapper.updateById(order);
    }

    /**
     * 订单改价获取订单和金额信息
     * @param orderId 主键
     */
    @Override
    public TpOrderVo gjOrderInfo(Long orderId) {
        LambdaQueryWrapper<TpOrder> lwq = new LambdaQueryWrapper<TpOrder>()
            .select(TpOrder::getId,TpOrder::getOrderId,TpOrder::getPrice,TpOrder::getPayPrice,TpOrder::getJsPrice,TpOrder::getCdPrice,TpOrder::getGjPrice,TpOrder::getSid,TpOrder::getKid,TpOrder::getAddTime)
            .eq(TpOrder::getId,orderId);
        return baseMapper.selectVoOne(lwq);
    }

    /**
     * 订单改价
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int gjOrder(Long orderId, BigDecimal price) {
        TpOrder order = baseMapper.selectById(orderId);
        //已支付减去改价金额
        BigDecimal payPrice = order.getPayPrice().subtract(price);
        if(order.getPayState() != 1){
            if(payPrice.compareTo(BigDecimal.ZERO) < 0){
                throw new ServiceException("改价金额不能大于客户已付金额");
            }
            order.setGjPrice(price);
            order.setJsPrice(order.getPrice().subtract(order.getCdPrice()).subtract(price));
            order.setGpay(getGjPayPrice(order.getPrice(),order.getPayPrice(),price));
            order.setJsPayPrice(getJsPayPrice(order.getPrice(),order.getPayPrice(),order.getPrice().subtract(order.getCdPrice()).subtract(price)));
        }else{
            order.setGjPrice(price);
            order.setJsPrice(order.getPrice().subtract(order.getCdPrice()).subtract(price));
        }
        boolean res =  saveOrderRecord(order.getId(),"订单改价","订单:"+order.getOrderId()+"改价成功！改价金额："+price,2,null);
        if(!res){
            throw new ServiceException("订单改价失败");
        }
        return baseMapper.updateById(order);
    }

    /**
     * 查询订单统计（客服）
     * @param bo
     * @return
     */
    @Override
    public CustomerOrderSumVo queryCustomerSum(TpOrderBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        CustomerOrderSumVo vo = new CustomerOrderSumVo();
        bo.setIsDel(1);

        MPJLambdaWrapper<TpOrder> mlqw = buildQueryMPJWrapperKF(bo);
        mlqw.leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid);
        Long orderCount = baseMapper.selectJoinCount(mlqw);
        vo.setOrderCount(orderCount);

        MPJLambdaWrapper<TpOrder> lqw = buildQueryMPJWrapperKF(bo);
        lqw.select(TpOrder::getId,TpOrder::getPrice,TpOrder::getPayPrice,TpOrder::getGjPrice,TpOrder::getGpay,TpOrder::getCdPrice,TpOrder::getKfpay)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .leftJoin(TpClientStaff.class,TpClientStaff::getId,TpOrder::getSkid)
            .leftJoin(TpWechat.class,TpWechat::getId,TpOrder::getWid);

        List<TpOrderVo> list = baseMapper.selectJoinList(TpOrderVo.class,lqw);
        BigDecimal zyjSum = list.stream().map(f -> new BigDecimal(String.valueOf(f.getPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal ydkSum = list.stream().map(f -> new BigDecimal(String.valueOf(f.getPayPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal cdze = list.stream().map(f -> new BigDecimal(String.valueOf(f.getCdPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        //BigDecimal cdyfk = list.stream().map(f -> new BigDecimal(String.valueOf(f.getKfpay()))).reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal cdyfk = new BigDecimal(0);
        if(StringUtils.isNotBlank(bo.getOrderId()) || bo.getDeptIds() != null || bo.getPhone() != null || StringUtils.isNotBlank(bo.getWcode()) || StringUtils.isNotBlank(bo.getScode()) || StringUtils.isNotBlank(bo.getBcode()) || StringUtils.isNotBlank(bo.getFcode()) || bo.getAssignState() != null || bo.getStyle() != null || StringUtils.isNotBlank(bo.getSpace()) || bo.getQuality() != null || bo.getType() != null || bo.getState() != null || StringUtils.isNotBlank(bo.getRemark()) || StringUtils.isNotBlank(bo.getJsRemark()) || bo.getPayState() != null || bo.getIsC() != null){
            List<Long> oids = list.stream().map(TpOrderVo::getId).collect(Collectors.toList());
            if(oids.size() > 0){
                cdyfk = staffPayMapper.selectList(new LambdaQueryWrapper<TpStaffPay>().select(TpStaffPay::getPrice).in(TpStaffPay::getOid,oids)).stream().map(TpStaffPay::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
        }else{
            if(loginUser.getIdentity() == 3){
                cdyfk = staffPayMapper.selectList(new LambdaQueryWrapper<TpStaffPay>().select(TpStaffPay::getPrice).eq(TpStaffPay::getAddUser,loginUser.getIdentity()).between(TpStaffPay::getAddTime,bo.getParams().get("addBeginTime"),bo.getParams().get("addEndTime"))).stream().map(TpStaffPay::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            }else {
                cdyfk = staffPayMapper.selectList(new LambdaQueryWrapper<TpStaffPay>().select(TpStaffPay::getPrice).between(TpStaffPay::getAddTime,bo.getParams().get("addBeginTime"),bo.getParams().get("addEndTime"))).stream().map(TpStaffPay::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
        }
        BigDecimal gjyj = list.stream().map(f -> new BigDecimal(String.valueOf(f.getGjPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal gjydk = list.stream().map(f -> new BigDecimal(String.valueOf(f.getGpay()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        vo.setGjyj(gjyj);
        vo.setGjydk(gjydk);

        vo.setZyjSum(zyjSum);
        vo.setYdkSum(ydkSum);
        vo.setWdkSum(zyjSum.subtract(ydkSum));
        // 检查 zyjSum 是否为零
        if (zyjSum.compareTo(BigDecimal.ZERO) == 0) {
            vo.setDkl("0%");
        } else {
            BigDecimal dkl = ydkSum.divide(zyjSum, 2, RoundingMode.HALF_UP);
            vo.setDkl(dkl.multiply(BigDecimal.valueOf(100)) + "%");
        }
        // 检查 orderCount 是否为零
        if (orderCount == 0) {
            vo.setJj(BigDecimal.ZERO);
        } else {
            vo.setJj(zyjSum.divide(BigDecimal.valueOf(orderCount), 2, RoundingMode.HALF_UP));
        }
        vo.setCdze(cdze);
        vo.setCdyfk(cdyfk);
        vo.setSjydk(ydkSum.subtract(cdyfk));
        return vo;
    }

    /**
     *查询订单统计（技术）
     * @param bo
     * @return
     */
    @Override
    public SkillOrderSumVo querySkillSum(TpOrderBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser != null && loginUser.getIdentity() == 3){
            throw new ServiceException("您无权限查看技术订单列表");
        }
        SkillOrderSumVo vo = new SkillOrderSumVo();
        bo.setIsDel(1);
        MPJLambdaWrapper<TpOrder> lqw = buildQueryMPJWrapper(bo);
        lqw.leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .isNotNull(TpOrder::getBid);
        Long orderCount = baseMapper.selectJoinCount(lqw);
        vo.setOrderCount(orderCount);

        MPJLambdaWrapper<TpOrder> olqw = buildQueryMPJWrapper(bo);
        olqw.select(TpOrder::getId,TpOrder::getPrice,TpOrder::getGjPrice,TpOrder::getJsPrice,TpOrder::getJsPayPrice)
            .leftJoin(SysUser.class,"s",SysUser::getUserId,TpOrder::getSid)
            .leftJoin(SysUser.class,"f",SysUser::getUserId,TpOrder::getFid)
            .leftJoin(SysUser.class,"b",SysUser::getUserId,TpOrder::getBid)
            .leftJoin(TpClient.class,TpClient::getId,TpOrder::getKid)
            .isNotNull(TpOrder::getBid);
        List<TpOrderVo> list = baseMapper.selectJoinList(TpOrderVo.class,olqw);
        BigDecimal zyjSum = list.stream().map(f -> new BigDecimal(String.valueOf(f.getPrice().subtract(f.getGjPrice())))).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal ydkSum = list.stream().map(f -> new BigDecimal(String.valueOf(f.getJsPayPrice()))).reduce(BigDecimal.ZERO, BigDecimal::add);

        vo.setZyjSum(zyjSum);
        vo.setYdkSum(ydkSum);
        // 检查 zyjSum 是否为零
        if (zyjSum.compareTo(BigDecimal.ZERO) == 0) {
            vo.setDkl("0%");
        } else {
            BigDecimal dkl = ydkSum.divide(zyjSum, 2, RoundingMode.HALF_UP);
            vo.setDkl(dkl.multiply(BigDecimal.valueOf(100)) + "%");
        }
        //List结果集取订单ID
        List<Long> newList = list.stream().map(TpOrderVo::getId).collect(Collectors.toList());
        // 确保 newList 不为空
        if (newList != null && newList.size() > 0) {
            LambdaQueryWrapper<TpOrderSmall> lwq1 = new LambdaQueryWrapper<>();
//        lwq1.inSql(TpOrderSmall::getOid,"select id from tp_order where is_del = 1");
            lwq1.in(TpOrderSmall::getOid,newList);
            Long ycxt = smallMapper.selectCount(lwq1);

            LambdaQueryWrapper<TpOrderBig> lwq2 = new LambdaQueryWrapper<>();
//        lwq2.in(TpOrderBig::getOid,"select id from tp_order where is_del = 1");
            lwq2.in(TpOrderBig::getOid,newList);
            Long ycdt = bigMapper.selectCount(lwq2);

            LambdaQueryWrapper<TpOrderModel> lwq3 = new LambdaQueryWrapper<>();
//        lwq3.in(TpOrderModel::getOid,"select id from tp_order where is_del = 1");
            lwq3.in(TpOrderModel::getOid,newList);
            Long ycmx = modelMapper.selectCount(lwq3);

            vo.setYcxt(ycxt);
            vo.setYcdt(ycdt);
            vo.setYcmx(ycmx);
        }else {
            vo.setYcxt(0L);
            vo.setYcdt(0L);
            vo.setYcmx(0L);
        }
        return vo;
    }

    //获取订单编号
    public static String genItemId() {
        //取当前时间的长整形值包含毫秒
        long millis = System.currentTimeMillis();
        String result = String.valueOf(millis).substring(6, 13);
        //加上两位随机数
        Random random = new Random();
        int end2 = random.nextInt(99);
        //如果不足两位前面补0
        return "DD" + result + String.format("%02d", end2);
    }

    //插入操作记录
    public Boolean saveOrderRecord(Long orderId, String type,String content,Integer state,String record) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        TpOrderRecord orderRecord = new TpOrderRecord();
        orderRecord.setOid(orderId);
        orderRecord.setType(type);
        orderRecord.setContent(content);
        orderRecord.setAddUser(loginUser.getUserId());
        orderRecord.setAddTime(new Date());
        orderRecord.setState(state);
        if(record != null){
            orderRecord.setRecord(record);
        }
        return recordMapper.insert(orderRecord) > 0;
    }

    //改价已支付
    public BigDecimal getGjPayPrice(BigDecimal price,BigDecimal payPrice,BigDecimal gjPrice){
        BigDecimal bili = payPrice.divide(price,6,RoundingMode.HALF_UP);
        return gjPrice.multiply(bili).setScale(2, RoundingMode.HALF_UP);
    }

    //技术已支付
    public BigDecimal getJsPayPrice(BigDecimal price,BigDecimal payPrice,BigDecimal jsPrice){
        BigDecimal bili = payPrice.divide(price, 6, RoundingMode.HALF_UP);
        return jsPrice.multiply(bili).setScale(2, RoundingMode.HALF_UP);
    }

    public int getDataScope() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<String> ids = loginUser != null ?
            loginUser.getRoles().stream().filter(Objects::nonNull).map(role -> role.getDataScope()).filter(Objects::nonNull).collect(Collectors.toList()) :
            Collections.emptyList();

        if (ids.contains("1")) {
            return 1;
        } else if (ids.contains("2")) {
            return 2;
        } else if (ids.contains("3")) {
            return 3;
        } else if (ids.contains("4")) {
            return 4;
        } else if (ids.contains("5")) {
            return 5;
        }
        return 0;
    }

    public List<Long> getDeptIds(){
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<Long> roleIds = loginUser.getRoles().stream().map(RoleDTO::getRoleId).collect(Collectors.toList());
        List<Long> getDeptIds = roleDeptMapper.selectList(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, roleIds)).stream().map(SysRoleDept::getDeptId).collect(Collectors.toList());
        return getDeptIds.stream().distinct().collect(Collectors.toList());
    }

    public List<Long> getOrderTypeIds(){
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<Long> roleIds = loginUser.getRoles().stream().map(RoleDTO::getRoleId).collect(Collectors.toList());
        List<String> orderTypeIds = roleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, roleIds)).stream().map(SysRole::getOrderType).collect(Collectors.toList());
        // 使用 StringBuilder 拼接字符串
        StringBuilder sb = new StringBuilder();
        for (String orderType : orderTypeIds) {
            sb.append(orderType).append(",");
        }
        // 去除最后一个多余的逗号
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }
        List<Long> getOrderTypeIds = Arrays.stream(sb.toString().split(",")).map(Long::parseLong).collect(Collectors.toList());
        return getOrderTypeIds.stream().distinct().collect(Collectors.toList());
    }

    // 取大于等于num的最小1000倍数
    public static int getMinMultipleOfOneThousand(int num) {
        return num / 1000 * 1000;
    }

    /**
     * 判断时间是否在今天9点之后
     * @param inputDateTime
     * @return
     */
    public static boolean isNotBeforeToday9AM(String inputDateTime) {
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将输入的字符串转换为LocalDateTime对象
        LocalDateTime inputLocalDateTime = LocalDateTime.parse(inputDateTime, formatter);
        // 获取今天的日期
        LocalDateTime today9AM = LocalDateTime.now().toLocalDate().atTime(0, 0);
        // 比较两个日期时间
        return !inputLocalDateTime.isBefore(today9AM);
    }
}
