Skip to content

Commit 0af9bb3

Browse files
committed
fix: 终端支持搜索功能,支持光标左右移动、中间输入、Backspace和Delete操作
1 parent e34f887 commit 0af9bb3

File tree

15 files changed

+848
-113
lines changed

15 files changed

+848
-113
lines changed

jarboot-api/src/main/java/io/github/majianzheng/jarboot/api/constant/CommonConst.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public class CommonConst {
5858
public static final String SID_PARAM = "sid";
5959

6060
public static final String USER_DIR = "userDir";
61+
public static final String HOST_KEY = "host";
62+
public static final String UUID_KEY = "uuid";
6163

6264
/** Task status */
6365
public static final String STARTING = "STARTING";

jarboot-server/src/main/java/io/github/majianzheng/jarboot/controller/PreferencesController.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,31 @@ public void getBasicConfigImage(@PathVariable("file") String file, HttpServletRe
4747
* 更新资源
4848
* @param fileName 文件名
4949
* @param file 文件
50+
* @return {@link ResponseVo} 更新成功
5051
* @throws IOException io异常
5152
*/
5253
@PostMapping("/image/{fileName}")
5354
@PrivilegeCheck(value = "PREFERENCES_CONFIG")
5455
@EnableAuditLog("更新LOGO或图标")
55-
public void updateBasicConfigImage(
56+
public ResponseVo<String> updateBasicConfigImage(
5657
@PathVariable("fileName") String fileName,
5758
@RequestParam("file") MultipartFile file) throws IOException {
5859
File imageFile = getImageFile(fileName);
5960
try (InputStream is = file.getInputStream(); OutputStream os = FileUtils.openOutputStream(imageFile)) {
6061
IOUtils.copy(is, os);
6162
}
63+
return HttpResponseUtils.success();
64+
}
65+
66+
/**
67+
* 删除背景图片
68+
* @return {@link ResponseVo} 删除成功
69+
*/
70+
@EnableAuditLog("删除背景图片")
71+
@DeleteMapping("/image/bg.png")
72+
public ResponseVo<String> deleteBgImage() {
73+
FileUtils.deleteQuietly(getImageFile("bg.png"));
74+
return HttpResponseUtils.success();
6275
}
6376

6477
/**
@@ -77,7 +90,7 @@ public ResponseVo<String> getProductName() {
7790
*/
7891
@PutMapping("/productName")
7992
@PrivilegeCheck(value = "PREFERENCES_CONFIG")
80-
@EnableAuditLog("设置产品名称")
93+
@EnableAuditLog("设置系统名称")
8194
public ResponseVo<String> setProductName(String productName) {
8295
SettingUtils.setProductName(productName);
8396
return HttpResponseUtils.success();

jarboot-ui2/package.json

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@
1313
},
1414
"dependencies": {
1515
"@element-plus/icons-vue": "^2.3.1",
16-
"axios": "^1.7.7",
16+
"@xterm/addon-attach": "^0.11.0",
17+
"@xterm/addon-canvas": "^0.7.0",
18+
"@xterm/addon-fit": "^0.10.0",
19+
"@xterm/addon-image": "^0.8.0",
20+
"@xterm/addon-search": "^0.15.0",
21+
"@xterm/addon-serialize": "^0.13.0",
22+
"@xterm/addon-unicode11": "^0.8.0",
23+
"@xterm/addon-web-links": "^0.11.0",
24+
"@xterm/addon-webgl": "^0.18.0",
25+
"@xterm/xterm": "^5.5.0",
1726
"codemirror": "^5.63.3",
1827
"echarts": "^5.4.3",
1928
"element-plus": "^2.8.8",
@@ -23,17 +32,7 @@
2332
"spark-md5": "^3.0.2",
2433
"vue": "^3.3.4",
2534
"vue-i18n": "^9.5.0",
26-
"vue-router": "^4.2.5",
27-
"xterm": "^5.3.0",
28-
"xterm-addon-attach": "^0.9.0",
29-
"xterm-addon-canvas": "^0.5.0",
30-
"xterm-addon-fit": "^0.8.0",
31-
"xterm-addon-image": "^0.5.0",
32-
"xterm-addon-search": "^0.13.0",
33-
"xterm-addon-serialize": "^0.11.0",
34-
"xterm-addon-unicode11": "^0.6.0",
35-
"xterm-addon-web-links": "^0.9.0",
36-
"xterm-addon-webgl": "^0.16.0"
35+
"vue-router": "^4.2.5"
3736
},
3837
"devDependencies": {
3938
"@rushstack/eslint-patch": "^1.1.4",

jarboot-ui2/src/assets/main.less

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,7 @@
66
body {
77
margin: 0;
88
}
9-
@media (hover: hover) {
10-
a:hover {
11-
}
12-
}
139

14-
@media (min-width: 1024px) {
15-
body {
16-
}
17-
18-
#app {
19-
}
20-
}
2110
.el-button:focus-visible {
2211
outline: none !important;
2312
}
@@ -123,6 +112,17 @@ body {
123112
animation: span-frame1 3s infinite linear;
124113
}
125114

115+
/* 确保终端容器和子元素允许文本选择 */
116+
.xterm, .xterm-viewport, .xterm-screen {
117+
user-select: text !important;
118+
-webkit-user-select: text !important;
119+
}
120+
/* 禁用鼠标事件的拦截(如存在) */
121+
.xterm-viewport {
122+
pointer-events: auto !important;
123+
}
124+
125+
126126
@keyframes span-frame1
127127
{
128128
from {transform: rotate(0deg);}

jarboot-ui2/src/common/CommonConst.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const LOCALHOST = 'localhost';
4040

4141
export const FAVICON_URL = '/jarboot/preferences/image/favicon.ico';
4242
export const LOGO_URL = '/jarboot/preferences/image/logo.png';
43+
export const BG_URL = '/jarboot/preferences/image/bg.png';
4344

4445
export const DEFAULT_PRIVILEGE = {
4546
SERVICES_MGR: true,

jarboot-ui2/src/common/CommonUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ export default class CommonUtils {
7070
return query;
7171
}
7272

73+
public static copyString(str: string) {
74+
const input = document.createElement('textarea');
75+
input.value = str;
76+
document.body.append(input);
77+
input.focus();
78+
input.select();
79+
document.execCommand('copy');
80+
document.body.removeChild(input);
81+
}
7382
public static exportServer(name: string, clusterHost: string): void {
7483
const a = document.createElement('a');
7584
let url = `/api/jarboot/cluster/manager/exportService/${name}.zip`;

jarboot-ui2/src/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ declare module '@vue/runtime-core' {
3535
ElForm: typeof import('element-plus/es')['ElForm']
3636
ElFormItem: typeof import('element-plus/es')['ElFormItem']
3737
ElIcon: typeof import('element-plus/es')['ElIcon']
38+
ElImage: typeof import('element-plus/es')['ElImage']
3839
ElInput: typeof import('element-plus/es')['ElInput']
3940
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
4041
ElLink: typeof import('element-plus/es')['ElLink']

0 commit comments

Comments
 (0)