diff --git a/static/test_interface5.html b/static/test_interface5.html index 7d8fd0f..40e340a 100644 --- a/static/test_interface5.html +++ b/static/test_interface5.html @@ -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 @@
- +
-
- - +
+ +
+
+
+ + +
+
-
JPG/PNG 正面照  |  发型序号 Female: 1椭圆/2花瓣/3心形/4直线/5波浪  |  Male: 1椭圆/2倒弧/3M形/4直线  |  每个发型返回 middle/high/low 三档 + 生发图
+
JPG/PNG 正面照  |  Female: 椭圆/花瓣/心形/直线/波浪  |  Male: 椭圆/倒弧/M形/直线  |  每个发型返回 middle/high/low 三档 + 生发图
@@ -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');