新增 API格式 下拉选择框:
- raw - 原始API格式(使用 /v1/images/generations 端点)
- openai - OpenAI格式(使用 /v1/chat/completions 端点)
2. JavaScript 核心逻辑 (script.js)
设置字段 (script.js:10)
- currentSettings 新增 apiFormat: 'raw' 字段
API 服务 (script.js:685-916)
- testConnection: 根据 API 格式选择 /models 或 /v1/models 端点
- generateImage:
- 原始格式: 使用 prompt 请求体,端点 /v1/images/generations
- OpenAI格式: 使用 messages 请求体,端点 /v1/chat/completions
- extractImagesFromContent: 新增方法,支持从 Chat 响应中提取图像:
- ✅ Markdown 图片语法 
- ✅ Base64 图像数据
- ✅ 通用图像 URL(放宽限制)
- ✅ JSON 格式内容(包括代码块)
- ✅ 多模态内容数组
设置持久化 (script.js:1591, 1771, 1909)
- loadSettings / saveSettings 支持 apiFormat
- 自动保存监听器包含 apiFormat
连接测试 (script.js:2027, 2037)
- app.testConnection 传递 apiFormat 参数
231 lines
15 KiB
HTML
231 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Grok Image Generator</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
|
<link href="styles.css" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
<div class="main-container">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h1 class="mb-0">
|
|
<i class="fas fa-image me-2"></i>
|
|
Grok Image Generator
|
|
</h1>
|
|
<p class="mb-0 mt-2">基于 Grok API 的智能图像生成工具</p>
|
|
</div>
|
|
<div class="card-body">
|
|
<!-- 设置面板 -->
|
|
<div class="accordion mb-4" id="settingsAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSettings" aria-expanded="false" aria-controls="collapseSettings">
|
|
<i class="fas fa-cog me-2"></i>API设置
|
|
</button>
|
|
</h2>
|
|
<div id="collapseSettings" class="accordion-collapse collapse" data-bs-parent="#settingsAccordion">
|
|
<div class="accordion-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="apiKey" class="form-label">API Key</label>
|
|
<input type="password" class="form-control" id="apiKey" placeholder="输入您的 API Key">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="baseUrl" class="form-label">API 地址</label>
|
|
<input type="url" class="form-control" id="baseUrl" placeholder="输入 API 地址,如 http://localhost:8000">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="mb-3">
|
|
<label for="model" class="form-label">模型</label>
|
|
<select class="form-select" id="model">
|
|
<option value="grok-imagine-1.0">Grok Imagine 1.0</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="mb-3">
|
|
<label for="apiFormat" class="form-label">API格式</label>
|
|
<select class="form-select" id="apiFormat">
|
|
<option value="raw">原始API格式</option>
|
|
<option value="openai">OpenAI格式</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="mb-3">
|
|
<label for="responseFormat" class="form-label">响应格式</label>
|
|
<select class="form-select" id="responseFormat">
|
|
<option value="b64_json">Base64 (推荐)</option>
|
|
<option value="url">URL</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="mb-3">
|
|
<label for="timeout" class="form-label">超时时间 (秒)</label>
|
|
<input type="number" class="form-control" id="timeout" value="600">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="mb-3">
|
|
<label for="proxy" class="form-label">代理 (可选)</label>
|
|
<input type="url" class="form-control" id="proxy" placeholder="http://proxy:port">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span class="status-indicator status-disconnected" id="connectionStatus"></span>
|
|
<span id="connectionText">未连接</span>
|
|
</div>
|
|
<div>
|
|
<button class="btn btn-outline-primary me-2" onclick="testConnection()">
|
|
<i class="fas fa-plug me-2"></i>测试连接
|
|
</button>
|
|
<button class="btn btn-outline-warning" onclick="app.clearStorage()">
|
|
<i class="fas fa-broom me-2"></i>清除存储数据
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 图像上传区域(当前 API 不支持) -->
|
|
<div class="mb-4">
|
|
<h5><i class="fas fa-upload me-2"></i>上传参考图像 <span class="badge bg-secondary">暂不支持</span></h5>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="border-2 border-dashed rounded p-4 text-center h-100 d-flex flex-column justify-content-center bg-light" id="dropZone" style="opacity: 0.6;">
|
|
<i class="fas fa-cloud-upload-alt fa-3x text-muted mb-3"></i>
|
|
<p class="text-muted">当前 API 仅支持文本生成图像,暂不支持图像编辑</p>
|
|
<input type="file" class="d-none" id="imageInput" accept="image/*" multiple disabled>
|
|
<button class="btn btn-outline-secondary" disabled>
|
|
功能暂不可用
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<div class="row" id="imagePreview" style="max-height: 250px; overflow-y: auto; border: 1px solid #dee2e6; border-radius: .25rem; padding-top: 1rem;">
|
|
<div class="col-12 d-flex h-100 align-items-center justify-content-center">
|
|
<p class="text-muted">未选择图像</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 图像生成模块 -->
|
|
<div class="mb-4">
|
|
<h5><i class="fas fa-image me-2"></i>图像生成</h5>
|
|
<div class="input-group mb-3">
|
|
<textarea class="form-control" id="messageInput" rows="3" placeholder="输入您的图像生成请求..."></textarea>
|
|
</div>
|
|
<div class="d-flex flex-column gap-3">
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text">生成数量</span>
|
|
<input type="number" class="form-control" id="batchCount" min="1" max="20" value="6" placeholder="输入生成数量">
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<button class="btn btn-primary flex-fill" onclick="sendMessage()">
|
|
<i class="fas fa-paper-plane me-2"></i>生成一张
|
|
</button>
|
|
<button class="btn btn-success flex-fill" onclick="sendBatchMessage()">
|
|
<i class="fas fa-magic me-2"></i>批量生成
|
|
</button>
|
|
</div>
|
|
<small class="text-muted">支持1-20张图像同时生成</small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 加载指示器 -->
|
|
<div class="loading-spinner" id="loadingSpinner">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">加载中...</span>
|
|
</div>
|
|
<p class="mt-2">正在生成图像,请稍候...</p>
|
|
</div>
|
|
|
|
<!-- 聊天历史 -->
|
|
<div class="accordion mb-4" id="chatAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseChat" aria-expanded="false" aria-controls="collapseChat">
|
|
<i class="fas fa-history me-2"></i>对话历史
|
|
</button>
|
|
</h2>
|
|
<div id="collapseChat" class="accordion-collapse collapse" data-bs-parent="#chatAccordion">
|
|
<div class="accordion-body">
|
|
<div id="chatHistory" style="max-height: 400px; overflow-y: auto;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 生成的图像画廊 -->
|
|
<div class="mb-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h5 class="mb-0"><i class="fas fa-images me-2"></i>生成的图像</h5>
|
|
<button class="btn btn-success" id="downloadAllImagesBtn" style="display: none;">
|
|
<i class="fas fa-download me-2"></i>全部下载
|
|
</button>
|
|
</div>
|
|
<div class="image-gallery" id="imageGallery"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 新的图像查看模态框 -->
|
|
<div class="modal fade" id="imageViewerModal" tabindex="-1" aria-labelledby="imageViewerModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-fullscreen">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="imageViewerModalLabel">图像查看</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center position-relative">
|
|
<!-- 左翻页按钮 -->
|
|
<button type="button" class="btn btn-light position-absolute top-50 start-0 translate-middle-y" id="prevImageBtn">
|
|
<i class="fas fa-chevron-left"></i>
|
|
</button>
|
|
|
|
<!-- 图像显示区域 -->
|
|
<img id="viewerModalImage" src="" alt="查看图像" class="img-fluid">
|
|
|
|
<!-- 右翻页按钮 -->
|
|
<button type="button" class="btn btn-light position-absolute top-50 end-0 translate-middle-y" id="nextImageBtn">
|
|
<i class="fas fa-chevron-right"></i>
|
|
</button>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" id="viewerDeleteImage">
|
|
<i class="fas fa-trash me-2"></i>删除图像
|
|
</button>
|
|
<button type="button" class="btn btn-primary" id="viewerDownloadImage">
|
|
<i class="fas fa-download me-2"></i>下载图像
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="script.js"></script>
|
|
</body>
|
|
</html> |