diff --git a/backend/terminal/src/main/java/com/kkbpro/terminal/constants/enums/ResultCodeEnum.java b/backend/terminal/src/main/java/com/kkbpro/terminal/constants/enums/ResultCodeEnum.java index 8ab1853..c3ddc59 100644 --- a/backend/terminal/src/main/java/com/kkbpro/terminal/constants/enums/ResultCodeEnum.java +++ b/backend/terminal/src/main/java/com/kkbpro/terminal/constants/enums/ResultCodeEnum.java @@ -2,7 +2,7 @@ public enum ResultCodeEnum { - COOPERATE_KEY_INVALID(-2, "Cooperate Key is Invalid"), + COOPERATE_KEY_INVALID(-2, "Cooperation Key is Invalid"), CONNECT_FAIL(-1,"Fail to connect remote server"), diff --git a/backend/terminal/src/main/java/com/kkbpro/terminal/controller/AdvanceController.java b/backend/terminal/src/main/java/com/kkbpro/terminal/controller/AdvanceController.java index 3fe0edf..3c16bcb 100644 --- a/backend/terminal/src/main/java/com/kkbpro/terminal/controller/AdvanceController.java +++ b/backend/terminal/src/main/java/com/kkbpro/terminal/controller/AdvanceController.java @@ -14,7 +14,9 @@ import org.springframework.web.bind.annotation.RestController; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStreamReader; +import java.util.List; /** * 高级功能接口类 @@ -47,10 +49,10 @@ public class AdvanceController { }; /** - * 获取协作Key + * 生成协作Key */ - @GetMapping("/cooperate") - public Result cooperate(String sshKey, Boolean readOnly, Integer maxHeadCount) throws Exception { + @GetMapping("/cooperate/key") + public Result cooperateKey(String sshKey, Boolean readOnly, Integer maxHeadCount) throws Exception { String errorMsg = "协作Key生成失败"; String successMsg = "协作Key生成成功"; @@ -72,6 +74,32 @@ public Result cooperate(String sshKey, Boolean readOnly, Integer maxHeadCount) t return Result.success(successMsg, key); } + /** + * 结束协作 + */ + @PostMapping("/cooperate/end") + public Result cooperateEnd(String sshKey) throws IOException { + String errorMsg = "结束协作失败"; + String successMsg = "结束协作成功"; + + SSHClient ssh = WebSocketServer.sshClientMap.get(sshKey); + WebSocketServer webSocketServer = WebSocketServer.webSocketServerMap.get(sshKey); + if(ssh == null || webSocketServer == null) { + return Result.error(FileBlockStateEnum.SSH_NOT_EXIST.getState(),"连接断开," + errorMsg); + } + + webSocketServer.setCooperateInfo(null); + List sessions = WebSocketServer.cooperateMap.get(sshKey); + WebSocketServer.cooperateMap.remove(sshKey); + if(sessions != null) { + for(javax.websocket.Session session : sessions) { + session.close(); + } + } + + return Result.success(successMsg); + } + // 完整命令 // echo -n "$(uptime | awk -F'load average: ' '{print $2}' | awk '{print $1}' | sed 's/,//')@" && \ // echo -n "$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')@" && \ diff --git a/backend/terminal/src/main/resources/locales/en_US.json b/backend/terminal/src/main/resources/locales/en_US.json index 4442dec..2974b19 100644 --- a/backend/terminal/src/main/resources/locales/en_US.json +++ b/backend/terminal/src/main/resources/locales/en_US.json @@ -46,8 +46,10 @@ "文件不存在": "No Such File", "云端文件过多": "Too many Cloud Files", "云端上传成功": "Cloud File Uploaded", - "协作Key生成成功": "Cooperate Key Generate Success", - "协作Key生成失败": "Cooperate Key Generate Failed", + "协作Key生成成功": "Cooperation Key Generate Success", + "协作Key生成失败": "Cooperation Key Generate Failed", + "结束协作成功": "End Cooperation Success", + "结束协作失败": "End Cooperation Failed", "获取监控状态成功": "Obtain Monitor Status Success", "获取监控状态失败": "Obtain Monitor Status Failed", "获取Docker信息成功": "Obtain Docker Info Success", diff --git a/front/terminal/src/components/advance/CooperateGen.vue b/front/terminal/src/components/advance/CooperateGen.vue index c1a08cd..9814e6c 100644 --- a/front/terminal/src/components/advance/CooperateGen.vue +++ b/front/terminal/src/components/advance/CooperateGen.vue @@ -71,7 +71,7 @@ export default { const confirm = async () => { const maxHC = maxHeadCount.value; $.ajax({ - url: http_base_url + '/cooperate', + url: http_base_url + '/cooperate/key', type:'get', data:{ time:new Date().getTime(), @@ -89,7 +89,7 @@ export default { grouping: true, repeatNum: Number.MIN_SAFE_INTEGER, }); - context.emit('handleCooperate', maxHC, link); + context.emit('handleCooperate', maxHC); closeDialog(); } else { diff --git a/front/terminal/src/components/preview/TxtPreview.vue b/front/terminal/src/components/preview/TxtPreview.vue index b3df682..a96b849 100644 --- a/front/terminal/src/components/preview/TxtPreview.vue +++ b/front/terminal/src/components/preview/TxtPreview.vue @@ -205,10 +205,14 @@ export default { let serverEncode = 'UTF-8'; const urlParams = getUrlParams(url); if(urlParams.sshKey) serverEncode = changeStr2(urlParams.sshKey.split('-')[1]); + if(encode.value && encode.value.toLowerCase() === 'gb2312') encode.value = 'GBK'; encodeSet.value = ['UTF-8','GBK','ISO-8859-1','Windows-1252']; + // 服务器编码不在默认编码集中 if(!encodeSet.value.map(item => item.toLowerCase()).includes(serverEncode.toLowerCase())) encodeSet.value.unshift(serverEncode); - if(!encode.value || encode.value.toLowerCase() == 'ascii') encode.value = serverEncode; + // 编码格式为ASCII,则默认使用服务器编码 + if(!encode.value || encode.value.toLowerCase() === 'ascii') encode.value = serverEncode; else if(!encodeSet.value.map(item => item.toLowerCase()).includes(encode.value.toLowerCase())) encodeSet.value.unshift(encode.value); + else encode.value = encodeSet.value.find(item => item.toLowerCase() === encode.value.toLowerCase()); }; // 语言模式 diff --git a/front/terminal/src/locales/en_US.json b/front/terminal/src/locales/en_US.json index fef7239..cbb8361 100644 --- a/front/terminal/src/locales/en_US.json +++ b/front/terminal/src/locales/en_US.json @@ -171,6 +171,7 @@ "是": "Yes", "否": "No", "协作Key生成失败": "Cooperate Key Generate Failed", + "确定结束此次协作吗?": "Sure to end this Cooperation?", "概览": "Overview", "核心": "Core", "负载": "Load", diff --git a/front/terminal/src/views/FrameWork.vue b/front/terminal/src/views/FrameWork.vue index 8e0af17..336e14d 100644 --- a/front/terminal/src/views/FrameWork.vue +++ b/front/terminal/src/views/FrameWork.vue @@ -5,7 +5,7 @@
{{ $t('连接设置') }}
{{ $t('偏好设置') }}
{{ $t('文件管理') }}
-
+
{{ $t('高级') }}
@@ -13,20 +13,20 @@
{{ $t('重启') }}
-
+
{{ $t('协作') }}
{{ $t('监控') }}
Docker
-
+
kk Terminal
- {{ onlineNumber }} + {{ onlineNumber }}
{{ $t('开始录制') }} @@ -157,6 +157,7 @@ export default { 'Success':'Connecting success !\r\n', 'Connecting':'Connecting to remote server ...\r\n', 'Disconnected':'Disconnect to remote server.\r\n', + 'End':'This Cooperation is Ended.\r\n', }); const now_connect_status = ref(connect_status.value['Connecting']); @@ -330,21 +331,32 @@ export default { const cooperating = ref(false); const onlineNumber = ref(0); const maxNumber = ref(0); - const cooperateLink = ref(null); - const handleCooperate = (num, link) => { + const handleCooperate = (num) => { maxNumber.value = num; - cooperateLink.value = link; cooperating.value = true; }; - const copyCooperateLink = async () => { - await toClipboard(cooperateLink.value); - ElMessage({ - message: i18n.global.t('协作链接已复制'), - type: 'success', - grouping: true, - repeatNum: Number.MIN_SAFE_INTEGER, + const endCooperate = () => { + $.ajax({ + url: http_base_url + '/cooperate/end', + type:'post', + data:{ + sshKey:sshKey.value, + }, + async success(resp) { + if(resp.status == 'success') { + maxNumber.value = 0; + cooperating.value = false; + } + ElMessage({ + message: resp.info, + type: resp.status, + }); + } }); }; + const endCooperateConfirm = () => { + deleteDialog(i18n.global.t('提示'), i18n.global.t('确定结束此次协作吗?'), endCooperate); + }; // websocket连接 const sshKey = ref(''); @@ -407,6 +419,11 @@ export default { socket.value.onclose = (e) => { if(now_connect_status.value == connect_status.value['Success'] && e.code != 3333) { sshKey.value = ''; + if(urlParams.value.cooperate) { + now_connect_status.value = connect_status.value['End']; + termWrite("\r\n" + now_connect_status.value); + return; + } closeBlock(); now_connect_status.value = connect_status.value['Disconnected']; termWrite("\r\n" + now_connect_status.value); @@ -421,6 +438,16 @@ export default { const showSettings = (newVal) => { isShowSetting.value = newVal; isShowAdvance.value = false; + showAdvance(false); + }; + let advanceTimer = null; + const showAdvance = (newVal) => { + if(advanceTimer) clearTimeout(advanceTimer); + if(isShowAdvance.value != newVal) { + advanceTimer = setTimeout(() => { + isShowAdvance.value = newVal; + }, 400); + } }; const connectSettingRef = ref(); const styleSettingRef = ref(); @@ -544,6 +571,7 @@ export default { else if(type == 5) { isShowSetting.value = true; isShowAdvance.value = true; + showAdvance(true); } // 协作 else if(type == 6) { @@ -595,7 +623,6 @@ export default { cooperating.value = false; onlineNumber.value = 0; maxNumber.value = 0; - cooperateLink.value = null; // 高级-监控模块 if(statusMonitorRef.value) statusMonitorRef.value.deepCloseDialog(); // 高级-Docker模块 @@ -808,6 +835,7 @@ export default { terminal, doSSHConnect, socket, + showAdvance, showSettings, isShowSetting, isShowAdvance, @@ -839,9 +867,8 @@ export default { cooperating, onlineNumber, maxNumber, - cooperateLink, handleCooperate, - copyCooperateLink, + endCooperateConfirm, calcType, installDocker, }