- 添加API客户端、加密存储和provision/token激活逻辑 - WebSocket改用Bearer令牌认证,移除REGISTER请求 - 设备ID改为服务端下发,支持令牌刷新和强制下线处理 - 新增deviceSecret加密存储和accessToken自动刷新 - 更新设备ID获取方式为出厂SN,添加安全存储依赖
104 lines
3.9 KiB
Vue
104 lines
3.9 KiB
Vue
<script setup>
|
||
import { ref } from 'vue';
|
||
import { store, login, register, connectSignaling } from '../store/controllerStore';
|
||
|
||
const username = ref('');
|
||
const password = ref('');
|
||
const showRegister = ref(false);
|
||
const regUsername = ref('');
|
||
const regPassword = ref('');
|
||
const regBusy = ref(false);
|
||
const regError = ref('');
|
||
|
||
async function onLogin() {
|
||
const ok = await login(username.value.trim(), password.value);
|
||
if (ok) {
|
||
await connectSignaling();
|
||
}
|
||
}
|
||
|
||
async function onRegister() {
|
||
regError.value = '';
|
||
regBusy.value = true;
|
||
try {
|
||
await register({ username: regUsername.value.trim(), password: regPassword.value });
|
||
// 注册成功后直接登录并连接。
|
||
username.value = regUsername.value.trim();
|
||
password.value = regPassword.value;
|
||
showRegister.value = false;
|
||
await onLogin();
|
||
} catch (e) {
|
||
regError.value = e.message || '注册失败';
|
||
} finally {
|
||
regBusy.value = false;
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="login-mask">
|
||
<div class="login-card">
|
||
<div class="login-brand">WebRTC 网页远程控制</div>
|
||
<div class="login-sub">登录后才能连接信令服务器并发起远程控制</div>
|
||
|
||
<form v-if="!showRegister" class="login-form" @submit.prevent="onLogin">
|
||
<label>用户名
|
||
<input v-model="username" type="text" autocomplete="username" placeholder="请输入用户名" />
|
||
</label>
|
||
<label>密码
|
||
<input v-model="password" type="password" autocomplete="current-password" placeholder="请输入密码" />
|
||
</label>
|
||
<p v-if="store.loginError" class="login-err">{{ store.loginError }}</p>
|
||
<button class="btn primary" type="submit" :disabled="store.loginBusy">
|
||
{{ store.loginBusy ? '登录中…' : '登录' }}
|
||
</button>
|
||
<button class="btn link" type="button" @click="showRegister = true">没有账号?注册</button>
|
||
</form>
|
||
|
||
<form v-else class="login-form" @submit.prevent="onRegister">
|
||
<label>用户名
|
||
<input v-model="regUsername" type="text" autocomplete="username" placeholder="设置用户名" />
|
||
</label>
|
||
<label>密码
|
||
<input v-model="regPassword" type="password" autocomplete="new-password" placeholder="设置密码(至少12位,含大小写/数字/特殊字符)" />
|
||
</label>
|
||
<p v-if="regError" class="login-err">{{ regError }}</p>
|
||
<button class="btn primary" type="submit" :disabled="regBusy">
|
||
{{ regBusy ? '注册中…' : '注册并登录' }}
|
||
</button>
|
||
<button class="btn link" type="button" @click="showRegister = false">返回登录</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.login-mask {
|
||
position: fixed; inset: 0;
|
||
display: flex; align-items: center; justify-content: center;
|
||
background: radial-gradient(circle at 30% 20%, #1e293b, #0f172a 70%);
|
||
}
|
||
.login-card {
|
||
width: 360px; padding: 32px;
|
||
background: #1e293b; border: 1px solid #334155; border-radius: 16px;
|
||
box-shadow: 0 20px 60px rgba(0,0,0,.45); color: #e2e8f0;
|
||
}
|
||
.login-brand { font-size: 20px; font-weight: 700; color: #38bdf8; }
|
||
.login-sub { margin: 8px 0 20px; font-size: 13px; color: #94a3b8; }
|
||
.login-form { display: flex; flex-direction: column; gap: 14px; }
|
||
.login-form label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: #cbd5e1; }
|
||
.login-form input {
|
||
padding: 10px 12px; border-radius: 8px; border: 1px solid #334155;
|
||
background: #0f172a; color: #e2e8f0; font-size: 14px;
|
||
}
|
||
.login-form input:focus { outline: none; border-color: #38bdf8; }
|
||
.login-err { color: #f87171; font-size: 13px; margin: 0; }
|
||
.btn.primary {
|
||
padding: 11px; border: none; border-radius: 8px; cursor: pointer;
|
||
background: #38bdf8; color: #0f172a; font-weight: 600; font-size: 14px;
|
||
}
|
||
.btn.primary:disabled { opacity: .6; cursor: default; }
|
||
.btn.link { background: none; border: none; color: #94a3b8; cursor: pointer; font-size: 13px; }
|
||
.btn.link:hover { color: #38bdf8; }
|
||
</style>
|