diff --git a/project/短视频脚本创作/V1.0/mcn-work-shop/public/data-pages.js b/project/短视频脚本创作/V1.0/mcn-work-shop/public/data-pages.js index 6be3f70..de43211 100644 --- a/project/短视频脚本创作/V1.0/mcn-work-shop/public/data-pages.js +++ b/project/短视频脚本创作/V1.0/mcn-work-shop/public/data-pages.js @@ -170,8 +170,9 @@ function bindBatchBar(container, opts) { ============================================================ */ // 需求单字段顺序:弹窗需求框展示、AI 输出模板、创作 prompt 共用(值空 = 待 AI 按账号设定与选题自决) // 09-02 v10:需求框定位=选题补充——只留本条视频选题侧字段 + 兜底「其他」;账号设定类(情绪基调/受众/结构性符号/广告植入)由人设卡提供,不在此重复收集 +// 09-02 v11:dur 时长目标 移出需求栏 → 需求栏下方「功能选项」下拉(30/60/120/240/自定义),值由 w.dur 单独承载 const REQ_FIELDS = [ - ['idea', '一句话创意与选题'], ['form', '叙事形态'], ['dur', '时长目标'], + ['idea', '一句话创意'], ['form', '叙事形态'], ['plot', '核心情节'], ['end', '结尾落点'], ['note', '其他约束'], ]; // 需求 md 行 → 向导字段映射(parseReqSheet 用) @@ -188,13 +189,16 @@ function parseReqSheet(md) { } return out; } -// 状态 → 6 行完整需求清单(供 AI 每轮保持同模板输出;空字段留空值) +// 状态 → 需求清单 md(供 AI 每轮保持同模板输出;空字段留空值;时长由选项条承载,不走 AI 模板) function reqMdOf(w) { return REQ_FIELDS.map(([k, label]) => `- ${label}:${String(w[k] || '').trim()}`).join('\n'); } -// 状态 → 已填需求行(创作 prompt 用,非空才输出) +// 状态 → 已填需求行(创作 prompt / 确认弹窗用,非空才输出;时长=选项条独立值,追加在清单尾部) function reqLines(w) { - return REQ_FIELDS.filter(([k]) => String(w[k] || '').trim()).map(([k, label]) => `- ${label}:${String(w[k]).trim()}`); + const lines = REQ_FIELDS.filter(([k]) => String(w[k] || '').trim()).map(([k, label]) => `- ${label}:${String(w[k]).trim()}`); + const dur = String(w.dur || '').trim(); + if (dur) lines.push(`- 时长目标:${dur}`); + return lines; } // 组装创作 prompt:人设块在前(既有铁律),需求+附件素材在后;空维度不输出由 AI 自主决策 function buildCreatePrompt(accountName, w, personaBlock, hasPersona, attachText) { @@ -209,7 +213,7 @@ function buildCreatePrompt(accountName, w, personaBlock, hasPersona, attachText) } /* AI创作 弹窗(09-02 v2:需求框 + 输入框 对话式打磨)—— - 顶部=创作需求(6 行选题字段,随对话逐轮被 AI 更新,空值标「待定·由 AI 按账号设定与选题自决」) + 顶部=创作需求(5 行选题字段,随对话逐轮被 AI 更新,空值标「待定·由 AI 按账号设定与选题自决」)+ 下方时长选项条 中部=对话流(用户输入 vs AI 整理/追问),底部=输入框 + 提交创作 */ async function confirmAiScript(accountName, btn) { const accId = btn && btn.dataset.accId ? btn.dataset.accId : ''; @@ -241,6 +245,20 @@ async function confirmAiScript(accountName, btn) {
+
+ 时长目标 + + +
@@ -262,7 +280,7 @@ async function confirmAiScript(accountName, btn) { mask.querySelector('[data-x]').addEventListener('click', close); const q = (s) => mask.querySelector(s); - /* —— 需求框渲染:6 个选题字段,维度名作标题、内容在下方 —— */ + /* —— 需求框渲染:5 个选题字段,维度名作标题、内容在下方 —— */ const renderSheet = () => { const rows = REQ_FIELDS.map(([k, label]) => { const v = String(w[k] || '').trim(); @@ -283,6 +301,21 @@ async function confirmAiScript(accountName, btn) { const open = box.classList.toggle('open'); sheetToggle.setAttribute('aria-expanded', open ? 'true' : 'false'); }); + /* —— 时长选项条(09-02 v11):下拉 30/60/120/240/自定义;值写 w.dur,随 reqLines 进入确认弹窗与创作 prompt —— */ + const durSel = q('#reqDur'); + const durCustom = q('#reqDurCustom'); + const durNum = q('#reqDurNum'); + const syncDur = () => { + const sel = durSel.value; + if (sel === 'custom') { durCustom.hidden = false; durNum.focus(); w.dur = ''; return; } + durCustom.hidden = true; + w.dur = sel ? sel + '秒' : ''; + }; + durSel.addEventListener('change', syncDur); + durNum.addEventListener('input', () => { + const n = Math.round(Number(durNum.value)); + w.dur = (Number.isFinite(n) && n > 0) ? n + '秒' : ''; + }); /* —— 对话流渲染 —— */ const renderDialog = () => { const el = q('#reqDialog'); @@ -290,7 +323,7 @@ async function confirmAiScript(accountName, btn) { ? convo.map((c) => (c.role === 'u' ? `
${esc(c.text)}
` : `
${esc(c.text)}
`)).join('') - : `
在这里输入一个初步想法,AI 会引导你补齐创意 / 形态 / 时长 / 情节 / 结尾等选题需求;每条输入都会即时更新上方的创作需求框。账号级设定(情绪基调 / 受众 / 植入等)已由账号设定提供,无需重复填写。也可点回形针上传需求文档(doc / docx / txt / pdf)。Enter 发送,Shift+Enter 换行。
`; + : `
在这里输入一个初步想法,AI 会引导你补齐创意 / 形态 / 情节 / 结尾等选题需求;每条输入都会即时更新上方的创作需求框。账号级设定(情绪基调 / 受众 / 植入等)已由账号设定提供,无需重复填写。也可点回形针上传需求文档(doc / docx / txt / pdf)。Enter 发送,Shift+Enter 换行。
`; el.scrollTop = el.scrollHeight; }; const setBusy = (b) => { @@ -420,7 +453,7 @@ async function confirmAiScript(accountName, btn) { ck.innerHTML = `