save code

This commit is contained in:
Ubuntu
2026-07-10 00:38:39 +08:00
parent f8e30ad32e
commit de2cecf0d5
+56 -17
View File
@@ -21,7 +21,12 @@
.form-group { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.form-group label { font-size: 13px; font-weight: 600; color: #374151; }
.form-group select { padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; }
.form-group input[type=text] { padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; width: 150px; }
.hair-checkboxes { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
.hair-checkboxes label { font-size: 13px; font-weight: 500; color: #374151; cursor: pointer; display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.hair-checkboxes label input[type=checkbox] { cursor: pointer; }
.checkbox-actions { display: flex; gap: 6px; margin-left: 4px; }
.checkbox-actions button { font-size: 11px; padding: 2px 8px; border-radius: 4px; border: 1px solid #d1d5db; background: #f9fafb; cursor: pointer; }
.checkbox-actions button:hover { background: #e5e7eb; }
.btn { padding: 10px 28px; border: none; border-radius: 8px; font-size: 15px; cursor: pointer; font-weight: 600; transition: .2s; }
.btn-primary { background: #2563eb; color: #fff; }
.btn-primary:hover { background: #1d4ed8; }
@@ -50,14 +55,6 @@
.result-card .info { padding: 10px 12px; font-size: 12px; display: flex; justify-content: space-between; align-items: center; }
.result-card .info .badge { background: #2563eb; color: #fff; padding: 1px 8px; border-radius: 10px; font-size: 11px; }
/* 预览叠加 */
.preview-stack { position: relative; display: inline-block; line-height: 0; background: #222; border-radius: 8px; overflow: hidden; }
.preview-stack img { display: block; max-width: 100%; max-height: 450px; }
.preview-stack .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
.preview-controls { display: flex; gap: 14px; align-items: center; font-size: 12px; color: #9ca3af; }
.preview-controls label { display: flex; align-items: center; gap: 4px; cursor: pointer; }
/* 三档 + 生发图 横向排列 */
.level-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.level-cell { background: #222; border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; }
@@ -89,16 +86,22 @@
<div class="file-input"><input type="file" id="imageFile" accept="image/jpeg,image/png,.jpg,.jpeg,.png"></div>
<div class="form-group">
<label>性别</label>
<select id="gender"><option value="female" selected>👩 Female5种)</option><option value="male">👨 Male4种)</option></select>
<select id="gender" onchange="onGenderChange()"><option value="female" selected>👩 Female5种)</option><option value="male">👨 Male4种)</option></select>
</div>
<div class="form-group">
<label title="必填,逗号分隔多选如 1,2,3">发型序号 *</label>
<input type="text" id="hairStyle" placeholder="必填 如 1,2,3">
<div class="form-group" style="align-items:flex-start">
<label style="padding-top:3px">发型 *</label>
<div>
<div class="hair-checkboxes" id="hairStyleGroup"></div>
<div class="checkbox-actions" style="margin-top:4px">
<button type="button" onclick="selectAllHair(true)">全选</button>
<button type="button" onclick="selectAllHair(false)">全不选</button>
</div>
</div>
</div>
<button class="btn btn-primary" id="submitBtn" onclick="submitTest()">🚀 提交</button>
<button class="btn btn-outline btn-sm" onclick="clearResults()">清除</button>
</div>
<div class="hint">JPG/PNG 正面照 &nbsp;|&nbsp; 发型序号 Female: 1椭圆/2花瓣/3心形/4直线/5波浪 &nbsp;|&nbsp; Male: 1椭圆/2倒弧/3M形/4直线 &nbsp;|&nbsp; 每个发型返回 middle/high/low 三档 + 生发图</div>
<div class="hint">JPG/PNG 正面照 &nbsp;|&nbsp; Female: 椭圆/花瓣/心形/直线/波浪 &nbsp;|&nbsp; Male: 椭圆/倒弧/M形/直线 &nbsp;|&nbsp; 每个发型返回 middle/high/low 三档 + 生发图</div>
<div id="statusBar" class="status hidden"></div>
</div>
</div>
@@ -138,17 +141,52 @@ let _images = [], _origUrl = '', _center = null;
function $(id) { return document.getElementById(id); }
function setStatus(t, type) { const b=$('statusBar'); b.textContent=t; b.className='status '+type; }
// 发型列表(同接口2
const HAIR_STYLES = {
female: [
{ value:'1', label:'1. ellipse 椭圆' },
{ value:'2', label:'2. flower 花瓣' },
{ value:'3', label:'3. heart 心形' },
{ value:'4', label:'4. straight 直线' },
{ value:'5', label:'5. wave 波浪' },
],
male: [
{ value:'1', label:'1. ellipse 椭圆' },
{ value:'2', label:'2. inverse_arc 倒弧' },
{ value:'3', label:'3. m M形' },
{ value:'4', label:'4. straight 直线' },
]
};
function onGenderChange() {
const g = $('gender').value;
const div = $('hairStyleGroup');
div.innerHTML = '';
HAIR_STYLES[g].forEach(s => {
const cb = document.createElement('input');
cb.type = 'checkbox'; cb.value = s.value; cb.id = 'hs_' + s.value;
const lb = document.createElement('label');
lb.htmlFor = cb.id; lb.appendChild(cb);
lb.appendChild(document.createTextNode(' ' + s.label));
div.appendChild(lb);
});
}
function selectAllHair(select) {
document.querySelectorAll('#hairStyleGroup input[type=checkbox]').forEach(cb => { cb.checked = select; });
}
async function submitTest() {
const f = $('imageFile').files[0];
if (!f) { setStatus('请选择图片', 'error'); return; }
const _hs = $('hairStyle').value.trim();
if (!_hs) { setStatus('请填写发型序号(必填,如 1,2,3', 'error'); return; }
const checked = [...document.querySelectorAll('#hairStyleGroup input:checked')].map(cb => cb.value);
if (!checked.length) { setStatus('请至少选择一个发型', 'error'); return; }
_origUrl = URL.createObjectURL(f);
$('submitBtn').disabled = true; $('submitBtn').textContent = '⏳ ...';
setStatus('请求中...', 'info'); $('resultsArea').classList.add('hidden');
const fd = new FormData(); fd.append('image_file', f); fd.append('gender', $('gender').value); fd.append('hair_style', _hs);
const fd = new FormData(); fd.append('image_file', f); fd.append('gender', $('gender').value); fd.append('hair_style', checked.join(','));
const _reqStart = performance.now();
try {
const r = await fetch(API_BASE + '/api/v1/hairline/generate', { method:'POST', body:fd });
@@ -214,6 +252,7 @@ function copyJson() {
}
document.addEventListener('DOMContentLoaded', () => {
onGenderChange(); // 初始填充发型列表
const dz = $('imageFile');
dz.addEventListener('dragover', e => { e.preventDefault(); dz.style.borderColor='#2563eb'; });
dz.addEventListener('dragleave', () => dz.style.borderColor='#ddd');