package com.fs.qw.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.ad.enums.AdUploadType;
import com.fs.ad.service.IAdHtmlClickLogService;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.PubFun;
import com.fs.common.utils.StringUtils;
import com.fs.company.cache.ICompanyCacheService;
import com.fs.company.cache.ICompanyUserCacheService;
import com.fs.company.service.ICompanyConfigService;
import com.fs.course.config.CourseConfig;
import com.fs.course.domain.FsCourseSop;
import com.fs.course.domain.FsCourseSopLogs;
import com.fs.course.domain.FsCourseWatchLog;
import com.fs.course.mapper.FsCourseLinkMapper;
import com.fs.course.mapper.FsCourseSopLogsMapper;
import com.fs.course.mapper.FsCourseSopMapper;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.course.param.FsCourseLinkCreateParam;
import com.fs.course.service.IFsCourseLinkService;
import com.fs.crm.domain.CrmCustomer;
import com.fs.crm.mapper.CrmCustomerMapper;
import com.fs.qw.domain.*;
import com.fs.qw.dto.GetQwRepeatDataDTO;
import com.fs.qw.mapper.*;
import com.fs.qw.param.*;
import com.fs.qw.param.newparam.ExternalContactPageListParam;
import com.fs.qw.result.QwExternalContactLogVo;
import com.fs.qw.result.QwExternalContactVo;
import com.fs.qw.service.*;
import com.fs.qw.vo.*;
import com.fs.qw.vo.newvo.ExternalContactDetailsVO;
import com.fs.qw.vo.newvo.ExternalContactListVO;
import com.fs.qw.vo.newvo.ExternalContactNumVO;
import com.fs.qw.vo.newvo.ExternalContactPageVO;
import com.fs.qwApi.Result.QwOpenidResult;
import com.fs.qwApi.domain.*;
import com.fs.qwApi.domain.inner.*;
import com.fs.qwApi.param.*;
import com.fs.qwApi.service.QwApiService;
import com.fs.sop.domain.QwSop;
import com.fs.sop.domain.SopUserLogs;
import com.fs.sop.domain.SopUserLogsInfo;
import com.fs.sop.mapper.QwSopLogsMapper;
import com.fs.sop.mapper.QwSopMapper;
import com.fs.sop.mapper.SopUserLogsInfoMapper;
import com.fs.sop.params.*;
import com.fs.sop.service.IQwSopService;
import com.fs.sop.service.ISopUserLogsInfoService;
import com.fs.sop.service.ISopUserLogsService;
import com.fs.store.domain.FsUser;
import com.fs.store.mapper.FsUserMapper;
import com.fs.system.domain.SysConfig;
import com.fs.system.service.ISysConfigService;
import com.fs.voice.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.DateUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.ParseException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 企业微信客户Service业务层处理
 *
 * @author fs
 * @date 2024-06-20
 */
@Slf4j
@Service
public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactMapper, QwExternalContact> implements IQwExternalContactService {

    private static final String miniappRealLink = "/pages_course/video.html?course=";
    private static final String registerLink = "/registerCourse/pages/index?qwExternalId=";

    @Autowired
    private QwExternalContactMapper qwExternalContactMapper;
    @Autowired
    private IQwExternalContactService qwExternalContactService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private QwExternalContactBlackLogMapper qwExternalContactBlackLogMapper;
    @Autowired
    private IQwExternalContactBlackLogService qwExternalContactBlackLogService;
    @Autowired
    private IQwTagService iQwTagService;
    @Autowired
    ICompanyConfigService companyConfigService;
    @Autowired
    private QwUserMapper qwUserMapper;
    @Autowired
    private FsCourseWatchLogMapper watchLogMapper;
    @Autowired
    QwApiService qwApiService;
    @Autowired
    QwContactWayMapper qwContactWayMapper;
    @Autowired
    IAdHtmlClickLogService adHtmlClickLogService;
    @Autowired
    private QwExternalContactTransferLogMapper qwExternalContactTransferLogMapper;
    @Autowired
    IQwContactWayService qwContactWayService;
    @Autowired
    QwContactWayUserMapper qwContactWayUserMapper;
    @Autowired
    QwContactWayLogsMapper qwContactWayLogsMapper;

    @Autowired
    QwFriendWelcomeMapper qwFriendWelcomeMapper;

    @Autowired
    ISopUserLogsInfoService iSopUserLogsInfoService;

    @Autowired
    private FsCourseLinkMapper fsCourseLinkMapper;


    @Autowired
    QwAutoTagsMapper qwAutoTagsMapper;
    @Autowired
    CrmCustomerMapper crmCustomerMapper;
    @Autowired
    QwAutoTagsLogsMapper qwAutoTagsLogsMapper;
    @Autowired
    IAdHtmlClickLogService iAdHtmlClickLogService;

    @Autowired
    IQwSopService qwSopService;

    @Autowired
    IQwExternalContactCrmService contactCrmService;

    @Autowired
    FsCourseSopLogsMapper fsSopLogsMapper;

    @Autowired
    FsCourseSopMapper fsSopMapper;

    @Autowired
    CrmCustomerMapper customerMapper;

    @Autowired
    FsCourseWatchLogMapper fsCourseWatchLogMapper;
    @Autowired
    QwAppContactWayLogsMapper qwAppContactWayLogsMapper;
    @Autowired
    private QwSopMapper qwSopMapper;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    private FsUserMapper fsUserMapper;
    @Autowired
    private QwSopLogsMapper qwSopLogsMapper;

    @Autowired
    private QwAppContactWayMapper qwAppContactWayMapper;
    @Autowired
    private SopUserLogsInfoMapper sopUserLogsInfoMapper;

    @Autowired
    private ISopUserLogsService sopUserLogsService;

    @Autowired
    private IFsCourseLinkService iFsCourseLinkService;

    @Autowired
    private IQwExternalErrRetryService errRetryService;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private RedisCache redisCache;


    Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void addQwCourseJob() {
        List<QwSop> qwSops = qwSopMapper.selectQwSopByIsRating();
        for (QwSop qwSop : qwSops) {

            fsCourseWatchLogMapper.selectFsCourseWatchLogBySopId(qwSop.getId());
        }
    }

    @Override
    public int updateQwExternalContactByFsUserId(Integer commentStatus, Long fsUserId) {
        return qwExternalContactMapper.updateQwExternalContactByFsUserId(commentStatus, fsUserId);
    }

    /**
     * 根据外部联系人ID查询用户是否已购产品
     * @param qwExternalContactId   外部联系人ID
     * @return  Boolean
     */
    @Override
    public Boolean getBuyStatusByExtId(Long qwExternalContactId) {
        return qwExternalContactMapper.getBuyStatusByExtId(qwExternalContactId);
    }

    /**
     * 查询企业微信客户
     *
     * @param id 企业微信客户主键
     * @return 企业微信客户
     */
    @Override
    public QwExternalContact selectQwExternalContactById(Long id) {
        return qwExternalContactMapper.selectQwExternalContactById(id);
    }

    /**
     * 根据外部联系人的userid 获取到详细信息
     */
    @Override
    public List<QwExternalContact> selectQwExternalContactByExternalUserId(String externalUserId, String corpId) {

        return qwExternalContactMapper.selectQwExternalContactByExternalUserId(externalUserId, corpId);
    }


    /**
     * 统计预期发送消息人员的客户总数
     */
    @Override
    public R expectQwGroupMsgCountCustomer(QwCountCustomerParam userIdList) {

        int count = qwExternalContactMapper.expectQwGroupMsgCountCustomer(userIdList);
        return R.ok().put("data", count);
    }

    /**
     * 预计发送消息人员的客户列表
     */

    @Override
    public ArrayList<String> selectQwGroupMsgExpectCustomerList(QwCountCustomerParam userIdList, String corpId) {


        return qwExternalContactMapper.selectQwGroupMsgExpectCustomerList(userIdList, corpId);
    }

    /**
     * 查询企业微信客户列表
     *
     * @param qwExternalContact 企业微信客户
     * @return 企业微信客户
     */
    @Override
    public List<QwExternalContact> selectQwExternalContactList(QwExternalContact qwExternalContact) {
        return qwExternalContactMapper.selectQwExternalContactList(qwExternalContact);
    }

    /**
     * 新增企业微信客户
     *
     * @param qwExternalContact 企业微信客户
     * @return 结果
     */
    @Override
    public int insertQwExternalContact(QwExternalContact qwExternalContact) {
        return qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
    }

    /**
     * 修改企业微信客户
     *
     * @param qwExternalContact 企业微信客户
     * @return 结果
     */
    @Override
    public int updateQwExternalContact(QwExternalContact qwExternalContact) {
        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
        param.setRemark(qwExternalContact.getRemark());
        param.setUserid(qwExternalContact.getUserId());
        param.setExternal_userid(qwExternalContact.getExternalUserId());
        if (qwExternalContact.getRemarkMobiles() != null && qwExternalContact.getRemarkMobiles() != "") {
            List<String> mobiles = JSON.parseArray(qwExternalContact.getRemarkMobiles(), String.class);
            if (mobiles != null && mobiles.size() > 0) {
                param.setRemark_mobiles(mobiles);
            } else {
                param.setRemark_mobiles(Arrays.asList(""));
            }
        } else {
            param.setRemark_mobiles(Arrays.asList(""));
        }

        param.setDescription(qwExternalContact.getDescription());
        param.setRemark_company(qwExternalContact.getRemarkCorpName());
        QwExternalContactRemarkResult qwExternalContactRemarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());
        logger.info("QwExternalContactRemarkResult206：" + qwExternalContactRemarkResult);
        if (qwExternalContactRemarkResult.getErrcode() == 0) {
            return qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
        } else {
            return 0;
        }


    }

    @Override
    public int updateQwExternalContactCallEdit(QwExternalContact qwExternalContact) {
        return qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
    }

    /**
     * 批量删除企业微信客户
     *
     * @param ids 需要删除的企业微信客户主键
     * @return 结果
     */
    @Override
    public int deleteQwExternalContactByIds(Long[] ids) {
        return qwExternalContactMapper.deleteQwExternalContactByIds(ids);
    }

    /**
     * 删除企业微信客户信息
     *
     * @param id 企业微信客户主键
     * @return 结果
     */
    @Override
    public int deleteQwExternalContactById(Long id) {
        return qwExternalContactMapper.deleteQwExternalContactById(id);
    }

    @Override
    public List<QwExternalContactVO> selectQwExternalContactListVO(QwExternalContactParam qwExternalContact) {
        return qwExternalContactMapper.selectQwExternalContactListVO(qwExternalContact);
    }

    @Override
    public List<QwExternalContactVOTime> selectQwExternalContactListVOByIds(List<Long> ids) {
        return qwExternalContactMapper.selectQwExternalContactListVOByIds(ids);
    }

    @Override
    public R syncQwExternalContact(String corpId) throws IOException {

        QwUserIdResult userList = qwApiService.getUserList(corpId);

        List<DeptUser> deptUser = userList.getDept_user();

        for (DeptUser user : deptUser) {

            String userid = user.getUserid();

            QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userid);

            syncMyQwExternalContactRecursion(qwUser, null);

        }
        return R.ok();
    }

    @Override
    public R syncMyQwExternalContact(Long id) {

        QwUser qwUser = qwUserMapper.selectQwUserById(id);


        //对比同步客户信息
        getContactListResult(qwUser);

//        return  R.ok();
        return syncMyQwExternalContactRecursion(qwUser, null);
    }

    public void getContactListResult(QwUser qwUser) {

//        //异步处理销售删除客户的
//        asyncSopService.deleteSop(qwUser);

        QwExternalContactListResult contactListResult = qwApiService.getExternalcontactList(qwUser.getQwUserId(), qwUser.getCorpId());

        try {
            if (contactListResult.getErrcode() == 0) {

                List<String> externalUserid = contactListResult.getExternal_userid();
                List<String> qwExternalContactList = qwExternalContactMapper.selectQwExternalContactListAll(qwUser.getQwUserId(), qwUser.getCorpId());

                // 过滤：只保留在 qwExternalContactList 中，且不在 externalUserid 列表中的外部联系人ID
                List<String> notInExternalUseridList = qwExternalContactList.stream()
                        .filter(externalUserId -> !externalUserid.contains(externalUserId))
                        .collect(Collectors.toList());

                // 2. 设定每个批次大小
                final int batchSize = 500;

                // 3. 分批调用，避免一次塞太多
                for (int start = 0; start < notInExternalUseridList.size(); start += batchSize) {
                    // 计算此批次的结束位置
                    int end = Math.min(start + batchSize, notInExternalUseridList.size());

                    // 获取当前批次需要删除的 externalUserId 子列表
                    List<String> subList = notInExternalUseridList.subList(start, end);

                    //删除待发送记录
                    DeleteQwSopParam apiParam = new DeleteQwSopParam();
                    apiParam.setQwUserId(qwUser.getQwUserId());
                    apiParam.setCorpId(qwUser.getCorpId());
                    apiParam.setExternalUserIds(subList);

                    // 批量删除 qw_external_contact 表中已经删除的客户的营期以及发送记录
                    sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdList(apiParam);
                    sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChatList(apiParam);


                    //批量删除发送记录
                    qwSopLogsMapper.deleteQwSopLogsByExternalUserIdList(apiParam);
                }

//                notInExternalUseridList.forEach(item->{
//                    // 删除 qw_external_contact 表中不存在的客户的营期
//                    sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactId(qwUser.getQwUserId(),qwUser.getCorpId(), item.trim());
//                    sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChat(qwUser.getQwUserId(),qwUser.getCorpId(), item.trim());
//                });

                if (!notInExternalUseridList.isEmpty()) {
                    //批量更新状态
                    batchUpdateQwExternalContact(notInExternalUseridList, qwUser.getQwUserId(), qwUser.getCorpId());
                }

            } else {
                logger.error("获取员工的客户列表失败：qwUserId:" + qwUser.getQwUserId() +
                        "|corpId:" + qwUser.getCorpId() +
                        "|errcode:" + contactListResult.getErrcode() +
                        "|errmsg:" + contactListResult.getErrmsg());
            }
        } catch (Exception e) {
            logger.error("同步企业微信客户异常-匹配外部联系人情况：{}", e.getMessage());
        }
    }

    //批量更新 库里有，但是企业微信调用回来的列表 没有了
    private void batchUpdateQwExternalContact(List<String> notInExternalUseridList, String qwUserId, String corpId) {
        // 定义批量插入的大小
        int batchSize = 500;

        // 循环处理外部用户 ID，每次处理批量大小的子集
        for (int i = 0; i < notInExternalUseridList.size(); i += batchSize) {

            int endIndex = Math.min(i + batchSize, notInExternalUseridList.size());
            List<String> batchList = notInExternalUseridList.subList(i, endIndex);  // 获取当前批次的子集

            // 直接使用批次数据进行批量更新，不需要额外的 List
            try {
                qwExternalContactMapper.batchUpdateQwExternalContactStatus(batchList, qwUserId, corpId);
            } catch (Exception e) {
                // 记录异常日志，方便后续排查问题
                logger.error("批量更新数据时发生异常，处理的批次起始索引为: " + i, e);
            }
        }
    }

    //递归
    public R syncMyQwExternalContactRecursion(QwUser qwUser, String getNextCursor) {


        String qwUserId = qwUser.getQwUserId();
        String corpId = qwUser.getCorpId();
        Long companyId = qwUser.getCompanyId();

        QwExternalListParam param = new QwExternalListParam();
        param.setLimit(100);
        param.setUserid_list(Arrays.asList(qwUserId));
        param.setCursor(getNextCursor);

        QwExternalContactAllListResult list = qwApiService.getAllExternalcontactList(param, corpId);


        try {
            if (list.getErrcode() == 0) {
                List<ExternalContactInfo> externalContactList = list.getExternal_contact_list();
                for (ExternalContactInfo externalContactInfo : externalContactList) {

                    ExternalContact externalContact = externalContactInfo.getExternal_contact();
                    FollowInfo followInfo = externalContactInfo.getFollow_info();
                    QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalContact.getExternal_userid(), qwUserId, corpId);

                    if (qwExternalContact == null) {
                        qwExternalContact = new QwExternalContact();
                        qwExternalContact.setUserId(qwUserId); // 设置属于用户ID
                        qwExternalContact.setExternalUserId(externalContact.getExternal_userid()); // 设置外部联系人ID


                        qwExternalContact.setCorpId(corpId); // 设置企业ID
                        qwExternalContact.setCompanyId(companyId); // 设置公司ID
                    }


                    // 设置公共属性
                    qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
                    qwExternalContact.setQwUserId(qwUser.getId());
                    qwExternalContact.setName(externalContact.getName()); // 设置名称
                    qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
                    qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户，2企业微信用户)
                    qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
                    qwExternalContact.setUnionid(externalContact.getUnionid());
                    qwExternalContact.setDescription(followInfo.getDescription()); // 设置描述信息
                    qwExternalContact.setRemark(followInfo.getRemark());

//                        if (followInfo.getTag_id() != null && !followInfo.getTag_id().isEmpty()) {
                    qwExternalContact.setTagIds(JSON.toJSONString(followInfo.getTag_id())); // 设置标签ID
//                        }

//                        if (followInfo.getRemark_mobiles() != null && !followInfo.getRemark_mobiles().isEmpty()) {
                    qwExternalContact.setRemarkMobiles(JSON.toJSONString(followInfo.getRemark_mobiles())); // 设置备注电话号码
//                        }

                    qwExternalContact.setState(followInfo.getState());

                    if (followInfo.getState() != null && !followInfo.getState().isEmpty()) {
                        String s = "way:" + corpId + ":";
                        if (followInfo.getState().contains(s)) {
                            String wayId = followInfo.getState().substring(followInfo.getState().indexOf(s) + s.length());
                            qwExternalContact.setWayId(Long.parseLong(wayId));
                        }
                    }
                    qwExternalContact.setRemarkCorpName(followInfo.getRemark_corp_name()); // 设置备注企业名称
                    qwExternalContact.setAddWay(followInfo.getAdd_way()); // 设置来源
                    qwExternalContact.setOperUserid(followInfo.getOper_userid()); // 设置oper用户ID

//                QwOpenidByExternalcontactParams externalcontactParams = new QwOpenidByExternalcontactParams();
//                externalcontactParams.setExternal_userid(qwExternalContact.getExternalUserId());
//                QwOpenidResult qwOpenidResult = qwApiService.externalcontactToOpenid(externalcontactParams, corpId);
//                qwExternalContact.setOpenId(qwOpenidResult.getOpenid());

                    // 根据是否存在记录进行更新或插入
                    if (qwExternalContact.getId() != null) {
                        qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
                    } else {
                        qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
                    }
                }

            } else {
                return R.error("同步失败：" + list.getErrmsg());
            }
        } catch (Exception e) {
            logger.error("递归同步客户信息失败：quUser:--" + qwUser);
        }


        if (!StringUtil.strIsNullOrEmpty(list.getNext_cursor())) {
            syncMyQwExternalContactRecursion(qwUser, list.getNext_cursor());
        }
        return R.ok();
    }

    @Override
    public R syncQwExternalContactUnassigned(String corpId) {
        QwUnassignedListParam qwUnassignedListParam = new QwUnassignedListParam();
        qwUnassignedListParam.setPage_size(1000);
        QwUnassignedListResult unassignedList = qwApiService.getUnassignedList(qwUnassignedListParam, corpId);

        if (unassignedList.getErrcode() == 0) {
            List<QwUnassignedListResult.InfoEntry> info = unassignedList.getInfo();
            for (QwUnassignedListResult.InfoEntry infoEntry : info) {

                QwExternalContact qwExternalContact = new QwExternalContact();
                qwExternalContact.setExternalUserId(infoEntry.getExternal_userid());
                qwExternalContact.setUserId(infoEntry.getHandover_userid());
                qwExternalContact.setStatus(0);
                List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactList(qwExternalContact);
                if (qwExternalContacts != null && qwExternalContacts.size() > 0) {
                    for (QwExternalContact externalContact : qwExternalContacts) {
                        QwExternalContact q = new QwExternalContact();
                        q.setId(externalContact.getId());
                        q.setStatus(1);
                        qwExternalContactMapper.updateQwExternalContact(q);
                    }
                }
            }
        }
        return R.ok();
    }

    @Override
    public R resignedTransfer(ResignedTransferParam param) {

        QwUser qwUser = qwUserMapper.selectQwUserById(param.getUserId());
        Integer err = 0;
        Integer suc = 0;
        if (qwUser != null) {
            List<Long> ids = param.getIds();
            for (Long id : ids) {
                QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(id);

                if (qwExternalContact == null || qwExternalContact.getUserId().equals(qwUser.getQwUserId())) {
                    err++;
                } else {
                    QwTransferCustomerResignedParam qwTransferCustomerParam = new QwTransferCustomerResignedParam();
                    qwTransferCustomerParam.setHandover_userid(qwExternalContact.getUserId());
                    qwTransferCustomerParam.setTakeover_userid(qwUser.getQwUserId());
                    qwTransferCustomerParam.setExternal_userid(Arrays.asList(qwExternalContact.getExternalUserId()));
                    QwTransferCustomerResignedResult qwTransferCustomerResignedParam = qwApiService.resignedTransferCustomer(qwTransferCustomerParam, param.getCorpId());

                    if (qwTransferCustomerResignedParam.getErrcode() == 0) {
                        List<QwCustomer> customer = qwTransferCustomerResignedParam.getCustomer();
                        if (customer != null && customer.size() > 0) {
                            for (QwCustomer qwCustomer : customer) {
                                if (qwCustomer.getErrcode() == 0) {
                                    QwExternalContactTransferLog qwExternalContactTransferLog = new QwExternalContactTransferLog();
                                    // qwExternalContactTransferLog.setCompanyId(param.getCorpId());
                                    qwExternalContactTransferLog.setExternalContactId(id);
                                    qwExternalContactTransferLog.setCompanyUserId(qwExternalContact.getCompanyUserId());
                                    qwExternalContactTransferLog.setCreateTime(new Date());
                                    qwExternalContactTransferLog.setStatus(2);
                                    qwExternalContactTransferLog.setQwUserId(qwUser.getId());
                                    qwExternalContactTransferLog.setHandoverUserId(qwExternalContact.getUserId());
                                    qwExternalContactTransferLog.setTakeoverUserId(qwUser.getQwUserId());
                                    qwExternalContactTransferLog.setCorpId(param.getCorpId());
                                    qwExternalContactTransferLog.setExternalUserId(qwCustomer.getExternal_userid());
                                    qwExternalContactTransferLogMapper.insertQwExternalContactTransferLog(qwExternalContactTransferLog);
                                    QwExternalContact qwExternal = new QwExternalContact();
                                    qwExternal.setStatus(2);
                                    qwExternal.setTransferStatus(2);
                                    qwExternal.setId(qwExternalContact.getId());
                                    qwExternalContactMapper.updateQwExternalContact(qwExternal);
                                    suc++;
                                } else {
                                    err++;
                                }
                            }
                        } else {
                            err++;
                        }
                    } else {
                        err++;
                    }
                }
            }
        }
        return R.ok("接替成功：" + suc + ",接替失败：" + err);
    }

    @Override
    public R transfer(TransferParam param) {

        QwUser qwUser = qwUserMapper.selectQwUserById(param.getUserId());
        Integer err = 0;
        Integer suc = 0;
        if (qwUser != null) {
            List<Long> ids = param.getIds();
            for (Long id : ids) {
                QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(id);
                if (qwExternalContact == null || qwExternalContact.getUserId().equals(qwUser.getQwUserId())) {
                    err++;
                } else {
                    QwTransferCustomerParam qwTransferCustomerParam = new QwTransferCustomerParam();
                    String content = param.getContent();
                    if (content == null || content.isEmpty()) {
                        content = "您好，您的服务已升级，后续将由我的同事接替我的工作，继续为您服务。";
                    }
                    qwTransferCustomerParam.setTransfer_success_msg(content);
                    qwTransferCustomerParam.setHandover_userid(qwExternalContact.getUserId());
                    qwTransferCustomerParam.setTakeover_userid(qwUser.getQwUserId());
                    qwTransferCustomerParam.setExternal_userid(Arrays.asList(qwExternalContact.getExternalUserId()));
                    QwTransferCustomerResult qwTransferCustomerResult = qwApiService.transferCustomer(qwTransferCustomerParam, param.getCorpId());

                    if (qwTransferCustomerResult.getErrcode() == 0) {
                        List<QwCustomer> customer = qwTransferCustomerResult.getCustomer();
                        if (customer != null && customer.size() > 0) {
                            for (QwCustomer qwCustomer : customer) {
                                if (qwCustomer.getErrcode() == 0) {
                                    QwExternalContactTransferLog qwExternalContactTransferLog = new QwExternalContactTransferLog();
                                    // qwExternalContactTransferLog.setCompanyId(param.getCorpId());
                                    qwExternalContactTransferLog.setExternalContactId(id);
                                    qwExternalContactTransferLog.setCompanyUserId(qwExternalContact.getCompanyUserId());
                                    qwExternalContactTransferLog.setCreateTime(new Date());
                                    qwExternalContactTransferLog.setStatus(2);
                                    qwExternalContactTransferLog.setQwUserId(qwUser.getId());
                                    qwExternalContactTransferLog.setHandoverUserId(qwExternalContact.getUserId());
                                    qwExternalContactTransferLog.setTakeoverUserId(qwUser.getQwUserId());
                                    qwExternalContactTransferLog.setCorpId(param.getCorpId());
                                    qwExternalContactTransferLog.setExternalUserId(qwCustomer.getExternal_userid());
                                    qwExternalContactTransferLog.setHandoverQwUserId(qwExternalContact.getQwUserId());
                                    qwExternalContactTransferLogMapper.insertQwExternalContactTransferLog(qwExternalContactTransferLog);
                                    QwExternalContact qwExternal = new QwExternalContact();
                                    qwExternal.setStatus(2);
                                    qwExternal.setTransferStatus(2);
                                    qwExternal.setId(qwExternalContact.getId());
                                    qwExternalContactMapper.updateQwExternalContact(qwExternal);
                                    suc++;
                                } else {
                                    err++;
                                }
                            }
                        } else {
                            err++;
                        }
                    } else {
                        err++;
                    }
                }
            }
        }
        return R.ok("接替成功：" + suc + ",接替失败：" + err);
    }

    @Override
    public R addUserTag(QwExternalContactAddTagParam param) throws JSONException {
        int err = 0;
        int suc = 0;
        // 获取当前日期（只包含年月日）
        LocalDate currentDate = LocalDate.now();
        // 获取当前系统时间 (HH:mm)
        LocalTime localTime = LocalTime.now();

        List<Long> userIds = param.getUserIds();
        for (Long userId : userIds) {

            QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(userId);
            QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
            qwEditUserTagParam.setAdd_tag(param.getTagIds());
            qwEditUserTagParam.setUserid(qwExternalContact.getUserId());
            qwEditUserTagParam.setExternal_userid(qwExternalContact.getExternalUserId());

            try {

                QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, param.getCorpId());
                if (qwResult.getErrcode() == 0) {

                    //客户本身的标签集合+打的标签
                    QwExternalContact qwExternal = new QwExternalContact();
                    String tagIds = qwExternalContact.getTagIds();

                    // 将标签字符串解析为 List    //客户总标签
                    List<String> tagIdsList = new ArrayList<>();

                    Set<String> uniqueIds = new HashSet<>();
                    if (tagIds != null && !tagIds.isEmpty()) {
                        List<String> parsedTags = JSON.parseArray(tagIds, String.class);
                        if (parsedTags != null && !parsedTags.isEmpty()) {
                            uniqueIds.addAll(parsedTags);
                        }
                    }

                    // 将 param 中的标签 ID 加入集合
                    if (param.getTagIds() != null && !param.getTagIds().isEmpty()) {
                        uniqueIds.addAll(param.getTagIds());
                    }

                    // 将唯一标签集合设置回 qwExternal
                    qwExternal.setTagIds(JSON.toJSONString(uniqueIds));


                    if (qwExternal.getTagIds() != null && !qwExternal.getTagIds().isEmpty()) {
                        tagIdsList = JSON.parseArray(qwExternal.getTagIds(), String.class);
                    }

                    qwExternal.setId(userId);

                    logger.info("客户添加标签addUserTag：" + qwExternalContact.getName() + "|公司" + qwExternalContact.getCorpId() + "|员工" + qwExternalContact.getUserId() + "|总标签" + tagIdsList);

                    //插件sop
                    processTagsAll(qwExternalContact, qwExternalContact.getCorpId(), tagIdsList, currentDate, localTime);

                    //新客对话
//                    processTagsAllByAiChat(qwExternalContact,param.getCorpId(),tagIdsList);

                    suc++;
                    qwExternalContactMapper.updateQwExternalContact(qwExternal);
                } else {
                    err++;
                }
            } catch (Exception e) {
                logger.error("客户添加标签失败：" + qwEditUserTagParam + e.getMessage());
            }


        }

        return R.ok("成功：" + suc + ",失败：" + err);
    }


    @Override
    public R delUserTag(QwExternalContactAddTagParam param) {

        // 获取当前日期（只包含年月日）
        LocalDate currentDate = LocalDate.now();
        // 获取当前系统时间 (HH:mm)
        LocalTime localTime = LocalTime.now();

        int err = 0;
        int suc = 0;
        List<Long> userIds = param.getUserIds();
        for (Long userId : userIds) {

            QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(userId);

            QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
            qwEditUserTagParam.setRemove_tag(param.getTagIds());
            qwEditUserTagParam.setUserid(qwExternalContact.getUserId());
            qwEditUserTagParam.setExternal_userid(qwExternalContact.getExternalUserId());

            try {
                QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, param.getCorpId());
                if (qwResult.getErrcode() == 0) {

                    String tagIds = qwExternalContact.getTagIds();
                    if (tagIds != null && tagIds != "") {
                        List<String> ids = JSON.parseArray(tagIds, String.class);
                        for (String tagId : param.getTagIds()) {
                            ids.removeIf(str -> str.equals(tagId));
                        }

                        QwExternalContact qwExternal = new QwExternalContact();
                        qwExternal.setId(userId);
                        qwExternal.setTagIds(JSON.toJSONString(ids));

                        qwExternalContactMapper.updateQwExternalContact(qwExternal);

                        logger.info("客户移除标签delUserTag：" + qwExternalContact.getName() + "|公司" + qwExternalContact.getCorpId() + "|员工" + qwExternalContact.getUserId() + "|总标签" + ids);

                        //检查sop
                        processTagsAll(qwExternalContact, param.getCorpId(), ids, currentDate, localTime);

                        //新客对话
//                        processTagsAllByAiChat(qwExternalContact,param.getCorpId(),ids);
                    }
                    suc++;

                } else {
                    err++;
                }

            } catch (Exception e) {
                logger.error("移除标签失败:" + qwEditUserTagParam + e.getMessage());
            }


        }


        return R.ok("成功：" + suc + ",失败：" + err);
    }

    public void insertQwExternalByMq(Long ExtId) {
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(ExtId);
        LocalDate currentDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        if (qwExternalContact == null) {
            return;
        }
        QwContactWay qwContactWay = null;
        QwUser qwUser = getQwUserByRedis(qwExternalContact.getCorpId(), qwExternalContact.getUserId());
        String tagIds = qwExternalContact.getTagIds();
        List<String> extTagIds = Optional.ofNullable(JSON.parseArray(tagIds, String.class)).orElseGet(ArrayList::new);
        List<String> addTag = new ArrayList<>();
        String tagRemark = null;
        List<String> allTags = new ArrayList<>();
        String description = qwExternalContact.getDescription();
        String state = qwExternalContact.getState();
        String corpId = qwExternalContact.getCorpId();
        QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoTagsByIdJSON(corpId, qwExternalContact.getId());
        if (qwAutoTags != null) {
            List<QwAutoTagsRulesTags> qwAutoTagsRulesTagsList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);
            DayOfWeek today = LocalDate.now().getDayOfWeek();
            int todayIndex = today.getValue();
            LocalTime now = LocalTime.now();

            for (QwAutoTagsRulesTags rulesTags : qwAutoTagsRulesTagsList) {
                List<String> tagsItem = rulesTags.getTags();
                List<Integer> week = rulesTags.getWeek();
                String endTime = rulesTags.getEndTime();
                String remarks = rulesTags.getRemarks();
                boolean isTodayInWeek = week.contains(todayIndex);
                LocalTime start = LocalTime.parse(rulesTags.getStartTime());
                LocalTime end = LocalTime.parse(endTime.equals("24:00") ? "23:59:59" : endTime);
                boolean isNowInTimeRange = !now.isBefore(start) && !now.isAfter(end);
                if (isTodayInWeek && isNowInTimeRange) {
                    addTag.addAll(tagsItem);
                    if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                        String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                        tagRemark = DayDate.substring(1);
                    }
                    if (!StringUtil.strIsNullOrEmpty(remarks)) {
                        tagRemark = (tagRemark == null ? "" : (tagRemark + "-")) + remarks;
                    }

                }
            }

            if (!addTag.isEmpty()) {
                addAutoTagsLogs(qwAutoTags.getId(), qwUser, qwExternalContact, addTag);

            }
        }


        if (StringUtils.isNotEmpty(state) && state.contains("way:" + corpId + ":")) {
            qwContactWay = qwContactWayMapper.selectQwContactWayById(Long.parseLong(state.substring(23)));
            if (qwContactWay != null) {
                if (qwContactWay.getUserType() == 1 && qwContactWay.getIsUserLimit() == 1) {
                    delQwUserWay(qwExternalContact.getUserId(), qwExternalContact.getCorpId());
                }
                if (qwContactWay.getIsRemark() == 1) {
                    String name = qwExternalContact.getName();
                    String remark = qwContactWay.getRemark();
                    tagRemark = (qwContactWay.getRemarkStatus() == 1) ? name + "-" + remark : remark + "-" + name;
                }
                if (qwContactWay.getIsTag() == 1) {
                    List<String> wayTags = JSON.parseArray(qwContactWay.getTags(), String.class);
                    addTag.addAll(wayTags);
                }
                if (qwContactWay.getIsDescription() == 1) {
                    description = qwContactWay.getDescription();
                }
                addWayLog(qwContactWay, qwExternalContact);
            }
        }
        QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
        qwEditUserTagParam.setUserid(qwExternalContact.getUserId());
        qwEditUserTagParam.setExternal_userid(qwExternalContact.getExternalUserId());
        qwEditUserTagParam.setAdd_tag(addTag);
        QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);
        if (qwResult.getErrcode() == 0) {
            allTags = Stream.concat(addTag.stream(), extTagIds.stream())
                    .distinct()
                    .collect(Collectors.toList());
            addAutoTagsLogs(qwAutoTags.getId(), qwUser, qwExternalContact, addTag);


            checkHaveQwSopNew(qwUser, allTags, qwExternalContact, currentDate, localTime);
        } else if (qwResult.getErrcode() == 45035) {
            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 1, qwResult.getErrmsg());
        }


        if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
            qwExternalContact.setRemark(tagRemark + "-" + qwContactWay.getName());
            QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
            param.setRemark(qwExternalContact.getRemark());
            param.setUserid(qwExternalContact.getUserId());
            param.setExternal_userid(qwExternalContact.getExternalUserId());
            param.setDescription(description);
            QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());
            if (remarkResult.getErrcode() == 45035) {
                insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 2, remarkResult.getErrmsg());
            }
        }

        QwExternalContact ext = new QwExternalContact();
        ext.setId(qwExternalContact.getId());
        ext.setTagIds(JSON.toJSONString(allTags));
        ext.setRemark(tagRemark);
        ext.setDescription(description);
        qwExternalContactMapper.updateQwExternalContact(qwExternalContact);

        QwExternalContactTransferLog transferLog = new QwExternalContactTransferLog();
        transferLog.setCorpId(corpId);
        transferLog.setTakeoverUserId(qwExternalContact.getUserId());
        transferLog.setExternalUserId(qwExternalContact.getExternalUserId());
        QwExternalContactTransferLog transferLogListByCheck = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogListByCheck(transferLog);
        if (transferLogListByCheck != null) {
            transferLogListByCheck.setStatus(1);
            qwExternalContactTransferLogMapper.updateQwExternalContactTransferLog(transferLogListByCheck);
            QwExternalContact contact1 = new QwExternalContact();
            contact1.setUserId(transferLogListByCheck.getHandoverUserId());
            contact1.setCorpId(transferLogListByCheck.getCorpId());
            contact1.setStatus(4);
            contact1.setTransferStatus(1);
            contact1.setExternalUserId(transferLogListByCheck.getExternalUserId());
            qwExternalContactMapper.updateQwExternalContactByUseridTransfer(contact1);
        }


    }

    private void addAutoTagsLogs(Long id, QwUser qwUser, QwExternalContact qwExternalContact, List<String> addTag) {
        QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
        qwAutoTagsLogs.setAutoTagId(id);
        qwAutoTagsLogs.setType(3L);
        qwAutoTagsLogs.setQwUserid(qwUser.getId());
        qwAutoTagsLogs.setExternalUserId(qwExternalContact.getExternalUserId());
        qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(addTag));
        qwAutoTagsLogs.setAddTime(new Date());
        qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
        qwAutoTagsLogs.setCorpId(qwUser.getCorpId());
        qwExternalContact.setTagIds(JSON.toJSONString(addTag));
        qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);

    }


    void addWayLog(QwContactWay qwContactWay, QwExternalContact qwExternalContact) {
        QwContactWayLogs qwContactWayLogs = new QwContactWayLogs();
        qwContactWayLogs.setWayId(qwContactWay.getId());
        qwContactWayLogs.setUserId(qwExternalContact.getQwUserId());
        qwContactWayLogs.setInformationId(qwContactWay.getInformationId());
        qwContactWayLogs.setType(1);
        qwContactWayLogs.setExternalUserId(qwExternalContact.getId());
        qwContactWayLogs.setCreateTime(new Date());
        qwContactWayLogs.setMsg("添加客户");
        qwContactWayLogsMapper.insertQwContactWayLogs(qwContactWayLogs);
        qwContactWayMapper.addContactWayNum(qwContactWay.getId());
        if (qwContactWay.getInformationId() != null) {
            qwContactWayMapper.addInformationNum(qwContactWay.getInformationId());
        }
    }

    void delQwUserWay(String userID, String corpId) {
        QwContactWayUser qwContactWayUser = qwContactWayUserMapper.selectQwContactWayUserByUserIdAndCompanyId(userID, corpId);
        if (qwContactWayUser != null) {
            qwContactWayUser.setDayCount(qwContactWayUser.getDayCount() - 1);
            qwContactWayUserMapper.updateQwContactWayUser(qwContactWayUser);
            if (qwContactWayUser.getDayCount() <= 0) {
                //超过限制
                qwContactWayService.updateQwContactWayBYLimit(qwContactWayUser.getWayId());
            }

        }
    }

    public void insertQwExternalContactByQwCallback(String externalUserID, String userID, Long companyId, String corpId, String state, String welcomeCode) throws ParseException {
        QwExternalContactResult externalContactResult = qwApiService.getExternalcontact(externalUserID, corpId);
        if (externalContactResult.getErrcode() != 0) {
            logger.error("获取客户信息出错：" + externalContactResult.getErrmsg());
            return;
        }
        ExternalContact externalContact = externalContactResult.getExternal_contact();
        FollowUser followUser = externalContactResult.getFollow_user().stream()
                .filter(follow -> follow.getUserid().equals(userID))
                .findFirst()
                .orElse(null);
        if (followUser == null) {
            logger.error("未查到获取客户信息：" + externalUserID + "|" + userID + "|" + corpId);
            return;
        }
        List<Tag> tags = followUser.getTags();
        List<String> remarkMobiles = followUser.getRemark_mobiles();
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalByExternalIdAndCompanyIdToIdAndFs(externalUserID, userID, corpId);
        QwUser qwUser = getQwUserByRedis(corpId, userID);
        boolean isNewQwExternalContact = qwExternalContact == null;
        qwExternalContact = qwExternalContact == null ? new QwExternalContact() : qwExternalContact;
        qwExternalContact.setCreateTime(new Date());
        qwExternalContact.setRemarkCorpName(followUser.getRemark_corp_name()); // 设置备注企业名称
        qwExternalContact.setAddWay(followUser.getAdd_way()); // 设置来源
        qwExternalContact.setOperUserid(followUser.getOper_userid()); // 设置oper用户ID
        qwExternalContact.setCorpId(corpId); // 设置企业ID
        qwExternalContact.setUserId(userID); // 设置属于用户ID
        qwExternalContact.setExternalUserId(externalUserID); // 设置外部联系人ID
        qwExternalContact.setCorpId(corpId);
        qwExternalContact.setStatus(0);
        qwExternalContact.setCreateTime(new Date());
        qwExternalContact.setCompanyId(qwUser.getCompanyId()); // 设置公司ID
        qwExternalContact.setState(state);
        if (!tags.isEmpty()) {
            qwExternalContact.setTagIds(JSON.toJSONString(tags.stream().map(Tag::getTag_id).collect(Collectors.toList())));
        }
        if (remarkMobiles != null && !remarkMobiles.isEmpty()) {
            qwExternalContact.setRemarkMobiles(JSON.toJSONString(remarkMobiles)); // 设置备注电话号码
        }
        qwExternalContact.setCreateTime(new Date());
        if (isNewQwExternalContact) {
            qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
        } else {
            qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
        }
        if (welcomeCode != null && !welcomeCode.isEmpty()) {
            boolean isSend = true;
            //way欢迎语
            if (StringUtils.isNotEmpty(state) && state.contains("way:" + corpId + ":")) {
                QwContactWay qwContactWay = qwContactWayMapper.selectQwContactWayById(Long.parseLong(state.substring(23)));
                if (qwContactWay != null) {
                    if (qwContactWay.getIsWelcome() != null && qwContactWay.getIsWelcome() == 1 && qwContactWay.getIsSpanWelcome() == 1) {
                        String name = externalContact.getName();
                        String closeWelcomeWord = qwContactWay.getCloseWelcomeWord();
                        Boolean isClose = true;
                        if (closeWelcomeWord != null && !closeWelcomeWord.isEmpty()) {
                            List<String> strings = JSON.parseArray(closeWelcomeWord, String.class);
                            isClose = strings.stream().noneMatch(name::contains);
                        }
                        if (isClose) {
                            isSend = qwContactWayService.sendWelcomeMsg(qwContactWay, corpId, welcomeCode, qwUser, qwExternalContact.getId());
                        }
                    }
                }
            }
            if (isSend) {
                QwFriendWelcomeVO qwFriendWelcomeVO = qwFriendWelcomeMapper.selectQwFriendWelcomeByUserIdVO(qwUser.getId(), corpId);
                if (qwFriendWelcomeVO != null) {
                    SendWelcomeMsgParam sendWelcomeMsgParam = new SendWelcomeMsgParam();
                    sendWelcomeMsgParam.setWelcome_code(welcomeCode);
                    String isDay = qwFriendWelcomeVO.getIsDayparting();
                    switch (isDay) {
                        case "1":
                            List<QwFriendWelcomeDayPart.Schedule> schedules = JSON.parseArray(qwFriendWelcomeVO.getDaypartingItemlist(), QwFriendWelcomeDayPart.Schedule.class);
                            LocalTime now = LocalTime.now();
                            Integer week = LocalDate.now().getDayOfWeek().getValue();
                            boolean match = false;
                            for (QwFriendWelcomeDayPart.Schedule schedule : schedules) {
                                if (schedule.getWeek().contains(week)) {
                                    LocalTime start = LocalTime.parse(schedule.getStartTime());
                                    LocalTime end = LocalTime.parse(schedule.getEndTime().equals("24:00") ? "23:59:59" : schedule.getEndTime());
                                    if (!now.isBefore(start) && !now.isAfter(end)) {
                                        sendWelcomeMsgParam = welcomeMsg(schedule.getWelcomeText(), schedule.getAttachments(), qwUser, corpId, qwExternalContact.getId());
                                        match = true;
                                        break;
                                    }
                                }
                            }
                            // 如果没有找到匹配项
                            if (!match) {
                                List<SendWelcomeMsgParam.Attachment> attachments = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                                sendWelcomeMsgParam = welcomeMsg(qwFriendWelcomeVO.getWelcomeText(), attachments, qwUser, corpId, qwExternalContact.getId());
                            }
                            break;
                        case "2":
                            List<SendWelcomeMsgParam.Attachment> attachments = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                            sendWelcomeMsgParam = welcomeMsg(qwFriendWelcomeVO.getWelcomeText(), attachments, qwUser, corpId, qwExternalContact.getId());
                            break;
                    }
                    QwResult qwResult = qwApiService.sendWelcomeMsg(sendWelcomeMsgParam, corpId);
                    if (qwResult.getErrcode() == 41050 || qwResult.getErrcode() == 41051) {
//                        sendHookWelcome(qwUser,sendWelcomeMsgParam,qwExternalContact);
                    }
                }

            }
        }
//        try {
//            rocketMQTemplate.syncSend("ad-upload", JSON.toJSONString(AdUploadVo.builder().state(state).type(AdUploadType.ADD_WX).build()));
//
//        }catch (Exception e){
//            logger.error("语音上传消息失败",e);
//        }

        try {
            rocketMQTemplate.syncSend("qw-addExt", JSON.toJSONString(qwExternalContact));
        } catch (Exception e) {
            logger.error("添加外部联系人消息失败", e);
        }

    }

    //补发好友欢迎语
