refactor(workshop): 爆点改名『创新 / 爆点』并移至一句话创意之后 v19

- REQ_FIELDS:blow 标签 爆点→创新 / 爆点,字段序 idea→blow→pain→relate→form→note
- clarify 服务端模板同步;空态/注释同步字段序
This commit is contained in:
maogeigei committed 2026-09-02 18:51:02 +08:00
1 parent 8e476d20f6
commit 6602b8d45e
2 files changed
+5 -4

No files matched your search

@@ -173,8 +173,9 @@ function bindBatchBar(container, opts) {
// 09-02 v11:dur 时长目标 移出需求栏 → 需求栏下方「功能选项」下拉(30/60/120/240/自定义),值由 w.dur 单独承载 // 09-02 v11:dur 时长目标 移出需求栏 → 需求栏下方「功能选项」下拉(30/60/120/240/自定义),值由 w.dur 单独承载
// 09-02 v17:选题落点要素(痛点/爽点、共鸣/共情、爆点)加入需求框——创作流程需要但不是必填,空值由 AI 按账号设定与选题自决 // 09-02 v17:选题落点要素(痛点/爽点、共鸣/共情、爆点)加入需求框——创作流程需要但不是必填,空值由 AI 按账号设定与选题自决
// 09-02 v18:叙事形态→叙事结构;删核心情节/结尾落点(情节与结尾由 AI 创作阶段自决,无需用户填写) // 09-02 v18:叙事形态→叙事结构;删核心情节/结尾落点(情节与结尾由 AI 创作阶段自决,无需用户填写)
// 09-02 v19:爆点→创新/爆点,字段序调整至「一句话创意」之后
const REQ_FIELDS = [ const REQ_FIELDS = [
['idea', '一句话创意'], ['pain', '痛点/爽点'], ['relate', '共鸣/共情'], ['blow', '爆点'], ['idea', '一句话创意'], ['blow', '创新 / 爆点'], ['pain', '痛点/爽点'], ['relate', '共鸣/共情'],
['form', '叙事结构'], ['note', '其他约束'], ['form', '叙事结构'], ['note', '其他约束'],
]; ];
// 需求 md 行 → 向导字段映射(parseReqSheet 用) // 需求 md 行 → 向导字段映射(parseReqSheet 用)
@@ -215,7 +216,7 @@ function buildCreatePrompt(accountName, w, personaBlock, hasPersona, attachText)
} }
/* AI创作 弹窗(09-02 v2:需求框 + 输入框 对话式打磨)—— /* AI创作 弹窗(09-02 v2:需求框 + 输入框 对话式打磨)——
顶部=创作需求(6 行选题字段:创意+落点要素(痛点爽点/共鸣/爆点,可空)+叙事结构/其他约束,随对话逐轮被 AI 更新,空值标「待完善」)+ 下方时长选项条 顶部=创作需求(6 行选题字段:创意+创新爆点+落点要素(痛点爽点/共鸣,可空)+叙事结构/其他约束,随对话逐轮被 AI 更新,空值标「待完善」)+ 下方时长选项条
中部=对话流(用户输入 vs AI 整理/追问),底部=输入框 + 提交创作 */ 中部=对话流(用户输入 vs AI 整理/追问),底部=输入框 + 提交创作 */
async function confirmAiScript(accountName, btn) { async function confirmAiScript(accountName, btn) {
const accId = btn && btn.dataset.accId ? btn.dataset.accId : ''; const accId = btn && btn.dataset.accId ? btn.dataset.accId : '';
@@ -325,7 +326,7 @@ async function confirmAiScript(accountName, btn) {
? convo.map((c) => (c.role === 'u' ? convo.map((c) => (c.role === 'u'
? `<div class="req-msg mine"><div class="req-bubble">${esc(c.text)}</div></div>` ? `<div class="req-msg mine"><div class="req-bubble">${esc(c.text)}</div></div>`
: `<div class="req-msg ai"><div class="req-bubble">${esc(c.text)}</div></div>`)).join('') : `<div class="req-msg ai"><div class="req-bubble">${esc(c.text)}</div></div>`)).join('')
: `<div class="req-dialog-empty">在这里输入一个初步想法,AI 会引导你补齐创意 / 痛点爽点 / 共鸣 / 爆点 / 叙事结构等需求(落点要素可留空,由 AI 按账号设定与选题补齐,情节与结尾由 AI 创作);每条输入都会即时更新上方的创作需求框。支持上传附件。Enter 发送,Shift+Enter 换行。</div>`; : `<div class="req-dialog-empty">在这里输入一个初步想法,AI 会引导你补齐创意 / 创新·爆点 / 痛点爽点 / 共鸣 / 叙事结构等需求(落点要素可留空,由 AI 按账号设定与选题补齐,情节与结尾由 AI 创作);每条输入都会即时更新上方的创作需求框。支持上传附件。Enter 发送,Shift+Enter 换行。</div>`;
el.scrollTop = el.scrollHeight; el.scrollTop = el.scrollHeight;
}; };
const setBusy = (b) => { const setBusy = (b) => {
@@ -705,7 +705,7 @@ const server = http.createServer((req, res) => {
+ '4. 输出必须严格分两段:第一段是对用户说的话(120 字以内,含必要时的问题);\n' + '4. 输出必须严格分两段:第一段是对用户说的话(120 字以内,含必要时的问题);\n'
+ '然后另起一行单独输出 ==REQ==;\n' + '然后另起一行单独输出 ==REQ==;\n'
+ '接着输出 6 行需求清单(仍未确定的项留空值,严禁编造;情节/结尾/时长不由本清单承载,由创作阶段按人设与选题自决),模板:\n' + '接着输出 6 行需求清单(仍未确定的项留空值,严禁编造;情节/结尾/时长不由本清单承载,由创作阶段按人设与选题自决),模板:\n'
+ '- 一句话创意:\n- 痛点/爽点:\n- 共鸣/共情:\n- 爆点:\n- 叙事结构:\n- 其他约束:\n' + '- 一句话创意:\n- 创新 / 爆点:\n- 痛点/爽点:\n- 共鸣/共情:\n- 叙事结构:\n- 其他约束:\n'
+ '5. 需求框只收集本条视频的选题相关信息;账号级设定(情绪基调 / 目标受众 / 结构性符号 / 广告植入等)已由账号设定自动带入创作,不要向达人重复询问这些维度——仅当达人主动提出与账号设定不同的要求时,将其记入「其他约束」。'; + '5. 需求框只收集本条视频的选题相关信息;账号级设定(情绪基调 / 目标受众 / 结构性符号 / 广告植入等)已由账号设定自动带入创作,不要向达人重复询问这些维度——仅当达人主动提出与账号设定不同的要求时,将其记入「其他约束」。';
// 4) Dify blocking 调用 // 4) Dify blocking 调用
const difyUrl = String(process.env.DIFY_URL || 'https://mydify.youmanvideo.com/v1').replace(/\/+$/, ''); const difyUrl = String(process.env.DIFY_URL || 'https://mydify.youmanvideo.com/v1').replace(/\/+$/, '');