Merge branch 'main' into abstract

This commit is contained in:
Lazy 2024-01-14 22:48:20 +08:00
commit 0c706badb4
12 changed files with 97 additions and 49 deletions

View File

@ -79,9 +79,8 @@
}
},
"../common/dist": {
"name": "common",
"version": "1.0.0",
"license": "ISC",
"name": "mcsmanager-common",
"version": "0.0.1",
"dependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^20.9.0",
@ -2080,7 +2079,7 @@
},
"node_modules/espree/node_modules/acorn": {
"version": "7.4.1",
"resolved": "http://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true,
"bin": {
@ -2262,9 +2261,9 @@
"integrity": "sha1-PjKNj95BKtR+c44751C00pAENJg="
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"version": "1.15.4",
"resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
@ -6489,7 +6488,7 @@
"dependencies": {
"acorn": {
"version": "7.4.1",
"resolved": "http://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
@ -6631,9 +6630,9 @@
"integrity": "sha1-PjKNj95BKtR+c44751C00pAENJg="
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
"version": "1.15.4",
"resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
},
"form-data": {
"version": "4.0.0",

View File

@ -59,6 +59,7 @@ declare module 'vue' {
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATypography: typeof import('ant-design-vue/es')['Typography']
ATypographyLink: typeof import('ant-design-vue/es')['TypographyLink']
ATypographyParagraph: typeof import('ant-design-vue/es')['TypographyParagraph']
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']

View File

@ -4,7 +4,10 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="theme-color" content="#000000" />
@ -86,7 +89,7 @@
</div>
</div>
</div>
<div id="app"></div>
<div id="app-mount-point" style="width: 100vw"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -4716,9 +4716,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
@ -12899,9 +12899,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
},
"for-each": {
"version": "0.3.3",

View File

@ -9,7 +9,7 @@ html {
padding: 0px;
background-color: var(--background-color);
overflow-x: hidden;
overflow-y: overlay;
overflow-y: auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
@ -144,6 +144,12 @@ html {
backdrop-filter: saturate(110%) blur(4px);
}
.ant-modal {
margin-top: 16px !important;
margin-bottom: 16px !important;
}
// Scrollbar
*::-webkit-scrollbar {
width: 8px;
height: 8px;

View File

@ -234,9 +234,15 @@ const appMenus = computed(() => {
title: t("TXT_CODE_2c69ab15"),
icon: LogoutOutlined,
click: async () => {
await execute();
message.success(t("TXT_CODE_11673d8c"));
router.go(0);
Modal.confirm({
title: $t("确定要退出当前用户吗?"),
async onOk() {
await execute();
message.success(t("TXT_CODE_11673d8c"));
window.localStorage.clear();
setTimeout(() => (window.location.href = "/"), 400);
}
});
},
conditions: !containerState.isDesignMode && isLogged.value,
onlyPC: false

View File

@ -53,6 +53,7 @@ export function useTerminal() {
const isReady = ref<boolean>(false);
const terminal = ref<Terminal>();
const isConnect = ref<boolean>(false);
const isLoading = ref<boolean>(false);
const socketAddress = ref("");
let fitAddonTask: NodeJS.Timer;
@ -71,9 +72,17 @@ export function useTerminal() {
socketAddress.value = addr;
const password = remoteInfo.password;
socket = io(addr, {});
socket = io(addr, {
multiplex: false,
reconnectionDelayMax: 1000 * 10,
timeout: 1000 * 10,
reconnection: true,
reconnectionAttempts: 3,
rejectUnauthorized: false
});
socket.on("connect", () => {
console.info("[Socket.io] connecting:", addr);
socket?.emit("stream/auth", {
data: { password }
});
@ -81,6 +90,7 @@ export function useTerminal() {
});
socket.on("connect_error", (error) => {
console.error("[Socket.io] Connect error: ", addr, error);
isConnect.value = false;
events.emit("error", error);
});
@ -105,6 +115,7 @@ export function useTerminal() {
});
socket.on("reconnect", () => {
console.warn("[Socket.io] reconnect:", addr);
isConnect.value = true;
socket?.emit("stream/auth", {
data: { password }
@ -112,9 +123,9 @@ export function useTerminal() {
});
socket.on("disconnect", () => {
console.warn("[Socket.io] disconnect:", addr);
isConnect.value = false;
events.emit("disconnect");
socket?.close();
});
socket.on("instance/stdout", (packet) => events.emit("stdout", packet?.data));
@ -161,13 +172,6 @@ export function useTerminal() {
});
});
term.writeln(
`${TERM_COLOR.TERM_TEXT_GREEN}[MCSManager] ${TERM_COLOR.TERM_TEXT_GRAY}Instance app terminal.${TERM_COLOR.TERM_RESET}`
);
term.writeln(
`${TERM_COLOR.TERM_TEXT_GREEN}[MCSManager] ${TERM_COLOR.TERM_TEXT_GRAY}Terminal is ready.${TERM_COLOR.TERM_RESET}\r\n`
);
terminal.value = term;
return term;
};

View File

@ -21,7 +21,7 @@ window.addEventListener("unhandledrejection", function (event) {
console.error("Unhandled promise rejection:", event.reason);
});
const { updateUserInfo, state } = useAppStateStore();
const { updateUserInfo } = useAppStateStore();
export async function mountApp() {
try {
@ -35,6 +35,6 @@ export async function mountApp() {
app.use(createPinia());
app.use(router);
app.use(getI18nInstance());
app.mount("#app");
app.mount("#app-mount-point");
}
}

View File

@ -45,7 +45,18 @@ export function jsonToMap(json: JsonData, topTitle = "", map = {}) {
title = `${key}`;
}
const value = json[key];
if (value instanceof Array) {
if (value === null || value === "") {
Object.defineProperty(map, title, {
enumerable: true,
configurable: true,
get() {
return json[key] ?? "";
},
set(v) {
json[key] = v;
}
});
} else if (value instanceof Array) {
if (typeof value[0] === "object") {
jsonToMap(value, title, map);
} else {

View File

@ -66,6 +66,8 @@ const instanceStatusText = computed(
() => String(INSTANCE_STATUS[String(instanceInfo?.value?.status)]) || t("TXT_CODE_c8333afa")
);
let term: Terminal | null = null;
const quickOperations = computed(() =>
arrayFilter([
{
@ -189,12 +191,14 @@ events.on("error", (error: Error) => {
socketError.value = error;
});
let term: Terminal | null = null;
const clearTerminal = () => {
term?.clear();
};
const refreshPage = () => {
window.location.reload();
};
onMounted(async () => {
try {
if (instanceId && daemonId) {
@ -220,8 +224,12 @@ onMounted(async () => {
{{ $t("TXT_CODE_812a629e") + socketAddress }}
</a-typography-paragraph>
<div>
<img :src="connectErrorImage" style="width: 100%" />
<img :src="connectErrorImage" style="width: 100%; height: 110px" />
</div>
<a-typography-title :level="5">{{ $t("错误信息:") }}</a-typography-title>
<a-typography-paragraph>
<pre style="font-size: 12px"><code>{{ socketError.message }}</code></pre>
</a-typography-paragraph>
<a-typography-title :level="5">{{ $t("TXT_CODE_f1c96d8a") }}</a-typography-title>
<a-typography-paragraph>
<ul>
@ -238,6 +246,9 @@ onMounted(async () => {
{{ $t("TXT_CODE_9c188ec8") }}
</li>
</ul>
<div class="flex flex-center">
<a-typography-link @click="refreshPage">{{ $t("重新连接") }}</a-typography-link>
</div>
</a-typography-paragraph>
</div>
</div>
@ -394,11 +405,18 @@ onMounted(async () => {
.error-card-container {
overflow: hidden;
max-width: 500px;
max-width: 440px;
border: 1px solid var(--color-gray-6) !important;
background-color: var(--color-gray-1);
border-radius: 4px;
padding: 12px;
box-shadow: 0px 0px 2px var(--color-gray-7);
}
@media (max-width: 992px) {
.error-card-container {
max-width: 90vw !important;
}
}
}
.console-wrapper {
@ -445,12 +463,12 @@ onMounted(async () => {
background-color: #1e1e1e;
padding: 8px;
border-radius: 6px;
// overflow-x: auto !important;
overflow-x: auto !important;
// overflow-y: auto !important;
display: flex;
flex-direction: column;
.terminal-container {
min-width: 680px;
min-width: 1200px;
height: 100%;
}

View File

@ -1298,7 +1298,7 @@
"TXT_CODE_ef650d57": "仿真终端",
"TXT_CODE_4c846289": "通过仿真终端转发程序来获得终端完全交互能力。\n包括使用 TabCtrl 功能键等。",
"TXT_CODE_d6e7f572": "如果使用有问题,建议关闭。",
"TXT_CODE_e1a3b150": "网页颜色渲染",
"TXT_CODE_e1a3b150": "前端颜色渲染",
"TXT_CODE_6a515e35": "网页自动给输出内容增加颜色渲染,渲染的颜色不一定完全正确。",
"TXT_CODE_1295831e": "如果颜色渲染功能与软件自带的颜色功能冲突,可以关闭此功能。",
"TXT_CODE_b91a94f9": "命令执行回车符",

View File

@ -2044,9 +2044,9 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
@ -5991,9 +5991,9 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
},
"form-data": {
"version": "4.0.0",