吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1535|回复: 15
收起左侧

[其他原创] 油猴脚本-元宝Ai问题列表

  [复制链接]
violetlength 发表于 2026-3-19 11:26
本帖最后由 violetlength 于 2026-3-19 11:28 编辑

功能:在元宝AI对话窗口,当一个对话中含有多个问题时,可以提取展示对应的问题列表;并定位问题;

如何使用:
把代码添加到油猴,即可使用
[JavaScript] 纯文本查看 复制代码
// ==UserScript==
// @name         AI对话问题提取器(元宝专用)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description 展示当前对话,都有哪些问题,点击定位问题
// @AuThor       violetlength
// @match        *://yuanbao.tencent.com/*
// @match        *://*.yuanbao.tencent.com/*
// @grant        GM_addStyle
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // ========== 配置区域 ==========
    const CONFIG = {
        sidebarWidth: 380,
        position: 'right',
        autoExtract: true,
        debug: true
    };

    // ========== 元宝专用选择器 ==========
    const YUANBAO_SELECTORS = {
        userQuestionSelector: 'div[data-conv-speaker="human"]',
        questionTextSelector: '.hyc-content-text',
        questionContainerSelector: '.agent-chat__bubble__content'
    };

    // ========== 全局变量 ==========
    let sidebar = null;
    let toggleBtn = null;
    let currentQuestions = [];

    // ========== 样式定义 ==========
    GM_addStyle(`
        /* 浮动按钮 - 确保显示 */
        #toggle-sidebar-btn {
            position: fixed;
            ${CONFIG.position}: 20px;
            bottom: 30px;
            width: 56px;
            height: 56px;
            border-radius: 50%;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            cursor: pointer;
            box-shadow: 0 6px 24px rgba(102, 126, 234, 0.45);
            z-index: 2147483646;
            font-size: 22px;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 1;
            visibility: visible;
            transform: scale(1);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        #toggle-sidebar-btn:hover {
            transform: scale(1.15);
            box-shadow: 0 8px 32px rgba(102, 126, 234, 0.55);
        }

        #toggle-sidebar-btn:active {
            transform: scale(1.05);
        }

        /* 侧边栏 - 固定高度,带滚动条 */
        #ai-question-sidebar {
            position: fixed;
            top: 0;
            ${CONFIG.position}: -${CONFIG.sidebarWidth + 50}px;
            width: ${CONFIG.sidebarWidth}px;
            height: 100vh; /* 固定高度为视口高度 */
            background: #ffffff;
            box-shadow: -4px 0 20px rgba(0,0,0,0.15);
            z-index: 2147483647;
            overflow-y: auto; /* 侧边栏整体滚动 */
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            transition: ${CONFIG.position} 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            border: 1px solid #e2e8f0;
        }

        #ai-question-sidebar.visible {
            ${CONFIG.position}: 0 !important;
        }

        /* 侧边栏头部 - 固定 */
        .sidebar-header {
            position: sticky;
            top: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 16px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 10;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .sidebar-header h3 {
            margin: 0;
            font-size: 16px;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .platform-badge {
            background: rgba(255,255,255,0.25);
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 500;
        }

        .close-btn {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
            flex-shrink: 0;
        }

        .close-btn:hover {
            background: rgba(255,255,255,0.35);
            transform: rotate(90deg);
        }

        /* 问题列表容器 - 确保宽度限制 + 禁止横向滚动 */
.question-list-container {
  padding: 12px;
  max-height: calc(100vh - 140px);
  max-width: 100%;   /* 限制容器最大宽度(父级可用宽度) */
  overflow-y: auto;  /* 垂直滚动 */
  overflow-x: hidden;/* 禁止横向滚动条 */
  box-sizing: border-box;
}

/* 单个问题项 - 宽度100% + 包含内边距/边框 */
.question-item {
  background: #f8f9fa;
  border-left: 4px solid #667eea;
  margin-bottom: 12px;
  padding: 14px;
  border-radius: 0 8px 8px 0;
  cursor: pointer;
  transition: all 0.2s;
  width: 100%;       /* 强制占满父容器宽度 */
  box-sizing: border-box; /* padding/border 包含在宽度内 */
  display: flex;     /* 让序号、文本、时间横向排列(可选,根据布局) */
  align-items: flex-start; /* 垂直对齐顶部 */
}

/* 序号 - 固定尺寸,避免挤压文本 */
.question-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  width: 24px;
  height: 24px;
  line-height: 24px;
  text-align: center;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 600;
  margin-right: 10px;
  flex-shrink: 0;    /* 序号不收缩,固定宽度 */
}

/* 问题文本 - 单行省略号核心样式 */
.question-text {
  display: inline-block;
  vertical-align: middle;
  white-space: nowrap;   /* 强制单行显示 */
  overflow: hidden;      /* 隐藏溢出内容 */
  text-overflow: ellipsis; /* 溢出显示省略号 */
  font-size: 13px;
  line-height: 1.6;
  color: #334155;
  flex: 1;               /* 占据剩余空间(配合父级 display:flex) */
  min-width: 0;          /* 关键!防止 flex 子项被内容撑开(旧版浏览器兼容) */
}

/* 时间 - 独立行,不影响文本单行 */
.question-time {
  display: block;
  font-size: 11px;
  color: #94a3b8;
  margin-top: 8px;
  margin-left: 34px; /* 与序号宽度+间距对齐 */
}

        /* 空状态 */
        .empty-state {
            text-align: center;
            padding: 40px 20px;
            color: #64748b;
        }

        .empty-state svg {
            width: 80px;
            height: 80px;
            margin-bottom: 20px;
            opacity: 0.4;
        }

        .empty-state p {
            margin: 0;
            font-size: 14px;
        }

        .empty-state .hint {
            font-size: 12px;
            color: #94a3b8;
            margin-top: 8px;
        }

        /* 加载动画 */
        .loading {
            text-align: center;
            padding: 40px 20px;
        }

        .spinner {
            width: 40px;
            height: 40px;
            border: 4px solid #f1f5f9;
            border-top: 4px solid #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 0 auto 16px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        /* 滚动条美化 */
        #ai-question-sidebar::-webkit-scrollbar,
        .question-list-container::-webkit-scrollbar {
            width: 8px;
        }

        #ai-question-sidebar::-webkit-scrollbar-track,
        .question-list-container::-webkit-scrollbar-track {
            background: #f1f5f9;
            border-radius: 4px;
        }

        #ai-question-sidebar::-webkit-scrollbar-thumb,
        .question-list-container::-webkit-scrollbar-thumb {
            background: linear-gradient(135deg, #cbd5e1 0%, #94a3b8 100%);
            border-radius: 4px;
        }

        #ai-question-sidebar::-webkit-scrollbar-thumb:hover,
        .question-list-container::-webkit-scrollbar-thumb:hover {
            background: linear-gradient(135deg, #94a3b8 0%, #64748b 100%);
        }

        /* 遮罩层 */
        #sidebar-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.3);
            z-index: 2147483645;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s;
        }

        #sidebar-overlay.visible {
            opacity: 1;
            visibility: visible;
        }

        /* 头部统计 */
        .header-stats {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .question-count {
            background: rgba(255,255,255,0.25);
            padding: 4px 10px;
            border-radius: 12px;
            font-size: 12px;
            font-weight: 500;
        }

        .refresh-btn {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            width: 28px;
            height: 28px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
        }

        .refresh-btn:hover {
            background: rgba(255,255,255,0.35);
            transform: rotate(180deg);
        }
    `);

    // ========== 核心功能 ==========

    /**
     * 提取元宝对话中的问题
     */
    function extractYuanbaoQuestions() {
        console.log('🔍 开始提取元宝对话问题...');

        const questions = [];
        const elements = document.querySelectorAll(YUANBAO_SELECTORS.userQuestionSelector);

        console.log(`📋 找到 ${elements.length} 个用户消息元素`);

        elements.forEach((el, index) => {
            if (!el) return;

            // 优先查找 .hyc-content-text
            let textEl = el.querySelector(YUANBAO_SELECTORS.questionTextSelector);
            let text = '';

            if (textEl) {
                text = textEl.innerText.trim();
            } else {
                // 备用:查找 bubble content
                const content = el.querySelector(YUANBAO_SELECTORS.questionContainerSelector);
                if (content) {
                    text = content.innerText.trim();
                } else {
                    // 最后备用:直接取元素文本
                    text = el.innerText.trim();
                }
            }

            if (text && text.length > 5 && !questions.some(q => q.text === text)) {
                questions.push({
                    id: index,
                    text: text,
                    element: el,
                    timestamp: new Date().toLocaleTimeString()
                });
            }
        });

        console.log(`✅ 提取到 ${questions.length} 个问题`);
        return questions;
    }

    /**
     * 创建浮动按钮
     */
    function createFloatingButton() {
        if (toggleBtn) return toggleBtn;

        toggleBtn = document.createElement('button');
        toggleBtn.id = 'toggle-sidebar-btn';
        toggleBtn.innerHTML = '📋';
        toggleBtn.title = '显示/隐藏问题列表';
        toggleBtn.style.display = 'flex';
        toggleBtn.style.visibility = 'visible';
        toggleBtn.style.opacity = '1';

        toggleBtn.addEventListener('click', () => {
            toggleSidebar();
        });

        document.body.appendChild(toggleBtn);
        console.log('✅ 浮动按钮已创建');
        return toggleBtn;
    }

    /**
     * 创建侧边栏
     */
    function createSidebar() {
        if (sidebar) return sidebar;

        sidebar = document.createElement('div');
        sidebar.id = 'ai-question-sidebar';
        sidebar.innerHTML = `
            <div class="sidebar-header">
                <h3>
                    问题列表
                </h3>
                <div class="header-stats">
                    <span class="question-count" id="question-count">0 个问题</span>
                    <button class="refresh-btn" id="refresh-btn" title="刷新列表">&#8635;</button>
                    <button class="close-btn" id="close-sidebar" title="关闭">×</button>
                </div>
            </div>
            <div class="question-list-container" id="question-list">
                <div class="empty-state">
                    <svg viewBox="0 0 24 24" fill="currentColor">
                        <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
                    </svg>
                    <p>点击"刷新"按钮开始提取</p>
                    <p class="hint">支持元宝平台</p>
                </div>
            </div>
        `;

        document.body.appendChild(sidebar);

        // 绑定事件
        document.getElementById('close-sidebar').addEventListener('click', hideSidebar);
        document.getElementById('refresh-btn').addEventListener('click', refreshQuestions);

        // 遮罩层点击关闭
        const overlay = document.getElementById('sidebar-overlay');
        if (overlay) {
            overlay.addEventListener('click', hideSidebar);
        } else {
            // 创建遮罩层
            const newOverlay = document.createElement('div');
            newOverlay.id = 'sidebar-overlay';
            newOverlay.addEventListener('click', hideSidebar);
            document.body.appendChild(newOverlay);
        }

        console.log('&#9989; 侧边栏已创建');
        return sidebar;
    }

    /**
     * 渲染问题列表
     */
    function renderQuestions(questions) {
        const listContainer = document.getElementById('question-list');
        const countElement = document.getElementById('question-count');

        if (!listContainer || !countElement) return;

        countElement.textContent = `${questions.length} 个问题`;

        if (questions.length === 0) {
            listContainer.innerHTML = `
                <div class="empty-state">
                    <svg viewBox="0 0 24 24" fill="currentColor">
                        <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
                    </svg>
                    <p>未找到问题</p>
                    <p class="hint">请确保页面已加载对话内容</p>
                </div>
            `;
            currentQuestions = [];
            return;
        }

        const listHTML = questions.map((q, i) => `
            <div class="question-item" data-index="${i}" data-id="${q.id}" data-full-text="${escapeHtml(q.text)}">
                <span class="question-index">${i + 1}</span>
                <span class="question-text" title="${escapeHtml(q.text)}">${escapeHtml(q.text)}</span>
            </div>
        `).join('');

        listContainer.innerHTML = listHTML;
        currentQuestions = questions;

        // 绑定点击事件
        const questionItems = listContainer.querySelectorAll('.question-item');
        questionItems.forEach((item, index) => {
            item.addEventListener('click', () => {
                const q = questions[index];
                if (q && q.element) {
                    q.element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                }
            });
        });
    }

    /**
     * 转义HTML
     */
    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    /**
     * 显示侧边栏
     */
    function showSidebar() {
        if (sidebar) {
            sidebar.classList.add('visible');
            const overlay = document.getElementById('sidebar-overlay');
            if (overlay) overlay.classList.add('visible');
            console.log('&#9989; 侧边栏已显示');
        }
    }

    /**
     * 隐藏侧边栏
     */
    function hideSidebar() {
        if (sidebar) {
            sidebar.classList.remove('visible');
            const overlay = document.getElementById('sidebar-overlay');
            if (overlay) overlay.classList.remove('visible');
            console.log('&#9989; 侧边栏已隐藏');
        }
    }

    /**
     * 切换侧边栏显示/隐藏
     * 新增:从隐藏切换到显示时自动刷新问题列表
     */
    function toggleSidebar() {
        if (!sidebar) {
            createSidebar();
        }

        const isCurrentlyHidden = !sidebar.classList.contains('visible');

        if (isCurrentlyHidden) {
            // 即将显示,先刷新数据
            console.log('&#128260; 侧边栏即将展开,自动刷新问题列表...');
            refreshQuestions();
            showSidebar();
        } else {
            // 即将隐藏
            hideSidebar();
        }

        console.log(`&#128260; 侧边栏状态: ${isCurrentlyHidden ? '显示' : '隐藏'}`);
    }

    /**
     * 刷新问题列表
     */
    function refreshQuestions() {
        console.log('&#128260; 刷新问题列表...');
        createSidebar();
        const questions = extractYuanbaoQuestions();
        renderQuestions(questions);
    }

    /**
     * 主函数
     */
    function main() {
        console.log('&#128640; AI对话问题提取器(元宝完善版)v4.1 已加载');
        console.log('&#128205; 当前页面:', window.location.href);

        // 创建浮动按钮
        createFloatingButton();

        // 自动提取
        if (CONFIG.autoExtract) {
            setTimeout(() => {
                refreshQuestions();
            }, 2000);
        }

        // 暴露全局方法
        window.AIQuestionExtractor = {
            refresh: refreshQuestions,
            show: showSidebar,
            hide: hideSidebar,
            toggle: toggleSidebar,
            debug: () => {
                console.log('&#128269; 匹配元素数量:', document.querySelectorAll(YUANBAO_SELECTORS.userQuestionSelector).length);
                console.log('&#128203; 当前问题列表:', currentQuestions.length);
            }
        };

        console.log('&#128161; 调试命令:');
        console.log('   AIQuestionExtractor.refresh() - 手动刷新');
        console.log('   AIQuestionExtractor.toggle() - 切换显示/隐藏');
        console.log('   AIQuestionExtractor.debug() - 查看调试信息');
    }

    // 启动脚本
    main();

})();


47cad788-f6fb-408e-9a77-6d79d3fb4f77.png
34146402-bc29-46fe-ac66-5cac3cf672e2.png

免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
abca123 + 1 我很赞同!
981930674 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ZhangPuBi 发表于 2026-3-19 13:45
看上去挺有意思的,大佬厉害。
pingda 发表于 2026-3-19 14:18
javasmx626 发表于 2026-3-19 14:36
cuist77 发表于 2026-3-19 14:55
感谢分享。用下试试
wuyeaizhea5521 发表于 2026-3-19 14:57
感谢分享,使用了
头像被屏蔽
long769 发表于 2026-3-19 15:15
提示: 作者被禁止或删除 内容自动屏蔽
lynne1168207 发表于 2026-3-19 15:18
看上去挺有意思的,大佬厉害。
xxx123444 发表于 2026-3-19 16:11
不错的创意
jake77 发表于 2026-3-19 20:35
感谢分享,试一下。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-10 11:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表