<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI助手</title>
<!-- 引入外部资源 -->
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<style>
/* ==================== 基础样式 ==================== */
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
/* ==================== AI助手样式 ==================== */
/* 会动的小人样式 */
.ai-assistant {
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
z-index: 1000;
transition: all 0.3s ease;
animation: float 3s ease-in-out infinite, pulse 2s infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.ai-assistant:hover {
transform: translateY(-5px) scale(1.1);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
}
.ai-assistant i {
font-size: 1.5rem;
}
/* ==================== 聊天窗口样式 ==================== */
.chat-container {
position: fixed;
bottom: 105px;
right: 30px;
width: 420px;
height: 600px;
background-color: white;
border-radius: 20px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
display: flex;
flex-direction: column;
overflow: hidden;
transform: scale(0);
transform-origin: bottom right;
opacity: 0;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
z-index: 999;
border: none;
background: #f8f9fa;
display: none;
}
.chat-container.active {
transform: scale(1);
opacity: 1;
display: flex;
}
.chat-container.minimized {
transform: translateY(calc(100% - 40px)) scale(1);
opacity: 1;
height: 40px;
overflow: hidden;
}
.chat-container.fullscreen {
width: 100vw;
height: 100vh;
bottom: 0;
right: 0;
border-radius: 0;
}
.chat-header {
background: #ffffff;
padding: 12px 24px 12px 15px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
border-bottom: 1px solid #e9ecef;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
flex-shrink: 0;
}
.chat-header h2 {
margin: 0;
color: #1a1a2e;
font-weight: 600;
letter-spacing: -0.5px;
font-size: 16px;
text-align: center;
flex: 1;
padding: 0 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.window-controls {
display: flex;
gap: 8px;
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
}
.window-btn {
width: 12px;
height: 12px;
border-radius: 50%;
border: none;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.1);
}
.close-btn {
background-color: #ff5f56;
border: 0.5px solid #e0443e;
}
.close-btn:hover {
background-color: #ff3b30;
}
.minimize-btn {
background-color: #ffbd2e;
border: 0.5px solid #d6a123;
}
.minimize-btn:hover {
background-color: #ffa700;
}
.fullscreen-btn {
background-color: #27c93f;
border: 0.5px solid #1dad2b;
}
.fullscreen-btn:hover {
background-color: #1aad2b;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 20px;
background-color: #f8f9fa;
scroll-behavior: smooth;
}
.chat-messages::-webkit-scrollbar {
width: 6px;
}
.chat-messages::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.05);
border-radius: 3px;
}
.chat-messages::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 3px;
}
.message {
margin-bottom: 16px;
padding: 14px 20px;
border-radius: 20px;
max-width: 85%;
word-wrap: break-word;
position: relative;
line-height: 1.6;
font-size: 15px;
color: #1a1a2e;
background: #ffffff;
border: 1px solid #e9ecef;
box-shadow: 0 2px 12px rgba(67, 97, 238, 0.08);
}
.user-message {
margin-left: auto;
border-radius: 20px 20px 4px 20px;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: white;
border: none;
}
.bot-message {
margin-right: auto;
border-radius: 20px 20px 20px 4px;
}
.message-time {
font-size: 12px;
color: #6c757d;
margin-top: 8px;
text-align: right;
}
.error-message {
color: #e53e3e;
background-color: #fff5f5;
padding: 12px 16px;
border-radius: 12px;
margin: 10px 0;
font-size: 13px;
border: 1px solid rgba(229, 62, 62, 0.2);
}
/* ==================== 输入区域样式 ==================== */
.chat-input-container {
display: flex;
flex-direction: column;
padding: 15px;
background: rgba(255, 255, 255, 0.9);
border-top: 1px solid #e9ecef;
flex-shrink: 0;
position: relative;
}
/* 隐藏输入框滚动条 */
#message-input::-webkit-scrollbar {
display: none; /* 隐藏滚动条但保留滚动功能 */
}
/* 处理进度提示样式调整到输入框上方 */
.processing-container {
position: absolute;
top: -40px;
left: 15px;
right: 15px;
z-index: 1;
}
.processing-message {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
background: #ffffff;
border-radius: 8px;
font-size: 13px;
color: #4b5563;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e9ecef;
width: 100%;
box-sizing: border-box;
animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.processing-message i {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.input-actions {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.action-button {
background: none;
border: none;
color: #6b7280;
cursor: pointer;
font-size: 14px;
padding: 6px 10px;
border-radius: 8px;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 6px;
}
.action-button:hover {
background: #f3f4f6;
color: #4f46e5;
}
.action-button.highlight {
background: #e0e7ff;
color: #4f46e5;
}
.action-button.highlight:hover {
background: #c7d2fe;
}
.badge {
background: #ef4444;
color: white;
border-radius: 50%;
width: 18px;
height: 18px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
margin-left: 4px;
}
.input-wrapper {
display: flex;
align-items: flex-end;
gap: 8px;
}
#message-input {
flex: 1;
padding: 12px 18px;
border: 1px solid #e9ecef;
border-radius: 20px;
outline: none;
font-size: 14px;
color: #1a1a2e;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: rgba(255, 255, 255, 0.6);
resize: none;
min-height: 44px;
max-height: 120px;
overflow-y: auto;
-ms-overflow-style: none; /* IE和Edge隐藏滚动条 */
scrollbar-width: none; /* Firefox隐藏滚动条 */
}
#message-input:focus {
border-color: #6366f1;
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.15);
}
#send-button {
margin-left: 12px;
padding: 0;
width: 44px;
height: 44px;
background-color: #6366f1;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(67, 97, 238, 0.25);
}
#send-button:hover {
background-color: #4f46e5;
transform: scale(1.05);
}
#send-button:disabled {
background-color: #c7d2fe;
cursor: not-allowed;
transform: none;
}
.file-preview {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 8px;
padding: 8px;
background: rgba(99, 102, 241, 0.05);
border-radius: 8px;
border: 1px dashed #c7d2fe;
}
.file-preview-item {
display: flex;
align-items: center;
padding: 6px 10px;
background: white;
border-radius: 6px;
font-size: 13px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.file-preview-item i {
margin-right: 8px;
color: #6366f1;
}
.remove-file-btn {
margin-left: auto;
color: #9ca3af;
cursor: pointer;
transition: color 0.2s;
}
.remove-file-btn:hover {
color: #ef4444;
}
/* ==================== 扩展面板样式 ==================== */
/* 修改后的扩展面板样式 - 居中显示在视窗中 */
.extensions-panel {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 居中定位 */
width: 360px;
max-height: 400px;
background: white;
border-radius: 12px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
z-index: 1001;
display: none;
opacity: 0;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
flex-direction: column;
overflow: hidden;
border: 1px solid #e9ecef;
}
.extensions-panel.active {
transform: translate(-50%, -50%); /* 保持居中 */
opacity: 1;
display: flex;
}
.extensions-header {
padding: 12px 16px;
border-bottom: 1px solid #e9ecef;
display: flex;
justify-content: space-between;
align-items: center;
}
.extensions-title {
font-weight: 600;
color: #1a1a2e;
}
.close-extensions {
background: none;
border: none;
color: #6b7280;
cursor: pointer;
font-size: 16px;
padding: 4px;
border-radius: 50%;
transition: all 0.2s;
}
.close-extensions:hover {
background: #f3f4f6;
color: #6366f1;
}
.extensions-scroll-area {
flex: 1;
overflow-y: auto;
padding: 12px;
}
.extension-item {
display: flex;
padding: 12px;
border-radius: 8px;
margin-bottom: 8px;
transition: all 0.2s;
border: 1px solid #e9ecef;
}
.extension-item:hover {
background: #f9fafb;
border-color: #e0e7ff;
}
.extension-icon {
width: 40px;
height: 40px;
border-radius: 8px;
background: #f3f4f6;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
flex-shrink: 0;
overflow: hidden;
}
.extension-icon img {
width: 100%;
height: 100%;
object-fit: cover;
}
.extension-content {
flex: 1;
min-width: 0;
}
.extension-name {
font-weight: 600;
margin-bottom: 4px;
color: #1a1a2e;
}
.extension-description {
font-size: 12px;
color: #6b7280;
line-height: 1.4;
}
.add-button {
margin-left: 12px;
padding: 6px 12px;
background: #6366f1;
color: white;
border: none;
border-radius: 6px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s;
white-space: nowrap;
align-self: center;
}
.add-button:hover {
background: #4f46e5;
}
.add-button.added {
background: #10b981;
}
.add-button.added:hover {
background: #059669;
}
/* ==================== 选项按钮样式 ==================== */
.option-buttons {
display: flex;
gap: 8px;
margin-top: 8px;
flex-wrap: wrap;
}
.option-button {
padding: 8px 12px;
background: #e0e7ff;
color: #4f46e5;
border: none;
border-radius: 6px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s;
}
.option-button:hover {
background: #c7d2fe;
}
/* 修改后的下载按钮样式 - 居中显示 */
.download-btn {
display: block; /* 改为块级元素 */
margin: 8px auto 0; /* 上下边距8px,左右自动居中 */
padding: 8px 16px;
background: #6366f1;
color: white;
border: none;
border-radius: 6px;
font-size: 13px;
cursor: pointer;
transition: all 0.2s;
width: fit-content; /* 宽度适应内容 */
text-align: center; /* 文本居中 */
}
.download-btn:hover {
background: #4f46e5;
}
.download-btn i {
margin-right: 6px;
}
/* ==================== 图片预览样式 ==================== */
.image-preview {
max-width: 100%;
max-height: 200px;
border-radius: 8px;
border: 1px solid #e9ecef;
margin: 8px auto;
display: block;
object-fit: contain;
}
/* ==================== 夜间模式样式 ==================== */
body.dark-mode .chat-container {
background: #1e293b;
}
body.dark-mode .chat-header {
background: #1e293b;
border-bottom: 1px solid #334155;
}
body.dark-mode .chat-header h2 {
color: #f8fafc;
}
body.dark-mode .chat-messages {
background: #1e293b;
}
body.dark-mode .message {
background: #0f172a;
color: #f8fafc;
border: 1px solid #334155;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
}
body.dark-mode .message-time {
color: #94a3b8;
}
body.dark-mode .chat-input-container {
background: #1e293b;
border-top: 1px solid #334155;
}
body.dark-mode #message-input {
background: #0f172a;
color: #f8fafc;
border: 1px solid #334155;
}
body.dark-mode #message-input:focus {
border-color: #818cf8;
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.2);
}
body.dark-mode .error-message {
background: #1e1b4b;
color: #a5b4fc;
border: 1px solid #4338ca;
}
body.dark-mode .extensions-panel {
background: #1e293b;
border-color: #334155;
}
body.dark-mode .extensions-header {
border-bottom-color: #334155;
}
body.dark-mode .extensions-title {
color: #f8fafc;
}
body.dark-mode .close-extensions {
color: #94a3b8;
}
body.dark-mode .close-extensions:hover {
background: #334155;
color: #818cf8;
}
body.dark-mode .extensions-scroll-area {
background: #1e293b;
}
body.dark-mode .extension-item {
background: #0f172a;
border-color: #334155;
}
body.dark-mode .extension-item:hover {
background: #1e293b;
border-color: #475569;
}
body.dark-mode .extension-icon {
background: #1e293b;
}
body.dark-mode .extension-name {
color: #f8fafc;
}
body.dark-mode .extension-description {
color: #94a3b8;
}
body.dark-mode .option-button {
background: #1e293b;
color: #818cf8;
}
body.dark-mode .option-button:hover {
background: #334155;
}
body.dark-mode .file-preview {
background: rgba(99, 102, 241, 0.1);
border-color: #334155;
}
body.dark-mode .file-preview-item {
background: #1e293b;
color: #f8fafc;
}
body.dark-mode .action-button {
color: #94a3b8;
}
body.dark-mode .action-button:hover {
background: #1e293b;
color: #818cf8;
}
body.dark-mode .action-button.highlight {
background: #1e293b;
color: #818cf8;
}
body.dark-mode .action-button.highlight:hover {
background: #334155;
}
body.dark-mode .processing-message {
background: #1e293b;
color: #cbd5e1;
}
/* ==================== 响应式设计 ==================== */
@media (max-width: 480px) {
.chat-container {
width: 95vw;
right: 2.5vw;
bottom: 100px;
height: 70vh;
}
.extensions-panel {
width: 90vw;
max-height: 60vh;
}
.image-preview {
max-height: 150px;
}
}
/* 新增样式 */
.hidden {
display: none !important;
}
</style>
</head>
<body class="light-mode">
<!-- AI助手小人 -->
<div class="ai-assistant" id="ai-assistant">
<i class="fas fa-robot"></i>
</div>
<!-- AI助手聊天窗口 -->
<div class="chat-container" id="chat-container">
<div class="chat-header">
<div class="window-controls">
<button class="window-btn close-btn" id="close-btn"></button>
<button class="window-btn minimize-btn" id="minimize-btn"></button>
<button class="window-btn fullscreen-btn" id="fullscreen-btn"></button>
</div>
<h2>AI助手</h2>
</div>
<!-- 聊天消息区域 -->
<div class="chat-messages" id="chat-messages">
<!-- AI欢迎消息 -->
<div class="message bot-message">
您好!我是AI助手,我可以帮您转换图片格式或解析视频。请先添加相应的扩展功能。
<div class="message-time">今天 10:30</div>
</div>
</div>
<!-- 输入区域 -->
<div class="chat-input-container">
<!-- 处理进度提示容器 -->
<div class="processing-container">
<div class="processing-message hidden" id="processing-message">
<i class="fas fa-spinner"></i>
<span>正在处理您的请求...</span>
</div>
</div>
<div class="input-actions">
<button class="action-button" id="attach-button">
<i class="fas fa-paperclip"></i>
<span>附件</span>
</button>
<button class="action-button highlight" id="extend-button">
<i class="fas fa-puzzle-piece"></i>
<span>扩展</span>
<div class="badge">2</div>
</button>
</div>
<div class="input-wrapper">
<textarea id="message-input" placeholder="发送消息..."></textarea>
<button id="send-button" disabled>
<i class="fas fa-paper-plane"></i>
</button>
</div>
<!-- 文件预览区域 -->
<div class="file-preview hidden" id="file-preview"></div>
<!-- 隐藏的文件输入 -->
<input type="file" id="file-input" class="hidden" accept="image/*,video/*,audio/*" multiple>
</div>
</div>
<!-- 扩展面板 -->
<div class="extensions-panel" id="extensions-panel">
<div class="extensions-header">
<div class="extensions-title">添加扩展</div>
<button class="close-extensions" id="close-extensions">
<i class="fas fa-times"></i>
</button>
</div>
<div class="extensions-scroll-area">
<!-- 图片格式转换 -->
<div class="extension-item" id="image-converter">
<div class="extension-icon">
<img src="https://lf3-appstore-sign.oceancloudapi.com/ocean-cloud-tos/FileBizType.BIZ_BOT_WORKFLOW/1682717607724762_1744706486858059414_2qmmg0xEV9.png?lk3s=cd508e2b&x-expires=2061097613&x-signature=62GS9dYBZw7OyrsN2HtZ5s8XtMo%3D" alt="图片格式转换">
</div>
<div class="extension-content">
<div class="extension-name">图片格式转换</div>
<div class="extension-description">可生成高质量的图片,也可以编辑已有的图片,支持JPG、PNG、WEBP等多种格式转换</div>
</div>
<button class="add-button" id="image-converter-btn">
<i class="fas fa-plus"></i> 添加
</button>
</div>
<!-- 影视解析 -->
<div class="extension-item" id="video-parser">
<div class="extension-icon">
<img src="https://lf9-appstore-sign.oceancloudapi.com/ocean-cloud-tos/plugin_icon/3732214325715875_1703131669996743697_6V4mnfwUUf.png?lk3s=cd508e2b&x-expires=2061097613&x-signature=yb3na%2Fk6ZOLgOEzhqR4CGIXKMTY%3D" alt="影视解析">
</div>
<div class="extension-content">
<div class="extension-name">影视解析</div>
<div class="extension-description">查询全球影视资源,支持各大平台视频解析,获取高清播放链接</div>
</div>
<button class="add-button" id="video-parser-btn">
<i class="fas fa-plus"></i> 添加
</button>
</div>
</div>
</div>
<script>
// ==================== AI助手功能 ====================
document.addEventListener('DOMContentLoaded', function() {
const aiAssistant = {
/**
* 初始化AI助手
*/
init: function() {
this.extensions = {
imageConverter: false,
videoParser: false
};
this.currentFiles = [];
this.isMinimized = false;
// 设置事件监听器
this.setupEventListeners();
// 恢复聊天窗口状态
this.restoreChatState();
// 初始化输入框高度
this.adjustTextareaHeight();
// 更新扩展数量徽章
this.updateExtensionBadge();
},
/**
* 恢复聊天窗口状态
*/
restoreChatState: function() {
const chatState = localStorage.getItem('chatState');
if (chatState) {
const { minimized, fullscreen } = JSON.parse(chatState);
const chatContainer = document.getElementById('chat-container');
this.isMinimized = minimized;
if (fullscreen) {
chatContainer.classList.add('fullscreen');
}
if (minimized) {
chatContainer.classList.add('minimized');
} else {
chatContainer.classList.remove('minimized');
}
}
},
/**
* 保存聊天窗口状态
*/
saveChatState: function() {
const chatContainer = document.getElementById('chat-container');
const chatState = {
minimized: this.isMinimized,
fullscreen: chatContainer.classList.contains('fullscreen')
};
localStorage.setItem('chatState', JSON.stringify(chatState));
},
/**
* 设置事件监听器
*/
setupEventListeners: function() {
const aiAssistantBtn = document.getElementById('ai-assistant');
const chatContainer = document.getElementById('chat-container');
const closeBtn = document.getElementById('close-btn');
const minimizeBtn = document.getElementById('minimize-btn');
const fullscreenBtn = document.getElementById('fullscreen-btn');
const sendButton = document.getElementById('send-button');
const messageInput = document.getElementById('message-input');
const fileInput = document.getElementById('file-input');
const attachButton = document.getElementById('attach-button');
const extendButton = document.getElementById('extend-button');
const extensionsPanel = document.getElementById('extensions-panel');
const closeExtensions = document.getElementById('close-extensions');
const imageConverterBtn = document.getElementById('image-converter-btn');
const videoParserBtn = document.getElementById('video-parser-btn');
// 主按钮点击事件 - 切换聊天窗口显示/隐藏
aiAssistantBtn.addEventListener('click', () => this.toggleChat());
// 窗口控制按钮事件
closeBtn.addEventListener('click', () => this.closeChat());
minimizeBtn.addEventListener('click', () => this.minimizeChat());
fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
// 消息发送事件
sendButton.addEventListener('click', () => this.sendMessage());
messageInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
});
// 输入框内容变化事件
messageInput.addEventListener('input', () => {
sendButton.disabled = messageInput.value.trim() === '' && this.currentFiles.length === 0;
this.adjustTextareaHeight();
});
// 附件按钮事件
attachButton.addEventListener('click', () => fileInput.click());
// 文件上传事件
fileInput.addEventListener('change', (e) => this.handleFileUpload(e));
// 扩展按钮事件
extendButton.addEventListener('click', () => this.toggleExtensionsPanel());
// 关闭扩展面板按钮
closeExtensions.addEventListener('click', () => this.hideExtensionsPanel());
// 扩展添加按钮事件
imageConverterBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleExtension('imageConverter', imageConverterBtn);
});
videoParserBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleExtension('videoParser', videoParserBtn);
});
// 点击文档其他地方关闭扩展面板
document.addEventListener('click', (e) => {
if (!e.target.closest('#extensions-panel') && !e.target.closest('#extend-button')) {
this.hideExtensionsPanel();
}
});
},
/**
* 切换聊天窗口显示/隐藏
*/
toggleChat: function() {
const chatContainer = document.getElementById('chat-container');
const aiAssistantBtn = document.getElementById('ai-assistant');
if (chatContainer.classList.contains('active')) {
chatContainer.classList.remove('active');
setTimeout(() => {
chatContainer.style.display = 'none';
aiAssistantBtn.style.display = 'flex';
}, 300);
} else {
// 如果之前是最小化状态,先恢复窗口
if (this.isMinimized) {
chatContainer.classList.remove('minimized');
this.isMinimized = false;
this.saveChatState();
}
chatContainer.style.display = 'flex';
setTimeout(() => {
chatContainer.classList.add('active');
document.getElementById('message-input').focus();
}, 10);
aiAssistantBtn.style.display = 'none';
}
},
/**
* 关闭聊天窗口
*/
closeChat: function() {
const chatContainer = document.getElementById('chat-container');
const aiAssistantBtn = document.getElementById('ai-assistant');
chatContainer.classList.remove('active');
setTimeout(() => {
chatContainer.style.display = 'none';
aiAssistantBtn.style.display = 'flex';
}, 300);
},
/**
* 最小化/恢复聊天窗口
*/
minimizeChat: function() {
const chatContainer = document.getElementById('chat-container');
this.isMinimized = !this.isMinimized;
if (this.isMinimized) {
chatContainer.classList.add('minimized');
} else {
chatContainer.classList.remove('minimized');
}
this.saveChatState();
},
/**
* 切换全屏模式
*/
toggleFullscreen: function() {
const chatContainer = document.getElementById('chat-container');
chatContainer.classList.toggle('fullscreen');
this.saveChatState();
},
/**
* 显示/隐藏扩展面板
*/
toggleExtensionsPanel: function() {
const extensionsPanel = document.getElementById('extensions-panel');
if (extensionsPanel.classList.contains('active')) {
this.hideExtensionsPanel();
} else {
extensionsPanel.style.display = 'flex';
setTimeout(() => {
extensionsPanel.classList.add('active');
}, 10);
}
},
/**
* 隐藏扩展面板
*/
hideExtensionsPanel: function() {
const extensionsPanel = document.getElementById('extensions-panel');
extensionsPanel.classList.remove('active');
setTimeout(() => {
extensionsPanel.style.display = 'none';
}, 300);
},
/**
* 切换扩展功能状态
*/
toggleExtension: function(extensionName, button) {
const isAdded = button.classList.contains('added');
if (isAdded) {
button.classList.remove('added');
button.innerHTML = '<i class="fas fa-plus"></i> 添加';
this.extensions[extensionName] = false;
this.addExtensionFeedback(extensionName, false);
} else {
button.classList.add('added');
button.innerHTML = '<i class="fas fa-check"></i> 已添加';
this.extensions[extensionName] = true;
this.addExtensionFeedback(extensionName, true);
// 添加扩展后关闭面板
setTimeout(() => {
this.hideExtensionsPanel();
}, 500);
}
this.updateExtensionBadge();
},
/**
* 更新扩展数量徽章
*/
updateExtensionBadge: function() {
const badge = document.querySelector('.badge');
const count = Object.values(this.extensions).filter(Boolean).length;
badge.textContent = count;
},
/**
* 添加扩展反馈消息
*/
addExtensionFeedback: function(extensionName, isAdded) {
const chatMessages = document.getElementById('chat-messages');
const feedbackMsg = document.createElement('div');
feedbackMsg.className = 'message bot-message';
if (isAdded) {
feedbackMsg.innerHTML = `
<div>已成功添加${extensionName}扩展功能。</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
} else {
feedbackMsg.innerHTML = `
<div>已移除${extensionName}扩展功能。</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
}
chatMessages.appendChild(feedbackMsg);
chatMessages.scrollTop = chatMessages.scrollHeight;
},
/**
* 处理文件上传
*/
handleFileUpload: function(event) {
const files = Array.from(event.target.files);
this.currentFiles = files;
const filePreview = document.getElementById('file-preview');
const sendButton = document.getElementById('send-button');
if (files.length > 0) {
filePreview.innerHTML = '';
filePreview.classList.remove('hidden');
files.slice(0, 3).forEach(file => {
const fileElement = document.createElement('div');
fileElement.className = 'file-preview-item';
fileElement.innerHTML = `
<i class="fas fa-file"></i> ${file.name}
<span class="remove-file-btn" data-file="${file.name}">
<i class="fas fa-times"></i>
</span>
`;
filePreview.appendChild(fileElement);
});
if (files.length > 3) {
const moreFiles = document.createElement('div');
moreFiles.className = 'file-preview-item';
moreFiles.innerHTML = `
<i class="fas fa-ellipsis-h"></i> 还有 ${files.length - 3} 个文件
`;
filePreview.appendChild(moreFiles);
}
} else {
filePreview.classList.add('hidden');
}
sendButton.disabled = document.getElementById('message-input').value.trim() === '' && files.length === 0;
},
/**
* 发送消息
*/
sendMessage: function() {
const messageInput = document.getElementById('message-input');
const message = messageInput.value.trim();
const files = this.currentFiles;
const chatMessages = document.getElementById('chat-messages');
const processingMessage = document.getElementById('processing-message');
if (message || files.length > 0) {
// 添加用户消息
const userMessageDiv = document.createElement('div');
userMessageDiv.className = 'message user-message';
if (message) {
userMessageDiv.textContent = message;
}
// 添加文件预览
if (files.length > 0) {
files.forEach(file => {
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const img = document.createElement('img');
img.src = e.target.result;
img.className = 'image-preview';
userMessageDiv.appendChild(img);
};
reader.readAsDataURL(file);
} else {
const fileElement = document.createElement('div');
fileElement.innerHTML = `<i class="fas fa-file"></i> ${file.name}`;
userMessageDiv.appendChild(fileElement);
}
});
}
// 添加时间戳
const timeDiv = document.createElement('div');
timeDiv.className = 'message-time';
timeDiv.textContent = this.getCurrentTime();
userMessageDiv.appendChild(timeDiv);
chatMessages.appendChild(userMessageDiv);
// 显示处理中状态
processingMessage.classList.remove('hidden');
// 清空输入
messageInput.value = '';
document.getElementById('send-button').disabled = true;
document.getElementById('file-input').value = '';
document.getElementById('file-preview').classList.add('hidden');
this.currentFiles = [];
// 滚动到底部
chatMessages.scrollTop = chatMessages.scrollHeight;
// 模拟AI处理
setTimeout(() => {
processingMessage.classList.add('hidden');
this.generateAIResponse(message, files);
}, 1500);
}
},
/**
* 生成AI回复
*/
generateAIResponse: function(message, files) {
const chatMessages = document.getElementById('chat-messages');
const botMessage = document.createElement('div');
botMessage.className = 'message bot-message';
// 检查是否是视频链接
const videoPlatforms = ['v.qq.com', 'mgtv.com', 'iqiyi.com', 'youku.com', 'le.com', 'sohu.com'];
const isVideoLink = message && videoPlatforms.some(platform => message.includes(platform));
// 检查是否有图片文件上传
const hasImage = files.some(file => file.type.startsWith('image/'));
if (isVideoLink) {
if (this.extensions.videoParser) {
// 视频解析功能
const videoUrl = `https://www.yemu.xyz/?url=${encodeURIComponent(message)}`;
botMessage.innerHTML = `
<div>已为您解析视频链接:</div>
<div style="margin-top:8px;">
<iframe src="${videoUrl}" width="100%" height="200" frameborder="0" allowfullscreen></iframe>
</div>
<div style="margin-top:8px;font-size:13px;color:#6b7280;">
<i class="fas fa-info-circle"></i> 视频解析服务由第三方提供,请遵守相关平台规定
</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
} else {
// 提示添加影视解析扩展
botMessage.innerHTML = `
<div>检测到您发送了视频链接,但尚未添加影视解析扩展。</div>
<button class="option-button" id="add-video-parser-btn" style="margin-top:10px;">
<i class="fas fa-plus"></i> 添加影视解析扩展
</button>
<div class="message-time">${this.getCurrentTime()}</div>
`;
// 为添加扩展按钮添加事件监听器
setTimeout(() => {
document.getElementById('add-video-parser-btn').addEventListener('click', () => {
this.toggleExtensionsPanel();
});
}, 100);
}
} else if (hasImage) {
if (this.extensions.imageConverter) {
// 显示图片转换选项
const imageFile = files.find(file => file.type.startsWith('image/'));
botMessage.innerHTML = `
<div>已收到您上传的图片,请选择要转换的格式:</div>
<div class="option-buttons">
<button class="option-button convert-btn" data-format="png">转换为PNG</button>
<button class="option-button convert-btn" data-format="jpg">转换为JPG</button>
<button class="option-button convert-btn" data-format="webp">转换为WEBP</button>
</div>
<div style="margin-top:12px;font-size:13px;color:#6b7280;">
<i class="fas fa-info-circle"></i> 转换后将提供下载链接
</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
// 为转换按钮添加事件监听器
setTimeout(() => {
document.querySelectorAll('.convert-btn').forEach(btn => {
btn.addEventListener('click', () => {
const format = btn.dataset.format;
this.convertImage(imageFile, format);
});
});
}, 100);
} else {
// 提示添加图片转换扩展
botMessage.innerHTML = `
<div>检测到您上传了图片,但尚未添加图片格式转换扩展。</div>
<button class="option-button" id="add-image-converter-btn" style="margin-top:10px;">
<i class="fas fa-plus"></i> 添加图片格式转换扩展
</button>
<div class="message-time">${this.getCurrentTime()}</div>
`;
// 为添加扩展按钮添加事件监听器
setTimeout(() => {
document.getElementById('add-image-converter-btn').addEventListener('click', () => {
this.toggleExtensionsPanel();
});
}, 100);
}
} else {
// 默认回复
botMessage.innerHTML = `
<div>我已收到您的消息。${message ? `关于"${message}"` : ''},我可以为您提供以下帮助:</div>
<div style="margin-top:8px;">
1. 信息查询<br>
2. 问题解答<br>
3. 使用扩展功能
</div>
<div style="margin-top:8px;">请告诉我您更具体的需求。</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
}
chatMessages.appendChild(botMessage);
chatMessages.scrollTop = chatMessages.scrollHeight;
},
/**
* 转换图片格式
*/
convertImage: function(file, targetFormat) {
const chatMessages = document.getElementById('chat-messages');
const processingMsg = document.createElement('div');
processingMsg.className = 'message bot-message';
processingMsg.innerHTML = `
<div>正在将图片转换为 ${targetFormat.toUpperCase()},请稍候...</div>
<div class="message-time">${this.getCurrentTime()}</div>
`;
chatMessages.appendChild(processingMsg);
chatMessages.scrollTop = chatMessages.scrollHeight;
// 模拟转换过程
setTimeout(() => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const resultMsg = document.createElement('div');
resultMsg.className = 'message bot-message';
resultMsg.innerHTML = `
<div>图片已成功转换为 ${targetFormat.toUpperCase()} 格式:</div>
<img src="${canvas.toDataURL(`image/${targetFormat}`)}" class="image-preview">
<button class="download-btn" onclick="window.downloadImage('${canvas.toDataURL(`image/${targetFormat}`)}', 'converted.${targetFormat}')">
<i class="fas fa-download"></i> 下载 ${targetFormat.toUpperCase()} 文件
</button>
<div class="message-time">${this.getCurrentTime()}</div>
`;
chatMessages.appendChild(resultMsg);
chatMessages.scrollTop = chatMessages.scrollHeight;
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}, 2000);
},
/**
* 调整输入框高度
*/
adjustTextareaHeight: function() {
const textarea = document.getElementById('message-input');
textarea.style.height = 'auto';
textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px';
},
/**
* 获取当前时间
*/
getCurrentTime: function() {
const now = new Date();
return `今天 ${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;
}
};
// 全局下载函数
window.downloadImage = function(url, filename) {
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
// 初始化AI助手
aiAssistant.init();
});
</script>
</body>
</html>
index.html