Files

501 lines
23 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>穿搭镜检</title>
<link rel="stylesheet" href="/common/common.css" />
<link rel="stylesheet" href="/tools/style_check/style_check.css" />
</head>
<body>
<div id="topbar"></div>
<main class="sc-page">
<div id="mainSections">
<section class="sc-card sc-profile-card">
<h1>穿搭镜检</h1>
<p id="profileSlogan" class="sc-subtitle"></p>
<div class="sc-profile-tabs">
<button id="tabRelaxed" class="sc-tab-btn">中老年休闲沉稳版</button>
<button id="tabFashion40" class="sc-tab-btn">中老年流行时尚版</button>
<button id="tabWave" class="sc-tab-btn">WAVE穿搭参考</button>
<button id="tabKorean" class="sc-tab-btn">韩式穿搭参考</button>
<button id="tabZhihu" class="sc-tab-btn">知乎穿搭推荐</button>
<button id="tabX" class="sc-tab-btn">欧美穿搭参考 (X)</button>
</div>
</section>
<section class="sc-card">
<h2>今日建议</h2>
<p class="sc-subtitle">独立工具 · 双版本隔离 · 温区优先</p>
<div class="sc-inline">
<label>场景</label>
<select id="scene">
<option value="commute">通勤</option>
<option value="weekend">周末轻运动</option>
<option value="business_light">轻商务会面</option>
</select>
<label>温度(℃)</label>
<input id="tempC" type="number" step="0.1" placeholder="例如 18" />
<label>温区</label>
<select id="tempZone">
<option value="">自动按温度</option>
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<button id="btnToday">获取今日建议</button>
</div>
<div id="todayBox" class="sc-result"></div>
</section>
<section class="sc-card">
<h2>智能图像 + AI审核</h2>
<div class="sc-inline">
<label>场景</label>
<select id="aiScene">
<option value="commute">通勤</option>
<option value="weekend">周末轻运动</option>
<option value="business_light">轻商务会面</option>
</select>
<label>温区</label>
<select id="aiTempZone">
<option value="">自动按温度</option>
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<input id="aiImage" type="file" accept="image/*" />
<button id="btnAiAudit">开始AI审核</button>
</div>
<div class="sc-ai-layout">
<div class="sc-ai-left">
<img id="aiPreview" class="sc-ai-preview" alt="待审核图片预览" />
</div>
<div class="sc-ai-right">
<div id="aiAuditResult" class="sc-result"></div>
<div id="aiAuditIssues" class="sc-result"></div>
</div>
</div>
</section>
<section class="sc-card">
<h2>搭配库</h2>
<div class="sc-inline">
<label>筛选场景</label>
<select id="filterScene">
<option value="">全部</option>
<option value="commute">通勤</option>
<option value="weekend">周末轻运动</option>
<option value="business_light">轻商务会面</option>
</select>
<label>筛选温区</label>
<select id="filterTempZone">
<option value="">全部</option>
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<input id="filterQ" type="text" placeholder="关键词搜索" />
<button id="btnSearch">查询</button>
</div>
<div class="sc-table-wrap">
<table class="sc-table">
<thead>
<tr>
<th>名称</th>
<th>场景</th>
<th>温区标签</th>
<th>上衣</th>
<th>下装</th>
<th>鞋</th>
<th>外搭</th>
<th>配饰</th>
<th>备注</th>
<th>服饰库匹配</th>
<th>操作</th>
</tr>
</thead>
<tbody id="outfitBody"></tbody>
</table>
</div>
</section>
<section class="sc-card">
<h2>服饰库(基础数据来源)</h2>
<div class="sc-inline">
<label>槽位</label>
<select id="libSlot">
<option value="">全部</option>
<option value="top">上衣</option>
<option value="bottom">下装</option>
<option value="shoes">鞋</option>
<option value="outer">外搭</option>
<option value="accessory">配饰</option>
</select>
<label>温区</label>
<select id="libTempZone">
<option value="">全部</option>
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<input id="libQ" type="text" placeholder="关键词/品牌搜索" />
<button id="btnLibSearch">查询服饰库</button>
<button id="btnRebuildLinks">重建匹配</button>
<button id="btnFetchLocalImages">自动找图到本地</button>
</div>
<div class="sc-table-wrap">
<table class="sc-table">
<thead>
<tr>
<th>名称</th>
<th>槽位</th>
<th>类别</th>
<th>温区</th>
<th>品牌</th>
<th>价位</th>
<th>图片</th>
<th>关键词</th>
<th>说明</th>
<th>操作</th>
</tr>
</thead>
<tbody id="libBody"></tbody>
</table>
</div>
<div id="unmatchedReport" class="sc-result"></div>
<input id="libUploadInput" type="file" accept="image/*" style="display:none" />
<h3>新增 / 编辑服饰库条目</h3>
<div class="sc-form-grid">
<input id="libItemId" type="hidden" />
<label>名称</label><input id="libItemName" type="text" placeholder="短款立领夹克" />
<label>槽位</label>
<select id="libItemSlot">
<option value="top">上衣</option>
<option value="bottom">下装</option>
<option value="shoes">鞋</option>
<option value="outer">外搭</option>
<option value="accessory">配饰</option>
</select>
<label>类别</label><input id="libItemCategory" type="text" placeholder="夹克" />
<label>温区</label>
<select id="libItemTempZone">
<option value="ALL">ALL</option>
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<label>品牌</label><input id="libItemBrands" type="text" />
<label>最低价</label><input id="libItemPriceMin" type="number" />
<label>最高价</label><input id="libItemPriceMax" type="number" />
<label>关键词</label><input id="libItemKeywords" type="text" />
<label>说明</label><input id="libItemNotes" type="text" />
</div>
<div class="sc-inline">
<button id="btnLibSave">保存服饰条目</button>
<button id="btnLibReset" class="ghost">清空服饰表单</button>
</div>
</section>
<section class="sc-card">
<h2>新增/更新搭配</h2>
<div class="sc-form-grid">
<input id="fId" type="hidden" />
<label>名称</label><input id="fName" type="text" placeholder="通勤休闲 B" />
<label>场景</label>
<select id="fScene">
<option value="commute">通勤</option>
<option value="weekend">周末轻运动</option>
<option value="business_light">轻商务会面</option>
</select>
<label>温区标签</label>
<select id="fTempZone">
<option value="5-12℃">5-12℃</option>
<option value="12-22℃">12-22℃</option>
<option value="22-30℃">22-30℃</option>
<option value="30℃+">30℃+</option>
</select>
<label>上衣</label><input id="fTop" type="text" />
<label>下装</label><input id="fBottom" type="text" />
<label>鞋</label><input id="fShoes" type="text" />
<label>外搭</label><input id="fOuter" type="text" />
<label>配饰</label><input id="fAccessory" type="text" />
<label>备注</label><input id="fNotes" type="text" />
</div>
<div class="sc-inline">
<button id="btnSave">保存</button>
<button id="btnReset" class="ghost">清空</button>
</div>
<div id="msg" class="sc-msg"></div>
</section>
<section class="sc-card">
<h2>30秒镜检</h2>
<div id="ruleList" class="sc-rule-list"></div>
<div class="sc-inline">
<button id="btnCheck">提交镜检</button>
</div>
<div id="recentChecks" class="sc-result"></div>
</section>
</div> <!-- end mainSections -->
<section id="waveSection" class="sc-card" style="display:none">
<div class="sc-inline" style="justify-content: space-between; align-items: center; margin-bottom: 16px;">
<div>
<h2 style="margin: 0; font-size: 20px; color: #f8fafc">WAVE穿搭参考 (男装专区)</h2>
<p class="sc-subtitle" style="margin: 4px 0 0 0">数据源自 WEAR.jp,基于 Qwen Vision 强过滤筛选,呈现懂流行、不装嫩的精选穿搭。</p>
</div>
<div style="text-align:right">
<input type="file" id="waveLinkFile" accept=".json,.txt" style="display:none" />
<button id="btnWaveUploadLinks" class="action-btn" style="background: rgba(234, 179, 8, 0.8); margin-right: 8px;">📤 投喂JSON链接</button>
<button id="btnWaveToggleCrawler" class="action-btn" style="background: rgba(37, 99, 235, 0.8)">▶ 启动佛系爬虫 (每页缓爬)</button>
<button id="btnWaveShowLogs" class="action-btn" style="background: rgba(100, 116, 139, 0.8); margin-left: 8px;">📄 查看实时日志</button>
<div id="waveCrawlerStatus" style="font-size: 12px; color: #94a3b8; margin-top: 8px; text-align: right;"></div>
</div>
</div>
<div id="waveGrid" class="wave-grid"></div>
</section>
<section id="koreanSection" class="sc-card" style="display:none">
<div class="sc-inline" style="justify-content: space-between; align-items: center; margin-bottom: 16px;">
<div>
<h2 style="margin: 0; font-size: 20px; color: #f8fafc">韩式穿搭参考</h2>
<p class="sc-subtitle" style="margin: 4px 0 0 0">数据源自 onthelook,基于 AI 筛选,呈现简约、高级感、清爽的韩式男装穿搭。</p>
</div>
<div style="text-align:right">
<input type="file" id="koreanLinkFile" accept=".json,.txt" style="display:none" />
<button id="btnKoreanUploadLinks" class="action-btn" style="background: rgba(234, 179, 8, 0.8); margin-right: 8px; display:none;">📤 投喂JSON链接</button>
<button id="btnKoreanToggleCrawler" class="action-btn" style="background: rgba(37, 99, 235, 0.8)">▶ 启动佛系爬虫</button>
<button id="btnKoreanShowLogs" class="action-btn" style="background: rgba(100, 116, 139, 0.8); margin-left: 8px;">📄 查看实时日志</button>
<div id="koreanCrawlerStatus" style="font-size: 12px; color: #94a3b8; margin-top: 8px; text-align: right;"></div>
</div>
</div>
<div id="koreanGrid" class="wave-grid"></div>
</section>
<section id="zhihuSection" class="sc-card" style="display:none">
<div id="zhihuToc" class="zhihu-toc">
<div class="toc-header">☰ 目录</div>
<div class="toc-body" id="zhihuTocBody"></div>
</div>
<div class="zhihu-content-area" id="zhihuContentArea">
<div class="zhihu-placeholder">
<h3>请在左上角目录中选择文章</h3>
</div>
</div>
</section>
<section id="xSection" class="sc-card" style="display:none; background: #000; padding: 0;">
<div class="x-layout">
<!-- X Sidebar -->
<aside class="x-sidebar">
<div style="display: flex; align-items: center; justify-content: space-between; padding-right: 12px;">
<div class="x-logo">
<svg viewBox="0 0 24 24" aria-hidden="true" fill="#e7e9ea"><g><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.008 3.827H5.078z"></path></g></svg>
</div>
<button id="btnXHelp" class="action-btn" style="background: rgba(100, 116, 139, 0.8); font-size: 12px; padding: 4px 8px;">📖 操作说明</button>
</div>
<nav class="x-nav">
<button class="x-nav-item active" onclick="loadXAccount('mensgrinding')">
<span class="x-icon">👤</span> <span class="x-label">@mensgrinding</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('MenStyle_61')">
<span class="x-icon">👤</span> <span class="x-label">@MenStyle_61</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('dieworkwear')">
<span class="x-icon">👤</span> <span class="x-label">@dieworkwear</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('mensfashion0')">
<span class="x-icon">👤</span> <span class="x-label">@mensfashion0</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('_menstylish')">
<span class="x-icon">👤</span> <span class="x-label">@_menstylish</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('Bestofmenstyles')">
<span class="x-icon">👤</span> <span class="x-label">@Bestofmenstyles</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('MenswearStyle')">
<span class="x-icon">👤</span> <span class="x-label">@MenswearStyle</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('apetogentleman')">
<span class="x-icon">👤</span> <span class="x-label">@apetogentleman</span>
</button>
<button class="x-nav-item" onclick="loadXAccount('Sartorialist')">
<span class="x-icon">👤</span> <span class="x-label">@Sartorialist</span>
</button>
</nav>
</aside>
<!-- X Timeline -->
<main class="x-timeline">
<div class="x-header">
<h2 id="xHeaderTitle">Home</h2>
</div>
<div id="xFeed" class="x-feed">
<div class="x-placeholder">
<div class="x-spinner"></div>
<p>正在加载推文...</p>
</div>
</div>
</main>
</div>
</section>
</main>
<!-- Lightbox Modal -->
<div id="waveLightbox" class="wave-lightbox" style="display:none">
<button class="wave-lb-close" id="waveLbClose">×</button>
<button class="wave-lb-nav prev" id="waveLbPrev">‹</button>
<button class="wave-lb-nav next" id="waveLbNext">›</button>
<div class="wave-lb-content">
<div class="wave-lb-img-wrap">
<img id="waveLbImg" src="" />
</div>
<div class="wave-lb-info">
<div class="wave-lb-badge">AI 穿搭解析</div>
<h4>💡 穿搭评价</h4>
<p id="waveLbEval"></p>
<div style="height:1px; background: rgba(148,163,184,0.2); margin: 24px 0;"></div>
<h4>⚠️ 借鉴与注意事项</h4>
<p id="waveLbNotes"></p>
<div style="margin-top: auto; padding-top: 24px; font-size: 12px; color: #64748b">
来源链接: <a id="waveLbSource" href="#" target="_blank" style="color: #3b82f6; text-decoration: none">打开原始网页</a>
</div>
</div>
</div>
</div>
<div id="koreanLightbox" class="wave-lightbox" style="display:none">
<button class="wave-lb-close" id="koreanLbClose">×</button>
<button class="wave-lb-nav prev" id="koreanLbPrev">‹</button>
<button class="wave-lb-nav next" id="koreanLbNext">›</button>
<div class="wave-lb-content">
<div class="wave-lb-img-wrap">
<img id="koreanLbImg" src="" />
</div>
<div class="wave-lb-info">
<div class="wave-lb-badge" style="background: rgba(236, 72, 153, 0.2); color: #f472b6;">韩式穿搭解析</div>
<h4>💡 穿搭评价</h4>
<p id="koreanLbEval"></p>
<div style="height:1px; background: rgba(148,163,184,0.2); margin: 24px 0;"></div>
<h4>⚠️ 借鉴与注意事项</h4>
<p id="koreanLbNotes"></p>
<div style="margin-top: auto; padding-top: 24px; font-size: 12px; color: #64748b">
来源链接: <a id="koreanLbSource" href="#" target="_blank" style="color: #f472b6; text-decoration: none">打开原始网页</a>
</div>
</div>
</div>
</div>
<!-- X Lightbox Modal -->
<div id="xLightbox" class="wave-lightbox" style="display:none">
<button class="wave-lb-close" id="xLbClose">×</button>
<button class="wave-lb-nav prev" id="xLbPrev">‹</button>
<button class="wave-lb-nav next" id="xLbNext">›</button>
<div class="wave-lb-content" style="flex-direction: column;">
<div class="wave-lb-img-wrap" style="flex: 1; max-height: 90vh;">
<img id="xLbImg" src="" style="object-fit: contain;" />
</div>
</div>
</div>
<div id="toast" class="sc-toast"></div>
<!-- Crawler Logs Modal -->
<div id="waveLogsModal" class="sc-modal-mask" style="display:none; align-items:center; justify-content:center">
<div class="sc-modal-panel" style="width: 800px; max-width: 90vw;">
<div class="sc-modal-header">
<h3 style="margin:0;font-size:18px">爬虫实时日志</h3>
</div>
<div class="sc-modal-body">
<pre id="waveLogsContent" style="background:#0f172a; color:#a5b4fc; padding:16px; border-radius:8px; height:400px; overflow-y:auto; font-size:13px; line-height:1.6; white-space:pre-wrap; margin:0; font-family:monospace;"></pre>
</div>
<div class="sc-modal-footer">
<button id="btnWaveLogsClose" class="sc-btn sc-btn-primary">关闭</button>
</div>
</div>
</div>
<div id="koreanLogsModal" class="sc-modal-mask" style="display:none; align-items:center; justify-content:center">
<div class="sc-modal-panel" style="width: 800px; max-width: 90vw;">
<div class="sc-modal-header">
<h3 style="margin:0;font-size:18px">爬虫实时日志 (韩式)</h3>
</div>
<div class="sc-modal-body">
<pre id="koreanLogsContent" style="background:#0f172a; color:#f472b6; padding:16px; border-radius:8px; height:400px; overflow-y:auto; font-size:13px; line-height:1.6; white-space:pre-wrap; margin:0; font-family:monospace;"></pre>
</div>
<div class="sc-modal-footer">
<button id="btnKoreanLogsClose" class="sc-btn sc-btn-primary" style="background: #ec4899; border-color: #ec4899;">关闭</button>
</div>
</div>
</div>
<!-- Debug Trace Modal: 记录爬虫切换请求的全链路响应 -->
<div id="debugTraceModal" class="sc-modal-mask" style="display:none; align-items:center; justify-content:center; z-index:10000">
<div class="sc-modal-panel" style="width: 880px; max-width: 95vw;">
<div class="sc-modal-header" style="display:flex;align-items:center;justify-content:space-between">
<h3 id="debugTraceTitle" style="margin:0;font-size:18px">调试跟踪</h3>
<span id="debugTraceStatus" style="font-size:12px;color:#64748b">运行中...</span>
</div>
<div class="sc-modal-body">
<pre id="debugTraceContent" style="background:#0f172a; color:#e2e8f0; padding:14px; border-radius:8px; height:480px; overflow-y:auto; font-size:12px; line-height:1.55; white-space:pre-wrap; word-break:break-all; margin:0; font-family:Consolas,monospace; user-select:text;"></pre>
</div>
<div class="sc-modal-footer" style="display:flex;gap:8px;justify-content:flex-end">
<button id="btnDebugTraceCopy" class="sc-btn" style="background:#0ea5e9;color:#fff;border-color:#0ea5e9">复制全部</button>
<button id="btnDebugTraceClose" class="sc-btn sc-btn-primary">关闭</button>
</div>
</div>
</div>
<div id="appModal" class="sc-modal-mask">
<div class="sc-modal-panel">
<div id="modalTitle" class="sc-modal-title"></div>
<div id="modalMessage" class="sc-modal-message"></div>
<div id="modalActions" class="sc-modal-actions"></div>
</div>
</div>
<script src="/common/common.js"></script>
<!-- X Help Modal -->
<div id="xHelpModal" class="sc-modal-mask" style="display:none; align-items:center; justify-content:center">
<div class="sc-modal-panel" style="width: 600px; max-width: 90vw;">
<div class="sc-modal-header">
<h3 style="margin:0;font-size:18px">📖 欧美穿搭爬虫操作说明</h3>
<button id="btnXHelpClose" class="sc-modal-close">✕</button>
</div>
<div class="sc-modal-body" style="padding: 20px; font-size: 14px; line-height: 1.6; color: #334155;">
<h4 style="margin-top: 0;">一、如何添加新的 X (Twitter) 账号?</h4>
<ol>
<li>打开后端脚本:<code>d:\Trae_Files\TRAE-Toolbox\scripts\crawl_x.js</code></li>
<li>找到顶部的 <code>accountsToCrawl</code> 数组,将目标账号(不带@)添加到数组中。</li>
<li>打开前端页面:<code>d:\Trae_Files\TRAE-Toolbox\public\tools\style_check\index.html</code></li>
<li>搜索 <code>class="x-nav"</code>,按照现有格式,复制并添加一行新的 <code>&lt;button&gt;</code>。</li>
<li>将 <code>onclick="loadXAccount('新账号')"</code> 以及显示文本 <code>@新账号</code> 修改为对应账号。</li>
</ol>
<h4>二、如何运行爬虫脚本抓取数据?</h4>
<ol>
<li>打开你的 <b>v2rayN</b> 代理软件,确保能够正常访问外网。</li>
<li>在 Trae IDE 的下方找到 <b>Terminal (终端)</b>,如果没打开,按 <kbd>Ctrl</kbd> + <kbd>`</kbd> (反引号)。</li>
<li>确保当前路径在项目根目录:<code>d:\Trae_Files\TRAE-Toolbox</code></li>
<li>输入以下命令并按回车运行:<br>
<code style="background: #f1f5f9; padding: 4px 8px; border-radius: 4px; display: inline-block; margin-top: 4px; color: #e11d48; font-weight: bold;">node scripts/crawl_x.js</code>
</li>
<li>脚本会弹出一个浏览器窗口并等待 30 秒,<b>请在这段时间内手动完成推特账号的登录</b>(如果尚未登录)。</li>
<li>登录完成后,回到终端按一下 <kbd>Enter (回车)</kbd>,脚本就会开始自动抓取账号最新推文和图片了。</li>
<li>抓取完毕后,刷新当前网页即可查看最新数据。</li>
</ol>
</div>
</div>
</div>
<script src="/tools/style_check/style_check.js"></script>
</body>
</html>