Merge branch 'develop' of https://github.com/HBAI-Ltd/Toonflow-app into develop

This commit is contained in:
zhishi 2026-02-27 09:47:30 +08:00
commit ad0d9b337b
16 changed files with 239 additions and 202 deletions

View File

@ -3,18 +3,18 @@ name: Build and Release
on:
push:
tags:
- 'v*'
- "v*"
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 1.0.0)'
description: "Version number (e.g., 1.0.0)"
required: false
type: string
jobs:
build-windows:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -22,8 +22,8 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'yarn'
node-version: "24"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
@ -47,7 +47,7 @@ jobs:
build-macos:
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -55,8 +55,8 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'yarn'
node-version: "24"
cache: "yarn"
- name: Install dependencies
run: yarn install --frozen-lockfile
@ -82,7 +82,7 @@ jobs:
needs: [build-windows, build-macos]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
@ -111,4 +111,4 @@ jobs:
dist/*.zip
dist/*.dmg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4
.gitignore vendored
View File

@ -43,4 +43,6 @@ db.sqlite
db.sqlite-shm
db.sqlite-wal
web/*
web/*
.devtools

View File

@ -517,9 +517,15 @@ pm2 monit # 监控面板
~~交流群 7~~
交流群 8:
~~交流群 8~~
<img src="./docs/chat8QR.jpg?r=2" alt="Toonflow Logo" height="400"/>
~~交流群 9~~
~~交流群 10~~
交流群 11:
<img src="./docs/chat11QR.jpg?r=2" alt="Toonflow Logo" height="400"/>
<p>使用微信扫码添加,二维码过期可提交 Issues 提醒更新</p>
---
@ -540,11 +546,11 @@ Toonflow 基于 AGPL-3.0 协议开源发布许可证详情https://www.gnu.
---
<!-- # ⭐️ 星标历史
# ⭐️ 星标历史
[![Star History Chart](https://api.star-history.com/svg?repos=HBAI-Ltd/Toonflow-app&type=date&legend=top-left)](https://www.star-history.com/#HBAI-Ltd/Toonflow-app&type=date&legend=top-left)
--- -->
---
# 🙏 致谢

BIN
docs/chat10QR.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

BIN
docs/chat11QR.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

BIN
docs/chat9QR.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

View File

@ -18,6 +18,7 @@ files:
- "!**/*.d.ts"
- "!src/**/*"
- "!scripts/**/*.ts"
- "!scripts/*.ts"
asar: true

View File

