package shop.alien.lawyer.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.LawyerConsultationOrderVO;
import shop.alien.entity.store.vo.WebSocketVo;
import shop.alien.lawyer.config.WebSocketProcess;
import shop.alien.lawyer.feign.AlienStoreFeign;
import shop.alien.lawyer.service.LawyerClientConsultationOrderService;
import shop.alien.lawyer.service.LawyerUserService;
import shop.alien.lawyer.service.OrderExpirationService;
import shop.alien.mapper.*;
import shop.alien.util.common.constant.LawyerStatusEnum;
import shop.alien.util.common.constant.OrderActionType;
import shop.alien.util.type.LifeMessageUtil;
import shop.alien.util.type.LifeNoticeUtil;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 咨询订单 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Transactional
@Service
@RequiredArgsConstructor
public class LawyerClientConsultationOrderServiceImpl extends ServiceImpl<LawyerConsultationOrderMapper, LawyerConsultationOrder> implements LawyerClientConsultationOrderService {

    private final LawyerConsultationOrderMapper consultationOrderMapper;
    private final LawyerUserService lawyerUserService;
    private final LawyerServiceAreaMapper lawyerServiceAreaMapper;
    private final LawyerUserMapper lawyerUserMapper;
    private final OrderExpirationService orderExpirationService;
    private final AlienStoreFeign alienStoreFeign;
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;
    private final LifeUserMapper lifeUserMapper;
    private final WebSocketProcess webSocketProcess;
    private final LifeMessageMapper lifeMessageMapper;
    private final LifeMessageUtil lifeMessageUtil;
    private final LawFirmMapper lawFirmMapper;

    /**
     * 系统发送者ID常量
     */
    private static final String SYSTEM_SENDER_ID = "system";

    /**
     * 同意退款动作标识
     */
    private static final String ACTION_AGREE = "1";

    /**
     * 拒绝退款动作标识
     */
    private static final String ACTION_REJECT = "2";

    /**
     * 已申请退款状态
     */
    private static final String REFUND_STATUS_APPLIED = "1";

    /**
     * 律师已拒绝退款状态
     */
    private static final String REFUND_STATUS_REJECTED = "2";

    /**
     * 律师已同意退款状态
     */
    private static final String REFUND_STATUS_AGREED = "3";

    /**
     * 分钟转秒的转换系数
     */
    private static final long MINUTE_TO_SECOND = 60L;

    /**
     * 律师发送者ID前缀
     */
    private static final String LAWYER_SENDER_PREFIX = "lawyer_";

    /**
     * 用户接收者ID前缀
     */
    private static final String USER_RECEIVER_PREFIX = "user_";

    /**
     * 删除标记：未删除
     */
    private static final Integer DELETE_FLAG_NOT_DELETED = 0;

    @Value("${order.coefficient}")
    private String coefficient;
    @Value("${order.coefficients}")
    private String coefficients;



    /**
     * 删除咨询订单
     * <p>
     * 删除前会进行以下校验：
     * 1. 参数校验：订单ID不能为空
     * 2. 订单存在性校验：订单必须存在
     * 3. 订单状态校验：进行中的订单不允许删除
     * 4. 如果订单是待支付状态，会取消Redis中的支付超时计时器
     * </p>
     *
     * @param id 订单ID
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> deleteConsultationOrder(Integer id) {
        log.info("开始删除咨询订单，订单ID={}", id);

        // 参数校验
        if (id == null) {
            log.warn("删除咨询订单失败：订单ID为空");
            return R.fail("订单ID不能为空");
        }

        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(id);
        if (order == null) {
            log.warn("删除咨询订单失败：订单不存在，订单ID={}", id);
            return R.fail("订单不存在");
        }

        // 检查订单状态：进行中的订单不允许删除
        Integer orderStatus = order.getOrderStatus();
        Integer inProgressStatus = LawyerStatusEnum.INPROGRESS.getStatus(); // 2:进行中
        if (inProgressStatus.equals(orderStatus)) {
            log.warn("删除咨询订单失败：订单进行中，不允许删除，订单ID={}, 订单编号={}",
                    id, order.getOrderNumber());
            return R.fail("订单进行中，不允许删除");
        }

        // 如果订单是待支付状态，取消Redis中的订单支付超时计时
        Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus(); // 0:待支付
        if (waitPayStatus.equals(orderStatus) && order.getOrderNumber() != null) {
            try {
                orderExpirationService.cancelOrderPaymentTimeout(order.getOrderNumber());
                log.info("已取消订单支付超时计时，订单编号={}", order.getOrderNumber());
            } catch (Exception e) {
                log.error("取消订单支付超时计时失败，订单编号={}", order.getOrderNumber(), e);
                // 继续执行删除操作，不因取消计时器失败而中断
            }
        }

        // 执行删除操作
        boolean result = this.removeById(id);
        if (result) {
            log.info("删除咨询订单成功，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.data(true, "删除成功");
        } else {
            log.error("删除咨询订单失败：数据库操作失败，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.fail("删除失败");
        }
    }

    /**
     * 填充律师服务领域信息到订单VO列表
     *
     * @param voPage 订单VO分页对象
     */
    private void fillLawyerServiceArea(IPage<LawyerConsultationOrderVO> voPage) {
        List<LawyerConsultationOrderVO> orderList = voPage.getRecords();
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }

        // 提取所有律师ID
        List<Integer> lawyerIdList = orderList.stream()
                .map(LawyerConsultationOrderVO::getLawyerUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(lawyerIdList)) {
            return;
        }

        // 批量查询律师问题场景
        Map<String, List<String>> serviceAreaMap = getLawyerServiceArea(lawyerIdList);
        if (serviceAreaMap.isEmpty()) {
            return;
        }

