R46: 脚本诊断维度改名——钩子设置→爆款开场、共鸣和共情→创意和爆点(排设定承接前);DIAG_KEY_ALIAS 旧 key 兼容保历史分数;data-pages ah→ai
This commit is contained in:
1 parent
05ea2c29c8
commit
e3bc43e48f
2 files changed
+12
-8
No files matched your search
@@ -1448,7 +1448,7 @@ async function openCustomScriptView(id) {
|
||||
/* ================= AI脚本诊断 ================= */
|
||||
async function renderReviews(view) {
|
||||
const d = await api('/api/dsh/rewrites').catch((e) => ({ ok: false, error: e.message }));
|
||||
const DIMS = ['设定承接', '框架节奏', '钩子设置', '叙事逻辑', '极致事件', '共鸣和共情', '其他', '总分'];
|
||||
const DIMS = ['创意和爆点', '设定承接', '框架节奏', '爆款开场', '叙事逻辑', '极致事件', '其他', '总分'];
|
||||
if (!d.ok) { view.innerHTML = `<div class="page"><div class="page-toolbar">${toolbarBack()}</div><div class="empty">${esc(d.error || '加载失败')}</div></div>`; bindBack(view); return; }
|
||||
const items = (d.items || []).filter((x) => x.status === 'done' && x.script_len > 0);
|
||||
// 补账号名
|
||||
@@ -1474,7 +1474,7 @@ async function renderReviews(view) {
|
||||
const sd = dimsOf(row);
|
||||
const rv = reviewOf(row);
|
||||
const dimsTd = DIMS.map((dim) => {
|
||||
const v = dim === '总分' ? sd.total : sd.dims[dim];
|
||||
const v = dim === '总分' ? sd.total : diagDimVal(sd.dims, dim);
|
||||
const clickable = dim === '总分' && rv && typeof v === 'number';
|
||||
return `<td style="text-align:center;${dim === '总分' && typeof v === 'number' ? 'color:var(--primary);font-weight:600' : 'color:var(--dim)'}">${clickable ? `<a class="link" data-review="${rv.id}">${fmtScore(v)}</a>` : fmtScore(v)}</td>`;
|
||||
}).join('');
|
||||
@@ -1547,9 +1547,9 @@ async function renderReviews(view) {
|
||||
const rv = d3.review;
|
||||
const typeName = rv.type === 'source' ? '原视频脚本复盘' : rv.type === 'compare' ? '对比分析' : 'AI 脚本复盘';
|
||||
let dimsObj = {}; try { dimsObj = JSON.parse(rv.dims_json || '{}'); } catch (e) {}
|
||||
const DIMS_ALL = ['设定承接', '框架节奏', '钩子设置', '叙事逻辑', '极致事件', '共鸣和共情', '格式规范性', '台词口语化', '内容合规', '教程完整链', '其他'];
|
||||
const DIMS_ALL = ['创意和爆点', '设定承接', '框架节奏', '爆款开场', '叙事逻辑', '极致事件', '格式规范性', '台词口语化', '内容合规', '教程完整链', '其他'];
|
||||
const scoreColor = (v) => (v >= 75 ? '#3a9e6d' : v >= 60 ? '#d99a2b' : '#d9534f');
|
||||
const scoreBar = (dims, prefix) => DIMS_ALL.map((k) => { const v = dims[k]; const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? scoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? scoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
const scoreBar = (dims, prefix) => DIMS_ALL.map((k) => { const v = diagDimVal(dims, k); const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? scoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? scoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
let body = '';
|
||||
if (rv.type === 'compare') {
|
||||
const aiD = dimsObj.ai || {}, srcD = dimsObj.source || {};
|
||||
@@ -1580,7 +1580,11 @@ async function renderReviews(view) {
|
||||
—— 分镜内容 = 该视频下 storyboard_log 中属当前版本的记录 + 生成/重新生成入口(仅参考选题脚本;自定义选题无视频载体不支持)
|
||||
数据源:/api/dsh/video-script + /api/dsh/video-detail(参考选题)/ /api/dsh/custom-script(自定义选题)
|
||||
+ /api/dsh/review-full?rewriteId=(当前版本诊断)+ /api/dsh/storyboards?videoId=(分镜) */
|
||||
const DIAG_DIMS = ['设定承接', '框架节奏', '钩子设置', '叙事逻辑', '极致事件', '共鸣和共情', '格式规范性', '台词口语化', '内容合规', '教程完整链', '其他'];
|
||||
const DIAG_DIMS = ['创意和爆点', '设定承接', '框架节奏', '爆款开场', '叙事逻辑', '极致事件', '格式规范性', '台词口语化', '内容合规', '教程完整链', '其他'];
|
||||
/* R46 维度术语改名(09-03):钩子设置→爆款开场、共鸣和共情→创意和爆点(排设定承接前)。
|
||||
维度名兼作 dims_json 数据 key——历史复盘仍为旧 key,取值回退别名兼容(新 key 缺失时读旧 key),保证历史分数继续展示 */
|
||||
const DIAG_KEY_ALIAS = { '爆款开场': '钩子设置', '创意和爆点': '共鸣和共情' };
|
||||
const diagDimVal = (dims, k) => { const v = dims[k]; return (typeof v === 'number' && Number.isFinite(v)) ? v : (DIAG_KEY_ALIAS[k] ? dims[DIAG_KEY_ALIAS[k]] : v); };
|
||||
const diagScoreColor = (v) => (v >= 75 ? '#3a9e6d' : v >= 60 ? '#d99a2b' : '#d9534f');
|
||||
const diagFmtScore = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : '-');
|
||||
|
||||
@@ -1604,7 +1608,7 @@ async function reportFullReview(reviewId) {
|
||||
const rv = d3.review;
|
||||
const typeName = rv.type === 'source' ? '原视频脚本复盘' : rv.type === 'compare' ? '对比分析' : 'AI 脚本复盘';
|
||||
let dimsObj = {}; try { dimsObj = JSON.parse(rv.dims_json || '{}'); } catch (e) {}
|
||||
const scoreBar = (dims, prefix) => DIAG_DIMS.map((k) => { const v = dims[k]; const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? diagScoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? diagScoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
const scoreBar = (dims, prefix) => DIAG_DIMS.map((k) => { const v = diagDimVal(dims, k); const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? diagScoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? diagScoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
let body = '';
|
||||
if (rv.type === 'compare') {
|
||||
const aiD = dimsObj.ai || {}, srcD = dimsObj.source || {};
|
||||
@@ -1701,7 +1705,7 @@ async function openScriptModal({ rewriteId, videoId } = {}) {
|
||||
const diagHtml = (dg) => {
|
||||
const { rv, dims, total, srcTotal } = dg;
|
||||
const totalFin = Number.isFinite(total);
|
||||
const scoreBar = DIAG_DIMS.map((k) => { const v = dims[k]; const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? diagScoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? diagScoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
const scoreBar = DIAG_DIMS.map((k) => { const v = diagDimVal(dims, k); const has = typeof v === 'number' && Number.isFinite(v); return `<div class="score-row"><span class="score-name">${esc(k)}</span><div class="score-bar"><div class="score-fill" style="width:${has ? v : 0}%;background:${has ? diagScoreColor(v) : '#eee'}"></div></div><span class="score-val" style="color:${has ? diagScoreColor(v) : 'var(--dim)'}">${has ? v : '—'}</span></div>`; }).join('');
|
||||
let html = `<div class="score-box"><div class="score-box-title">AI 总分 ${diagFmtScore(totalFin ? total : Number(rv.total))}${rv.type === 'compare' && Number.isFinite(srcTotal) ? `(对比源脚本 ${diagFmtScore(srcTotal)})` : ''}${rv.verdict ? ` · <span style="color:${totalFin ? diagScoreColor(total) : 'var(--dim)'}">${esc(rv.verdict)}</span>` : ''}</div>${scoreBar}</div>`;
|
||||
let issues = []; try { issues = JSON.parse(rv.issues_json || '[]'); } catch (e) {}
|
||||
if (issues.length) html += `<div class="review-issues"><div class="rw-pane-title">问题清单</div>${issues.map((it) => `<div class="issue-row"><span style="color:${it.severity === '高' ? '#d9534f' : it.severity === '中' ? '#d99a2b' : '#3a9e6d'};font-weight:600">${esc(it.severity || '低')}</span><span>${esc(it.issue || '')}</span>${it.suggestion ? `<span class="dim">→ ${esc(it.suggestion)}</span>` : ''}</div>`).join('')}</div>`;
|
||||
|
||||
@@ -42,6 +42,6 @@
|
||||
</div>
|
||||
|
||||
<script src="app.js?v=20260903y"></script>
|
||||
<script src="data-pages.js?v=20260903ag"></script>
|
||||
<script src="data-pages.js?v=20260903ai"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user