R55-R58: AI脚本弹窗版本条(新在右旧在左)+教程完整链维度不适用即隐藏+热点账号日榜+脚本删除按钮(级联诊断分镜, 含help-guide.js补纳入)

This commit is contained in:
maogeigei committed 2026-09-04 12:08:47 +08:00
1 parent 80b64b65b8
commit 1f59acd16b
8 files changed
+747 -107

No files matched your search

@@ -104,6 +104,32 @@ function deleteVideosDeep(w, vids) {
}
}
// 删除单条 AI 脚本(R58 弹窗「删除」):连坐该脚本的诊断复盘(script_review ai/compare)与分镜提示词(storyboard_log)。
// 若删除后其视频下已无剩余脚本 → 视频级 source 复盘与该视频游离分镜(rewrite_id 空)一并清理,避免孤儿数据。
function deleteScript(rewriteId) {
const id = Number(rewriteId);
if (!(id > 0)) throw new Error('脚本 ID 无效');
if (!fs.existsSync(DSH_DB)) throw new Error('数据库不可用');
const w = new DatabaseSync(DSH_DB);
try {
const row = w.prepare(`SELECT id, video_id, aweme_id FROM rewrite_log WHERE id=?`).get(id);
if (!row) return { deleted: 0 };
w.prepare(`DELETE FROM script_review WHERE rewrite_id=?`).run(id); /* ai/compare 诊断 */
w.prepare(`DELETE FROM storyboard_log WHERE rewrite_id=?`).run(id); /* 该脚本分镜 */
if (row.video_id) {
const remain = w.prepare(`SELECT COUNT(*) c FROM rewrite_log WHERE video_id=? AND id<>?`).get(row.video_id, id).c;
if (remain === 0) {
w.prepare(`DELETE FROM script_review WHERE type='source' AND video_id=?`).run(row.video_id);
w.prepare(`DELETE FROM storyboard_log WHERE video_id=? AND (rewrite_id IS NULL OR rewrite_id=0)`).run(row.video_id);
}
}
const r = w.prepare(`DELETE FROM rewrite_log WHERE id=?`).run(id);
return { deleted: Number(r.changes) };
} finally {
w.close();
}
}
/* ================= 账号 ================= */
function listTracks() {
@@ -341,16 +367,17 @@ function listRecentScripts(limit = 4) {
// 根目录旧平铺文件仍兼容读取(任务旧产物)。
// 全品类单文件(hot/likes)无赛道段:category 顶层标记「全部」,实际赛道在 list[].category,
// 赛道下拉 = 各期文件条目 category 并集,赛道筛选按条目 category 匹配。
const RANK_SUB = { week: '账号周榜', hot: '视频热榜', likes: '点赞榜' };
const RANK_SUB = { week: '账号周榜', day: '账号日榜', hot: '视频热榜', likes: '点赞榜' };
const RANK_FILE_RE = {
week: /^抖音周榜_(.+)_(\d{4}-\d{2}-\d{2})\.json$/,
day: /^抖音账号日榜_(\d{4}-\d{2}-\d{2})\.json$/,
hot: /^抖音周榜_视频热榜_(\d{4}-\d{2}-\d{2})\.json$/,
likes: /^抖音周榜_点赞榜_(\d{4}-\d{2}-\d{2})\.json$/,
};
// 工作台所需赛道白名单(09-03 定:与账号周榜 douyin-top-account 保留 5 赛道同口径)
// 口径差异:账号榜 type=「生活vlog」;作品榜条目 category=「生活记录」——并集同时放行。
// 生效范围:hot/likes(全品类文件)赛道下拉与列表(含「全部」)只保留白名单条目;week 文件名赛道天然在白名单内。
// 生效范围:day/hot/likes(全品类文件)赛道下拉与列表(含「全部」)只保留白名单条目;week 文件名赛道天然在白名单内。
const RANK_KEEP = ['生活记录', '生活vlog', '小剧场', '亲子', '美食', '旅行'];
const RANK_KEEP_SET = new Set(RANK_KEEP);
@@ -464,8 +491,8 @@ function getRanking({ board = 'week', date = '', category = '', sortBy = '', ord
items = items.filter((it) => String(it.category || '').trim() === category);
}
}
// 默认排序键随榜:week=综合得分 / hot=点赞 / likes=新增点赞(同分按排名升序)
const DEF_KEY = board === 'week' ? 'comprehensiveScore' : board === 'hot' ? 'likeCount' : 'add_digg_count';
// 默认排序键随榜:week/day(账号榜)=综合得分 / hot=点赞 / likes=新增点赞(同分按排名升序)
const DEF_KEY = (board === 'week' || board === 'day') ? 'comprehensiveScore' : board === 'hot' ? 'likeCount' : 'add_digg_count';
if (!order && (!sortBy || sortBy === DEF_KEY)) {
items.sort((a, b) => {
const va = num(a[DEF_KEY]), vb = num(b[DEF_KEY]);
@@ -565,7 +592,7 @@ function getRewriteStats(account = '') {
}
module.exports = {
dbAvailable, setFavorite, batchDelete, listTracks, listAccounts, listAccountVideos, getPersona, getAccountAnalysis,
dbAvailable, setFavorite, batchDelete, deleteScript, listTracks, listAccounts, listAccountVideos, getPersona, getAccountAnalysis,
listVideos, getVideoDetail, getVideoScript, listRewrites, listStoryboards, listRecentScripts,
getReviewDetail, getReviewFull, getStats, rankingMeta, getRanking, rankingFreshness, DSH_DB, RANKING_DIR,
listCustomScripts, getCustomScript, saveScript, getRewriteStats,