09-10 工作台:配置收敛、复盘字段契约修复、原创选题分镜支持、榜单期号区间显示
配置收敛:
- 端口/DB名/产出根/榜单目录单源化到 mcn-work-shop/config.json,代码层统一经 load-config.js 读取
- 新增 get-port.js 供 start.bat 读端口(bat 内嵌 node -e 会被 cmd 截断,读到的是兜底值)
- start.bat 修复失效的 managed node 路径(原写死 22.22.2 已不存在),改为遍历 versions 自动探测
复盘诊断页(真 bug 修复):
- 问题清单严重度全部显示成绿色 + 修改建议不显示:模型输出 {sev:'high',fix} 与前端读取 {severity:'高',suggestion} 字段名与取值均不匹配
- 前端新增 normIssue 归一化,兼容 sev/severity/level 与中英取值,并回补所属维度显示
- 在 submit-review-tasks 与诊断/复盘 prompt 中固化 issues_json 字段契约,从源头防 schema 漂移
分镜提示词:
- 原创选题(video_id 为空)原本无生成入口(分镜按 video_id 查询)
- listStoryboards 支持按 rewrite_id 查询,前端放开入口、切版本重查,并补落库指令(此前入库靠模型自由发挥)
榜单展示:
- 期号改为显示区间「08/31 ~ 09/06」,避免被误读为单日(期号=该周周一)
- 后端新增 collectRanges,从落盘文件读真实 dateStart/dateEnd 随 API 返回(日榜 start=end 不显区间)
其他:
- 清理 dsh 环境废弃后的历史叙述类废话(16 文件约 18 处),文末变更记录区保留
- 新增 docs/工作台UI规范.md(设计 token / 布局 / 8 页面路由 / 12 类组件 / 9 条已知坑)
This commit is contained in:
1 parent
6cb29a9877
commit
c48902f063
58 files changed
+895
-263
No files matched your search
@@ -1,7 +1,8 @@
|
||||
// 短视频工作台 - 数据访问层(只读复用业务数据目录)
|
||||
// 数据源:工作台目录 mcn-plugin.db(dsh 库副本,node:sqlite 只读)+ 三方数据目录 抖音榜单/*.json
|
||||
// 与 dsh 原库(~/.dsh/mcn-plugin.db)隔离:两边各访问各的,互不影响
|
||||
// 页面逻辑参照 dsh-plugin-mcn 重新开发,仅复用数据库 schema 与榜单文件格式
|
||||
// 数据源:工作台目录 mcn-plugin.db(node:sqlite 只读)+ 三方数据目录 抖音榜单/*.json
|
||||
// 09-10:dsh 侧已整套下线(~/.dsh/skills/、~/.dsh/mcn-plugin.db、D:\dshworkspace 均不存在),
|
||||
// 工作台 DB 为唯一读写副本,不再有「与 dsh 原库隔离」的双库关系
|
||||
// 页面逻辑参照 dsh-plugin-mcn 重新开发(历史沿革),仅复用数据库 schema 与榜单文件格式
|
||||
'use strict';
|
||||
|
||||
const { DatabaseSync } = require('node:sqlite');
|
||||
@@ -9,18 +10,19 @@ const path = require('node:path');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
|
||||
// 工作台自有数据库副本(与 dsh 原库隔离)
|
||||
const DSH_DB = path.join(__dirname, 'mcn-plugin.db');
|
||||
// 读取工作台 config.json(load-config.js 唯一入口 + 默认值唯一来源,配置收敛)
|
||||
const { loadConfig } = require('./load-config');
|
||||
const CFG = loadConfig();
|
||||
|
||||
// 榜单目录解析(09-03 定稿:跟随 mcn-data-insight 榜单落盘规范的数据源分层)
|
||||
// 优先级:① 环境变量 MCN_RANKING_DIR 显式覆盖 → ② dsh 部署(技能在 ~/.dsh 下)→ D:\dshworkspace\抖音榜单
|
||||
// → ③ 开发机/用户环境(①③):桌面 MCNSkill项目\三方数据\红狐数据\抖音榜单(运行时解析真实桌面,兼容 OneDrive 重定向)
|
||||
// 工作台自有数据库副本(唯一读写副本)
|
||||
const DSH_DB = path.join(__dirname, CFG.dbName);
|
||||
|
||||
// 榜单目录解析(09-03 定稿)
|
||||
// 优先级:① 环境变量 MCN_RANKING_DIR 显式覆盖 → ② 桌面/<CFG.businessDataDir>(config.json,运行时解析真实桌面,兼容 OneDrive 重定向)
|
||||
function resolveRankingDir() {
|
||||
if (process.env.MCN_RANKING_DIR) return process.env.MCN_RANKING_DIR;
|
||||
const isDshDeploy = __dirname.includes('.dsh');
|
||||
if (isDshDeploy) return 'D:\\dshworkspace\\抖音榜单';
|
||||
const home = os.homedir();
|
||||
const rel = path.join('MCNSkill项目', '三方数据', '红狐数据', '抖音榜单');
|
||||
const rel = path.join(...CFG.businessDataDir);
|
||||
const candidates = [
|
||||
path.join(home, 'Desktop', rel),
|
||||
path.join(home, 'OneDrive', 'Desktop', rel),
|
||||
@@ -295,8 +297,14 @@ function listRewrites(videoId) {
|
||||
return { items: rows };
|
||||
}
|
||||
|
||||
function listStoryboards(videoId) {
|
||||
/* 09-10:原创选题(video_id 为空)原本查不到分镜 → 分镜 tab 无生成入口。
|
||||
现支持按 rewrite_id 查询,使无视频载体的脚本也能挂分镜(storyboard_log 本就有 rewrite_id 列)。 */
|
||||
function listStoryboards(videoId, rewriteId) {
|
||||
const d = getDb(); if (!d) return [];
|
||||
const rid = Number(rewriteId);
|
||||
if (Number.isFinite(rid) && rid > 0 && !(Number(videoId) > 0)) {
|
||||
return d.prepare(`SELECT id, video_id, rewrite_id, script_text, status, created_time, updated_time FROM storyboard_log WHERE rewrite_id=? ORDER BY id DESC`).all(rid);
|
||||
}
|
||||
return d.prepare(`SELECT id, video_id, rewrite_id, script_text, status, created_time, updated_time FROM storyboard_log WHERE video_id=? ORDER BY id DESC`).all(videoId);
|
||||
}
|
||||
|
||||
@@ -428,12 +436,30 @@ function collectCategories(board, files) {
|
||||
return RANK_KEEP.filter((c) => found.has(c));
|
||||
}
|
||||
|
||||
// 期次真实区间:{ date: {start, end} }(周榜=周一~周日;日榜 start=end=当日)
|
||||
// 09-10:UI 改显示「08-31 ~ 09-06」而非裸期号 2026-08-31——期号是周一,只看期号会误以为仅 8/31 单日。
|
||||
// 同一 date 可能有多个文件(week 每赛道一个),取首个即可(区间相同)。
|
||||
function collectRanges(board, files) {
|
||||
const out = {};
|
||||
const seen = new Set();
|
||||
for (const pf of files) {
|
||||
if (seen.has(pf.date)) continue;
|
||||
seen.add(pf.date);
|
||||
try {
|
||||
const d = JSON.parse(fs.readFileSync(rankFilePath(pf.dir, pf.name), 'utf8'));
|
||||
const s = String(d.dateStart || d.date || '').trim();
|
||||
if (s) out[pf.date] = { start: s, end: String(d.dateEnd || d.date || s).trim() };
|
||||
} catch (e) {}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function rankingMeta(board = 'week') {
|
||||
const empty = { dates: [], categories: [] };
|
||||
const empty = { dates: [], categories: [], ranges: {} };
|
||||
const files = listRankFiles(board);
|
||||
if (!files.length) return empty;
|
||||
const dates = [...new Set(files.map((f) => f.date))];
|
||||
return { dates, categories: collectCategories(board, files) };
|
||||
return { dates, categories: collectCategories(board, files), ranges: collectRanges(board, files) };
|
||||
}
|
||||
|
||||
// 榜单数据新鲜度(更新防重依据,09-03 新增):递归扫描 RANKING_DIR(三榜子目录 + 根目录旧平铺)全部 .json,
|
||||
@@ -472,7 +498,7 @@ function parseNum(v) {
|
||||
}
|
||||
|
||||
function getRanking({ board = 'week', date = '', category = '', sortBy = '', order = '', page = 1, pageSize = 20 } = {}) {
|
||||
const empty = { dates: [], categories: [], category: '', date: '', total: 0, items: [] };
|
||||
const empty = { dates: [], categories: [], ranges: {}, category: '', date: '', total: 0, items: [] };
|
||||
const files = listRankFiles(board);
|
||||
if (!files.length) return empty;
|
||||
const dates = [...new Set(files.map((f) => f.date))];
|
||||
@@ -524,7 +550,7 @@ function getRanking({ board = 'week', date = '', category = '', sortBy = '', ord
|
||||
}
|
||||
return { ...row, inDb: !!hit, dbId: hit ? hit.id : null };
|
||||
});
|
||||
return { dates, categories, category, date: selDate, total, page: Math.max(1, Number(page) || 1), pageSize: limit, items: pageItems };
|
||||
return { dates, categories, ranges: collectRanges(board, files), category, date: selDate, total, page: Math.max(1, Number(page) || 1), pageSize: limit, items: pageItems };
|
||||
}
|
||||
|
||||
/* ================= AI写脚本:原创选题(无视频载体)================= */
|
||||
|
||||
Reference in new issue
Block a user