This commit is contained in:
2026-06-30 15:02:20 +08:00
commit 3948b5a48a
306 changed files with 77275 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
const fs = require('fs');
const path = require('path');
const repoRoot = path.join(__dirname, '..', '..');
const src = path.join(repoRoot, 'backend-node');
const dest = path.join(__dirname, '..', 'backend-app');
const dirsToCopy = ['src', 'configs', 'scripts', 'migrations'];
if (!fs.existsSync(src)) {
console.error('backend-node not found at', src);
process.exit(1);
}
if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true });
fs.mkdirSync(dest, { recursive: true });
for (const dir of dirsToCopy) {
const from = path.join(src, dir);
const to = path.join(dest, dir);
if (fs.existsSync(from)) {
fs.cpSync(from, to, { recursive: true });
}
}
// 合并 desktop 自带的初始迁移(保证 01_init、02_add_default_model 等存在)
const migrationsDest = path.join(dest, 'migrations');
const initialMigrations = path.join(__dirname, 'initial-migrations');
if (!fs.existsSync(migrationsDest)) fs.mkdirSync(migrationsDest, { recursive: true });
if (fs.existsSync(initialMigrations)) {
for (const f of fs.readdirSync(initialMigrations)) {
if (f.endsWith('.sql')) {
fs.copyFileSync(path.join(initialMigrations, f), path.join(migrationsDest, f));
}
}
console.log('Merged initial-migrations -> desktop/backend-app/migrations');
}
console.log('Copied backend-node (src, configs, scripts, migrations) -> desktop/backend-app');
+14
View File
@@ -0,0 +1,14 @@
const fs = require('fs');
const path = require('path');
const repoRoot = path.join(__dirname, '..', '..');
const src = path.join(repoRoot, 'frontweb', 'dist');
const dest = path.join(__dirname, '..', 'frontweb-dist');
if (!fs.existsSync(src)) {
console.error('frontweb/dist not found. Run: cd frontweb && npm run build');
process.exit(1);
}
if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true });
fs.cpSync(src, dest, { recursive: true });
console.log('Copied frontweb/dist -> desktop/frontweb-dist');
+43
View File
@@ -0,0 +1,43 @@
process.env.ELECTRON_MIRROR = 'https://npmmirror.com/mirrors/electron/';
process.env.ELECTRON_BUILDER_BINARIES_MIRROR = 'https://cdn.npmmirror.com/binaries/electron-builder-binaries/';
const { spawnSync } = require('child_process');
const path = require('path');
const isWin = process.platform === 'win32';
const cwd = path.join(__dirname, '..');
// 第一步:完整构建(含示例资源),前端/后端同时准备
console.log('\n========== [1/2] 构建完整版(含示例资源)==========\n');
const full = spawnSync(isWin ? 'npm.cmd' : 'npm', ['run', 'dist'], {
stdio: 'inherit',
shell: isWin,
cwd,
});
if (full.status !== 0) {
console.error('完整版构建失败,终止。');
process.exit(full.status || 1);
}
// 第二步:纯净版构建(不含示例资源),前端/后端已准备好,直接调 electron-builder
console.log('\n========== [2/2] 构建纯净版(不含示例资源)==========\n');
const lite = spawnSync(
isWin ? 'npx.cmd' : 'npx',
['electron-builder', '--win', '--config', 'electron-builder-lite.json'],
{
stdio: 'inherit',
shell: isWin,
cwd,
}
);
if (lite.status !== 0) {
console.error('纯净版构建失败。');
process.exit(lite.status || 1);
}
console.log('\n========== 全部构建完成 ==========');
console.log('输出目录:release/');
console.log(' 完整版安装包:LocalMiniDrama Setup x.x.x.exe');
console.log(' 完整版便携版:LocalMiniDrama x.x.x.exe');
console.log(' 纯净版安装包:LocalMiniDrama-Lite-Setup-x.x.x.exe');
console.log(' 纯净版便携版:LocalMiniDrama-Lite-x.x.x.exe\n');
process.exit(0);
@@ -0,0 +1,294 @@
-- 最小初始表结构,与 backend-node 业务代码对齐(若无 backend-node/migrations 则使用本文件)
CREATE TABLE IF NOT EXISTS dramas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL DEFAULT '',
description TEXT,
genre TEXT,
style TEXT DEFAULT 'realistic',
tags TEXT,
thumbnail TEXT,
total_episodes INTEGER DEFAULT 1,
total_duration INTEGER DEFAULT 0,
status TEXT DEFAULT 'draft',
metadata TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS episodes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER NOT NULL,
episode_number INTEGER DEFAULT 0,
title TEXT DEFAULT '',
script_content TEXT,
description TEXT,
duration INTEGER DEFAULT 0,
video_url TEXT,
thumbnail TEXT,
status TEXT DEFAULT 'draft',
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS storyboards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
episode_id INTEGER NOT NULL,
scene_id INTEGER,
storyboard_number INTEGER DEFAULT 0,
title TEXT,
description TEXT,
location TEXT,
time TEXT,
duration REAL,
dialogue TEXT,
action TEXT,
atmosphere TEXT,
image_prompt TEXT,
video_prompt TEXT,
characters TEXT,
shot_type TEXT,
angle TEXT,
movement TEXT,
video_url TEXT,
status TEXT DEFAULT 'draft',
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS characters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER NOT NULL,
name TEXT NOT NULL DEFAULT '',
role TEXT,
description TEXT,
personality TEXT,
appearance TEXT,
image_url TEXT,
local_path TEXT,
voice_style TEXT,
sort_order INTEGER DEFAULT 0,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS episode_characters (
episode_id INTEGER NOT NULL,
character_id INTEGER NOT NULL,
PRIMARY KEY (episode_id, character_id)
);
CREATE TABLE IF NOT EXISTS scenes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER NOT NULL,
episode_id INTEGER,
location TEXT,
time TEXT,
prompt TEXT,
image_url TEXT,
local_path TEXT,
storyboard_count INTEGER DEFAULT 0,
status TEXT DEFAULT 'draft',
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS props (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER NOT NULL,
name TEXT NOT NULL DEFAULT '',
type TEXT,
description TEXT,
prompt TEXT,
image_url TEXT,
local_path TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS storyboard_props (
storyboard_id INTEGER NOT NULL,
prop_id INTEGER NOT NULL,
PRIMARY KEY (storyboard_id, prop_id)
);
CREATE TABLE IF NOT EXISTS frame_prompts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
storyboard_id INTEGER NOT NULL,
frame_type TEXT,
prompt TEXT,
description TEXT,
layout TEXT,
created_at TEXT,
updated_at TEXT
);
CREATE TABLE IF NOT EXISTS ai_service_configs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
service_type TEXT NOT NULL,
provider TEXT DEFAULT '',
name TEXT DEFAULT '',
base_url TEXT DEFAULT '',
api_key TEXT,
model TEXT,
default_model TEXT,
endpoint TEXT,
query_endpoint TEXT,
priority INTEGER DEFAULT 0,
is_default INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1,
settings TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS async_tasks (
id TEXT PRIMARY KEY,
type TEXT NOT NULL,
status TEXT NOT NULL,
progress INTEGER DEFAULT 0,
message TEXT,
resource_id TEXT,
created_at TEXT,
updated_at TEXT,
completed_at TEXT,
error TEXT,
result TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS image_generations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
storyboard_id INTEGER,
drama_id INTEGER,
scene_id INTEGER,
character_id INTEGER,
provider TEXT,
prompt TEXT,
negative_prompt TEXT,
model TEXT,
frame_type TEXT,
reference_images TEXT,
size TEXT,
quality TEXT,
image_url TEXT,
local_path TEXT,
status TEXT,
task_id TEXT,
completed_at TEXT,
error_msg TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS video_generations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER,
storyboard_id INTEGER,
provider TEXT,
prompt TEXT,
model TEXT,
duration REAL,
aspect_ratio TEXT,
image_url TEXT,
first_frame_url TEXT,
last_frame_url TEXT,
reference_image_urls TEXT,
video_url TEXT,
local_path TEXT,
status TEXT,
task_id TEXT,
scene_id INTEGER,
completed_at TEXT,
error_msg TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS video_merges (
id INTEGER PRIMARY KEY AUTOINCREMENT,
episode_id INTEGER,
drama_id INTEGER,
title TEXT,
provider TEXT,
model TEXT,
status TEXT,
scenes TEXT,
task_id TEXT,
created_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS character_libraries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL DEFAULT '',
category TEXT,
image_url TEXT,
local_path TEXT,
description TEXT,
tags TEXT,
source_type TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS scene_libraries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
location TEXT NOT NULL DEFAULT '',
time TEXT,
prompt TEXT,
description TEXT,
image_url TEXT,
local_path TEXT,
category TEXT,
tags TEXT,
source_type TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS prop_libraries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL DEFAULT '',
description TEXT,
prompt TEXT,
image_url TEXT,
local_path TEXT,
category TEXT,
tags TEXT,
source_type TEXT,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
CREATE TABLE IF NOT EXISTS assets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
drama_id INTEGER,
name TEXT,
type TEXT,
category TEXT,
url TEXT,
local_path TEXT,
file_size INTEGER,
mime_type TEXT,
width INTEGER,
height INTEGER,
duration REAL,
image_gen_id INTEGER,
video_gen_id INTEGER,
created_at TEXT,
updated_at TEXT,
deleted_at TEXT
);
@@ -0,0 +1,2 @@
-- 为已有库增加 default_model 列(新建库 01 已包含则跳过)
ALTER TABLE ai_service_configs ADD COLUMN default_model TEXT;
@@ -0,0 +1,2 @@
-- 道具归属集:从某集剧本提取的道具记入该集,本集资源列表会展示
ALTER TABLE props ADD COLUMN episode_id INTEGER;
@@ -0,0 +1,4 @@
-- async_tasks 缺少 completed_at、error、result 时补上(与 taskService 一致)
ALTER TABLE async_tasks ADD COLUMN completed_at TEXT;
ALTER TABLE async_tasks ADD COLUMN error TEXT;
ALTER TABLE async_tasks ADD COLUMN result TEXT;
@@ -0,0 +1,3 @@
-- image_generations 缺少 completed_at / error_msg 时补上
ALTER TABLE image_generations ADD COLUMN completed_at TEXT;
ALTER TABLE image_generations ADD COLUMN error_msg TEXT;
@@ -0,0 +1,2 @@
-- characters 表缺少 local_path 时补上
ALTER TABLE characters ADD COLUMN local_path TEXT;
@@ -0,0 +1,3 @@
-- scenes 表缺少 image_url / local_path 时补上
ALTER TABLE scenes ADD COLUMN image_url TEXT;
ALTER TABLE scenes ADD COLUMN local_path TEXT;