//    void sendHookWelcome(QwUser qwUser,SendWelcomeMsgParam sendWelcomeMsgParam,QwExternalContact qwExternalContact){
//        if (qwUser.getAppKey()!=null&& !qwUser.getAppKey().isEmpty()){
//            ArrayList<String> msgParamList=new ArrayList<>();
//            msgParamList.add(sendWelcomeMsgParam.getText().getContent());
//            sendWelcomeMsgParam.getAttachments().forEach(item->{
//                if (("link").equals(item.getMsgtype())) {
//                    msgParamList.add(item.getLink().getUrl());
//                }
//            });
//            if (!msgParamList.isEmpty()){
//                for (String value : msgParamList) {
//                    QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
//                    QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
//                    sendMsgParam.setType(101003);
//                    sendMsgData.setMsg(value);
//                    sendMsgData.setOpenId(qwExternalContact.getExternalUserId());
//                    sendMsgData.setSyncKey("1");
//                    sendMsgParam.setData(sendMsgData);
//                    SendHookAIParam sendAIParam = new SendHookAIParam();
//                    sendAIParam.setCmd("aiReplyMsg");
//                    sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
//                    sendAIParam.setKey(qwUser.getAppKey());
//                    logger.info("补欢迎语:" + qwExternalContact.getExternalUserId()+":"+value);
//                    redisTemplate.opsForList().leftPush("AiMsg:"+qwUser.getAppKey(), JSON.toJSONString(sendAIParam));
//                }
//            }
//        }
//    }

    SendWelcomeMsgParam welcomeMsg(String content, List<SendWelcomeMsgParam.Attachment> attachments, QwUser qwUser, String corpId, Long id) {
        SendWelcomeMsgParam sendWelcomeMsgParam = new SendWelcomeMsgParam();
        TextMessage textMessage = new TextMessage();
        textMessage.setContent(content);
        sendWelcomeMsgParam.setText(textMessage);
        List<SendWelcomeMsgParam.Attachment> attachmentsMatch = attachmentsTools(attachments, qwUser, corpId, id);
        sendWelcomeMsgParam.setAttachments(attachmentsMatch);
        return sendWelcomeMsgParam;
    }

    public QwUser getQwUserByRedis(String corpId, String userID) {
        String key = (String) redisCache.getCacheObject("qwUserRd:" + corpId + ":" + userID);
        if (!StringUtil.strIsNullOrEmpty(key)) {
            return JSON.parseObject(key, QwUser.class);
        }
        QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userID);
        redisCache.setCacheObject("qwUserRd:" + qwUser.getCorpId() + ":" + qwUser.getQwUserId(), JSON.toJSONString(qwUser), 1, TimeUnit.HOURS);
        return qwUser;
    }

    ;

    @Override
    public void insertQwExternalContactByExternalUserId(String externalUserID, String userID, Long companyId, String corpId, String state, String welcomeCode) throws ParseException {

        // 获取当前日期（只包含年月日）
        LocalDate currentDate = LocalDate.now();
        // 获取当前系统时间 (HH:mm)
        LocalTime localTime = LocalTime.now();
        QwExternalContactResult externalContactResult = qwApiService.getExternalcontact(externalUserID, corpId);
        boolean isSend = true;
        boolean isWay = false;
        QwContactWay wayId = null;
        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("qw.config");
        QwConfig qwConfig = JSON.parseObject(sysConfig.getConfigValue(), QwConfig.class);

//
//        String json = sysConfigService.selectConfigByKey("course.config");
//        QwConfig qwConfig = JSON.parseObject(json, QwConfig.class);

        //先入客户
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalByExternalIdAndCompanyIdToIdAndFs(externalUserID, userID, corpId);
        boolean isNewQwExternalContact = qwExternalContact == null ? true : false;
        qwExternalContact = qwExternalContact == null ? new QwExternalContact() : qwExternalContact;

        //是否开启重粉判断
        if(qwConfig.isRepeat()){
            List<QwExternalContact> externalContactList = qwExternalContactMapper.selectList(new QueryWrapper<QwExternalContact>().eq("external_user_id", externalUserID).eq("corp_id", corpId));
            if(!externalContactList.isEmpty()){
                externalContactList.forEach(e -> {
                    e.setIsRepeat(1);
                });
                qwExternalContactService.updateBatchById(externalContactList);
                qwExternalContact.setIsRepeat(1);
            }
        }

        qwExternalContact.setUserId(userID); // 设置属于用户ID
        qwExternalContact.setExternalUserId(externalUserID); // 设置外部联系人ID
        qwExternalContact.setCorpId(corpId);
        qwExternalContact.setCreateTime(new Date());

//        QwExternalContact finalQwExternalContact = qwExternalContact;
        try {
            rocketMQTemplate.syncSend("ad-upload", JSON.toJSONString(AdUploadVo.builder().state(state).type(AdUploadType.ADD_WX).build()));
        } catch (Exception e) {
            logger.error("回调-语音发送消息失败", e);
        }
//        iAdHtmlClickLogService.upload(state, AdUploadType.ADD_WX, e -> finalQwExternalContact.setUploadAddWxStatus(1));

        //先入一次库
        if (isNewQwExternalContact) {
            qwExternalContact.setName("待同步客户");
            qwExternalContact.setGender(0);
            qwExternalContactMapper.insert(qwExternalContact);
        } else {
            qwExternalContactMapper.updateById(qwExternalContact);
        }

        QwExternalContact contact = qwExternalContact;
        QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userID);

        if (state != null && state != "") {
            String s = "way:" + corpId + ":";
            if (state.contains(s)) {
                if (welcomeCode != null && welcomeCode != "") {
                    String substring = state.substring(state.indexOf(s) + s.length());
                    QwContactWay qwContactWay = qwContactWayMapper.selectQwContactWayById(Long.parseLong(substring));
                    logger.info("qwContactWay：" + qwContactWay);
                    if (qwContactWay != null) {
                        isWay = true;
                        wayId = qwContactWay;
                        if (qwContactWay.getIsWelcome() != null && qwContactWay.getIsWelcome() == 1) {
                            Boolean isClose = true;
                            if (wayId.getIsSpanWelcome() == 1) {
                                ExternalContact externalContact = externalContactResult.getExternal_contact();
                                String name = externalContact.getName();
                                String closeWelcomeWord = wayId.getCloseWelcomeWord();
                                if (closeWelcomeWord != null && closeWelcomeWord.length() > 0) {
                                    List<String> strings = JSON.parseArray(closeWelcomeWord, String.class);
                                    for (String string : strings) {
                                        if (name.contains(string)) {
                                            isClose = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (qwContactWay.getIsSpanWelcome() == 1 && isClose) {
                                isSend = qwContactWayService.sendWelcomeMsg(qwContactWay, corpId, welcomeCode, qwUser, contact.getId());
                            }
                        }
                        if (qwContactWay.getUserType() == 1 && qwContactWay.getIsUserLimit() == 1) {
                            QwContactWayUser qwContactWayUser = qwContactWayUserMapper.selectQwContactWayUserByUserIdAndCompanyId(userID, corpId);
                            if (qwContactWayUser != null) {
                                qwContactWayUser.setDayCount(qwContactWayUser.getDayCount() - 1);
                                qwContactWayUserMapper.updateQwContactWayUser(qwContactWayUser);
                                if (qwContactWayUser.getDayCount() <= 0) {
                                    //超过限制
                                    qwContactWayService.updateQwContactWayBYLimit(qwContactWayUser.getWayId());
                                }

                            }
                        }
                    }
                }
            }
        }

        if (isSend && welcomeCode != null && welcomeCode != "") {
            if (qwUser != null) {
                // 查询成员的欢迎语以及欢迎图片
                QwFriendWelcomeVO qwFriendWelcomeVO = qwFriendWelcomeMapper.selectQwFriendWelcomeByUserIdVO(qwUser.getId(), corpId);
                if (qwFriendWelcomeVO != null) {
                    SendWelcomeMsgParam sendWelcomeMsgParam = new SendWelcomeMsgParam();
                    sendWelcomeMsgParam.setWelcome_code(welcomeCode);
                    ArrayList<String> msgParamList = new ArrayList<>();
                    if (qwFriendWelcomeVO.getIsDayparting().equals("1")) {
                        List<QwFriendWelcomeDayPart.Schedule> schedules = JSON.parseArray(qwFriendWelcomeVO.getDaypartingItemlist(), QwFriendWelcomeDayPart.Schedule.class);
                        LocalTime now = LocalTime.now();
                        Integer week = LocalDate.now().getDayOfWeek().getValue();
                        boolean match = false;
                        for (QwFriendWelcomeDayPart.Schedule schedule : schedules) {
                            if (schedule.getWeek().contains(week)) {
                                LocalTime start = LocalTime.parse(schedule.getStartTime());
                                LocalTime end = LocalTime.parse(schedule.getEndTime().equals("24:00") ? "23:59:59" : schedule.getEndTime());
                                if (!now.isBefore(start) && !now.isAfter(end)) {

                                    TextMessage textMessage = new TextMessage();
                                    textMessage.setContent(schedule.getWelcomeText());
                                    sendWelcomeMsgParam.setText(textMessage);
                                    msgParamList.add(schedule.getWelcomeText());
                                    List<SendWelcomeMsgParam.Attachment> attachments = schedule.getAttachments();
                                    List<SendWelcomeMsgParam.Attachment> attachmentsMatch = attachmentsTools(attachments, qwUser, corpId, contact.getId());
                                    sendWelcomeMsgParam.setAttachments(attachmentsMatch);
                                    attachmentsMatch.forEach(item -> {
                                        if (("link").equals(item.getMsgtype())) {
                                            msgParamList.add(item.getLink().getUrl());
                                        }
                                    });
                                    match = true;
                                    break; // 找到匹配项后退出整个for循环
                                }
                            }
                        }
                        // 如果没有找到匹配项
                        if (!match) {
                            TextMessage textMessage = new TextMessage();
                            textMessage.setContent(qwFriendWelcomeVO.getWelcomeText());
                            sendWelcomeMsgParam.setText(textMessage);
                            msgParamList.add(qwFriendWelcomeVO.getWelcomeText());
                            List<SendWelcomeMsgParam.Attachment> attachmentsAll = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                            List<SendWelcomeMsgParam.Attachment> attachmentsNotMach = attachmentsTools(attachmentsAll, qwUser, corpId, contact.getId());
                            sendWelcomeMsgParam.setAttachments(attachmentsNotMach);
                            attachmentsNotMach.forEach(item -> {
                                if (("link").equals(item.getMsgtype())) {
                                    msgParamList.add(item.getLink().getUrl());
                                }
                            });
                        }

                    } else {
                        // 不分时段
                        TextMessage textMessage = new TextMessage();
                        textMessage.setContent(qwFriendWelcomeVO.getWelcomeText());
                        sendWelcomeMsgParam.setText(textMessage);
                        msgParamList.add(qwFriendWelcomeVO.getWelcomeText());
                        // 设置所有附件
                        List<SendWelcomeMsgParam.Attachment> attachmentsAll = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                        //加短链
                        List<SendWelcomeMsgParam.Attachment> attachments = attachmentsTools(attachmentsAll, qwUser, corpId, contact.getId());
                        sendWelcomeMsgParam.setAttachments(attachments);
                        attachments.forEach(item -> {
                            if (("link").equals(item.getMsgtype())) {
                                msgParamList.add(item.getLink().getUrl());
                            }
                        });
                    }

                    QwResult qwResult = qwApiService.sendWelcomeMsg(sendWelcomeMsgParam, corpId);
                    logger.info("发送好友欢迎语的参数:" + sendWelcomeMsgParam + "发送好友欢迎语结果:" + qwResult);
//                    if (qwResult.getErrcode()==41050||qwResult.getErrcode()==41051){
//                        if (qwUser.getAppKey()!=null&& !qwUser.getAppKey().equals("")){
//                            if (msgParamList!=null&&msgParamList.size()>0){
//                                for (String value : msgParamList) {
//                                    QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
//                                    QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
//                                    sendMsgParam.setType(101003);
//                                    sendMsgData.setMsg(value);
//                                    sendMsgData.setOpenId(qwExternalContact.getExternalUserId());
//                                    sendMsgData.setSyncKey("1");
//                                    sendMsgParam.setData(sendMsgData);
//                                    SendHookAIParam sendAIParam = new SendHookAIParam();
//                                    sendAIParam.setCmd("aiReplyMsg");
//                                    sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
//                                    sendAIParam.setKey(qwUser.getAppKey());
//                                    logger.info("补欢迎语:" + qwExternalContact.getExternalUserId()+":"+value);
//                                    redisTemplate.opsForList().leftPush("AiMsg:"+qwUser.getAppKey(), JSON.toJSONString(sendAIParam));
//                                }
//                            }
//                        }
//                    }
                }
            }
        }
        ExternalContact externalContact = externalContactResult.getExternal_contact();
        List<FollowUser> followUsers = externalContactResult.getFollow_user();
        logger.info("外部联系人的情况里面0:" + userID + ":" + externalUserID + ":" + followUsers);
        if (state != null && state != "") {
            String appWay = "appCont:" + corpId + ":";
            if (state.contains(appWay)) {
                String substring = state.substring(state.indexOf(appWay) + appWay.length());
                QwAppContactWay qwAppContactWay = qwAppContactWayMapper.selectQwAppContactWayById(Long.parseLong(substring));
                if (qwAppContactWay != null) {
                    //更新外部联系人
                    QwExternalContact qwe2 = new QwExternalContact();
                    qwe2.setId(contact.getId());
                    qwe2.setFsUserId(qwAppContactWay.getUserId());
//                    adHtmlClickLogService.upload(contact.getState(), AdUploadType.REGISTERED, e -> contact.setUploadRegisterStatus(1));
                    qwExternalContactMapper.updateQwExternalContact(qwe2);

                    //更新用户记录
                    qwAppContactWay.setStatus(2);
                    qwAppContactWayMapper.updateQwAppContactWay(qwAppContactWay);

                    QwAppContactWayLogs wayLogs = qwAppContactWayLogsMapper.selectQwAppContactWayLogsByAppWayId(qwAppContactWay.getId());

                    if (wayLogs == null) {

                        QwAppContactWayLogs qwAppContactWayLogs = new QwAppContactWayLogs();
                        qwAppContactWayLogs.setAppWayId(qwAppContactWay.getId());
                        qwAppContactWayLogs.setUserId(qwAppContactWay.getUserId());
                        FsUser fsUser = fsUserMapper.selectFsUserByUserId(qwAppContactWay.getUserId());
                        if (fsUser != null) {
                            qwAppContactWayLogs.setSource(fsUser.getSource());
                        }
                        qwAppContactWayLogs.setCorpId(qwAppContactWay.getCorpId());
                        qwAppContactWayLogs.setCreateTime(new Date());
                        qwAppContactWayLogs.setExternalUserId(contact.getId());
                        if (qwUser != null) {
                            qwAppContactWayLogs.setCompanyId(qwUser.getCompanyId());
                            qwAppContactWayLogs.setQwUserId(qwUser.getId());
                            qwAppContactWayLogs.setCompanyUserId(qwUser.getCompanyUserId());
                        }

                        qwAppContactWayLogsMapper.insertQwAppContactWayLogs(qwAppContactWayLogs);
                        if (fsUser != null) {
                            FsUser u1 = new FsUser();
                            u1.setUserId(fsUser.getUserId());
                            u1.setIsAddQw(1);
                            fsUserMapper.updateFsUser(u1);
                        }
                    }

                    QwGetContactWayParam qwGetContactWayParam = new QwGetContactWayParam();
                    qwGetContactWayParam.setConfig_id(qwAppContactWay.getConfigId());
                    QwResult qwResult = qwApiService.delContactWay(qwGetContactWayParam, qwAppContactWay.getCorpId());
                    if (qwResult.getErrcode() == 0) {
                        qwAppContactWay.setWayStatus(2);
                        qwAppContactWayMapper.updateQwAppContactWay(qwAppContactWay);
                    }

                }
            }
        }
        for (FollowUser followUser : followUsers) {
            if (followUser.getUserid().equals(userID)) {
                qwExternalContact.setUserId(followUser.getUserid()); // 设置属于用户ID
                qwExternalContact.setExternalUserId(externalContact.getExternal_userid()); // 设置外部联系人ID
                if (qwUser != null) {
                    qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
                    qwExternalContact.setQwUserId(qwUser.getId());
                }
                qwExternalContact.setWayId(wayId == null ? null : wayId.getId());
                qwExternalContact.setStatus(0);
                qwExternalContact.setState(state);
                qwExternalContact.setName(externalContact.getName()); // 设置名称
                qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
                qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户，2企业微信用户)
                qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
                qwExternalContact.setDescription(followUser.getDescription()); // 设置描述信息
                List<Tag> tags = followUser.getTags();
                Set<String> combinedTagsSet = new HashSet<>();
                if (tags != null && tags.size() > 0) {
                    List<String> tagArr = new ArrayList<>();
                    for (Tag tag : tags) {
                        tagArr.add(tag.getTag_id());
                    }
                    combinedTagsSet.addAll(tagArr);
                    qwExternalContact.setTagIds(JSON.toJSONString(tagArr)); // 设置标签ID
                }
                if (followUser.getRemark_mobiles() != null && followUser.getRemark_mobiles().size() > 0) {
                    List<String> remarkMobiles = followUser.getRemark_mobiles();
                    // 设置备注电话号码
                    qwExternalContact.setRemarkMobiles(JSON.toJSONString(remarkMobiles));
                    //自动绑定CRM客户
                    for (String remarkMobile : remarkMobiles) {
                        Long id = crmCustomerMapper.selectCrmCustomerByCrmMobile(remarkMobile);
                        if (id != null) {
                            qwExternalContact.setCustomerId(id);
                            //小程序用户id
                            Long fsUserId = crmCustomerMapper.selectFsUserByCrmMobile(remarkMobile);
                            if (fsUserId != null) {
                                CrmCustomer crmCustomer = new CrmCustomer();
                                crmCustomer.setUserId(fsUserId);
                                crmCustomer.setCustomerId(id);
                                //CRM用户自动绑定小程序用户
                                crmCustomerMapper.updateCrmCustomer(crmCustomer);
                            }
                            break;
                        }
                    }
                }
                qwExternalContact.setCreateTime(new Date());
                qwExternalContact.setRemarkCorpName(followUser.getRemark_corp_name()); // 设置备注企业名称
                qwExternalContact.setAddWay(followUser.getAdd_way()); // 设置来源
                qwExternalContact.setOperUserid(followUser.getOper_userid()); // 设置oper用户ID
                qwExternalContact.setCorpId(corpId); // 设置企业ID
                qwExternalContact.setCompanyId(qwUser.getCompanyId()); // 设置公司ID
                //添加的标签
                QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
                qwEditUserTagParam.setUserid(userID);
                qwEditUserTagParam.setExternal_userid(externalUserID);
                //添加标签的日志记录
                QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
                // 用来存储合并并去重后的 总 tags 集合
                String tagRemark = null;
                //根据qwUser 匹配 分时段的标签
                QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoTagsByIdJSON(corpId, qwUser.getId());
                log.info("自动打标签方案{}", qwAutoTags);
                if (qwAutoTags != null) {
                    //标签日志记录
                    qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
                    qwAutoTagsLogs.setType(3L);
                    qwAutoTagsLogs.setQwUserid(qwUser.getId());
                    qwAutoTagsLogs.setExternalUserId(externalUserID);
                    List<QwAutoTagsRulesTags> qwAutoTagsRulesTagsList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);
                    boolean isMatch = false;
                    //存分时段里符合条件的标签
                    Set<String> combinedTagsItem = new HashSet<>();
                    // 获取今天的星期数
                    DayOfWeek today = LocalDate.now().getDayOfWeek();
                    int todayIndex = today.getValue(); // 1: Monday, 2: Tuesday, ..., 7: Sunday
                    // 获取当前时间
                    LocalTime now = LocalTime.now();
                    LocalDate nowDate = LocalDate.now();
                    // 遍历所有规则
                    for (QwAutoTagsRulesTags rulesTags : qwAutoTagsRulesTagsList) {
                        List<String> tagsItem = rulesTags.getTags();
//                        List<Integer> week = rulesTags.getWeek();
                        LocalDate startDate = rulesTags.getStartDate();
                        LocalDate endDate = rulesTags.getEndDate();
                        String startTime = rulesTags.getStartTime();
                        String endTime = rulesTags.getEndTime();
                        String remarks = rulesTags.getRemarks();
                        log.info("自动打标签开始时间：{} 到 {}， time：{} 到 {}", startDate, endDate, startTime, endTime);
                        // 检查今天是否在 week 集合中
//                        boolean isTodayInWeek = week.contains(todayIndex);
                        boolean isToday = false;
                        if(startDate != null && endDate != null){
                            log.info("进入日期判断");
                            isToday = !nowDate.isBefore(startDate) && !nowDate.isAfter(endDate);
                        }
                        // 转换时间字符串为 LocalTime
                        LocalTime start = LocalTime.parse(startTime);
                        LocalTime end = LocalTime.parse(endTime.equals("24:00") ? "23:59:59" : endTime);
                        // 检查当前时间是否在 startTime 和 endTime 之间
                        boolean isNowInTimeRange = !now.isBefore(start) && !now.isAfter(end);
                        log.info("是否满足时间打标签：天：{}， 时：{}", isToday, isNowInTimeRange);
                        log.info("是否每天{}", rulesTags.getEveryDay());
                        // 如果当前时间和日期匹配规则，将 tagsItem 添加到 combinedTagsSet 中
                        if (((rulesTags.getEveryDay() != null && rulesTags.getEveryDay() == 1) || isToday) && isNowInTimeRange) {

                            combinedTagsSet.addAll(tagsItem);
                            combinedTagsItem.addAll(tagsItem);
                            isMatch = true;
                            if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                tagRemark = DayDate.substring(1);
                            }
                            //如果备注不为空
                            if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                tagRemark = DayDate.substring(1);
                            }
                            //如果备注不为空
                            if (!StringUtil.strIsNullOrEmpty(remarks)) {
                                tagRemark = (tagRemark == null ? "" : (tagRemark + "-")) + remarks;
                            }
                        }
                    }
                    // 如果有匹配的规则，使用 combinedTagsList
                    if (isMatch) {
                        // 转换一下分时段-符合 条件的 列表
                        List<String> combinedTags = new ArrayList<>(combinedTagsItem);
                        qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(combinedTags));
                        qwAutoTagsLogs.setAddTime(new Date());
                        qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
                        qwAutoTagsLogs.setCorpId(qwUser.getCorpId());
                        //总标签 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                        // 设置标签
                        qwEditUserTagParam.setAdd_tag(combinedTagsList);
                        // 企微加标签
                        QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);

                        logger.info("自动添加标签的状态:" + qwResult.getErrcode() + "|" + qwResult.getErrmsg() + "|qwEditUserTagParam--" + qwEditUserTagParam);

                        if (qwResult.getErrcode() == 0) {
                            // 用户存标签
                            qwExternalContact.setTagIds(JSON.toJSONString(combinedTagsList));
                            qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);

                            logger.info("分时段里符合的标签-自动SOP条件:" + combinedTagsList + "|" + qwUser.getQwUserId() + "|" + externalUserID);

                            //检查sop进营期
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } else if (qwResult.getErrcode() == 45035) {
                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 1, qwResult.getErrmsg());
                            logger.info("自动添加标签添加失败-已加入补偿机制中:" + qwEditUserTagParam);
                        }

                    } else {
                        // 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                        logger.info("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                        try {
                            //检查sop进营期
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } catch (Exception e) {
                            logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                        }
                    }
                } else {
                    try {
                        // 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                        logger.error("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                        try {
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } catch (Exception e) {
                            logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                        }
                    } catch (Exception e) {
                        logger.error("打标签出错" + e.getMessage());
                    }

                }

                //有渠道活码
                if (isWay) {
                    if (wayId.getIsDescription() == 1) {
                        qwExternalContact.setDescription(wayId.getDescription());
                    }
                    if (wayId.getIsRemark() == 1) {
                        if (wayId.getRemarkStatus() == 1) {
                            if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark() + "-" + tagRemark);
                            } else {
                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark());
                            }

                        } else {
                            if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                                qwExternalContact.setRemark(tagRemark + "-" + wayId.getRemark() + "-" + externalContact.getName());
                            } else {
                                qwExternalContact.setRemark(wayId.getRemark() + "-" + externalContact.getName());
                            }

                        }
                    }
                    if (wayId.getIsDescription() == 1 || wayId.getIsRemark() == 1) {

                        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                        param.setRemark(qwExternalContact.getRemark());
                        param.setUserid(userID);
                        param.setExternal_userid(externalUserID);
                        param.setDescription(qwExternalContact.getDescription());
                        QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());

                        if (remarkResult.getErrcode() == 45035) {

                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 2, remarkResult.getErrmsg());
                            logger.error("修改备注1失败-已加入补偿机制中：{}", qwEditUserTagParam);

                        }

                        logger.info("修改备注：{}", remarkResult);

                    }
                    //有标签
                    if (wayId.getIsTag() == 1) {
                        //渠道活码的标签
                        List<String> wayTags = JSON.parseArray(wayId.getTags(), String.class);
                        //总添加标签
                        combinedTagsSet.addAll(wayTags);
                        //用户存标签
                        qwExternalContact.setTagIds(wayId.getTags());
                    }
                } else {
                    if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                        qwExternalContact.setRemark(tagRemark + "-" + externalContact.getName());
                        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                        param.setRemark(qwExternalContact.getRemark());
                        param.setUserid(userID);
                        param.setExternal_userid(externalUserID);
                        QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());

                        if (remarkResult.getErrcode() == 45035) {
                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 2, remarkResult.getErrmsg());
                            logger.error("修改备注1失败-已加入补偿机制中：{}", qwEditUserTagParam);
                        }

                        logger.info("修改备注2：{}", remarkResult);

                    }
                }


            }
        }

        //更新在职继承（可能有 可能没有）
        QwExternalContactTransferLog transferLog = new QwExternalContactTransferLog();
        transferLog.setCorpId(corpId);
        transferLog.setTakeoverUserId(userID);
        transferLog.setExternalUserId(externalUserID);
        QwExternalContactTransferLog transferLogListByCheck = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogListByCheck(transferLog);
        if (transferLogListByCheck != null) {
            transferLogListByCheck.setStatus(1);
            qwExternalContactTransferLogMapper.updateQwExternalContactTransferLog(transferLogListByCheck);

            QwExternalContact contact1 = new QwExternalContact();
            contact1.setUserId(transferLogListByCheck.getHandoverUserId());
            contact1.setCorpId(transferLogListByCheck.getCorpId());
            contact1.setStatus(4);
            contact1.setTransferStatus(1);
            contact1.setExternalUserId(transferLogListByCheck.getExternalUserId());
            qwExternalContactMapper.updateQwExternalContactByUseridTransfer(contact1);
        }

        //上面存过了，这里就更新
        qwExternalContact.setId(contact.getId());
        qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
        QwOpenidByExternalcontactParams externalcontactParams = new QwOpenidByExternalcontactParams();
        externalcontactParams.setExternal_userid(externalUserID);
        //录入单独的CRM客户信息  没啥用
        QwOpenidResult qwOpenidResult = qwApiService.externalcontactToOpenid(externalcontactParams, corpId);
        QwExternalContactCrm qwExternalContactCrm = new QwExternalContactCrm();
        qwExternalContactCrm.setExternalUserId(externalUserID);
        qwExternalContactCrm.setExternalUserName(qwExternalContact.getName());
        qwExternalContactCrm.setAvatar(qwExternalContact.getAvatar());
        qwExternalContactCrm.setOpenid(qwOpenidResult.getOpenid());
        contactCrmService.insertOrUpdateQwExternalContactCrm(qwExternalContactCrm);
        if (isWay) {
            QwContactWayLogs qwContactWayLogs = new QwContactWayLogs();
            qwContactWayLogs.setWayId(wayId.getId());
            qwContactWayLogs.setUserId(qwExternalContact.getQwUserId());
            qwContactWayLogs.setInformationId(wayId.getInformationId());
            qwContactWayLogs.setType(1);
            qwContactWayLogs.setExternalUserId(qwExternalContact.getId());
            qwContactWayLogs.setCreateTime(new Date());
            qwContactWayLogs.setMsg("添加客户");
            qwContactWayLogsMapper.insertQwContactWayLogs(qwContactWayLogs);
            qwContactWayMapper.addContactWayNum(wayId.getId());
            if (wayId.getInformationId() != null) {
                qwContactWayMapper.addInformationNum(wayId.getInformationId());
            }
        }
    }

    public void checkHaveQwSop(Set<String> combinedTagsSet, QwUser qwUser, String corpId, List<String> combinedTagsList,
                               String userID, String externalUserID, ExternalContact externalContact, QwExternalContact contact,
                               LocalDate currentDate, LocalTime localTime) {
        if (!combinedTagsSet.isEmpty()) {
            //分时段里符合的标签-再用来创建自动SOP+（总标签）
            QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
            qwSopAutoByTags.setCorpId(corpId);
            qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
            qwSopAutoByTags.setSendType(2);
            List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
            try {
                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                    //SOP规则
                    qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                }
                //aiSop任务
                List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
                if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()){
                    qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS,userID,qwUser,corpId,externalUserID,externalContact.getName(),contact);
                }

            } catch (Exception e) {
                logger.error("符合的标签-加入营期或新客对话 失败：" + qwSopAutoByTags + "|" + qwUser.getQwUserId() + "|" + externalUserID + "|" + e);
            }
        }
    }

    @Override
    public void insertQwExternalContactByExternalUserId2(String externalUserID, String userID, Long companyId, String corpId, String state, String welcomeCode) throws ParseException {

        // 获取当前日期（只包含年月日）
        LocalDate currentDate = LocalDate.now();
        // 获取当前系统时间 (HH:mm)
        LocalTime localTime = LocalTime.now();
        QwExternalContactResult externalContactResult = qwApiService.getExternalcontact(externalUserID, corpId);
        boolean isSend = true;
        boolean isWay = false;
        QwContactWay wayId = null;
        //先入客户
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalByExternalIdAndCompanyIdToIdAndFs(externalUserID, userID, corpId);
        boolean isNewQwExternalContact = qwExternalContact == null ? true : false;
        qwExternalContact = qwExternalContact == null ? new QwExternalContact() : qwExternalContact;
        qwExternalContact.setUserId(userID); // 设置属于用户ID
        qwExternalContact.setExternalUserId(externalUserID); // 设置外部联系人ID
        qwExternalContact.setCorpId(corpId);
        qwExternalContact.setCreateTime(new Date());

        //先入一次库
        if (isNewQwExternalContact) {
            qwExternalContact.setName("待同步客户");
            qwExternalContact.setGender(0);
            qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
        } else {
            qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
        }

        QwExternalContact contact = qwExternalContact;
        QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userID);

        ExternalContact externalContact = externalContactResult.getExternal_contact();
        List<FollowUser> followUsers = externalContactResult.getFollow_user();
        logger.info("外部联系人的情况里面0:" + userID + ":" + externalUserID + ":" + followUsers);
        if (state != null && state != "") {
            String appWay = "appCont:" + corpId + ":";
            if (state.contains(appWay)) {
                String substring = state.substring(state.indexOf(appWay) + appWay.length());
                QwAppContactWay qwAppContactWay = qwAppContactWayMapper.selectQwAppContactWayById(Long.parseLong(substring));
                if (qwAppContactWay != null) {
                    //更新外部联系人
                    QwExternalContact qwe2 = new QwExternalContact();
                    qwe2.setId(contact.getId());
                    qwe2.setFsUserId(qwAppContactWay.getUserId());
//                    adHtmlClickLogService.upload(contact.getState(), AdUploadType.REGISTERED, e -> contact.setUploadRegisterStatus(1));
                    qwExternalContactMapper.updateQwExternalContact(qwe2);

                    //更新用户记录
                    qwAppContactWay.setStatus(2);
                    qwAppContactWayMapper.updateQwAppContactWay(qwAppContactWay);

                    QwAppContactWayLogs wayLogs = qwAppContactWayLogsMapper.selectQwAppContactWayLogsByAppWayId(qwAppContactWay.getId());

                    if (wayLogs == null) {

                        QwAppContactWayLogs qwAppContactWayLogs = new QwAppContactWayLogs();
                        qwAppContactWayLogs.setAppWayId(qwAppContactWay.getId());
                        qwAppContactWayLogs.setUserId(qwAppContactWay.getUserId());
                        FsUser fsUser = fsUserMapper.selectFsUserByUserId(qwAppContactWay.getUserId());
                        if (fsUser != null) {
                            qwAppContactWayLogs.setSource(fsUser.getSource());
                        }
                        qwAppContactWayLogs.setCorpId(qwAppContactWay.getCorpId());
                        qwAppContactWayLogs.setCreateTime(new Date());
                        qwAppContactWayLogs.setExternalUserId(contact.getId());
                        if (qwUser != null) {
                            qwAppContactWayLogs.setCompanyId(qwUser.getCompanyId());
                            qwAppContactWayLogs.setQwUserId(qwUser.getId());
                            qwAppContactWayLogs.setCompanyUserId(qwUser.getCompanyUserId());
                        }

                        qwAppContactWayLogsMapper.insertQwAppContactWayLogs(qwAppContactWayLogs);
                        if (fsUser != null) {
                            FsUser u1 = new FsUser();
                            u1.setUserId(fsUser.getUserId());
                            u1.setIsAddQw(1);
                            fsUserMapper.updateFsUser(u1);
                        }
                    }

                    QwGetContactWayParam qwGetContactWayParam = new QwGetContactWayParam();
                    qwGetContactWayParam.setConfig_id(qwAppContactWay.getConfigId());
                    QwResult qwResult = qwApiService.delContactWay(qwGetContactWayParam, qwAppContactWay.getCorpId());
                    if (qwResult.getErrcode() == 0) {
                        qwAppContactWay.setWayStatus(2);
                        qwAppContactWayMapper.updateQwAppContactWay(qwAppContactWay);
                    }

                }
            }
        }
        for (FollowUser followUser : followUsers) {
            if (followUser.getUserid().equals(userID)) {
                qwExternalContact.setUserId(followUser.getUserid()); // 设置属于用户ID
                qwExternalContact.setExternalUserId(externalContact.getExternal_userid()); // 设置外部联系人ID
                if (qwUser != null) {
                    qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
                    qwExternalContact.setQwUserId(qwUser.getId());
                }
                qwExternalContact.setWayId(wayId == null ? null : wayId.getId());
                qwExternalContact.setStatus(0);
                qwExternalContact.setState(state);
                qwExternalContact.setName(externalContact.getName()); // 设置名称
                qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
                qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户，2企业微信用户)
                qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
                qwExternalContact.setDescription(followUser.getDescription()); // 设置描述信息
                List<Tag> tags = followUser.getTags();
                Set<String> combinedTagsSet = new HashSet<>();
                if (tags != null && tags.size() > 0) {
                    List<String> tagArr = new ArrayList<>();
                    for (Tag tag : tags) {
                        tagArr.add(tag.getTag_id());
                    }
                    combinedTagsSet.addAll(tagArr);
                    qwExternalContact.setTagIds(JSON.toJSONString(tagArr)); // 设置标签ID
                }
                if (followUser.getRemark_mobiles() != null && followUser.getRemark_mobiles().size() > 0) {
                    List<String> remarkMobiles = followUser.getRemark_mobiles();
                    // 设置备注电话号码
                    qwExternalContact.setRemarkMobiles(JSON.toJSONString(remarkMobiles));
                    //自动绑定CRM客户
                    for (String remarkMobile : remarkMobiles) {
                        Long id = crmCustomerMapper.selectCrmCustomerByCrmMobile(remarkMobile);
                        if (id != null) {
                            qwExternalContact.setCustomerId(id);
                            //小程序用户id
                            Long fsUserId = crmCustomerMapper.selectFsUserByCrmMobile(remarkMobile);
                            if (fsUserId != null) {
                                CrmCustomer crmCustomer = new CrmCustomer();
                                crmCustomer.setUserId(fsUserId);
                                crmCustomer.setCustomerId(id);
                                //CRM用户自动绑定小程序用户
                                crmCustomerMapper.updateCrmCustomer(crmCustomer);
                            }
                            break;
                        }
                    }
                }
                qwExternalContact.setCreateTime(new Date());
                qwExternalContact.setRemarkCorpName(followUser.getRemark_corp_name()); // 设置备注企业名称
                qwExternalContact.setAddWay(followUser.getAdd_way()); // 设置来源
                qwExternalContact.setOperUserid(followUser.getOper_userid()); // 设置oper用户ID
                qwExternalContact.setCorpId(corpId); // 设置企业ID
                qwExternalContact.setCompanyId(qwUser.getCompanyId()); // 设置公司ID
                //添加的标签
                QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
                qwEditUserTagParam.setUserid(userID);
                qwEditUserTagParam.setExternal_userid(externalUserID);
                //添加标签的日志记录
                QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
                // 用来存储合并并去重后的 总 tags 集合
                String tagRemark = null;
                //根据qwUser 匹配 分时段的标签
                QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoTagsByIdJSON(corpId, qwUser.getId());
                if (qwAutoTags != null) {
                    //标签日志记录
                    qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
                    qwAutoTagsLogs.setType(3L);
                    qwAutoTagsLogs.setQwUserid(qwUser.getId());
                    qwAutoTagsLogs.setExternalUserId(externalUserID);
                    List<QwAutoTagsRulesTags> qwAutoTagsRulesTagsList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);
                    boolean isMatch = false;
                    //存分时段里符合条件的标签
                    Set<String> combinedTagsItem = new HashSet<>();
                    // 获取今天的星期数
                    DayOfWeek today = LocalDate.now().getDayOfWeek();
                    int todayIndex = today.getValue(); // 1: Monday, 2: Tuesday, ..., 7: Sunday
                    // 获取当前时间
                    LocalTime now = LocalTime.now();
                    // 遍历所有规则
                    for (QwAutoTagsRulesTags rulesTags : qwAutoTagsRulesTagsList) {
                        List<String> tagsItem = rulesTags.getTags();
                        List<Integer> week = rulesTags.getWeek();
                        String startTime = rulesTags.getStartTime();
                        String endTime = rulesTags.getEndTime();
                        String remarks = rulesTags.getRemarks();

                        // 检查今天是否在 week 集合中
                        boolean isTodayInWeek = week.contains(todayIndex);
                        // 转换时间字符串为 LocalTime
                        LocalTime start = LocalTime.parse(startTime);
                        LocalTime end = LocalTime.parse(endTime.equals("24:00") ? "23:59:59" : endTime);
                        // 检查当前时间是否在 startTime 和 endTime 之间
                        boolean isNowInTimeRange = !now.isBefore(start) && !now.isAfter(end);
                        // 如果当前时间和日期匹配规则，将 tagsItem 添加到 combinedTagsSet 中
                        if (isTodayInWeek && isNowInTimeRange) {

                            combinedTagsSet.addAll(tagsItem);
                            combinedTagsItem.addAll(tagsItem);
                            isMatch = true;
                            if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                tagRemark = DayDate.substring(1);
                            }
                            //如果备注不为空
                            if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                tagRemark = DayDate.substring(1);
                            }
                            //如果备注不为空
                            if (!StringUtil.strIsNullOrEmpty(remarks)) {
                                tagRemark = (tagRemark == null ? "" : (tagRemark + "-")) + remarks;
                            }
                        }
                    }
                    // 如果有匹配的规则，使用 combinedTagsList
                    if (isMatch) {
                        // 转换一下分时段-符合 条件的 列表
                        List<String> combinedTags = new ArrayList<>(combinedTagsItem);
                        qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(combinedTags));
                        qwAutoTagsLogs.setAddTime(new Date());
                        qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
                        qwAutoTagsLogs.setCorpId(qwUser.getCorpId());
                        //总标签 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                        // 设置标签
                        qwEditUserTagParam.setAdd_tag(combinedTagsList);
                        // 企微加标签
                        QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);

                        logger.info("自动添加标签的状态:" + qwResult.getErrcode() + "|" + qwResult.getErrmsg() + "|qwEditUserTagParam--" + qwEditUserTagParam);

                        if (qwResult.getErrcode() == 0) {
                            // 用户存标签
                            qwExternalContact.setTagIds(JSON.toJSONString(combinedTagsList));
                            qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);

                            logger.info("分时段里符合的标签-自动SOP条件:" + combinedTagsList + "|" + qwUser.getQwUserId() + "|" + externalUserID);

                            //检查sop进营期
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } else if (qwResult.getErrcode() == 45035) {
                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 1, qwResult.getErrmsg());
                            logger.info("自动添加标签添加失败-已加入补偿机制中:" + qwEditUserTagParam);
                        }

                    } else {
                        // 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                        logger.info("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                        try {
                            //检查sop进营期
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } catch (Exception e) {
                            logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                        }
                    }
                } else {
                    try {
                        // 转换回列表
                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                        logger.error("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                        try {
                            checkHaveQwSop(combinedTagsSet, qwUser, corpId, combinedTagsList, userID, externalUserID,
                                    externalContact, contact, currentDate, localTime);
                        } catch (Exception e) {
                            logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                        }

                    } catch (Exception e) {
                        logger.error("打标签出错" + e.getMessage());
                    }

                }


                //有渠道活码
                if (isWay) {
                    if (wayId.getIsDescription() == 1) {
                        qwExternalContact.setDescription(wayId.getDescription());
                    }
                    if (wayId.getIsRemark() == 1) {
                        if (wayId.getRemarkStatus() == 1) {
                            if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark() + "-" + tagRemark);
                            } else {
                                qwExternalContact.setRemark(externalContact.getName() + "-" + wayId.getRemark());
                            }

                        } else {
                            if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                                qwExternalContact.setRemark(tagRemark + "-" + wayId.getRemark() + "-" + externalContact.getName());
                            } else {
                                qwExternalContact.setRemark(wayId.getRemark() + "-" + externalContact.getName());
                            }

                        }
                    }
                    if (wayId.getIsDescription() == 1 || wayId.getIsRemark() == 1) {

                        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                        param.setRemark(qwExternalContact.getRemark());
                        param.setUserid(userID);
                        param.setExternal_userid(externalUserID);
                        param.setDescription(qwExternalContact.getDescription());
                        QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());

                        if (remarkResult.getErrcode() == 45035) {

                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 2, remarkResult.getErrmsg());
                            logger.error("修改备注1失败-已加入补偿机制中：{}", qwEditUserTagParam);

                        }

                        logger.info("修改备注：{}", remarkResult);

                    }
                    //有标签
                    if (wayId.getIsTag() == 1) {
                        //渠道活码的标签
                        List<String> wayTags = JSON.parseArray(wayId.getTags(), String.class);
                        //总添加标签
                        combinedTagsSet.addAll(wayTags);
                        //用户存标签
                        qwExternalContact.setTagIds(wayId.getTags());
                    }
                } else {
                    if (!StringUtil.strIsNullOrEmpty(tagRemark)) {
                        qwExternalContact.setRemark(tagRemark + "-" + externalContact.getName());
                        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                        param.setRemark(qwExternalContact.getRemark());
                        param.setUserid(userID);
                        param.setExternal_userid(externalUserID);
                        QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());

                        if (remarkResult.getErrcode() == 45035) {
                            //加入补偿机制
                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 2, remarkResult.getErrmsg());
                            logger.error("修改备注1失败-已加入补偿机制中：{}", qwEditUserTagParam);
                        }

                        logger.info("修改备注2：{}", remarkResult);

                    }
                }


            }
        }

        //更新在职继承（可能有 可能没有）
        QwExternalContactTransferLog transferLog = new QwExternalContactTransferLog();
        transferLog.setCorpId(corpId);
        transferLog.setTakeoverUserId(userID);
        transferLog.setExternalUserId(externalUserID);
        QwExternalContactTransferLog transferLogListByCheck = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogListByCheck(transferLog);
        if (transferLogListByCheck != null) {
            transferLogListByCheck.setStatus(1);
            qwExternalContactTransferLogMapper.updateQwExternalContactTransferLog(transferLogListByCheck);

            QwExternalContact contact1 = new QwExternalContact();
            contact1.setUserId(transferLogListByCheck.getHandoverUserId());
            contact1.setCorpId(transferLogListByCheck.getCorpId());
            contact1.setStatus(4);
            contact1.setTransferStatus(1);
            contact1.setExternalUserId(transferLogListByCheck.getExternalUserId());
            qwExternalContactMapper.updateQwExternalContactByUseridTransfer(contact1);
        }

        //上面存过了，这里就更新
        qwExternalContact.setId(contact.getId());
        qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
        QwOpenidByExternalcontactParams externalcontactParams = new QwOpenidByExternalcontactParams();
        externalcontactParams.setExternal_userid(externalUserID);
        //录入单独的CRM客户信息  没啥用
        QwOpenidResult qwOpenidResult = qwApiService.externalcontactToOpenid(externalcontactParams, corpId);
        QwExternalContactCrm qwExternalContactCrm = new QwExternalContactCrm();
        qwExternalContactCrm.setExternalUserId(externalUserID);
        qwExternalContactCrm.setExternalUserName(qwExternalContact.getName());
        qwExternalContactCrm.setAvatar(qwExternalContact.getAvatar());
        qwExternalContactCrm.setOpenid(qwOpenidResult.getOpenid());
        contactCrmService.insertOrUpdateQwExternalContactCrm(qwExternalContactCrm);
        if (isWay) {
            QwContactWayLogs qwContactWayLogs = new QwContactWayLogs();
            qwContactWayLogs.setWayId(wayId.getId());
            qwContactWayLogs.setUserId(qwExternalContact.getQwUserId());
            qwContactWayLogs.setInformationId(wayId.getInformationId());
            qwContactWayLogs.setType(1);
            qwContactWayLogs.setExternalUserId(qwExternalContact.getId());
            qwContactWayLogs.setCreateTime(new Date());
            qwContactWayLogs.setMsg("添加客户");
            qwContactWayLogsMapper.insertQwContactWayLogs(qwContactWayLogs);
            qwContactWayMapper.addContactWayNum(wayId.getId());
            if (wayId.getInformationId() != null) {
                qwContactWayMapper.addInformationNum(wayId.getInformationId());
            }
        }
    }

    public void insertQwExternalErrRetryTool(String corpId, String params, Integer retryState, String msg) {

        QwExternalErrRetry errRetry = new QwExternalErrRetry();
        errRetry.setTakeState(1);
        errRetry.setCorpId(corpId);
        errRetry.setRetryState(retryState);
        errRetry.setRetryType(2);
        errRetry.setRetryParams(JSON.toJSONString(params));
        errRetry.setRetryNum(0);
        errRetry.setCreateTime(new Date());
        errRetry.setMark(msg);

        errRetryService.insertQwExternalErrRetry(errRetry);

    }

    /**
     * 检查是否有sop任务
     */
    public void checkHaveQwSopNew(QwUser qwUser, List<String> combinedTagsList, QwExternalContact contact,
                                  LocalDate currentDate, LocalTime localTime) {
        if (!combinedTagsList.isEmpty()) {
            //分时段里符合的标签-再用来创建自动SOP+（总标签）
            QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
            qwSopAutoByTags.setCorpId(contact.getCorpId());
            qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
            qwSopAutoByTags.setSendType(2);
            List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);

            try {
                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                    //SOP规则
                    qwSopRuleTimeTools(qwSopRuleTimeVOS, contact.getUserId(), qwUser, contact.getCorpId(), contact.getExternalUserId(), contact.getName(), contact, currentDate, localTime, combinedTagsList);
                }
//                //aiSop任务
//                List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()){
//                    qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS,contact.getUserId(),qwUser,contact.getCorpId(),contact.getExternalUserId(),contact.getName(),contact);
//                }

            } catch (Exception e) {
                logger.error("符合的标签-加入营期或新客对话 失败：" + qwSopAutoByTags + "|" + qwUser.getQwUserId() + "|" + contact.getExternalUserId() + "|" + e);
            }
        }
    }

    public void qwSopRuleTimeTools(List<QwSopRuleTimeVO> qwSopRuleTimeVOS, String userID, QwUser qwUser, String corpId,
                                   String externalUserID, String externalContactName, QwExternalContact contact,
                                   LocalDate currentDate, LocalTime localTime, List<String> combinedTagsList) {
        // 定义日期和时间格式化器
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("qw.config");
        List<SopUserLogsInfo> sopUserLogsInfos = sopUserLogsInfoMapper.repeatProject(PubFun.listToNewList(qwSopRuleTimeVOS, QwSopRuleTimeVO::getProject), externalUserID);
        Map<Integer, List<String>> collect = sopUserLogsInfos.stream().collect(Collectors.groupingBy(SopUserLogsInfo::getProject, Collectors.mapping(SopUserLogsInfo::getSopId, Collectors.toList())));
        log.info("进入生成营期");
        // sop任务
        qwSopRuleTimeVOS.forEach(ruleTimeVO -> {
            if(sysConfig != null){
                QwConfig qwConfig = JSON.parseObject(sysConfig.getConfigValue(), QwConfig.class);
                if(qwConfig.isProject()){
                    List<String> sopIdList = collect.get(ruleTimeVO.getProject());
                    log.info("是否多个项目:{}", sopIdList);
                    if(sopIdList.isEmpty()) return;
                    if(sopIdList.contains(ruleTimeVO.getId())) return;
                }
            }
            // 将排除的字符串转成列表
            List<String> excludedTagsList = new ArrayList<>();
            if (ruleTimeVO.getExcludeTags() != null && !ruleTimeVO.getExcludeTags().isEmpty()) {
                excludedTagsList = Arrays.asList(ruleTimeVO.getExcludeTags().split(","));
            }

            // 检查 combinedTagsList 是否包含排除列表中的任意一个标签
            boolean containsExcludedTag = combinedTagsList.stream()
                    .anyMatch(excludedTagsList::contains);

            //含任意一个排除标签
            if (containsExcludedTag) {
                return;
            }

            // 自动sop的规则
            QwAutoSopTimeParam qwAutoSopTimeParam = JSON.parseObject(ruleTimeVO.getAutoSopTime(), QwAutoSopTimeParam.class);

            // 用于查询/或新增
            SopUserLogs userLogs = new SopUserLogs();
            userLogs.setSopId(ruleTimeVO.getId());
            userLogs.setSopTempId(ruleTimeVO.getTempId());
            userLogs.setCorpId(ruleTimeVO.getCorpId());
            userLogs.setStatus(1);

            // 用于今天的新增
            SopUserLogsParamByDate userLogsParamByDate = new SopUserLogsParamByDate();
            userLogsParamByDate.setSopId(ruleTimeVO.getId());
            userLogsParamByDate.setSopTempId(ruleTimeVO.getTempId());
            userLogsParamByDate.setCorpId(ruleTimeVO.getCorpId());
            userLogsParamByDate.setStatus(1);

            // 从数据库中取到的开始时间（Date类型），转换为 LocalDate
            Date sopStartTime = ruleTimeVO.getStartTime();
            //开始时间
            LocalDate sopStartLocalDate = sopStartTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            // 设定用户信息
            userLogs.setQwUserId(userID);
            userLogs.setUserId(qwUser.getId() + "|" + qwUser.getCompanyUserId() + "|" + qwUser.getCompanyId());
            userLogsParamByDate.setQwUserId(userID);
            userLogsParamByDate.setUserId(qwUser.getId() + "|" + qwUser.getCompanyUserId() + "|" + qwUser.getCompanyId());

            // 创建 SopUserLogsInfo
            SopUserLogsInfo logsInfo = new SopUserLogsInfo();
            logsInfo.setQwUserId(userID.trim());
            logsInfo.setCorpId(qwUser.getCorpId());
            logsInfo.setExternalContactId(externalUserID.trim());
            logsInfo.setExternalId(contact.getId());
            logsInfo.setFsUserId(contact.getFsUserId());
            logsInfo.setExternalUserName(externalContactName);
            logsInfo.setSopId(ruleTimeVO.getId());


            //查看在职转接里 是否有这个客户
            int i = qwSopRuleTimeToolsCheckJobTransfer(ruleTimeVO, corpId, userID, externalUserID, userLogs, logsInfo, userLogsParamByDate);
            if (i == 1) {
                return;
            }
            // 判断 SOP 任务的开始时间
            qwSopRuleTimeToolsCheck(sopStartLocalDate, currentDate, dateFormatter, userLogs, logsInfo, userLogsParamByDate, qwAutoSopTimeParam, timeFormatter, localTime);
        });
    }

    /**
     * 检查是否在 在职继承 里
     */
    public int qwSopRuleTimeToolsCheckJobTransfer(QwSopRuleTimeVO ruleTimeVO, String corpId, String userID, String externalUserID,
                                                  SopUserLogs userLogs, SopUserLogsInfo logsInfoNew, SopUserLogsParamByDate userLogsParamByDate) {

        QwExternalContactTransferLog transferLogParam = new QwExternalContactTransferLog();
        transferLogParam.setCorpId(corpId);
        transferLogParam.setTakeoverUserId(userID);
        transferLogParam.setExternalUserId(externalUserID);

        QwExternalContactTransferLog transferLogVO = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogListByCheck(transferLogParam);
        //不在在职继承等待接替里-则是个新客户
        if (transferLogVO == null) {
            return 0;
        } else {

            //在职继承里，则走 营期继承的方案
            //1·符合条件的sop任务里,俩个在职继承的销售在同一个sop任务里，则走继承
            if (ruleTimeVO.getQwUserIds().contains(String.valueOf(transferLogVO.getHandoverQwUserId()))) {

                logger.info("在职继承里:" + externalUserID + "/" + userID + "/" + corpId + "/" + ruleTimeVO.getId() + "/" + transferLogVO.getId());

                SopUserLogsInfo logsInfoParamOld = new SopUserLogsInfo();
                logsInfoParamOld.setSopId(ruleTimeVO.getId());
                logsInfoParamOld.setQwUserId(transferLogVO.getHandoverUserId());
                logsInfoParamOld.setCorpId(corpId);
                logsInfoParamOld.setExternalContactId(transferLogVO.getExternalUserId());

                //查询这个客户在原员工上在哪个营期
                SopUserLogsInfo logsInfoOld = sopUserLogsInfoMapper.selectSopUserLogsInfoByCheckJobTransfer(logsInfoParamOld);
                if (logsInfoOld == null) {
                    logger.info("在职继承里没查到营期id:" + logsInfoParamOld);
                    //没查到营期id，则是个新客户
                    return 0;
                } else {
                    //查到营期id，则查看是哪个营期里的
                    SopUserLogs sopUserLogs = sopUserLogsService.selectSopUserLogsById(logsInfoOld.getUserLogsId());
                    if (sopUserLogs == null) {
                        //没查到原员工-营期信息，则默认是个新客户
                        logger.info("在职继承里没查到原员工:" + sopUserLogs);
                        return 0;
                    } else {
                        //拿到营期时间
                        String startTime = sopUserLogs.getStartTime();
                        userLogs.setStartTime(startTime);

                        //查询新员工是否有这天的营期
                        String unionSopStartId = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                        //如果营期存在
                        if (!StringUtil.strIsNullOrEmpty(unionSopStartId)) {

                            //将这个客户入到 新员工下的营期里
                            logsInfoNew.setUserLogsId(unionSopStartId);

                            // 查询客户是否已存在
                            handleInsertSopUserLogsInfo(logsInfoNew);

                        } else {

                            // 没有营期记录就先插入
                            userLogsParamByDate.setStartTime(startTime);

                            sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);

                            // 再次查询 拿营期主键
                            String unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                            logsInfoNew.setUserLogsId(unionSopStartIdNew);
                            // 查询是否在营期里，如果没有再插入
                            handleInsertSopUserLogsInfo(logsInfoNew);
                        }


                        //删除原员工对此客户的营期信息
                        sopUserLogsInfoMapper.deleteById(logsInfoOld.getId());

                        return 1;
                    }

                }
            } else {
                //俩个销售不在同一个sop任务里，则当新客户
                return 0;
            }
        }


    }

    public void qwSopRuleTimeToolsCheck(LocalDate sopStartLocalDate, LocalDate currentDate, DateTimeFormatter dateFormatter,
                                        SopUserLogs userLogs, SopUserLogsInfo logsInfo, SopUserLogsParamByDate userLogsParamByDate,
                                        QwAutoSopTimeParam qwAutoSopTimeParam, DateTimeFormatter timeFormatter, LocalTime localTime) {

        try {
            // 还没开始 (未来,不包括今天)
            if (sopStartLocalDate.isAfter(currentDate)) {
                // 大于当前日期，说明还没有开始：
                // -> 以 SOP 任务的开始时间为营期
                String sopStartLocalDateStr = sopStartLocalDate.format(dateFormatter);

                userLogs.setStartTime(sopStartLocalDateStr);
                // 查询开始时间营期表
                String unionSopStartId = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                // 如果营期表里有，则加入；否则创建新营期
                if (!StringUtil.strIsNullOrEmpty(unionSopStartId)) {
                    logsInfo.setUserLogsId(unionSopStartId);
                    // 查询这个人是否已在该营期里
                    handleInsertSopUserLogsInfo(logsInfo);
                } else {
                    // 没有营期记录就先插入
                    userLogsParamByDate.setStartTime(sopStartLocalDateStr);

                    sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);

                    // 再次查询 拿营期主键
                    String unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);
                    logsInfo.setUserLogsId(unionSopStartIdNew);

                    // 查询是否在营期里，如果没有再插入
                    handleInsertSopUserLogsInfo(logsInfo);
                }
            } else {
                // sopStartLocalDate <= currentDate -> 说明已经开始
                // -> 以“今天 / 明天”作为营期
                // 获取 AutoSopType
                Integer autoSopType = qwAutoSopTimeParam.getAutoSopType();

                // 今天的日期字符串
                String todayStr = currentDate.format(dateFormatter);
                userLogs.setStartTime(todayStr);

                // 查询今天的营期表
                String unionSopStartId2 = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                // 明天日期字符串
                LocalDate tomorrowDate = currentDate.plusDays(1);
                String tomorrowStr = tomorrowDate.format(dateFormatter);

                // 复制一份 userLogs，设为明天
                SopUserLogs userLogsTomorrow = new SopUserLogs();
                BeanUtils.copyProperties(userLogs, userLogsTomorrow);
                userLogsTomorrow.setStartTime(tomorrowStr);

                // 复制一份 SopUserLogsParamByDate，设为明天
                SopUserLogsParamByDate paramByDateTomorrow = new SopUserLogsParamByDate();
                BeanUtils.copyProperties(userLogsParamByDate, paramByDateTomorrow);
                paramByDateTomorrow.setStartTime(tomorrowStr);

                // 查询明天的营期表
                String unionTomorrowSopId2 = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogsTomorrow);

                // 根据 autoSopType 分支处理
                switch (autoSopType) {
                    // 立即执行
                    case 1: {
                        String autoStartTime = qwAutoSopTimeParam.getAutoStartTime();
                        String autoEndTime = qwAutoSopTimeParam.getAutoEndTime();

                        // 如果结束时间为 24:00，则替换成 23:59
                        if ("24:00".equals(autoEndTime)) {
                            autoEndTime = "23:59";
                        }

                        // 转为 LocalTime
                        LocalTime startTime = LocalTime.parse(autoStartTime, timeFormatter);
                        LocalTime endTime = LocalTime.parse(autoEndTime, timeFormatter);

                        // 判断当前时间是否在 [startTime, endTime] 范围内
                        if (!localTime.isBefore(startTime) && !localTime.isAfter(endTime)) {
                            // 在范围内 => 加入到今天的营期
                            if (!StringUtil.strIsNullOrEmpty(unionSopStartId2)) {

                                logsInfo.setUserLogsId(unionSopStartId2);

                                // 查询客户是否已存在
                                handleInsertSopUserLogsInfo(logsInfo);

                            } else {
                                // 没有今天天的营期就先建
                                userLogsParamByDate.setStartTime(todayStr);
                                sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);
                                // 查询客户是否已存在
                                SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(logsInfo);
                                if (userLogsInfo == null) {

                                    // 再查今天的营期的主键
                                    userLogs.setStartTime(todayStr);
                                    String unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);

                                    logsInfo.setUserLogsId(unionSopStartIdNew);
                                    //客户入营期
                                    sopUserLogsInfoMapper.insertSopUserLogsInfo(logsInfo);
                                }
                            }
                        } else {
                            // 不在范围内 => 加入到明天的营期
                            if (!StringUtil.strIsNullOrEmpty(unionTomorrowSopId2)) {
                                logsInfo.setUserLogsId(unionTomorrowSopId2);
                                // 查询是否已存在客户入营期
                                handleInsertSopUserLogsInfo(logsInfo);
                            } else {
                                // 没有明天的营期就先建
                                handleNextDayExecution(paramByDateTomorrow, logsInfo, userLogsTomorrow);
                            }
                        }
                        break;
                    }
                    // 次日执行
                    case 2: {
                        // 直接加入到明天的营期没有明天的营期就先建
                        if (!StringUtil.strIsNullOrEmpty(unionTomorrowSopId2)) {
                            logsInfo.setUserLogsId(unionTomorrowSopId2);
                            //客户入营期
                            handleInsertSopUserLogsInfo(logsInfo);
                        } else {
                            // 没有明天的营期就先建
                            handleNextDayExecution(paramByDateTomorrow, logsInfo, userLogsTomorrow);
                        }
                        break;
                    }
                    default:
                        // 其他类型可根据需要自行扩展
                        break;
                }
            }
        } catch (Exception e) {
            logger.error("qwSopRuleTimeToolsCheckError:" + e);
        }

    }

    public void handleInsertSopUserLogsInfo(SopUserLogsInfo sopUserLogsInfo) {
        SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(sopUserLogsInfo);
        if (userLogsInfo == null) {
            sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
        }
    }

    public void handleNextDayExecution(SopUserLogsParamByDate paramByDateTomorrow, SopUserLogsInfo sopUserLogsInfo, SopUserLogs userLogsTomorrow) {

        sopUserLogsService.insertSopUserLogsByDate(paramByDateTomorrow);

        SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectSopUserLogsInfo(sopUserLogsInfo);
        if (userLogsInfo == null) {

            String unionTomorrowSopId2New = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogsTomorrow);
            sopUserLogsInfo.setUserLogsId(unionTomorrowSopId2New);

            sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
        }
    }

    private void qwAiSopRuleTimeTools(List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS, String userID, QwUser qwUser, String corpId, String externalUserID, String externalContactName, QwExternalContact contact) {

        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("qw.config");
        List<SopUserLogsInfo> sopUserLogsInfos = sopUserLogsInfoMapper.repeatProject(PubFun.listToNewList(qwSopAiRuleTimeVOS, QwSopRuleTimeVO::getProject), externalUserID);
        Map<Integer, List<String>> collect = sopUserLogsInfos.stream().collect(Collectors.groupingBy(SopUserLogsInfo::getProject, Collectors.mapping(SopUserLogsInfo::getSopId, Collectors.toList())));
        qwSopAiRuleTimeVOS.forEach(ruleTimeVO -> {
            if(sysConfig != null){
                QwConfig qwConfig = JSON.parseObject(sysConfig.getConfigValue(), QwConfig.class);
                if(qwConfig.isProject()){
                    List<String> sopIdList = collect.get(ruleTimeVO.getProject());
                    log.info("是否多个项目:{}", sopIdList);
                    if(sopIdList.isEmpty()) return;
                    if(sopIdList.contains(ruleTimeVO.getId())) return;
                }
            }
            SopUserLogsInfo sopUserLogsInfo = new SopUserLogsInfo();
            sopUserLogsInfo.setQwUserId(userID.trim());
            sopUserLogsInfo.setCorpId(corpId.trim());
            sopUserLogsInfo.setExternalContactId(externalUserID.trim());
            sopUserLogsInfo.setExternalId(contact.getId());
            sopUserLogsInfo.setFsUserId(contact.getFsUserId());
            sopUserLogsInfo.setExternalUserName(externalContactName);
            sopUserLogsInfo.setSopId(ruleTimeVO.getId());
            SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectChatSopUserLogsInfo(sopUserLogsInfo);
            if (userLogsInfo == null) {
                logger.info("营期中没有新增");
                sopUserLogsInfoMapper.insertChatSopUserLogsInfo(sopUserLogsInfo);
            }
        });
    }

    //todo 聊天sop添加营期人员
    @Override
    public void qwChatSopRuleTimeTool(List<QwSopRuleTimeVO> qwSopRuleTimeVOS, String userID, String corpId, String externalUserID, String externalContactName, QwExternalContact contact) {
        //sop任务
        qwSopRuleTimeVOS.forEach(ruleTimeVO -> {

            SopUserLogsInfo sopUserLogsInfo = new SopUserLogsInfo();
            sopUserLogsInfo.setQwUserId(userID.trim());
            sopUserLogsInfo.setCorpId(corpId.trim());
            sopUserLogsInfo.setExternalContactId(externalUserID.trim());
            sopUserLogsInfo.setExternalId(contact.getId());
            sopUserLogsInfo.setFsUserId(contact.getFsUserId());
            sopUserLogsInfo.setExternalUserName(externalContactName);
            sopUserLogsInfo.setSopId(ruleTimeVO.getId());
            SopUserLogsInfo userLogsInfo = sopUserLogsInfoMapper.selectChatSopUserLogsInfo(sopUserLogsInfo);
            if (userLogsInfo == null) {
                sopUserLogsInfoMapper.insertChatSopUserLogsInfo(sopUserLogsInfo);
            }

        });
    }


    public List<SendWelcomeMsgParam.Attachment> attachmentsTools(List<SendWelcomeMsgParam.Attachment> attachments,
                                                                 QwUser qwUser,
                                                                 String corpId,
                                                                 Long qwExternalId) {

        if (attachments == null || attachments.isEmpty()) {
            return attachments;
        }

        String json = sysConfigService.selectConfigByKey("course.config");
        CourseConfig config = JSON.parseObject(json, CourseConfig.class);

        attachments.forEach(att -> {
            // 生成短链的条件判断
            if ("link".equals(att.getMsgtype())
                    && !StringUtil.strIsNullOrEmpty(att.getLink().getCourseId())
                    && !StringUtil.strIsNullOrEmpty(att.getLink().getVideoId())) {

                try {
                    //发课程
                    if (att.getLink().getIsFixed()==0){
                        FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                        param.setVideoId(Long.valueOf(att.getLink().getVideoId()));
                        param.setQwUserId(String.valueOf(qwUser.getId()));
                        param.setDays(att.getLink().getExpiresDays());
                        param.setCorpId(corpId);
                        param.setCourseId(Long.valueOf(att.getLink().getCourseId()));
                        param.setCompanyUserId(qwUser.getCompanyUserId());
                        param.setCompanyId(qwUser.getCompanyId());
                        param.setQwExternalId(qwExternalId);
                        param.setSendTime(new Date());

                        // 调用服务生成短链
                        R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);

                        if (linkUrl != null && linkUrl.get("url") != null) {
                            att.getLink().setUrl(linkUrl.get("url").toString());
                        }
                        //生成观看记录
                        addWatchLogIfNeeded(Integer.valueOf(att.getLink().getVideoId()),
                                Integer.valueOf(att.getLink().getCourseId()),
                                String.valueOf(qwUser.getId()),
                                String.valueOf(qwUser.getCompanyUserId()),
                                String.valueOf(qwUser.getCompanyId()),
                                String.valueOf(qwExternalId));
                    }else if (att.getLink().getIsFixed()==1){

                        if (config != null) {
                            att.getLink().setUrl(config.getRegisterDomainName()+registerLink+qwExternalId);
                        }else {
                            logger.error("企业配置信息为空：发送注册链接失败");
                        }
                    }


                } catch (Exception e) {
                    logger.error("欢迎语生成短链失败:", e);
                }
            }else if ("link".equals(att.getMsgtype()) && att.getLink().getIsFixed()==1 ) {

                if (config != null) {
                    att.getLink().setUrl(config.getRegisterDomainName()+registerLink+qwExternalId);
                }else {
                    logger.error("企业配置信息为空：发送注册链接失败");
                }

            }
            //小程序
            if ("miniprogram".equals(att.getMsgtype())
                    && !StringUtil.strIsNullOrEmpty(att.getMiniprogram().getCourseId())
                    && !StringUtil.strIsNullOrEmpty(att.getMiniprogram().getVideoId())) {

                try {

                    String mediaId = (String) redisCache.getCacheObject("miniprogram:" + corpId + ":" + att.getMiniprogram().getCourseId());
                    if (!StringUtil.strIsNullOrEmpty(mediaId)) {

                        FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                        param.setVideoId(Long.valueOf(att.getMiniprogram().getVideoId()));
                        param.setQwUserId(String.valueOf(qwUser.getId()));
                        param.setDays(att.getMiniprogram().getExpiresDays());
                        param.setCorpId(corpId);
                        param.setCourseId(Long.valueOf(att.getMiniprogram().getCourseId()));
                        param.setCompanyUserId(qwUser.getCompanyUserId());
                        param.setCompanyId(qwUser.getCompanyId());
                        param.setQwExternalId(qwExternalId);
                        param.setSendTime(new Date());

                        String linkUrl = iFsCourseLinkService.createLinkUrlWcmini(param);

                        if (!StringUtil.strIsNullOrEmpty(linkUrl)) {
                            att.getMiniprogram().setPage(linkUrl);
                        }

                        att.getMiniprogram().setPic_media_id(mediaId);

                        //生成观看记录
                        addWatchLogIfNeeded(Integer.valueOf(att.getMiniprogram().getVideoId()),
                                Integer.valueOf(att.getMiniprogram().getCourseId()),
                                String.valueOf(qwUser.getId()),
                                String.valueOf(qwUser.getCompanyUserId()),
                                String.valueOf(qwUser.getCompanyId()),
                                String.valueOf(qwExternalId));
                    } else {
                        logger.error("查到课程相关信息:" + corpId + ":" + att.getMiniprogram().getCourseId());
                    }

                } catch (Exception e) {
                    logger.error("欢迎语生成小程序消息失败:" + e.getMessage() + "|" + corpId + "|" + att.getMiniprogram().getCourseId());
                }
            }

        });

        return attachments;
    }

    //添加watchLog记录
    private void addWatchLogIfNeeded(Integer videoId, Integer courseId,
                                     String qwUserId, String companyUserId,
                                     String companyId, String externalId) {
        FsCourseWatchLog watchLog = new FsCourseWatchLog();
        watchLog.setVideoId(videoId != null ? videoId.longValue() : null);
        watchLog.setQwExternalContactId(externalId != null ? Long.valueOf(externalId) : null);
        watchLog.setSendType(2);
        watchLog.setQwUserId(qwUserId);
        watchLog.setSopId(null);
        watchLog.setCourseId(courseId != null ? courseId.longValue() : null);
        watchLog.setCompanyUserId(companyUserId != null ? Long.valueOf(companyUserId) : null);
        watchLog.setCompanyId(companyId != null ? Long.valueOf(companyId) : null);
        watchLog.setCreateTime(new Date());
        watchLog.setUpdateTime(new Date());
        watchLog.setLogType(3);
        watchLog.setUserId(0L);
        watchLogMapper.insertOrUpdateFsCourseWatchLog(watchLog);
    }

    @Override
    public void updateQwExternalContactByExternalUserId(String externalUserID, String userID, String corpId) {
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalUserID, userID, corpId);

        // 获取当前日期（只包含年月日）
        LocalDate currentDate = LocalDate.now();
        // 获取当前系统时间 (HH:mm)
        LocalTime localTime = LocalTime.now();

        if (qwExternalContact != null) {
            QwExternalContactResult contactResult = qwApiService.getExternalcontact(externalUserID, corpId);
//            logger.info("修改查询用户：" + externalcontact);
            List<FollowUser> followUsers = contactResult.getFollow_user();
            for (FollowUser followUser : followUsers) {
                if (followUser.getUserid().equals(userID)) {
                    QwExternalContact qwExternalContact1 = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalUserID, userID, corpId);
                    if (qwExternalContact1 != null) {

                        QwExternalContact qw = new QwExternalContact();
                        qw.setId(qwExternalContact1.getId());
                        qw.setDescription(followUser.getDescription()); // 设置描述信息
                        List<Tag> tags = followUser.getTags();

                        if (tags != null && tags.size() > 0) {

                            List<String> tagArr = new ArrayList<>();
                            for (Tag tag : tags) {
                                if (tag != null && tag.getTag_id() != null) {
                                    tagArr.add(tag.getTag_id());
                                }
                            }
                            logger.info("客户添加标签回调中的addUserTag：" + qwExternalContact1.getName() + "|公司" + qwExternalContact1.getCorpId() + "|员工" + qwExternalContact1.getUserId() + "|总标签" + tagArr + "|原标签" + qwExternalContact1.getTagIds());

                            //检查sop
                            processTagsAll(qwExternalContact1, corpId, tagArr, currentDate, localTime);

                            //新客对话
//                            processTagsAllByAiChat(qwExternalContact1,corpId,tagArr);

                            qw.setTagIds(JSON.toJSONString(tagArr)); // 设置标签ID

                        }
                        if (followUser.getRemark_mobiles() != null && followUser.getRemark_mobiles().size() > 0) {
                            List<String> remarkMobiles = followUser.getRemark_mobiles();
                            qw.setRemarkMobiles(JSON.toJSONString(remarkMobiles));
                        }
                        qw.setRemarkCorpName(followUser.getRemark_corp_name()); // 设置备注企业名称
                        qwExternalContactMapper.updateQwExternalContact(qw);
                    }

                }

            }

        }
    }


    /**
     * 整合客户的标签的逻辑 ，新增和移除 都要移除和添加到营期里
     */
    private void processTagsAll(QwExternalContact qwExternalContact, String corpId, List<String> tagArr, LocalDate currentDate, LocalTime localTime) {

        List<String> cleanedTagList = tagArr.stream()
                .map(String::trim)   // 去除前后空格
                .filter(s -> !s.isEmpty()) // 过滤掉空字符串（如果有）
                .distinct()           // 去重
                .collect(Collectors.toList());

        QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
        qwSopAutoByTags.setQwUserId(String.valueOf(qwExternalContact.getQwUserId()));
        qwSopAutoByTags.setCorpId(corpId);
        qwSopAutoByTags.setTagsIdsSelectList(cleanedTagList);
        qwSopAutoByTags.setSendType(2);

        // 定义日期和时间格式化器
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");


        try {
            //查询匹配这个销售所有正在执行的 SOP任务 ps:仅仅是AI插件的
            List<QwSopRuleTimeVO> runRuleTime = qwSopMapper.selectQwSopByQwUserId(qwSopAutoByTags);

            logger.info("查出来的销售 任务长度：" + runRuleTime.size());
            //如果剩下的总标签 啥也没有
            // 查询匹配这些Tag的SOP任务
            if (cleanedTagList.isEmpty()) {

                //这个人标签空了，以防万一 将这个销售下的这个人的所有sop里的他（可能没有） 全刷一遍
                if (!runRuleTime.isEmpty()) {
                    runRuleTime.forEach(runSop -> {

                        logger.info("cleanedTagList-空了，将这个销售下的这个人的所有sop里的他（可能没有） 全刷一遍 sopId:{}", runSop.getId());
                        deleteBySopIdToContactIdTools(runSop.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                    });
                }
            } else {
                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeachNotAuto(qwSopAutoByTags);

                if (!qwSopRuleTimeVOS.isEmpty()) {

                    //匹配上剩下的标签看看符合不符合
                    qwSopRuleTimeVOS.forEach(ruleTimeVO -> {

                        // 将排除的字符串转成列表
                        List<String> excludedTagsList = new ArrayList<>();
                        if (ruleTimeVO.getExcludeTags() != null && !ruleTimeVO.getExcludeTags().isEmpty()) {
                            excludedTagsList = Arrays.asList(ruleTimeVO.getExcludeTags().split(","));
                        }


                        // 检查 combinedTagsList 是否包含排除列表中的任意一个标签
                        boolean containsExcludedTag = cleanedTagList.stream()
                                .anyMatch(excludedTagsList::contains);

                        //含任意一个排除标签
                        if (containsExcludedTag) {
                            logger.info("该客户已匹配到规则，但是被排除，规则id:" + ruleTimeVO.getId() + "|cleanedTagList" + cleanedTagList + "|excludedTagsList" + excludedTagsList);
                            deleteBySopIdToContactIdTools(ruleTimeVO.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                        } else {
                            //检查 有可能在营期里 有可能不在。在不动，不在
                            // 从数据库中取到的开始时间（Date类型），转换为 LocalDate
                            Date sopStartTime = ruleTimeVO.getStartTime();
                            //开始时间
                            LocalDate sopStartLocalDate = sopStartTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

                            // 自动sop的规则
                            QwAutoSopTimeParam qwAutoSopTimeParam = JSON.parseObject(ruleTimeVO.getAutoSopTime(), QwAutoSopTimeParam.class);

                            // 用于查询/或新增
                            SopUserLogs userLogs = new SopUserLogs();
                            userLogs.setSopId(ruleTimeVO.getId());
                            userLogs.setSopTempId(ruleTimeVO.getTempId());
                            userLogs.setCorpId(ruleTimeVO.getCorpId());
                            userLogs.setStatus(1);

                            // 用于今天的新增
                            SopUserLogsParamByDate userLogsParamByDate = new SopUserLogsParamByDate();
                            userLogsParamByDate.setSopId(ruleTimeVO.getId());
                            userLogsParamByDate.setSopTempId(ruleTimeVO.getTempId());
                            userLogsParamByDate.setCorpId(ruleTimeVO.getCorpId());
                            userLogsParamByDate.setStatus(1);

                            // 设定用户信息
                            userLogs.setQwUserId(qwExternalContact.getUserId());
                            userLogs.setUserId(qwExternalContact.getQwUserId() + "|" + qwExternalContact.getCompanyUserId() + "|" + qwExternalContact.getCompanyId());
                            userLogsParamByDate.setQwUserId(qwExternalContact.getUserId());
                            userLogsParamByDate.setUserId(qwExternalContact.getQwUserId() + "|" + qwExternalContact.getCompanyUserId() + "|" + qwExternalContact.getCompanyId());

                            // 创建 SopUserLogsInfo
                            SopUserLogsInfo logsInfo = new SopUserLogsInfo();
                            logsInfo.setQwUserId(qwExternalContact.getUserId());
                            logsInfo.setCorpId(corpId);
                            logsInfo.setExternalContactId(qwExternalContact.getExternalUserId());
                            logsInfo.setExternalId(qwExternalContact.getId());
                            logsInfo.setFsUserId(qwExternalContact.getFsUserId());
                            logsInfo.setExternalUserName(qwExternalContact.getName());
                            logsInfo.setSopId(ruleTimeVO.getId());

                            //检查营期
                            qwSopRuleTimeToolsCheck(sopStartLocalDate, currentDate, dateFormatter, userLogs, logsInfo, userLogsParamByDate, qwAutoSopTimeParam, timeFormatter, localTime);

                        }

                    });

                    List<QwSopRuleTimeVO> qwSopRuleTimeVOSRemove = qwSopMapper.selectQwSopAutoByTagsByForeachRemoveNotAuto(qwSopAutoByTags);
                    if (!qwSopRuleTimeVOSRemove.isEmpty()) {
                        qwSopRuleTimeVOSRemove.forEach(vosRemove -> {
                            logger.info("删除这个客户在这个销售的其他无关的sop任务" + vosRemove.getId() + "标签：" + tagArr + "id:" + qwExternalContact.getQwUserId());
                            deleteBySopIdToContactIdTools(vosRemove.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                        });
                    }

//                    if (!runRuleTime.isEmpty() && !qwSopRuleTimeVOS.isEmpty()){
//
//                        //剔除掉 销售的其他任务里的，这个人的信息ps:可能没有
//                        Set<String> qwSopRuleTimeVOIds = qwSopRuleTimeVOS.stream()
//                                .map(QwSopRuleTimeVO::getId)
//                                .filter(Objects::nonNull)       // 过滤掉 null
//                                .map(String::trim)              // 去除前后空格
//                                .collect(Collectors.toSet());
//
//                        if (!qwSopRuleTimeVOIds.isEmpty()){
//
//                            //在 qwSopRuleTimeVOS 中过滤掉包含在 runRuleTimeIds 中的 id
//                            List<QwSopRuleTimeVO> notOverlapList = runRuleTime.stream()
//                                    .filter(item -> item.getId() != null &&!qwSopRuleTimeVOIds.contains(item.getId().trim()))
//                                    .collect(Collectors.toList());
//
//                            notOverlapList.forEach(notSop->{
//                                logger.info("删除这个客户在这个销售的其他不符合的sop"+notSop.getId()+"标签："+tagArr+"id:"+qwExternalContact.getQwUserId()+"排除的标签:"+qwSopRuleTimeVOIds);
//
//                                deleteBySopIdToContactIdTools(notSop.getId(),qwExternalContact.getUserId(),qwExternalContact.getCorpId(),qwExternalContact.getId());
//
//                            });
//                        }
//                    }
                } else {
                    //没匹配上任意一个（即这个剩下的标签匹配不上任意的sop），但是销售有任务-以防万一-删除这个客户在这个销售的sop
                    if (!runRuleTime.isEmpty()) {
                        runRuleTime.forEach(runSop -> {
                            logger.info("没匹配上任意一个（即这个剩下的标签匹配不上任意的sop），但是销售有任务-以防万一-删除这个客户在这个销售的sop" + runSop.getId() + "标签：" + tagArr + "id:" + qwExternalContact.getQwUserId());
                            deleteBySopIdToContactIdTools(runSop.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                        });
                    }
                }

            }

        } catch (Exception e) {
            logger.error("改动了客户的标签的异常：qwExternalContact" + qwExternalContact + "|corpId" + corpId + "|cleanedTagList" + cleanedTagList);
        }

    }

    ;

    /**
     * 新客对话
     */
    private void processTagsAllByAiChat(QwExternalContact qwExternalContact, String corpId, List<String> tagArr) {

        List<String> cleanedTagList = tagArr.stream()
                .map(String::trim)   // 去除前后空格
                .filter(s -> !s.isEmpty()) // 过滤掉空字符串（如果有）
                .distinct()           // 去重
                .collect(Collectors.toList());


        QwSopAutoByTags sopAutoByTagsChat = new QwSopAutoByTags();

        sopAutoByTagsChat.setQwUserId(String.valueOf(qwExternalContact.getQwUserId()));
        sopAutoByTagsChat.setCorpId(corpId);
        sopAutoByTagsChat.setTagsIdsSelectList(cleanedTagList);
        sopAutoByTagsChat.setSendType(4);

        try {
            //查询匹配这个销售所有正在执行的 SOP任务 ps:仅仅是AI插件的
            List<QwSopRuleTimeVO> runRuleTime = qwSopMapper.selectQwSopByQwUserId(sopAutoByTagsChat);

            //如果剩下的总标签 啥也没有
            // 查询匹配这些Tag的SOP任务
            if (cleanedTagList.isEmpty()) {

                //这个人标签空了，以防万一 将这个销售下的这个人的所有sop里的他（可能没有） 全刷一遍
                if (!runRuleTime.isEmpty()) {
                    runRuleTime.forEach(runSop -> {

                        deleteBySopIdToContactIdChatTools(runSop.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                    });
                }
            } else {
                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeachNotAuto(sopAutoByTagsChat);
                if (!qwSopRuleTimeVOS.isEmpty()) {

                    //匹配上剩下的标签看看符合不符合
                    qwSopRuleTimeVOS.forEach(ruleTimeVO -> {

                        // 将排除的字符串转成列表
                        List<String> excludedTagsList = new ArrayList<>();
                        if (ruleTimeVO.getExcludeTags() != null && !ruleTimeVO.getExcludeTags().isEmpty()) {
                            excludedTagsList = Arrays.asList(ruleTimeVO.getExcludeTags().split(","));
                        }

                        // 检查 combinedTagsList 是否包含排除列表中的任意一个标签
                        boolean containsExcludedTag = cleanedTagList.stream()
                                .anyMatch(excludedTagsList::contains);

                        //含任意一个排除标签
                        if (containsExcludedTag) {

                            deleteBySopIdToContactIdChatTools(ruleTimeVO.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                        }

                    });
                } else {
                    //没匹配上任意一个（即这个剩下的标签匹配不上任意的sop），但是销售有任务-以防万一-删除这个客户在这个销售的sop
                    if (!runRuleTime.isEmpty()) {
                        runRuleTime.forEach(runSop -> {

                            deleteBySopIdToContactIdChatTools(runSop.getId(), qwExternalContact.getUserId(), qwExternalContact.getCorpId(), qwExternalContact.getId());

                        });
                    }
                }
            }
        } catch (Exception e) {
            logger.error("移除新客对话sop任务失败：客户信息-" + qwExternalContact + "|" + cleanedTagList + "|" + e);
        }

    }

    public void deleteBySopIdToContactIdTools(String sopId, String qwUserId, String corpId, Long externalId) {

        // 删除Sop任务营期里的该客户信息
        SopUserLogsInfoDelParam logsInfoDelParam = new SopUserLogsInfoDelParam();
        try {
            logsInfoDelParam.setSopId(sopId);
            logsInfoDelParam.setQwUserId(qwUserId);
            logsInfoDelParam.setCorpId(corpId);
            logsInfoDelParam.setExternalId(externalId);
            sopUserLogsInfoMapper.deleteBySopIdToContactId(logsInfoDelParam);

            logger.info("移除sop营期：" + logsInfoDelParam);

        } catch (Exception e) {
            logger.error("删除Sop任务营期里的该客户信息异常：" + logsInfoDelParam + "|" + e.getMessage());
        }
    }

    public void deleteBySopIdToContactIdChatTools(String sopId, String qwUserId, String corpId, Long externalId) {

        // 删除Sop任务营期里的该客户信息
        SopUserLogsInfoDelParam logsInfoDelParam = new SopUserLogsInfoDelParam();
        try {
            logsInfoDelParam.setSopId(sopId);
            logsInfoDelParam.setQwUserId(qwUserId);
            logsInfoDelParam.setCorpId(corpId);
            logsInfoDelParam.setExternalId(externalId);
            sopUserLogsInfoMapper.deleteBySopIdToContactIdChat(logsInfoDelParam);
            logger.info("移除新客对话sop营期：" + logsInfoDelParam);
        } catch (Exception e) {
            logger.error("删除chatSop任务营期里的该客户信息异常：" + logsInfoDelParam + "|" + e.getMessage());
        }
    }

    @Override
    public void deleteQwExternalContactByExternalUserId(String externalUserID, String userID, String corpId) {


        //先查 客户是不是在在职转接里面的。是的话先保留
        QwExternalContactTransferLog transferLogParam = new QwExternalContactTransferLog();
        transferLogParam.setCorpId(corpId);
        transferLogParam.setHandoverUserId(userID);
        transferLogParam.setExternalUserId(externalUserID);

        QwExternalContactTransferLog transferLogVO = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogListByCheckHand(transferLogParam);

        if (transferLogVO == null) {
            logger.info("删除客户-无转接记录-" + transferLogParam);
            //销售删除客户-找这个销售的sop任务中所有的营期里有没有这个客户，删了
            sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactId(userID, corpId, externalUserID);
            sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChat(userID, corpId, externalUserID);

        }

        //删除待发送记录
        GetQwSopLogsByJsApiParam apiParam = new GetQwSopLogsByJsApiParam();
        apiParam.setQwUserId(userID);
        apiParam.setCorpId(corpId);
        apiParam.setExternalUserId(externalUserID);
        qwSopLogsMapper.deleteQwSopLogsByJsApi(apiParam);

        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalUserID, userID, corpId);
        logger.info("删除客户");
        if (qwExternalContact != null) {
            QwExternalContact qwExternal = new QwExternalContact();
            qwExternal.setId(qwExternalContact.getId());
            qwExternal.setStatus(4);
            qwExternal.setDelTime(new Date());
//            logger.info("删除用户客户更改状态");
            qwExternalContactMapper.updateQwExternalContact(qwExternal);
        }
    }

    @Override
    public void deletefollowUserByExternalUserId(String externalUserID, String userID, String corpId) {

        //客户删除销售-找这个销售的sop任务中所有的营期里有没有这个客户，删了(暂时不要删-这种流失的有些一样能发消息)
//        sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactId(userID,corpId, externalUserID);
        logger.error("客户删除销售-" + "|" + externalUserID + "|" + userID + "|" + corpId);

        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalUserID, userID, corpId);
        if (qwExternalContact != null) {
            if (qwExternalContact.getStatus() != 4) {
                QwExternalContact qwExternal = new QwExternalContact();
                qwExternal.setId(qwExternalContact.getId());
                qwExternal.setStatus(3);
                qwExternal.setLossTime(new Date());
                qwExternalContactMapper.updateQwExternalContact(qwExternal);
            }
            if (qwExternalContact.getWayId() != null) {
                qwContactWayService.updateQwContactWayByLoss(qwExternalContact);
            }

        }

    }

    @Override
    public void transferFailByExternalUserId(String externalUserID, String userID, String corpId, String failReason) {

        Integer status = 0;
        if (failReason.equals("customer_limit_exceed")) {
            status = 4;
        } else {
            status = 3;
        }

        QwExternalContactTransferLog qwExternalContactTransferLog = new QwExternalContactTransferLog();
        qwExternalContactTransferLog.setTakeoverUserId(userID);
        qwExternalContactTransferLog.setExternalUserId(externalUserID);
        qwExternalContactTransferLog.setCorpId(corpId);

        List<QwExternalContactTransferLog> qwExternalContactTransferLogs = qwExternalContactTransferLogMapper.selectQwExternalContactTransferLogList(qwExternalContactTransferLog);
        for (QwExternalContactTransferLog externalContactTransferLog : qwExternalContactTransferLogs) {
            externalContactTransferLog.setStatus(status);
            qwExternalContactTransferLogMapper.updateQwExternalContactTransferLog(externalContactTransferLog);
        }

    }

    @Override
    public int updateQwExternalContactStatus(QwExternalContact qwExternalContact) {
        QwExternalContact qwExternal = new QwExternalContact();
        qwExternal.setId(qwExternalContact.getId());
        qwExternal.setStageStatus(qwExternalContact.getStageStatus());
        return qwExternalContactMapper.updateQwExternalContact(qwExternal);
    }

    /**
     * 企业微信客户与企业客户绑定
     */
    @Override
    public int updateQwExternalContactBindCustomer(QwExternalContact qwExternalContact) {
//
//        CrmCustomer customer=new CrmCustomer();
//
//        Long customerId = qwExternalContact.getCustomerId();
//        Long id = qwExternalContact.getId();

        //更新企微客户-CRM客户绑定关系
        QwExternalContactCrm qwExternalContactCrm = new QwExternalContactCrm();
        qwExternalContactCrm.setExternalUserId(qwExternalContact.getExternalUserId());
        qwExternalContactCrm.setExternalUserName(qwExternalContact.getName());
        qwExternalContactCrm.setAvatar(qwExternalContact.getAvatar());
        qwExternalContactCrm.setOpenid(qwExternalContact.getOperUserid());
        qwExternalContactCrm.setCorpId(qwExternalContact.getCorpId());
        qwExternalContactCrm.setCustomerId(qwExternalContact.getCustomerId());

        contactCrmService.insertOrUpdateQwExternalContactCrm(qwExternalContactCrm);

        CrmCustomer customer = new CrmCustomer();

        customer.setQwName(qwExternalContact.getName());
        customer.setCustomerId(qwExternalContact.getCustomerId());

        customerMapper.updateCrmCustomer(customer);

        return qwExternalContactMapper.updateQwExternalContactByExternalUserId(qwExternalContact);
    }

    /**
     * 设置客户-课节SOP
     */
    @Override
    public R setCustomerCourseSop(QwFsCustomerCourseSopParam param) {


//        try {
//            //查看是否有看课信息
//            FsCourseWatchLog fsCourseWatchLog = new FsCourseWatchLog();
//            fsCourseWatchLog.setUserId(param.getMiniUserId());
//            fsCourseWatchLog.setVideoId(param.getBusinessId());
//            fsCourseWatchLog.setQwExternalContactId(param.getExternalContactId());
//
//            //录入日志
//            FsCourseSopLogs fsSopLogs = new FsCourseSopLogs();
//
//            List<QwSopSettingParams> paramsList = JSON.parseArray(param.getSetting(), QwSopSettingParams.class);
//
//            fsSopLogs.setQwUserid(param.getQwUserid());
//            fsSopLogs.setCompanyUserId(param.getCompanyUserId());
//            fsSopLogs.setExternalUserId(param.getExternalUserId());
//            fsSopLogs.setCustomerId(param.getCustomerId());
//            fsSopLogs.setCompanyId(param.getCompanyId());
//            fsSopLogs.setReceivingStatus(0L);
//            fsSopLogs.setSopId(param.getSopId());
//            fsSopLogs.setSopType(param.getSopType());
//            fsSopLogs.setBusinessId(param.getBusinessId());
//
//            String sortLink = "";
//
//            FsCourseLinkCreateParam linkCreateParam = new FsCourseLinkCreateParam();
//            linkCreateParam.setVideoId(param.getBusinessId());
//            linkCreateParam.setQwUserId(param.getQwUserid());
//            linkCreateParam.setDays(param.getDays());
//            linkCreateParam.setCorpId(param.getCorpId());
//
//            R createLink = fsCourseLinkService.createLinkUrl(linkCreateParam);
//            if (createLink.get("code").equals(200)) {
//                sortLink = createLink.get("url").toString();
//            } else {
//                return createLink;
//            }
//
//
//            List<FsCourseWatchLog> fsCourseWatchLogs = fsCourseWatchLogMapper.selectFsCourseWatchLogList(fsCourseWatchLog);
//            //没有记录 ，则全记录
//            if (fsCourseWatchLogs.isEmpty()) {
//
//                for (QwSopSettingParams params : paramsList) {
//
//                    for (QwSopSettingParams.Content content : params.getContent()) {
//                        if (content.getIsBindUrl().equals("1")) {
//                            content.setUrl(sortLink);
//                            content.setValue(content.getValue() + "\n" + sortLink);
//                        }
//                    }
//                    fsSopLogs.setContentJson(JSON.toJSONString(params.getContent()));
//                    fsSopLogs.setWatchStatus(Integer.valueOf(params.getRuleType()));
//                    if (params.getRuleType().equals("0")) {
//                        fsSopLogs.setSendStatus(3L);
//                    } else {
//                        fsSopLogs.setSendStatus(4L);
//                    }
//
//                    // 获取当前时间
//                    Date currentTime = new Date();
//
//                    // 使用 Calendar 处理时间
//                    Calendar calendar = Calendar.getInstance();
//                    calendar.setTime(currentTime);
//
//                    if (params.getType() == 1) {
//
//                        // 将字符串转换为整数
//                        int hourToAdd = Integer.parseInt(params.getHour());
//                        int minuteToAdd = Integer.parseInt(params.getMinute());
//
//                        // 将小时和分钟添加到当前时间
//                        calendar.add(Calendar.HOUR, hourToAdd);
//                        calendar.add(Calendar.MINUTE, minuteToAdd);
//
//                        // 获取新的时间
//                        Date newTime = calendar.getTime();
//
//                        fsSopLogs.setSendTime(newTime);
//
//                    } else if (params.getType() == 2) {
//
//                        calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(params.getDay()));
//
//                        // 解析时间字符串并设置时间
//                        SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
//                        try {
//                            Date parsedTime = timeFormatter.parse(params.getTime());
//
//                            Calendar timeCalendar = Calendar.getInstance();
//                            timeCalendar.setTime(parsedTime);
//
//                            // 设置新的日期的小时和分钟
//                            calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
//                            calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
//                            calendar.set(Calendar.SECOND, 0); // 设置秒为0
//
//                            fsSopLogs.setSendTime(calendar.getTime());
//                        } catch (Exception e) {
//                            e.printStackTrace();
//                        }
//
//                    }
//
//                    int i = fsSopLogsMapper.insertFsCourseSopLogs(fsSopLogs);
//                }
//
//                fsCourseWatchLog.setLogType(3);
//                fsCourseWatchLog.setCreateTime(new Date());
//                fsCourseWatchLogMapper.insertFsCourseWatchLog(fsCourseWatchLog);
//            }
//            else {
//                // 根据 ruleType 分类 params
//                Map<String, List<QwSopSettingParams>> paramsMap = new HashMap<>();
//
//                // 遍历 paramsList，将其分类到对应的 ruleType
//                for (QwSopSettingParams params : paramsList) {
//                    paramsMap.computeIfAbsent(params.getRuleType(), k -> new ArrayList<>()).add(params);
//                }
//
//                List<String> ruleTypesToProcess = new ArrayList<>();
//
//                //存在记录 则录入相关状态的 SOP
//                switch (fsCourseWatchLogs.get(0).getLogType()) {
//                    //领取(看课中) 记入 看课中 已完课的消息
//                    case 1:
//                        ruleTypesToProcess.add("2");
//                        ruleTypesToProcess.add("3");
//                        break;
//                    //已看完 计入 已完课的消息
//                    case 2:
//                        ruleTypesToProcess.add("3");
//                        break;
//                    //待看课 计入 带看课 看课中 已完课的消息
//                    case 3:
//                        ruleTypesToProcess.add("1");
//                        ruleTypesToProcess.add("2");
//                        ruleTypesToProcess.add("3");
//                        break;
//                }
//
//                // 批量处理符合条件的所有 params
//                for (String ruleType : ruleTypesToProcess) {
//                    List<QwSopSettingParams> caseParams = paramsMap.get(ruleType);
//                    if (caseParams != null) {
//                        for (QwSopSettingParams params : caseParams) {
//
//                            fsSopLogs.setContentJson(JSON.toJSONString(params.getContent()));
//                            fsSopLogs.setWatchStatus(Integer.valueOf(params.getRuleType()));
//                            fsSopLogs.setSendStatus(4L);
//                            // 获取当前时间
//                            Date currentTime = new Date();
//
//                            // 使用 Calendar 处理时间
//                            Calendar calendar = Calendar.getInstance();
//                            calendar.setTime(currentTime);
//
//                            if (params.getType() == 1) {
//
//                                // 将字符串转换为整数
//                                int hourToAdd = Integer.parseInt(params.getHour());
//                                int minuteToAdd = Integer.parseInt(params.getMinute());
//
//                                // 将小时和分钟添加到当前时间
//                                calendar.add(Calendar.HOUR, hourToAdd);
//                                calendar.add(Calendar.MINUTE, minuteToAdd);
//
//                                // 获取新的时间
//                                Date newTime = calendar.getTime();
//
//                                fsSopLogs.setSendTime(newTime);
//
//                            } else if (params.getType() == 2) {
//
//                                calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(params.getDay()));
//
//                                // 解析时间字符串并设置时间
//                                SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
//                                try {
//                                    Date parsedTime = timeFormatter.parse(params.getTime());
//
//                                    Calendar timeCalendar = Calendar.getInstance();
//                                    timeCalendar.setTime(parsedTime);
//
//                                    // 设置新的日期的小时和分钟
//                                    calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
//                                    calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
//                                    calendar.set(Calendar.SECOND, 0); // 设置秒为0
//
//                                    fsSopLogs.setSendTime(calendar.getTime());
//                                } catch (Exception e) {
//                                    e.printStackTrace();
//                                }
//
//                            }
//                            // 这里可以根据需要设置 fsSopLogs 的属性
//                            fsSopLogsMapper.insertFsCourseSopLogs(fsSopLogs);
//                        }
//                    }
//                }
//
//            }
//
//        } catch (Exception e) {
//            return R.error("配置出错：" + e.getMessage());
//        }

        return R.ok();
    }

    /**
     * 查询是否已经设置过客户-某个课节的SOP
     */
    @Override
    public Boolean getCustomerCourseSop(QwFsCustomerCourseSopGetParam param) {

        FsCourseSopLogs fsSopLogs = new FsCourseSopLogs();
        fsSopLogs.setQwUserid(param.getQwUserid());
        fsSopLogs.setExternalUserId(param.getExternalUserId());
        fsSopLogs.setBusinessId(param.getBusinessId());
        fsSopLogs.setCompanyId(param.getCompanyId());

        List<FsCourseSopLogs> fsSopLogsList = fsSopLogsMapper.selectFsCourseSopLogsList(fsSopLogs);
        return !fsSopLogsList.isEmpty();

    }

    @Override
    public R setCustomerCourseSopList(QwFsCustomerCourseSopListParam param) {

        List<Long> ids = param.getIds();

        FsCourseSop fsSop = fsSopMapper.selectFsCourseSopById(param.getFsCourseSopId());

        //记录批量设置SOP时，没有绑定CRM的客户
        ArrayList<String> errorCRMList = new ArrayList<>();

        //记录批量中绑定了CRM 客户 却没有绑定 小程序的
        ArrayList<String> errorUseridList = new ArrayList<>();

        //客户没有所属成员
        ArrayList<String> errorCompanyList = new ArrayList<>();

        //记录成功的数量
        Long successNum = 0L;

        //录入日志
        FsCourseSopLogs fsSopLogs = new FsCourseSopLogs();
//
//        for (Long id : ids) {
//            QwExternalContactFsCrmVO qwExternalContact = qwExternalContactMapper.selectQwExternalContactByIdToCrm(id);
//
//            if (qwExternalContact.getCustomerId() == null || qwExternalContact.getCustomerId() == 0L) {
//                errorCRMList.add(qwExternalContact.getName());
//
//            } else if (qwExternalContact.getMiniUserId() == null) {
//                errorUseridList.add(qwExternalContact.getName());
//            } else if (qwExternalContact.getCompanyUserId() == null || qwExternalContact.getCompanyUserId() == 0L) {
//                errorCompanyList.add(qwExternalContact.getName());
//            } else {
//
//                List<QwSopSettingParams> paramsList = JSON.parseArray(fsSop.getSetting(), QwSopSettingParams.class);
//
//                fsSopLogs.setQwUserid(qwExternalContact.getUserId());
//                fsSopLogs.setCompanyUserId(qwExternalContact.getCompanyUserId());
//                fsSopLogs.setExternalUserId(qwExternalContact.getExternalUserId());
//                fsSopLogs.setCompanyId(qwExternalContact.getCompanyId());
//                fsSopLogs.setReceivingStatus(0L);
//                fsSopLogs.setSopId(fsSop.getId());
//                fsSopLogs.setSopType(fsSop.getSopType());
//                fsSopLogs.setBusinessId(fsSop.getBusinessId());
//
//                String sortLink = "";
//                FsCourseLinkCreateParam linkCreateParam = new FsCourseLinkCreateParam();
//                linkCreateParam.setVideoId(fsSop.getBusinessId());
//                linkCreateParam.setQwUserId(qwExternalContact.getUserId());
//                linkCreateParam.setDays(param.getDays());
//                linkCreateParam.setCorpId(param.getCorpId());
//                R createLink = fsCourseLinkService.createLinkUrl(linkCreateParam);
//                if (createLink.get("code").equals(200)) {
//                    sortLink = createLink.get("url").toString();
//                } else {
//                    return createLink;
//                }
//
//                //查看是否有看课信息
//                FsCourseWatchLog fsCourseWatchLog = new FsCourseWatchLog();
//                fsCourseWatchLog.setUserId(qwExternalContact.getMiniUserId());
//                fsCourseWatchLog.setVideoId(fsSopLogs.getBusinessId());
//                fsCourseWatchLog.setQwExternalContactId(qwExternalContact.getId());
//                List<FsCourseWatchLog> fsCourseWatchLogs = fsCourseWatchLogMapper.selectFsCourseWatchLogList(fsCourseWatchLog);
//
//                //没有记录 ，则全记录
//                if (fsCourseWatchLogs.isEmpty()) {
//
//                    for (QwSopSettingParams params : paramsList) {
//
//                        for (QwSopSettingParams.Content content : params.getContent()) {
//                            if (content.getIsBindUrl().equals("1")) {
//                                content.setUrl(sortLink);
//                                content.setValue(content.getValue() + "\n" + sortLink);
//                            }
//                        }
//                        fsSopLogs.setContentJson(JSON.toJSONString(params.getContent()));
//                        fsSopLogs.setWatchStatus(Integer.valueOf(params.getRuleType()));
//                        if (params.getRuleType().equals("0")) {
//                            fsSopLogs.setSendStatus(3L);
//                        }
//                        else {
//                            fsSopLogs.setSendStatus(4L);
//                        }
//
//                        // 获取当前时间
//                        Date currentTime = new Date();
//
//                        // 使用 Calendar 处理时间
//                        Calendar calendar = Calendar.getInstance();
//                        calendar.setTime(currentTime);
//
//                        if (params.getType() == 1) {
//
//                            // 将字符串转换为整数
//                            int hourToAdd = Integer.parseInt(params.getHour());
//                            int minuteToAdd = Integer.parseInt(params.getMinute());
//
//                            // 将小时和分钟添加到当前时间
//                            calendar.add(Calendar.HOUR, hourToAdd);
//                            calendar.add(Calendar.MINUTE, minuteToAdd);
//
//                            // 获取新的时间
//                            Date newTime = calendar.getTime();
//
//                            fsSopLogs.setSendTime(newTime);
//
//                        }
//                        else if (params.getType() == 2) {
//
//                            calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(params.getDay()));
//
//                            // 解析时间字符串并设置时间
//                            SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
//                            try {
//                                Date parsedTime = timeFormatter.parse(params.getTime());
//
//                                Calendar timeCalendar = Calendar.getInstance();
//                                timeCalendar.setTime(parsedTime);
//
//                                // 设置新的日期的小时和分钟
//                                calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
//                                calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
//                                calendar.set(Calendar.SECOND, 0); // 设置秒为0
//
//                                fsSopLogs.setSendTime(calendar.getTime());
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//
//                        }
//
//                        int i = fsSopLogsMapper.insertFsCourseSopLogs(fsSopLogs);
//                        successNum++;
//                    }
//
//                    fsCourseWatchLog.setLogType(3);
//                    fsCourseWatchLog.setCreateTime(new Date());
//                    fsCourseWatchLogMapper.insertFsCourseWatchLog(fsCourseWatchLog);
//                }
//                else {
//                    // 根据 ruleType 分类 params
//                    Map<String, List<QwSopSettingParams>> paramsMap = new HashMap<>();
//
//                    // 遍历 paramsList，将其分类到对应的 ruleType
//                    for (QwSopSettingParams params : paramsList) {
//                        paramsMap.computeIfAbsent(params.getRuleType(), k -> new ArrayList<>()).add(params);
//                    }
//
//                    List<String> ruleTypesToProcess = new ArrayList<>();
//
//                    //存在记录 则录入相关状态的 SOP
//                    switch (fsCourseWatchLogs.get(0).getLogType()) {
//                        //领取(看课中) 记入 看课中 已完课的消息
//                        case 1:
//                            ruleTypesToProcess.add("2");
//                            ruleTypesToProcess.add("3");
//                            break;
//                        //已看完 计入 已完课的消息
//                        case 2:
//                            ruleTypesToProcess.add("3");
//                            break;
//                        //待看课 计入 带看课 看课中 已完课的消息
//                        case 3:
//                            ruleTypesToProcess.add("1");
//                            ruleTypesToProcess.add("2");
//                            ruleTypesToProcess.add("3");
//                            break;
//                    }
//
//                    // 批量处理符合条件的所有 params
//                    for (String ruleType : ruleTypesToProcess) {
//                        List<QwSopSettingParams> caseParams = paramsMap.get(ruleType);
//                        if (caseParams != null) {
//                            for (QwSopSettingParams params : caseParams) {
//
//                                //附上短链
//                                for (QwSopSettingParams.Content content : params.getContent()) {
//                                    if (content.getIsBindUrl().equals("1")) {
//                                        content.setUrl(sortLink);
//                                        content.setValue(content.getValue() + "\n" + sortLink);
//                                    }
//                                }
//
//                                fsSopLogs.setContentJson(JSON.toJSONString(params.getContent()));
//                                fsSopLogs.setWatchStatus(Integer.valueOf(params.getRuleType()));
//                                fsSopLogs.setSendStatus(4L);
//                                // 获取当前时间
//                                Date currentTime = new Date();
//
//                                // 使用 Calendar 处理时间
//                                Calendar calendar = Calendar.getInstance();
//                                calendar.setTime(currentTime);
//
//                                if (params.getType() == 1) {
//
//                                    // 将字符串转换为整数
//                                    int hourToAdd = Integer.parseInt(params.getHour());
//                                    int minuteToAdd = Integer.parseInt(params.getMinute());
//
//                                    // 将小时和分钟添加到当前时间
//                                    calendar.add(Calendar.HOUR, hourToAdd);
//                                    calendar.add(Calendar.MINUTE, minuteToAdd);
//
//                                    // 获取新的时间
//                                    Date newTime = calendar.getTime();
//
//                                    fsSopLogs.setSendTime(newTime);
//
//                                } else if (params.getType() == 2) {
//
//                                    calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(params.getDay()));
//
//                                    // 解析时间字符串并设置时间
//                                    SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
//                                    try {
//                                        Date parsedTime = timeFormatter.parse(params.getTime());
//
//                                        Calendar timeCalendar = Calendar.getInstance();
//                                        timeCalendar.setTime(parsedTime);
//
//                                        // 设置新的日期的小时和分钟
//                                        calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
//                                        calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
//                                        calendar.set(Calendar.SECOND, 0); // 设置秒为0
//
//                                        fsSopLogs.setSendTime(calendar.getTime());
//                                    } catch (Exception e) {
//                                        e.printStackTrace();
//                                    }
//
//                                }
//                                // 这里可以根据需要设置 fsSopLogs 的属性
//                                fsSopLogsMapper.insertFsCourseSopLogs(fsSopLogs);
//                            }
//                        }
//
//                        successNum++;
//                    }
//
//                }
//
//            }
//
//        }

        return R.ok().put("successNum", successNum).put("failCRM", errorCRMList).put("failMiNi", errorUseridList).put("failCompany", errorCompanyList);
    }

    @Override
    public R updateQwExternalContactBindUserId(QwExternalContact qwExternalContact) {
        QwExternalContact c = new QwExternalContact();
        c.setId(qwExternalContact.getId());
        c.setFsUserId(qwExternalContact.getFsUserId());
//        adHtmlClickLogService.upload(c.getState(), AdUploadType.REGISTERED, e -> c.setUploadRegisterStatus(1));
        qwExternalContactMapper.updateQwExternalContact(c);

        //换绑营期中的
        sopUserLogsInfoMapper.updateQwExternalContactChangeUserId(qwExternalContact.getId(), qwExternalContact.getFsUserId());

        //更改看课记录(暂时不用，有点危险)
//        watchLogMapper.updateFsCourseWatchLogByQwExternalId(qwExternalContact.getId(),qwExternalContact.getFsUserId());

        return R.ok();
    }

    @Override
    public R updateQwExternalContactUnBindUserId(Long id) {

        //解除外部联系人里的
        qwExternalContactMapper.updateQwExternalContactUnBindUserId(id);

        //解除营期信息里的
        sopUserLogsInfoMapper.updateQwExternalContactUnBindUserId(id);

        return R.ok();
    }

    @Override
    public QwExternalContact getQwExternalContactDetails(QwExternalContactHParam contactHParam) {
        return qwExternalContactMapper.getQwExternalContactDetails(contactHParam);
    }


    @Autowired
    QwCompanyMapper qwCompanyMapper;

    @Override
    public void qwExternalContactSync() {
        List<QwOptionsVO> qwOptionsVOS = qwCompanyMapper.selectQwCompanyListOptionsVO();
        ExecutorService executor = Executors.newFixedThreadPool(qwOptionsVOS.size());

        logger.info("开始同步");
        for (QwOptionsVO qwOptionsVO : qwOptionsVOS) {
            String corpId = qwOptionsVO.getCorpId();
            System.out.println("同步的" + corpId);
            logger.info("同步的" + corpId);
            executor.execute(() -> qwExternalContactSyncByCorpId(corpId));
        }
        executor.shutdown();

    }

    @Override
    public List<QwExternalContactVo> selectAllQwJoinAdClickLog(Integer type) {
        return baseMapper.selectAllQwJoinAdClickLog(type);
    }

    @Override
    public List<QwExternalContactLogVo> selectAllFormAd(ConversionStatisticsParam param) {
        return baseMapper.selectAllFormAd(param);
    }

    @Override
    public R syncAddMyQwExternalContact(Long id) {
        QwUser qwUser = qwUserMapper.selectQwUserById(id);
        String userID = qwUser.getQwUserId();

        QwExternalContactListResult contactListResult = qwApiService.getExternalcontactList(qwUser.getQwUserId(), qwUser.getCorpId());
        if (contactListResult.getErrcode() == 0) {
            //企微获取的id
            List<String> externalUserid = contactListResult.getExternal_userid();
            //库里的
            List<String> qwExternalContactList = qwExternalContactMapper.selectQwExternalContactListAllNoDel(qwUser.getQwUserId(), qwUser.getCorpId());

            List<String> addList = externalUserid.stream()
                    .filter(externalUserId -> !qwExternalContactList.contains(externalUserId))
                    .collect(Collectors.toList());


            String qwUserId = qwUser.getQwUserId();
            String corpId = qwUser.getCorpId();
            Long companyId = qwUser.getCompanyId();
            for (String ext : addList) {
                String externalUserID = ext;
                QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(ext, qwUser.getQwUserId(), qwUser.getCorpId());

                if (qwExternalContact == null) {
                    QwExternalContactResult followUsers = qwApiService.getExternalcontact(ext, qwUser.getCorpId());
                    ExternalContact externalContact = followUsers.getExternal_contact();
                    List<FollowUser> followUser = followUsers.getFollow_user();
                    for (FollowUser followInfo : followUser) {
                        if (followInfo.getUserid().equals(qwUserId)) {
                            LocalDate currentDate = LocalDate.now();
                            // 获取当前系统时间 (HH:mm)
                            LocalTime localTime = LocalTime.now();
                            qwExternalContact = new QwExternalContact();
                            qwExternalContact.setUserId(qwUserId); // 设置属于用户ID
                            qwExternalContact.setExternalUserId(ext); // 设置外部联系人ID
                            qwExternalContact.setCorpId(corpId); // 设置企业ID
                            qwExternalContact.setCompanyId(companyId); // 设置公司ID
                            qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
                            qwExternalContact.setQwUserId(qwUser.getId());
                            qwExternalContact.setName(externalContact.getName()); // 设置名称
                            qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
                            qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户，2企业微信用户)
                            qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
                            qwExternalContact.setUnionid(externalContact.getUnionid());
                            qwExternalContact.setDescription(followInfo.getDescription()); // 设置描述信息
                            qwExternalContact.setRemark(followInfo.getRemark());
                            List<Tag> tags = followInfo.getTags();
                            List<String> tagIds = tags.stream()
                                    .map(Tag::getTag_id)
                                    .collect(Collectors.toList());
                            Set<String> combinedTagsSet = new HashSet<>(tagIds);
                            qwExternalContact.setTagIds(JSON.toJSONString(tagIds)); // 设置标签ID
                            qwExternalContact.setRemarkMobiles(JSON.toJSONString(followInfo.getRemark_mobiles())); // 设置备注电话号码
                            qwExternalContact.setState(followInfo.getState());
                            if (followInfo.getState() != null && !followInfo.getState().isEmpty()) {
                                String s = "way:" + corpId + ":";
                                if (followInfo.getState().contains(s)) {
                                    String wayId = followInfo.getState().substring(followInfo.getState().indexOf(s) + s.length());
                                    qwExternalContact.setWayId(Long.parseLong(wayId));
                                }
                            }
                            qwExternalContact.setCreateTime(new Date());
                            qwExternalContact.setRemarkCorpName(followInfo.getRemark_corp_name()); // 设置备注企业名称
                            qwExternalContact.setAddWay(followInfo.getAdd_way()); // 设置来源
                            qwExternalContact.setOperUserid(followInfo.getOper_userid()); // 设置oper用户ID
                            qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
                            SyncAddSendWelcome(qwExternalContact, qwUser, qwUser.getCorpId());
                            //发送好友欢迎语
//

                            QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoTagsByIdJSON(corpId, qwUser.getId());

                            QwExternalContact contact = qwExternalContact;
                            System.out.println(contact.getId());

                            if (qwAutoTags != null) {
                                QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
                                qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
                                qwAutoTagsLogs.setType(3L);
                                qwAutoTagsLogs.setQwUserid(qwUser.getId());
                                qwAutoTagsLogs.setExternalUserId(ext);

                                List<QwAutoTagsRulesTags> qwAutoTagsRulesTagsList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);
                                boolean isMatch = false;
                                //存分时段里符合条件的标签
                                Set<String> combinedTagsItem = new HashSet<>();
                                // 获取今天的星期数
                                DayOfWeek today = LocalDate.now().getDayOfWeek();
                                int todayIndex = today.getValue(); // 1: Monday, 2: Tuesday, ..., 7: Sunday
                                // 获取当前时间
                                LocalTime now = LocalTime.now();
                                // 遍历所有规则
                                String tagRemark = null;
                                for (QwAutoTagsRulesTags rulesTags : qwAutoTagsRulesTagsList) {

                                    List<String> tagsItem = rulesTags.getTags();
                                    List<Integer> week = rulesTags.getWeek();
                                    String startTime = rulesTags.getStartTime();
                                    String endTime = rulesTags.getEndTime();
                                    String remarks = rulesTags.getRemarks();

                                    // 检查今天是否在 week 集合中
                                    boolean isTodayInWeek = week.contains(todayIndex);
                                    // 转换时间字符串为 LocalTime
                                    LocalTime start = LocalTime.parse(startTime);
                                    LocalTime end = LocalTime.parse(endTime.equals("24:00") ? "23:59:59" : endTime);
                                    // 检查当前时间是否在 startTime 和 endTime 之间
                                    boolean isNowInTimeRange = !now.isBefore(start) && !now.isAfter(end);
                                    // 如果当前时间和日期匹配规则，将 tagsItem 添加到 combinedTagsSet 中
                                    if (isTodayInWeek && isNowInTimeRange) {

                                        combinedTagsSet.addAll(tagsItem);
                                        combinedTagsItem.addAll(tagsItem);
                                        isMatch = true;
                                        //如果备注不为空
                                        if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                            String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                            tagRemark = DayDate.substring(1);
                                        }
                                        //如果备注不为空
                                        if (!StringUtil.strIsNullOrEmpty(remarks)) {
                                            tagRemark = (tagRemark == null ? "" : (tagRemark + "-")) + remarks;
                                        }
                                    }
                                }
                                QwExternalContact qu = new QwExternalContact();
                                if (tagRemark != null) {
                                    qu.setRemark(tagRemark + "-" + externalContact.getName());
                                    QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                                    param.setRemark(qu.getRemark());
                                    param.setUserid(userID);
                                    param.setExternal_userid(externalUserID);
                                    QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());
                                }

                                // 如果有匹配的规则，使用 combinedTagsList
                                if (isMatch) {
                                    QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
                                    qwEditUserTagParam.setUserid(userID);
                                    qwEditUserTagParam.setExternal_userid(externalUserID);
                                    //添加标签的日志记录

                                    List<String> combinedTags = new ArrayList<>(combinedTagsItem);
                                    qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(combinedTags));
                                    qwAutoTagsLogs.setAddTime(new Date());
                                    qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
                                    qwAutoTagsLogs.setCorpId(qwUser.getCorpId());
                                    //总标签 转换回列表
                                    List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                                    // 设置标签
                                    System.out.println("标签");
                                    System.out.println(combinedTagsList);
                                    qwEditUserTagParam.setAdd_tag(combinedTagsList);

                                    // 企微加标签
                                    QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);
                                    if (qwResult.getErrcode() == 0) {
                                        qwExternalContact.setTagIds(JSON.toJSONString(combinedTagsList));
                                        qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);
                                        if (!combinedTagsSet.isEmpty()) {
                                            //分时段里符合的标签-再用来创建自动SOP
                                            QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                            qwSopAutoByTags.setCorpId(corpId);
                                            qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                            qwSopAutoByTags.setSendType(2);
                                            List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                            logger.info("分时段里符合的标签-自动SOP条件:" + qwSopAutoByTags + "|" + qwUser.getQwUserId() + "|" + ext);
                                            log.info("qwSopRuleTimeVOS:{}", qwSopRuleTimeVOS);
                                            if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                //SOP规则
                                                qwSopRuleTimeTools(qwSopRuleTimeVOS, qwUserId, qwUser, corpId, ext, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                            }
                                            //aiSop任务
//                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                            if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                            }
                                        }
                                    } else if (qwResult.getErrcode() == 45035) {
                                        //加入补偿机制
                                        insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 1, qwResult.getErrmsg());

                                    }


                                    qu.setId(contact.getId());
                                    qu.setTagIds(JSON.toJSONString(combinedTagsList));

                                    qwExternalContactMapper.updateQwExternalContact(qu);


                                } else {
                                    // 转换回列表
                                    List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                                    logger.info("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                                    try {
                                        if (!combinedTagsSet.isEmpty()) {
                                            //分时段里符合的标签-再用来创建自动SOP
                                            QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                            qwSopAutoByTags.setCorpId(corpId);
                                            qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                            qwSopAutoByTags.setSendType(2);
                                            List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                            if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                //SOP规则
                                                qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                            }
//                                            //aiSop任务
//                                            logger.info("/n 传参:" + qwSopAutoByTags);
//                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                            logger.info("/n查询到的sop:" + qwSopAiRuleTimeVOS);
//                                            if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                            }
                                        }
                                    } catch (Exception e) {

                                    }

                                }

                            } else {
                                try {
                                    // 转换回列表
                                    List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);

                                    logger.error("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);

                                    try {
                                        if (!combinedTagsSet.isEmpty()) {
                                            //分时段里符合的标签-再用来创建自动SOP
                                            QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                            qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                            qwSopAutoByTags.setCorpId(corpId);
                                            qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                            qwSopAutoByTags.setSendType(2);
                                            List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                            if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                //SOP规则
                                                qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                            }
//                                            //aiSop任务
//                                            List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                            if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                            }
                                        }
                                    } catch (Exception e) {
                                        logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                                    }

                                } catch (Exception e) {
                                    logger.error("打标签出错" + e.getMessage());
                                }

                            }


                        }
                    }


                }

            }

            //库里有 企微没有的
            List<String> notInExternalUseridList = qwExternalContactList.stream()
                    .filter(externalUserId -> !externalUserid.contains(externalUserId))
                    .collect(Collectors.toList());


            if (!notInExternalUseridList.isEmpty()) {
                DeleteQwSopParam apiParam = new DeleteQwSopParam();
                apiParam.setQwUserId(qwUser.getQwUserId());
                apiParam.setCorpId(qwUser.getCorpId());
                apiParam.setExternalUserIds(notInExternalUseridList);

                // 批量删除 qw_external_contact 表中已经删除的客户的营期以及发送记录
                sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdList(apiParam);
                sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChatList(apiParam);
                //批量删除发送记录
                qwSopLogsMapper.deleteQwSopLogsByExternalUserIdList(apiParam);
                //批量更新状态
                batchUpdateQwExternalContact(notInExternalUseridList, qwUser.getQwUserId(), qwUser.getCorpId());
            }
        }
        return R.ok();
    }


    public R syncAddMyQwExternalContactByRedis(QwUser qwUser) {
        List<String> externalUserid = redisCache.getCacheObject("qwUserIds:" + qwUser.getId());
        if (StringUtils.isNotEmpty(externalUserid) && externalUserid.size() > 0) {
            String userID = qwUser.getQwUserId();
            //库里的
            List<String> qwExternalContactList = qwExternalContactMapper.selectQwExternalContactListAllNoDel(qwUser.getQwUserId(), qwUser.getCorpId());
            List<String> addList = externalUserid.stream()
                    .filter(externalUserId -> !qwExternalContactList.contains(externalUserId))
                    .collect(Collectors.toList());
            String qwUserId = qwUser.getQwUserId();
            String corpId = qwUser.getCorpId();
            Long companyId = qwUser.getCompanyId();
            if (addList != null && addList.size() < 50) {
                for (String ext : addList) {
                    String externalUserID = ext;
                    QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(ext, qwUser.getQwUserId(), qwUser.getCorpId());

                    if (qwExternalContact == null) {
                        QwExternalContactResult followUsers = qwApiService.getExternalcontact(ext, qwUser.getCorpId());
                        ExternalContact externalContact = followUsers.getExternal_contact();
                        List<FollowUser> followUser = followUsers.getFollow_user();
                        for (FollowUser followInfo : followUser) {
                            if (followInfo.getUserid().equals(qwUserId)) {
                                LocalDate currentDate = LocalDate.now();
                                // 获取当前系统时间 (HH:mm)
                                LocalTime localTime = LocalTime.now();
                                qwExternalContact = new QwExternalContact();
                                qwExternalContact.setUserId(qwUserId); // 设置属于用户ID
                                qwExternalContact.setExternalUserId(ext); // 设置外部联系人ID
                                qwExternalContact.setCorpId(corpId); // 设置企业ID
                                qwExternalContact.setCompanyId(companyId); // 设置公司ID
                                qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
                                qwExternalContact.setQwUserId(qwUser.getId());
                                qwExternalContact.setName(externalContact.getName()); // 设置名称
                                qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
                                qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户，2企业微信用户)
                                qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
                                qwExternalContact.setUnionid(externalContact.getUnionid());
                                qwExternalContact.setDescription(followInfo.getDescription()); // 设置描述信息
                                qwExternalContact.setRemark(followInfo.getRemark());
                                List<Tag> tags = followInfo.getTags();
                                List<String> tagIds = tags.stream()
                                        .map(Tag::getTag_id)
                                        .collect(Collectors.toList());
                                Set<String> combinedTagsSet = new HashSet<>(tagIds);
                                qwExternalContact.setTagIds(JSON.toJSONString(tagIds)); // 设置标签ID
                                qwExternalContact.setRemarkMobiles(JSON.toJSONString(followInfo.getRemark_mobiles())); // 设置备注电话号码
                                qwExternalContact.setState(followInfo.getState());
                                if (followInfo.getState() != null && !followInfo.getState().isEmpty()) {
                                    String s = "way:" + corpId + ":";
                                    if (followInfo.getState().contains(s)) {
                                        String wayId = followInfo.getState().substring(followInfo.getState().indexOf(s) + s.length());
                                        qwExternalContact.setWayId(Long.parseLong(wayId));
                                    }
                                }
                                qwExternalContact.setCreateTime(new Date());
                                qwExternalContact.setRemarkCorpName(followInfo.getRemark_corp_name()); // 设置备注企业名称
                                qwExternalContact.setAddWay(followInfo.getAdd_way()); // 设置来源
                                qwExternalContact.setOperUserid(followInfo.getOper_userid()); // 设置oper用户ID
                                qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
                                SyncAddSendWelcome(qwExternalContact, qwUser, qwUser.getCorpId());
                                //发送好友欢迎语
//
                                QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoTagsByIdJSON(corpId, qwUser.getId());

                                QwExternalContact contact = qwExternalContact;
                                System.out.println(contact.getId());

                                if (qwAutoTags != null) {
                                    QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
                                    qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
                                    qwAutoTagsLogs.setType(3L);
                                    qwAutoTagsLogs.setQwUserid(qwUser.getId());
                                    qwAutoTagsLogs.setExternalUserId(ext);

                                    List<QwAutoTagsRulesTags> qwAutoTagsRulesTagsList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);
                                    boolean isMatch = false;
                                    //存分时段里符合条件的标签
                                    Set<String> combinedTagsItem = new HashSet<>();
                                    // 获取今天的星期数
                                    DayOfWeek today = LocalDate.now().getDayOfWeek();
                                    int todayIndex = today.getValue(); // 1: Monday, 2: Tuesday, ..., 7: Sunday
                                    // 获取当前时间
                                    LocalTime now = LocalTime.now();
                                    // 遍历所有规则
                                    String tagRemark = null;
                                    for (QwAutoTagsRulesTags rulesTags : qwAutoTagsRulesTagsList) {

                                        List<String> tagsItem = rulesTags.getTags();
                                        List<Integer> week = rulesTags.getWeek();
                                        String startTime = rulesTags.getStartTime();
                                        String endTime = rulesTags.getEndTime();
                                        String remarks = rulesTags.getRemarks();

                                        // 检查今天是否在 week 集合中
                                        boolean isTodayInWeek = week.contains(todayIndex);
                                        // 转换时间字符串为 LocalTime
                                        LocalTime start = LocalTime.parse(startTime);
                                        LocalTime end = LocalTime.parse(endTime.equals("24:00") ? "23:59:59" : endTime);
                                        // 检查当前时间是否在 startTime 和 endTime 之间
                                        boolean isNowInTimeRange = !now.isBefore(start) && !now.isAfter(end);
                                        // 如果当前时间和日期匹配规则，将 tagsItem 添加到 combinedTagsSet 中
                                        if (isTodayInWeek && isNowInTimeRange) {

                                            combinedTagsSet.addAll(tagsItem);
                                            combinedTagsItem.addAll(tagsItem);
                                            isMatch = true;
                                            //如果备注不为空
                                            if (rulesTags.getIsDay() != null && rulesTags.getIsDay() == 1) {
                                                String DayDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
                                                tagRemark = DayDate.substring(1);
                                            }
                                            //如果备注不为空
                                            if (!StringUtil.strIsNullOrEmpty(remarks)) {
                                                tagRemark = (tagRemark == null ? "" : (tagRemark + "-")) + remarks;
                                            }
                                        }
                                    }
                                    QwExternalContact qu = new QwExternalContact();
                                    if (tagRemark != null) {
                                        qu.setRemark(tagRemark + "-" + externalContact.getName());
                                        QwExternalContactRemarkParam param = new QwExternalContactRemarkParam();
                                        param.setRemark(qu.getRemark());
                                        param.setUserid(userID);
                                        param.setExternal_userid(externalUserID);
                                        QwExternalContactRemarkResult remarkResult = qwApiService.externalcontactRemark(param, qwExternalContact.getCorpId());
                                    }

                                    // 如果有匹配的规则，使用 combinedTagsList
                                    if (isMatch) {
                                        QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
                                        qwEditUserTagParam.setUserid(userID);
                                        qwEditUserTagParam.setExternal_userid(externalUserID);
                                        //添加标签的日志记录

                                        List<String> combinedTags = new ArrayList<>(combinedTagsItem);
                                        qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(combinedTags));
                                        qwAutoTagsLogs.setAddTime(new Date());
                                        qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
                                        qwAutoTagsLogs.setCorpId(qwUser.getCorpId());
                                        //总标签 转换回列表
                                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                                        // 设置标签
                                        qwEditUserTagParam.setAdd_tag(combinedTagsList);

                                        // 企微加标签
                                        QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);
                                        if (qwResult.getErrcode() == 0) {
                                            qwExternalContact.setTagIds(JSON.toJSONString(combinedTagsList));
                                            qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);
                                            if (!combinedTagsSet.isEmpty()) {
                                                //分时段里符合的标签-再用来创建自动SOP
                                                QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                                qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                                qwSopAutoByTags.setCorpId(corpId);
                                                qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                                qwSopAutoByTags.setSendType(2);
                                                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                                logger.info("分时段里符合的标签-自动SOP条件:" + qwSopAutoByTags + "|" + qwUser.getQwUserId() + "|" + ext);
                                                log.info("qwSopRuleTimeVOS:{}", qwSopRuleTimeVOS);
                                                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                    //SOP规则
                                                    qwSopRuleTimeTools(qwSopRuleTimeVOS, qwUserId, qwUser, corpId, ext, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                }
                                                //aiSop任务
//                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                        qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                                    }
                                            }
                                        } else if (qwResult.getErrcode() == 45035) {
                                            //加入补偿机制
                                            insertQwExternalErrRetryTool(corpId, JSON.toJSONString(qwEditUserTagParam), 1, qwResult.getErrmsg());
                                        }
                                        qu.setId(contact.getId());
                                        qu.setTagIds(JSON.toJSONString(combinedTagsList));
                                        qwExternalContactMapper.updateQwExternalContact(qu);

                                    } else {
                                        // 转换回列表
                                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                                        logger.info("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                                        try {
                                            if (!combinedTagsSet.isEmpty()) {
                                                //分时段里符合的标签-再用来创建自动SOP
                                                QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                                qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                                qwSopAutoByTags.setCorpId(corpId);
                                                qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                                qwSopAutoByTags.setSendType(2);
                                                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                    //SOP规则
                                                    qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                }
                                                //aiSop任务
//                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                        qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                                    }
                                            }
                                        } catch (Exception e) {
                                        }
                                    }
                                } else {
                                    try {
                                        // 转换回列表
                                        List<String> combinedTagsList = new ArrayList<>(combinedTagsSet);
                                        logger.error("不符合分时段条件2--看全部标签是否有符合的：" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                                        try {
                                            if (!combinedTagsSet.isEmpty()) {
                                                //分时段里符合的标签-再用来创建自动SOP
                                                QwSopAutoByTags qwSopAutoByTags = new QwSopAutoByTags();
                                                qwSopAutoByTags.setQwUserId(String.valueOf(qwUser.getId()));
                                                qwSopAutoByTags.setCorpId(corpId);
                                                qwSopAutoByTags.setTagsIdsSelectList(combinedTagsList);
                                                qwSopAutoByTags.setSendType(2);
                                                List<QwSopRuleTimeVO> qwSopRuleTimeVOS = qwSopMapper.selectQwSopAutoByTagsByForeach(qwSopAutoByTags);
                                                if (qwSopRuleTimeVOS != null && !qwSopRuleTimeVOS.isEmpty()) {
                                                    //SOP规则
                                                    qwSopRuleTimeTools(qwSopRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact, currentDate, localTime, combinedTagsList);
                                                }
                                                //aiSop任务
//                                                    List<QwSopRuleTimeVO> qwSopAiRuleTimeVOS = qwSopMapper.selectQwAiSopAutoByTagsByForeach(qwSopAutoByTags);
//                                                    if (qwSopAiRuleTimeVOS != null && !qwSopAiRuleTimeVOS.isEmpty()) {
//                                                        qwAiSopRuleTimeTools(qwSopAiRuleTimeVOS, userID, qwUser, corpId, externalUserID, externalContact.getName(), contact);
//                                                    }
                                            }
                                        } catch (Exception e) {
                                            logger.error("用自带标签入营期出错" + combinedTagsList + "|" + externalUserID + "|" + userID + "|" + corpId);
                                        }
                                    } catch (Exception e) {
                                        logger.error("打标签出错" + e.getMessage());
                                    }
                                }
                            }
                        }
                    }
                    //库里有 企微没有的
