feat: 重构为 Go Web 脚手架——在线图片识别 Web 服务 + vision-cli 独立工具

- Gin + config.yaml + SQLite 后端骨架,JWT 登录 + 管理员初始化
- web/ 原生单页:拖拽多图上传 → Agnes 免费识别 → 结果复制
- HTTP API:/api/v1/vision/analyze 免鉴权 + 令牌桶限流,支持程序直调
- cmd/vision-cli 独立 CLI 工具(复用 service 层,不依赖 Web 服务)
- build.bat / build.sh 构建脚本,移除 mcp-server
- 统一响应格式 {code, message, data},CORS/JWT/限流中间件

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-12 23:59:17 +08:00
parent 8bf77301bd
commit a3bbf33358
25 changed files with 1902 additions and 798 deletions

80
web/index.html Normal file
View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vision Tool — 免费图片识别</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header class="topbar">
<div class="brand">
<span class="logo">👁️</span>
<div>
<h1>Vision Tool</h1>
<p>免费图片识别 · Agnes-2.0-Flash</p>
</div>
</div>
<div class="account" id="accountArea">
<!-- 登录状态由 JS 渲染 -->
</div>
</header>
<main class="container">
<section class="card upload-card">
<div class="dropzone" id="dropzone">
<input type="file" id="fileInput" accept="image/png,image/jpeg,image/gif,image/webp,image/bmp,image/tiff" multiple hidden>
<div class="dropzone-icon">🖼️</div>
<p class="dropzone-title">点击选择或拖拽图片到这里</p>
<p class="dropzone-hint">支持 PNG / JPG / GIF / WebP / BMP,可多张同时识别(对比异同)</p>
</div>
<div class="preview-list" id="previewList"></div>
<div class="prompt-row">
<input type="text" id="promptInput" class="prompt-input"
placeholder="可选:自定义分析提问,例如「提取图中所有文字」「分析这个 UI 的布局结构」">
<button class="btn btn-primary" id="analyzeBtn" disabled>开始识别</button>
</div>
</section>
<section class="card result-card" id="resultCard" hidden>
<div class="result-head">
<h2>识别结果</h2>
<div class="result-actions">
<button class="btn btn-ghost" id="copyBtn">复制</button>
</div>
</div>
<pre class="result-body" id="resultBody"></pre>
<p class="result-meta" id="resultMeta"></p>
</section>
</main>
<!-- 初始化管理员模态框 -->
<div class="modal-mask" id="initModal" hidden>
<div class="modal">
<h2>初始化管理员</h2>
<p class="modal-desc">首次使用,请创建管理员账号</p>
<input type="text" id="initUsername" placeholder="用户名" class="modal-input">
<input type="password" id="initPassword" placeholder="密码(至少 6 位)" class="modal-input">
<input type="password" id="initPassword2" placeholder="确认密码" class="modal-input">
<div class="modal-error" id="initError"></div>
<button class="btn btn-primary btn-block" id="initBtn">创建管理员</button>
</div>
</div>
<!-- 登录模态框 -->
<div class="modal-mask" id="loginModal" hidden>
<div class="modal">
<h2>登录</h2>
<input type="text" id="loginUsername" placeholder="用户名" class="modal-input">
<input type="password" id="loginPassword" placeholder="密码" class="modal-input">
<div class="modal-error" id="loginError"></div>
<button class="btn btn-primary btn-block" id="loginBtn">登录</button>
</div>
</div>
<footer class="footer">推理模型专心推理,图片理解交给免费小模型 · 识别接口支持 API 直接调用</footer>
<script src="/js/app.js"></script>
</body>
</html>