feat(core): Wave 3 batch2 — 资产库详情/上传/批量 + AI工具模特库/gen-card/pl-modal
资产库(P0,sub-agent):多选+吸底 bulk-bar、资产详情弹窗(立绘+三视图+标签/属性+商品媒体画廊)、 上传 Drawer→居中 Modal(类型分段+按类型字段+拖拽预览)、缺三视图徽标(复用现成类) AI图片工具(P0,sub-agent):接入现成 ActorLibrary 模特库弹窗、gen-card 三件套(再生成/就地反馈/ 已采用绿角标,采用反馈去全局弹窗改就地)、平台套图恢复多选+分组、商品库 pl-modal 选择器(restraint重写) 验证: tsc 0 · build 0 · 走查 资产详情/上传弹窗开关ESC + 模特库/pl-modal 打开 全过 · 0 console error ⚠️ 真实数据缺(未造假):资产「移动到」改分类需 api.updateAsset 支持 category 字段; 详情三视图版本历史 V1 是 mock 无真实源;平台无 platform 字段→前端组织分批。均移交监督。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
0083918207
commit
38f56cb037
@@ -391,6 +391,19 @@
|
||||
.image-workbench .iw-main-h .tb-chip svg { width: 10px; height: 10px; color: var(--ink-3); }
|
||||
.image-workbench .iw-main-h .tb-menu-wrap { position: relative; }
|
||||
.image-workbench .iw-main-h .tb-search-wrap { display: inline-flex; align-items: center; }
|
||||
/* P0④「商品库」入口(打开 pl-modal 全屏选择器 · 二级胶囊) */
|
||||
.image-workbench .iw-main-h .iw-pl-btn {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
height: 32px; padding: 0 12px 0 10px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-sm);
|
||||
color: var(--black-alpha-72);
|
||||
font-size: 13px; font-family: inherit; cursor: pointer;
|
||||
transition: border-color var(--t-base), color var(--t-base), background var(--t-base);
|
||||
}
|
||||
.image-workbench .iw-main-h .iw-pl-btn:hover { border-color: var(--heat-20); color: var(--heat); background: var(--heat-12); }
|
||||
.image-workbench .iw-main-h .iw-pl-btn svg { width: 13px; height: 13px; }
|
||||
.image-workbench .iw-main-body {
|
||||
flex: 1; min-height: 0;
|
||||
display: grid;
|
||||
@@ -426,8 +439,24 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.image-workbench .iw-step-h .title { font-size: 14px; font-weight: 600; color: var(--accent-black); }
|
||||
.image-workbench .iw-step-h .right { margin-left: auto; font-size: 12px; color: var(--heat); cursor: pointer; }
|
||||
.image-workbench .iw-step-h .right { font-size: 12px; color: var(--heat); cursor: pointer; }
|
||||
.image-workbench .iw-step-h .right:hover { text-decoration: underline; }
|
||||
/* P0①「模特库」入口按钮(打开全屏 ActorLibrary · 二级胶囊 · 不抢主橙) */
|
||||
.image-workbench .iw-step-h .iw-actor-lib-btn {
|
||||
margin-left: auto;
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
height: 26px; padding: 0 10px 0 8px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-sm);
|
||||
color: var(--black-alpha-72);
|
||||
font-size: 12px; font-family: inherit; cursor: pointer;
|
||||
transition: border-color var(--t-base), color var(--t-base), background var(--t-base);
|
||||
}
|
||||
.image-workbench .iw-step-h .iw-actor-lib-btn:hover { border-color: var(--heat-20); color: var(--heat); background: var(--heat-12); }
|
||||
.image-workbench .iw-step-h .iw-actor-lib-btn svg { width: 12px; height: 12px; }
|
||||
/* 模特库按钮在场时,「全部 (n)」紧随其后,不再 margin-left:auto */
|
||||
.image-workbench .iw-step-h .iw-actor-lib-btn + .right { margin-left: 8px; }
|
||||
.image-workbench .iw-sub-h {
|
||||
font-size: 12px; color: var(--black-alpha-48);
|
||||
margin-bottom: 6px;
|
||||
@@ -687,7 +716,40 @@
|
||||
transition: background var(--t-base), color var(--t-base);
|
||||
}
|
||||
.image-workbench .gen-img-btn:hover { background: var(--black-alpha-4); color: var(--accent-black); }
|
||||
.image-workbench .gen-img-btn:disabled { color: var(--black-alpha-24); cursor: not-allowed; }
|
||||
.image-workbench .gen-img-btn:disabled:hover { background: transparent; color: var(--black-alpha-24); }
|
||||
.image-workbench .gen-img-btn svg { width: 14px; height: 14px; }
|
||||
|
||||
/* §4.18 ② 中央就地反馈(采用瞬间亮 1.5s · 暗底白字 · 禁全局 toast) */
|
||||
.image-workbench .gen-image-feedback {
|
||||
position: absolute; inset: 0;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
|
||||
background: rgba(38, 38, 38, .88);
|
||||
color: var(--accent-white);
|
||||
border-radius: var(--r-md);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity .2s ease;
|
||||
z-index: 3;
|
||||
}
|
||||
.image-workbench .gen-image.show-feedback .gen-image-feedback { opacity: 1; }
|
||||
.image-workbench .gen-image-feedback svg { width: 20px; height: 20px; }
|
||||
.image-workbench .gen-image-feedback span { font-size: 12px; font-weight: 500; letter-spacing: .02em; }
|
||||
|
||||
/* §4.18 ③ 左上「已采用」绿角标(批次 adopted 常驻 · forest token) */
|
||||
.image-workbench .gen-adopt-badge {
|
||||
position: absolute; top: 8px; left: 8px;
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
height: 22px; padding: 0 8px 0 6px;
|
||||
background: var(--accent-forest);
|
||||
color: var(--accent-white);
|
||||
font-family: var(--font-mono); font-size: 11px; font-weight: 600;
|
||||
letter-spacing: .02em;
|
||||
border-radius: var(--r-pill);
|
||||
z-index: 3;
|
||||
}
|
||||
.image-workbench .gen-adopt-badge svg { width: 11px; height: 11px; }
|
||||
|
||||
/* 底部操作按钮行(§4.18 .gen-card-actions · 二级 + ghost · 不放主橙) */
|
||||
.image-workbench .gen-card-actions {
|
||||
display: flex; gap: 8px;
|
||||
@@ -735,6 +797,32 @@
|
||||
/* 批次卡:复用 .gen-card。每批各带一个导航头(.iw-pv-h),批次间靠「卡片→下一个头」拉开间距;
|
||||
首个头紧跟 iw-preview 顶 padding,无需额外上间距(故只给跟在卡片后的头加 margin)。 */
|
||||
.image-workbench .gen-batch-card + .iw-pv-h { margin-top: 22px; }
|
||||
|
||||
/* P0③ · 平台套图多平台分组 section 头(平台 logo + 名 + 批次数) */
|
||||
.image-workbench .iw-cover-group-h {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
margin: 6px 0 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid var(--border-faint);
|
||||
}
|
||||
.image-workbench .gen-batch-card + .iw-cover-group-h { margin-top: 28px; }
|
||||
.image-workbench .iw-cover-group-h .cg-logo {
|
||||
width: 24px; height: 24px;
|
||||
border-radius: var(--r-sm);
|
||||
display: grid; place-items: center;
|
||||
color: var(--accent-white);
|
||||
font-family: var(--font-mono); font-size: 12px; font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.image-workbench .iw-cover-group-h .cg-name { font-size: 14px; font-weight: 600; color: var(--accent-black); }
|
||||
.image-workbench .iw-cover-group-h .cg-ct {
|
||||
margin-left: auto;
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-48); letter-spacing: .02em;
|
||||
}
|
||||
/* 分组头里第一个导航头紧跟,无需额外上间距 */
|
||||
.image-workbench .iw-cover-group-h + .iw-pv-h { margin-top: 0; }
|
||||
|
||||
/* 批次头(数量 + 状态) */
|
||||
.image-workbench .gen-batch-h {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
@@ -780,10 +868,10 @@
|
||||
}
|
||||
/* 批次底部气泡向上弹出(底部空间不足) */
|
||||
.image-workbench .gen-bubble.gen-bubble-up { top: auto; bottom: calc(100% + 6px); }
|
||||
.image-workbench .gen-img-more:hover .gen-bubble,
|
||||
.image-workbench .gen-img-more:focus-within .gen-bubble,
|
||||
.image-workbench .gen-batch-more:hover .gen-bubble,
|
||||
.image-workbench .gen-batch-more:focus-within .gen-bubble { display: block; }
|
||||
/* 单图气泡改 click 驱动(§4.18 悬浮组在 hover 浮层内,hover 嵌套会闪;用 .open 显式控制) */
|
||||
.image-workbench .gen-img-more .gen-bubble.open { display: block; }
|
||||
.image-workbench .gen-bubble-item {
|
||||
width: 100%;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
@@ -1622,3 +1710,189 @@
|
||||
.asset-factory .history-type { font-size: 12px; color: var(--black-alpha-48); margin-top: 3px; font-family: var(--font-mono); letter-spacing: .02em; }
|
||||
.asset-factory .history-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
|
||||
.asset-factory .history-foot .mono { font-family: var(--font-mono); font-size: 12px; color: var(--black-alpha-48); }
|
||||
|
||||
/* ============================================================
|
||||
D · 商品库全屏选择器(.pl-modal · P0④)
|
||||
基线:public/exact/model-photo.html .pl-modal —— 重写为 restraint token
|
||||
(旧 styles.css .pl-card/.pl-modal 是暖米/出错色,禁复用)。
|
||||
全屏无遮罩,portal 到 body,顶 z-index。多选 + 右上勾 + 底部已选汇总。
|
||||
============================================================ */
|
||||
.pl-modal-bg {
|
||||
position: fixed; inset: 0;
|
||||
background: var(--surface);
|
||||
z-index: 998;
|
||||
display: flex;
|
||||
}
|
||||
.pl-modal {
|
||||
flex: 1;
|
||||
background: var(--surface);
|
||||
overflow: hidden;
|
||||
display: flex; flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
.pl-modal-h {
|
||||
display: flex; align-items: center; gap: 14px;
|
||||
padding: 14px 28px;
|
||||
border-bottom: 1px solid var(--border-faint);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pl-modal-h h2 { font-size: 16px; font-weight: 600; color: var(--accent-black); }
|
||||
.pl-modal-h .ct {
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-48); letter-spacing: .02em;
|
||||
}
|
||||
.pl-modal-h .actions { margin-left: auto; display: flex; gap: 10px; }
|
||||
.pl-modal-h .x {
|
||||
width: 32px; height: 32px;
|
||||
display: grid; place-items: center;
|
||||
background: transparent; border: 0; border-radius: var(--r-sm);
|
||||
cursor: pointer; color: var(--black-alpha-56);
|
||||
transition: background var(--t-base), color var(--t-base);
|
||||
}
|
||||
.pl-modal-h .x:hover { background: var(--black-alpha-8); color: var(--accent-black); }
|
||||
.pl-modal-body {
|
||||
flex: 1; min-height: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 200px minmax(0, 1fr);
|
||||
}
|
||||
@media (max-width: 900px) { .pl-modal-body { grid-template-columns: 160px minmax(0, 1fr); } }
|
||||
|
||||
/* 左 · 分类侧栏 */
|
||||
.pl-side {
|
||||
border-right: 1px solid var(--border-faint);
|
||||
padding: 18px 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.pl-side .pl-side-h {
|
||||
padding: 0 20px 8px;
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-48); letter-spacing: .06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.pl-side .pl-side-item {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 9px 20px;
|
||||
cursor: pointer; color: var(--black-alpha-72);
|
||||
font-size: 13px;
|
||||
border-left: 3px solid transparent;
|
||||
transition: background var(--t-base), color var(--t-base);
|
||||
}
|
||||
.pl-side .pl-side-item:hover { background: var(--black-alpha-4); }
|
||||
.pl-side .pl-side-item.active {
|
||||
background: var(--heat-12); color: var(--accent-black);
|
||||
border-left-color: var(--heat); font-weight: 600;
|
||||
}
|
||||
.pl-side .pl-side-item .ct {
|
||||
margin-left: auto;
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-48);
|
||||
}
|
||||
|
||||
/* 右 · 搜索 toolbar + 网格 + 底部汇总 */
|
||||
.pl-main { overflow: hidden; padding: 0; display: flex; flex-direction: column; min-width: 0; }
|
||||
.pl-toolbar {
|
||||
padding: 14px 28px;
|
||||
border-bottom: 1px solid var(--border-faint);
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pl-toolbar .search { position: relative; flex: 1; max-width: 360px; }
|
||||
.pl-toolbar .search input {
|
||||
width: 100%; height: 32px;
|
||||
padding: 0 10px 0 32px;
|
||||
background: var(--background-lighter);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-sm);
|
||||
font-size: 13px; font-family: inherit;
|
||||
color: var(--accent-black); outline: none;
|
||||
transition: border-color var(--t-base), background var(--t-base);
|
||||
}
|
||||
.pl-toolbar .search input:focus { border-color: var(--heat-40); background: var(--surface); }
|
||||
.pl-toolbar .search input::placeholder { color: var(--black-alpha-48); }
|
||||
.pl-toolbar .search svg {
|
||||
position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
|
||||
width: 14px; height: 14px; color: var(--black-alpha-48);
|
||||
pointer-events: none;
|
||||
}
|
||||
.pl-toolbar .btn-new {
|
||||
height: 32px; padding: 0 14px;
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-sm);
|
||||
color: var(--accent-black);
|
||||
font-family: inherit; font-size: 13px;
|
||||
cursor: pointer; margin-left: auto;
|
||||
transition: background var(--t-base), border-color var(--t-base);
|
||||
}
|
||||
.pl-toolbar .btn-new:hover { background: var(--background-lighter); border-color: var(--black-alpha-24); }
|
||||
.pl-scroll {
|
||||
flex: 1; min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding: 20px 28px 28px;
|
||||
}
|
||||
.pl-empty {
|
||||
padding: 60px 20px;
|
||||
text-align: center; color: var(--black-alpha-48);
|
||||
font-size: 13px; line-height: 1.7;
|
||||
}
|
||||
.pl-empty .mono { font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; margin-bottom: 6px; }
|
||||
.pl-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
.pl-card {
|
||||
position: relative;
|
||||
background: var(--background-lighter);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-md);
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
text-align: left; font-family: inherit;
|
||||
transition: background var(--t-base), border-color var(--t-base);
|
||||
}
|
||||
.pl-card:hover { background: var(--surface); }
|
||||
.pl-card.selected { border-color: var(--heat); background: var(--heat-12); }
|
||||
.pl-card .pl-thumb {
|
||||
aspect-ratio: 1;
|
||||
border-radius: var(--r-sm);
|
||||
}
|
||||
.pl-card .pl-thumb.has-real-media { overflow: hidden; background: var(--black-alpha-4); }
|
||||
.pl-card .pl-thumb.has-real-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
.pl-card .pl-name {
|
||||
font-size: 13px; font-weight: 500; color: var(--accent-black);
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.pl-card .pl-meta {
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-48); letter-spacing: .02em;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.pl-card .pl-check {
|
||||
position: absolute; top: 16px; right: 16px;
|
||||
width: 22px; height: 22px;
|
||||
background: var(--surface);
|
||||
border: 1.5px solid var(--black-alpha-24);
|
||||
border-radius: 50%;
|
||||
display: grid; place-items: center;
|
||||
z-index: 2; color: var(--accent-white);
|
||||
}
|
||||
.pl-card .pl-check svg { width: 11px; height: 11px; visibility: hidden; }
|
||||
.pl-card.selected .pl-check { background: var(--heat); border-color: var(--heat); }
|
||||
.pl-card.selected .pl-check svg { visibility: visible; }
|
||||
|
||||
/* 底部 · 已选汇总 + 操作 */
|
||||
.pl-modal-f {
|
||||
padding: 14px 28px;
|
||||
border-top: 1px solid var(--border-faint);
|
||||
display: flex; justify-content: flex-end; align-items: center; gap: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pl-modal-f .summary {
|
||||
margin-right: auto;
|
||||
font-family: var(--font-mono); font-size: 12px;
|
||||
color: var(--black-alpha-56); letter-spacing: .02em;
|
||||
}
|
||||
.pl-modal-f .summary b { color: var(--heat); font-weight: 600; }
|
||||
|
||||
Reference in New Issue
Block a user