完善更新功能

This commit is contained in:
ACT丶流星雨 2026-04-02 20:38:01 +08:00
parent 1a49e2f8d5
commit f447436930
5 changed files with 113 additions and 92 deletions

27
data/update.json Normal file
View File

@ -0,0 +1,27 @@
{
"version": "1.0.8",
"time": 1775118545494,
"data": {
"toonflow": [
{
"type": "zip",
"url": "https://toonflow.oss-cn-beijing.aliyuncs.com/latest/latest.zip"
},
{
"type": "windows",
"url": "https://toonflow.oss-cn-beijing.aliyuncs.com/latest/latest.exe"
},
{
"type": "linux",
"url": "https://toonflow.oss-cn-beijing.aliyuncs.com/latest/latest.AppImage"
},
{
"type": "macos",
"url": "https://toonflow.oss-cn-beijing.aliyuncs.com/latest/latest.dmg"
}
],
"github": [],
"atomgit": [],
"gitee": []
}
}

BIN
docs/g-star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

View File

@ -13,19 +13,16 @@ declare const __APP_VERSION__: string | undefined;
* extraResources data * extraResources data
*/ */
function getVersionFromFile(filePath: string): string | null { function getVersionFromUpdateJson(filePath: string): string | null {
try { try {
if (fs.existsSync(filePath)) { if (fs.existsSync(filePath)) {
return fs.readFileSync(filePath, "utf8").trim(); const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
return data.version ?? null;
} }
} catch {} } catch {}
return null; return null;
} }
function writeVersionToFile(filePath: string, version: string): void {
fs.writeFileSync(filePath, version, { encoding: "utf8" });
}
function copyDirForce(src: string, dest: string): void { function copyDirForce(src: string, dest: string): void {
if (!fs.existsSync(src)) return; if (!fs.existsSync(src)) return;
if (fs.existsSync(dest)) { if (fs.existsSync(dest)) {
@ -37,14 +34,13 @@ function copyDirForce(src: string, dest: string): void {
function initializeData(): void { function initializeData(): void {
const srcDir = path.join(process.resourcesPath, "data"); const srcDir = path.join(process.resourcesPath, "data");
const destDir = path.join(app.getPath("userData"), "data"); const destDir = path.join(app.getPath("userData"), "data");
const versionFile = path.join(destDir, "version.txt"); const updateJsonFile = path.join(destDir, "update.json");
const currentVersion = typeof __APP_VERSION__ !== "undefined" ? __APP_VERSION__ : "0.0.0"; const currentVersion = typeof __APP_VERSION__ !== "undefined" ? __APP_VERSION__ : "0.0.0";
const userVersion = getVersionFromFile(versionFile); const userVersion = getVersionFromUpdateJson(updateJsonFile);
// 首次安装或无version.txt,直接全量拷贝 // 首次安装或无update.json,直接全量拷贝
if (!fs.existsSync(destDir) || !userVersion) { if (!fs.existsSync(destDir) || !userVersion) {
copyDirRecursive(srcDir, destDir); copyDirRecursive(srcDir, destDir);
writeVersionToFile(versionFile, currentVersion);
return; return;
} }
@ -52,7 +48,6 @@ function initializeData(): void {
if (userVersion !== currentVersion) { if (userVersion !== currentVersion) {
copyDirForce(path.join(srcDir, "serve"), path.join(destDir, "serve")); copyDirForce(path.join(srcDir, "serve"), path.join(destDir, "serve"));
copyDirForce(path.join(srcDir, "web"), path.join(destDir, "web")); copyDirForce(path.join(srcDir, "web"), path.join(destDir, "web"));
writeVersionToFile(versionFile, currentVersion);
} }
} }

View File

@ -1,4 +1,4 @@
// @routes-hash b96beb71b18fbc98620917e465530e0c // @routes-hash 6fee4152cf981edb9229a3dcfafcb1a7
import { Express } from "express"; import { Express } from "express";
import route1 from "./routes/agents/clearMemory"; import route1 from "./routes/agents/clearMemory";
@ -99,39 +99,38 @@ import route95 from "./routes/scriptAgent/getPlanData";
import route96 from "./routes/scriptAgent/setPlanData"; import route96 from "./routes/scriptAgent/setPlanData";
import route97 from "./routes/scriptAgent/updateData"; import route97 from "./routes/scriptAgent/updateData";
import route98 from "./routes/setting/about/checkUpdate"; import route98 from "./routes/setting/about/checkUpdate";
import route99 from "./routes/setting/about/downloadApp copy"; import route99 from "./routes/setting/about/downloadApp";
import route100 from "./routes/setting/about/downloadApp"; import route100 from "./routes/setting/agentDeploy/agentSetKey";
import route101 from "./routes/setting/agentDeploy/agentSetKey"; import route101 from "./routes/setting/agentDeploy/deployAgentModel";
import route102 from "./routes/setting/agentDeploy/deployAgentModel"; import route102 from "./routes/setting/agentDeploy/getAgentDeploy";
import route103 from "./routes/setting/agentDeploy/getAgentDeploy"; import route103 from "./routes/setting/dbConfig/clearData";
import route104 from "./routes/setting/dbConfig/clearData"; import route104 from "./routes/setting/dev/getSwitchAiDevTool";
import route105 from "./routes/setting/dev/getSwitchAiDevTool"; import route105 from "./routes/setting/dev/updateSwitchAiDevTool";
import route106 from "./routes/setting/dev/updateSwitchAiDevTool"; import route106 from "./routes/setting/fileManagement/openFolder";
import route107 from "./routes/setting/fileManagement/openFolder"; import route107 from "./routes/setting/getTextModel";
import route108 from "./routes/setting/getTextModel"; import route108 from "./routes/setting/loginConfig/getUser";
import route109 from "./routes/setting/loginConfig/getUser"; import route109 from "./routes/setting/loginConfig/updateUserPwd";
import route110 from "./routes/setting/loginConfig/updateUserPwd"; import route110 from "./routes/setting/memoryConfig/delAllMemory";
import route111 from "./routes/setting/memoryConfig/delAllMemory"; import route111 from "./routes/setting/memoryConfig/getMemory";
import route112 from "./routes/setting/memoryConfig/getMemory"; import route112 from "./routes/setting/memoryConfig/sureMemory";
import route113 from "./routes/setting/memoryConfig/sureMemory"; import route113 from "./routes/setting/promptManage/getPrompt";
import route114 from "./routes/setting/promptManage/getPrompt"; import route114 from "./routes/setting/promptManage/updatePrompt";
import route115 from "./routes/setting/promptManage/updatePrompt"; import route115 from "./routes/setting/skillManagement/getSkillContent";
import route116 from "./routes/setting/skillManagement/getSkillContent"; import route116 from "./routes/setting/skillManagement/getSkillList";
import route117 from "./routes/setting/skillManagement/getSkillList"; import route117 from "./routes/setting/skillManagement/saveSkillContent";
import route118 from "./routes/setting/skillManagement/saveSkillContent"; import route118 from "./routes/setting/vendorConfig/addVendor";
import route119 from "./routes/setting/vendorConfig/addVendor"; import route119 from "./routes/setting/vendorConfig/deleteVendor";
import route120 from "./routes/setting/vendorConfig/deleteVendor"; import route120 from "./routes/setting/vendorConfig/enableVendor";
import route121 from "./routes/setting/vendorConfig/enableVendor"; import route121 from "./routes/setting/vendorConfig/getCodeByLink";
import route122 from "./routes/setting/vendorConfig/getCodeByLink"; import route122 from "./routes/setting/vendorConfig/getVendorList";
import route123 from "./routes/setting/vendorConfig/getVendorList"; import route123 from "./routes/setting/vendorConfig/modelTest";
import route124 from "./routes/setting/vendorConfig/modelTest"; import route124 from "./routes/setting/vendorConfig/updateCode";
import route125 from "./routes/setting/vendorConfig/updateCode"; import route125 from "./routes/setting/vendorConfig/updateVendor";
import route126 from "./routes/setting/vendorConfig/updateVendor"; import route126 from "./routes/task/getProject";
import route127 from "./routes/task/getProject"; import route127 from "./routes/task/getTaskApi";
import route128 from "./routes/task/getTaskApi"; import route128 from "./routes/task/getTaskCategories";
import route129 from "./routes/task/getTaskCategories"; import route129 from "./routes/task/taskDetails";
import route130 from "./routes/task/taskDetails"; import route130 from "./routes/test/test";
import route131 from "./routes/test/test";
export default async (app: Express) => { export default async (app: Express) => {
app.use("/api/agents/clearMemory", route1); app.use("/api/agents/clearMemory", route1);
@ -232,37 +231,36 @@ export default async (app: Express) => {
app.use("/api/scriptAgent/setPlanData", route96); app.use("/api/scriptAgent/setPlanData", route96);
app.use("/api/scriptAgent/updateData", route97); app.use("/api/scriptAgent/updateData", route97);
app.use("/api/setting/about/checkUpdate", route98); app.use("/api/setting/about/checkUpdate", route98);
app.use("/api/setting/about/downloadApp copy", route99); app.use("/api/setting/about/downloadApp", route99);
app.use("/api/setting/about/downloadApp", route100); app.use("/api/setting/agentDeploy/agentSetKey", route100);
app.use("/api/setting/agentDeploy/agentSetKey", route101); app.use("/api/setting/agentDeploy/deployAgentModel", route101);
app.use("/api/setting/agentDeploy/deployAgentModel", route102); app.use("/api/setting/agentDeploy/getAgentDeploy", route102);
app.use("/api/setting/agentDeploy/getAgentDeploy", route103); app.use("/api/setting/dbConfig/clearData", route103);
app.use("/api/setting/dbConfig/clearData", route104); app.use("/api/setting/dev/getSwitchAiDevTool", route104);
app.use("/api/setting/dev/getSwitchAiDevTool", route105); app.use("/api/setting/dev/updateSwitchAiDevTool", route105);
app.use("/api/setting/dev/updateSwitchAiDevTool", route106); app.use("/api/setting/fileManagement/openFolder", route106);
app.use("/api/setting/fileManagement/openFolder", route107); app.use("/api/setting/getTextModel", route107);
app.use("/api/setting/getTextModel", route108); app.use("/api/setting/loginConfig/getUser", route108);
app.use("/api/setting/loginConfig/getUser", route109); app.use("/api/setting/loginConfig/updateUserPwd", route109);
app.use("/api/setting/loginConfig/updateUserPwd", route110); app.use("/api/setting/memoryConfig/delAllMemory", route110);
app.use("/api/setting/memoryConfig/delAllMemory", route111); app.use("/api/setting/memoryConfig/getMemory", route111);
app.use("/api/setting/memoryConfig/getMemory", route112); app.use("/api/setting/memoryConfig/sureMemory", route112);
app.use("/api/setting/memoryConfig/sureMemory", route113); app.use("/api/setting/promptManage/getPrompt", route113);
app.use("/api/setting/promptManage/getPrompt", route114); app.use("/api/setting/promptManage/updatePrompt", route114);
app.use("/api/setting/promptManage/updatePrompt", route115); app.use("/api/setting/skillManagement/getSkillContent", route115);
app.use("/api/setting/skillManagement/getSkillContent", route116); app.use("/api/setting/skillManagement/getSkillList", route116);
app.use("/api/setting/skillManagement/getSkillList", route117); app.use("/api/setting/skillManagement/saveSkillContent", route117);
app.use("/api/setting/skillManagement/saveSkillContent", route118); app.use("/api/setting/vendorConfig/addVendor", route118);
app.use("/api/setting/vendorConfig/addVendor", route119); app.use("/api/setting/vendorConfig/deleteVendor", route119);
app.use("/api/setting/vendorConfig/deleteVendor", route120); app.use("/api/setting/vendorConfig/enableVendor", route120);
app.use("/api/setting/vendorConfig/enableVendor", route121); app.use("/api/setting/vendorConfig/getCodeByLink", route121);
app.use("/api/setting/vendorConfig/getCodeByLink", route122); app.use("/api/setting/vendorConfig/getVendorList", route122);
app.use("/api/setting/vendorConfig/getVendorList", route123); app.use("/api/setting/vendorConfig/modelTest", route123);
app.use("/api/setting/vendorConfig/modelTest", route124); app.use("/api/setting/vendorConfig/updateCode", route124);
app.use("/api/setting/vendorConfig/updateCode", route125); app.use("/api/setting/vendorConfig/updateVendor", route125);
app.use("/api/setting/vendorConfig/updateVendor", route126); app.use("/api/task/getProject", route126);
app.use("/api/task/getProject", route127); app.use("/api/task/getTaskApi", route127);
app.use("/api/task/getTaskApi", route128); app.use("/api/task/getTaskCategories", route128);
app.use("/api/task/getTaskCategories", route129); app.use("/api/task/taskDetails", route129);
app.use("/api/task/taskDetails", route130); app.use("/api/test/test", route130);
app.use("/api/test/test", route131);
} }

View File

@ -27,16 +27,14 @@ export default router.post(
async (req, res) => { async (req, res) => {
const { source } = req.body; const { source } = req.body;
const getUrl: any = { const getUrl = "https://toonflow.oss-cn-beijing.aliyuncs.com/update.json";
toonflow: "http://localhost:5173/update.json",
github: "https://api.github.com/repos/toonflow/toonflow/releases/latest",
gitee: "https://gitee.com/api/v5/repos/toonflow/toonflow/releases/latest",
atomgit: "https://api.github.com/repos/atomgit/atomgit/releases/latest",
};
const vsersion = await fetch(getUrl[source]).then((res) => res.json()); const versionInfo = await fetch(getUrl).then((res) => res.json());
if (!vsersion) return res.status(400).send(error("无法获取版本信息")); if (!versionInfo) return res.status(400).send(error("无法获取版本信息"));
const { version: tagger, time, data } = vsersion; const { version: tagger, time, data } = versionInfo;
const sourceData = data[source];
if (!sourceData) return res.status(400).send(error("无法获取该源的下载信息"));
const platformType: Record<string, string> = { const platformType: Record<string, string> = {
win32: "windows", win32: "windows",
@ -44,22 +42,25 @@ export default router.post(
linux: "linux", linux: "linux",
}; };
const zipItem = data.find((d: any) => d.type === "zip"); const zipItem = sourceData.find((d: any) => d.type === "zip");
const installerItem = data.find((d: any) => d.type === platformType[process.platform]); const installerItem = sourceData.find((d: any) => d.type === platformType[process.platform]);
const taggerList = tagger.split(".").map(Number); const taggerList = tagger.split(".").map(Number);
const currentVersionList = APP_VERSION.split(".").map(Number); const currentVersionList = APP_VERSION.split(".").map(Number);
//对比Major //对比Major
if (taggerList[0] > currentVersionList[0]) { if (taggerList[0] > currentVersionList[0]) {
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true, time, url: installerItem?.url })); if (!installerItem) return res.status(400).send(error("该源暂无适用于当前系统的安装包"));
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true, time, url: installerItem.url }));
} }
//对比Minor //对比Minor
if (taggerList[1] > currentVersionList[1]) { if (taggerList[1] > currentVersionList[1]) {
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true, time, url: installerItem?.url })); if (!installerItem) return res.status(400).send(error("该源暂无适用于当前系统的安装包"));
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true, time, url: installerItem.url }));
} }
//Patch //Patch
if (taggerList[2] > currentVersionList[2]) { if (taggerList[2] > currentVersionList[2]) {
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: false, time, url: zipItem?.url })); if (!zipItem) return res.status(400).send(error("该源暂无增量更新包"));
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: false, time, url: zipItem.url }));
} }
return res.status(200).send(success({ needUpdate: false, latestVersion: tagger, reinstall: false, time })); return res.status(200).send(success({ needUpdate: false, latestVersion: tagger, reinstall: false, time }));
}, },