package com.yida.data.school.smart.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yida.data.common.core.common.ResultMsgType;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.constant.StringConstant;
import com.yida.data.common.core.entity.pay.ConstructionPayOrder;
import com.yida.data.common.core.entity.smart.*;
import com.yida.data.common.core.entity.system.BaiduApiConfig;
import com.yida.data.common.core.entity.system.ConstructionPayConfig;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.UnionPayConfig;
import com.yida.data.common.core.enums.*;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.*;
import com.yida.data.common.service.CommonService;
import com.yida.data.school.dto.smart.h5.CreateGuideStepOrderDTO;
import com.yida.data.school.dto.smart.h5.RosterFaceMatchDTO;
import com.yida.data.school.dto.smart.h5.RosterPageDTO;
import com.yida.data.school.smart.mapper.EduSmartWelcomeGuideRosterRelationMapper;
import com.yida.data.school.smart.service.*;
import com.yida.data.school.vo.smart.h5.GuideStepOrderRosterCacheVO;
import com.yida.data.school.vo.smart.h5.RosterFaceMatchVO;
import com.yida.data.school.vo.smart.h5.RosterStepPayInfoVO;
import jodd.util.ThreadUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ExecutorService;

/**
 * 智慧迎新H5接口 service
 *
 * @author ZYJ
 * @date 2023/6/19 17:19
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class H5EduSmartWelcomeServiceImpl implements H5EduSmartWelcomeService {

    private final EduGuideStepOrderService eduGuideStepOrderService;
    private final EduSmartWelcomeGuideService eduSmartWelcomeGuideService;
    private final EduSmartWelcomeGuideStepService eduSmartWelcomeGuideStepService;
    private final EduSmartWelcomeGuideRosterService eduSmartWelcomeGuideRosterService;
    private final EduSmartWelcomeGuideRosterRelationService eduSmartWelcomeGuideRosterRelationService;
    private final EduSmartWelcomeGuideRosterRelationStepService eduSmartWelcomeGuideRosterRelationStepService;

    private final EduSmartWelcomeGuideRosterRelationMapper eduSmartWelcomeGuideRosterRelationMapper;

    private final RedisService redisService;
    private final CommonService commonService;

    private final WxPublicUtil wxPublicUtil;

    @Value("${febs.uploadUrl}")
    private String uploadUrl;

    @Value("${febs.welcomePayUrl}")
    private String welcomePayUrl;

    private static final Snowflake ORDER_CODE_GENERATOR = new Snowflake(1, 1);

    private static final ExecutorService GUIDE_STEP_ORDER_SUCCESS_POOL =
        ThreadPoolUtil.getThreadPool("guide-step-order-pool-%d");

    @Override
    public RosterStepPayInfoVO createGuideStepOrder(CreateGuideStepOrderDTO dto) {

        Dept school = commonService.getDept(dto.getDeptId());
        if (Objects.isNull(school)) {
            throw new FebsException("学校信息错误");
        }
        // 查询用户信息
        String openId = wxPublicUtil.getOpenId(school.getWxPublicAppId(), school.getWxPublicSecret(), dto.getCode());
        // 查询openId是否绑定了对应的信息
        EduSmartWelcomeGuideRosterRelation rosterRelation = eduSmartWelcomeGuideRosterRelationService
            .getOpenIdRelation(openId, dto.getDeptId());
        if (Objects.isNull(rosterRelation)) {
            throw new FebsException("请绑定基础信息后再扫码进行操作！");
        }
        dto.setGuideId(rosterRelation.getGuideId());
        dto.setRelationId(rosterRelation.getId());
        // 判断是否有下单缓存信息
        GuideStepOrderRosterCacheVO cacheVO = (GuideStepOrderRosterCacheVO) redisService.get(
            CachePrefixConstant.GUIDE_STEP_ORDER_ROSTER + rosterRelation.getId());
        if (Objects.nonNull(cacheVO)) {
            Object orderFlag = redisService.get(CachePrefixConstant.GUIDE_STEP_ORDER_FLAG + cacheVO.getOrderNo());
            // 判断是否还存在支付链接
            if (Objects.nonNull(orderFlag)) {
                EduGuideStepOrder order = eduGuideStepOrderService.getOne(new LambdaQueryWrapper<>(new EduGuideStepOrder())
                    .eq(EduGuideStepOrder::getOrderCode, cacheVO.getOrderNo()));
                if (Objects.isNull(order) || OrderStatusEnum.CLOSED.getStatus().equals(order.getOrderStatus())) {
                    throw new FebsException("支付异常！请稍后重试");
                }
                return getPayInfo(order, orderFlag.toString(), true);
            }
        }
//        // 查询步骤信息
//        EduSmartWelcomeGuideStep step = eduSmartWelcomeGuideStepService.getById(dto.getStepId());
//        if (Objects.isNull(step)) {
//            throw new FebsException("当前步骤不支持缴费功能");
//        }
//        if (!GuideStepTypeEnum.PAY_TYPE.getType().equals(step.getStepType())) {
//            throw new FebsException("当前步骤不支持缴费功能");
//        }
//        // 查询绑定信息
//        EduSmartWelcomeGuideRosterRelation rosterRelation =
//                eduSmartWelcomeGuideRosterRelationService.getById(dto.getRelationId());
//        if (Objects.isNull(rosterRelation)) {
//            throw new FebsException("信息错误");
//        }
//
//        EduSmartWelcomeGuideRoster guideRoster = eduSmartWelcomeGuideRosterService.getById(rosterRelation.getRosterId());
//        if (Objects.isNull(guideRoster)) {
//            throw new FebsException("信息错误");
//        }
//        rosterRelation.setGuideRoster(guideRoster);
//        // 判断是否已经缴费过
//        EduSmartWelcomeGuideRosterRelationStep relationStep = eduSmartWelcomeGuideRosterRelationStepService
//                .getOne(Wrappers.lambdaQuery(new EduSmartWelcomeGuideRosterRelationStep())
//                        .eq(EduSmartWelcomeGuideRosterRelationStep::getRosterId, guideRoster.getId())
//                        .eq(EduSmartWelcomeGuideRosterRelationStep::getStepId, step.getId())
//                        .eq(EduSmartWelcomeGuideRosterRelationStep::getPayStatus, PayStatusEnum.PAY_SUCCESS.getStatus())
//                        .eq(EduSmartWelcomeGuideRosterRelationStep::getStatus, AuditStatusEnum.PASS_STATUS.getStatus())
//                );
//        if (Objects.nonNull(relationStep)) {
//            throw new FebsException("请勿重复缴费");
//        }
//        // 判断前提步骤执行状态
//        if (Objects.nonNull(step.getPremiseStepId())) {
//            EduSmartWelcomeGuideRosterRelationStep premiseRelationStep = eduSmartWelcomeGuideRosterRelationStepService
//                    .getOne(Wrappers.lambdaQuery(new EduSmartWelcomeGuideRosterRelationStep())
//                            .eq(EduSmartWelcomeGuideRosterRelationStep::getRosterId, guideRoster.getId())
//                            .eq(EduSmartWelcomeGuideRosterRelationStep::getStepId, step.getPremiseStepId())
//                            .eq(EduSmartWelcomeGuideRosterRelationStep::getStatus, AuditStatusEnum.PASS_STATUS.getStatus())
//                    );
//            if (Objects.isNull(premiseRelationStep)) {
//                EduSmartWelcomeGuideStep premiseStep = eduSmartWelcomeGuideStepService.getById(step.getPremiseStepId());
//                throw new FebsException(String.format("请审核通过【%s】后执行其它步骤！", premiseStep.getStepName()));
//            }
//        }

        String orderCode = "";
        try {
            // 订单号 需要根据支付方式生成不同的订单号
            String orderNo = "";
            if (PayWay.WEI_XIN.getValue().equals(dto.getPayWay())) {
                // 微信
                orderNo = String.valueOf(ORDER_CODE_GENERATOR.nextId());
            } else if (PayWay.UNION.getValue().equals(dto.getPayWay())) {
                // 银联
                // 获取银联商户号相关信息
                UnionPayConfig config = commonService.getUnionPayConfigByDept(rosterRelation.getDeptId());
                if (Objects.isNull(config)) {
                    log.error("获取银联商户号相关信息错误deptId: {}", rosterRelation.getDeptId());
                    throw new FebsException("暂未配置支付信息");
                }
                orderNo = UnionPayUtil.getOrderNumber(Objects.nonNull(config.getParentConfig())
                    ? config.getParentConfig().getSourceNumber() : config.getSourceNumber());
            } else if (PayWay.CONSTRUCTION_PAY.getValue().equals(dto.getPayWay())) {
                // 建行
                // 获取建行支付配置相关信息
                ConstructionPayConfig config = commonService.getConstructionPayConfigByDept(rosterRelation.getDeptId());
                if (Objects.isNull(config)) {
                    log.error("获取建行支付配置相关信息错误deptId: {}", rosterRelation.getDeptId());
                    throw new FebsException("暂未配置支付信息");
                }
                orderNo = ConstructionPayUtil.getOrderNumber(config.getMerchantId());
            }

            if (StringUtils.isEmpty(orderNo)) {
                log.error("生成订单号失败！");
                throw new FebsException(ResultMsgType.ORDER_FAIL.getValue());
            }
            orderCode = orderNo;
            GuideStepOrderRosterCacheVO orderRosterCacheVO = GuideStepOrderRosterCacheVO.builder()
                .guideId(dto.getGuideId())
//                    .stepId(dto.getStepId())
                .relationId(dto.getRelationId())
                .deptId(rosterRelation.getDeptId())
                .orderNo(orderNo)
                .build();
            // 添加花名册人员迎新订单缓存
            redisService.set(CachePrefixConstant.GUIDE_STEP_ORDER_ROSTER + dto.getRelationId(),
                orderRosterCacheVO, 900L);
            return createOrder(dto, null, rosterRelation, orderNo);
        } catch (Exception e) {
            if (log != null) {
                log.error("下单失败", e);
            }
            // 删除花名册人员迎新订单缓存
            redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER_ROSTER + dto.getRelationId());
            // 删除迎新订单对应缓存
            if (StringUtils.isNotBlank(orderCode)) {
                redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER + orderCode);
                redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER_FLAG + orderCode);
            }
            throw new FebsException(e instanceof FebsException ? e.getMessage() : ResultMsgType.ORDER_FAIL.getValue());
        }
    }

    /**
     * 生成订单并返回支付信息
     *
     * @param dto            生成花名册步骤订单请求类
     * @param step           步骤信息
     * @param rosterRelation 关联关系信息
     * @param orderNo        订单号
     * @return com.yida.data.school.vo.smart.h5.RosterStepPayInfoVO
     * @author ZYJ
     * @date 2023/6/20 17:28
     */
    private RosterStepPayInfoVO createOrder(CreateGuideStepOrderDTO dto, EduSmartWelcomeGuideStep step,
        EduSmartWelcomeGuideRosterRelation rosterRelation, String orderNo) {
        // 生成迎新订单信息
        EduGuideStepOrder eduGuideStepOrder = new EduGuideStepOrder();
        eduGuideStepOrder.setOrderCode(orderNo);
        // 流水号
        eduGuideStepOrder.setTransactionNumber(PayUtil.generateSerialNumber("P", rosterRelation.getDeptId(), ""));
        eduGuideStepOrder.setGuideId(dto.getGuideId());
//        eduGuideStepOrder.setStepId(dto.getStepId());
        eduGuideStepOrder.setRosterId(rosterRelation.getRosterId());
        eduGuideStepOrder.setRelationId(dto.getRelationId());
        // 指南信息
        EduSmartWelcomeGuide guide = eduSmartWelcomeGuideService.getById(dto.getGuideId());
        // 金额
        BigDecimal money = guide.getMoney();
        eduGuideStepOrder.setTotalMoney(money);
        eduGuideStepOrder.setPracticalMoney(money);
        eduGuideStepOrder.setPhone(rosterRelation.getGuideRoster().getMobile());
        // 订单状态和支付状态
        eduGuideStepOrder.setOrderStatus(OrderStatusEnum.NOT_PAY.getStatus());
        eduGuideStepOrder.setPayStatus(PayStatusEnum.NOT_PAY.getStatus());
        eduGuideStepOrder.setPayWay(dto.getPayWay());
        eduGuideStepOrder.setPayType(dto.getPayType());
        eduGuideStepOrder.setDeptId(rosterRelation.getDeptId());
        // 保存订单主体信息
        eduGuideStepOrderService.save(eduGuideStepOrder);

        // 返回值
        RosterStepPayInfoVO payInfoVO = new RosterStepPayInfoVO();
        // 金额为0，直接为成功订单
        if (NumberUtil.isLessOrEqual(eduGuideStepOrder.getPracticalMoney(), BigDecimal.ZERO)) {
            guideStepOrderPaySuccess(eduGuideStepOrder.getOrderCode(), LocalDateTime.now());
            payInfoVO.setNeedToPay(false);
            payInfoVO.setOrderCode(eduGuideStepOrder.getOrderCode());
        } else {
            // 下单返回信息
            String result = placeOrder(eduGuideStepOrder);
            // 添加迎新订单缓存
            redisService.set(CachePrefixConstant.GUIDE_STEP_ORDER + eduGuideStepOrder.getOrderCode(), eduGuideStepOrder, 900L);
            redisService.set(CachePrefixConstant.GUIDE_STEP_ORDER_FLAG + eduGuideStepOrder.getOrderCode(), result, 900L);
            payInfoVO = getPayInfo(eduGuideStepOrder, result, true);
        }
        return payInfoVO;
    }

    /**
     * 调用第三方接口生成支付信息
     *
     * @param eduGuideStepOrder 迎新订单信息
     * @return java.lang.String
     * @author ZYJ
     * @date 2023/6/20 17:17
     */
    private String placeOrder(EduGuideStepOrder eduGuideStepOrder) {
        // 下单返回信息
        String result = "";
        try {
            if (PayWay.CONSTRUCTION_PAY.getValue().equals(eduGuideStepOrder.getPayWay())) {
                // 建行支付
                result = ConstructionPayUtil.getQrPayUrl(
                    commonService.getConstructionPayConfigByDept(eduGuideStepOrder.getDeptId()),
                    ConstructionPayOrder.builder()
                        .orderNo(eduGuideStepOrder.getOrderCode())
                        .payMoney(eduGuideStepOrder.getPracticalMoney())
                        .orderTime(Date.from(eduGuideStepOrder.getCreateDate().atZone(ZoneId.systemDefault()).toInstant()))
                        .build());
            }
        } catch (Exception e) {
            log.error("迎新订单下单失败", e);
            throw new FebsException(ResultMsgType.ORDER_FAIL.getValue());
        }
        if (StringUtils.isEmpty(result)) {
            log.error("迎新订单失败, 没有支付信息");
            throw new FebsException(ResultMsgType.ORDER_FAIL.getValue());
        }
        return result;
    }

    /**
     * 获取订单支付信息
     *
     * @param order     迎新订单信息
     * @param orderFlag 订单支付标识
     * @param needToPay 是否需要跳转支付
     * @return com.yida.data.school.vo.smart.h5.RosterStepPayInfoVO
     * @author ZYJ
     * @date 2023/6/20 17:16
     */
    public RosterStepPayInfoVO getPayInfo(EduGuideStepOrder order, String orderFlag, boolean needToPay) {
        RosterStepPayInfoVO payInfoVO = null;
        if (PayWay.CONSTRUCTION_PAY.getValue().equals(order.getPayWay())) {
            // 建行
            payInfoVO = RosterStepPayInfoVO.builder()
                .orderCode(order.getOrderCode())
                .payWay(order.getPayWay())
                .payType(order.getPayType())
                .needToPay(needToPay)
                .payUrl(orderFlag)
                .build();
        }
        return payInfoVO;
    }

    @Override
    public void guideStepOrderPaySuccess(String orderCode, LocalDateTime payDate) {
//        File qrCodeFile = null;
        try {
            // 修改订单信息
            EduGuideStepOrder order = eduGuideStepOrderService.getOne(new LambdaQueryWrapper<>(new EduGuideStepOrder())
                .eq(EduGuideStepOrder::getOrderCode, orderCode));
            order.setPayDate(payDate);
            order.setOrderStatus(OrderStatusEnum.PAY_SUCCESS.getStatus());
            order.setPayStatus(PayStatusEnum.PAY_SUCCESS.getStatus());
            eduGuideStepOrderService.updateById(order);
//            // 修改步骤支付状态
//            EduSmartWelcomeGuideRosterRelationStep relationStep = eduSmartWelcomeGuideRosterRelationStepService
//                    .getOne(Wrappers.lambdaQuery(new EduSmartWelcomeGuideRosterRelationStep())
//                            .eq(EduSmartWelcomeGuideRosterRelationStep::getRelationId, order.getRelationId())
//                            .eq(EduSmartWelcomeGuideRosterRelationStep::getStepId, order.getStepId())
//                    );
//            if (!Objects.nonNull(relationStep)) {
//                relationStep = new EduSmartWelcomeGuideRosterRelationStep();
//                relationStep.setDeptId(order.getDeptId());
//                relationStep.setGuideId(order.getGuideId());
//                relationStep.setRosterId(order.getRosterId());
//                relationStep.setRelationId(order.getRelationId());
//                relationStep.setStepId(order.getStepId());
//            }
//            relationStep.setStatus(AuditStatusEnum.PASS_STATUS.getStatus());
//            relationStep.setPayStatus(PayStatusEnum.PAY_SUCCESS.getStatus());
//            eduSmartWelcomeGuideRosterRelationStepService.saveOrUpdate(relationStep);

            // 更新用户支付状态
            EduSmartWelcomeGuideRoster guideRoster = eduSmartWelcomeGuideRosterService.getById(order.getRosterId());
            eduSmartWelcomeGuideRosterService.updateById(
                EduSmartWelcomeGuideRoster.builder()
                    .id(guideRoster.getId())
                    .payStatus(1)
                    .build());
            // 生成花名册二维码信息
//            EduSmartWelcomeGuideRoster guideRoster = eduSmartWelcomeGuideRosterService.getById(order.getRosterId());
//            JSONObject obj = JSONUtil.createObj()
//                    .set("rosterId", guideRoster.getId())
//                    .set("deptId", order.getDeptId())
//                    .set("guideId", order.getGuideId())
//                    .set("fullName", guideRoster.getFullName())
//                    .set("graduateSchool", guideRoster.getGraduateSchool())
//                    .set("idNumber", guideRoster.getIdNumber())
//                    .set("admittedMajor", guideRoster.getAdmittedMajor());
//            // 生成文件名称
//            String fileName = UUID.randomUUID().toString(true) + ".png";
//            String filePath = FileUtil.getLocalUploadAddress() + fileName;
//            QrCodeUtil.generateQrCodeImage(obj.toString(), 400, 400, filePath);
//            // 上传文件到媒资
//            qrCodeFile = new File(filePath);
//            String qrCodeAddress = FileUtil.uploadFileToMediaServer(uploadUrl, qrCodeFile);
//            eduSmartWelcomeGuideRosterService.updateById(
//                    EduSmartWelcomeGuideRoster.builder()
//                            .id(guideRoster.getId())
//                            .qrCodeUrl(qrCodeAddress)
//                            .build());

            // 删除花名册人员迎新订单缓存
            redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER_ROSTER + order.getRelationId());
            // 删除迎新订单对应缓存
            redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER + orderCode);
            redisService.del(CachePrefixConstant.GUIDE_STEP_ORDER_FLAG + orderCode);
        } catch (Exception e) {
            log.error("迎新订单支付成功接口调用失败", e);
            throw new FebsException("调用失败");
        }
    }

    @Override
    public void guideStepOrderSuccess(String orderCode) {
        GUIDE_STEP_ORDER_SUCCESS_POOL.execute(() -> {
            EduGuideStepOrder order = eduGuideStepOrderService.getOne(new LambdaQueryWrapper<>(new EduGuideStepOrder())
                .eq(EduGuideStepOrder::getOrderCode, orderCode));

            if (Objects.nonNull(order)
                && (OrderStatusEnum.NOT_PAY.getStatus().equals(order.getOrderStatus())
                || OrderStatusEnum.USER_PAYING.getStatus().equals(order.getOrderStatus()))) {
                if (PayWay.CONSTRUCTION_PAY.getValue().equals(order.getPayWay())) {
                    // 建行
                    constructionGuideStepOrderSuccess(order);
                }
            }
        });
    }

    /**
     * 处理建行查询订单
     *
     * @param order 订单信息
     * @author ZYJ
     * @date 2023/6/20 17:36
     */
    private void constructionGuideStepOrderSuccess(EduGuideStepOrder order) {
        boolean flag = false;
        // 订单号
        String orderCode = order.getOrderCode();
        // 查询建行支付配置
        ConstructionPayConfig config = commonService.getConstructionPayConfigByDept(order.getDeptId());
        if (Objects.isNull(config)) {
            log.error("当前学校赞未配置建行支付信息");
            return;
        }

        while (LocalDateTimeUtil.between(order.getCreateDate(), LocalDateTime.now()).getSeconds() < 900L) {
            try {
                JSONObject resJson = ConstructionPayUtil.queryOrder(config, orderCode);
                // 支付信息
                JSONObject queryOrder = resJson.getJSONObject("QUERYORDER");
                // 金额
                BigDecimal amount = new BigDecimal(queryOrder.getStr("AMOUNT"));
                if (order.getPracticalMoney().compareTo(amount) != 0) {
                    log.error("支付信息金额错误");
                    break;
                }
                // 支付状态
                String status = (String) queryOrder.get("STATUSCODE");
                if (ConstructionTradeStateEnum.WAIT_BANK_CONFIRM.getStatus().equals(status)
                    || ConstructionTradeStateEnum.WAIT_BANK_CONFIRM_OTHER.getStatus().equals(status)) {
                    continue;
                }
                ConstructionTradeStateEnum tradeStateEnum = EnumUtils.valueOf(ConstructionTradeStateEnum.class, status,
                    ConstructionTradeStateEnum.class.getMethod("getStatus"));
                switch (Objects.requireNonNull(tradeStateEnum)) {
                    // 支付成功
                    case TRADE_SUCCESS:
                        guideStepOrderPaySuccess(order.getOrderCode(),
                            LocalDateTimeUtil.parse((String) queryOrder.get("ORDERDATE"), DatePattern.PURE_DATETIME_PATTERN));
                        flag = true;
                        break;
                    // 订单关闭
                    case TRADE_FAIL:
                        order.setOrderStatus(OrderStatusEnum.CLOSED.getStatus());
                        order.setPayStatus(PayStatusEnum.CANCEL.getStatus());
                        eduGuideStepOrderService.updateById(order);
                        flag = true;
                        break;
                    default:
                        break;
                }
                if (flag) {
                    break;
                }
                ThreadUtil.sleep(1500L);
            } catch (Exception e) {
                ThreadUtil.sleep(1500L);
                log.error("迎新订单(建行支付方式)完成失败, orderNo: {}", orderCode, e);
            }
        }
    }

    @Override
    public RosterFaceMatchVO rosterFaceMatch(RosterFaceMatchDTO dto) {
        File file = null;
        try {
            // 查询步骤信息
            EduSmartWelcomeGuideStep step = eduSmartWelcomeGuideStepService.getById(dto.getStepId());
            if (Objects.isNull(step)) {
                throw new FebsException("当前步骤不支持人脸对比功能");
            }
            if (!GuideStepTypeEnum.MATCH_FACE.getType().equals(step.getStepType())) {
                throw new FebsException("当前步骤不支持人脸对比功能");
            }
            // 查询绑定信息
            EduSmartWelcomeGuideRosterRelation rosterRelation =
                eduSmartWelcomeGuideRosterRelationService.getById(dto.getRelationId());
            if (Objects.isNull(rosterRelation)) {
                throw new FebsException("信息错误");
            }
            EduSmartWelcomeGuideRoster guideRoster = eduSmartWelcomeGuideRosterService.getById(rosterRelation.getRosterId());
            if (Objects.isNull(guideRoster)) {
                throw new FebsException("信息错误");
            }
            // 判断前提步骤执行状态
            if (Objects.nonNull(step.getPremiseStepId())) {
                EduSmartWelcomeGuideRosterRelationStep premiseRelationStep = eduSmartWelcomeGuideRosterRelationStepService
                    .getOne(Wrappers.lambdaQuery(new EduSmartWelcomeGuideRosterRelationStep())
                        .eq(EduSmartWelcomeGuideRosterRelationStep::getRosterId, guideRoster.getId())
                        .eq(EduSmartWelcomeGuideRosterRelationStep::getStepId, step.getPremiseStepId())
                        .eq(EduSmartWelcomeGuideRosterRelationStep::getStatus, AuditStatusEnum.PASS_STATUS.getStatus())
                    );
                if (Objects.isNull(premiseRelationStep)) {
                    EduSmartWelcomeGuideStep premiseStep = eduSmartWelcomeGuideStepService.getById(step.getPremiseStepId());
                    throw new FebsException(String.format("请审核通过【%s】后执行其它步骤！", premiseStep.getStepName()));
                }
            }
            // 查询百度api配置信息
            BaiduApiConfig config = commonService
                .getBaiDuApiConfigByDept(rosterRelation.getDeptId(), BaiDuModuleEnum.FACE_DETECT.getValue());
            if (Objects.isNull(config)) {
                log.error("获取百度api相关信息错误deptId: {}", rosterRelation.getDeptId());
                throw new FebsException("暂未配置人脸对比信息");
            }
            // 人脸对比 阈值80
            String score = BaiDuUtil.faceMatch(config, guideRoster.getAvatar(), dto.getBase64());
            int valid = NumberUtil.isLess(new BigDecimal("60"), new BigDecimal(score)) ? 1 : 0;
            RosterFaceMatchVO matchVO = RosterFaceMatchVO.builder()
                .valid(valid)
                .score(score)
                .build();
            // 对比成功则上传图片
            if (valid == 1) {
                String fileName = FileUtil.getLocalUploadAddress() + UUID.randomUUID() + ".png";
                file = new File(fileName);
                // 上传图片
                file = Base64.decodeToFile(dto.getBase64(), file);
                String url = FileUtil.uploadFileToMediaServer(uploadUrl, file);
                matchVO.setUrl(url);
                // 保存人脸图片信息
                EduSmartWelcomeGuideRosterRelationStep relationStep = eduSmartWelcomeGuideRosterRelationStepService
                    .getOne(Wrappers.lambdaQuery(new EduSmartWelcomeGuideRosterRelationStep())
                        .eq(EduSmartWelcomeGuideRosterRelationStep::getRelationId, dto.getRelationId())
                        .eq(EduSmartWelcomeGuideRosterRelationStep::getStepId, dto.getStepId())
                    );
                if (Objects.nonNull(relationStep)) {
                    relationStep.setStatus(AuditStatusEnum.PASS_STATUS.getStatus());
                    relationStep.setUploadFileUrl(url);
                } else {
                    relationStep = new EduSmartWelcomeGuideRosterRelationStep();
                    relationStep.setDeptId(guideRoster.getDeptId());
                    relationStep.setGuideId(dto.getGuideId());
                    relationStep.setRosterId(guideRoster.getId());
                    relationStep.setRelationId(dto.getRelationId());
                    relationStep.setStepId(dto.getStepId());
                    relationStep.setStatus(AuditStatusEnum.PASS_STATUS.getStatus());
                    relationStep.setUploadFileUrl(url);
                }
                eduSmartWelcomeGuideRosterRelationStepService.saveOrUpdate(relationStep);
            }
            return matchVO;
        } catch (Exception e) {
            throw new FebsException(e instanceof FebsException ? e.getMessage() : "人脸对比失败");
        } finally {
            if (Objects.nonNull(file)) {
                cn.hutool.core.io.FileUtil.del(file);
            }
        }

    }

    @Override
    public EduSmartWelcomeGuideRoster getUserQrCodeUrl(Long rosterId) {
        EduSmartWelcomeGuideRoster roster = (EduSmartWelcomeGuideRoster) redisService
            .hget(CachePrefixConstant.WELCOME_ROSTER, rosterId.toString());
        if (ObjectUtil.isNull(roster)) {
            roster = eduSmartWelcomeGuideRosterService.getById(rosterId);
        }
        return roster;
    }

    @Override
    public String getPayQrCodeUrl(Long deptId) {
        Dept dept = commonService.getDept(deptId);
        if (Objects.isNull(dept)) {
            throw new FebsException("学校信息错误");
        }
        return welcomePayUrl + StringConstant.QUESTION_MARK + "deptId=" + dept.getDeptId()
            + StringConstant.AMPERSAND + "appId=" + dept.getWxPublicAppId();
    }

    @Override
    public IPage<EduSmartWelcomeGuideRosterRelation> listRoster(RosterPageDTO dto) {
        return eduSmartWelcomeGuideRosterRelationMapper.listRoster(dto.toPage(), dto);
    }
}