@ -1,6 +1,6 @@
{
"name": "toonflow-app",
"version": "1.0.6-dev2",
"version": "1.0.6",
"description": "Toonflow 是一款 AI 短剧漫剧工具,能够利用 AI 技术将小说自动转化为剧本,并结合 AI 生成的图片和视频,实现高效的短剧创作。",
"author": "HBAI-Ltd <ltlctools@outlook.com>",
"homepage": "https://github.com/HBAI-Ltd/Toonflow-app#readme",

View File

@ -3,26 +3,26 @@ import path from "path";
import startServe, { closeServe } from "src/app";
function createMainWindow(): void {
const isDev = process.env.NODE_ENV === "dev" || !app.isPackaged;
const basePath = isDev ? process.cwd() : app.getAppPath();
const win = new BrowserWindow({
width: 900,
height: 600,
show: true,
autoHideMenuBar: true,
icon: path.join(
basePath,
"scripts",
process.platform === "win32" ? "logo.ico" : "logo.png"
),
});
const htmlPath = path.join(basePath, "scripts", "web", "index.html");
// 开发环境和生产环境使用不同的路径
const isDev = process.env.NODE_ENV === "dev" || !app.isPackaged;
const htmlPath = isDev
? path.join(process.cwd(), "scripts", "web", "index.html")
: path.join(app.getAppPath(), "scripts", "web", "index.html");
void win.loadFile(htmlPath);
}
app.whenReady().then(async () => {
createMainWindow();
await startServe();
try {
await startServe();
} catch (err) {
console.error("[服务启动失败]:", err);
}
});
app.on("window-all-closed", () => {

File diff suppressed because one or more lines are too long

View File

@ -7,13 +7,28 @@ const defaultEnvValues: Record<string, string> = {
prod: `NODE_ENV=prod\nPORT=60000\nOSSURL=http://127.0.0.1:60000/`,
};
//加载环境变量
const env = process.env.NODE_ENV ?? "dev";
// 判断是否为打包后的 Electron 环境
const isElectron = typeof process.versions?.electron !== "undefined";
let isPackaged = false;
if (isElectron) {
const { app } = require("electron");
isPackaged = app.isPackaged;
}
//加载环境变量(打包环境默认使用 prod
const env = process.env.NODE_ENV ?? (isPackaged ? "prod" : "dev");
if (!env) {
console.log("[环境变量为空]");
process.exit(1);
} else {
const envDir = path.resolve("env");
// Electron 打包环境使用 userData 目录,开发环境使用项目根目录
let envDir: string;
if (isElectron) {
const { app } = require("electron");
envDir = path.join(app.getPath("userData"), "env");
} else {
envDir = path.resolve("env");
}
const envFilePath = path.join(envDir, `.env.${env}`);
// 自动创建 env 目录和文件(.gitignore 可能忽略了这些文件)

View File

@ -29,7 +29,7 @@ export default async (knex: Knex): Promise<void> => {
await addColumn("t_video", "aiConfigId", "integer");
await addColumn("t_config", "modelType", "text");
await addColumn("t_videoConfig", "audioEnabled", "integer");
await addColumn("t_videoConfig", "errorReason", "text");
await addColumn("t_video", "errorReason", "text");
//更正字段
await alterColumnType("t_config", "modelType", "text");

View File

@ -1,160 +1,162 @@
// @routes-hash 3cfad40b3c8658b442ab766a9323d740
// @routes-hash a5e432459af85c08bbc13a86444f292c
import { Express } from "express";
import route1 from "./routes/assets/addAssets";
import route2 from "./routes/assets/delAssets";
import route3 from "./routes/assets/generateAssets";
import route4 from "./routes/assets/getAssets";
import route5 from "./routes/assets/getImage";
import route6 from "./routes/assets/getStoryboard";
import route7 from "./routes/assets/polishPrompt";
import route8 from "./routes/assets/saveAssets";
import route9 from "./routes/assets/updateAssets";
import route10 from "./routes/index/index";
import route11 from "./routes/novel/addNovel";
import route12 from "./routes/novel/delNovel";
import route13 from "./routes/novel/getNovel";
import route14 from "./routes/novel/updateNovel";
import route15 from "./routes/other/clearDatabase";
import route16 from "./routes/other/deleteAllData";
import route17 from "./routes/other/getCaptcha";
import route18 from "./routes/other/login";
import route19 from "./routes/other/testAI";
import route20 from "./routes/other/testImage";
import route21 from "./routes/other/testVideo";
import route22 from "./routes/outline/addOutline";
import route23 from "./routes/outline/agentsOutline";
import route24 from "./routes/outline/delOutline";
import route25 from "./routes/outline/getHistory";
import route26 from "./routes/outline/getOutline";
import route27 from "./routes/outline/getPartScript";
import route28 from "./routes/outline/getStoryline";
import route29 from "./routes/outline/setHistory";
import route30 from "./routes/outline/updateOutline";
import route31 from "./routes/outline/updateScript";
import route32 from "./routes/outline/updateStoryline";
import route33 from "./routes/project/addProject";
import route34 from "./routes/project/delProject";
import route35 from "./routes/project/getProject";
import route36 from "./routes/project/getProjectCount";
import route37 from "./routes/project/getSingleProject";
import route38 from "./routes/project/updateProject";
import route39 from "./routes/prompt/getPrompts";
import route40 from "./routes/prompt/updatePrompt";
import route41 from "./routes/script/generateScriptApi";
import route42 from "./routes/script/generateScriptSave";
import route43 from "./routes/script/geScriptApi";
import route44 from "./routes/setting/addModel";
import route45 from "./routes/setting/configurationModel";
import route46 from "./routes/setting/delModel";
import route47 from "./routes/setting/getAiModelMap";
import route48 from "./routes/setting/getLog";
import route49 from "./routes/setting/getSetting";
import route50 from "./routes/setting/getVideoModelList";
import route51 from "./routes/setting/updateModel";
import route52 from "./routes/setting/updeteModel";
import route53 from "./routes/storyboard/batchSuperScoreImage";
import route54 from "./routes/storyboard/chatStoryboard";
import route55 from "./routes/storyboard/generateShotImage";
import route56 from "./routes/storyboard/generateStoryboardApi";
import route57 from "./routes/storyboard/generateVideoPrompt";
import route58 from "./routes/storyboard/getStoryboard";
import route59 from "./routes/storyboard/keepStoryboard";
import route60 from "./routes/storyboard/saveStoryboard";
import route61 from "./routes/storyboard/uploadImage";
import route62 from "./routes/task/getTaskApi";
import route63 from "./routes/task/taskDetails";
import route64 from "./routes/user/getUser";
import route65 from "./routes/video/addVideo";
import route66 from "./routes/video/addVideoConfig";
import route67 from "./routes/video/deleteVideoConfig";
import route68 from "./routes/video/generatePrompt";
import route69 from "./routes/video/generateVideo";
import route70 from "./routes/video/getManufacturer";
import route71 from "./routes/video/getVideo";
import route72 from "./routes/video/getVideoConfigs";
import route73 from "./routes/video/getVideoModel";
import route74 from "./routes/video/getVideoStoryboards";
import route75 from "./routes/video/reviseVideoStoryboards";
import route76 from "./routes/video/saveVideo";
import route77 from "./routes/video/upDateVideoConfig";
import route3 from "./routes/assets/delAssetsImage";
import route4 from "./routes/assets/generateAssets";
import route5 from "./routes/assets/getAssets";
import route6 from "./routes/assets/getImage";
import route7 from "./routes/assets/getStoryboard";
import route8 from "./routes/assets/polishPrompt";
import route9 from "./routes/assets/saveAssets";
import route10 from "./routes/assets/updateAssets";
import route11 from "./routes/index/index";
import route12 from "./routes/novel/addNovel";
import route13 from "./routes/novel/delNovel";
import route14 from "./routes/novel/getNovel";
import route15 from "./routes/novel/updateNovel";
import route16 from "./routes/other/clearDatabase";
import route17 from "./routes/other/deleteAllData";
import route18 from "./routes/other/getCaptcha";
import route19 from "./routes/other/login";
import route20 from "./routes/other/testAI";
import route21 from "./routes/other/testImage";
import route22 from "./routes/other/testVideo";
import route23 from "./routes/outline/addOutline";
import route24 from "./routes/outline/agentsOutline";
import route25 from "./routes/outline/delOutline";
import route26 from "./routes/outline/getHistory";
import route27 from "./routes/outline/getOutline";
import route28 from "./routes/outline/getPartScript";
import route29 from "./routes/outline/getStoryline";
import route30 from "./routes/outline/setHistory";
import route31 from "./routes/outline/updateOutline";
import route32 from "./routes/outline/updateScript";
import route33 from "./routes/outline/updateStoryline";
import route34 from "./routes/project/addProject";
import route35 from "./routes/project/delProject";
import route36 from "./routes/project/getProject";
import route37 from "./routes/project/getProjectCount";
import route38 from "./routes/project/getSingleProject";
import route39 from "./routes/project/updateProject";
import route40 from "./routes/prompt/getPrompts";
import route41 from "./routes/prompt/updatePrompt";
import route42 from "./routes/script/generateScriptApi";
import route43 from "./routes/script/generateScriptSave";
import route44 from "./routes/script/geScriptApi";
import route45 from "./routes/setting/addModel";
import route46 from "./routes/setting/configurationModel";
import route47 from "./routes/setting/delModel";
import route48 from "./routes/setting/getAiModelMap";
import route49 from "./routes/setting/getLog";
import route50 from "./routes/setting/getSetting";
import route51 from "./routes/setting/getVideoModelList";
import route52 from "./routes/setting/updateModel";
import route53 from "./routes/setting/updeteModel";
import route54 from "./routes/storyboard/batchSuperScoreImage";
import route55 from "./routes/storyboard/chatStoryboard";
import route56 from "./routes/storyboard/generateShotImage";
import route57 from "./routes/storyboard/generateStoryboardApi";
import route58 from "./routes/storyboard/generateVideoPrompt";
import route59 from "./routes/storyboard/getStoryboard";
import route60 from "./routes/storyboard/keepStoryboard";
import route61 from "./routes/storyboard/saveStoryboard";
import route62 from "./routes/storyboard/uploadImage";
import route63 from "./routes/task/getTaskApi";
import route64 from "./routes/task/taskDetails";
import route65 from "./routes/user/getUser";
import route66 from "./routes/video/addVideo";
import route67 from "./routes/video/addVideoConfig";
import route68 from "./routes/video/deleteVideoConfig";
import route69 from "./routes/video/generatePrompt";
import route70 from "./routes/video/generateVideo";
import route71 from "./routes/video/getManufacturer";
import route72 from "./routes/video/getVideo";
import route73 from "./routes/video/getVideoConfigs";
import route74 from "./routes/video/getVideoModel";
import route75 from "./routes/video/getVideoStoryboards";
import route76 from "./routes/video/reviseVideoStoryboards";
import route77 from "./routes/video/saveVideo";
import route78 from "./routes/video/upDateVideoConfig";
export default async (app: Express) => {
app.use("/assets/addAssets", route1);
app.use("/assets/delAssets", route2);
app.use("/assets/generateAssets", route3);
app.use("/assets/getAssets", route4);
app.use("/assets/getImage", route5);
app.use("/assets/getStoryboard", route6);
app.use("/assets/polishPrompt", route7);
app.use("/assets/saveAssets", route8);
app.use("/assets/updateAssets", route9);
app.use("/index", route10);
app.use("/novel/addNovel", route11);
app.use("/novel/delNovel", route12);
app.use("/novel/getNovel", route13);
app.use("/novel/updateNovel", route14);
app.use("/other/clearDatabase", route15);
app.use("/other/deleteAllData", route16);
app.use("/other/getCaptcha", route17);
app.use("/other/login", route18);
app.use("/other/testAI", route19);
app.use("/other/testImage", route20);
app.use("/other/testVideo", route21);
app.use("/outline/addOutline", route22);
app.use("/outline/agentsOutline", route23);
app.use("/outline/delOutline", route24);
app.use("/outline/getHistory", route25);
app.use("/outline/getOutline", route26);
app.use("/outline/getPartScript", route27);
app.use("/outline/getStoryline", route28);
app.use("/outline/setHistory", route29);
app.use("/outline/updateOutline", route30);
app.use("/outline/updateScript", route31);
app.use("/outline/updateStoryline", route32);
app.use("/project/addProject", route33);
app.use("/project/delProject", route34);
app.use("/project/getProject", route35);
app.use("/project/getProjectCount", route36);
app.use("/project/getSingleProject", route37);
app.use("/project/updateProject", route38);
app.use("/prompt/getPrompts", route39);
app.use("/prompt/updatePrompt", route40);
app.use("/script/generateScriptApi", route41);
app.use("/script/generateScriptSave", route42);
app.use("/script/geScriptApi", route43);
app.use("/setting/addModel", route44);
app.use("/setting/configurationModel", route45);
app.use("/setting/delModel", route46);
app.use("/setting/getAiModelMap", route47);
app.use("/setting/getLog", route48);
app.use("/setting/getSetting", route49);
app.use("/setting/getVideoModelList", route50);
app.use("/setting/updateModel", route51);
app.use("/setting/updeteModel", route52);
app.use("/storyboard/batchSuperScoreImage", route53);
app.use("/storyboard/chatStoryboard", route54);
app.use("/storyboard/generateShotImage", route55);
app.use("/storyboard/generateStoryboardApi", route56);
app.use("/storyboard/generateVideoPrompt", route57);
app.use("/storyboard/getStoryboard", route58);
app.use("/storyboard/keepStoryboard", route59);
app.use("/storyboard/saveStoryboard", route60);
app.use("/storyboard/uploadImage", route61);
app.use("/task/getTaskApi", route62);
app.use("/task/taskDetails", route63);
app.use("/user/getUser", route64);
app.use("/video/addVideo", route65);
app.use("/video/addVideoConfig", route66);
app.use("/video/deleteVideoConfig", route67);
app.use("/video/generatePrompt", route68);
app.use("/video/generateVideo", route69);
app.use("/video/getManufacturer", route70);
app.use("/video/getVideo", route71);
app.use("/video/getVideoConfigs", route72);
app.use("/video/getVideoModel", route73);
app.use("/video/getVideoStoryboards", route74);
app.use("/video/reviseVideoStoryboards", route75);
app.use("/video/saveVideo", route76);
app.use("/video/upDateVideoConfig", route77);
app.use("/assets/delAssetsImage", route3);
app.use("/assets/generateAssets", route4);
app.use("/assets/getAssets", route5);
app.use("/assets/getImage", route6);
app.use("/assets/getStoryboard", route7);
app.use("/assets/polishPrompt", route8);
app.use("/assets/saveAssets", route9);
app.use("/assets/updateAssets", route10);
app.use("/index", route11);
app.use("/novel/addNovel", route12);
app.use("/novel/delNovel", route13);
app.use("/novel/getNovel", route14);
app.use("/novel/updateNovel", route15);
app.use("/other/clearDatabase", route16);
app.use("/other/deleteAllData", route17);
app.use("/other/getCaptcha", route18);
app.use("/other/login", route19);
app.use("/other/testAI", route20);
app.use("/other/testImage", route21);
app.use("/other/testVideo", route22);
app.use("/outline/addOutline", route23);
app.use("/outline/agentsOutline", route24);
app.use("/outline/delOutline", route25);
app.use("/outline/getHistory", route26);
app.use("/outline/getOutline", route27);
app.use("/outline/getPartScript", route28);
app.use("/outline/getStoryline", route29);
app.use("/outline/setHistory", route30);
app.use("/outline/updateOutline", route31);
app.use("/outline/updateScript", route32);
app.use("/outline/updateStoryline", route33);
app.use("/project/addProject", route34);
app.use("/project/delProject", route35);
app.use("/project/getProject", route36);
app.use("/project/getProjectCount", route37);
app.use("/project/getSingleProject", route38);
app.use("/project/updateProject", route39);
app.use("/prompt/getPrompts", route40);
app.use("/prompt/updatePrompt", route41);
app.use("/script/generateScriptApi", route42);
app.use("/script/generateScriptSave", route43);
app.use("/script/geScriptApi", route44);
app.use("/setting/addModel", route45);
app.use("/setting/configurationModel", route46);
app.use("/setting/delModel", route47);
app.use("/setting/getAiModelMap", route48);
app.use("/setting/getLog", route49);
app.use("/setting/getSetting", route50);
app.use("/setting/getVideoModelList", route51);
app.use("/setting/updateModel", route52);
app.use("/setting/updeteModel", route53);
app.use("/storyboard/batchSuperScoreImage", route54);
app.use("/storyboard/chatStoryboard", route55);
app.use("/storyboard/generateShotImage", route56);
app.use("/storyboard/generateStoryboardApi", route57);
app.use("/storyboard/generateVideoPrompt", route58);
app.use("/storyboard/getStoryboard", route59);
app.use("/storyboard/keepStoryboard", route60);
app.use("/storyboard/saveStoryboard", route61);
app.use("/storyboard/uploadImage", route62);
app.use("/task/getTaskApi", route63);
app.use("/task/taskDetails", route64);
app.use("/user/getUser", route65);
app.use("/video/addVideo", route66);
app.use("/video/addVideoConfig", route67);
app.use("/video/deleteVideoConfig", route68);
app.use("/video/generatePrompt", route69);
app.use("/video/generateVideo", route70);
app.use("/video/getManufacturer", route71);
app.use("/video/getVideo", route72);
app.use("/video/getVideoConfigs", route73);
app.use("/video/getVideoModel", route74);
app.use("/video/getVideoStoryboards", route75);
app.use("/video/reviseVideoStoryboards", route76);
app.use("/video/saveVideo", route77);
app.use("/video/upDateVideoConfig", route78);
}

View File

@ -0,0 +1,27 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
const router = express.Router();
// 删除资产图片
export default router.post(
"/",
validateFields({
imageId: z.number().optional(),
assetsId: z.number().optional(),
}),
async (req, res) => {
const { imageId, assetsId } = req.body;
if (assetsId) {
await u.db("t_assets").where("id", assetsId).update({
filePath: null,
});
}
if (imageId) {
await u.db("t_image").where("id", imageId).delete();
}
res.status(200).send(success({ message: "删除资产图片成功" }));
},
);

View File

@ -8,6 +8,6 @@ export default router.post("/", async (req, res) => {
const configData = await u
.db("t_aiModelMap")
.leftJoin("t_config", "t_aiModelMap.configId", "t_config.id")
.select("t_aiModelMap.name", "t_config.model", "t_aiModelMap.id", "t_aiModelMap.key");
.select("t_aiModelMap.name", "t_config.model", "t_aiModelMap.id", "t_aiModelMap.key", "t_config.manufacturer");
res.status(200).send(success(configData));
});

View File

@ -1,20 +1,6 @@
// @db-hash 5a1cbe86324cb073c1931fc53c56725f
// @db-hash 8ef9e37c14c453b2d95832b971baca8a
//该文件由脚本自动生成,请勿手动修改
export interface _t_video_old_20260210 {
'aiConfigId'?: number | null;
'configId'?: number | null;
'filePath'?: string | null;
'firstFrame'?: string | null;
'id'?: number;
'model'?: string | null;
'prompt'?: string | null;
'resolution'?: string | null;
'scriptId'?: number | null;
'state'?: number | null;
'storyboardImgs'?: string | null;
'time'?: number | null;
}
export interface t_aiModelMap {
'configId'?: number | null;
'id'?: number;
@ -53,6 +39,7 @@ export interface t_config {
'manufacturer'?: string | null;
'model'?: string | null;
'modelType'?: string | null;
'name'?: string | null;
'type'?: string | null;
'userId'?: number | null;
}
@ -152,12 +139,10 @@ export interface t_video {
'time'?: number | null;
}
export interface t_videoConfig {
'aiConfigId'?: number | null;
'audioEnabled'?: number | null;
'createTime'?: number | null;
'duration'?: number | null;
'endFrame'?: string | null;
'errorReason'?: string | null;
'id'?: number;
'images'?: string | null;
'manufacturer'?: string | null;
@ -172,7 +157,6 @@ export interface t_videoConfig {
}
export interface DB {
"_t_video_old_20260210": _t_video_old_20260210;
"t_aiModelMap": t_aiModelMap;
"t_assets": t_assets;
"t_chatHistory": t_chatHistory;