package shop.alien.second.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import shop.alien.config.properties.RiskControlProperties;
import shop.alien.entity.SecondVideoTask;
import shop.alien.entity.second.*;
import shop.alien.entity.second.enums.RiskControlRuleTypeEnum;
import shop.alien.entity.second.enums.SecondGoodsStatusEnum;
import shop.alien.entity.second.enums.SecondUserCreditScoreEnum;
import shop.alien.entity.second.vo.*;
import shop.alien.entity.store.*;
import shop.alien.entity.store.vo.LifeUserVo;
import shop.alien.entity.store.vo.WebSocketVo;
import shop.alien.mapper.*;
import shop.alien.mapper.second.*;
import shop.alien.second.feign.AlienStoreFeign;
import shop.alien.second.service.*;
import shop.alien.second.util.SecondHandSearchAiUtils;
import shop.alien.util.common.Constants;
import shop.alien.util.common.VideoUtils;
import shop.alien.util.common.safe.*;
import shop.alien.util.type.LifeCollectIdentityQuery;
import shop.alien.util.type.LifeNoticeUtil;
import shop.alien.second.util.SecondLikeRecordIdentityHelper;
import shop.alien.second.util.SecondLikeRecordIdentityHelper.SecondLikerScope;

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

/**
 * 二手商品服务实现类
 * 提供二手商品的增删改查、审核、上下架、风控等相关业务逻辑处理
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, SecondGoods> implements SecondGoodsService {


    /**
     * 视频审核功能是否启用的配置项
     */
    @Value("${video.moderation.enabled}")
    private boolean videoModerationEnabled;

    /**
     * 视频审核失败时是否阻塞商品发布的配置项
     */
    @Value("${video.moderation.block-on-failure}")
    private boolean videoModerationBlockOnFailure;

    /**
     * 视频审核服务，用于处理商品中视频内容的审核
     */
    private final VideoModerationService videoModerationService;

    /**
     * 视频工具类，提供视频相关操作功能
     */
    private final VideoUtils videoUtils;

    /**
     * 文本审核工具，用于审核商品标题、描述等文本内容
     */
    private final TextModerationUtil textModerationUtil;

    /**
     * 图片审核工具，用于审核商品图片内容
     */
    private final ImageModerationUtil imageModerationUtil;

    /**
     * 二手商品Mapper，用于操作二手商品数据表
     */
    private final SecondGoodsMapper secondGoodsMapper;

    /**
     * 二手商品审核Mapper，用于操作二手商品审核记录表
     */
    private final SecondGoodsAuditMapper secondGoodsAuditMapper;

    /**
     * 用户信息Mapper，用于操作用户信息表
     */
    private final LifeUserMapper lifeUserMapper;

    /**
     * 公告Mapper，用于操作公告信息表
     */
    private final LifeNoticeMapper lifeNoticeMapper;

    private final LifeNoticeUtil lifeNoticeUtil;

    /**
     * 店铺图片Mapper，用于操作图片信息表
     */
    private final StoreImgMapper storeImgMapper;

    /**
     * 黑名单Mapper，用于操作用户黑名单表
     */
    private final LifeBlacklistMapper lifeBlacklistMapper;

    /**
     * 点赞记录Mapper，用于操作点赞记录表
     */
    private final LifeLikeRecordMapper lifeLikeRecordMapper;

    private final SecondLikeRecordIdentityHelper lifeLikeIdentityHelper;

    /**
     * 收藏Mapper，用于操作收藏记录表
     */
    private final LifeCollectMapper lifeCollectMapper;

    /**
     * 店铺服务Feign接口，用于跨服务调用
     */
    private final AlienStoreFeign alienStoreFeign;

    /**
     * 商品操作历史记录Mapper，用于操作商品操作记录表
     */
    private final SecondGoodsRecordMapper secondGoodsRecordMapper;

    /**
     * 二手交易记录Mapper，用于操作二手交易记录表
     */
    @Autowired
    private SecondTradeRecordMapper secondTradeRecordMapper;

    /**
     * 用户违规举报Mapper，用于操作用户举报记录表
     */
    private final LifeUserViolationMapper lifeUserViolationMapper;

    /**
     * 字典Mapper，用于操作数据字典表
     */
    private final StoreDictionaryMapper storeDictionaryMapper;

    /**
     * 平台二手交易服务，提供二手交易相关业务逻辑
     */
    private final PlatformSecondTradeService platformSecondTradeService;

    /**
     * 二手搜索 AI 接口工具，用于调用 life-manager 智能搜索
     */
    private final SecondHandSearchAiUtils secondHandSearchAiUtils;

    /**
     * 风控配置属性，包含各种风控规则的配置参数
     */
    @Autowired
    private RiskControlProperties riskControlProperties;

    /**
     * 风控服务，提供风控相关业务逻辑处理
     */
    private final RiskControlService riskControlService;

    private final SecondGoodsAuditService secondGoodsAuditService;

    private final SecondUserCreditMapper secondUserCreditMapper;
    private final SecondUserCreditRecordMapper secondUserCreditRecordMapper;

    /**
     * 获取商品操作记录详情（管理后台使用）
     * @param recordId 商品操作记录ID
     * @return 商品操作记录详情VO对象
     */
    /**
     * 获取商品操作记录详情（管理后台使用）
     * @param recordId 商品操作记录ID
     * @return 商品操作记录详情VO对象
     */
    @Override
    public SecondGoodsRecordDetailVo getAdminGoodsRecordDetail(Integer recordId) {
        // 1. 获取商品操作记录基本信息
        QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("sg.id", recordId);
        SecondGoodsRecord record = secondGoodsRecordMapper.selectGoodsRecordById(queryWrapper);
        if (record == null) {
            return null;
        }

        // 2. 转换为VO对象
        SecondGoodsRecordDetailVo detailVo = SecondGoodsRecordDetailVo.fromRecord(record);

        if (record.getUserId() != null){
            // 获取联系人
            QueryWrapper<LifeUser> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.lambda()
                    .eq(LifeUser::getId, record.getUserId())
                    .eq(LifeUser::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED);
            LifeUser user = lifeUserMapper.selectOne(userQueryWrapper);

            detailVo.setUserName(user.getUserName());
            detailVo.setUserPhone(user.getUserPhone());
        }


        // 3. 获取商品图片列表
        QueryWrapper<StoreImg> imageQueryWrapper = new QueryWrapper<>();
        imageQueryWrapper.lambda()
                .eq(StoreImg::getStoreId, record.getId())
                .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_RECORD)
                .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                .orderByAsc(StoreImg::getImgSort);
        List<StoreImg> imageList = storeImgMapper.selectList(imageQueryWrapper);

        // 4. 提取图片URL列表
        if (CollectionUtil.isNotEmpty(imageList)) {
            List<String> imageUrls = imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .collect(Collectors.toList());
            List<Map<String, Object>> imgList = processReportImages(imageList,2);
            detailVo.setImgList(imgList);
            detailVo.setImageUrls(imageUrls);
        }

        return detailVo;
    }

    /**
     * 获取商品详情（管理后台使用）
     * @param goodsId 商品ID
     * @return 商品详情VO对象
     * @throws Exception 处理过程中可能抛出的异常
     */
    /**
     * 获取商品详情（管理后台使用）
     * @param goodsId 商品ID
     * @return 商品详情VO对象
     * @throws Exception 处理过程中可能抛出的异常
     */
    @Override
    public SecondGoodsDetailVo getAdminGoodsDetail(Integer goodsId) throws Exception {
        // 基本信息
        SecondGoodsDetailVo detailVo =  dealSecondGoodsInfo(goodsId);
        // 3. 获取商品操作记录集合
        QueryWrapper<SecondGoodsRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(SecondGoodsRecord::getGoodsId, goodsId)
                .orderByDesc(SecondGoodsRecord::getCreatedTime);
        List<SecondGoodsRecord> operationRecords = secondGoodsRecordMapper.selectdminGoodsList(recordQueryWrapper);
        detailVo.setOperationRecords(operationRecords);

        // 4. 获取商品交易记录集合
        QueryWrapper<SecondTradeRecord> tradeQueryWrapper = new QueryWrapper<>();
        tradeQueryWrapper.eq("goods_id", goodsId)
                .orderByDesc("created_time");
        List<SecondTradeRecord> tradeRecords = secondTradeRecordMapper.selectList(tradeQueryWrapper);
        // 处理交易步骤 调取 PlatformSecondTradeServiceImpl.getOperationJsonList
        List<SecondTradeRecordVo> secondTradeRecordVos = Lists.newArrayList();
        if (CollectionUtil.isNotEmpty(tradeRecords)){
            for (SecondTradeRecord tradeRecord : tradeRecords) {
                SecondTradeRecordVo secondTradeRecordVo = new SecondTradeRecordVo();
                BeanUtils.copyProperties(tradeRecord, secondTradeRecordVo);
                // 交易节点
                secondTradeRecordVo.setOperationJsonList(platformSecondTradeService.getOperationJsonList(tradeRecord.getId()));
                // 获取联系人
                QueryWrapper<LifeUser> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper.lambda()
                        .eq(LifeUser::getId, secondTradeRecordVo.getBuyerId())
                        .eq(LifeUser::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED);
                LifeUser user = lifeUserMapper.selectOne(userQueryWrapper);
                secondTradeRecordVo.setUserName(user.getUserName());
                secondTradeRecordVo.setUserPhone(user.getUserPhone());
                secondTradeRecordVos.add(secondTradeRecordVo);
            }
        }
        detailVo.setTradeRecords(secondTradeRecordVos);

        // 5. 获取商品举报集合
        QueryWrapper<LifeUserViolation> reportQueryWrapper = new QueryWrapper<>();
        reportQueryWrapper.lambda()
                .eq(LifeUserViolation::getGoodsId, goodsId)
                .eq(LifeUserViolation::getReportContextType, "4") // 4：二手商品
                .orderByDesc(LifeUserViolation::getCreatedTime);
        List<LifeUserViolation> reports = lifeUserViolationMapper.selectList(reportQueryWrapper);

        // 转换举报信息为SecondReportingVo
        List<SecondReportingVo> reportingVos = convertReportsToVos(reports);
        detailVo.setReports(reportingVos);

        return detailVo;
    }

    /**
     * 处理商品信息（管理后台使用）
     * @param goodsId 商品ID
     * @return 商品详情VO对象
     */
    @Override
    public SecondGoodsDetailVo dealSecondGoodsInfo(Integer goodsId) {
        SecondGoodsDetailVo SecondGoodsDetailVo = new SecondGoodsDetailVo();
        QueryWrapper<SecondGoodsVo> goodsVoQueryWrapper = new QueryWrapper<>();
        goodsVoQueryWrapper
                .eq("sg.id", goodsId);
        // 1. 获取商品基本信息
        SecondGoodsVo goodsInfo = secondGoodsMapper.getGoodsById(goodsVoQueryWrapper);

        // 2. 获取商品图片列表
        QueryWrapper<StoreImg> imageQueryWrapper = new QueryWrapper<>();
        imageQueryWrapper.lambda()
                .eq(StoreImg::getStoreId, goodsId)
                .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS)
                .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                .orderByAsc(StoreImg::getImgSort);
        List<StoreImg> imageList = storeImgMapper.selectList(imageQueryWrapper);
        // 提取图片URL列表
        if (CollectionUtil.isNotEmpty(imageList)) {
            List<String> imageUrls = imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .collect(Collectors.toList());
            List<Map<String, Object>> imgList = processReportImages(imageList,2);
            goodsInfo.setImgList(imgList);
            goodsInfo.setImgUrl(imageUrls);
        }
        SecondGoodsDetailVo.setGoodsInfo(goodsInfo);
        return SecondGoodsDetailVo;
    }

    /**
     * 处理商品记录信息
     * @param goodsId 商品ID
     * @return 商品VO对象
     */
    @Override
    public SecondGoodsVo dealSecondGoodsRecordInfo(Integer goodsId) {
        QueryWrapper<SecondGoodsVo> goodsVoQueryWrapper = new QueryWrapper<>();
        goodsVoQueryWrapper.eq("sg.id", goodsId);
        // 1. 获取商品基本信息
        SecondGoodsVo goodsInfo = secondGoodsMapper.getGoodsRecordById(goodsVoQueryWrapper);

        // 2. 获取商品图片列表
        QueryWrapper<StoreImg> imageQueryWrapper = new QueryWrapper<>();
        imageQueryWrapper.lambda()
                .eq(StoreImg::getStoreId, goodsId)
                .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_RECORD)
                .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                .orderByAsc(StoreImg::getImgSort);
        List<StoreImg> imageList = storeImgMapper.selectList(imageQueryWrapper);
        // 提取图片URL列表
        if (CollectionUtil.isNotEmpty(imageList)) {
            List<String> imageUrls = imageList.stream()
                    .map(StoreImg::getImgUrl)
                    .collect(Collectors.toList());
            List<Map<String, Object>> imgList = processReportImages(imageList,2);
            goodsInfo.setImgList(imgList);
            goodsInfo.setImgUrl(imageUrls);
        }
        return goodsInfo;
    }

    /**
     * 记录商品操作历史
     * @param goods 商品信息
     * @param operationName 操作名称
     */
    @Override
    public void recordGoodsOperation(SecondGoods goods,String operationName) {
        try {
            log.warn("开始创建操作历史: {},{} ", goods,operationName);
            SecondGoodsRecord record = new SecondGoodsRecord();
            record.setOperationName(operationName);
            record.setGoodsId(goods.getId());
            record.setUserId(goods.getUserId());
            record.setTitle(goods.getTitle());
            record.setDescription(goods.getDescription());
            // 价格转换
            if (goods.getAmount() != null) {
                record.setPrice(goods.getAmount());
            } else if (goods.getPrice() != null && !goods.getPrice().isEmpty()) {
                try {
                    record.setPrice(new BigDecimal(goods.getPrice()));
                } catch (Exception e) {
                    log.warn("转换商品价格时出错: {}", e.getMessage());
                }
            }
            record.setPosition(goods.getPosition());
            record.setLikeCount(goods.getLikeCount());
            record.setCollectCount(goods.getCollectCount());
            record.setCategoryOneId(goods.getCategoryOneId());
            record.setCategoryTwoId(goods.getCategoryTwoId());
            record.setLabel(goods.getLabel());
            record.setTopic(goods.getTopic());
            record.setTradeId(goods.getTradeId());
            record.setReleaseTime(goods.getReleaseTime());
            record.setGoodsStatus(goods.getGoodsStatus());
            record.setFailedReason(goods.getFailedReason());
            record.setHomeImage(goods.getHomeImage());
            record.setVideoTaskId(goods.getVideoTaskId());
            record.setVideoFirstFrame(goods.getVideoFirstFrame());
            record.setDeleteFlag(goods.getDeleteFlag());
            record.setCreatedTime(goods.getCreatedTime());
            record.setCreatedUserId(goods.getCreatedUserId());
            record.setUpdatedTime(goods.getUpdatedTime());
            record.setUpdatedUserId(goods.getUpdatedUserId());
            record.setAddressText(goods.getAddressText());

            secondGoodsRecordMapper.insert(record);
            log.warn("创建操作历史结束: {} ", record);
            // 保存图片信息
            saveRecordGoodsImages(record);
        } catch (Exception e) {
            log.error("记录商品操作历史时发生异常", e);
        }
    }


    /**
     * 保存二手商品记录图片类型信息
     *
     * @param record 保存后的商品记录
     */
    /**
     * 保存二手商品记录图片类型信息
     *
     * @param record 保存后的商品记录
     */
    private void saveRecordGoodsImages(SecondGoodsRecord record ) {

        log.info("创建操作历图片史开始: {} ", record);
        // 获取商品图片列表
        QueryWrapper<StoreImg> query = new QueryWrapper<>();
        query.lambda().eq(StoreImg::getStoreId, record.getGoodsId())
                .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS);
        List<StoreImg> storeImgs = storeImgMapper.selectList(query);
        // 保存前先把原有的删除
        storeImgs.forEach(storeImgModel -> {
            StoreImg storeImg = new StoreImg();
            storeImg.setStoreId(record.getId());
            storeImg.setImgType(Constants.ImageType.SECOND_HAND_RECORD);
            storeImg.setImgSort(storeImgModel.getImgSort());
            storeImg.setImgDescription("二手商品记录图片类型");
            storeImg.setDeleteFlag(Constants.DeleteFlag.NOT_DELETED);
            storeImg.setCreatedTime(new Date());
            storeImg.setUpdatedTime(new Date());
            storeImg.setCreatedUserId(1);
            storeImg.setUpdatedUserId(1);
            storeImg.setImgUrl(storeImgModel.getImgUrl());
            // 保存图片 插入store_img数据库
            storeImgMapper.insert(storeImg);
            log.info("创建操作历图片结束: {} ", storeImg);
        });
    }

    /**
     * 批量转换举报信息为SecondReportingVo对象
     * @param reports 举报信息列表
     * @return SecondReportingVo列表
     */
    /**
     * 批量转换举报信息为SecondReportingVo对象
     * @param reports 举报信息列表
     * @return SecondReportingVo列表
     */
    private List<SecondReportingVo> convertReportsToVos(List<LifeUserViolation> reports) {
        List<SecondReportingVo> reportingVos = new ArrayList<>();

        // 获取所有相关的举报类型字典信息
        List<String> dictTypes = reports.stream()
                .map(LifeUserViolation::getDictType)
                .distinct()
                .collect(Collectors.toList());

        List<Integer> dictIds = reports.stream()
                .map(LifeUserViolation::getDictId)
                .distinct()
                .collect(Collectors.toList());

        Map<String, StoreDictionary> dictMap = new HashMap<>();
        if (!dictTypes.isEmpty() && !dictIds.isEmpty()) {
            QueryWrapper<StoreDictionary> dictQueryWrapper = new QueryWrapper<>();
            dictQueryWrapper.lambda()
                    .in(StoreDictionary::getTypeName, dictTypes)
                    .in(StoreDictionary::getDictId, dictIds);
            List<StoreDictionary> dicts = storeDictionaryMapper.selectList(dictQueryWrapper);
            dictMap = dicts.stream()
                    .collect(Collectors.toMap(
                            d -> d.getTypeName() + "_" + d.getDictId(),
                            d -> d));
        }

        // 转换每个举报信息
        for (LifeUserViolation report : reports) {
            SecondReportingVo reportingVo = new SecondReportingVo();
            BeanUtils.copyProperties(report, reportingVo);

            // 查询用户表 根据举报用户类型和举报用户ID 查询 life_user 表 user_phone
            LifeUser reporter = lifeUserMapper.selectById(report.getReportingUserId());
            if (reporter != null) {
                // 处理举报用户名称  life_user 表 user_name
                reportingVo.setReportingUserName(reporter.getUserName());
                // 处理联系方式  life_user 表 user_phone
                reportingVo.setReportingUserPhone(reporter.getUserPhone());
            }

            // 基本信息
            reportingVo.setId(report.getId());
            // 处理状态
            reportingVo.setProcessingStatus(report.getProcessingStatus());

            // 举报时间
            reportingVo.setReportingTime(report.getCreatedTime());
            // 举报内容补充
            reportingVo.setReportingContext(report.getOtherReasonContent());
//            reportingVo.setFeedbackTime(report.getCreatedTime());
//            reportingVo.setFeedbackContext("平台已受理，感谢您的反馈！");

            // 获取举报类型信息
            StoreDictionary storeDictionary = dictMap.get(report.getDictType() + "_" + report.getDictId());
            // 举报类型
            reportingVo.setReportContextType(storeDictionary.getDictDetail());
            // 二手商品举报
            SecondGoods secondGoods = secondGoodsMapper.selectById(report.getBusinessId());
            if (secondGoods != null) {
                reportingVo.setPrice(secondGoods.getPrice() != null ?
                        secondGoods.getPrice().toString() : null);
                reportingVo.setHomeImage(secondGoods.getHomeImage());
                reportingVo.setTitle(secondGoods.getTitle());
                reportingVo.setDescription(secondGoods.getDescription());
            }
            // 处理举报凭证图片
            // 查询图片信息
            LambdaQueryWrapper<StoreImg> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreImg::getStoreId, report.getId());
            wrapper.eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_REPORT);
            List<StoreImg> imgList = storeImgMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(imgList)) {
                // 提取图片URL
                List<String> urlList = imgList.stream()
                        .map(StoreImg::getImgUrl)
                        .collect(Collectors.toList());
                reportingVo.setImgList(processReportImages(imgList,1));
            }

            reportingVos.add(reportingVo);
        }

        return reportingVos;
    }

    /**
     * 处理举报凭证图片
     * @param imageList 图片URL集合
     * @param type  类型 1-举报 2-商品
     * @return 图片列表
     */
    /**
     * 处理举报凭证图片
     * @param imageList 图片URL集合
     * @param type  类型 1-举报 2-商品
     * @return 图片列表
     */
    private List<Map<String, Object>> processReportImages(List<StoreImg> imageList, Integer type) {
        List<Map<String, Object>> list = new ArrayList<>();
        List<String> videoFileType = Arrays.asList("mp4", "avi", "flv", "mkv", "rmvb", "wmv", "3gp", "mov");

        for (StoreImg img : imageList) {
            // 过滤掉imgUrl为空或null的记录
            if (img == null || StringUtils.isBlank(img.getImgUrl())) {
                continue;
            }

            Map<String, Object> map = new HashMap<>();
            String fileType = img.getImgUrl().substring(img.getImgUrl().lastIndexOf(".") + 1);
            if (videoFileType.contains(fileType.toLowerCase())) {
                map.put("type", "video");
            } else {
                map.put("type", "image");
            }
            map.put("imgUrl", img.getImgUrl());
            if (type == 1) {
                map.put("videoUrl", img.getImgUrl());
            }
            list.add(map);
        }

        return list;
    }

    /**
     * 校验用户是否具备发布商品资格
     */
    @Override
    public String validatePublishQualification(Integer userId) {
        if (userId == null) {
            return "用户未登录，无法发布商品";
        }
        LifeUser user = lifeUserMapper.selectById(userId);
        if (user == null) {
            return "用户不存在";
        }
        if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard())) {
            return "请先完成实名认证后再发布商品";
        }
        LambdaQueryWrapper<SecondUserCredit> creditWrapper = new LambdaQueryWrapper<>();
        creditWrapper.eq(SecondUserCredit::getUserId, userId)
                .eq(SecondUserCredit::getDeleteFlag, 0);
        SecondUserCredit userCredit = secondUserCreditMapper.selectOne(creditWrapper);
        int userPoints = userCredit != null && userCredit.getUserPoints() != null ? userCredit.getUserPoints() : 0;
        if (userPoints < 100) {
            return "信用分不足100，无法发布商品";
        }
        return null;
    }

    /**
     * 保存商品为草稿状态
     * @param goods 商品实体
     * @return 是否成功保存
     */
    @Override
    public boolean saveAsDraft(SecondGoodsVo goods) {
        // 设置商品状态为草稿
        goods.setGoodsStatus(SecondGoodsStatusEnum.DRAFT.getCode());
        if (null != goods.getId()){
            // 更新商品基本信息
            if (!updateById(goods)) {
                return false; // 保存失败直接返回
            }
        }else {
            // 保存商品基本信息
            if (!save(goods)) {
                return false; // 保存失败直接返回
            }
        }
        // 获取保存后的商品ID，用于后续业务处理
        Integer savedGoodsId = goods.getId();
        if (savedGoodsId == null) {
            return false; // 如果获取不到ID，视为操作失败
        }
        // 保存商品图片信息
        return saveStoreImages(savedGoodsId, goods);
    }


    /**
     * 创建商品基本信息
     * @param goodsDTO 商品信息DTO
     * @param editFlag 编辑标识 1-编辑 0-新增
     * @return 是否创建成功
     * @throws Exception 处理过程中可能抛出的异常
     */
    @Override
    public boolean createBasicInfo(SecondGoodsVo goodsDTO,Integer editFlag) throws Exception {
        try {
            // 实现基本信息保存逻辑
            SecondGoods goods = new SecondGoods();
            BeanUtils.copyProperties(goodsDTO, goods);

            boolean saveResult;
            if (editFlag == 1) {
                goods.setId(goodsDTO.getId());
//                goods = secondGoodsMapper.selectById(goodsDTO.getId());
                // 保存商品基本信息
                saveResult = updateById(goods);
            } else {
                // 保存商品基本信息
                saveResult = save(goods);
            }

            if (!saveResult) {
                return false; // 保存失败直接返回
            }

            // 获取保存后的商品ID，用于后续业务处理
            Integer savedGoodsId = goods.getId();
            if (savedGoodsId == null) {
                return false; // 如果获取不到ID，视为操作失败
            }

            // 保存商品图片信息
            if (!saveStoreImages(savedGoodsId, goodsDTO )) {
                return false;
            }
            goods = secondGoodsMapper.selectById(savedGoodsId);
            // 审核不通过时已设置状态，返回成功但标记为审核失败
            performContentReview(goodsDTO, goods);

            return true;
        } catch (Exception e) {
            // 记录异常日志
            log.error("创建或更新二手商品基本信息时发生异常", e);
            return false;
        }
    }


    /**
     * 检查用户在24小时内 频繁修改发布商品的数量是否超过限制
     * @param goods  用户ID,商品ID
     * @return 是否未超过限制
     */
    /**
     * 检查用户在24小时内 频繁修改发布商品的数量是否超过限制
     * @param goods  用户ID,商品ID
     * @return 是否未超过限制
     */
    private boolean checkUserPublishLimit(SecondGoods goods) {
        // 获取配置的阈值
        int publishLimit = riskControlProperties.getTradeFraud().getPublishCount24h();
        // 时间窗口（小时）
        int timeWindowHours = riskControlProperties.getTradeFraud().getTimeWindowHours();

        // 计算时间窗口前的时间
        Date timeWindowStart = new Date(System.currentTimeMillis() - timeWindowHours * 60 * 60 * 1000L);

        // 查询用户在24小时内发布的商品数量
        LambdaQueryWrapper<SecondGoodsRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecondGoodsRecord::getUserId, goods.getUserId())
                .eq(SecondGoodsRecord::getGoodsId, goods.getId())
                .ge(SecondGoodsRecord::getReleaseTime, timeWindowStart)
                .in(SecondGoodsRecord::getGoodsStatus,
                        SecondGoodsStatusEnum.LISTED.getCode(),
                        SecondGoodsStatusEnum.SOLD.getCode());
        // 获取发布
        List<SecondGoodsRecord> secondGoodsRecordList = secondGoodsRecordMapper.selectList(queryWrapper);
        // 提取商品id集合
        List<Integer> secondGoodsRecordIdList = secondGoodsRecordList.stream().map(SecondGoodsRecord::getId).collect(Collectors.toList());
        // 转成json
        String json = JSON.toJSONString(secondGoodsRecordIdList);
        // 获取实际发布数量
        int sameCategoryCount = secondGoodsRecordList.size();
        // 如果发布数量超过限制，记录风控数据
        if (sameCategoryCount > publishLimit) {
            // "异常发布-同类商品发布频率"
//            riskControlService.recordRiskControlData(goods.getUserId(), RiskControlRuleTypeEnum.TRANSACTION_FRAUD.getRuleType(), RiskControlRuleTypeEnum.TRANSACTION_FRAUD.getDescription(), goods.getId().toString(),json);

            String startDate = LocalDateTime.now().minusHours(24L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String endDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            List<SecondUserCreditRecord> num = secondUserCreditRecordMapper.selectList(new LambdaQueryWrapper<SecondUserCreditRecord>()
                    .eq(SecondUserCreditRecord::getUserId, goods.getUserId())
                    .eq(SecondUserCreditRecord::getPointsType, SecondUserCreditScoreEnum.TRADING_FRAUD.getCode())
                    .ge(SecondUserCreditRecord::getCreatedTime, startDate)
                    .le(SecondUserCreditRecord::getCreatedTime, endDate));
            if (num.size() <= 0) {
                LambdaQueryWrapper<SecondUserCredit> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(SecondUserCredit::getUserId, goods.getUserId())
                        .orderByDesc(SecondUserCredit::getCreatedTime).last("LIMIT 1");
                SecondUserCredit secondUserCredit = secondUserCreditMapper.selectOne(queryWrapper1);
                int score = secondUserCredit.getUserPoints() + SecondUserCreditScoreEnum.TRADING_FRAUD.getScore();
                secondUserCredit.setUserPoints(score);
                secondUserCreditMapper.updateById(secondUserCredit);

                SecondUserCreditRecord record = new SecondUserCreditRecord();
                record.setUserId(goods.getUserId());
                record.setPointsType(SecondUserCreditScoreEnum.TRADING_FRAUD.getCode());
                record.setPoints(SecondUserCreditScoreEnum.TRADING_FRAUD.getScore());
                record.setCurrentScoreCount(score);
                record.setCreatedTime(new Date());
                secondUserCreditRecordMapper.insert(record);

                // 小于100分封禁用户
                if (score < 100) {
                    LifeUser user = new LifeUser();
                    user.setId(goods.getUserId());
                    user.setIsBanned(1);
                    lifeUserMapper.updateById(user);
                }
            }

            return false;
        }
        return true;
    }

    /**
     * 检查用户在指定时间窗口内发布同类商品的数量是否超过限制
     * @param goods 商品信息
     * @return 是否未超过限制
     */
    /**
     * 检查用户在指定时间窗口内发布同类商品的数量是否超过限制
     * @param goods 商品信息
     * @return 是否未超过限制
     */
    private boolean checkUserPublishSameCategoryLimit(SecondGoods goods) {
        // 获取配置的阈值
        int sameCategoryLimit = riskControlProperties.getAbnormalPublish().getSameCategoryCount24h();
        int timeWindowHours = riskControlProperties.getAbnormalPublish().getTimeWindowHours();

        // 计算时间窗口前的时间
        Date timeWindowStart = new Date(System.currentTimeMillis() - timeWindowHours * 60 * 60 * 1000L);

        // 查询用户在时间窗口内发布同类商品的数量
        LambdaQueryWrapper<SecondGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecondGoods::getUserId, goods.getUserId())
                .eq(SecondGoods::getCategoryOneId, goods.getCategoryOneId())
                .eq(SecondGoods::getCategoryTwoId, goods.getCategoryTwoId())
                .ge(SecondGoods::getReleaseTime, timeWindowStart)
                .in(SecondGoods::getGoodsStatus,
                        SecondGoodsStatusEnum.LISTED.getCode(),
                        SecondGoodsStatusEnum.SOLD.getCode());

        // 获取发布
        List<SecondGoods> secondGoodsList = list(queryWrapper);
        // 提取商品id集合
        List<Integer> secondGoodsIds = secondGoodsList.stream().map(SecondGoods::getId).collect(Collectors.toList());
        // 转成json
        String json = JSON.toJSONString(secondGoodsIds);
        // 获取实际发布数量
        int sameCategoryCount = secondGoodsList.size();
        // 如果发布数量超过限制，记录风控数据
        if (sameCategoryCount > sameCategoryLimit) {
            // "异常发布-同类商品发布频率"
//            riskControlService.recordRiskControlData(goods.getUserId(), RiskControlRuleTypeEnum.ABNORMAL_PUBLISH.getRuleType(), RiskControlRuleTypeEnum.ABNORMAL_PUBLISH.getDescription(), goods.getId().toString(),json);

            String startDate = LocalDateTime.now().minusHours(24L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String endDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            List<SecondUserCreditRecord> num = secondUserCreditRecordMapper.selectList(new LambdaQueryWrapper<SecondUserCreditRecord>()
                    .eq(SecondUserCreditRecord::getUserId, goods.getUserId())
                    .eq(SecondUserCreditRecord::getPointsType, SecondUserCreditScoreEnum.ABNORMAL_RELEASE.getCode())
                    .ge(SecondUserCreditRecord::getCreatedTime, startDate)
                    .le(SecondUserCreditRecord::getCreatedTime, endDate));
            if (num.size() <= 0) {
                LambdaQueryWrapper<SecondUserCredit> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(SecondUserCredit::getUserId, goods.getUserId())
                        .orderByDesc(SecondUserCredit::getCreatedTime).last("LIMIT 1");
                SecondUserCredit secondUserCredit = secondUserCreditMapper.selectOne(queryWrapper1);
                int score = secondUserCredit.getUserPoints() + SecondUserCreditScoreEnum.ABNORMAL_RELEASE.getScore();
                secondUserCredit.setUserPoints(score);
                secondUserCreditMapper.updateById(secondUserCredit);

                SecondUserCreditRecord record = new SecondUserCreditRecord();
                record.setUserId(goods.getUserId());
                record.setPointsType(SecondUserCreditScoreEnum.ABNORMAL_RELEASE.getCode());
                record.setPoints(SecondUserCreditScoreEnum.ABNORMAL_RELEASE.getScore());
                record.setCurrentScoreCount(score);
                record.setCreatedTime(new Date());
                secondUserCreditRecordMapper.insert(record);

                // 小于100分封禁用户
                if (score < 100) {
                    LifeUser user = new LifeUser();
                    user.setId(goods.getUserId());
                    user.setIsBanned(1);
                    lifeUserMapper.updateById(user);
                }
            }


            return false;
        }
        return true;
    }

    /**
     * 执行商品发布风控检查
     * @param goods 商品信息
     */
    @Override
    public void performPublishRiskCheck(SecondGoods goods) {
        // 检查用户是否在24小时内发布同类商品超过阈值
        if (!checkUserPublishSameCategoryLimit(goods)) {
            log.warn("用户 {} 在24小时内发布同类商品次数超过限制", goods.getUserId());
        }

        // 检查用户是否在24小时内发布商品超过阈值
        if (!checkUserPublishLimit(goods)) {
            log.warn("用户 {} 在24小时内发布商品次数超过限制", goods.getUserId());
        }
    }

    /**
     * 执行内容审核
     * @param goodsDTO 商品信息
     * @param goods 商品实体
     */
    private void performContentReview(SecondGoodsVo goodsDTO, SecondGoods goods) throws Exception {
        // 图片审核
        boolean imageAuditResult = performImageReviews(goods, goodsDTO);
        /* 添加截断，避免审核结果过多，三个顺序执行，第一个失败后直接返回，以此类推 */

        // 审核失败。直接返回
        if (!imageAuditResult) {
            // 图片审核不通过，记录操作历史
            recordGoodsOperation(goods,"图片审核失败");
            return;
        }

        // 文本审核
        boolean textAuditResult = performTextReview(goods, goodsDTO);
        // 审核失败。直接返回
        if (!textAuditResult) {
            // 文本审核不通过，记录操作历史
            recordGoodsOperation(goods,"文本审核失败");
            return;
        }

        // 视频审核
//        List<String> taskIds = performVideoReviews(goods, goodsDTO);
//
//        // 如果成功提交了视频审核任务，设置商品状态为审核中
//        if (!taskIds.isEmpty()) {
//            goods.setGoodsStatus(SecondGoodsStatusEnum.UNDER_REVIEW.getCode()); // 审核中
//            goods.setVideoTaskId(taskIds.get(0)); // 保存第一个任务ID到商品表
//            goods.setFailedReason("");
//            updateById(goods);
//            // 审核中审核记录
//            createGoodsAudit(goods, "", Constants.AuditStatus.UNDER_REVIEW);
//            // 审核中，记录操作历史
////            recordGoodsOperation(goods);
//            return;
//        }

//        List<String> videoUrls = extractVideoUrls(goodsDTO.getImgUrl());
//        if (videoUrls.isEmpty()) {
//            // ai 审核
//            secondGoodsAuditService.performSecondRoundReview(goods, goodsDTO);
//            return;
//        }

        // 审核通过后上架商品
        approveAndListGoods(goods);

        // 检查用户是否在24小时内发布同类商品超过阈值
        if (!checkUserPublishSameCategoryLimit(goods)) {
            log.warn("用户 {} 在24小时内发布同类商品次数超过限制", goodsDTO.getUserId());
        }

        // 检查用户是否在24小时内发布商品超过阈值
        if (!checkUserPublishLimit(goods)) {
            log.warn("用户 {} 在24小时内发布商品次数超过限制", goodsDTO.getUserId());

        }
    }

    /**
     * 创建商品审核记录
     * @param goods 商品信息
     */