        // 填充问题场景
        orderList.forEach(order -> {
            Integer lawyerUserId = order.getLawyerUserId();
            if (lawyerUserId != null) {
                String lawyerUserIdStr = String.valueOf(lawyerUserId);
                List<String> serviceAreaList = serviceAreaMap.get(lawyerUserIdStr);
                if (CollectionUtils.isNotEmpty(serviceAreaList)) {
                    order.setLawyerLegalProblemScenarioList(serviceAreaList);
                }
            }
        });
    }

    /**
     * 批量查询律师问题场景
     *
     * @param lawyerIdList 律师ID列表
     * @return 律师问题场景Map，key为律师ID（String），value为问题场景名称列表
     */
    private Map<String, List<String>> getLawyerServiceArea(List<Integer> lawyerIdList) {
        Map<String, List<String>> serviceAreaMap = new HashMap<>();
        if (CollectionUtils.isEmpty(lawyerIdList)) {
            return serviceAreaMap;
        }

        QueryWrapper<LawyerServiceArea> wrapper = new QueryWrapper<>();
        wrapper.in("lsa.lawyer_user_id", lawyerIdList)
                .eq("lsa.delete_flag", 0)
                .eq("lsa.status", 1);

        List<Map<String, Object>> serviceAreaDataList = lawyerServiceAreaMapper.getLawyerLegalProblemScenarioList(wrapper);
        if (CollectionUtils.isEmpty(serviceAreaDataList)) {
            return serviceAreaMap;
        }

        for (Map<String, Object> row : serviceAreaDataList) {
            Object lawyerUserIdObj = row.get("lawyer_user_id");
            if (lawyerUserIdObj == null) {
                continue;
            }

            String lawyerUserId = String.valueOf(lawyerUserIdObj);
            String scenarioName = (String) row.get("name");
            String scenarioNameValue = StringUtils.hasText(scenarioName) ? scenarioName : "";

            serviceAreaMap.computeIfAbsent(lawyerUserId, k -> new ArrayList<>())
                    .add(scenarioNameValue);
        }

        return serviceAreaMap;
    }

    /**
     * 获取咨询订单详情
     * <p>
     * 查询订单基本信息、律师信息和律师问题场景信息
     * </p>
     *
     * @param lawyerOrderId 订单ID
     * @return 咨询订单详情VO，如果订单不存在或参数为空则返回空对象
     */
    @Override
    public LawyerConsultationOrderVO getConsultationOrderDetail(String lawyerOrderId) {
        log.info("获取咨询订单详情，订单ID={}", lawyerOrderId);

        // 参数校验
        if (!StringUtils.hasText(lawyerOrderId)) {
            log.warn("获取咨询订单详情失败：订单ID为空");
            return new LawyerConsultationOrderVO();
        }

        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(lawyerOrderId);
        if (order == null) {
            log.warn("获取咨询订单详情失败：订单不存在，订单ID={}", lawyerOrderId);
            return new LawyerConsultationOrderVO();
        }

        // 复制订单基本信息
        LawyerConsultationOrderVO orderVO = new LawyerConsultationOrderVO();
        BeanUtils.copyProperties(order, orderVO);

        // 填充律师相关信息
        fillLawyerRelatedInfo(orderVO, order.getLawyerUserId());

        return orderVO;
    }

    /**
     * 填充律师相关信息到订单VO
     * <p>
     * 包括律师基本信息和律师问题场景列表
     * </p>
     *
     * @param orderVO    订单VO对象
     * @param lawyerUserId 律师用户ID
     */
    private void fillLawyerRelatedInfo(LawyerConsultationOrderVO orderVO, Integer lawyerUserId) {
        if (lawyerUserId == null) {
            return;
        }

        // 查询并填充律师基本信息
        LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerUserId);
        if (lawyerUser != null) {
            fillLawyerInfo(orderVO, lawyerUser);
        }

        // 查询并填充律师问题场景
        fillLawyerServiceAreaForOrder(orderVO, lawyerUserId);
    }

    /**
     * 填充律师问题场景信息到订单VO
     *
     * @param orderVO     订单VO对象
     * @param lawyerUserId 律师用户ID
     */
    private void fillLawyerServiceAreaForOrder(LawyerConsultationOrderVO orderVO, Integer lawyerUserId) {
        List<Integer> lawyerIdList = Collections.singletonList(lawyerUserId);
        Map<String, List<String>> serviceAreaMap = getLawyerServiceArea(lawyerIdList);

        if (serviceAreaMap.isEmpty()) {
            return;
        }

        String lawyerUserIdStr = String.valueOf(lawyerUserId);
        List<String> serviceAreaList = serviceAreaMap.get(lawyerUserIdStr);
        if (CollectionUtils.isNotEmpty(serviceAreaList)) {
            orderVO.setLawyerLegalProblemScenarioList(serviceAreaList);
        }
    }

    /**
     * 查询咨询订单信息（律师端）
     *
     * @param pageNum        页码
     * @param pageSize       页容量
     * @param startDate      开始时间
     * @param endDate        结束时间
     * @param clientUserName 客户端用户名
     * @param orderStatus    订单状态
     * @param lawyerId       律师ID
     * @return 订单信息Map，包含订单列表、总数、进行中数量、已完成数量
     */
    @Override
    public Map<String, Object> getLawyerConsultationOrderInfo(int pageNum, int pageSize, String startDate,
            String endDate, String clientUserName, String orderStatus, String lawyerId) {
        log.info("查询咨询订单信息（律师端）- pageNum={}, pageSize={}, startDate={}, endDate={}, "
                + "clientUserName={}, orderStatus={}, lawyerId={}",
                pageNum, pageSize, startDate, endDate, clientUserName, orderStatus, lawyerId);

        // 参数校验：律师ID不能为空
        if (!StringUtils.hasText(lawyerId)) {
            log.warn("查询咨询订单信息失败：律师ID为空");
            return buildEmptyResultMap(pageNum, pageSize);
        }

        // 创建分页对象
        Page<LawyerConsultationOrderVO> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        QueryWrapper<LawyerConsultationOrderVO> queryWrapper = buildOrderQueryWrapper(
                lawyerId, orderStatus, clientUserName, startDate, endDate);
        QueryWrapper<LawyerConsultationOrderVO> statisticsWrapper = buildStatisticsQueryWrapper(
                lawyerId, clientUserName,startDate, endDate);

        // 查询订单列表
        IPage<LawyerConsultationOrderVO> voPage = consultationOrderMapper.getLawyerConsultationOrderInfo(
                page, queryWrapper);

        // 填充律师问题场景信息
        if (voPage != null) {
            fillLawyerServiceArea(voPage);
            // 为待支付订单计算倒计时（30分钟有效期）
            calculateCountdownForPendingOrders(voPage);
            //填充未读消息
            fillUnreadMessage(voPage,lawyerId);
        }

        // 获取统计信息
        statisticsWrapper.groupBy("lco.order_status");
        List<Map<String, Object>> statisticsInfo = consultationOrderMapper.getLawyerStatisticsInfo(
                statisticsWrapper);

        // 构建状态统计Map并计算各状态订单数量
        Map<Integer, Integer> statusCountMap = buildStatusCountMap(statisticsInfo);
        Map<String, Integer> orderStatistics = calculateOrderStatistics(statusCountMap);

        // 构建返回结果
        return buildResultMap(voPage, orderStatistics);
    }

    /**
     * 填充未读消息数量
     *
     * @param voPage 订单VO分页对象
     */
    private void fillUnreadMessage(IPage<LawyerConsultationOrderVO> voPage,String lawyerId) {
        List<LawyerConsultationOrderVO> orderList = voPage.getRecords();
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }

        // 提取所有律师ID，并加上lawyer_前缀
        List<String> lawyerIdList = orderList.stream()
                .map(LawyerConsultationOrderVO::getClientUserPhone)
                .filter(Objects::nonNull)
                .map(phone -> "user_" + phone)
                .distinct()
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(lawyerIdList)) {
            return;
        }

        LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerId);
        String phone = lawyerUser.getPhone();

        LambdaQueryWrapper<LifeMessage> lifeMessageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        lifeMessageUtil.applySenderInQuery(lifeMessageLambdaQueryWrapper, lawyerIdList);
        lifeMessageLambdaQueryWrapper.eq(LifeMessage::getDeleteFlag, 0);
        lifeMessageLambdaQueryWrapper.eq(LifeMessage::getIsRead, 0);
        lifeMessageUtil.applyReceiverQuery(lifeMessageLambdaQueryWrapper, "lawyer_" + phone);
        List<LifeMessage> lifeMessageList = lifeMessageMapper.selectList(lifeMessageLambdaQueryWrapper);


        // 按照senderId进行分组，返回senderId和数量的map
        Map<String, Long> senderIdCountMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(lifeMessageList)){
            senderIdCountMap = lifeMessageList.stream()
                    .collect(Collectors.groupingBy(LifeMessage::getSenderId, Collectors.counting()));
        }

        for(LawyerConsultationOrderVO lawyerConsultationOrderVO : voPage.getRecords()){
            String lawyerPhone = "user_" + lawyerConsultationOrderVO.getClientUserPhone();
            if(!senderIdCountMap.isEmpty() && senderIdCountMap.containsKey(lawyerPhone) && lawyerConsultationOrderVO.getOrderStatus() == 2){
                long messageCount = senderIdCountMap.get(lawyerPhone);
                lawyerConsultationOrderVO.setUnreadMessage(messageCount);
            } else {
                lawyerConsultationOrderVO.setUnreadMessage(0L);
            }
        }
    }

    /**
     * 构建空结果Map
     *
     * @param pageNum  页码
     * @param pageSize 页容量
     * @return 空结果Map
     */
    private Map<String, Object> buildEmptyResultMap(int pageNum, int pageSize) {
        Map<String, Object> resultMap = new HashMap<>();
        Page<LawyerConsultationOrderVO> emptyPage = new Page<>(pageNum, pageSize);
        emptyPage.setRecords(Collections.emptyList());
        emptyPage.setTotal(0);
        resultMap.put("lawyerOrderCount", 0L);
        resultMap.put("lawyerInProgressOrderCount", 0);
        resultMap.put("lawyerCompleteOrderCount", 0);
        resultMap.put("lawyerWaitAcceptStatusOrderCount", 0);
        resultMap.put("lawyerRefundedStatusOrderCount", 0);
        resultMap.put("lawyerConsultationOrderList", Collections.emptyList());
        return resultMap;
    }

    /**
     * 计算订单统计信息
     *
     * @param statusCountMap 状态统计Map
     * @return 订单统计信息Map
     */
    private Map<String, Integer> calculateOrderStatistics(Map<Integer, Integer> statusCountMap) {
        Map<String, Integer> statistics = new HashMap<>();
        Integer waitAcceptStatus = LawyerStatusEnum.WAIT_ACCEPT.getStatus();
        Integer inProgressStatus = LawyerStatusEnum.INPROGRESS.getStatus();
        Integer completeStatus = LawyerStatusEnum.COMPLETE.getStatus();
        Integer refundedStatus = LawyerStatusEnum.REFUNDED.getStatus();
        Integer cancelStatus = LawyerStatusEnum.CANCEL.getStatus();

        int waitAcceptCount = statusCountMap.getOrDefault(waitAcceptStatus, 0);
        int inProgressCount = statusCountMap.getOrDefault(inProgressStatus, 0);
        int completeCount = statusCountMap.getOrDefault(completeStatus, 0);
        int refundedCount = statusCountMap.getOrDefault(refundedStatus, 0);
        int cancelCount = statusCountMap.getOrDefault(cancelStatus, 0);

        statistics.put("waitAcceptCount", waitAcceptCount);
        statistics.put("inProgressCount", inProgressCount);
        statistics.put("completeCount", completeCount);
        statistics.put("refundedCount", refundedCount);
        statistics.put("cancelCount", cancelCount);
        statistics.put("totalCount", waitAcceptCount + inProgressCount + completeCount + refundedCount );

        return statistics;
    }

    /**
     * 构建返回结果Map
     *
     * @param voPage         订单分页对象
     * @param orderStatistics 订单统计信息
     * @return 结果Map
     */
    private Map<String, Object> buildResultMap(IPage<LawyerConsultationOrderVO> voPage,
            Map<String, Integer> orderStatistics) {
        Map<String, Object> resultMap = new HashMap<>();

        // 设置统计信息
        resultMap.put("lawyerInProgressOrderCount", orderStatistics.get("inProgressCount"));
        resultMap.put("lawyerCompleteOrderCount", orderStatistics.get("completeCount"));
        resultMap.put("lawyerWaitAcceptStatusOrderCount", orderStatistics.get("waitAcceptCount"));
        resultMap.put("lawyerRefundedStatusOrderCount", orderStatistics.get("refundedCount"));
        resultMap.put("lawyerOrderCount", (long) orderStatistics.get("totalCount"));

        // 设置订单列表
        List<LawyerConsultationOrderVO> orderList = (voPage != null && voPage.getRecords() != null)
                ? voPage.getRecords() : Collections.emptyList();
        resultMap.put("lawyerConsultationOrderList", orderList);

        return resultMap;
    }

    /**
     * 构建订单查询条件
     *
     * @param lawyerId       律师ID
     * @param orderStatus    订单状态
     * @param clientUserName 客户端用户名
     * @param startDate      开始时间
     * @param endDate        结束时间
     * @return 查询条件包装器
     */
    private QueryWrapper<LawyerConsultationOrderVO> buildOrderQueryWrapper(String lawyerId, String orderStatus,
            String clientUserName, String startDate, String endDate) {
        QueryWrapper<LawyerConsultationOrderVO> queryWrapper = new QueryWrapper<>();

        // 订单状态条件
        if (StringUtils.hasText(orderStatus)) {
            queryWrapper.in("lco.order_status", Collections.singletonList(orderStatus));
        } else {
            // 默认查询非待支付和已取消的订单
            Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus();
            Integer cancelStatus = LawyerStatusEnum.CANCEL.getStatus();
            queryWrapper.notIn("lco.order_status",
                    Arrays.asList(String.valueOf(cancelStatus), String.valueOf(waitPayStatus)));
        }

        // 律师ID条件
        queryWrapper.eq("lco.lawyer_user_id", lawyerId);

        // 客户端用户名条件
        if (StringUtils.hasText(clientUserName)) {
            queryWrapper.like("lur.user_name", clientUserName);
        }

        // 删除标记条件
        queryWrapper.eq("lco.delete_flag", 0);

        // 时间范围条件
        if (StringUtils.hasText(startDate)) {
            queryWrapper.ge("lco.payment_time", startDate);
        }

        if (StringUtils.hasText(endDate)) {
            queryWrapper.le("lco.payment_time", endDate);
        }

        // 排序条件
        queryWrapper.orderByDesc("lco.created_time");

        return queryWrapper;
    }

    /**
     * 构建统计查询条件
     *
     * @param lawyerId       律师ID
     * @param clientUserName 客户端用户名
     * @return 统计查询条件包装器
     */
    private QueryWrapper<LawyerConsultationOrderVO> buildStatisticsQueryWrapper(String lawyerId,
            String clientUserName, String startDate, String endDate) {
        QueryWrapper<LawyerConsultationOrderVO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lco.lawyer_user_id", lawyerId);
        queryWrapper.eq("lco.delete_flag", 0);

        // 时间范围条件
        if (StringUtils.hasText(startDate)) {
            queryWrapper.ge("lco.payment_time", startDate);
        }

        if (StringUtils.hasText(endDate)) {
            queryWrapper.le("lco.payment_time", endDate);
        }

        if (StringUtils.hasText(clientUserName)) {
            queryWrapper.like("lur.user_name", clientUserName);
        }

        return queryWrapper;
    }

    /**
     * 构建状态统计Map
     *
     * @param statisticsInfo 统计信息列表
     * @return 状态统计Map，key为订单状态，value为订单数量
     */
    private Map<Integer, Integer> buildStatusCountMap(List<Map<String, Object>> statisticsInfo) {
        Map<Integer, Integer> statusCountMap = new HashMap<>();
        if (CollectionUtils.isEmpty(statisticsInfo)) {
            return statusCountMap;
        }

        for (Map<String, Object> map : statisticsInfo) {
            Object statusObj = map.get("order_status");
            Object countObj = map.get("order_count");

            if (statusObj == null || countObj == null) {
                continue;
            }

            Integer status = (Integer) statusObj;
            // COUNT(*) 返回类型可能是Long
            Long countLong = (Long) countObj;
            statusCountMap.put(status, countLong.intValue());
        }

        return statusCountMap;
    }

    /**
     * 为待支付订单计算倒计时（30分钟有效期）
     *
     * @param voPage 订单分页对象
     */
    private void calculateCountdownForPendingOrders(IPage<LawyerConsultationOrderVO> voPage) {
        if (voPage == null || voPage.getRecords() == null) {
            return;
        }

        Date now = new Date();
        long validitySeconds = 30 * 60; // 30分钟 = 1800秒

        for (LawyerConsultationOrderVO vo : voPage.getRecords()) {
            // 仅对待支付订单（orderStatus=0）计算倒计时
            if (vo.getOrderStatus() != null && vo.getOrderStatus() == 0) {
                Date orderTime = vo.getOrderTime();
                if (orderTime != null) {
                    long elapsedSeconds = (now.getTime() - orderTime.getTime()) / 1000;
                    long remainingSeconds = validitySeconds - elapsedSeconds;
                    // 如果已过期，设置为0
                    vo.setCountdownSeconds(Math.max(0, remainingSeconds));
                } else {
                    vo.setCountdownSeconds(0L);
                }
            } else {
                // 非待支付订单，倒计时为null
                vo.setCountdownSeconds(null);
            }
        }
    }

    /**
     * 填充律师信息到订单VO
     *
     * @param orderVO    订单VO对象
     * @param lawyerUser 律师用户对象
     */
    private void fillLawyerInfo(LawyerConsultationOrderVO orderVO, LawyerUser lawyerUser) {
        orderVO.setLawyerName(lawyerUser.getName());
        orderVO.setLawyerPhone(lawyerUser.getPhone());
        orderVO.setLawyerEmail(lawyerUser.getEmail());
        orderVO.setLawyerCertificateNo(lawyerUser.getLawyerCertificateNo());
        // 通过firm_id查询律所名称
        if (lawyerUser.getFirmId() != null) {
            LawFirm lawFirm = lawFirmMapper.selectById(lawyerUser.getFirmId());
            orderVO.setLawFirm(lawFirm != null && (lawFirm.getDeleteFlag() == null || lawFirm.getDeleteFlag() == 0) 
                    ? lawFirm.getFirmName() : null);
        } else {
            orderVO.setLawFirm(null);
        }
        orderVO.setPracticeYears(lawyerUser.getPracticeYears());
        orderVO.setSpecialtyFields(lawyerUser.getSpecialtyFields());
        orderVO.setCertificationStatus(lawyerUser.getCertificationStatus());
        orderVO.setServiceCount(lawyerUser.getServiceCount());
        orderVO.setServiceScore(lawyerUser.getServiceScore());
        orderVO.setLawyerConsultationFee(lawyerUser.getConsultationFee());
        orderVO.setProvince(lawyerUser.getProvince());
        orderVO.setCity(lawyerUser.getCity());
        orderVO.setDistrict(lawyerUser.getDistrict());
        orderVO.setAddress(lawyerUser.getAddress());
        orderVO.setHeadImg(lawyerUser.getHeadImg());
        orderVO.setNickName(lawyerUser.getNickName());
        orderVO.setPersonalIntroduction(lawyerUser.getPersonalIntroduction());
    }

    /**
     * 律师确认订单
     * <p>
     * 支持两种操作类型：
     * 1. 接单：将订单状态从待接单更新为进行中
     * 2. 取消：将订单状态更新为已取消
     * </p>
     *
     * @param id        订单ID
     * @param actionType 操作类型：1-接单，2-取消
     * @return 确认结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> confirmOrder(String id, String actionType) {
        log.info("开始律师确认订单，订单ID={}, 操作类型={}", id, actionType);

        // 参数校验
        if (id == null || id.trim().isEmpty()) {
            log.warn("律师确认订单失败：订单ID为空");
            return R.fail("订单ID不能为空");
        }

        if (actionType == null || actionType.trim().isEmpty()) {
            log.warn("律师确认订单失败：操作类型为空");
            return R.fail("操作类型不能为空");
        }

        // 操作类型格式校验
        String trimmedActionType = actionType.trim();
        OrderActionType actionTypeEnum = OrderActionType.getByCode(trimmedActionType);
        if (actionTypeEnum == null) {
            log.warn("律师确认订单失败：操作类型无效，actionType={}", actionType);
            return R.fail("操作类型无效，1-接单，2-取消");
        }

        // 将订单ID转换为Integer
        Integer orderId;
        try {
            orderId = Integer.parseInt(id.trim());
        } catch (NumberFormatException e) {
            log.warn("律师确认订单失败：订单ID格式错误，id={}", id, e);
            return R.fail("订单ID格式错误");
        }

        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(orderId);
        if (order == null) {
            log.warn("律师确认订单失败：订单不存在，订单ID={}", orderId);
            return R.fail("订单不存在");
        }

        // 清除redis缓存，避免调用订单超时处理
        orderExpirationService.cancelOrderAcceptTimeout(order.getOrderNumber());

        // 验证订单状态是否为待接单
        Integer orderStatus = order.getOrderStatus();
        Integer waitAcceptStatus = LawyerStatusEnum.WAIT_ACCEPT.getStatus();
        if (!waitAcceptStatus.equals(orderStatus)) {
            log.warn("律师确认订单失败：订单状态不是待接单，订单ID={}, 订单编号={}, 当前状态={}",
                    orderId, order.getOrderNumber(), orderStatus);
            return R.fail("订单状态不是待接单，无法确认");
        }

        // 根据操作类型处理
        if (actionTypeEnum == OrderActionType.ACCEPT) {
            // 接单：更新订单状态为进行中
            Integer inProgressStatus = LawyerStatusEnum.INPROGRESS.getStatus();
            Date acceptTime = new Date();
            order.setOrderStatus(inProgressStatus);
            order.setAcceptOrdersTime(acceptTime);
            order.setUpdatedTime(acceptTime);
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime validityDateTime = now.plusDays(3)
                    .withHour(0)
                    .withMinute(0)
                    .withSecond(0)
                    .withNano(0);
            order.setValidityPeriod(Date.from(validityDateTime.atZone(ZoneId.systemDefault()).toInstant()));

            // 执行更新操作
            boolean result = this.updateById(order);
            if (result) {
                log.info("律师接单成功，订单ID={}, 订单编号={}, 状态从{}变更为{}",
                        orderId, order.getOrderNumber(), waitAcceptStatus, inProgressStatus);
                
                // 发送接单通知
                sendAcceptOrderNotice(order, acceptTime);
                
                return R.data(true, "接单成功");
            } else {
                log.error("律师接单失败：数据库操作失败，订单ID={}, 订单编号={}", orderId, order.getOrderNumber());
                return R.fail("接单失败");
            }
        } else {
            // 取消：更新订单状态为已取消
            Integer cancelStatus = LawyerStatusEnum.REFUNDED.getStatus();
            order.setOrderStatus(cancelStatus);
            order.setUpdatedTime(new Date());

            // 执行更新操作
            boolean result = this.updateById(order);
            if (result) {
                log.info("律师取消订单成功，订单ID={}, 订单编号={}, 状态从{}变更为{}",
                        orderId, order.getOrderNumber(), waitAcceptStatus, cancelStatus);
                
                // 发送拒绝接单通知
                sendRejectOrderNotice(order);
                
                // 发送退款到账通知
                sendRefundArrivalNotice(order);
                
                return R.data(true, "取消订单成功");
            } else {
                log.error("律师取消订单失败：数据库操作失败，订单ID={}, 订单编号={}", orderId, order.getOrderNumber());
                return R.fail("取消订单失败");
            }
        }
    }

    /**
     * 订单开始计时（律师端）
     * <p>
     * 订单开始计时功能说明：
     * 1. 通过订单ID查询订单信息，验证订单是否存在
     * 2. 校验订单状态，必须是进行中状态才能开始计时
     * 3. 判断订单是否按分钟收费（chargeMinute和minuteNum都不为空）
     * 4. 如果按分钟收费，计算超时时间并调用订单完成超时方法设置超时限制
     * 5. 超时后系统会自动将订单状态更新为已完成
     * </p>
     *
     * @param id 订单ID，不能为空
     * @return R<Boolean> 操作结果，true表示成功，false表示失败
     * @throws IllegalArgumentException 当订单ID为空或无效时抛出
     * @author system
     * @since 2025-01-XX
     */
    @Override
    public R<Boolean> orderStartTiming(String id) {
        log.info("订单开始计时请求开始，订单ID={}", id);

        // 参数校验
        validateOrderId(id);

        try {
            // 查询并校验订单
            LawyerConsultationOrder order = queryAndValidateOrder(id);

            // 校验订单状态
            validateOrderStatus(order, id);

            // 处理订单计时逻辑
            return processOrderTiming(order, id);

        } catch (IllegalArgumentException e) {
            log.warn("订单开始计时参数校验失败，订单ID={}，错误信息：{}", id, e.getMessage());
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("订单开始计时异常，订单ID={}，异常信息：{}", id, e.getMessage(), e);
            return R.fail("订单开始计时失败：" + e.getMessage());
        }
    }

    /**
     * 校验订单ID
     * <p>
     * 检查订单ID是否为空或无效
     * </p>
     *
     * @param id 订单ID
     * @throws IllegalArgumentException 当订单ID为空或无效时抛出
     */
    private void validateOrderId(String id) {
        if (StringUtils.isEmpty(id)) {
            log.warn("订单开始计时参数校验失败：订单ID为空");
            throw new IllegalArgumentException("订单ID不能为空");
        }

        // 去除前后空格后再次检查
        String trimmedId = id.trim();
        if (trimmedId.isEmpty()) {
            log.warn("订单开始计时参数校验失败：订单ID为空字符串");
            throw new IllegalArgumentException("订单ID不能为空");
        }
    }

    /**
     * 查询并校验订单
     * <p>
     * 根据订单ID查询订单信息，并校验订单是否存在
     * </p>
     *
     * @param id 订单ID
     * @return 订单对象
     * @throws IllegalArgumentException 当订单不存在时抛出
     */
    private LawyerConsultationOrder queryAndValidateOrder(String id) {
        LawyerConsultationOrder order = this.getById(id);
        if (order == null) {
            log.warn("订单开始计时失败：订单不存在，订单ID={}", id);
            throw new IllegalArgumentException("订单不存在");
        }

        log.debug("订单查询成功，订单ID={}, 订单编号={}, 订单状态={}", 
                id, order.getOrderNumber(), order.getOrderStatus());
        return order;
    }

    /**
     * 校验订单状态
     * <p>
     * 检查订单状态是否为进行中，只有进行中的订单才能开始计时
     * </p>
     *
     * @param order 订单对象
     * @param id    订单ID（用于日志记录）
     * @throws IllegalArgumentException 当订单状态不是进行中时抛出
     */
    private void validateOrderStatus(LawyerConsultationOrder order, String id) {
        Integer inProgressStatus = LawyerStatusEnum.INPROGRESS.getStatus();
        Integer currentOrderStatus = order.getOrderStatus();

        if (!inProgressStatus.equals(currentOrderStatus)) {
            log.warn("订单开始计时失败：订单状态不是进行中，订单ID={}, 订单编号={}, 当前状态={}, 期望状态={}",
                    id, order.getOrderNumber(), currentOrderStatus, inProgressStatus);
            throw new IllegalArgumentException("订单状态不是进行中，无法开始计时");
        }

        log.debug("订单状态校验通过，订单ID={}, 订单编号={}, 订单状态=进行中", id, order.getOrderNumber());
    }

    /**
     * 处理订单计时逻辑
     * <p>
     * 判断订单是否按分钟收费，如果是则设置超时限制
     * </p>
     *
     * @param order 订单对象
     * @param id    订单ID（用于日志记录）
     * @return 操作结果
     */
    private R<Boolean> processOrderTiming(LawyerConsultationOrder order, String id) {
        // 判断订单是否按分钟收费
        if (isMinuteBasedCharging(order)) {
            // 按分钟收费，设置超时限制
            return setMinuteBasedTimeout(order, id);
        } else {
            // 不是按分钟收费，无需设置超时限制
            log.info("订单不是按分钟收费，无需设置超时限制，订单ID={}, 订单编号={}", 
                    id, order.getOrderNumber());
            return R.data(true, "订单不是按分钟收费，无需设置超时限制");
        }
    }

    /**
     * 判断订单是否按分钟收费
     * <p>
     * 通过检查chargeMinute和minuteNum字段是否都不为空来判断
     * </p>
     *
     * @param order 订单对象
     * @return true表示按分钟收费，false表示不是按分钟收费
     */
    private boolean isMinuteBasedCharging(LawyerConsultationOrder order) {
        return order.getChargeMinute() != null && order.getMinuteNum() != null;
    }

    /**
     * 设置按分钟收费订单的超时限制
     * <p>
     * 计算超时时间（分钟数转换为秒），并调用订单完成超时方法设置超时限制
     * </p>
     *
     * @param order 订单对象
     * @param id    订单ID（用于日志记录）
     * @return 操作结果
     */
    private R<Boolean> setMinuteBasedTimeout(LawyerConsultationOrder order, String id) {
        try {
            // 计算超时时间（分钟数转换为秒）
            long timeoutSeconds = calculateTimeoutSeconds(order.getMinuteNum());

            // 调用订单完成超时方法设置超时限制
            orderExpirationService.setOrderCompleteTimeout(order.getOrderNumber(), timeoutSeconds);

            log.info("订单开始计时成功，订单ID={}, 订单编号={}, 超时时间={}秒（{}分钟）",
                    id, order.getOrderNumber(), timeoutSeconds, order.getMinuteNum());

            return R.data(true, "订单开始计时成功");

        } catch (Exception e) {
            log.error("设置订单超时限制失败，订单ID={}, 订单编号={}，异常信息：{}",
                    id, order.getOrderNumber(), e.getMessage(), e);
            throw new RuntimeException("设置订单超时限制失败：" + e.getMessage(), e);
        }
    }

    /**
     * 计算超时时间（秒）
     * <p>
     * 将分钟数转换为秒数
     * </p>
     *
     * @param minuteNum 分钟数，必须大于0
     * @return 超时时间（秒）
     * @throws IllegalArgumentException 当分钟数无效时抛出
     */
    private long calculateTimeoutSeconds(Integer minuteNum) {
        if (minuteNum == null || minuteNum <= 0) {
            log.warn("计算超时时间失败：分钟数无效，minuteNum={}", minuteNum);
            throw new IllegalArgumentException("分钟数必须大于0");
        }

        long timeoutSeconds = minuteNum * MINUTE_TO_SECOND;
        log.debug("计算超时时间，分钟数={}, 超时时间={}秒", minuteNum, timeoutSeconds);
        return timeoutSeconds;
    }

    /**
     * 申请退款
     * <p>
     * 申请退款前会进行以下校验：
     * 1. 参数校验：订单ID不能为空，退款原因不能为空
     * 2. 订单存在性校验：订单必须存在
     * 3. 订单支付状态校验：只有已支付的订单才能申请退款
     * 4. 订单状态校验：待支付、已取消的订单不允许申请退款
     * </p>
     *
     * @param id 订单ID
     * @param refundReason 退款原因
     * @return 申请退款结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> requestRefund(Integer id, String refundReason) {
        log.info("开始申请退款，订单ID={}, 退款原因={}", id, refundReason);

        // 参数校验
        if (id == null) {
            log.warn("申请退款失败：订单ID为空");
            return R.fail("订单ID不能为空");
        }

        if (!StringUtils.hasText(refundReason)) {
            log.warn("申请退款失败：退款原因为空，订单ID={}", id);
            return R.fail("退款原因不能为空");
        }

        // 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(id);
        if (order == null) {
            log.warn("申请退款失败：订单不存在，订单ID={}", id);
            return R.fail("订单不存在");
        }

        // 检查订单支付状态：只有已支付的订单才能申请退款
        Integer paymentStatus = order.getPaymentStatus();
        Integer paidStatus = 1; // 1:已支付
        if (paymentStatus == 0 || !paidStatus.equals(paymentStatus)) {
            log.warn("申请退款失败：订单未支付，无法申请退款，订单ID={}, 订单编号={}, 支付状态={}",
                    id, order.getOrderNumber(), paymentStatus);
            return R.fail("订单未支付，无法申请退款");
        }

        // 检查订单状态：待支付、已取消的订单不允许申请退款
        Integer orderStatus = order.getOrderStatus();
        Integer waitPayStatus = LawyerStatusEnum.WAIT_PAY.getStatus(); // 0:待支付
        Integer cancelStatus = LawyerStatusEnum.CANCEL.getStatus(); // 4:已取消

        if (waitPayStatus.equals(orderStatus)) {
            log.warn("申请退款失败：订单待支付，无法申请退款，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.fail("订单待支付，无法申请退款");
        }

        if (cancelStatus.equals(orderStatus)) {
            log.warn("申请退款失败：订单已取消，无法申请退款，订单ID={}, 订单编号={}", id, order.getOrderNumber());
            return R.fail("订单已取消，无法申请退款");
        }

        // 检查订单是否已经申请过退款（这里可以根据业务需求添加退款状态字段来判断）
        // 目前暂时允许重复申请，实际业务中可能需要添加退款状态字段来防止重复申请

        // 更新订单状态为退款中或已退款（根据业务需求，这里暂时不更新订单状态，只记录退款申请）
        // 如果需要更新订单状态，可以添加退款状态字段，例如：refundStatus (0:未退款, 1:退款中, 2:已退款, 3:退款失败)
        
        // 记录退款申请信息（这里可以根据业务需求创建退款记录表，或者更新订单表的退款相关字段）
        log.info("申请退款成功，订单ID={}, 订单编号={}, 订单金额={}分, 退款原因={}",
                id, order.getOrderNumber(), order.getOrderAmount(), refundReason);

        // 这里可以调用实际的退款接口处理退款
        // 例如：调用支付宝退款接口、更新退款状态等
        // 目前先返回成功，实际业务中需要根据退款接口的返回结果来判断

        return R.data(true, "退款申请已提交，请等待处理");
    }

    /**
     * 退款申请处理（律师端）
     * <p>
     * 处理退款申请前会进行以下校验：
     * 1. 参数校验：律师ID、订单ID、处理动作不能为空
     * 2. 订单存在性校验：订单必须存在
     * 3. 订单归属校验：订单必须属于该律师
     * 4. 退款状态校验：订单必须处于已申请退款状态
     * 5. 处理动作校验：处理动作必须为同意(1)或拒绝(2)
     * 6. 拒绝原因校验：拒绝时必须提供拒绝原因
     * </p>
     * <p>
     * 处理逻辑：
     * - 同意退款：将订单状态设置为已退款(5)，申请退款状态设置为已同意(3)，并发送同意通知
     * - 拒绝退款：将申请退款状态设置为已拒绝(2)，更新拒绝原因，并发送拒绝通知
     * </p>
     *
     * @param lawyerConsultationOrder 订单对象
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> refundApplyProcess(LawyerConsultationOrder lawyerConsultationOrder) {
        Integer lawyerId = lawyerConsultationOrder.getLawyerUserId();
        Integer orderId = lawyerConsultationOrder.getId();
        String processAction = lawyerConsultationOrder.getProcessAction();
        String rejectRefundReason = lawyerConsultationOrder.getRejectRefundReason();
        
        log.info("开始处理退款申请，律师ID={}, 订单ID={}, 处理动作={}", lawyerId, orderId, processAction);

        // 1. 参数校验
        R<Boolean> paramValidateResult = validateRefundProcessParams(lawyerId, orderId, processAction, rejectRefundReason);
        if (paramValidateResult != null) {
            return paramValidateResult;
        }

        // 2. 查询订单信息
        LawyerConsultationOrder order = consultationOrderMapper.selectById(orderId);
        if (Objects.isNull(order)) {
            log.warn("处理退款申请失败：订单不存在，订单ID={}", orderId);
            return R.fail("订单不存在");
        }

        // 3. 业务校验
        R<Boolean> businessValidateResult = validateRefundProcessBusiness(lawyerId, order);
        if (businessValidateResult != null) {
            return businessValidateResult;
        }

        // 4. 取消退款超时计时器
        try {
            orderExpirationService.cancelOrderRefundTimeout(order.getOrderNumber());
        } catch (Exception e) {
            log.error("取消退款超时计时器失败，订单编号={}", order.getOrderNumber(), e);
            // 继续执行，不因取消计时器失败而中断
        }

        // 5. 根据处理动作进行相应处理
        if (ACTION_AGREE.equals(processAction)) {
            return processAgreeRefund(order);
        } else {
            return processRejectRefund(order, rejectRefundReason);
        }
    }

    /**
     * 校验退款处理参数
     *
     * @param lawyerId          律师ID
     * @param orderId           订单ID
     * @param processAction     处理动作
     * @param rejectRefundReason 拒绝原因
     * @return 校验失败时返回错误结果，校验通过返回null
     */
    private R<Boolean> validateRefundProcessParams(Integer lawyerId, Integer orderId, 
                                                     String processAction, String rejectRefundReason) {
        // 律师ID校验
        if (Objects.isNull(lawyerId) || lawyerId <= 0) {
            log.warn("处理退款申请失败：律师ID为空或无效，lawyerId={}", lawyerId);
            return R.fail("律师ID不能为空");
        }

        // 订单ID校验
        if (Objects.isNull(orderId) || orderId <= 0) {
            log.warn("处理退款申请失败：订单ID为空或无效，orderId={}", orderId);
            return R.fail("订单ID不能为空");
        }

        // 处理动作校验
        if (!StringUtils.hasText(processAction)) {
            log.warn("处理退款申请失败：处理动作为空，订单ID={}", orderId);
            return R.fail("处理动作不能为空");
        }

        // 处理动作值校验
        if (!ACTION_AGREE.equals(processAction) && !ACTION_REJECT.equals(processAction)) {
            log.warn("处理退款申请失败：处理动作无效，订单ID={}, 处理动作={}", orderId, processAction);
            return R.fail("处理动作无效，1-同意，2-拒绝");
        }

        // 拒绝原因校验：拒绝时必须提供拒绝原因
        if (ACTION_REJECT.equals(processAction) && !StringUtils.hasText(rejectRefundReason)) {
            log.warn("处理退款申请失败：拒绝退款时必须提供拒绝原因，订单ID={}", orderId);
            return R.fail("拒绝退款时必须提供拒绝原因");
        }

        return null;
    }

    /**
     * 校验退款处理业务规则
     *
     * @param lawyerId 律师ID
     * @param order    订单对象
     * @return 校验失败时返回错误结果，校验通过返回null
     */
    private R<Boolean> validateRefundProcessBusiness(Integer lawyerId, LawyerConsultationOrder order) {
        Integer orderId = order.getId();
        
        // 订单归属校验：订单必须属于该律师
        Integer orderLawyerId = order.getLawyerUserId();
        if (Objects.isNull(orderLawyerId) || !lawyerId.equals(orderLawyerId)) {
            log.warn("处理退款申请失败：订单不属于该律师，订单ID={}, 订单律师ID={}, 请求律师ID={}", 
                    orderId, orderLawyerId, lawyerId);
            return R.fail("订单不属于该律师，无法处理退款申请");
        }

        // 退款状态校验：订单必须处于已申请退款状态
        String applyRefundStatus = order.getApplyRefundStatus();
        if (!REFUND_STATUS_APPLIED.equals(applyRefundStatus)) {
            log.warn("处理退款申请失败：订单未申请退款或已处理，订单ID={}, 订单编号={}, 退款状态={}", 
                    orderId, order.getOrderNumber(), applyRefundStatus);
            return R.fail("订单未申请退款或已处理，无法重复处理");
        }

        return null;
    }

    /**
     * 处理同意退款
     * <p>
     * 1. 更新订单状态为已退款(5)
     * 2. 更新申请退款状态为已同意(3)
     * 3. 发送同意退款通知给申请人
     * </p>
     *
     * @param order 订单对象
     * @return 处理结果
     */
    private R<Boolean> processAgreeRefund(LawyerConsultationOrder order) {
        log.info("开始处理同意退款，订单ID={}, 订单编号={}", order.getId(), order.getOrderNumber());

        try {
            // 1. 更新订单状态和退款状态
            Date processTime = new Date();
            LambdaUpdateWrapper<LawyerConsultationOrder> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(LawyerConsultationOrder::getId, order.getId())
                    .set(LawyerConsultationOrder::getOrderStatus, LawyerStatusEnum.REFUNDED.getStatus())
                    .set(LawyerConsultationOrder::getApplyRefundStatus, REFUND_STATUS_AGREED)
                    .set(LawyerConsultationOrder::getApplyRefundProcessTime, processTime)
                    .set(LawyerConsultationOrder::getApplyRefundTime, processTime)
                    .set(LawyerConsultationOrder::getUpdatedTime, processTime);

            int updateCount = consultationOrderMapper.update(null, updateWrapper);
            if (updateCount <= 0) {
                log.error("处理同意退款失败：更新订单状态失败，订单ID={}, 订单编号={}", 
                        order.getId(), order.getOrderNumber());
                return R.fail("处理同意退款失败，请稍后重试");
            }

            // 2. 发送同意退款通知给申请人
            sendRefundAgreeNotice(order);

            log.info("处理同意退款成功，订单ID={}, 订单编号={}", order.getId(), order.getOrderNumber());
            return R.data(true, "已同意退款申请");
        } catch (Exception e) {
            log.error("处理同意退款异常，订单ID={}, 订单编号={}, 异常信息={}", 
                    order.getId(), order.getOrderNumber(), e.getMessage(), e);
            return R.fail("处理同意退款失败，请稍后重试");
        }
    }

    /**
     * 处理拒绝退款
     * <p>
     * 1. 更新申请退款状态为已拒绝(2)
     * 2. 更新拒绝退款原因
     * 3. 发送拒绝退款通知给申请人
     * </p>
     *
     * @param order              订单对象
     * @param rejectRefundReason 拒绝原因
     * @return 处理结果
     */
    private R<Boolean> processRejectRefund(LawyerConsultationOrder order, String rejectRefundReason) {
        log.info("开始处理拒绝退款，订单ID={}, 订单编号={}, 拒绝原因={}", 
                order.getId(), order.getOrderNumber(), rejectRefundReason);

        try {
            // 1. 更新订单退款状态和拒绝原因
            Date processTime = new Date();
            LambdaUpdateWrapper<LawyerConsultationOrder> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(LawyerConsultationOrder::getId, order.getId())
                    .set(LawyerConsultationOrder::getApplyRefundStatus, REFUND_STATUS_REJECTED)
                    .set(LawyerConsultationOrder::getRejectRefundReason, rejectRefundReason)
                    .set(LawyerConsultationOrder::getApplyRefundProcessTime, processTime)
                    .set(LawyerConsultationOrder::getUpdatedTime, processTime);

            int updateCount = consultationOrderMapper.update(null, updateWrapper);
            if (updateCount <= 0) {
                log.error("处理拒绝退款失败：更新订单状态失败，订单ID={}, 订单编号={}", 
                        order.getId(), order.getOrderNumber());
                return R.fail("处理拒绝退款失败，请稍后重试");
            }

            // 2. 发送拒绝退款通知给申请人
            sendRefundRejectNotice(order, rejectRefundReason);

            log.info("处理拒绝退款成功，订单ID={}, 订单编号={}", order.getId(), order.getOrderNumber());
            return R.data(true, "已拒绝退款申请");
        } catch (Exception e) {
            log.error("处理拒绝退款异常，订单ID={}, 订单编号={}, 异常信息={}", 
                    order.getId(), order.getOrderNumber(), e.getMessage(), e);
            return R.fail("处理拒绝退款失败，请稍后重试");
        }
    }

    /**
     * 发送同意退款通知给申请人
     *
     * @param order 订单对象
     */
    private void sendRefundAgreeNotice(LawyerConsultationOrder order) {
        try {
            Integer clientUserId = order.getClientUserId();
            if (clientUserId == null) {
                log.warn("发送同意退款通知失败：客户端用户ID为空，订单ID={}", order.getId());
                return;
            }

            // 获取申请人接收ID
            String receiverId = getClientReceiverId(clientUserId);
            if (!StringUtils.hasText(receiverId)) {
                log.warn("发送同意退款通知失败：获取申请人接收ID失败，订单ID={}, 用户ID={}", 
                        order.getId(), clientUserId);
                return;
            }

            // 构建通知消息
            String orderNumber = order.getOrderNumber() != null ? order.getOrderNumber() : "";
            String message = String.format("您的编号为%s的订单，律师已同意您的退款申请，订单金额将在1-3个工作日原路返还，请注意查收。", 
                    orderNumber);

            // 创建并保存通知
            LifeNotice lifeNotice = createRefundNotice(order.getId(), receiverId, "退款申请处理通知", message);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
            if (noticeResult <= 0) {
                log.warn("发送同意退款通知失败：保存通知失败，订单ID={}", order.getId());
                return;
            }

            // 发送WebSocket消息
            sendWebSocketMessage(receiverId, lifeNotice);

            log.info("发送同意退款通知成功，接收人ID={}, 订单编号={}", receiverId, orderNumber);
        } catch (Exception e) {
            log.error("发送同意退款通知异常，订单ID={}, 异常信息={}", order.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送拒绝退款通知给申请人
     *
     * @param order              订单对象
     * @param rejectRefundReason 拒绝原因
     */
    private void sendRefundRejectNotice(LawyerConsultationOrder order, String rejectRefundReason) {
        try {
            Integer clientUserId = order.getClientUserId();
            if (clientUserId == null) {
                log.warn("发送拒绝退款通知失败：客户端用户ID为空，订单ID={}", order.getId());
                return;
            }

            // 获取申请人接收ID
            String receiverId = getClientReceiverId(clientUserId);
            if (!StringUtils.hasText(receiverId)) {
                log.warn("发送拒绝退款通知失败：获取申请人接收ID失败，订单ID={}, 用户ID={}", 
                        order.getId(), clientUserId);
                return;
            }

            // 构建通知消息
            String orderNumber = order.getOrderNumber() != null ? order.getOrderNumber() : "";
            String rejectReason = StringUtils.hasText(rejectRefundReason) ? rejectRefundReason : "无";
            String message = String.format("您的编号为%s的订单，律师已拒绝您的退款申请。拒绝原因：%s。如您仍有疑问，可通过举报的方式提交平台审核", 
                    orderNumber, rejectReason);

            // 创建并保存通知
            LifeNotice lifeNotice = createRefundNotice(order.getId(), receiverId, "拒绝退款通知", message);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
            if (noticeResult <= 0) {
                log.warn("发送拒绝退款通知失败：保存通知失败，订单ID={}", order.getId());
                return;
            }

            // 发送WebSocket消息
            sendWebSocketMessage(receiverId, lifeNotice);

            log.info("发送拒绝退款通知成功，接收人ID={}, 订单编号={}", receiverId, orderNumber);
        } catch (Exception e) {
            log.error("发送拒绝退款通知异常，订单ID={}, 异常信息={}", order.getId(), e.getMessage(), e);
        }
    }

    /**
     * 获取客户端用户接收ID
     *
     * @param clientUserId 客户端用户ID
     * @return 接收人ID，格式：user_ + 手机号
     */
    private String getClientReceiverId(Integer clientUserId) {
        if (clientUserId == null || clientUserId <= 0) {
            log.warn("获取客户端用户接收ID失败：用户ID为空或无效");
            return null;
        }

        try {
            LifeUser lifeUser = lifeUserMapper.selectById(clientUserId);
            if (lifeUser != null && StringUtils.hasText(lifeUser.getUserPhone())) {
                return "user_" + lifeUser.getUserPhone();
            }
        } catch (Exception e) {
            log.error("获取客户端用户手机号异常，用户ID={}, 异常信息={}", clientUserId, e.getMessage(), e);
        }

        log.warn("获取客户端用户手机号失败，用户ID={}", clientUserId);
        return null;
    }

    /**
     * 创建退款通知对象
     *
     * @param businessId 业务ID（订单ID）
     * @param receiverId 接收人ID
     * @param title      通知标题
     * @param message    通知消息
     * @return 通知对象
     */
    private LifeNotice createRefundNotice(Integer businessId, String receiverId, String title, String message) {
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId(SYSTEM_SENDER_ID);
        lifeNotice.setBusinessId(businessId);
        lifeNotice.setReceiverId(receiverId);
        lifeNotice.setTitle(title);
        lifeNotice.setNoticeType(1);
        lifeNotice.setIsRead(0);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", message);
        lifeNotice.setContext(jsonObject.toJSONString());
        lifeNotice.setBusinessType(1);

        return lifeNotice;
    }

    /**
     * 发送WebSocket消息
     *
     * @param receiverId 接收人ID
     * @param lifeNotice 通知对象
     */
    private void sendWebSocketMessage(String receiverId, LifeNotice lifeNotice) {
        try {
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId(SYSTEM_SENDER_ID);
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSON.toJSONString(lifeNotice));
            webSocketProcess.sendMessage(receiverId, JSON.toJSONString(webSocketVo));
        } catch (Exception e) {
            log.error("发送WebSocket消息异常，接收人ID={}, 异常信息={}", receiverId, e.getMessage(), e);
        }
    }

    /**
     * 发送接单通知给客户端用户
     *
     * @param order      订单对象
     * @param acceptTime 接单时间
     */
    private void sendAcceptOrderNotice(LawyerConsultationOrder order, Date acceptTime) {
        try {
            Integer clientUserId = order.getClientUserId();
            if (clientUserId == null) {
                log.warn("发送接单通知失败：客户端用户ID为空，订单ID={}", order.getId());
                return;
            }

            // 获取客户端用户接收ID
            String receiverId = getClientReceiverId(clientUserId);
            if (!StringUtils.hasText(receiverId)) {
                log.warn("发送接单通知失败：获取客户端用户接收ID失败，订单ID={}, 用户ID={}", 
                        order.getId(), clientUserId);
                return;
            }

            // 格式化日期
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String acceptTimeStr = dateFormat.format(acceptTime);
            
            // 计算当前时间三天后的23:59:59
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime validityDateTime = now.plusDays(3)
                    .withHour(23)
                    .withMinute(59)
                    .withSecond(59)
                    .withNano(0);
            Date validityDate = Date.from(validityDateTime.atZone(ZoneId.systemDefault()).toInstant());
            String validityPeriodStr = dateFormat.format(validityDate);

            // 构建通知消息
            String orderNumber = order.getOrderNumber() != null ? order.getOrderNumber() : "";
            String message = String.format("您的编号为%s的订单已于%s被律师接单，有效期至%s。请在有效期内与律师沟通。", 
                    orderNumber, acceptTimeStr, validityPeriodStr);

            // 创建并保存通知
            LifeNotice lifeNotice = createOrderNotice(order.getId(), receiverId, "接单通知", message);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
            if (noticeResult <= 0) {
                log.warn("发送接单通知失败：保存通知失败，订单ID={}", order.getId());
                return;
            }

            // 发送WebSocket消息
            sendWebSocketMessage(receiverId, lifeNotice);

            log.info("发送接单通知成功，接收人ID={}, 订单编号={}", receiverId, orderNumber);
        } catch (Exception e) {
            log.error("发送接单通知异常，订单ID={}, 异常信息={}", order.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送拒绝接单通知给客户端用户
     *
     * @param order 订单对象
     */
    private void sendRejectOrderNotice(LawyerConsultationOrder order) {
        try {
            Integer clientUserId = order.getClientUserId();
            if (clientUserId == null) {
                log.warn("发送拒绝接单通知失败：客户端用户ID为空，订单ID={}", order.getId());
                return;
            }

            // 获取客户端用户接收ID
            String receiverId = getClientReceiverId(clientUserId);
            if (!StringUtils.hasText(receiverId)) {
                log.warn("发送拒绝接单通知失败：获取客户端用户接收ID失败，订单ID={}, 用户ID={}", 
                        order.getId(), clientUserId);
                return;
            }

            // 获取拒绝原因
            String rejectReason = order.getReasonOrderRefusal();
            if (!StringUtils.hasText(rejectReason)) {
                rejectReason = "无";
            }

            // 构建通知消息
            String orderNumber = order.getOrderNumber() != null ? order.getOrderNumber() : "";
            String message = String.format("您的编号为%s的订单已被拒绝，拒绝原因：%s。订单金额将在1-3个工作日原路返还，请注意查收。", 
                    orderNumber, rejectReason);

            // 创建并保存通知
            LifeNotice lifeNotice = createOrderNotice(order.getId(), receiverId, "拒绝接单通知", message);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
            if (noticeResult <= 0) {
                log.warn("发送拒绝接单通知失败：保存通知失败，订单ID={}", order.getId());
                return;
            }

            // 发送WebSocket消息
            sendWebSocketMessage(receiverId, lifeNotice);

            log.info("发送拒绝接单通知成功，接收人ID={}, 订单编号={}", receiverId, orderNumber);
        } catch (Exception e) {
            log.error("发送拒绝接单通知异常，订单ID={}, 异常信息={}", order.getId(), e.getMessage(), e);
        }
    }

    /**
     * 发送退款到账通知给客户端用户
     *
     * @param order 订单对象
     */
    private void sendRefundArrivalNotice(LawyerConsultationOrder order) {
        try {
            Integer clientUserId = order.getClientUserId();
            if (clientUserId == null) {
                log.warn("发送退款到账通知失败：客户端用户ID为空，订单ID={}", order.getId());
                return;
            }

            // 获取客户端用户接收ID
            String receiverId = getClientReceiverId(clientUserId);
            if (!StringUtils.hasText(receiverId)) {
                log.warn("发送退款到账通知失败：获取客户端用户接收ID失败，订单ID={}, 用户ID={}", 
                        order.getId(), clientUserId);
                return;
            }

            // 构建通知消息
            String orderNumber = order.getOrderNumber() != null ? order.getOrderNumber() : "";
            String message = String.format("您的编号为%s的订单，订单金额已原路返还至您的支付渠道，请查收。", 
                    orderNumber);

            // 创建并保存通知
            LifeNotice lifeNotice = createOrderNotice(order.getId(), receiverId, "退款到账通知", message);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
            if (noticeResult <= 0) {
                log.warn("发送退款到账通知失败：保存通知失败，订单ID={}", order.getId());
                return;
            }

            // 发送WebSocket消息
            sendWebSocketMessage(receiverId, lifeNotice);

            log.info("发送退款到账通知成功，接收人ID={}, 订单编号={}", receiverId, orderNumber);
        } catch (Exception e) {
            log.error("发送退款到账通知异常，订单ID={}, 异常信息={}", order.getId(), e.getMessage(), e);
        }
    }

    /**
     * 创建订单通知对象
     *
     * @param businessId 业务ID（订单ID）
     * @param receiverId 接收人ID
     * @param title      通知标题
     * @param message    通知消息
     * @return 通知对象
     */
    private LifeNotice createOrderNotice(Integer businessId, String receiverId, String title, String message) {
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId(SYSTEM_SENDER_ID);
        lifeNotice.setBusinessId(businessId);
        lifeNotice.setReceiverId(receiverId);
        lifeNotice.setTitle(title);
        lifeNotice.setNoticeType(1);
        lifeNotice.setIsRead(0);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", message);
        lifeNotice.setContext(jsonObject.toJSONString());
        lifeNotice.setBusinessType(1);

        return lifeNotice;
    }

    /**
     * 检查订单接单后是否有消息记录
     * <p>
     * 根据订单ID查询订单信息，获取律师接单时间、用户ID和律师ID，
     * 然后查询 life_message 表，检查是否存在律师发送给用户的消息记录，
     * 且消息创建时间大于接单时间。
     * </p>
     * <p>
     * 处理流程：
     * 1. 参数校验：订单ID不能为空
     * 2. 查询订单信息：获取接单时间、用户ID、律师ID
     * 3. 校验订单信息：订单必须存在，且必须有接单时间
     * 4. 查询律师信息：获取律师手机号
     * 5. 查询用户信息：获取用户手机号
     * 6. 构建消息查询条件：sender_id=律师phone，receiver_id=用户phone，created_time>接单时间
     * 7. 查询消息记录：如果存在记录返回true，否则返回false
     * </p>
     *
     * @param id 订单ID，不能为空
     * @return true表示有消息记录，false表示无消息记录
     * @throws IllegalArgumentException 当订单ID无效或订单不存在时抛出
     * @throws RuntimeException        当查询异常时抛出
     * @author system
     * @since 2025-01-XX
     */
    @Override
    public Boolean checkMessageAfterAccept(String id) {
        log.info("检查订单接单后是否有消息记录开始，订单ID={}", id);

        // 参数校验
        validateOrderId(id);

        try {
            // 查询订单信息
            LawyerConsultationOrder order = queryOrderById(id);

            // 校验订单信息
            validateOrderInfo(order, id);

            // 获取接单时间、用户ID、律师ID
            Date acceptOrdersTime = order.getAcceptOrdersTime();
            Integer clientUserId = order.getClientUserId();
            Integer lawyerUserId = order.getLawyerUserId();

            // 查询律师和用户信息，获取手机号
            String lawyerPhone = queryLawyerPhone(lawyerUserId, id);
            String userPhone = queryUserPhone(clientUserId, id);

            // 构建消息查询条件并查询
            boolean hasMessage = queryMessageAfterAccept(lawyerPhone, userPhone, acceptOrdersTime, id);

            log.info("检查订单接单后是否有消息记录完成，订单ID={}，是否有消息={}", id, hasMessage);
            return hasMessage;

        } catch (IllegalArgumentException e) {
            log.warn("检查订单接单后是否有消息记录参数校验失败，订单ID={}，错误信息：{}", id, e.getMessage());
            throw e;
        } catch (RuntimeException e) {
            log.error("检查订单接单后是否有消息记录异常，订单ID={}，异常信息：{}", id, e.getMessage(), e);
            throw new RuntimeException("检查消息记录失败：" + e.getMessage(), e);
        } catch (Exception e) {
            log.error("检查订单接单后是否有消息记录未知异常，订单ID={}，异常信息：{}", id, e.getMessage(), e);
            throw new RuntimeException("检查消息记录失败，请稍后重试", e);
        }
    }

    /**
     * 根据订单ID查询订单信息
     * <p>
     * 查询订单的详细信息
     * </p>
     *
     * @param id 订单ID
     * @return 订单信息
     * @throws RuntimeException 当查询异常时抛出
     */
    private LawyerConsultationOrder queryOrderById(String id) {
        try {
            LawyerConsultationOrder order = consultationOrderMapper.selectById(id);
            if (order == null) {
                log.warn("检查订单接单后是否有消息记录：订单不存在，订单ID={}", id);
                throw new IllegalArgumentException("订单不存在，订单ID=" + id);
            }
            log.debug("查询订单信息成功，订单ID={}", id);
            return order;
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询订单信息异常，订单ID={}，异常信息：{}", id, e.getMessage(), e);
            throw new RuntimeException("查询订单信息失败：" + e.getMessage(), e);
        }
    }

    /**
     * 校验订单信息
     * <p>
     * 检查订单是否包含必要的信息（接单时间、用户ID、律师ID）
     * </p>
     *
     * @param order 订单信息
     * @param id    订单ID
     * @throws IllegalArgumentException 当订单信息不完整时抛出
     */
    private void validateOrderInfo(LawyerConsultationOrder order, String id) {
        if (order.getAcceptOrdersTime() == null) {
            log.warn("检查订单接单后是否有消息记录：订单接单时间为空，订单ID={}", id);
            throw new IllegalArgumentException("订单接单时间为空，订单ID=" + id);
        }

        if (order.getClientUserId() == null) {
            log.warn("检查订单接单后是否有消息记录：订单用户ID为空，订单ID={}", id);
            throw new IllegalArgumentException("订单用户ID为空，订单ID=" + id);
        }

        if (order.getLawyerUserId() == null) {
            log.warn("检查订单接单后是否有消息记录：订单律师ID为空，订单ID={}", id);
            throw new IllegalArgumentException("订单律师ID为空，订单ID=" + id);
        }
    }

    /**
     * 查询律师手机号
     * <p>
     * 根据律师ID查询律师信息，获取手机号
     * </p>
     *
     * @param lawyerUserId 律师ID
     * @param orderId      订单ID（用于日志）
     * @return 律师手机号
     * @throws RuntimeException 当查询异常或律师不存在时抛出
     */
    private String queryLawyerPhone(Integer lawyerUserId, String orderId) {
        try {
            LawyerUser lawyerUser = lawyerUserMapper.selectById(lawyerUserId);
            if (lawyerUser == null) {
                log.warn("检查订单接单后是否有消息记录：律师不存在，律师ID={}，订单ID={}", lawyerUserId, orderId);
                throw new RuntimeException("律师不存在，律师ID=" + lawyerUserId);
            }

            String phone = lawyerUser.getPhone();
            if (phone == null || phone.trim().isEmpty()) {
                log.warn("检查订单接单后是否有消息记录：律师手机号为空，律师ID={}，订单ID={}", lawyerUserId, orderId);
                throw new RuntimeException("律师手机号为空，律师ID=" + lawyerUserId);
            }

            log.debug("查询律师手机号成功，律师ID={}，手机号={}", lawyerUserId, phone);
            return phone;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询律师手机号异常，律师ID={}，订单ID={}，异常信息：{}", lawyerUserId, orderId, e.getMessage(), e);
            throw new RuntimeException("查询律师手机号失败：" + e.getMessage(), e);
        }
    }

    /**
     * 查询用户手机号
     * <p>
     * 根据用户ID查询用户信息，获取手机号
     * </p>
     *
     * @param clientUserId 用户ID
     * @param orderId      订单ID（用于日志）
     * @return 用户手机号
     * @throws RuntimeException 当查询异常或用户不存在时抛出
     */
    private String queryUserPhone(Integer clientUserId, String orderId) {
        try {
            LifeUser lifeUser = lifeUserMapper.selectById(clientUserId);
            if (lifeUser == null) {
                log.warn("检查订单接单后是否有消息记录：用户不存在，用户ID={}，订单ID={}", clientUserId, orderId);
                throw new RuntimeException("用户不存在，用户ID=" + clientUserId);
            }

            String phone = lifeUser.getUserPhone();
            if (phone == null || phone.trim().isEmpty()) {
                log.warn("检查订单接单后是否有消息记录：用户手机号为空，用户ID={}，订单ID={}", clientUserId, orderId);
                throw new RuntimeException("用户手机号为空，用户ID=" + clientUserId);
            }

            log.debug("查询用户手机号成功，用户ID={}，手机号={}", clientUserId, phone);
            return phone;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询用户手机号异常，用户ID={}，订单ID={}，异常信息：{}", clientUserId, orderId, e.getMessage(), e);
            throw new RuntimeException("查询用户手机号失败：" + e.getMessage(), e);
        }
    }

    /**
     * 查询接单后的消息记录
     * <p>
     * 查询 life_message 表，条件：
     * - sender_id = 律师phone（格式：lawyer_phone）
     * - receiver_id = 用户phone（格式：user_phone）
     * - created_time > 接单时间
     * </p>
     *
     * @param lawyerPhone      律师手机号
     * @param userPhone        用户手机号
     * @param acceptOrdersTime 接单时间
     * @param orderId          订单ID（用于日志）
     * @return true表示有消息记录，false表示无消息记录
     */
    private boolean queryMessageAfterAccept(String lawyerPhone, String userPhone, Date acceptOrdersTime, String orderId) {
        try {
            // 构建发送者ID和接收者ID
            String senderId = LAWYER_SENDER_PREFIX + lawyerPhone;
            String receiverId = USER_RECEIVER_PREFIX + userPhone;

            // 构建查询条件
            LambdaQueryWrapper<LifeMessage> queryWrapper = new LambdaQueryWrapper<>();
            lifeMessageUtil.applySenderReceiverPairQuery(queryWrapper, senderId, receiverId);
            queryWrapper.gt(LifeMessage::getCreatedTime, acceptOrdersTime)
                    .eq(LifeMessage::getDeleteFlag, DELETE_FLAG_NOT_DELETED)
                    .last("LIMIT 1");

            // 查询消息记录（只需要判断是否存在，使用 selectOne 并判断是否为 null）
            LifeMessage message = lifeMessageMapper.selectOne(queryWrapper);

            boolean hasMessage = message != null;
            log.debug("查询接单后消息记录完成，订单ID={}，发送者ID={}，接收者ID={}，接单时间={}，是否有消息={}",
                    orderId, senderId, receiverId, acceptOrdersTime, hasMessage);

            return hasMessage;
        } catch (Exception e) {
            log.error("查询接单后消息记录异常，订单ID={}，律师手机号={}，用户手机号={}，接单时间={}，异常信息：{}",
                    orderId, lawyerPhone, userPhone, acceptOrdersTime, e.getMessage(), e);
            // 异常时返回 false，避免影响主流程
            return false;
        }
    }
}

