2026-06-18 17:11:56 +08:00
<!DOCTYPE html>
< html lang = "zh-CN" >
< head >
< meta charset = "UTF-8" >
< title > 自动化工具 — AI 穿搭页签</ title >
< style >
: root {
--win : #f0f0f0 ; --panel : #fff ; --panel-2 : #f7f7f7 ; --line : #d6d6d6 ; --line-2 : #e3e3e3 ;
--canvas : #9a9da3 ; --txt : #202020 ; --txt-2 : #555 ; --txt-3 : #888 ;
--accent : #0067c0 ; --accent-2 : #0078d4 ; --accent-soft : #cfe4f7 ; --accent-bg : #e8f1fb ;
--green : #107c10 ; --amber : #b87a00 ; --red : #c42b1c ; --info : #15538f ; --r : 3 px ;
--font : "Segoe UI" , "Microsoft YaHei" , "微软雅黑" , sans-serif ;
--mono : "Cascadia Mono" , "Consolas" , "Microsoft YaHei" , monospace ;
}
* { box-sizing : border-box ; margin : 0 ; padding : 0 }
body { font-family : var ( -- font ); color : var ( -- txt ); font-size : 12 px ; background : #cfcfcf ; display : flex ; align-items : center ; justify-content : center ; padding : 24 px ; min-height : 100 vh }
. app { width : 1920 px ; height : 1080 px ; background : var ( -- win ); display : grid ; grid-template-rows : 34 px 40 px 1 fr 26 px ; border : 1 px solid #b5b5b5 ; overflow : hidden ; box-shadow : 0 18 px 50 px rgba ( 0 , 0 , 0 , .35 )}
@ media ( max-width : 2000px ) {. app { transform : scale ( .92 )}}
@ media ( max-width : 1800px ) {. app { transform : scale ( .78 )}}
@ media ( max-width : 1500px ) {. app { transform : scale ( .62 )}}
@ media ( max-width : 1200px ) {. app { transform : scale ( .48 )}}
@ media ( max-width : 950px ) {. app { transform : scale ( .34 )}}
/* ---- TITLE ---- */
. title { background : #fff ; border-bottom : 1 px solid var ( -- line ); display : flex ; align-items : center ; padding : 0 0 0 12 px ; height : 34 px }
. title . ic { width : 18 px ; height : 18 px ; border-radius : 3 px ; background : linear-gradient ( 135 deg , #0078d4 , #005a9e ); display : grid ; place-items : center ; color : #fff ; font-size : 11 px ; font-weight : 700 ; margin-right : 8 px }
. title . t { font-size : 12 px ; color : var ( -- txt )}
. title . ver { font-size : 11 px ; color : var ( -- txt -3 ); margin-left : 8 px }
. title . gear { margin-left : auto ; display : flex ; align-items : center ; gap : 6 px ; height : 100 % ; padding : 0 12 px ; color : var ( -- txt -2 ); border-left : 1 px solid var ( -- line -2 )}
. title . gear : hover { background : #f0f0f0 }
. title . win-btns { display : flex ; height : 34 px }
. title . wb { width : 46 px ; display : grid ; place-items : center ; color : #444 ; font-size : 11 px }
. title . wb . close : hover { background : #c42b1c ; color : #fff }. title . wb : hover { background : #e6e6e6 }
/* ---- TABS ---- */
. tabs { background : var ( -- win ); border-bottom : 1 px solid var ( -- line ); display : flex ; align-items : flex-end ; padding : 0 12 px ; gap : 4 px }
. tab { display : flex ; align-items : center ; gap : 8 px ; height : 32 px ; padding : 0 18 px ; background : #e4e4e4 ; border : 1 px solid var ( -- line ); border-bottom : none ; border-radius : 6 px 6 px 0 0 ; color : var ( -- txt -2 ); position : relative ; top : 1 px }
. tab . num { width : 18 px ; height : 18 px ; border-radius : 50 % ; background : #bcbcbc ; color : #fff ; font-size : 11 px ; font-weight : 700 ; display : grid ; place-items : center }
. tab . nm { font-size : 13 px }
. tab . on { background : #fff ; color : var ( -- txt ); border-color : var ( -- line ); font-weight : 600 }
. tab . on . num { background : var ( -- accent )}
. tab : not ( . on ) : hover { background : #ececec }
/* ---- BODY GRID ---- */
. body { display : grid ; grid-template-columns : 558 px 1 fr 300 px ; min-height : 0 }
/* ---- LEFT : data source + settings ---- */
. left { background : var ( -- panel ); border-right : 1 px solid var ( -- line ); display : flex ; flex-direction : column ; min-height : 0 }
. lscroll { flex : 1 ; overflow : auto ; padding : 12 px }
. grp { border : 1 px solid var ( -- line ); border-radius : var ( -- r ); background : #fff ; margin-bottom : 14 px ; position : relative ; padding : 15 px 12 px 12 px }
. grp-t { position : absolute ; top : -8 px ; left : 9 px ; background : #fff ; padding : 0 6 px ; font-size : 11 px ; font-weight : 600 ; color : var ( -- txt -2 )}
. fl label { display : block ; color : var ( -- txt -2 ); margin-bottom : 4 px ; font-size : 11 px }
. row { display : flex ; gap : 8 px ; margin-bottom : 8 px }. row : last-child { margin-bottom : 0 }. fl { flex : 1 ; min-width : 0 }
. path { display : flex ; align-items : center ; height : 28 px ; border : 1 px solid var ( -- line ); border-radius : var ( -- r ); background : #fff }
. path . p { flex : 1 ; padding : 0 7 px ; color : #444 ; font-size : 11 px ; white-space : nowrap ; overflow : hidden ; text-overflow : ellipsis }
. path . br { width : 30 px ; height : 100 % ; border-left : 1 px solid var ( -- line ); display : grid ; place-items : center ; background : var ( -- win )}
. sel { display : flex ; align-items : center ; justify-content : space-between ; height : 28 px ; border : 1 px solid var ( -- line ); border-radius : var ( -- r ); background : #fff ; padding : 0 8 px }
. sel . car { color : #666 ; font-size : 10 px }
. inp { display : flex ; align-items : center ; height : 28 px ; border : 1 px solid var ( -- line ); border-radius : var ( -- r ); background : #fff ; padding : 0 7 px }
. inp input { border : none ; outline : none ; width : 100 % ; font : inherit ; color : var ( -- txt ); background : none }
. inp . u { color : var ( -- txt -3 ); font-size : 11 px ; padding-left : 4 px }
. inp . focus { border-color : var ( -- accent ); box-shadow : 0 0 0 1 px var ( -- accent )}
. ckline { display : flex ; align-items : center ; gap : 6 px ; color : var ( -- txt -2 ); margin-top : 2 px }
. cbox { width : 14 px ; height : 14 px ; border : 1 px solid #999 ; border-radius : 2 px ; background : #fff ; display : inline-block ; flex : none }
. cbox . on { background : var ( -- accent ); border-color : var ( -- accent )}
. cbox . on :: after { content : "✓" ; color : #fff ; font-size : 9 px ; line-height : 12 px ; display : block ; text-align : center }
/* loaded-excel summary line */
. xlmeta { display : flex ; flex-wrap : wrap ; gap : 5 px ; margin-top : 8 px }
. chipmeta { font-size : 10 px ; padding : 1 px 8 px ; border-radius : 9 px ; background : #eef3f9 ; color : #2b5b8c }
. chipmeta . done { background : #e3f3e3 ; color : #2c7a2c }
. chipmeta . wait { background : #eee ; color : #666 }
. chipmeta . err { background : #fbe4e2 ; color : #a3271c }
/* prompt editor */
. ta { width : 100 % ; height : 128 px ; overflow : auto ; border : 1 px solid var ( -- line ); border-radius : var ( -- r ); background : #fff ; padding : 8 px 9 px ; font : 12 px / 1.7 var ( -- font ); color : var ( -- txt )}
. ph { color : var ( -- info ); font-weight : 600 }
. promptbar { display : flex ; flex-wrap : wrap ; gap : 6 px ; margin-top : 8 px }
. pchip { display : flex ; align-items : center ; gap : 5 px ; height : 26 px ; padding : 0 9 px ; border : 1 px solid var ( -- line ); border-radius : 13 px ; background : #fff ; color : var ( -- txt -2 ); font-size : 11 px }
. pchip . pp { color : var ( -- info ); font-family : var ( -- mono )}
. pchip : hover { background : #f3f8fd ; border-color : var ( -- accent - soft )}
. pchip . act { margin-left : auto ; border-color : var ( -- accent - soft ); color : var ( -- accent )}
/* compact settings grid */
. sgrid { display : grid ; grid-template-columns : 1 fr 1 fr 1 fr ; gap : 8 px 10 px }
. sgrid . fl { margin : 0 }
/* ---- CENTER : the transformation thesis + batch table ---- */
. center { background : var ( -- panel -2 ); display : grid ; grid-template-rows : auto 1 fr ; min-height : 0 }
/* results strip — recently finished outputs only (no live/in-flight state) */
. rstrip { padding : 14 px 16 px 0 }
. rstrip-h { display : flex ; align-items : baseline ; gap : 10 px ; margin-bottom : 10 px }
. rstrip-h . st { font-size : 13 px ; font-weight : 600 }
. rstrip-h . meta { color : var ( -- txt -3 ); font-size : 11 px }
. rstrip-h . hint { margin-left : auto ; color : var ( -- txt -3 ); font-size : 11 px }
. rcards { display : flex ; gap : 10 px ; overflow-x : auto ; padding-bottom : 6 px }
. rcard { width : 126 px ; flex : none ; border : 1 px solid var ( -- line ); border-radius : 6 px ; overflow : hidden ; background : #fff }
. rcard . new { border-color : var ( -- accent - soft ); box-shadow : 0 0 0 2 px var ( -- accent - bg )}
. rcard . rimg { height : 150 px ; position : relative ; overflow : hidden ; display : grid ; place-items : center ; background : radial-gradient ( 120 % 90 % at 50 % 0 , #eef4fb 0 , #e3edf7 48 % , #d8e6f3 100 % )}
. rcard . badge-new { position : absolute ; top : 5 px ; left : 5 px ; background : var ( -- accent ); color : #fff ; font-size : 9 px ; padding : 1 px 6 px ; border-radius : 8 px ; z-index : 2 }
. rcard . rcap { display : flex ; align-items : center ; gap : 6 px ; padding : 5 px 8 px ; border-top : 1 px solid var ( -- line -2 ); font-size : 11 px }
. rcard . rcap b { font-weight : 600 }
. rcard . rcap . sz { margin-left : auto ; color : var ( -- txt -3 ); font-size : 10 px }
. rcard . pending { opacity : .85 }
. rcard . pending . rimg { background : repeating-linear-gradient ( 45 deg , #f1f1f1 0 8 px , #f6f6f6 8 px 16 px ); color : var ( -- txt -3 ); font-size : 11 px }
/* mini worn-on-model figure (result thumbnail); per-card color via --tee / inline --prt */
. mfig { position : relative ; width : 96 px ; height : 132 px ; filter : drop-shadow ( 0 5 px 12 px rgba ( 0 , 0 , 0 , .14 ))}
. mfig . hr { position : absolute ; top : 1 px ; left : 50 % ; transform : translateX ( -50 % ); width : 35 px ; height : 20 px ; border-radius : 18 px 18 px 0 0 ; background : #3a2a22 }
. mfig . h { position : absolute ; top : 6 px ; left : 50 % ; transform : translateX ( -50 % ); width : 28 px ; height : 32 px ; border-radius : 14 px 14 px 13 px 13 px ; background : #e7c5a8 }
. mfig . nk { position : absolute ; top : 32 px ; left : 50 % ; transform : translateX ( -50 % ); width : 14 px ; height : 11 px ; background : #e0b89a }
. mfig . ts { position : absolute ; top : 38 px ; left : 50 % ; transform : translateX ( -50 % ); width : 88 px ; height : 94 px ; background : var ( -- tee , #fdfdfb ); border-radius : 14 px 14 px 6 px 6 px ; box-shadow : inset 0 4 px 12 px rgba ( 0 , 0 , 0 , .06 )}
. mfig . sl , . mfig . sr { position : absolute ; top : 42 px ; width : 20 px ; height : 56 px ; background : var ( -- tee , #fdfdfb ); border-radius : 10 px }
. mfig . sl { left : 2 px ; transform : rotate ( 8 deg )}. mfig . sr { right : 2 px ; transform : rotate ( -8 deg )}
. mfig . ch { position : absolute ; top : 60 px ; left : 50 % ; transform : translateX ( -50 % ); width : 40 px ; height : 40 px ; border-radius : 4 px ; background : var ( -- prt , transparent )}
/* batch table */
. tablewrap { margin : 14 px 16 px 16 px ; display : flex ; flex-direction : column ; min-height : 0 ; border : 1 px solid var ( -- line ); border-radius : 6 px ; background : #fff ; overflow : hidden }
. tbl-h { display : flex ; align-items : center ; gap : 10 px ; height : 34 px ; padding : 0 12 px ; background : var ( -- panel -2 ); border-bottom : 1 px solid var ( -- line -2 )}
. tbl-h . tt { font-weight : 600 }
. tbl-h . tmeta { color : var ( -- txt -3 ); font-size : 11 px }
. tbl-h . filters { margin-left : auto ; display : flex ; gap : 6 px }
. fbtn { height : 24 px ; padding : 0 10 px ; border : 1 px solid var ( -- line ); border-radius : 12 px ; background : #fff ; color : var ( -- txt -2 ); font-size : 11 px ; display : flex ; align-items : center ; gap : 5 px }
. fbtn . on { background : var ( -- accent - bg ); border-color : var ( -- accent - soft ); color : var ( -- accent )}
. tbl-scroll { flex : 1 ; overflow : auto }
table . bt { width : 100 % ; border-collapse : collapse ; font-size : 11 px }
table . bt th { position : sticky ; top : 0 ; background : #f4f4f4 ; border-bottom : 1 px solid var ( -- line ); text-align : left ; font-weight : 600 ; color : var ( -- txt -2 ); padding : 7 px 10 px ; white-space : nowrap }
table . bt td { border-bottom : 1 px solid var ( -- line -2 ); padding : 6 px 10 px ; color : var ( -- txt ); white-space : nowrap }
table . bt tr . sel td { background : var ( -- accent - bg )}
table . bt tr : hover td { background : #f7faff }
. bidx { color : var ( -- txt -3 ); width : 34 px }
. gthumb { width : 22 px ; height : 26 px ; border-radius : 2 px ; display : inline-block ; vertical-align : -7 px ; margin-right : 7 px ; border : 1 px solid rgba ( 0 , 0 , 0 , .12 ); background : #f0f0ec }
. gthumb . d { background : #2c3037 }
. pill { display : inline-block ; padding : 1 px 9 px ; border-radius : 9 px ; font-size : 10 px ; font-weight : 600 }
. pill . done { background : #e3f3e3 ; color : #2c7a2c }
. pill . run { background : #e0eefc ; color : #15538f }
. pill . wait { background : #eee ; color : #666 }
. pill . skip { background : #f1efe6 ; color : #8a7a3a }
. pill . err { background : #fbe4e2 ; color : #a3271c }
. lnk { color : var ( -- accent )}
. muted { color : var ( -- txt -3 )}
/* ---- RIGHT : run + log ---- */
. right { background : var ( -- win ); border-left : 1 px solid var ( -- line ); display : flex ; flex-direction : column ; min-height : 0 }
. runtop { padding : 14 px 14 px 10 px ; border-bottom : 1 px solid var ( -- line ); background : #fff }
. runtop . rt { font-size : 11 px ; font-weight : 600 ; color : var ( -- txt -2 ); margin-bottom : 10 px }
. progwrap { display : flex ; align-items : center ; gap : 14 px }
. ring { --p : 32 ; width : 78 px ; height : 78 px ; border-radius : 50 % ; flex : none ;
background : conic-gradient ( var ( -- accent ) calc ( var ( -- p ) * 1 % ), #e8e8e8 0 );
display : grid ; place-items : center ; position : relative }
. ring :: before { content : "" ; position : absolute ; inset : 9 px ; border-radius : 50 % ; background : #fff }
. ring . pc { position : relative ; font-size : 17 px ; font-weight : 700 ; color : var ( -- txt )}
. ring . pc small { font-size : 10 px ; color : var ( -- txt -3 ); font-weight : 400 }
. stats { flex : 1 ; display : grid ; grid-template-columns : 1 fr 1 fr ; gap : 7 px }
. stat { border : 1 px solid var ( -- line ); border-radius : var ( -- r ); padding : 5 px 8 px ; background : #fafafa }
. stat . v { font-size : 15 px ; font-weight : 700 ; line-height : 1.2 }
. stat . k { font-size : 10 px ; color : var ( -- txt -3 )}
. stat . done . v { color : var ( -- green )}. stat . err . v { color : var ( -- red )}. stat . skip . v { color : var ( -- amber )}. stat . left . v { color : var ( -- txt -2 )}
. runbtns { padding : 12 px 14 px ; border-bottom : 1 px solid var ( -- line ); display : flex ; flex-direction : column ; gap : 8 px ; background : var ( -- win )}
. btn { width : 100 % ; height : 36 px ; border-radius : var ( -- r ); display : flex ; align-items : center ; justify-content : center ; gap : 7 px ; font-size : 12 px ; font-weight : 600 ; border : 1 px solid var ( -- line )}
. btn . pri { background : var ( -- accent ); border-color : var ( -- accent ); color : #fff }. btn . pri : hover { background : var ( -- accent -2 )}
. btn . stop { background : #fff ; border-color : #e0b4ae ; color : var ( -- red )}. btn . stop : hover { background : #fdf3f2 }
. btn . sec { background : #fff }. btn . sec : hover { background : #f3f8fd }
. brow { display : flex ; gap : 8 px }. brow . btn { margin : 0 }
. logwrap { flex : 1 ; display : flex ; flex-direction : column ; min-height : 0 }
. log-h { display : flex ; align-items : center ; gap : 8 px ; padding : 8 px 14 px ; background : var ( -- panel -2 ); border-bottom : 1 px solid var ( -- line -2 )}
. log-h . lt { font-weight : 600 ; color : var ( -- txt -2 ); font-size : 11 px }
. log-h . auto { margin-left : auto ; display : flex ; align-items : center ; gap : 5 px ; color : var ( -- txt -3 ); font-size : 10 px }
. logbody { flex : 1 ; overflow : auto ; background : #fbfbfb ; padding : 8 px 10 px ; font : 11 px / 1.65 var ( -- mono ); color : #444 }
. logbody . l { display : flex ; gap : 8 px ; white-space : nowrap }
. logbody . ts { color : #aaa ; flex : none }
. logbody . ok { color : var ( -- green )}
. logbody . warn { color : var ( -- amber )}
. logbody . erl { color : var ( -- red )}
. logbody . vio { color : var ( -- info )}
/* ---- STATUS BAR ---- */
. status { background : #fff ; border-top : 1 px solid var ( -- line ); display : flex ; align-items : center ; padding : 0 12 px ; gap : 14 px ; color : var ( -- txt -2 ); font-size : 11 px }
. status . s { display : flex ; align-items : center ; gap : 5 px }. status b { color : var ( -- txt ); font-weight : 600 }
. dot { width : 7 px ; height : 7 px ; border-radius : 50 % }. dot . g { background : var ( -- green )}. dot . a { background : var ( -- amber )}. dot . v { background : var ( -- info )}
. status . sp { flex : 1 }. vsep { width : 1 px ; height : 14 px ; background : var ( -- line -2 )}
</ style >
</ head >
< body >
< div class = "app" >
<!-- TITLE -->
< div class = "title" >
< div class = "ic" > 穿</ div >< div class = "t" > 自动化工具</ div >< div class = "ver" > v1.0.0</ div >
< div class = "gear" >< span style = "font-size:14px" > ⚙️</ span > 配置</ div >
< div class = "win-btns" >< div class = "wb" > —</ div >< div class = "wb" > ▢</ div >< div class = "wb close" > ✕</ div ></ div >
</ div >
<!-- TABS -->
< div class = "tabs" >
< div class = "tab" >< span class = "num" > 1</ span >< span class = "nm" > 添加印花</ span ></ div >
< div class = "tab on" >< span class = "num" > 2</ span >< span class = "nm" > AI 穿搭</ span ></ div >
< div class = "tab" >< span class = "num" > 3</ span >< span class = "nm" > 导出上架</ span ></ div >
</ div >
<!-- BODY -->
< div class = "body" >
<!-- LEFT : data source + settings -->
< div class = "left" >
< div class = "lscroll" >
< div class = "grp" >< div class = "grp-t" > 数据源(Excel) </ div >
< div class = "fl" style = "margin-bottom:8px" >< label > Excel 文件</ label >
< div class = "path" >< span class = "p" > D:\\电商\\2026春\\商品表.xlsx</ span >< span class = "br" > …</ span ></ div >
</ div >
< div class = "xlmeta" >
< span class = "chipmeta" > 共 60 行</ span >
< span class = "chipmeta done" > 已完成 12</ span >
< span class = "chipmeta wait" > 待处理 45</ span >
< span class = "chipmeta err" > 失败 3</ span >
</ div >
</ div >
< div class = "grp" >< div class = "grp-t" > 输出</ div >
< div class = "fl" style = "margin-bottom:8px" >< label > 输出目录</ label >
< div class = "path" >< span class = "p" > D:\\CMBot\\合并后的图片</ span >< span class = "br" > …</ span ></ div >
</ div >
< div class = "fl" >< label > AI 模型</ label >
< div class = "sel" >< span > Nano Banana 2 · 中转</ span >< span class = "car" > ▼</ span ></ div >
</ div >
</ div >
< div class = "grp" >< div class = "grp-t" > 通用话术</ div >
2026-06-22 09:16:04 +08:00
< div class = "ta" > 为商品「< span class = "ph" > {title}</ span > 」生成人物上身实穿效果图:真人模特正面穿着这件衣服,完整保留款式、版型、颜色与印花图案,自然光、纯色棚拍背景,电商主图风格,不加文字与促销标签。</ div >
2026-06-18 17:11:56 +08:00
< div class = "promptbar" >
< span class = "pchip" > 插入< span class = "pp" > {title}</ span ></ span >
< span class = "pchip act" > ⤢ 预览最终提示词</ span >
</ div >
< div class = "promptbar" style = "margin-top:8px" >
< span class = "pchip" style = "flex:1;justify-content:center;color:var(--accent);border-color:var(--accent-soft)" > 💾 保存话术</ span >
</ div >
</ div >
< div class = "grp" >< div class = "grp-t" > 生成设置</ div >
< div class = "ckline" style = "margin-bottom:12px" >< span class = "cbox on" ></ span > 重试上次失败的行(失败 3) </ div >
< div class = "sgrid" >
< div class = "fl" >< label > 并发数</ label >< div class = "inp" >< input value = "1" ></ div ></ div >
< div class = "fl" >< label > 新请求间隔</ label >< div class = "inp" >< input value = "2" >< span class = "u" > 秒</ span ></ div ></ div >
< div class = "fl" >< label > 单任务冷却</ label >< div class = "inp" >< input value = "1" >< span class = "u" > 秒</ span ></ div ></ div >
< div class = "fl" >< label > 失败重试</ label >< div class = "inp" >< input value = "2" >< span class = "u" > 次</ span ></ div ></ div >
< div class = "fl" >< label > 分辨率</ label >< div class = "sel" >< span > 1K</ span >< span class = "car" > ▼</ span ></ div ></ div >
< div class = "fl" >< label > JPG 质量</ label >< div class = "sel" >< span > 均衡 85</ span >< span class = "car" > ▼</ span ></ div ></ div >
</ div >
</ div >
</ div >
</ div >
<!-- CENTER : transformation thesis + batch table -->
< div class = "center" >
< div class = "rstrip" >
< div class = "rstrip-h" >
< span class = "st" > 最近结果</ span >
< span class = "meta" > 已完成 12 张 · 新图自动加到最左</ span >
< span class = "hint" > 单击看大图 · 右键打开所在文件夹</ span >
</ div >
< div class = "rcards" >
< div class = "rcard new" style = "--tee:#2c3037" >
< div class = "rimg" >< span class = "badge-new" > 最新</ span >
< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:repeating-linear-gradient(45deg,#eee 0 5px,#bbb 5px 10px)" ></ div ></ div >
</ div >
< div class = "rcap" >< b > TY028</ b >< span class = "sz" > 1.8 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#f4efe6" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:conic-gradient(from 20deg,#ff6b6b,#feca57,#48dbfb,#ff9ff3,#ff6b6b)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY027</ b >< span class = "sz" > 1.6 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#2f4660" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:radial-gradient(circle at 50% 50%,#ff7e5f,#feb47b)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY026</ b >< span class = "sz" > 1.9 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#3a623d" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:linear-gradient(120deg,#5f27cd,#48dbfb)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY025</ b >< span class = "sz" > 1.5 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#6e2a2a" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:repeating-linear-gradient(45deg,#333 0 6px,#eee 6px 12px)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY024</ b >< span class = "sz" > 2.0 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#bba258" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:radial-gradient(circle at 30% 30%,#10ac84,#222f3e)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY023</ b >< span class = "sz" > 1.7 MB</ span ></ div >
</ div >
< div class = "rcard" style = "--tee:#5a7a9a" >
< div class = "rimg" >< div class = "mfig" >< div class = "hr" ></ div >< div class = "h" ></ div >< div class = "nk" ></ div >< div class = "sl" ></ div >< div class = "sr" ></ div >< div class = "ts" ></ div >< div class = "ch" style = "background:conic-gradient(from 20deg,#ff6b6b,#feca57,#48dbfb,#ff9ff3,#ff6b6b)" ></ div ></ div ></ div >
< div class = "rcap" >< b > TY022</ b >< span class = "sz" > 1.6 MB</ span ></ div >
</ div >
< div class = "rcard pending" >
< div class = "rimg" > 待生成</ div >
< div class = "rcap" >< b > TY031</ b >< span class = "sz muted" > —</ span ></ div >
</ div >
</ div >
</ div >
< div class = "tablewrap" >
< div class = "tbl-h" >
< span class = "tt" > 处理明细</ span >
< span class = "tmeta" > 按 Excel 行顺序 · 每完成一行即写回并保存</ span >
< div class = "filters" >
< span class = "fbtn on" > 全部 60</ span >
< span class = "fbtn" > 失败 3</ span >
< span class = "fbtn" > 跳过 0</ span >
</ div >
</ div >
< div class = "tbl-scroll" >
< table class = "bt" >
< thead >< tr >
< th class = "bidx" > 行</ th >< th > 标题</ th >< th > 货号</ th >< th > 衣服图</ th >< th > 状态</ th >< th > 结果 / 原因</ th >
</ tr ></ thead >
< tbody >
< tr >< td class = "bidx" > 2</ td >< td > 纯棉宽松短袖T恤</ td >< td > TY027</ td >< td >< span class = "gthumb" ></ span > TY027_白底.png</ td >< td >< span class = "pill done" > 完成</ span ></ td >< td >< span class = "lnk" > 合并后的图片\\TY027.jpg</ span ></ td ></ tr >
< tr >< td class = "bidx" > 3</ td >< td > 美式复古印花卫衣</ td >< td > TY028</ td >< td >< span class = "gthumb d" ></ span > TY028_白底.png</ td >< td >< span class = "pill done" > 完成</ span ></ td >< td >< span class = "lnk" > 合并后的图片\\TY028.jpg</ span ></ td ></ tr >
< tr >< td class = "bidx" > 4</ td >< td > 高腰显瘦牛仔裤</ td >< td > TY029</ td >< td >< span class = "gthumb" style = "background:#4a6b8a" ></ span > TY029_白底.png</ td >< td >< span class = "pill err" > 失败</ span ></ td >< td class = "muted" > 衣服图打不开:文件不存在</ td ></ tr >
< tr class = "sel" >< td class = "bidx" > 13</ td >< td > 碎花连衣裙夏季新款</ td >< td > TY030</ td >< td >< span class = "gthumb" ></ span > TY030_白底.png</ td >< td >< span class = "pill run" > 生成中</ span ></ td >< td class = "muted" > 第 1 次尝试 · 78%</ td ></ tr >
< tr >< td class = "bidx" > 14</ td >< td > 设计感小众衬衫</ td >< td > TY031</ td >< td >< span class = "gthumb d" ></ span > TY031_白底.png</ td >< td >< span class = "pill wait" > 待处理</ span ></ td >< td class = "muted" > —</ td ></ tr >
< tr >< td class = "bidx" > 15</ td >< td > —</ td >< td > —</ td >< td class = "muted" > (标题/货号为空)</ td >< td >< span class = "pill skip" > 跳过</ span ></ td >< td class = "muted" > 字段不完整,安全跳过</ td ></ tr >
< tr >< td class = "bidx" > 16</ td >< td > 休闲百搭运动短裤</ td >< td > TY033</ td >< td >< span class = "gthumb" style = "background:#3a623d" ></ span > TY033_白底.png</ td >< td >< span class = "pill wait" > 待处理</ span ></ td >< td class = "muted" > —</ td ></ tr >
< tr >< td class = "bidx" > 17</ td >< td > 法式茶歇方领上衣</ td >< td > TY034</ td >< td >< span class = "gthumb" ></ span > TY034_白底.png</ td >< td >< span class = "pill wait" > 待处理</ span ></ td >< td class = "muted" > —</ td ></ tr >
< tr >< td class = "bidx" > 18</ td >< td > oversize 落肩外套</ td >< td > TY035</ td >< td >< span class = "gthumb d" ></ span > TY035_白底.png</ td >< td >< span class = "pill wait" > 待处理</ span ></ td >< td class = "muted" > —</ td ></ tr >
< tr >< td class = "bidx" > 19</ td >< td > 冰丝防晒空调衫</ td >< td > TY036</ td >< td >< span class = "gthumb" style = "background:#bba258" ></ span > TY036_白底.png</ td >< td >< span class = "pill wait" > 待处理</ span ></ td >< td class = "muted" > —</ td ></ tr >
</ tbody >
</ table >
</ div >
</ div >
</ div >
<!-- RIGHT : run + log -->
< div class = "right" >
< div class = "runtop" >
< div class = "rt" > 本次进度</ div >
< div class = "progwrap" >
< div class = "ring" style = "--p:25" >< span class = "pc" > 15< small > /60</ small ></ span ></ div >
< div class = "stats" >
< div class = "stat done" >< div class = "v" > 12</ div >< div class = "k" > 完成</ div ></ div >
< div class = "stat err" >< div class = "v" > 1</ div >< div class = "k" > 失败</ div ></ div >
< div class = "stat skip" >< div class = "v" > 2</ div >< div class = "k" > 跳过</ div ></ div >
< div class = "stat left" >< div class = "v" > 45</ div >< div class = "k" > 待处理</ div ></ div >
</ div >
</ div >
</ div >
< div class = "runbtns" >
< div class = "btn stop" > ■ 停止生成</ div >
< div class = "brow" >
< div class = "btn sec" > ⬇ 导出失败清单</ div >
< div class = "btn sec" > 📂 打开输出目录</ div >
</ div >
</ div >
< div class = "logwrap" >
< div class = "log-h" >< span class = "lt" > 实时日志</ span >< span class = "auto" >< span class = "cbox on" style = "width:12px;height:12px" ></ span > 自动滚动</ span ></ div >
< div class = "logbody" >
< div class = "l" >< span class = "ts" > 15:42:01</ span >< span > 读取 商品表.xlsx:60 行,待处理 47</ span ></ div >
< div class = "l" >< span class = "ts" > 15:42:01</ span >< span class = "warn" > 跳过第 9 行:标题/货号为空</ span ></ div >
< div class = "l" >< span class = "ts" > 15:42:02</ span >< span > 开始生成,并发 1,分辨率 1K</ span ></ div >
< div class = "l" >< span class = "ts" > 15:42:18</ span >< span class = "ok" > ✓ TY027 完成 → TY027.jpg( 1.6 MB) </ span ></ div >
< div class = "l" >< span class = "ts" > 15:42:40</ span >< span class = "ok" > ✓ TY028 完成 → TY028.jpg( 1.8 MB) </ span ></ div >
< div class = "l" >< span class = "ts" > 15:43:02</ span >< span class = "erl" > ✕ TY029 失败:衣服图打不开(文件不存在)</ span ></ div >
< div class = "l" >< span class = "ts" > 15:43:03</ span >< span class = "muted" > 已写回 Excel E/F 列并保存</ span ></ div >
< div class = "l" >< span class = "ts" > 15:43:20</ span >< span class = "vio" > ↻ TY030 生成中…(已用 14s,请求进行中)</ span ></ div >
< div class = "l" >< span class = "ts" > 15:43:34</ span >< span class = "vio" > · TY030 等待中转响应(心跳)</ span ></ div >
</ div >
</ div >
</ div >
</ div >
<!-- STATUS -->
< div class = "status" >
< div class = "s" >< span class = "dot v" ></ span > 数据源:< b > 商品表.xlsx</ b ></ div >< div class = "vsep" ></ div >
< div class = "s" > 模型:< b > Nano Banana 2</ b ></ div >< div class = "vsep" ></ div >
< div class = "s" > 输出:< b > 合并后的图片</ b ></ div >
< div class = "sp" ></ div >
< div class = "s" >< span class = "dot a" ></ span > 生成中 15/60</ div >< div class = "vsep" ></ div >
< div class = "s" style = "color:#c42b1c" > 1 项失败</ div >< div class = "vsep" ></ div >
< div class = "s" style = "color:var(--green)" > ✓ 已写回 TY028.jpg</ div >
</ div >
</ div >
</ body >
</ html >