[Feat] Basic PLS lifecycle mgmt

This commit is contained in:
Minoricew
2025-06-06 02:05:04 +08:00
parent 839afa79e8
commit 6da8348b41
18 changed files with 739 additions and 271 deletions

View File

@@ -18,12 +18,73 @@
}
.acs-bc-pls-status-page-main-logo {
max-width: 13.5%;
max-width: 11%;
opacity: 0.45;
margin-top: 1.5rem;
margin-bottom: 1.5rem;
}
.acs-bc-psp-operations-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
}
.acs-bc-psp-operation-btn {
--svg-color: rgb(17, 140, 255);
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-left: 0.75rem;
margin-right: 0.75rem;
transition: opacity 0.25s, color 0.5s;
}
.acs-bc-psp-operation-btn p {
font-size: normal;
margin-left: 5px;
margin-top: -1px;
color: var(--svg-color);
}
.acs-bc-psp-operation-btn svg {
max-width: 16px;
max-height: 16px;
}
.acs-bc-psp-operation-btn.acs-bc-psp-o-btn-dangerous {
--svg-color: rgb(244, 8, 8);
}
.acs-bc-psp-operation-btn[aura-disabled="true"] {
--svg-color: rgba(0, 0, 0, 0.25);
}
.acs-bc-psp-operation-btn[aura-disabled="true"]:hover,
.acs-bc-psp-operation-btn[aura-disabled="true"]:active {
cursor: not-allowed !important;
opacity: 1 !important;
}
.acs-bc-psp-operation-btn:hover,
.acs-bc-psp-operation-btn:active {
cursor: pointer;
}
.acs-bc-psp-operation-btn:hover {
opacity: 0.6;
}
.acs-bc-psp-operation-btn:active {
opacity: 0.3;
}
.acs-bc-pls-status-page-status-el {
display: flex;
align-items: center;

View File

@@ -9,6 +9,91 @@
class="acs-bc-pls-status-page-main-logo"
/>
<div class="acs-bc-psp-operations-container">
<div class="acs-bc-psp-operation-btn" id="acsBcPsp-operBtn-Refresh">
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
>
<path
fill="var(--svg-color)"
d="M26 18A10 10 0 1 1 16 8h6.182l-3.584 3.585L20 13l6-6l-6-6l-1.402 1.414L22.185 6H16a12 12 0 1 0 12 12Z"
/>
</svg>
<p>刷新状态</p>
</div>
<div
class="acs-bc-psp-operation-btn"
aura-disabled="true"
id="acsBcPsp-operBtn-Download"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
>
<path
fill="var(--svg-color)"
d="M23.5 22H23v-2h.5a4.5 4.5 0 0 0 .36-9H23l-.1-.82a7 7 0 0 0-13.88 0L9 11h-.86a4.5 4.5 0 0 0 .36 9H9v2h-.5A6.5 6.5 0 0 1 7.2 9.14a9 9 0 0 1 17.6 0A6.5 6.5 0 0 1 23.5 22"
/>
<path
fill="var(--svg-color)"
d="M17 26.17V14h-2v12.17l-2.59-2.58L11 25l5 5l5-5l-1.41-1.41z"
/>
</svg>
<p>下载内核</p>
</div>
<div class="acs-bc-psp-operation-btn" id="acsBcPsp-operBtn-Install">
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
>
<path
fill="var(--svg-color)"
d="m10 6l1.414-1.414L15 8.172V0h2v8.172l3.586-3.586L22 6l-6 6z"
/>
<path
fill="var(--svg-color)"
d="M22 16a5.98 5.98 0 0 0-1.757-4.243L16 16l-4.243-4.243A6 6 0 1 0 22 16"
/>
<path
fill="var(--svg-color)"
d="M30 16a13.96 13.96 0 0 0-4.105-9.895l-1.414 1.414a12 12 0 1 1-16.962 0L6.105 6.105A13.997 13.997 0 1 0 30 16"
/>
</svg>
<p>安装服务</p>
</div>
<div
class="acs-bc-psp-operation-btn acs-bc-psp-o-btn-dangerous"
id="acsBcPsp-operBtn-Uninstall"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
>
<path
fill="var(--svg-color)"
d="M30 21.4L28.6 20L25 23.6L21.4 20L20 21.4l3.6 3.6l-3.6 3.6l1.4 1.4l3.6-3.6l3.6 3.6l1.4-1.4l-3.6-3.6z"
/>
<path
fill="var(--svg-color)"
d="M15.4 30L5 23.8c-.6-.4-1-1-1-1.7V9.9c0-.7.4-1.4 1-1.7l10-5.9c.3-.2.6-.3 1-.3s.7.1 1 .3l10 5.9c.6.4 1 1 1 1.7V16h-2V9.9L16 4L6 9.9v12.2l10.5 6.2z"
/>
</svg>
<p>卸载服务</p>
</div>
</div>
<div class="acs-bc-pls-status-page-status-el">
<p>安装状态</p>
<div

View File

@@ -1,11 +1,128 @@
if (!global.__HUGO_AURA_UI_FUNCTIONS__.subConfig)
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig = {};
(() => {
const REQUIRE_BASE = "../../aura/ui/pages/configSubPages/behaviourCtrl";
const IPC_METHOD_BASE = "$aura.pls";
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.plsStatus = {
updateOperationBtnStatus: async (btnName, side, btnContent = null) => {
const btnEl = document.getElementById(`acsBcPsp-operBtn-${btnName}`);
if (!btnEl) return false;
btnEl.setAttribute("aura-disabled", side ? "true" : "false");
if (btnContent) {
const btnPEl = btnEl.getElementsByTagName("p")[0];
btnPEl.textContent = btnContent;
}
if (side) {
btnEl.onclick = () => {};
} else {
switch (btnName) {
case "Refresh":
btnEl.onclick = () =>
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.plsStatus.refreshPlsStatus();
break;
case "Download":
break;
case "Install":
break;
case "Uninstall":
break;
default:
break;
}
}
return true;
},
updateStatus: async () => {
const curPlsStats = await updatePlsStatusFromLocal();
const acIdInst = "acs-bc-psp-installStatus-container";
const atIdInst = "acs-bc-psp-installStatus-text";
switch (curPlsStats.installed) {
case true:
updateStatusEl(acIdInst, atIdInst, "SUCCESS", "已安装");
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Uninstall", false);
break;
case false:
updateStatusEl(acIdInst, atIdInst, "PENDING", "未安装");
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Uninstall", true);
}
const acIdLaunch = "acs-bc-psp-launchStatus-container";
const atIdLaunch = "acs-bc-psp-launchStatus-text";
switch (curPlsStats.launched) {
case true:
updateStatusEl(acIdLaunch, atIdLaunch, "SUCCESS", "已启动");
break;
case false:
updateStatusEl(acIdLaunch, atIdLaunch, "PENDING", "未启动");
break;
}
const acIdConn = "acs-bc-psp-connStatus-container";
const atIdConn = "acs-bc-psp-connStatus-text";
switch (curPlsStats.connected) {
case true:
updateStatusEl(acIdConn, atIdConn, "SUCCESS", "已连接");
break;
case false:
updateStatusEl(acIdConn, atIdConn, "FAILED", "连接失败");
break;
}
if (curPlsStats.version && curPlsStats.version !== "未知") {
const versionTextEl = document.getElementById(
"acs-bc-psp-version-text"
);
versionTextEl.textContent = "v" + curPlsStats.version;
}
},
refreshPlsStatus: async () => {
const updateOperationBtnStatus =
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.plsStatus
.updateOperationBtnStatus;
updateOperationBtnStatus("Refresh", true);
const result = await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.retryPlsConnect`
);
if (result.success && result.status === "Retrying") {
updateOperationBtnStatus("Refresh", true, "正在重连");
ipcRenderer.once(
`${IPC_METHOD_BASE}.post.updateRetryStatus`,
async (_evt, _arg) => {
await global.__HUGO_AURA_GLOBAL__.utils.sleep(50);
updateOperationBtnStatus("Refresh", false, "刷新状态");
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.plsStatus.updateStatus();
}
);
} else if (result.success && result.status === "Already") {
updateOperationBtnStatus("Refresh", false, "刷新状态");
}
},
};
const GLOBAL_FUNCTIONS =
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.plsStatus;
const {
updatePlsStatusFromLocal,
} = require(`${REQUIRE_BASE}/../../../composables/plsConfigManager`);
const initBsTooltip = () => {
const tooltipTriggerList = document.querySelectorAll(
'[data-bs-toggle="tooltip"]'
);
const _tooltipList = [...tooltipTriggerList].map(
(tooltipTriggerEl) => new bootstrap.Tooltip(tooltipTriggerEl)
);
};
const updateStatusEl = (
areaContainerId,
areaTextId,
@@ -37,49 +154,13 @@
return true;
};
const updateStatus = async () => {
const curPlsStats = await updatePlsStatusFromLocal();
const acIdInst = "acs-bc-psp-installStatus-container";
const atIdInst = "acs-bc-psp-installStatus-text";
switch (curPlsStats.installed) {
case true:
updateStatusEl(acIdInst, atIdInst, "SUCCESS", "已安装");
break;
case false:
updateStatusEl(acIdInst, atIdInst, "PENDING", "未安装");
}
const acIdLaunch = "acs-bc-psp-launchStatus-container";
const atIdLaunch = "acs-bc-psp-launchStatus-text";
switch (curPlsStats.launched) {
case true:
updateStatusEl(acIdLaunch, atIdLaunch, "SUCCESS", "已启动");
break;
case false:
updateStatusEl(acIdLaunch, atIdLaunch, "PENDING", "未启动");
break;
}
const acIdConn = "acs-bc-psp-connStatus-container";
const atIdConn = "acs-bc-psp-connStatus-text";
switch (curPlsStats.connected) {
case true:
updateStatusEl(acIdConn, atIdConn, "SUCCESS", "已连接");
break;
case false:
updateStatusEl(acIdConn, atIdConn, "FAILED", "连接失败");
break;
}
if (curPlsStats.version && curPlsStats.version !== "未知") {
const versionTextEl = document.getElementById("acs-bc-psp-version-text");
versionTextEl.textContent = "v" + curPlsStats.version;
}
};
const onMounted = () => {
updateStatus();
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false);
initBsTooltip();
GLOBAL_FUNCTIONS.updateStatus();
document.addEventListener("onPLSStatsUpdate", () => {
GLOBAL_FUNCTIONS.updateStatus();
});
};
onMounted();

View File

@@ -9,6 +9,7 @@ const basicSettings = [
id: 0,
categoryName: "可访问性",
child: [
/*
{
index: 0,
id: "authToken",
@@ -18,7 +19,7 @@ const basicSettings = [
description: "选择一个安全的密钥, 用于 PLS 侧验证 Aura 前端身份",
restart: true,
reload: false,
restartPLS: false,
restartPLS: true,
associateVal: null,
auraIf: () => true,
defaultValue: "",
@@ -38,6 +39,39 @@ const basicSettings = [
return { valid: true };
},
},
*/
{
index: 0,
id: "plsListenPort",
type: "input",
subType: "text",
name: "PLS WS 监听端口",
description: "PLS 的 WebSocket 服务器将监听指定的端口",
restart: false,
reload: false,
PLSRequired: true,
restartPLS: true,
associateVal: null,
auraIf: () => true,
defaultValue: "",
placeHolder: "输入端口号 (10000 ~ 65535)",
valueGetter: () => {
if (!global.__HUGO_AURA__.plsSettings) return "";
return global.__HUGO_AURA__.plsSettings.wsPort;
},
callbackFn: (newVal) => {
if (newVal === "" || !newVal)
return { valid: false, hint: "请输入端口号" };
const numberNewVal = Number(newVal);
if (numberNewVal === NaN || !(10000 <= numberNewVal <= 65535)) {
return { valid: false, hint: "请输入合法的端口号 (10000 ~ 65535)" };
}
global.__HUGO_AURA__.plsSettings.wsPort = numberNewVal;
return { valid: true };
},
},
],
},
];