//                    List<String> notInExternalUseridList = qwExternalContactList.stream()
//                            .filter(externalUserId -> !externalUserid.contains(externalUserId))
//                            .collect(Collectors.toList());
//                    for (String s : notInExternalUseridList) {
//                        System.out.println("企微中被删除的：" + s);
//                    }
//
//                    if (!notInExternalUseridList.isEmpty()) {
//                        DeleteQwSopParam apiParam = new DeleteQwSopParam();
//                        apiParam.setQwUserId(qwUser.getQwUserId());
//                        apiParam.setCorpId(qwUser.getCorpId());
//                        apiParam.setExternalUserIds(notInExternalUseridList);
//
//                        // 批量删除 qw_external_contact 表中已经删除的客户的营期以及发送记录
//                        sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdList(apiParam);
//                        sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChatList(apiParam);
//                        //批量删除发送记录
//                        qwSopLogsMapper.deleteQwSopLogsByExternalUserIdList(apiParam);
//                        //批量更新状态
//                        batchUpdateQwExternalContact(notInExternalUseridList, qwUser.getQwUserId(), qwUser.getCorpId());
//                    }


                }


            }


        }


        return R.ok();
    }

    @Override
    public void qwExternalContactSyncAddAndDel() {
        List<QwUser> qwUser = qwUserMapper.getQwUserAllKey();
        long startTime = System.nanoTime();


        for (QwUser user : qwUser) {
            syncAddMyQwExternalContact(user.getId());
        }
        long endTime = System.nanoTime();
        long executionTime = endTime - startTime;
        double executionTimeMs = executionTime / 1_000_000.0;
        logger.info("全量智能同步" + " 执行时间: " + executionTimeMs + " 毫秒");


    }

    @Override
    public void qwExternalContactSyncAddRedis() {
        logger.info("开始外部联系人存redis");
        List<QwUser> qwUser = qwUserMapper.getQwUserAllKey();
        for (QwUser user : qwUser) {
            logger.info("外部联系人存redis：" + user.getId());
            QwExternalContactListResult contactListResult = qwApiService.getExternalcontactList(user.getQwUserId(), user.getCorpId());
            if (contactListResult.getErrcode() == 0) {
                List<String> externalUserid = contactListResult.getExternal_userid();
                if (externalUserid != null && externalUserid.size() > 0) {
                    String jsonString = JSON.toJSONString(externalUserid);
                    redisTemplate.opsForValue().set("qwUserExtIds:" + user.getCorpId() + ":" + user.getQwUserId(), jsonString);
                }
            }
        }
        logger.info("外部联系人存redis结束");

    }

    @Override
    public void qwExternalContactAddRedis() {
        logger.info("开始外部联系人存redis");
        List<QwUser> qwUser = qwUserMapper.getQwUserAllKey();
        for (QwUser user : qwUser) {
            logger.info("外部联系人存redis：" + user.getId());
            QwExternalContactListResult contactListResult = qwApiService.getExternalcontactList(user.getQwUserId(), user.getCorpId());
            if (contactListResult.getErrcode() == 0) {
                List<String> externalUserid = contactListResult.getExternal_userid();
                if (externalUserid != null && externalUserid.size() > 0) {
                    String jsonString = JSON.toJSONString(externalUserid);
                    redisTemplate.opsForValue().set("qwUserIds:" + user.getId(), jsonString);
                }
            }
        }
        logger.info("外部联系人存redis结束");

    }

    @Override
    public void qwExternalContactAddAndDelByRedis() {
        List<QwUser> qwUser = qwUserMapper.getQwUserAllKey();
        int i = 1;
        for (QwUser user : qwUser) {
            syncAddMyQwExternalContactByRedis(user);
            logger.info("外部联系人存redis：" + user.getId() + ":" + i);
            i++;
        }
    }

    @Override
    public void qwExternalContactAddCourseTag() {
        List<QwUser> qwUser = qwUserMapper.getQwUserAllKey();
        for (QwUser user : qwUser) {
            iQwTagService.AddCourseTag(user);

        }
    }


    @Override
    public List<ExternalContactListVO> externalContactPageList(ExternalContactPageListParam param) {
        return qwExternalContactMapper.selectExternalContactPageList(param);
    }

    @Override
    public ExternalContactPageVO getContactNumber(Long userId) {
        List<ExternalContactNumVO> list = qwExternalContactMapper.getContactNumber(userId);
        Map<String, Integer> map = list.stream().collect(Collectors.toMap(ExternalContactNumVO::getStatus, ExternalContactNumVO::getNum, (v1, v2) -> v1));
        ExternalContactPageVO pageVO = new ExternalContactPageVO();

        //总数
        int all = map.values().stream().mapToInt(Integer::intValue).sum();
        pageVO.setNumber(all - map.get("7"));
        //获取状态为7（被拉黑）的联系人数量
        pageVO.setBlackNum(map.get("7"));
        return pageVO;
    }

    @Override
    public ExternalContactDetailsVO getUserDetails(Long userId, Long contactId, String dateTag) {
        ExternalContactDetailsVO countAnswer = qwExternalContactMapper.getCountAnswer(userId, contactId, dateTag);
        ExternalContactDetailsVO countRedPacket = qwExternalContactMapper.getCountRedPacket(userId, contactId, dateTag);
        ExternalContactDetailsVO vo = new ExternalContactDetailsVO();
        if (countAnswer != null) {
            BeanUtils.copyProperties(countAnswer, vo);
        }
        if (countRedPacket != null) {
            BeanUtils.copyProperties(countRedPacket, vo);
        }
        return vo;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean disabledUser(String[] ids, boolean status) {
        // 不能使用自带的方法，只能写sql，额。。。。
        int result = 0;
        if(status){
            //取消禁用操作
            //查询禁用前的状态
            List<QwExternalContactBlackLog> qwExternalContactBlackLogs = qwExternalContactBlackLogMapper.selectContactLogByIds(Arrays.asList(ids));
            if(qwExternalContactBlackLogs != null && !qwExternalContactBlackLogs.isEmpty()){
                List<Map<Long,Integer>> list = new ArrayList<>();
                qwExternalContactBlackLogs.forEach(i -> {
                    Map<Long,Integer> map = new HashMap<>();
                    map.put( i.getId(), i.getStatus());
                    list.add(map);
                });
                result = qwExternalContactMapper.batchUpdateContactByIds(list);
            }
        }else {
            //禁用
            //将禁用时的状态写入到记录表中
            qwExternalContactBlackLogMapper.insertLogBySelectExternalContact(Arrays.asList(ids));
            result = qwExternalContactMapper.updateContactByIds(Arrays.asList(ids), 7);
        }
        return result > 0;
    }

    @Override
    public List<QwExternalContactVOTime> selectQwExternalContactListVOByUserIds(List<String> ids) {
        return qwExternalContactMapper.selectQwExternalContactListVOByUserIds(ids);
    }


    @Autowired
    private ICompanyCacheService companyCacheService;
    @Autowired
    private ICompanyUserCacheService companyUserCacheService;
    @Override
    public List<GetQwRepeatDataVO> getQwRepeatData(GetQwRepeatDataDTO dto) {

        List<QwExternalContact> externalContactList = qwExternalContactMapper
                .selectList(buildQuery(dto));
        List<GetQwRepeatDataVO> result = new ArrayList<>();
        for (QwExternalContact qwExternalContact : externalContactList) {
            GetQwRepeatDataVO getQwRepeatDataVO = new GetQwRepeatDataVO();
            getQwRepeatDataVO.setCompanyId(qwExternalContact.getCompanyId());
            if(qwExternalContact.getCompanyId() != null) {
                String companyName = companyCacheService.selectCompanyNameById(qwExternalContact.getCompanyId());
                getQwRepeatDataVO.setCompanyName(companyName);
            }
            getQwRepeatDataVO.setCompanyUserId(qwExternalContact.getCompanyUserId());
            if(qwExternalContact.getCompanyUserId() != null) {
                String companyUserName = companyUserCacheService.selectCompanyUserNameUserById(qwExternalContact.getCompanyUserId());
                getQwRepeatDataVO.setCompanyUserName(companyUserName);
            }
            getQwRepeatDataVO.setSaleerWx(qwExternalContact.getQwUserId());
            Date createTime = qwExternalContact.getCreateTime();
            if(createTime != null) {
                getQwRepeatDataVO.setCreateDate(DateUtils.formatDate(createTime, "yyyy-MM-dd HH:mm:ss"));
            }

            result.add(getQwRepeatDataVO);
        }

        return result;
    }

    public LambdaQueryWrapper<QwExternalContact> buildQuery(GetQwRepeatDataDTO dto){
        String corpId = dto.getCorpId();
        String externalUserID = dto.getExternalUserID();
        LambdaQueryWrapper<QwExternalContact> eq = new LambdaQueryWrapper<QwExternalContact>()
                .select(QwExternalContact::getFsUserId,
                        QwExternalContact::getCompanyId,
                        QwExternalContact::getCompanyUserId,
                        QwExternalContact::getName,
                        QwExternalContact::getQwUserId,
                        QwExternalContact::getCreateTime
                )
                .eq(QwExternalContact::getExternalUserId, externalUserID)
                .eq(QwExternalContact::getCorpId, corpId);

        return eq;
    }

    @Override
    public Integer selectQwIsRepeat(Long id) {
        return qwExternalContactMapper.selectQwIsRepeat(id);
    }

    /**
     * 根据id查询外部联系人信息
     * @param qwExternalContactId id
     * @return QwExternalContact
     */
    @Override
    public QwExternalContact getQwExternalContactDetailsById(Long qwExternalContactId) {
        return qwExternalContactMapper.getQwExternalContactDetailsById(qwExternalContactId);
    }

    //发送好友欢迎语
    void SyncAddSendWelcome(QwExternalContact qwExternalContact, QwUser qwUser, String corpId) {
        QwFriendWelcomeVO qwFriendWelcomeVO = qwFriendWelcomeMapper.selectQwFriendWelcomeByUserIdVO(qwUser.getId(), corpId);
        ArrayList<String> msgParamList = new ArrayList<>();
        if (qwFriendWelcomeVO != null) {

            // 是否分时段
            if (qwFriendWelcomeVO.getIsDayparting().equals("1")) {

                // 多个时段
                List<QwFriendWelcomeDayPart.Schedule> schedules = JSON.parseArray(qwFriendWelcomeVO.getDaypartingItemlist(), QwFriendWelcomeDayPart.Schedule.class);

                LocalTime now = LocalTime.now();
                // 获取当前是周几
                Integer week = LocalDate.now().getDayOfWeek().getValue();

                boolean match = false;

                for (QwFriendWelcomeDayPart.Schedule schedule : schedules) {
                    if (schedule.getWeek().contains(week)) {
                        LocalTime start = LocalTime.parse(schedule.getStartTime());
                        LocalTime end = LocalTime.parse(schedule.getEndTime().equals("24:00") ? "23:59:59" : schedule.getEndTime());

                        if (!now.isBefore(start) && !now.isAfter(end)) {
                            // 设置文本消息
                            msgParamList.add(schedule.getWelcomeText());

                            List<SendWelcomeMsgParam.Attachment> attachments = schedule.getAttachments();
                            // 设置所有附件 上短链
                            List<SendWelcomeMsgParam.Attachment> attachmentsMatch = attachmentsTools(attachments, qwUser, corpId, qwExternalContact.getId());

                            attachmentsMatch.forEach(item -> {
                                if (("link").equals(item.getMsgtype())) {
                                    msgParamList.add(item.getLink().getUrl());
                                }
                            });
                            match = true;
                            break; // 找到匹配项后退出整个for循环
                        }
                    }
                }

                // 如果没有找到匹配项
                if (!match) {
                    // 设置文本消息
                    msgParamList.add(qwFriendWelcomeVO.getWelcomeText());

                    // 设置所有附件
                    List<SendWelcomeMsgParam.Attachment> attachmentsAll = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                    //上短链
                    List<SendWelcomeMsgParam.Attachment> attachmentsNotMach = attachmentsTools(attachmentsAll, qwUser, corpId, qwExternalContact.getId());
                    attachmentsNotMach.forEach(item -> {
                        if (("link").equals(item.getMsgtype())) {
                            msgParamList.add(item.getLink().getUrl());
                        }

                    });
                }

            } else {

                msgParamList.add(qwFriendWelcomeVO.getWelcomeText());

                // 设置所有附件
                List<SendWelcomeMsgParam.Attachment> attachmentsAll = JSON.parseArray(qwFriendWelcomeVO.getAttachments(), SendWelcomeMsgParam.Attachment.class);
                //加短链
                List<SendWelcomeMsgParam.Attachment> attachments = attachmentsTools(attachmentsAll, qwUser, corpId, qwExternalContact.getId());
                attachments.forEach(item -> {
                    if (("link").equals(item.getMsgtype())) {
                        msgParamList.add(item.getLink().getUrl());
                    }

                });
            }
//                    if (qwUser.getAppKey()!=null){
//                        if (msgParamList!=null&&msgParamList.size()>0){
//                            for (String value : msgParamList) {
//                                QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
//                                QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
//                                sendMsgParam.setType(101003);
//                                sendMsgData.setMsg(value);
//                                sendMsgData.setOpenId(qwExternalContact.getExternalUserId());
//                                sendMsgData.setSyncKey("1");
//                                sendMsgParam.setData(sendMsgData);
//                                SendHookAIParam sendAIParam = new SendHookAIParam();
//                                sendAIParam.setCmd("aiReplyMsg");
//                                sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
//                                sendAIParam.setKey(qwUser.getAppKey());
//                                redisTemplate.opsForList().leftPush("AiMsg:"+qwUser.getAppKey(), JSON.toJSONString(sendAIParam));
//                            }
//                        }
//                    }

            System.out.println("这里最后发送好友好有欢迎语");

        }
    }

    public void qwExternalContactSyncByCorpId(String corpId) {

        logger.info("开始执行corp" + corpId);
        List<QwUser> qwUser = qwUserMapper.selectQwUserByCorp(corpId);
        for (QwUser user : qwUser) {
            logger.info(":" + corpId + ":" + user.getQwUserName());

            //同步客户信息的状态
            getContactListResult(user);

            //同步客户信息
            syncMyQwExternalContactRecursion(user, null);
            logger.info("企微凌晨同步完成" + corpId);
        }
    }
}
