Files
xiaoxia-saas/apps/web/src/pages/assets/assets.css
T
xiaoxia cdcb032e45
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 27s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 28s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m28s
CI/CD Pipeline / CI Gate (pull_request) Successful in 3s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m39s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m12s
AI Code Review / AI Code Review (pull_request) Failing after 6m15s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 0s
CI/CD Pipeline / Check push changed paths (push) Successful in 1s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 21s
CI/CD Pipeline / Build Staging API Image (push) Successful in 21s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 22s
CI/CD Pipeline / Integration Tests (push) Successful in 1m44s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m30s
CI/CD Pipeline / Validate - Style (push) Successful in 2m20s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 3m19s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 5m14s
CI/CD Pipeline / Unit Tests (push) Successful in 8m4s
CI/CD Pipeline / Validate - Security (push) Successful in 16m53s
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Failing after 255h51m59s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 255h52m3s
CI/CD Pipeline / Build Production Web Image (push) Failing after 255h52m3s
CI/CD Pipeline / Retag skipped Staging API Image (push) Failing after 256h8m32s
CI/CD Pipeline / Deploy Production (push) Failing after 255h51m59s
CI/CD Pipeline / Frontend Lint (push) Failing after 256h8m58s
CI/CD Pipeline / Build Production API Image (push) Failing after 255h52m3s
CI/CD Pipeline / Staging API Integration Tests (push) Failing after 256h6m56s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 256h6m56s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 256h27m48s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 256h29m25s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 256h29m30s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 256h29m31s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 256h29m25s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 256h29m34s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 256h29m35s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 256h29m36s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 256h29m35s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 256h29m37s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 256h31m30s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 256h31m30s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 256h31m30s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 256h31m33s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Failing after 256h31m34s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 256h31m34s
CI/CD Pipeline / Validate - Security (pull_request) Failing after 256h31m35s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 256h8m58s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 256h31m35s
CI/CD Pipeline / PR Build API Image (push) Failing after 256h8m58s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 256h31m37s
CI/CD Pipeline / CI Gate (push) Failing after 256h26m38s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Failing after 256h43m7s
CI/CD Pipeline / PR Build Web Image (push) Failing after 256h43m32s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 256h43m36s
CI/CD Pipeline / ACR Image Cleanup (push) Failing after 256h41m30s
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Failing after 256h43m6s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 257h4m4s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 257h4m8s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 257h4m10s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 257h6m5s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 257h6m8s
fix(#1718/#1714): 微信回调state误杀修复+错误透传防连点、上传失败完整可观测、哈希阈值降至64MB、昵称不预填 (#1723)
2026-09-05 22:52:49 +08:00

1080 lines
22 KiB
CSS
Raw 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.
/**
* 视频库页面 - V21 设计系统样式
* 两栏布局:左侧视频库列表(260px)+ 右侧素材网格
* 统一使用 CSS 变量,支持深色/浅色主题
*/
@import "../../styles/global.css";
/* ============================================================
页面容器
============================================================ */
.xx-assets-page {
min-height: 100%;
padding: var(--space-xl);
}
/* ============================================================
两栏布局
============================================================ */
.xx-assets-layout {
display: grid;
grid-template-columns: 260px 1fr;
gap: 20px;
align-items: start;
overflow: visible;
}
/* ============================================================
左侧视频库列表
============================================================ */
.xx-asset-library-list {
display: flex;
flex-direction: column;
gap: var(--space-sm);
position: sticky;
top: var(--space-md);
align-self: start;
}
.xx-asset-library-item {
border: 1px solid var(--border-color);
background: var(--bg-primary);
border-radius: var(--radius-sm);
padding: 14px;
cursor: pointer;
transition: var(--transition-all);
}
.xx-asset-library-item:hover {
border-color: var(--primary-color);
background: var(--primary-soft);
}
.xx-asset-library-item.active {
border-color: var(--primary-color);
background: var(--primary-soft);
box-shadow: var(--shadow-primary);
}
.xx-asset-library-item:active {
transform: scale(0.98);
box-shadow: var(--shadow-sm);
}
.xx-asset-library-item h4 {
margin: 0 0 var(--space-xs);
font-size: var(--font-size-base);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.xx-asset-library-item span {
font-size: var(--font-size-sm);
color: var(--text-secondary);
}
.xx-asset-library-delete {
background: none;
border: none;
color: var(--text-tertiary);
cursor: pointer;
padding: 4px;
border-radius: var(--radius-xs);
font-size: var(--font-size-sm);
transition: var(--transition-all);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
flex-shrink: 0;
}
.xx-asset-library-item:hover .xx-asset-library-delete {
opacity: 1;
}
.xx-asset-library-delete:hover {
color: var(--error-color);
background: var(--error-soft);
}
.xx-asset-library-delete:active {
background: var(--error-color);
color: var(--text-inverse);
transform: scale(0.92);
}
.xx-asset-library-add {
border: 1px dashed var(--border-color);
background: transparent;
border-radius: var(--radius-sm);
padding: 14px;
cursor: pointer;
text-align: center;
color: var(--text-secondary);
font-size: var(--font-size-sm);
transition: var(--transition-all);
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-xs);
}
.xx-asset-library-add:hover {
border-color: var(--primary-color);
color: var(--primary-color);
background: var(--primary-soft);
}
.xx-asset-library-add:active {
transform: scale(0.98);
background: var(--primary-soft);
border-style: solid;
}
/* ============================================================
右侧内容区
============================================================ */
.xx-assets-content {
display: flex;
flex-direction: column;
gap: var(--space-lg);
}
/* ============================================================
上传区域
============================================================ */
.xx-asset-upload-entry {
display: flex;
align-items: center;
gap: var(--space-md);
flex-wrap: wrap;
padding: var(--space-sm) var(--space-md);
border: 1px dashed transparent;
border-radius: var(--radius-md);
transition: var(--transition-all);
}
.xx-asset-upload-entry-dragover {
border-color: var(--primary-color);
background: var(--primary-soft);
}
.xx-asset-upload-btn {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
padding: 6px 16px;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--text-inverse);
background: var(--primary-color);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
transition: var(--transition-all);
white-space: nowrap;
}
.xx-asset-upload-btn:hover {
opacity: 0.9;
}
.xx-asset-upload-btn:active {
transform: scale(0.98);
}
.xx-asset-upload-status {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
font-size: var(--font-size-xs);
color: var(--text-tertiary);
}
/* ============================================================
筛选栏
============================================================ */
.xx-assets-filters {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
flex-wrap: wrap;
}
.xx-assets-filters-left {
display: flex;
align-items: center;
gap: var(--space-sm);
}
.xx-assets-filters-right {
display: flex;
align-items: center;
gap: var(--space-sm);
}
/* ============================================================
素材网格
============================================================ */
.xx-asset-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 14px;
}
/* ============================================================
素材卡片
============================================================ */
.xx-asset-card {
border: 1px solid var(--border-color);
background: var(--bg-primary);
border-radius: var(--radius-md);
overflow: hidden;
cursor: pointer;
transition: var(--transition-all);
}
.xx-asset-card:hover {
border-color: var(--primary-color);
box-shadow: var(--shadow-sm);
transform: translateY(-1px);
}
.xx-asset-card:active {
transform: translateY(0) scale(0.98);
box-shadow: var(--shadow-sm);
}
/* 缩略图 */
.xx-asset-thumb {
aspect-ratio: 3 / 4;
position: relative;
overflow: hidden;
display: grid;
place-items: center;
color: var(--text-inverse);
border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.xx-asset-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
}
.xx-asset-thumb-placeholder {
font-size: var(--font-size-xl);
opacity: 0.7;
}
/* 播放按钮 */
.xx-asset-play {
position: absolute;
width: 32px;
height: 32px;
border-radius: var(--radius-full);
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(4px);
display: grid;
place-items: center;
color: var(--text-inverse);
font-size: var(--font-size-sm);
transition: var(--transition-all);
}
.xx-asset-card:hover .xx-asset-play {
background: rgba(255, 255, 255, 0.4);
transform: scale(1.1);
}
/* 缩略图遮罩(处理中/失败等状态) */
.xx-asset-thumb-overlay {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-xs, 4px);
font-size: var(--font-size-xs);
font-weight: 500;
pointer-events: none;
}
.xx-asset-thumb-processing {
background: rgba(0, 0, 0, 0.4);
color: var(--text-inverse, #fff);
backdrop-filter: blur(2px);
}
.xx-asset-thumb-processing :first-child {
font-size: var(--font-size-2xl);
animation: spin 1s linear infinite;
}
.xx-asset-thumb-failed {
background: rgba(239, 68, 68, 0.25);
color: #fecaca;
}
.xx-asset-thumb-failed :first-child {
font-size: var(--font-size-2xl);
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* 删除按钮 */
.xx-asset-delete {
position: absolute;
bottom: var(--space-sm, 8px);
right: var(--space-sm, 8px);
width: 24px;
height: 24px;
border-radius: var(--radius-full, 999px);
background: rgba(0, 0, 0, 0.45);
backdrop-filter: blur(4px);
display: grid;
place-items: center;
color: #fff;
font-size: 13px;
cursor: pointer;
opacity: 0;
transition: var(--transition-all, all 0.2s ease);
z-index: 2;
}
.xx-asset-card:hover .xx-asset-delete {
opacity: 1;
}
.xx-asset-delete:hover {
background: rgba(255, 77, 79, 0.85);
transform: scale(1.1);
}
/* 选中态 */
.xx-asset-card-selected {
border-color: var(--primary-color) !important;
box-shadow: var(--shadow-primary) !important;
}
.xx-asset-check {
position: absolute;
top: var(--space-sm);
right: var(--space-sm);
width: 24px;
height: 24px;
border-radius: var(--radius-full);
background: var(--gradient-primary);
color: var(--text-inverse);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-sm);
z-index: 2;
}
/* 卡片信息 */
.xx-asset-info {
padding: 8px;
}
.xx-asset-name {
margin: 0 0 4px;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.xx-asset-meta {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--space-xs);
font-size: var(--font-size-xs);
color: var(--text-secondary);
margin-bottom: 4px;
min-width: 0;
}
/* 状态标签行:标签过长省略 */
.xx-asset-meta-status {
display: inline-flex;
align-items: center;
min-width: 0;
}
.xx-asset-meta-status .xx-status-pill {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.xx-asset-meta-duration {
flex-shrink: 0;
color: var(--text-tertiary);
font-variant-numeric: tabular-nums;
}
/* 余量标签独占一行 */
.xx-asset-meta-usage {
justify-content: flex-start;
margin-bottom: var(--space-xs);
}
/* 视频素材余量角标(仅状态展示,不影响卡片操作) */
.xx-asset-usage-badge {
display: inline-flex;
align-items: center;
padding: 1px 6px;
border-radius: var(--radius-full);
font-size: 10px;
font-weight: var(--font-weight-medium);
line-height: 1.5;
white-space: nowrap;
}
/* 已用尽:红色实心 */
.xx-asset-usage-badge-exhausted {
background: var(--error-color);
color: var(--text-inverse);
}
/* 即将用尽:红色软底 */
.xx-asset-usage-badge-warning {
background: var(--error-soft);
color: var(--error-color);
}
/* 已用 xx%:橙色软底 */
.xx-asset-usage-badge-ratio {
background: var(--warning-soft);
color: var(--warning-color);
}
/* 诊断按钮 */
.xx-asset-diagnose-btn {
width: 100%;
padding: 6px;
font-size: var(--font-size-sm);
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: var(--radius-xs);
color: var(--text-secondary);
cursor: pointer;
transition: var(--transition-all);
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-xs);
}
.xx-asset-diagnose-btn:hover {
border-color: var(--primary-color);
color: var(--primary-color);
background: var(--primary-soft);
}
.xx-asset-diagnose-btn:active {
background: var(--primary-color);
color: var(--text-inverse);
transform: scale(0.97);
}
.xx-asset-diagnose-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
/* ============================================================
状态标签(StatusPill)
============================================================ */
.xx-status-pill {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 1px 6px;
border-radius: var(--radius-full);
font-size: 10px;
font-weight: var(--font-weight-medium);
line-height: 1.5;
white-space: nowrap;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.xx-status-pill-ok {
background: var(--success-soft);
color: var(--success-color);
}
.xx-status-pill-warn {
background: var(--warning-soft);
color: var(--warning-color);
}
.xx-status-pill-bad {
background: var(--error-soft);
color: var(--error-color);
}
.xx-status-pill-info {
background: var(--info-soft);
color: var(--info-color);
}
/* ============================================================
骨架屏(素材列表加载占位)
============================================================ */
@keyframes xx-skeleton-pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
.xx-asset-skeleton {
pointer-events: none;
}
.xx-asset-skeleton .xx-asset-thumb {
background: var(--bg-tertiary);
}
.xx-skeleton-pulse {
animation: xx-skeleton-pulse 1.5s ease-in-out infinite;
}
.xx-skeleton-line {
height: 14px;
border-radius: var(--radius-xs);
background: var(--bg-tertiary);
}
/* 诊断按钮 loading 态 */
.xx-asset-diagnose-btn-loading {
opacity: 0.7;
cursor: not-allowed;
}
/* ============================================================
空状态
============================================================ */
.xx-assets-empty {
text-align: center;
padding: var(--space-3xl) var(--space-xl);
color: var(--text-secondary);
}
.xx-assets-empty-icon {
font-size: var(--font-size-3xl);
margin-bottom: var(--space-md);
opacity: 0.5;
}
/* ============================================================
批量操作栏
============================================================ */
.xx-assets-batch-bar {
display: flex;
align-items: center;
gap: var(--space-md);
padding: var(--space-md) var(--space-lg);
background: var(--primary-soft);
border: 1px solid var(--primary-color);
border-radius: var(--radius-md);
}
.xx-assets-batch-count {
font-size: var(--font-size-sm);
color: var(--primary-color);
font-weight: var(--font-weight-semibold);
}
/* ============================================================
内联样式迁移类
============================================================ */
.xx-asset-library-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.xx-asset-library-header h4 {
flex: 1;
margin: 0;
}
.xx-asset-form-body {
display: flex;
flex-direction: column;
gap: var(--space-md);
padding: var(--space-sm) 0;
}
.xx-asset-form-label {
margin-bottom: 6px;
font-size: var(--font-size-sm);
color: var(--text-secondary);
}
.xx-asset-video-player {
width: 100%;
max-height: 400px;
background: #000;
}
.xx-asset-empty-fallback {
text-align: center;
padding: var(--space-2xl) 0;
}
.xx-asset-empty-fallback-id {
font-size: var(--font-size-xs);
color: var(--text-tertiary);
}
/* ============================================================
骨架屏网格(加载态)
============================================================ */
.xx-assets-skeleton-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 14px;
}
.xx-assets-skeleton-card .xx-asset-thumb {
background: var(--bg-tertiary);
}
/* ============================================================
响应式
============================================================ */
@media (max-width: 1400px) {
.xx-asset-grid {
grid-template-columns: repeat(3, 1fr);
}
.xx-assets-skeleton-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 1200px) {
.xx-assets-layout {
grid-template-columns: 1fr;
}
.xx-asset-library-list {
flex-direction: row;
overflow-x: auto;
position: static;
gap: var(--space-sm);
padding-bottom: var(--space-sm);
}
.xx-asset-library-item {
min-width: 180px;
flex-shrink: 0;
}
.xx-asset-grid {
grid-template-columns: repeat(3, 1fr);
}
.xx-assets-skeleton-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.xx-assets-page {
padding: var(--space-md);
}
.xx-asset-grid {
grid-template-columns: repeat(2, 1fr);
}
.xx-assets-skeleton-grid {
grid-template-columns: repeat(2, 1fr);
}
.xx-assets-filters {
flex-direction: column;
align-items: stretch;
}
.xx-assets-filters-left,
.xx-assets-filters-right {
justify-content: flex-start;
}
}
@media (max-width: 480px) {
.xx-assets-page {
padding: var(--space-sm);
}
.xx-asset-grid {
grid-template-columns: 1fr;
}
.xx-assets-skeleton-grid {
grid-template-columns: 1fr;
}
}
/* ─── 上传队列面板 ─── */
.xx-upload-queue {
margin-top: 12px;
border: 1px solid var(--border-primary, #e5e7eb);
border-radius: 12px;
background: #fff;
overflow: hidden;
}
.xx-upload-queue-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 14px;
border-bottom: 1px solid var(--border-primary, #eef2f7);
background: #f8fafc;
}
.xx-upload-queue-title {
font-size: 13px;
font-weight: 600;
color: var(--text-primary, #1e293b);
}
.xx-upload-queue-list {
max-height: 240px;
overflow-y: auto;
}
.xx-upload-queue-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 10px 14px;
}
.xx-upload-queue-item + .xx-upload-queue-item {
border-top: 1px solid var(--border-primary, #f1f5f9);
}
.xx-upload-queue-icon {
padding-top: 2px;
font-size: 15px;
}
.xx-upload-queue-body {
flex: 1;
min-width: 0;
}
.xx-upload-queue-name {
font-size: 13px;
color: var(--text-primary, #1e293b);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.xx-upload-queue-progress {
margin-top: 6px;
height: 4px;
border-radius: 2px;
background: var(--border-primary, #e5e7eb);
overflow: hidden;
}
.xx-upload-queue-progress-bar {
height: 100%;
border-radius: 2px;
background: var(--primary-color, #6366f1);
transition: width 0.25s ease;
}
.xx-upload-queue-status {
margin-top: 4px;
font-size: 12px;
color: var(--text-tertiary, #94a3b8);
}
.xx-upload-queue-error .xx-upload-queue-status {
color: #ef4444;
}
.xx-upload-queue-error-detail {
margin-top: 4px;
font-size: 12px;
line-height: 1.5;
color: #ef4444;
word-break: break-word;
white-space: normal;
}
.xx-upload-queue-error-hint {
margin-top: 2px;
color: #b45309;
}
.xx-upload-queue-actions {
display: flex;
gap: 6px;
}
.xx-upload-queue-btn {
border: none;
background: none;
cursor: pointer;
font-size: 13px;
color: var(--text-tertiary, #94a3b8);
padding: 2px 4px;
}
.xx-upload-queue-btn:hover {
color: var(--primary-color, #6366f1);
}
/* ─── 素材卡片上传中遮罩进度条 ─── */
.xx-asset-thumb-uploading {
flex-direction: column;
gap: 8px;
}
.xx-asset-upload-bar {
width: 70%;
height: 4px;
border-radius: 2px;
background: rgba(255, 255, 255, 0.35);
overflow: hidden;
}
.xx-asset-upload-bar-inner {
height: 100%;
border-radius: 2px;
background: #fff;
transition: width 0.25s ease;
}
/* ─── 批量打标签弹窗 ─── */
.xx-batch-tag-modal {
display: flex;
flex-direction: column;
gap: 16px;
}
.xx-batch-tag-mode {
display: flex;
align-items: center;
gap: 8px;
}
.xx-batch-tag-mode-label {
font-size: 14px;
color: var(--text-primary, #111827);
font-weight: 500;
}
.xx-batch-tag-input-row {
display: flex;
gap: 8px;
}
.xx-batch-tag-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.xx-batch-tag-warning {
padding: 10px 12px;
background: #fff7ed;
border: 1px solid #fed7aa;
border-radius: var(--radius-md, 8px);
color: #c2410c;
font-size: 13px;
display: flex;
align-items: center;
gap: 6px;
}
/* ─── 批量改分类弹窗 ─── */
.xx-batch-classify-modal {
display: flex;
flex-direction: column;
gap: 12px;
}
.xx-batch-classify-hint {
font-size: 14px;
color: var(--text-secondary, #6b7280);
margin: 0;
}
/* ─── 批量智能标记弹窗 ─── */
.xx-batch-mark-modal {
display: flex;
flex-direction: column;
gap: 12px;
}
.xx-batch-mark-hint {
font-size: 14px;
color: var(--text-secondary, #6b7280);
margin: 0;
}
.xx-batch-mark-options {
display: flex;
flex-direction: column;
gap: 12px;
}
.xx-batch-mark-option {
display: flex;
flex-direction: column;
}
.xx-batch-mark-desc {
margin-left: 8px;
font-size: 13px;
color: var(--text-secondary, #6b7280);
}
/* ─── 操作结果 Drawer ─── */
.xx-batch-result {
display: flex;
flex-direction: column;
gap: 20px;
}
.xx-batch-result-summary {
display: flex;
gap: 16px;
padding: 16px;
background: var(--bg-secondary, #f9fafb);
border-radius: var(--radius-md, 8px);
}
.xx-batch-result-stat {
display: flex;
align-items: center;
gap: 6px;
font-size: 14px;
color: var(--text-primary, #111827);
}
.xx-batch-result-stat.success {
color: #059669;
}
.xx-batch-result-stat.fail {
color: #dc2626;
}
.xx-batch-result-total {
font-weight: 600;
}
.xx-batch-result-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.xx-batch-result-section-title {
font-size: 14px;
font-weight: 600;
display: flex;
align-items: center;
gap: 6px;
margin: 0;
}
.xx-batch-result-section-title.success {
color: #059669;
}
.xx-batch-result-section-title.fail {
color: #dc2626;
}
.xx-batch-result-ids {
display: flex;
flex-direction: column;
gap: 4px;
max-height: 300px;
overflow-y: auto;
}
.xx-batch-result-id {
padding: 6px 10px;
background: var(--bg-surface, #fff);
border: 1px solid var(--border-primary, #e5e7eb);
border-radius: var(--radius-sm, 4px);
font-size: 12px;
font-family: monospace;
color: var(--text-secondary, #6b7280);
word-break: break-all;
}
.xx-batch-result-id.fail {
border-color: #fecaca;
background: #fef2f2;
color: #dc2626;
}
/* 上传入口禁用态(直传进行中,防重复提交,Issue #1714) */
.xx-asset-upload-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.xx-asset-upload-btn:disabled:hover {
opacity: 0.6;
}
.xx-asset-upload-btn:disabled:active {
transform: none;
}
/* 处理超时遮罩:创建超过 10 分钟仍在处理中(疑似后端卡住),停止转圈并警示 */
.xx-asset-thumb-stalled {
background: rgba(217, 119, 6, 0.28);
color: #fde68a;
backdrop-filter: blur(2px);
}
.xx-asset-thumb-stalled :first-child {
font-size: var(--font-size-2xl);
}