feat: 剧本评分左侧面板滚动优化、电商克隆移动端适配、视觉细节精修
【剧本评分左侧面板滚动重构】 - 新增 script-eval-v5-left-main 滚动容器,上传区/AI信息/历史记录统一在容器内滚动 - 底部操作按钮(开始评测/导出报告)独立于滚动区外,始终可见可点击 - 历史评测列表增加 max-height 限制,超出区域内置滚动条 - 自定义窄滚动条(品牌绿半透明 thumb),保持视觉干净 - 短视口(≤760px/820px)压缩上传区和历史列表最小高度 【剧本评分视觉精修】 - 左侧面板增加渐变背景层次与分区微光分割线 - 上传区增加 ::after 伪元素径向光晕,hover 时品牌绿边框增强 - 已上传状态上传区增加绿色边框高亮(is-ready/is-complete) - 底部操作栏背景层次加深,导出按钮 hover 增加绿色反馈 - 右侧面板增加底部径向渐变,上传引导卡标题提亮 - 顶部状态栏背景加深,模糊效果增强 【电商克隆移动端适配增强】 - 900px/620px/480px 三级断点增加顶部预留空间,避免与导航重叠 - Logo 区域定位从 sticky 改为 static,避免滚动时遮挡内容 - 设置面板在窄屏下调整内边距与边距 【Token 用量页精简】 - 移除指标卡片序号角标,保持卡片视觉简洁
This commit is contained in:
@@ -362,109 +362,111 @@ function ScriptTokensPage() {
|
||||
<div className="script-eval-v5-page">
|
||||
{/* Left Panel */}
|
||||
<aside className="script-eval-v5-left">
|
||||
<div className="script-eval-v5-lp-section">
|
||||
<div className="script-eval-v5-lp-label">上传剧本</div>
|
||||
<div
|
||||
className="script-eval-v5-upload-zone"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
onKeyDown={uploadKeyDown}
|
||||
>
|
||||
{uploadedFile ? (
|
||||
<div className="script-eval-v5-upload-done is-show">
|
||||
<CheckCircleFilled />
|
||||
<span className="script-eval-v5-uf-meta">
|
||||
<span className="script-eval-v5-uf-name">{uploadedFile.name}</span>
|
||||
<span className="script-eval-v5-uf-size">{formatFileSize(uploadedFile.size)}</span>
|
||||
</span>
|
||||
<span className="script-eval-v5-uf-re" onClick={(e) => { e.stopPropagation(); handleReset(); }}>
|
||||
重新上传
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="script-eval-v5-upload-icon"><UploadOutlined /></div>
|
||||
<div className="script-eval-v5-upload-text">拖拽或点击上传</div>
|
||||
<button type="button" className="script-eval-v5-upload-btn" onClick={(e) => { e.stopPropagation(); fileInputRef.current?.click(); }}>
|
||||
<UploadOutlined /> 选择剧本
|
||||
</button>
|
||||
<div className="script-eval-v5-upload-hint">{TEXT_FILE_HINT}</div>
|
||||
</>
|
||||
)}
|
||||
<div className="script-eval-v5-left-main">
|
||||
<div className="script-eval-v5-lp-section">
|
||||
<div className="script-eval-v5-lp-label">上传剧本</div>
|
||||
<div
|
||||
className="script-eval-v5-upload-zone"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
onKeyDown={uploadKeyDown}
|
||||
>
|
||||
{uploadedFile ? (
|
||||
<div className="script-eval-v5-upload-done is-show">
|
||||
<CheckCircleFilled />
|
||||
<span className="script-eval-v5-uf-meta">
|
||||
<span className="script-eval-v5-uf-name">{uploadedFile.name}</span>
|
||||
<span className="script-eval-v5-uf-size">{formatFileSize(uploadedFile.size)}</span>
|
||||
</span>
|
||||
<span className="script-eval-v5-uf-re" onClick={(e) => { e.stopPropagation(); handleReset(); }}>
|
||||
重新上传
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="script-eval-v5-upload-icon"><UploadOutlined /></div>
|
||||
<div className="script-eval-v5-upload-text">拖拽或点击上传</div>
|
||||
<button type="button" className="script-eval-v5-upload-btn" onClick={(e) => { e.stopPropagation(); fileInputRef.current?.click(); }}>
|
||||
<UploadOutlined /> 选择剧本
|
||||
</button>
|
||||
<div className="script-eval-v5-upload-hint">{TEXT_FILE_HINT}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<input ref={fileInputRef} type="file" accept={TEXT_FILE_ACCEPT} style={{ display: "none" }} onChange={handleFileUpload} />
|
||||
</div>
|
||||
<input ref={fileInputRef} type="file" accept={TEXT_FILE_ACCEPT} style={{ display: "none" }} onChange={handleFileUpload} />
|
||||
</div>
|
||||
|
||||
<div className="script-eval-v5-lp-section">
|
||||
<div className="script-eval-v5-lp-label">AI 识别信息</div>
|
||||
<div className="script-eval-v5-info-grid">
|
||||
{!result ? (
|
||||
<div className="script-eval-v5-info-empty">上传剧本并点击评测后识别</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">综合评分</span>
|
||||
<span className="script-eval-v5-info-val"><span className="script-eval-v5-info-tag">{result.totalScore}分 · {grade}级</span></span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">文本长度</span>
|
||||
<span className="script-eval-v5-info-val">{script.length} 字</span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">评测时间</span>
|
||||
<span className="script-eval-v5-info-val">{new Date().toLocaleDateString("zh-CN")}</span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">击败比例</span>
|
||||
<span className="script-eval-v5-info-val">{beatPct}%</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="script-eval-v5-lp-section">
|
||||
<div className="script-eval-v5-lp-label">AI 识别信息</div>
|
||||
<div className="script-eval-v5-info-grid">
|
||||
{!result ? (
|
||||
<div className="script-eval-v5-info-empty">上传剧本并点击评测后识别</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">综合评分</span>
|
||||
<span className="script-eval-v5-info-val"><span className="script-eval-v5-info-tag">{result.totalScore}分 · {grade}级</span></span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">文本长度</span>
|
||||
<span className="script-eval-v5-info-val">{script.length} 字</span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">评测时间</span>
|
||||
<span className="script-eval-v5-info-val">{new Date().toLocaleDateString("zh-CN")}</span>
|
||||
</div>
|
||||
<div className="script-eval-v5-info-item">
|
||||
<span className="script-eval-v5-info-key">击败比例</span>
|
||||
<span className="script-eval-v5-info-val">{beatPct}%</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="script-eval-v5-lp-section is-fill">
|
||||
<div className="script-eval-v5-lp-label">历史评测</div>
|
||||
<div className="script-eval-v5-history-list">
|
||||
{!session ? (
|
||||
<div className="script-eval-v5-history-empty">登录后查看云端评测记录</div>
|
||||
) : history.length === 0 ? (
|
||||
<div className="script-eval-v5-history-empty">暂无评测记录</div>
|
||||
) : (
|
||||
history.map((item, i) => (
|
||||
<div key={i} className={`script-eval-v5-history-item${i === 0 ? " is-active" : ""}`}>
|
||||
<div className="script-eval-v5-hi-left">
|
||||
<div className="script-eval-v5-hi-name">{item.name}</div>
|
||||
<div className="script-eval-v5-hi-date">{item.date}</div>
|
||||
<div className="script-eval-v5-hi-bar">
|
||||
<div className="script-eval-v5-hi-bar-fill" style={{ width: `${Math.min(92, (item.score / 100) * 100)}%` }} />
|
||||
<div className="script-eval-v5-lp-section is-fill">
|
||||
<div className="script-eval-v5-lp-label">历史评测</div>
|
||||
<div className="script-eval-v5-history-list">
|
||||
{!session ? (
|
||||
<div className="script-eval-v5-history-empty">登录后查看云端评测记录</div>
|
||||
) : history.length === 0 ? (
|
||||
<div className="script-eval-v5-history-empty">暂无评测记录</div>
|
||||
) : (
|
||||
history.map((item, i) => (
|
||||
<div key={i} className={`script-eval-v5-history-item${i === 0 ? " is-active" : ""}`}>
|
||||
<div className="script-eval-v5-hi-left">
|
||||
<div className="script-eval-v5-hi-name">{item.name}</div>
|
||||
<div className="script-eval-v5-hi-date">{item.date}</div>
|
||||
<div className="script-eval-v5-hi-bar">
|
||||
<div className="script-eval-v5-hi-bar-fill" style={{ width: `${Math.min(92, (item.score / 100) * 100)}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="script-eval-v5-hi-right">
|
||||
<div className={`script-eval-v5-hi-score${item.score >= 90 ? " is-green" : ""}`}>{item.score}</div>
|
||||
<div className="script-eval-v5-hi-grade">{item.grade}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="script-eval-v5-hi-right">
|
||||
<div className={`script-eval-v5-hi-score${item.score >= 90 ? " is-green" : ""}`}>{item.score}</div>
|
||||
<div className="script-eval-v5-hi-grade">{item.grade}</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="script-eval-v5-lp-bottom">
|
||||
<button
|
||||
type="button"
|
||||
className="script-eval-v5-eval-btn"
|
||||
disabled={loading || !hasContent}
|
||||
onClick={() => void handleEvaluate()}
|
||||
>
|
||||
{loading ? <LoadingOutlined /> : <ThunderboltOutlined />}
|
||||
<span>{loading ? "评测中..." : "开始评测"}</span>
|
||||
</button>
|
||||
<button type="button" className="script-eval-v5-export-btn" disabled={!result} onClick={handleExportMarkdown}>
|
||||
<DownloadOutlined />
|
||||
<span>导出评测报告</span>
|
||||
</button>
|
||||
<div className="script-eval-v5-lp-bottom">
|
||||
<button
|
||||
type="button"
|
||||
className="script-eval-v5-eval-btn"
|
||||
disabled={loading || !hasContent}
|
||||
onClick={() => void handleEvaluate()}
|
||||
>
|
||||
{loading ? <LoadingOutlined /> : <ThunderboltOutlined />}
|
||||
<span>{loading ? "评测中..." : "开始评测"}</span>
|
||||
</button>
|
||||
<button type="button" className="script-eval-v5-export-btn" disabled={!result} onClick={handleExportMarkdown}>
|
||||
<DownloadOutlined />
|
||||
<span>导出评测报告</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user