chore: sync current WechatHookBot workspace
This commit is contained in:
165
utils/webui_static/app.js
Normal file
165
utils/webui_static/app.js
Normal file
@@ -0,0 +1,165 @@
|
||||
const { createApp, ref, provide, onMounted, onUnmounted } = Vue;
|
||||
|
||||
const app = createApp({
|
||||
setup() {
|
||||
const api = useApi();
|
||||
const currentPage = ref('log');
|
||||
const authReady = ref(false);
|
||||
const authenticated = ref(false);
|
||||
const authUser = ref('');
|
||||
const loginLoading = ref(false);
|
||||
const loginForm = ref({
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
provide('currentPage', currentPage);
|
||||
|
||||
async function refreshAuthState() {
|
||||
const json = await api.getAuthStatus();
|
||||
if (json) {
|
||||
authenticated.value = !!json.authenticated;
|
||||
authUser.value = json.username || '';
|
||||
if (json.username && !loginForm.value.username) {
|
||||
loginForm.value.username = json.username;
|
||||
}
|
||||
} else {
|
||||
authenticated.value = false;
|
||||
authUser.value = '';
|
||||
}
|
||||
authReady.value = true;
|
||||
}
|
||||
|
||||
async function login() {
|
||||
const username = (loginForm.value.username || '').trim();
|
||||
const password = loginForm.value.password || '';
|
||||
if (!username) {
|
||||
ElementPlus.ElMessage.warning('请输入账号');
|
||||
return;
|
||||
}
|
||||
if (!password) {
|
||||
ElementPlus.ElMessage.warning('请输入密码');
|
||||
return;
|
||||
}
|
||||
|
||||
loginLoading.value = true;
|
||||
const json = await api.login(username, password);
|
||||
loginLoading.value = false;
|
||||
if (!json) return;
|
||||
|
||||
authenticated.value = true;
|
||||
authUser.value = json.username || username;
|
||||
loginForm.value.password = '';
|
||||
currentPage.value = 'log';
|
||||
ElementPlus.ElMessage.success('登录成功');
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
await api.logout();
|
||||
authenticated.value = false;
|
||||
loginForm.value.password = '';
|
||||
currentPage.value = 'log';
|
||||
}
|
||||
|
||||
function handleAuthExpired() {
|
||||
const wasAuthenticated = authenticated.value;
|
||||
authenticated.value = false;
|
||||
loginForm.value.password = '';
|
||||
currentPage.value = 'log';
|
||||
if (wasAuthenticated) {
|
||||
ElementPlus.ElMessage.warning('登录状态已失效,请重新登录');
|
||||
}
|
||||
}
|
||||
|
||||
function handleAuthUpdated(event) {
|
||||
const username = event?.detail?.username;
|
||||
if (username) {
|
||||
authUser.value = username;
|
||||
}
|
||||
}
|
||||
|
||||
function handleLayoutAuthUpdated(username) {
|
||||
if (username) {
|
||||
authUser.value = username;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('webui-auth-required', handleAuthExpired);
|
||||
window.addEventListener('webui-auth-updated', handleAuthUpdated);
|
||||
refreshAuthState();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('webui-auth-required', handleAuthExpired);
|
||||
window.removeEventListener('webui-auth-updated', handleAuthUpdated);
|
||||
});
|
||||
|
||||
return {
|
||||
authReady,
|
||||
authenticated,
|
||||
authUser,
|
||||
loginLoading,
|
||||
loginForm,
|
||||
login,
|
||||
logout,
|
||||
handleLayoutAuthUpdated,
|
||||
};
|
||||
},
|
||||
template: `
|
||||
<div v-if="authReady" class="app-root">
|
||||
<div v-if="!authenticated"
|
||||
class="login-page">
|
||||
<el-card class="login-card">
|
||||
<template #header>
|
||||
<div class="login-title">WechatHookBot 控制台</div>
|
||||
<div class="login-subtitle">Bright Tech UI · 安全登录</div>
|
||||
</template>
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="账号">
|
||||
<el-input
|
||||
v-model="loginForm.username"
|
||||
autocomplete="username"
|
||||
placeholder="请输入账号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input
|
||||
v-model="loginForm.password"
|
||||
show-password
|
||||
autocomplete="current-password"
|
||||
placeholder="请输入密码"
|
||||
@keyup.enter="login" />
|
||||
</el-form-item>
|
||||
<el-button type="primary" :loading="loginLoading" style="width:100%" @click="login">
|
||||
登录
|
||||
</el-button>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<AppLayout
|
||||
v-else
|
||||
:auth-user="authUser"
|
||||
@logout="logout"
|
||||
@auth-updated="handleLayoutAuthUpdated" />
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
||||
app.use(ElementPlus, {
|
||||
locale: ElementPlusLocaleZhCn,
|
||||
});
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component);
|
||||
}
|
||||
|
||||
app.component('AppLayout', window.AppLayout);
|
||||
app.component('LogViewer', window.LogViewer);
|
||||
app.component('ConfigEditor', window.ConfigEditor);
|
||||
app.component('ConfigSection', window.ConfigSection);
|
||||
app.component('PluginList', window.PluginList);
|
||||
app.component('PluginConfigDialog', window.PluginConfigDialog);
|
||||
app.component('SecuritySettings', window.SecuritySettings);
|
||||
|
||||
app.mount('#app');
|
||||
Reference in New Issue
Block a user