mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-30 03:03:13 +08:00
Support auto update
This commit is contained in:
@ -0,0 +1,21 @@
|
||||
package ai.chat2db.server.web.api.controller.system;
|
||||
|
||||
import ai.chat2db.server.tools.common.util.ConfigUtils;
|
||||
import ai.chat2db.server.web.api.controller.system.util.SystemUtils;
|
||||
import ai.chat2db.server.web.api.controller.system.vo.AppVersionVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AutomaticUpgrade {
|
||||
|
||||
@Scheduled(fixedRate = 3600000) // 每小时运行一次
|
||||
public void checkVersionUpdates() {
|
||||
AppVersionVO appVersion = SystemUtils.getLatestVersion(ConfigUtils.getLocalVersion(), "auto", "");
|
||||
if (appVersion != null) {
|
||||
SystemUtils.upgrade(appVersion);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,20 +4,28 @@
|
||||
*/
|
||||
package ai.chat2db.server.web.api.controller.system;
|
||||
|
||||
import ai.chat2db.server.domain.api.model.Config;
|
||||
import ai.chat2db.server.domain.api.service.ConfigService;
|
||||
import ai.chat2db.server.domain.core.cache.CacheManage;
|
||||
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
|
||||
import ai.chat2db.server.tools.common.config.Chat2dbProperties;
|
||||
import ai.chat2db.server.tools.common.enums.ModeEnum;
|
||||
import ai.chat2db.server.tools.common.model.ConfigJson;
|
||||
import ai.chat2db.server.tools.common.util.ConfigUtils;
|
||||
import ai.chat2db.server.tools.common.util.EasyEnumUtils;
|
||||
import ai.chat2db.server.web.api.controller.ai.chat2db.client.Chat2dbAIClient;
|
||||
import ai.chat2db.server.web.api.controller.system.util.SystemUtils;
|
||||
import ai.chat2db.server.web.api.controller.system.vo.AppVersionVO;
|
||||
import ai.chat2db.server.web.api.controller.system.vo.SystemVO;
|
||||
import ai.chat2db.server.web.api.util.ApplicationContextUtil;
|
||||
import ai.chat2db.spi.ssh.SSHManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author jipengfei
|
||||
@ -43,10 +51,42 @@ public class SystemController {
|
||||
public DataResult<SystemVO> get() {
|
||||
ConfigJson configJson = ConfigUtils.getConfig();
|
||||
return DataResult.of(SystemVO.builder()
|
||||
.systemUuid(configJson.getSystemUuid())
|
||||
.build());
|
||||
.systemUuid(configJson.getSystemUuid())
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/get_latest_version")
|
||||
public DataResult<AppVersionVO> getLatestVersion(String currentVersion) {
|
||||
ConfigService configService = ApplicationContextUtil.getBean(ConfigService.class);
|
||||
Config keyConfig = configService.find(Chat2dbAIClient.CHAT2DB_OPENAI_KEY).getData();
|
||||
AppVersionVO appVersionVO = SystemUtils.getLatestVersion(currentVersion, "manual", keyConfig.getContent());
|
||||
ModeEnum mode = EasyEnumUtils.getEnum(ModeEnum.class, System.getProperty("chat2db.mode"));
|
||||
if (mode == ModeEnum.DESKTOP) {
|
||||
// In this mode, no user login is required, so only local access is available
|
||||
appVersionVO.setDesktop(true);
|
||||
}
|
||||
return DataResult.of(appVersionVO);
|
||||
}
|
||||
|
||||
@PostMapping("/update_desktop_version")
|
||||
public DataResult<String> updateDesktopVersion(@RequestBody AppVersionVO version) {
|
||||
new Thread(() -> {
|
||||
SystemUtils.upgrade(version);
|
||||
}).start();
|
||||
return DataResult.of(version.getVersion());
|
||||
}
|
||||
|
||||
@GetMapping("/is_update_success")
|
||||
public DataResult<Boolean> isUpdateSuccess(String version) {
|
||||
String localVersion = ConfigUtils.getLocalVersion();
|
||||
if (StringUtils.isEmpty(localVersion)) {
|
||||
return DataResult.of(false);
|
||||
}
|
||||
return DataResult.of(localVersion.equals(version));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前版本号
|
||||
*
|
||||
|
@ -0,0 +1,91 @@
|
||||
package ai.chat2db.server.web.api.controller.system.util;
|
||||
|
||||
|
||||
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
|
||||
import ai.chat2db.server.tools.common.util.ConfigUtils;
|
||||
import ai.chat2db.server.web.api.controller.system.vo.AppVersionVO;
|
||||
import ai.chat2db.spi.ssh.SSHManager;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.dtflys.forest.Forest;
|
||||
import com.dtflys.forest.utils.TypeReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.OkHttpClient;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 系统工具包
|
||||
*
|
||||
* @author Jiaju Zhuang
|
||||
*/
|
||||
@Slf4j
|
||||
public class SystemUtils {
|
||||
|
||||
/**
|
||||
* 停止当前应用
|
||||
*/
|
||||
public static void stop() {
|
||||
new Thread(() -> {
|
||||
log.info("1秒以后退出应用");
|
||||
// 1秒以后自动退出应用
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 直接系统退出
|
||||
log.info("开始退出系统应用");
|
||||
SSHManager.close();
|
||||
try {
|
||||
System.exit(0);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private static final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
private static final String VERSION_URL = "https://sqlgpt.cn/api/version.json";
|
||||
|
||||
private static final String ZIP_FILE_PATH = ConfigUtils.APP_PATH + File.separator + "versions" + File.separator;
|
||||
|
||||
public static void upgrade(AppVersionVO appVersion) {
|
||||
|
||||
String appPath = ConfigUtils.APP_PATH;
|
||||
|
||||
log.info("appPath: {}", appPath);
|
||||
if (StringUtils.isBlank(appPath) || !appPath.contains("app")) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String zipPath = ZIP_FILE_PATH + appVersion.getVersion() + ".zip";
|
||||
|
||||
HttpUtil.downloadFile(appVersion.getHotUpgradeUrl(), ZIP_FILE_PATH + appVersion.getVersion() + ".zip");
|
||||
|
||||
ZipUtil.unzip(zipPath);
|
||||
|
||||
FileUtil.del(zipPath);
|
||||
|
||||
ConfigUtils.updateVersion(appVersion.getVersion());
|
||||
} catch (Exception e) {
|
||||
log.error("checkVersionUpdates error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String LATEST_VERSION_URL = "https://test.sqlgpt.cn/api/client/version/check/v3?version=%s&type=wechat&userId=%s";
|
||||
|
||||
public static AppVersionVO getLatestVersion(String version, String type, String userId) {
|
||||
String url = String.format(LATEST_VERSION_URL, version, type, userId);
|
||||
DataResult<AppVersionVO> result = Forest.get(url)
|
||||
.connectTimeout(Duration.ofMillis(5000))
|
||||
.readTimeout(Duration.ofMillis(10000))
|
||||
.execute(new TypeReference<>() {
|
||||
});
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package ai.chat2db.server.web.api.controller.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class AppVersionVO {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime gmtCreate;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private LocalDateTime gmtModified;
|
||||
|
||||
/**
|
||||
* 新版本
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 哪些版本可以升级到该版本
|
||||
*/
|
||||
private String versionUse;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 下载地址
|
||||
*/
|
||||
private String downloadLink;
|
||||
|
||||
/**
|
||||
* 手工更新,自动强制更新
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 白名单,用于测试
|
||||
*/
|
||||
private String whiteList;
|
||||
|
||||
/**
|
||||
* 热更新包地址
|
||||
*/
|
||||
private String hotUpgradeUrl;
|
||||
|
||||
/**
|
||||
* 更新日志
|
||||
*/
|
||||
private String updateLog;
|
||||
|
||||
/**
|
||||
* 桌面
|
||||
*/
|
||||
private boolean desktop;
|
||||
}
|
Reference in New Issue
Block a user