Skip to content

Commit c72d4d2

Browse files
committed
feat 服务端在线升级支持配置 beta 计划(”妈妈“再也不用担心没有稳定版了)
1 parent 1d92205 commit c72d4d2

File tree

9 files changed

+162
-24
lines changed

9 files changed

+162
-24
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
1. 【server】新增 文件中心添加别名码来为文件进行分类下载,构建添加别名码可以同步到文件中心
88
(感谢 [@大灰灰大](https://gitee.com/linjianhui) [Gitee issues I6OUC8](https://gitee.com/dromara/Jpom/issues/I6OUC8)
9+
2. 【server】新增 服务端在线升级支持配置 beta 计划(”妈妈“再也不用担心没有稳定版了)(感谢@罗俊)
910

1011
### 🐞 解决BUG、优化功能
1112

modules/agent/src/main/java/io/jpom/controller/IndexController.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public JsonMessage<JSONObject> info() {
8787
jsonObject.put("manifest", instance);
8888
jsonObject.put("remoteVersion", remoteVersion);
8989
jsonObject.put("pluginSize", PluginFactory.size());
90+
jsonObject.put("joinBetaRelease", RemoteVersion.betaRelease());
9091
return JsonMessage.success("", jsonObject);
9192
}
9293

@@ -135,13 +136,13 @@ public JsonMessage<List<JSONObject>> getProcessList(String processName, Integer
135136
processName = StrUtil.emptyToDefault(processName, "java");
136137
List<JSONObject> processes = OshiUtils.getProcesses(processName, Convert.toInt(count, 20));
137138
processes = processes.stream()
138-
.peek(jsonObject -> {
139-
int processId = jsonObject.getIntValue("processId");
140-
String port = AbstractProjectCommander.getInstance().getMainPort(processId);
141-
jsonObject.put("port", port);
142-
//
143-
})
144-
.collect(Collectors.toList());
139+
.peek(jsonObject -> {
140+
int processId = jsonObject.getIntValue("processId");
141+
String port = AbstractProjectCommander.getInstance().getMainPort(processId);
142+
jsonObject.put("port", port);
143+
//
144+
})
145+
.collect(Collectors.toList());
145146
return JsonMessage.success("ok", processes);
146147
}
147148

modules/common/src/main/java/io/jpom/common/JpomApplicationEvent.java

+5
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
361361
@Configuration
362362
public static class SystemEvent implements ILoadEvent {
363363

364+
@Override
365+
public int getOrder() {
366+
return LOWEST_PRECEDENCE;
367+
}
368+
364369
@Override
365370
public void afterPropertiesSet(ApplicationContext applicationContext) throws Exception {
366371
CronUtils.upsert("system_monitor", "0 0 0,12 * * ?", this::executeTask);

modules/common/src/main/java/io/jpom/common/RemoteVersion.java

+33-2
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
*/
2323
package io.jpom.common;
2424

25+
import cn.hutool.core.convert.Convert;
2526
import cn.hutool.core.date.SystemClock;
2627
import cn.hutool.core.io.FileUtil;
2728
import cn.hutool.core.lang.Tuple;
2829
import cn.hutool.core.lang.Validator;
2930
import cn.hutool.core.util.ObjectUtil;
3031
import cn.hutool.core.util.StrUtil;
32+
import cn.hutool.core.util.SystemPropsUtil;
3133
import cn.hutool.http.HttpRequest;
3234
import cn.hutool.http.HttpResponse;
3335
import cn.hutool.http.HttpUtil;
@@ -70,6 +72,7 @@ public class RemoteVersion extends BaseJsonModel {
7072
* 1. <a href="https://jpom.top/docs/release-versions.json">https://jpom.top/docs/release-versions.json</a>
7173
*/
7274
private static final String DEFAULT_URL = "https://jpom.top/docs/release-versions.json";
75+
private static final String BETA_URL = "https://jpom.top/docs/beta-versions.json";
7376
private static String remoteVersionUrl;
7477
/**
7578
* 检查间隔时间
@@ -105,6 +108,10 @@ public class RemoteVersion extends BaseJsonModel {
105108
* 是否有新版本
106109
*/
107110
private Boolean upgrade;
111+
/**
112+
* 是否为 beta 版本
113+
*/
114+
private Boolean beta;
108115

109116
@Override
110117
public String toString() {
@@ -115,6 +122,30 @@ public static void setRemoteVersionUrl(String remoteVersionUrl) {
115122
RemoteVersion.remoteVersionUrl = remoteVersionUrl;
116123
}
117124

125+
/**
126+
* 获取 版本检查的 url
127+
*
128+
* @return 远程地址
129+
*/
130+
private static String loadDefaultUrl() {
131+
boolean beta = betaRelease();
132+
return beta ? BETA_URL : DEFAULT_URL;
133+
}
134+
135+
/**
136+
* 判断当前是否加入 beta 计划
137+
*
138+
* @return true 已经加入 false 未加入
139+
*/
140+
public static boolean betaRelease() {
141+
String betaRelease = SystemPropsUtil.get("JOIN_JPOM_BETA_RELEASE", StrUtil.EMPTY);
142+
return Convert.toBool(betaRelease, false);
143+
}
144+
145+
public static void changeBetaRelease(String beta) {
146+
SystemPropsUtil.set("JOIN_JPOM_BETA_RELEASE", beta);
147+
}
148+
118149
/**
119150
* 获取远程最新版本
120151
*
@@ -123,8 +154,8 @@ public static void setRemoteVersionUrl(String remoteVersionUrl) {
123154
public static RemoteVersion loadRemoteInfo() {
124155
String body = StrUtil.EMPTY;
125156
try {
126-
String remoteVersionUrl = StrUtil.emptyToDefault(RemoteVersion.remoteVersionUrl, DEFAULT_URL);
127-
remoteVersionUrl = Validator.isUrl(remoteVersionUrl) ? remoteVersionUrl : DEFAULT_URL;
157+
String remoteVersionUrl = StrUtil.emptyToDefault(RemoteVersion.remoteVersionUrl, loadDefaultUrl());
158+
remoteVersionUrl = Validator.isUrl(remoteVersionUrl) ? remoteVersionUrl : loadDefaultUrl();
128159
// 获取缓存中到信息
129160
RemoteVersion remoteVersion = RemoteVersion.loadTransitUrl(remoteVersionUrl);
130161
if (remoteVersion == null || StrUtil.isEmpty(remoteVersion.getTagName())) {

modules/common/src/main/java/io/jpom/util/StringUtil.java

+14-9
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424

2525
import cn.hutool.core.collection.CollStreamUtil;
2626
import cn.hutool.core.collection.CollUtil;
27+
import cn.hutool.core.convert.Convert;
2728
import cn.hutool.core.io.FileUtil;
2829
import cn.hutool.core.lang.Tuple;
2930
import cn.hutool.core.map.MapUtil;
31+
import cn.hutool.core.util.ClassUtil;
3032
import cn.hutool.core.util.ObjectUtil;
3133
import cn.hutool.core.util.StrUtil;
3234
import cn.hutool.core.util.URLUtil;
@@ -142,6 +144,9 @@ public static <T> T jsonConvert(String jsonStr, Class<T> cls) {
142144
if (StrUtil.isEmpty(jsonStr)) {
143145
return null;
144146
}
147+
if (ClassUtil.isPrimitiveWrapper(cls)) {
148+
return Convert.convert(cls, jsonStr);
149+
}
145150
try {
146151
return JSON.parseObject(jsonStr, cls);
147152
} catch (Exception e) {
@@ -251,15 +256,15 @@ public static Map<String, String> parseEnvStr(List<String> envStrList) {
251256
return MapUtil.newHashMap();
252257
}
253258
List<Tuple> collect = envStrList.stream()
254-
.map(StrUtil::trim)
255-
.filter(s -> !StrUtil.isEmpty(s) && !StrUtil.startWith(s, "#"))
256-
.map(s -> {
257-
List<String> list1 = StrUtil.splitTrim(s, "=");
258-
if (CollUtil.size(list1) != 2) {
259-
return null;
260-
}
261-
return new Tuple(list1.get(0), list1.get(1));
262-
}).filter(Objects::nonNull).collect(Collectors.toList());
259+
.map(StrUtil::trim)
260+
.filter(s -> !StrUtil.isEmpty(s) && !StrUtil.startWith(s, "#"))
261+
.map(s -> {
262+
List<String> list1 = StrUtil.splitTrim(s, "=");
263+
if (CollUtil.size(list1) != 2) {
264+
return null;
265+
}
266+
return new Tuple(list1.get(0), list1.get(1));
267+
}).filter(Objects::nonNull).collect(Collectors.toList());
263268
return CollStreamUtil.toMap(collect, objects -> objects.get(0), objects -> objects.get(1));
264269
}
265270
}

modules/server/src/main/java/io/jpom/controller/system/SystemUpdateController.java

+35-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import cn.hutool.core.io.IoUtil;
2727
import cn.hutool.core.io.resource.ResourceUtil;
2828
import cn.hutool.core.lang.Tuple;
29+
import cn.hutool.core.util.BooleanUtil;
2930
import cn.hutool.core.util.StrUtil;
3031
import cn.hutool.core.util.URLUtil;
3132
import com.alibaba.fastjson2.JSONObject;
@@ -40,8 +41,11 @@
4041
import io.jpom.permission.MethodFeature;
4142
import io.jpom.permission.SystemPermission;
4243
import io.jpom.service.dblog.BackupInfoService;
44+
import io.jpom.service.system.SystemParametersServer;
4345
import io.jpom.system.ServerConfig;
4446
import lombok.Lombok;
47+
import lombok.extern.slf4j.Slf4j;
48+
import org.springframework.context.ApplicationContext;
4549
import org.springframework.http.MediaType;
4650
import org.springframework.util.Assert;
4751
import org.springframework.web.bind.annotation.GetMapping;
@@ -69,15 +73,21 @@
6973
@RequestMapping(value = "system")
7074
@Feature(cls = ClassFeature.SYSTEM_UPGRADE)
7175
@SystemPermission(superUser = true)
72-
public class SystemUpdateController extends BaseServerController {
76+
@Slf4j
77+
public class SystemUpdateController extends BaseServerController implements ILoadEvent {
78+
79+
private static final String JOIN_JPOM_BETA_RELEASE = "JOIN_JPOM_BETA_RELEASE";
7380

7481
private final BackupInfoService backupInfoService;
7582
private final ServerConfig serverConfig;
83+
private final SystemParametersServer systemParametersServer;
7684

7785
public SystemUpdateController(BackupInfoService backupInfoService,
78-
ServerConfig serverConfig) {
86+
ServerConfig serverConfig,
87+
SystemParametersServer systemParametersServer) {
7988
this.backupInfoService = backupInfoService;
8089
this.serverConfig = serverConfig;
90+
this.systemParametersServer = systemParametersServer;
8191
}
8292

8393
@PostMapping(value = "info", produces = MediaType.APPLICATION_JSON_VALUE)
@@ -91,10 +101,26 @@ public JsonMessage<JSONObject> info(HttpServletRequest request, String machineId
91101
JSONObject jsonObject = new JSONObject();
92102
jsonObject.put("manifest", instance);
93103
jsonObject.put("remoteVersion", remoteVersion);
104+
jsonObject.put("joinBetaRelease", RemoteVersion.betaRelease());
94105
return JsonMessage.success("", jsonObject);
95106
});
96107
}
97108

109+
@GetMapping(value = "change-beta-release", produces = MediaType.APPLICATION_JSON_VALUE)
110+
@Feature(method = MethodFeature.LIST)
111+
public JsonMessage<String> changeBetaRelease(String beta) {
112+
boolean betaBool = this.changeBetaRelease2(beta);
113+
RemoteVersion.loadRemoteInfo();
114+
return JsonMessage.success(betaBool ? "成功加入 beta 计划" : "关闭 beta 计划成功");
115+
}
116+
117+
private boolean changeBetaRelease2(String beta) {
118+
boolean betaBool = BooleanUtil.toBoolean(beta);
119+
systemParametersServer.upsert(JOIN_JPOM_BETA_RELEASE, String.valueOf(betaBool), "是否加入 beta 计划");
120+
RemoteVersion.changeBetaRelease(String.valueOf(betaBool));
121+
return betaBool;
122+
}
123+
98124
/**
99125
* 更新日志
100126
*
@@ -213,4 +239,11 @@ public JsonMessage<String> upgrade(HttpServletRequest request,
213239
return JsonMessage.success(Const.UPGRADE_MSG);
214240
});
215241
}
242+
243+
@Override
244+
public void afterPropertiesSet(ApplicationContext applicationContext) throws Exception {
245+
String config = systemParametersServer.getConfig(JOIN_JPOM_BETA_RELEASE, String.class);
246+
boolean release2 = this.changeBetaRelease2(config);
247+
log.debug("beta plan:{}", release2);
248+
}
216249
}

modules/server/src/test/java/TestString.java

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2121
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222
*/
23+
2324
import cn.hutool.core.codec.Base64;
2425
import cn.hutool.core.collection.CollUtil;
2526
import cn.hutool.core.lang.PatternPool;
@@ -170,6 +171,9 @@ public void testTime() {
170171
@Test
171172
public void testVersion() {
172173
System.out.println(StrUtil.compareVersion("2.10.10", "2.10.9"));
174+
System.out.println(StrUtil.compareVersion("2.10.37", "2.10.38"));
175+
System.out.println(StrUtil.compareVersion("2.10.37", "2.10.37.1"));
176+
System.out.println(StrUtil.compareVersion("2.10.38", "2.10.37.9"));
173177
}
174178

175179
@Test

web-vue/src/api/system.js

+9
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,15 @@ export function changelog(data) {
234234
});
235235
}
236236

237+
export function changBetaRelease(params) {
238+
return axios({
239+
url: "/system/change-beta-release",
240+
method: "get",
241+
headers: {},
242+
params,
243+
});
244+
}
245+
237246
/**
238247
* 检查新版本
239248
*@param {String} nodeId 节点 ID

web-vue/src/components/upgrade/index.vue

+53-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,28 @@
1111
<a-timeline-item>
1212
<span class="layui-elem-quote">当前前端打包时间:{{ temp.vueTimeStamp }}</span>
1313
</a-timeline-item>
14+
<a-timeline-item v-if="!this.nodeId && !this.machineId">
15+
<span class="layui-elem-quote">beta计划:</span>
16+
<a-space>
17+
<a-switch checked-children="加入" un-checked-children="未加入" :disabled="true" v-model="temp.joinBetaRelease" />
18+
<template v-if="temp.joinBetaRelease">
19+
<a-button type="link" @click="handleChangeBetaRelease(false)">关闭 beat计划</a-button>
20+
</template>
21+
<template v-else>
22+
<a-tooltip>
23+
<template #title>
24+
加入 beta 计划可以及时获取到最新的功能、一些优化功能、最快修复 bug 的版本,但是 beta 版也可能在部分新功能上存在不稳定的情况。您需要根据您业务情况来评估是否可以加入 beta,在使用 beta
25+
版过程中遇到问题可以随时反馈给我们,我们会尽快为您解答。
26+
</template>
27+
<a-button icon="question-circle" type="link" @click="handleChangeBetaRelease(true)">我要加入</a-button>
28+
</a-tooltip>
29+
</template>
30+
</a-space>
31+
</a-timeline-item>
1432
<a-timeline-item>
1533
<span class="layui-elem-quote">当前版本号:{{ temp.version }} </span>
1634
<template v-if="temp.upgrade !== undefined">
17-
<a-tag v-if="temp.upgrade" color="pink" @click="upgrageVerion">新版本:{{ temp.newVersion }} <a-icon type="download" /></a-tag>
35+
<a-tag v-if="temp.upgrade" color="pink" @click="upgrageVerion">新版本:{{ temp.newVersion }} {{ temp.newBeta ? "/beta" : "" }} <a-icon type="download" /></a-tag>
1836
<a-tag v-else color="orange" @click="checkVersion">
1937
<a-icon type="rocket" />
2038
</a-tag>
@@ -69,7 +87,7 @@
6987
</div>
7088
</template>
7189
<script>
72-
import { systemInfo, uploadUpgradeFile, changelog, checkVersion, remoteUpgrade, uploadUpgradeFileMerge } from "@/api/system";
90+
import { systemInfo, uploadUpgradeFile, changelog, checkVersion, remoteUpgrade, uploadUpgradeFileMerge, changBetaRelease } from "@/api/system";
7391
import Vue from "vue";
7492
import MarkdownItVue from "markdown-it-vue";
7593
import "markdown-it-vue/dist/markdown-it-vue.css";
@@ -129,7 +147,7 @@ export default {
129147
this.temp = res.data?.manifest;
130148
//
131149
// vueTimeStamp
132-
this.temp = { ...this.temp, vueTimeStamp: parseTime(this.getMeta("build-time")) };
150+
this.temp = { ...this.temp, vueTimeStamp: parseTime(this.getMeta("build-time")), joinBetaRelease: res.data?.joinBetaRelease };
133151
//
134152
changelog({
135153
nodeId: this.nodeId,
@@ -357,7 +375,7 @@ export default {
357375
resolve(false);
358376
return;
359377
}
360-
this.temp = { ...this.temp, upgrade: data.upgrade, newVersion: data.tagName };
378+
this.temp = { ...this.temp, upgrade: data.upgrade, newVersion: data.tagName, newBeta: data.beta };
361379
362380
if (this.temp.upgrade && data.changelog) {
363381
this.changelog = data.changelog;
@@ -402,6 +420,37 @@ export default {
402420
},
403421
});
404422
},
423+
// 加入beta计划
424+
handleChangeBetaRelease(beta) {
425+
const html = beta
426+
? "确认要加入 beta 计划吗?<ul style='color:red;'>" +
427+
"<li><b> 加入 beta 计划可以及时获取到最新的功能、一些优化功能、最快修复 bug 的版本,但是 beta 版也可能在部分新功能上存在不稳定的情况。</b></li>" +
428+
"<li><b>下您需要根据您业务情况来评估是否可以加入 beta。</b></li>" +
429+
"<li>在使用 beta 版过程中遇到问题可以随时反馈给我们,我们会尽快为您解答。</li>" +
430+
" </ul>"
431+
: "确认要关闭 beta 计划吗?";
432+
const h = this.$createElement;
433+
this.$confirm({
434+
title: "系统提示",
435+
content: h("div", null, [h("p", { domProps: { innerHTML: html } }, null)]),
436+
okText: "确认",
437+
cancelText: "取消",
438+
onOk: () => {
439+
//
440+
changBetaRelease({
441+
beta: beta,
442+
}).then((res) => {
443+
if (res.code === 200) {
444+
this.$notification.success({
445+
message: res.msg,
446+
});
447+
448+
this.loadData();
449+
}
450+
});
451+
},
452+
});
453+
},
405454
},
406455
};
407456
</script>

0 commit comments

Comments
 (0)