//    @Transactional(rollbackFor = Exception.class)
    private void approveAndListGoods(SecondGoods goods) {
        boolean isNotified = false;
        try {
            // 如果所有审核都通过，设置为上架状态
            goods.setGoodsStatus(SecondGoodsStatusEnum.LISTED.getCode()); // 上架
            goods.setFailedReason("");
            goods.setReleaseTime(new Date()); // 上架时间
            updateById(goods);
            // 插入审核记录
            createGoodsAudit(goods, "", Constants.AuditStatus.PASSED);
            // 发送审核成功消息
            sendMessage(goods);
            isNotified = true; // 标记通知已发送
            // 上架 记录商品操作历史
            String operationName = "";
            QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("goods_id", goods.getId());
            List<SecondGoodsRecord> recordList = secondGoodsRecordMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(recordList)){
                operationName = "重新发布";
            }else {
                operationName = "首次发布";
            }
            recordGoodsOperation(goods, operationName);
        } catch (Exception e) {
            log.error("商品上架过程中发生异常，执行回滚", e);
            // 如果通知已发送但后续操作失败，需要补偿
            if (isNotified) {
                // 发送补偿消息，比如撤销通知或标记为异常状态
//                sendCompensationMessage(goods);
            }
            throw e;
        }
    }

    /**
     * 执行视频审核
     * @param goods 商品信息
     * @param goodsDTO 商品DTO信息
     * @return 审核结果
     */
    private List<String> performVideoReviews(SecondGoods goods, SecondGoodsVo goodsDTO) {
        List<String> videoUrls = extractVideoUrls(goodsDTO.getImgUrl());
        List<String> taskIds = new ArrayList<>();
        // 视频审核
        if (videoModerationEnabled) {
            if (!videoUrls.isEmpty()) {
                // 提交视频审核任务
                for (String videoUrl : videoUrls) {
                    try {
                        String taskId = videoModerationService.submitVideoModerationTask(videoUrl);
                        taskIds.add(taskId);
                    } catch (Exception e) {
                        log.error("提交视频审核任务失败，视频URL: {}", videoUrl, e);
                        if (videoModerationBlockOnFailure) {
                            // 视频审核提交失败，设置为审核失败状态
                            goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode());
                            goods.setFailedReason("视频审核提交失败: " + e.getMessage());
                            createGoodsAudit(goods, "视频审核提交失败", Constants.AuditStatus.FAILED);
                            sendFailedMsg(goods);
                        }
                    }
                }
            }
        }
        return taskIds;
    }

    /**
     * 执行文本审核
     * @param goods 商品信息
     * @param goodsDTO 商品DTO信息
     * @return 审核结果
     */
    private boolean performTextReview(SecondGoods goods, SecondGoodsVo goodsDTO) throws Exception {
        List<String> servicesList = Lists.newArrayList();
        servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
        servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
        // 使用商品发布场景的审核服务
        String test = goodsDTO.getDescription() + goodsDTO.getTitle() + goods.getLabel() + goods.getTopic();
        TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(test, servicesList);

        if ("high".equals(textCheckResult.getRiskLevel())) {
            // 文本审核不通过或存在高风险
            goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
            String failReason = "文本审核不通过：" + (textCheckResult.getRiskWords() != null ? textCheckResult.getRiskWords() : "存在高风险内容");
            goods.setFailedReason(failReason);
            // 插入审核记录
            createGoodsAudit(goods, failReason, Constants.AuditStatus.FAILED);
            // 发送审核失败消息
            sendFailedMsg(goods);
            return false;
        }
        return true;
    }

    /**
     * 执行图片审核
     * @param goods 商品信息
     * @param goodsDTO 商品DTO信息
     * @return 审核结果
     */
    private boolean performImageReviews(SecondGoods goods, SecondGoodsVo goodsDTO) throws Exception {
        // 图片审核（循环处理）
        List<String> imageUrls = goodsDTO.getImgUrl();
        //  根据imageUrls 过滤不是图片的url
        imageUrls = imageUrls.stream().filter(url -> url.toLowerCase().endsWith(".jpg") || url.toLowerCase().endsWith(".png") || url.toLowerCase().endsWith(".jpeg") || url.toLowerCase().endsWith(".gif")).collect(Collectors.toList());
        // 图片审核
        if (imageUrls != null && !imageUrls.isEmpty()) {
            StringBuilder failReasonBuilder = new StringBuilder();
            for (String imageUrl : imageUrls) {
                List<String> imgServicesList = Lists.newArrayList();
                // 内容治理检测 + AIGC图片风险检测
                imgServicesList.add(ImageReviewServiceEnum.TONALITY_IMPROVE.getService());
                imgServicesList.add(ImageReviewServiceEnum.AIGC_CHECK.getService());
//                imgServicesList.add(ImageReviewServiceEnum.IMG_QUERY_SECURITY_CHECK.getService());
                ImageModerationResultVO response = imageModerationUtil.productPublishCheck(imageUrl,imgServicesList);
                if ("high".equals(response.getRiskLevel())) {
                    // 图片审核不通过或存在高风险
                    goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
                    String failReason = "图片审核不通过：图片中包含" + (response.getDescriptions() != null ? response.getDescriptions() : "高风险内容");
                    goods.setFailedReason(failReason);
                    // 插入审核记录
                    createGoodsAudit(goods, failReason, Constants.AuditStatus.FAILED);
                    // 发送审核失败消息
                    sendFailedMsg(goods);
                    return false;
                }
            }
        }
        return true;
    }



    /**
     * 执行内容审核（图片、文本和视频）
     * @param goods 商品信息
     * @param goodsDTO 商品DTO信息
     * @return 审核结果
     */
    private boolean performContentReviews(SecondGoods goods, SecondGoodsVo goodsDTO) throws Exception {
        List<String> servicesList = Lists.newArrayList();
        servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
        servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
        // 使用商品发布场景的审核服务
        String test = goodsDTO.getDescription() + goodsDTO.getTitle() + goods.getLabel() + goods.getTopic();
        TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(test, servicesList);

        if ("high".equals(textCheckResult.getRiskLevel())) {
            // 文本审核不通过或存在高风险
            goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
            goods.setFailedReason("文本审核不通过：" + (textCheckResult.getRiskWords() != null ? textCheckResult.getRiskWords() : "存在高风险内容"));
            // 插入审核记录
            createGoodsAudit(goods, textCheckResult.getRiskWords(), Constants.AuditStatus.FAILED);
            // 发送审核失败消息
            sendFailedMsg(goods);
            return false;
        }

        // 图片审核（循环处理）
        List<String> imageUrls = goodsDTO.getImgUrl();
        if (!StringUtils.isEmpty(goodsDTO.getHomeImage())){
            imageUrls.add(goodsDTO.getHomeImage());
        }
        if (imageUrls != null && !imageUrls.isEmpty()) {
            StringBuilder failReasonBuilder = new StringBuilder();
            for (String imageUrl : imageUrls) {
                List<String> imgServicesList = Lists.newArrayList();
                // TODO 后续配置到数据库 中
                imgServicesList.add(ImageReviewServiceEnum.TONALITY_IMPROVE.getService());
                imgServicesList.add(ImageReviewServiceEnum.AIGC_CHECK.getService());
//                imgServicesList.add(ImageReviewServiceEnum.IMG_QUERY_SECURITY_CHECK.getService());
                ImageModerationResultVO response = imageModerationUtil.productPublishCheck(imageUrl,imgServicesList);
                if ("high".equals(response.getRiskLevel())) {
                    // 图片审核不通过或存在高风险
                    goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode()); // 审核失败
                    goods.setFailedReason("图片审核不通过：图片中包含" + (response.getDescriptions() != null ? response.getDescriptions() : "高风险内容"));
                    // 插入审核记录
                    createGoodsAudit(goods, response.getDescriptions(), Constants.AuditStatus.FAILED);
                    // 发送审核失败消息
                    sendFailedMsg(goods);
                    return false;
                }
            }
        }

        // 视频审核
        if (videoModerationEnabled) {
            List<String> videoUrls = extractVideoUrls(goodsDTO.getImgUrl());
            if (!videoUrls.isEmpty()) {
                // 提交视频审核任务
                List<String> taskIds = new ArrayList<>();
                for (String videoUrl : videoUrls) {
                    try {
                        String taskId = videoModerationService.submitVideoModerationTask(videoUrl);
                        taskIds.add(taskId);
                    } catch (Exception e) {
                        log.error("提交视频审核任务失败，视频URL: {}", videoUrl, e);
                        if (videoModerationBlockOnFailure) {
                            // 视频审核提交失败，设置为审核失败状态
                            goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode());
                            goods.setFailedReason("视频审核提交失败: " + e.getMessage());
                            createGoodsAudit(goods, "视频审核提交失败", Constants.AuditStatus.FAILED);
                            sendFailedMsg(goods);
                            return false;
                        }
                    }
                }

                // 如果成功提交了视频审核任务，设置商品状态为审核中
                if (!taskIds.isEmpty()) {
                    goods.setGoodsStatus(SecondGoodsStatusEnum.UNDER_REVIEW.getCode()); // 审核中
                    goods.setVideoTaskId(taskIds.get(0)); // 保存第一个任务ID到商品表
                    goods.setFailedReason("");
                    updateById(goods);
                    createGoodsAudit(goods, "", SecondGoodsStatusEnum.UNDER_REVIEW.getCode());
                    // 审核中，记录操作历史
//                    recordGoodsOperation(goods);
                    return true; // 异步处理，直接返回
                }
            }
        }

        // 如果所有审核都通过，设置为上架状态
        goods.setGoodsStatus(SecondGoodsStatusEnum.LISTED.getCode()); // 上架
        goods.setFailedReason("");
        goods.setReleaseTime(new Date()); // 上架时间
        updateById(goods);
        // 插入审核记录
        createGoodsAudit(goods, "", Constants.AuditStatus.PASSED);
        // 发送审核成功消息
        sendMessage(goods);
        // 审核成功，记录操作历史
        String operationName = "";
        QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("goods_id", goods.getId());
        List<SecondGoodsRecord> recordList = secondGoodsRecordMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(recordList)){
            operationName = "重新发布";
        }else {
            operationName = "首次发布";
        }
        recordGoodsOperation(goods, operationName);
        return true;
    }

    /**
     * 从图片URL列表中提取视频URL
     * @param imageUrls 图片URL列表
     * @return 视频URL列表
     */
    private List<String> extractVideoUrls(List<String> imageUrls) {
        if (CollectionUtil.isEmpty(imageUrls)) {
            return Collections.emptyList();
        }

        List<String> videoUrls = new ArrayList<>();
        for (String url : imageUrls) {
            if (isVideoUrl(url)) {
                videoUrls.add(url);
            }
        }
        return videoUrls;
    }

    /**
     * 创建商品审核记录
     *
     * @param goods 商品
     * @param failReason 审核结果
     */
    private void createGoodsAudit(SecondGoods goods, String failReason,Integer goodsStatus) {
        // 保存审核结果
        secondGoodsMapper.updateById(goods);
        // 插入审核记录
        SecondGoodsAudit auditRecord = new SecondGoodsAudit();
        auditRecord.setGoodsId(goods.getId());
        auditRecord.setGoodsStatus(goodsStatus); // 审核状态
        if (Constants.AuditStatus.FAILED.equals(goodsStatus)) {
            auditRecord.setFailedReason(failReason);
        }
        auditRecord.setCreatedUserId(goods.getUserId());
        auditRecord.setUpdatedUserId(goods.getUserId());
        auditRecord.setCreatedTime(new Date());
        auditRecord.setUpdatedTime(new Date());
        secondGoodsAuditMapper.insert(auditRecord);
        goods.setAuditRecordId(auditRecord.getId());
    }

    /**
     * 保存商品图片信息
     * @param savedGoodsId 保存后的商品ID
     * @param goods .getimgUrl 图片URL列表
     * @return 保存结果
     */
    private boolean saveStoreImages(Integer savedGoodsId, SecondGoodsVo goods ) {
        if (CollectionUtil.isEmpty(goods.getImgUrl())) {
            return true; // 如果没有图片，则返回成功
        }
        // 处理 第一个值为视频地址，获取视频第一帧作为商品封面图
        String coverImage = getCoverImageFromVideoOrImage(goods);
        if (coverImage != null) {
            // 更新商品表封面图字段
            SecondGoods secondGoods = new SecondGoods();
            secondGoods.setId(savedGoodsId);
            secondGoods.setHomeImage(coverImage);
            updateById(secondGoods);
        }
        // 保存前先把原有的删除
        storeImgMapper.delete(new LambdaUpdateWrapper<StoreImg>().eq(StoreImg::getStoreId, savedGoodsId).eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS));
        // 批量保存图片信息
        for(int i = 0; i < goods.getImgUrl().size(); i++){
            StoreImg storeImg = new StoreImg();
            storeImg.setStoreId(savedGoodsId);
            storeImg.setImgType(Constants.ImageType.SECOND_HAND_GOODS);
            storeImg.setImgSort(i);
            storeImg.setImgDescription("发布二手商品图片");
            storeImg.setDeleteFlag(Constants.DeleteFlag.NOT_DELETED);
            storeImg.setCreatedTime(new Date());
            storeImg.setUpdatedTime(new Date());
            storeImg.setCreatedUserId(1);
            storeImg.setUpdatedUserId(1);
            storeImg.setImgUrl(goods.getImgUrl().get(i));
            // 保存图片 插入store_img数据库
            storeImgMapper.insert(storeImg);
        }
        return true;
    }

    /**
     * 发送消息
     * @param goods 商品信息
     */
    private void sendMessage(SecondGoods goods) {
        // 根据 goods.getUserId() 获取用户信息
        LifeUser lifeUser = lifeUserMapper.selectById(goods.getUserId());
        String phone = lifeUser.getUserPhone();
        // 调取feign接口 发送消息 life_notice表
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId("system");
        lifeNotice.setReceiverId("user_"+ phone);
        lifeNotice.setBusinessId(goods.getAuditRecordId());
        lifeNotice.setTitle("商品审核通知");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("goodsId", goods.getId());
        jsonObject.put("status", "true");
        jsonObject.put("message", "恭喜您的商品已发布成功。");
        lifeNotice.setContext(jsonObject.toJSONString());
        lifeNotice.setNoticeType(Constants.Notice.SYSTEM_NOTICE); // 系统通知
        lifeNotice.setIsRead(0);
        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
        lifeNoticeMapper.insert(lifeNotice);
        sendNotice("user_"+ phone, lifeNotice);
    }

    /**
     * 发送通知消息
     * @param receiverId 接收者ID
     * @param lifeNotice 通知内容
     */
    private void sendNotice(String receiverId, LifeNotice lifeNotice) {
        try {
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
            alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.from(webSocketVo).toJSONString());
        } catch (Exception e) {
            log.error("发送消息通知失败，receiverId: {}", receiverId, e);
        }
    }

    /**
     * 发送审核失败消息
     * @param goods 商品审核信息
     */
    private void sendFailedMsg(SecondGoods goods) {
        // 根据 goods.getUserId() 获取用户信息
        LifeUser lifeUser = lifeUserMapper.selectById(goods.getUserId());
        String phone = lifeUser.getUserPhone();
        // 调取feign接口 发送消息 life_notice表
        LifeNotice lifeNotice = new LifeNotice();
        lifeNotice.setSenderId("system");
        lifeNotice.setReceiverId("user_"+ phone);
        lifeNotice.setBusinessId(goods.getAuditRecordId());
        lifeNotice.setTitle("商品审核通知");
        // TODO: 失败原因本期为固定文案，实际原因暂不保存

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("goodsId", goods.getId());
        jsonObject.put("status", "false");
        jsonObject.put("message", "抱歉您的商品发布失败，图片或文字存在违规行为，请您修改后重新发布。");
        lifeNotice.setContext(jsonObject.toJSONString());
        lifeNotice.setNoticeType(Constants.Notice.SYSTEM_NOTICE); // 系统通知
        lifeNotice.setIsRead(0);
        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
        lifeNoticeMapper.insert(lifeNotice);
        sendNotice("user_"+ phone, lifeNotice);
    }


    /**
     * 判断并获取商品封面图（若第一个链接是视频，则取第一帧）
     * @param goodsVo imgUrl 商品图片/视频链接列表
     * @return 封面图URL或处理后的图像标识
     */
    public String getCoverImageFromVideoOrImage(SecondGoodsVo goodsVo) {
        if (goodsVo.getImgUrl() == null || goodsVo.getImgUrl().isEmpty()) {
            return null;
        }

        String firstUrl = goodsVo.getImgUrl().get(0);
        if (isVideoUrl(firstUrl)) {
            // 如果是视频，获取第一帧作为封面图
            return goodsVo.getHomeImage();
//            return extractFirstFrameAsCover(firstUrl);
        } else {
            // 否则直接返回第一个图片链接
            return firstUrl;
        }
    }

    /**
     * 判断URL是否为视频地址（支持常见格式）
     * @param url 输入URL
     * @return 是否为视频地址
     */
    private boolean isVideoUrl(String url) {
        if (url == null) return false;
        url = url.toLowerCase();
        return url.endsWith(".mp4") ||
                url.endsWith(".avi") ||
                url.endsWith(".mov") ||
                url.endsWith(".flv") ||
                url.endsWith(".wmv") ||
                url.endsWith(".mkv");
    }

    /**
     * 提取视频第一帧作为封面图（需根据实际环境实现）
     * @param videoUrl 视频地址
     * @return 封面图URL或Base64编码字符串
     */
    private String extractFirstFrameAsCover(String videoUrl) {
        // 示例返回占位符
        return videoUtils.getImg(videoUrl);
    }

    /**
     * 获取热销商品列表（前10）
     * @return 热销商品列表
     */
    @Override
    public List<SecondGoods> getHotSellingRankingTop10() {
        return secondGoodsMapper.getHotSellingRankingTop10();
    }

    /**
     * 获取收藏商品列表（前10）
     * @return 收藏商品列表
     */
    @Override
    public List<SecondGoods> getCollectTop10() {
        return secondGoodsMapper.getCollectTop10();
    }

    /**
     * 获取热销商品分页列表
     * @param page 分页参数
     * @return 热销商品分页列表
     */
    @Override
    public IPage<SecondGoods> getHotSellingRanking(IPage<SecondGoods> page) {
        return secondGoodsMapper.getHotSellingRanking(page);
    }

    /**
     * 根据屏蔽类型获取屏蔽商品列表
     * @param page 分页参数
     * @param userId 用户ID
     * @param shieldType 屏蔽类型
     * @return 屏蔽商品分页列表
     */
    @Override
    public IPage<SecondGoods> getShieldedGoodsListByType(IPage<SecondGoods> page, Integer userId, Integer shieldType) {
        return secondGoodsMapper.getShieldedGoodsListByType(page, userId, shieldType);
    }

    /**
     * 搜索商品列表
     *
     * @param page 分页参数
     * @param userId 用户ID
     * @param secondGoodsVo 搜索参数
     * @return 商品列表
     */
    @Override
    public IPage<SecondGoodsVo> searchGoodsList(IPage<SecondGoodsVo> page,Integer userId, SecondGoodsVo secondGoodsVo) {
        // 获取商品屏蔽列表
        List<SecondGoods> shieldedGoodsList = getShieldedGoodsList(userId);
        // 提取屏蔽商品ID
        List<Integer> shieldedGoodsIds = shieldedGoodsList.stream()
                .map(SecondGoods::getId)
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(shieldedGoodsIds)) {
            shieldedGoodsIds = Collections.emptyList();
        }
        // 获取拉黑列表
        List<Integer> userIdList = lifeBlacklistMapper.getBlackList(userId);
        if (CollectionUtil.isEmpty(userIdList)) {
            userIdList = Collections.emptyList();
        }
        secondGoodsVo.setShieldedGoodsIds(shieldedGoodsIds);
        secondGoodsVo.setUserIdList(userIdList);

        // 优先调用 AI 二手搜索接口；有搜索词且 AI 返回有效结果时直接使用 AI 数据并处理成对应格式，否则走本地分页查询
        IPage<SecondGoodsVo> searchGoodsList = null;
        if (!StringUtils.isEmpty(secondGoodsVo.getSearchData())) {
            String releaseTimeStr = null;
            if (secondGoodsVo.getReleaseTime() != null) {
                releaseTimeStr = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(secondGoodsVo.getReleaseTime());
            }
            SecondHandSearchAiUtils.SecondHandSearchResult aiResult = secondHandSearchAiUtils.search(
                    secondGoodsVo.getSearchData(),
                    secondGoodsVo.getCurrentLatitude(),
                    secondGoodsVo.getCurrentLongitude(),
                    (int) page.getCurrent(),
                    (int) page.getSize(),
                    secondGoodsVo.getOrderType(),
                    releaseTimeStr,
                    shieldedGoodsIds,
                    userIdList);
            if (aiResult != null && CollectionUtil.isNotEmpty(aiResult.getRecords())) {
                searchGoodsList = buildPageFromAiResult(page, aiResult);
            }
        }
        if (searchGoodsList == null) {
//            log.info("使用本地查询");
//            searchGoodsList = getSecondGoodsVoIPage(page, secondGoodsVo, shieldedGoodsIds, userIdList);
            return searchGoodsList = new Page<SecondGoodsVo>();
        }

        // 判空
        if (CollectionUtil.isNotEmpty(searchGoodsList.getRecords())) {
            // 批量设置商品图片信息
//            batchSetGoodsImages(searchGoodsList);
            // 批量设置用户信息
            batchSetSearchUserInfo(searchGoodsList);
            // 批量设置收藏状态
            batchSetCollectStatus(searchGoodsList,secondGoodsVo.getUserPhone(), userId);
            // 批量设置点赞状态
            batchSetLikeStatus(searchGoodsList,secondGoodsVo.getUserPhone(), userId);
        }
        return searchGoodsList;
    }

    /**
     * 将 AI 搜索返回的 SecondGoodsVo 列表组装为分页结果（AI 已按 shieldedGoodsIds、userIdList 过滤，此处仅封装分页）
     */
    private IPage<SecondGoodsVo> buildPageFromAiResult(IPage<SecondGoodsVo> page,
                                                       SecondHandSearchAiUtils.SecondHandSearchResult aiResult) {
        Page<SecondGoodsVo> resultPage = new Page<>(page.getCurrent(), page.getSize());
        resultPage.setRecords(aiResult.getRecords() != null ? aiResult.getRecords() : Collections.emptyList());
        resultPage.setTotal(aiResult.getTotal());
        return resultPage;
    }

    /**
     * 查询搜索结果
     * @param page 分页参数
     * @param secondGoodsVo 查询参数
     * @param shieldedGoodsIds 屏蔽商品id
     * @param userIdList 屏蔽用户id
     * @return IPage<SecondGoodsVo> 搜索结果
     */
    private IPage<SecondGoodsVo> getSecondGoodsVoIPage(IPage<SecondGoodsVo> page, SecondGoodsVo secondGoodsVo, List<Integer> shieldedGoodsIds, List<Integer> userIdList) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.notIn(CollectionUtil.isNotEmpty(shieldedGoodsIds), "sg.id", shieldedGoodsIds)
                .notIn(CollectionUtil.isNotEmpty(userIdList), "sg.user_id", userIdList)
                .eq("sg.goods_status", SecondGoodsStatusEnum.LISTED.getCode())// 3-上架
                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .isNull("sg.trade_id");
        // 添加对 searchData 的模糊查询
        if (!StringUtils.isEmpty(secondGoodsVo.getSearchData())) {
            String searchData = "%" + secondGoodsVo.getSearchData() + "%";
            queryWrapper.and(wrapper -> wrapper
                            .like("sg.title", searchData)
//                .or()
//                .like("sg.label", searchData)
//                .or()
//                .like("sg.description", searchData)
//                .or()
//                .like("sgc1.category_name", searchData)
//                .or()
//                .like("sgc2.category_name", searchData)
//                .or()
//                .like("sg.topic", searchData)
            );
        }
        // 添加对 orderData 的排序 若不为空
        if (!StringUtils.isEmpty(secondGoodsVo.getOrderData()) && secondGoodsVo.getOrderType() != null) {
            // 正序
            if (secondGoodsVo.getOrderType() == 1){
                queryWrapper.orderByAsc(secondGoodsVo.getOrderData())
                        .orderByAsc("distance");
            }
            // 倒序
            if (secondGoodsVo.getOrderType() == 2){
                queryWrapper.orderByDesc(secondGoodsVo.getOrderData())
                        .orderByAsc("distance");
            }
        }else {
            queryWrapper.orderByAsc("distance");
        }

        // 添加对 releaseTime 的查询
        if (secondGoodsVo.getReleaseTime() != null) {
            queryWrapper.eq("sg.release_time", secondGoodsVo.getReleaseTime());
        }

        // 返回分页结果
        IPage<SecondGoodsVo> searchGoodsList = secondGoodsMapper.searchGoodsList(page, secondGoodsVo.getCurrentLatitude(), secondGoodsVo.getCurrentLongitude() ,queryWrapper);
        searchGoodsList.getRecords().forEach(secondGoods -> {
            secondGoods.setPosition(secondGoods.getSearchData());
        });
        return searchGoodsList;
    }

    /**
     * 批量设置收藏状态
     * @param searchGoodsList 搜索结果列表
     * @param userId 用户ID(登录用户)
     * @param phone 手机号
     */
    private void batchSetLikeStatus(IPage<SecondGoodsVo> searchGoodsList, String phone, Integer userId) {
        // 批量设置点赞状态
        searchGoodsList.getRecords().forEach(goods -> {
            if (userId != null) {
                // 设置点赞状态
                SecondLikerScope likerScope = lifeLikeIdentityHelper.fromLifeUserId(userId);
                LambdaQueryWrapper<LifeLikeRecord> likeQueryWrapper = new LambdaQueryWrapper<>();
                likeQueryWrapper.eq(LifeLikeRecord::getHuifuId, goods.getId())
                        .eq(LifeLikeRecord::getType, Constants.LikeType.SECOND_HAND_GOODS);
                lifeLikeIdentityHelper.applyLikerFilter(likeQueryWrapper, likerScope);
                if (lifeLikeRecordMapper.selectCount(likeQueryWrapper) > 0) {
                    goods.setLikeStatus(1);
                }
            }
        });
    }

    /**
     * 批量设置收藏状态
     * @param searchGoodsList 搜索结果列表
     * @param userId 用户ID(登录用户)
     * @param phone 手机号
     */
    private void batchSetCollectStatus(IPage<SecondGoodsVo> searchGoodsList,String phone, Integer userId) {
        // 批量设置收藏状态
        searchGoodsList.getRecords().forEach(goods -> {
            if (userId != null) {
                LifeCollectIdentityQuery.Scope collectScope = LifeCollectIdentityQuery.fromLifeUserId(userId);
                LambdaUpdateWrapper<LifeCollect> updateWrapper = new LambdaUpdateWrapper<>();
                LifeCollectIdentityQuery.applyUserSide(updateWrapper, collectScope);
                updateWrapper.eq(LifeCollect::getBusinessType, Constants.CollectBusinessType.DEFAULT)
                        .eq(LifeCollect::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                        .eq(LifeCollect::getBusinessId, goods.getId());
                if (lifeCollectMapper.selectCount(updateWrapper) > 0) {
                    goods.setCollectStatus(1);
                }
            }
        });
    }

    /**
     * 获取商品屏蔽列表
     * @param userId 用户ID
     * @return 商品屏蔽列表
     */
    private List<SecondGoods> getShieldedGoodsList(Integer userId) {
        // 调用mapper方法
        return secondGoodsMapper.getShieldedGoodsList(userId);
    }

    /**
     * 获取商品详情
     * @param id 商品ID
     * @return 商品详情
     */
    @Override
    public SecondGoodsVo getSecondGoodsById(Integer id) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg.id", id)
                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED);
        SecondGoodsVo secondGoods = secondGoodsMapper.getGoodsDetails(queryWrapper);
        // 设置图片信息
        QueryWrapper<StoreImg> query = new QueryWrapper<>();
        query.lambda()
                .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS) // 商品 图片
                .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                .in(StoreImg::getStoreId, id);
        List<StoreImg> storeImgs = storeImgMapper.selectList(query);
        // 设置图片信息
        if (CollectionUtil.isNotEmpty(storeImgs)) {
            secondGoods.setImgUrl(storeImgs.stream().map(StoreImg::getImgUrl).collect(Collectors.toList()));
        }
        return secondGoods;
    }

    /**
     * 获取屏蔽商品分页列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return 屏蔽商品分页列表
     */
    @Override
    public IPage<SecondGoodsVo> getShieldedGoodsPage(IPage<SecondGoodsVo> page, Integer userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                // 可以查看已删除的商品数据
//                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("ss.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("ss.user_id", userId)
                .eq("ss.shield_type", 1)
                .orderByDesc("ss.created_time");
        return secondGoodsMapper.getShieldedGoodsPage(page, queryWrapper);

    }

    /**
     * 获取收藏商品列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SecondGoodsVo> 收藏商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getCollectGoodsPage(IPage<SecondGoodsVo> page, int userId) {
        LifeCollectIdentityQuery.Scope collectScope = LifeCollectIdentityQuery.fromLifeUserId(userId);
        // 获取商品屏蔽列表
        List<SecondGoods> shieldedGoodsList = getShieldedGoodsList(userId);
        // 提取屏蔽商品ID
        List<Integer> shieldedGoodsIds = shieldedGoodsList.stream()
                .map(SecondGoods::getId)
                .collect(Collectors.toList());

        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                // 可以查看已删除的商品数据
                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("lc.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .notIn(CollectionUtil.isNotEmpty(shieldedGoodsIds), "sg.id", shieldedGoodsIds)
                .eq("lc.user_id_user_type", collectScope.getUserType())
                .eq("lc.user_id_ref_id", collectScope.getRefId())
                .orderByDesc("lc.created_time");
        return secondGoodsMapper.getCollectGoodsPage(page, queryWrapper);
    }

    /**
     * 获取购买商品列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SecondGoodsVo> 购买商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getBuyGoodsPage(IPage<SecondGoodsVo> page, int userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                // 可以查看已删除的商品数据
//                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("str.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("str.buyer_id", userId) // 买家ID
                .eq("sg.goods_status", SecondGoodsStatusEnum.SOLD.getCode()) // 5-已售出
                .eq("str.trade_status", Constants.TradeStatus.TRADE_SUCCESS) // 4-交易成功
                .orderByDesc("str.created_time");
        return secondGoodsMapper.getBuyGoodsPage(page, queryWrapper);
    }

    /**
     * 根据商品状态获取商品列表 - 0:草稿 1:审核中 2:审核失败 3:已上架 4:已下架 5:已售出
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SecondGoodsVo> 出售商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getSellGoodsPage(IPage<SecondGoodsVo> page, SecondGoodsVo secondGoodsVo,int userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("sg.user_id", userId)
                .eq("sg.goods_status", secondGoodsVo.getGoodsStatus()); // 5-已售出 ,0-草稿
        return secondGoodsMapper.getSellGoodsPage(page, queryWrapper);
    }

    /**
     * 获取用户商品列表
     * @param page 分页参数
     * @param userId 主页用户id
     * @return IPage<SecondGoodsVo> 用户商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getUserGoodsPage(IPage<SecondGoodsVo> page, Double currentLatitude , Double currentLongitude, Integer userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("sg.user_id", userId) // 主页用户ID
                .in("sg.goods_status", SecondGoodsStatusEnum.LISTED.getCode(), SecondGoodsStatusEnum.SOLD.getCode()) // 3-上架 5-已售出
                .orderByAsc("FIELD(sg.goods_status, 3, 5)")
                .orderByDesc("sg.release_time");
        return secondGoodsMapper.getUserGoodsPage(page, currentLatitude, currentLongitude, queryWrapper);
    }

    /**
     * 获取我的商品列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SecondGoodsVo> 我的商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getMyGoodsPage(IPage<SecondGoodsVo> page, int userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("sg.user_id", userId) // 用户ID
                .in("sg.goods_status", SecondGoodsStatusEnum.REVIEW_FAILED.getCode(),
                        SecondGoodsStatusEnum.DELISTED.getCode(),
                        SecondGoodsStatusEnum.SOLD.getCode(),
                        SecondGoodsStatusEnum.LISTED.getCode()) // 3-上架 5-已售出
                .orderByAsc("FIELD(sg.goods_status, 2, 4, 5, 3)")
                .orderByDesc("sg.release_time");
        return secondGoodsMapper.getMyGoodsPage(page, queryWrapper);
    }

    /**
     * 获取草稿列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SecondGoodsVo> 草稿列表
     */
    @Override
    public IPage<SecondGoodsVo> getDraftList(IPage<SecondGoodsVo> page, int userId) {
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("sg.user_id", userId) // 用户ID
                .eq("sg.goods_status", SecondGoodsStatusEnum.DRAFT.getCode())
                .orderByDesc("sg.created_time");
        return secondGoodsMapper.getDraftList(page, queryWrapper);
    }

    /**
     * 获取点赞商品列表
     * @param page 分页参数
     * @param userId 用户ID
     * @param phone 手机号
     * @return IPage<SecondGoodsVo> 点赞商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getLikeGoodsPage(IPage<SecondGoodsVo> page, int userId, String phone) {
        SecondLikerScope likerScope = lifeLikeIdentityHelper.fromLifeUserId(userId);
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("lc.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("lc.type", Constants.LikeType.SECOND_HAND_GOODS)
                .eq("sg.user_id", userId)
                .orderByDesc("lc.created_time");
        if (likerScope.hasTypeRef()) {
            queryWrapper.eq("lc.dianzan_user_type", likerScope.getDianzanUserType())
                    .eq("lc.dianzan_ref_id", likerScope.getDianzanRefId());
        }
        return secondGoodsMapper.getLikeGoodsPage(page, queryWrapper);
    }

    /**
     * 获取交易列表
     * @param page 分页参数
     * @param userId 用户ID
     * @return IPage<SellGoodsVo> 交易列表
     */
    @Override
    public IPage<SellGoodsVo> getTransactionList(IPage<SellGoodsVo> page, Integer userId) {
        IPage<SellGoodsVo> result = new Page<>();
        QueryWrapper<SellGoodsVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                // 可以查看已删除的商品数据
//                .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .eq("str.delete_flag", Constants.DeleteFlag.NOT_DELETED)
                .and(wrapper -> wrapper.eq("str.buyer_id", userId)
                        .or()
                        .eq("str.seller_id", userId))
                .orderByDesc("str.created_time");
        result = secondGoodsMapper.getTransactionList(page, userId, queryWrapper);
        // 批量设置用户信息
        batchSetSellUserInfo(result);
        return result;
    }

    /**
     * 根据用户ID和商品状态获取商品列表
     * @param userId 用户ID
     * @param goodsStatus 商品状态
     * @return 商品列表
     */
    @Override
    public List<SecondGoods> getGoodsListByUserId(Integer userId, Integer goodsStatus) {
        // 获取商品屏蔽列表
        List<SecondGoods> shieldedGoodsList = getShieldedGoodsList(userId);
        // 提取屏蔽商品ID
        List<Integer> shieldedGoodsIds = shieldedGoodsList.stream()
                .map(SecondGoods::getId)
                .collect(Collectors.toList());

        LambdaQueryWrapper<SecondGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecondGoods::getUserId, userId);
        queryWrapper.eq(SecondGoods::getGoodsStatus, goodsStatus);
        queryWrapper.notIn(CollectionUtil.isNotEmpty(shieldedGoodsIds), SecondGoods::getId, shieldedGoodsIds);
        queryWrapper.orderByDesc(SecondGoods::getReleaseTime);
        return secondGoodsMapper.selectList(queryWrapper);
    }

    /**
     * 处理视频审核结果
     * @param task 视频审核任务
     */
    @Override
    public void processVideoModerationResult(SecondVideoTask task) {
        try {
            // 查找关联的商品
            QueryWrapper<SecondGoods> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("video_task_id", task.getTaskId());
            SecondGoods goods = getOne(queryWrapper);

            if (goods == null) {
                log.warn("未找到关联的商品，任务ID: {}", task.getTaskId());
                return;
            }

            // 根据审核结果更新商品状态
            if ("none".equals(task.getRiskLevel())) {
                log.warn("视频审核通过，任务ID: {}", task.getTaskId());
                SecondGoodsVo secondGoodsVo = new SecondGoodsVo();
                BeanUtils.copyProperties(goods, secondGoodsVo);
                QueryWrapper<StoreImg> imgQueryWrapper = new QueryWrapper<>();
                imgQueryWrapper.eq("store_id", goods.getId());
                imgQueryWrapper.eq("img_type", 18);
                List<StoreImg> storeImgs = storeImgMapper.selectList(imgQueryWrapper);
                List<String> imgUrls = storeImgs.stream()
                        .map(StoreImg::getImgUrl)
                        .filter(imgUrl -> StringUtils.isNotBlank(imgUrl))
                        .collect(Collectors.toList());
                secondGoodsVo.setImgUrl(imgUrls);

                secondGoodsAuditService.performSecondRoundReview(goods, secondGoodsVo);
//
//                // 审核通过
//                goods.setGoodsStatus(SecondGoodsStatusEnum.LISTED.getCode());
//                goods.setFailedReason("");
//                goods.setReleaseTime(new Date());
//                updateById(goods);
//
//                // 更新审核记录
//                createGoodsAudit(goods, "", Constants.AuditStatus.PASSED);
//
//                // 发送审核成功消息
//                sendMessage(goods);
//                // 审核成功，记录操作历史
//                // 审核成功，记录操作历史
//                String operationName = "";
//                QueryWrapper<SecondGoodsRecord> queryRecordWrapper = new QueryWrapper<>();
//                queryRecordWrapper.eq("goods_id", goods.getId());
//                log.info("查询操作记录开始 goods_id: {}", goods.getId());
//                List<SecondGoodsRecord> recordList = secondGoodsRecordMapper.selectList(queryRecordWrapper);
//                log.info("查询操作记录结束 recordList: {}", recordList);
//                if (CollectionUtil.isNotEmpty(recordList)){
//                    operationName = "重新发布";
//                }else {
//                    operationName = "首次发布";
//                }
//                recordGoodsOperation(goods, operationName);
//
//                // 检查用户是否在24小时内发布同类商品超过阈值
//                if (!checkUserPublishSameCategoryLimit(goods)) {
//                    log.warn("用户 {} 在24小时内发布同类商品次数超过限制", goods.getUserId());
//                }
//
//                // 检查用户是否在24小时内发布商品超过阈值
//                if (!checkUserPublishLimit(goods)) {
//                    log.warn("用户 {} 在24小时内发布商品次数超过限制", goods.getUserId());
//
//                }
            } else {
                // 审核不通过
                goods.setGoodsStatus(SecondGoodsStatusEnum.REVIEW_FAILED.getCode());

                // 解析审核结果，生成具体的失败原因
                String failedReason = parseVideoModerationFailureReason(task);
                goods.setFailedReason(failedReason);
                updateById(goods);

                // 更新审核记录
                createGoodsAudit(goods, failedReason, Constants.AuditStatus.FAILED);

                // 记录操作历史
                recordGoodsOperation(goods, "视频审核失败");
                // 发送审核失败消息
                sendFailedMsg(goods);
            }
        } catch (Exception e) {
            log.error("处理视频审核结果时发生异常，任务ID: {}", task.getTaskId(), e);
        }
    }

    /**
     * 解析视频审核失败原因
     * @param task 视频审核任务
     * @return 失败原因
     */
    private String parseVideoModerationFailureReason(SecondVideoTask task) {
        StringBuilder reasonBuilder = new StringBuilder("视频审核不通过，风险等级: " + task.getRiskLevel());

        try {
            // 解析审核结果JSON
            JSONObject resultJson = JSON.parseObject(task.getResult());
            if (resultJson != null && resultJson.containsKey("data")) {
                JSONObject data = resultJson.getJSONObject("data");

                // 处理帧结果（视频画面）
                if (data.containsKey("FrameResult")) {
                    JSONObject frameResult = data.getJSONObject("FrameResult");
                    if (frameResult != null && frameResult.containsKey("FrameSummarys")) {
                        JSONArray frameSummarys = frameResult.getJSONArray("FrameSummarys");
                        if (frameSummarys != null && !frameSummarys.isEmpty()) {
                            reasonBuilder.append("。检测到违规内容:");
                            for (int i = 0; i < frameSummarys.size(); i++) {
                                JSONObject summary = frameSummarys.getJSONObject(i);
                                String label = summary.getString("Label");
                                String description = summary.getString("Description");
                                Integer labelSum = summary.getInteger("LabelSum");

                                if (label != null && !label.isEmpty()) {
                                    reasonBuilder.append("[").append(description != null ? description : label)
                                            .append("]出现").append(labelSum != null ? labelSum : 1).append("次;");
                                }
                            }
                        }
                    }
                }

                // 处理音频结果
                if (data.containsKey("AudioResult")) {
                    JSONObject audioResult = data.getJSONObject("AudioResult");
                    if (audioResult != null && audioResult.containsKey("AudioSummarys")) {
                        JSONArray audioSummarys = audioResult.getJSONArray("AudioSummarys");
                        if (audioSummarys != null && !audioSummarys.isEmpty()) {
                            reasonBuilder.append("。检测到违规音频:");
                            for (int i = 0; i < audioSummarys.size(); i++) {
                                JSONObject summary = audioSummarys.getJSONObject(i);
                                String label = summary.getString("Label");
                                String description = summary.getString("Description");
                                Integer labelSum = summary.getInteger("LabelSum");

                                if (label != null && !label.isEmpty()) {
                                    reasonBuilder.append("[").append(description != null ? description : label)
                                            .append("]出现").append(labelSum != null ? labelSum : 1).append("次;");
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.warn("解析视频审核结果失败，使用默认原因，任务ID: {}", task.getTaskId(), e);
        }

        return reasonBuilder.toString();
    }

    /**
     * 批量设置用户信息（用于SecondGoodsVo列表）
     * @param searchGoodsList 搜索结果
     */
    private void batchSetSearchUserInfo(IPage<SecondGoodsVo> searchGoodsList) {
        batchSetUserInfo(searchGoodsList,
                SecondGoodsVo::getUserId,
                (goods, userInfo) -> {
                    goods.setUserName(userInfo.getUserName());
                    goods.setRealName(userInfo.getRealName());
                    goods.setUserImage(userInfo.getUserImage());
                    goods.setUserId(userInfo.getId());
                    goods.setUserPhone("user_"+userInfo.getUserPhone());
                });
    }

    /**
     * 批量设置用户信息（用于SellGoodsVo列表）
     * @param sellGoodsList 搜索结果
     */
    private void batchSetSellUserInfo(IPage<SellGoodsVo> sellGoodsList) {
        batchSetUserInfo(sellGoodsList,
                SellGoodsVo::getUserId,
                (goods, userInfo) -> {
                    goods.setUserName(userInfo.getUserName());
                    goods.setRealName(userInfo.getRealName());
                    goods.setUserImage(userInfo.getUserImage());
                    goods.setUserId(userInfo.getId());
                    goods.setUserPhone(userInfo.getUserPhone());
                });
    }

    /**
     * 批量设置商品图片信息
     * @param searchGoodsList 商品列表
     */
    private void batchSetGoodsImages(IPage<SecondGoodsVo> searchGoodsList) {
        // 批量获取图片信息
        if (CollectionUtil.isNotEmpty(searchGoodsList.getRecords())) {
            List<Integer> goodsIds = searchGoodsList.getRecords().stream()
                    .map(SecondGoodsVo::getId)
                    .collect(Collectors.toList());
            // 批量获取图片信息
            QueryWrapper<StoreImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS) // 商品 图片
                    .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                    .in(StoreImg::getStoreId, goodsIds);
            List<StoreImg> imagesList= storeImgMapper.getImgsByGoodsIds(queryWrapper);
            // 集合根據商品id进行分组返回map
            Map<Integer, List<StoreImg>> imagesMap = imagesList.stream().collect(Collectors.groupingBy(StoreImg::getStoreId));
            // 遍历
            for (SecondGoodsVo goods : searchGoodsList.getRecords()) {
                // 提取图片url
                List<StoreImg> images = imagesMap.get(goods.getId());
                if (images != null) {
                    goods.setImgUrl(images.stream()
                            .map(StoreImg::getImgUrl)
                            .collect(Collectors.toList()));
                }
            }
        }
    }

    /**
     * 批量设置商品图片信息（用于管理后台）
     * @param goodsList 商品列表
     */
    private void batchSetGoodsImagesForAdmin(IPage<SecondGoodsVo> goodsList) {
        // 批量获取图片信息
        if (CollectionUtil.isNotEmpty(goodsList.getRecords())) {
            List<Integer> goodsIds = goodsList.getRecords().stream()
                    .map(SecondGoodsVo::getId)
                    .collect(Collectors.toList());
            // 批量获取图片信息
            QueryWrapper<StoreImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(StoreImg::getImgType, Constants.ImageType.SECOND_HAND_GOODS) // 商品 图片
                    .eq(StoreImg::getDeleteFlag, Constants.DeleteFlag.NOT_DELETED)
                    .in(StoreImg::getStoreId, goodsIds);
            List<StoreImg> imagesList= storeImgMapper.getImgsByGoodsIds(queryWrapper);
            // 集合根據商品id进行分组返回map
            Map<Integer, List<StoreImg>> imagesMap = imagesList.stream().collect(Collectors.groupingBy(StoreImg::getStoreId));
            // 遍历
            for (SecondGoodsVo goods : goodsList.getRecords()) {
                // 提取图片url
                List<StoreImg> images = imagesMap.get(goods.getId());
                if (images != null) {
                    goods.setImgUrl(images.stream()
                            .map(StoreImg::getImgUrl)
                            .collect(Collectors.toList()));

                }

                // 设置状态名称
                if (goods.getDeleteFlag() != null && goods.getDeleteFlag().equals(Constants.DeleteFlag.DELETED)) {
                    goods.setGoodsStatusName("已删除");
                } else if (goods.getGoodsStatus() != null) {
                    SecondGoodsStatusEnum statusEnum = SecondGoodsStatusEnum.fromCode(goods.getGoodsStatus());
                    if (statusEnum != null) {
                        goods.setGoodsStatusName(statusEnum.getDescription());
                    }
                }
            }
        }
    }


    /**
     * 批量设置用户信息
     * @param <T> 任意商品VO类型
     * @param goodsList 商品列表
     * @param userIdMapper 从商品VO获取用户ID的函数
     * @param userSetter 从用户信息设置到商品VO的函数
     */
    private <T> void batchSetUserInfo(IPage<T> goodsList,
                                      java.util.function.Function<T, Integer> userIdMapper,
                                      java.util.function.BiConsumer<T, LifeUserVo> userSetter) {
        if (CollectionUtil.isNotEmpty(goodsList.getRecords())) {
            List<Integer> userIds = goodsList.getRecords().stream()
                    .map(userIdMapper)
                    .collect(Collectors.toList());

            QueryWrapper<LifeUserVo> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", userIds)
                    .eq("delete_flag", Constants.DeleteFlag.NOT_DELETED);

            List<LifeUserVo> userInfoList = lifeUserMapper.getUserByIds(queryWrapper);
            Map<Integer, LifeUserVo> userInfoMap = userInfoList.stream()
                    .collect(Collectors.toMap(LifeUserVo::getId, lifeUserVo -> lifeUserVo));

            for (T goods : goodsList.getRecords()) {
                LifeUserVo userInfo = userInfoMap.get(userIdMapper.apply(goods));
                if (userInfo != null && userSetter != null) {
                    userSetter.accept(goods, userInfo);
                }
            }
        }
    }

    /**
     * 获取管理后台商品列表
     * @param page 分页参数
     * @param queryDTO 查询参数DTO
     * @return 商品列表
     */
    @Override
    public IPage<SecondGoodsVo> getAdminGoodsList(IPage<SecondGoodsVo> page, SecondGoodsAdminQueryDTO queryDTO) {
        // 构建查询条件
        QueryWrapper<SecondGoodsVo> queryWrapper = new QueryWrapper<>();

        // 商品名称模糊查询
        queryWrapper.like(org.apache.commons.lang3.StringUtils.isNotBlank(queryDTO.getTitle()), "sg.title", queryDTO.getTitle());
        // 过滤草稿
        queryWrapper.ne("sg.goods_status",SecondGoodsStatusEnum.DRAFT.getCode());
        // 状态查询分为两种情况处理
        if (queryDTO.getGoodsStatus() != null) {
            if (queryDTO.getGoodsStatus() == 6) {
                // 当状态为6时，查询删除标记为1的数据
                queryWrapper.eq("sg.delete_flag", Constants.DeleteFlag.DELETED);
            } else {
                // 其他状态按照商品状态进行查询，并且删除标记为0
                queryWrapper.eq("sg.goods_status", queryDTO.getGoodsStatus())
                        .eq("sg.delete_flag", Constants.DeleteFlag.NOT_DELETED);
            }
        }

        // 发布时间范围查询
        queryWrapper.ge(queryDTO.getReleaseStartTime() != null, "sg.release_time", queryDTO.getReleaseStartTime())
                .le(queryDTO.getReleaseEndTime() != null, "sg.release_time", queryDTO.getReleaseEndTime());
        queryWrapper.orderByDesc("sg.id");
        // 查询数据
        IPage<SecondGoodsVo> result = secondGoodsMapper.getAdminGoodsList(page, queryWrapper);

        // 批量设置商品图片信息
        batchSetGoodsImagesForAdmin(result);

        return result;
    }

    /**
     * 根据风控记录中的JSON数据批量下架商品
     * @param goodsIds 商品ID集合
     * @return 是否下架成功
     */
    public boolean batchShelveGoodsByIds(List<Integer> goodsIds) {
        if (goodsIds == null || goodsIds.isEmpty()) {
            return true;
        }

        // 批量更新商品状态为下架状态
        LambdaUpdateWrapper<SecondGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(SecondGoods::getId, goodsIds)
                .set(SecondGoods::getGoodsStatus, SecondGoodsStatusEnum.DELISTED.getCode());

        boolean updateResult = update(updateWrapper);

        if (updateResult) {
            // 批量查询更新后的商品信息
            Collection<SecondGoods> updatedGoodsList = listByIds(goodsIds);

            // 为每个商品记录操作历史并发送通知
            for (SecondGoods goods : updatedGoodsList) {
                recordGoodsOperation(goods, "风控下架");
                sendShelveMessage(goods);
            }
        }

        return updateResult;
    }

    /**
     * 根据风控记录中的JSON数据批量下架商品
     * @param ruleType 风控规则类型
     * @param businessId 业务ID
     * @return 是否下架成功
     */
    @Override
    public boolean batchShelveGoodsByRiskControlRecord(Integer ruleType, String businessId) {
        try {
            List<Integer> goodsIdList = Lists.newArrayList();
            // 获取相同类型的风控数据
            List<SecondRiskControlRecord> riskControlRecordList = riskControlService.getSameTypeRiskControlRecords(ruleType, businessId);
            // 获取风控数据详情
            List<String> detailInfoList = riskControlRecordList.stream()
                    .map(SecondRiskControlRecord::getDetailInfo)
                    .collect(Collectors.toList());

            // 声明所有被风控的商品ID
            List<Integer> idList = Lists.newArrayList();

            // 循环情信息json 转换为集合
            for (String detailInfo : detailInfoList){
                // 解析JSON获取商品ID列表
                List<Integer> ids = JSON.parseArray(detailInfo, Integer.class);
                idList.addAll(ids);
            }
            // goodsIdList 去重
            idList = idList.stream().distinct().collect(Collectors.toList());
            // 交易欺诈
            if (ruleType.equals(RiskControlRuleTypeEnum.TRANSACTION_FRAUD.getRuleType())){
                // 根据商品记录id集合查询商品Id 集合
                QueryWrapper<SecondGoodsRecord> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("id", idList);
                List<SecondGoodsRecord> goodsRecordList = secondGoodsRecordMapper.selectList(queryWrapper);
                // 获取商品Id集合
                List<Integer> goodsIds = goodsRecordList.stream().map(SecondGoodsRecord::getGoodsId).collect(Collectors.toList());
                // 去重
                goodsIds = goodsIds.stream().distinct().collect(Collectors.toList());
                goodsIdList.addAll(goodsIds);
                // 异常发布
            } else if (RiskControlRuleTypeEnum.ABNORMAL_PUBLISH.getRuleType().equals(ruleType)) {
                goodsIdList.addAll(idList);
            }
            // 调用批量下架方法
            return batchShelveGoodsByIds(goodsIdList);
        } catch (Exception e) {
            log.error("根据风控记录批量下架商品失败，详情: {}", ruleType, e);
            return false;
        }
    }

    /**
     * 下架商品
     * @param secondGoods 商品信息
     * @return 是否下架成功
     */
    @Override
    public boolean shelveSecondGoods(SecondGoodsVo secondGoods) {
        log.info("SecondGoodsServiceImpl.shelveSecondGoods?secondGoods={}", secondGoods.toString());
        // 修改商品状态为4 - 已下架
        secondGoods.setGoodsStatus(4);
        boolean updateResult = updateById(secondGoods);
        if (updateResult) {
            // 获取最新的商品信息并记录操作历史
            SecondGoods updatedGoods = getById(secondGoods.getId());
            recordGoodsOperation(updatedGoods, "下架商品");
            // 发送系统通知
            sendShelveMessage(updatedGoods);
            return true;
        } else {
            return false;
        }
    }


    /**
     * 发送商品下架消息
     * @param goods 商品信息
     */
    private void sendShelveMessage(SecondGoods goods) {
        try {
            // 根据 goods.getUserId() 获取用户信息
            LifeUser lifeUser = lifeUserMapper.selectById(goods.getUserId());
            String phone = lifeUser.getUserPhone();
            // 调取feign接口 发送消息 life_notice表
            LifeNotice lifeNotice = new LifeNotice();
            lifeNotice.setSenderId("system");
            lifeNotice.setReceiverId("user_"+ phone);
            lifeNotice.setBusinessId(goods.getId());
            lifeNotice.setTitle("商品下架通知");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("goodsId", goods.getId());
//            jsonObject.put("status", "true");
            jsonObject.put("message", "您的商品："+ goods.getTitle() + "已下架");
            lifeNotice.setContext(jsonObject.toJSONString());
            lifeNotice.setNoticeType(Constants.Notice.SYSTEM_NOTICE); // 系统通知
            lifeNotice.setIsRead(0);
            lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
            lifeNoticeMapper.insert(lifeNotice);
            sendShelveNotice("user_"+ phone, lifeNotice);
        } catch (Exception e) {
            log.error("发送消息通知失败，goods: {}", goods, e);
        }
    }

    /**
     * 发送下架通知
     * @param receiverId 接收者ID
     * @param lifeNotice 通知内容
     */
    private void sendShelveNotice(String receiverId, LifeNotice lifeNotice) {
        try {
            WebSocketVo webSocketVo = new WebSocketVo();
            webSocketVo.setSenderId("system");
            webSocketVo.setReceiverId(receiverId);
            webSocketVo.setCategory("notice");
            webSocketVo.setNoticeType("1");
            webSocketVo.setIsRead(0);
            webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
            alienStoreFeign.sendMsgToClientByPhoneId(receiverId, JSONObject.from(webSocketVo).toJSONString());
        } catch (Exception e) {
            log.error("发送消息通知失败，receiverId: {}", receiverId, e);
        }
    }

}