mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: 翻新除了配置文件的所有代码了
This commit is contained in:
parent
75e7bc7275
commit
a54f30acc1
136
napcat.webui/src/backend/shell.ts
Normal file
136
napcat.webui/src/backend/shell.ts
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
export class QQLoginManager {
|
||||||
|
private retCredential: string;
|
||||||
|
|
||||||
|
constructor(retCredential: string) {
|
||||||
|
this.retCredential = retCredential;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkQQLoginStatus(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
let QQLoginResponse = await fetch('../api/QQLogin/CheckLoginStatus', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': "Bearer " + this.retCredential,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (QQLoginResponse.status == 200) {
|
||||||
|
let QQLoginResponseJson = await QQLoginResponse.json();
|
||||||
|
if (QQLoginResponseJson.code == 0) {
|
||||||
|
return QQLoginResponseJson.data.isLogin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error checking QQ login status:", error);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkWebUiLogined(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
let LoginResponse = await fetch('../api/auth/check', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': "Bearer " + this.retCredential,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (LoginResponse.status == 200) {
|
||||||
|
let LoginResponseJson = await LoginResponse.json();
|
||||||
|
if (LoginResponseJson.code == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error checking web UI login status:", error);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async loginWithToken(token: string): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
let loginResponse = await fetch('../api/auth/login', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ token: token })
|
||||||
|
});
|
||||||
|
const loginResponseJson = await loginResponse.json();
|
||||||
|
let retCode = loginResponseJson.code;
|
||||||
|
if (retCode === 0) {
|
||||||
|
this.retCredential = loginResponseJson.data.Credential;
|
||||||
|
return this.retCredential;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error logging in with token:", error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getQQLoginQrcode(): Promise<string> {
|
||||||
|
try {
|
||||||
|
let QQLoginResponse = await fetch('../api/QQLogin/GetQQLoginQrcode', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': "Bearer " + this.retCredential,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (QQLoginResponse.status == 200) {
|
||||||
|
let QQLoginResponseJson = await QQLoginResponse.json();
|
||||||
|
if (QQLoginResponseJson.code == 0) {
|
||||||
|
return QQLoginResponseJson.data.qrcode || "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error getting QQ login QR code:", error);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getQQQuickLoginList(): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
let QQLoginResponse = await fetch('../api/QQLogin/GetQuickLoginList', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': "Bearer " + this.retCredential,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (QQLoginResponse.status == 200) {
|
||||||
|
let QQLoginResponseJson = await QQLoginResponse.json();
|
||||||
|
if (QQLoginResponseJson.code == 0) {
|
||||||
|
return QQLoginResponseJson.data || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error getting QQ quick login list:", error);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setQuickLogin(uin: string): Promise<{ result: boolean, errMsg: string }> {
|
||||||
|
try {
|
||||||
|
let QQLoginResponse = await fetch('../api/QQLogin/SetQuickLogin', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': "Bearer " + this.retCredential,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ uin: uin })
|
||||||
|
});
|
||||||
|
if (QQLoginResponse.status == 200) {
|
||||||
|
let QQLoginResponseJson = await QQLoginResponse.json();
|
||||||
|
if (QQLoginResponseJson.code == 0) {
|
||||||
|
return { result: true, errMsg: "" };
|
||||||
|
} else {
|
||||||
|
return { result: false, errMsg: QQLoginResponseJson.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error setting quick login:", error);
|
||||||
|
}
|
||||||
|
return { result: false, errMsg: "接口异常" };
|
||||||
|
}
|
||||||
|
}
|
@ -2,52 +2,41 @@
|
|||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<h2 class="sotheby-font">QQ Login</h2>
|
<h2 class="sotheby-font">QQ Login</h2>
|
||||||
<div class="login-methods">
|
<div class="login-methods">
|
||||||
<t-button id="quick-login" class="login-method" :class="{ active: isQuickLoginVisible }" @click="showQuickLogin">Quick Login</t-button>
|
<t-button id="quick-login" class="login-method" :class="{ active: loginMethod === 'quick' }"
|
||||||
<t-button id="qrcode-login" class="login-method" :class="{ active: isQrCodeVisible }" @click="showQrCodeLogin">QR Code</t-button>
|
@click="loginMethod = 'quick'">Quick Login</t-button>
|
||||||
|
<t-button id="qrcode-login" class="login-method" :class="{ active: loginMethod === 'qrcode' }"
|
||||||
|
@click="loginMethod = 'qrcode'">QR Code</t-button>
|
||||||
</div>
|
</div>
|
||||||
<div id="quick-login-dropdown" class="login-form" v-show="isQuickLoginVisible">
|
<div id="quick-login-dropdown" class="login-form" v-show="loginMethod === 'quick'">
|
||||||
<t-select id="quick-login-select" v-model="selectedAccount" @change="selectAccount">
|
<t-select id="quick-login-select" v-model="selectedAccount" @change="selectAccount"
|
||||||
|
placeholder="Select Account">
|
||||||
<t-option v-for="account in quickLoginList" :key="account" :value="account">{{ account }}</t-option>
|
<t-option v-for="account in quickLoginList" :key="account" :value="account">{{ account }}</t-option>
|
||||||
</t-select>
|
</t-select>
|
||||||
</div>
|
</div>
|
||||||
<div id="qrcode" class="qrcode" v-show="isQrCodeVisible">
|
<div id="qrcode" class="qrcode" v-show="loginMethod === 'qrcode'">
|
||||||
<canvas id="qrcode-canvas"></canvas>
|
<canvas ref="qrcodeCanvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<p id="message">{{ message }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
Power By NapCat.WebUi
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import '../css/style.css';
|
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { Button as TButton, Select as TSelect, Option as TOption, MessagePlugin } from 'tdesign-vue-next';
|
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
|
import { QQLoginManager } from '../backend/shell.ts';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const loginMethod = ref('quick');
|
||||||
const isQuickLoginVisible = ref(true);
|
|
||||||
const isQrCodeVisible = ref(false);
|
|
||||||
const quickLoginList = ref([]);
|
const quickLoginList = ref([]);
|
||||||
const selectedAccount = ref('');
|
const selectedAccount = ref('');
|
||||||
const message = ref('');
|
const qrcodeCanvas = ref(null);
|
||||||
|
const qqLoginManager = new QQLoginManager(localStorage.getItem('auth'));
|
||||||
const showQuickLogin = () => {
|
let heartBeatTimer = null;
|
||||||
isQuickLoginVisible.value = true;
|
|
||||||
isQrCodeVisible.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const showQrCodeLogin = () => {
|
|
||||||
isQuickLoginVisible.value = false;
|
|
||||||
isQrCodeVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectAccount = async (accountName) => {
|
const selectAccount = async (accountName) => {
|
||||||
//const { result, errMsg } = await SetQuickLogin(accountName, localStorage.getItem('auth'));
|
const { result, errMsg } = await qqLoginManager.setQuickLogin(accountName);
|
||||||
if (true) {
|
if (result) {
|
||||||
MessagePlugin.success("登录成功即将跳转");
|
MessagePlugin.success("登录成功即将跳转");
|
||||||
await router.push({ path: '/dashboard/basic-info' });
|
await router.push({ path: '/dashboard/basic-info' });
|
||||||
} else {
|
} else {
|
||||||
@ -62,12 +51,18 @@ const generateQrCode = (data, canvas) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const HeartBeat = async () => {
|
||||||
|
let isLogined = await qqLoginManager.checkQQLoginStatus();
|
||||||
|
if (isLogined) {
|
||||||
|
clearInterval(heartBeatTimer);
|
||||||
|
await router.push({ path: '/dashboard/basic-info' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const InitPages = async () => {
|
const InitPages = async () => {
|
||||||
// let QuickLists = await GetQQQucickLoginList(localStorage.getItem('auth'));
|
quickLoginList.value = await qqLoginManager.getQQQuickLoginList();
|
||||||
quickLoginList.value = ['example1', 'example2', 'example3'];
|
generateQrCode(await qqLoginManager.getQQLoginQrcode(), qrcodeCanvas.value);
|
||||||
// generateQrCode(await GetQQLoginQrcode(localStorage.getItem('auth')), document.querySelector('#qrcode-canvas'));
|
heartBeatTimer = setInterval(HeartBeat, 3000);
|
||||||
generateQrCode('test', document.querySelector('#qrcode-canvas'));
|
|
||||||
setInterval(HeartBeat, 3000);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -22,28 +22,66 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import '../css/style.css';
|
import '../css/style.css';
|
||||||
import '../css/font.css';
|
import '../css/font.css';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref, onMounted } from 'vue';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import { LockOnIcon } from 'tdesign-icons-vue-next';
|
import { LockOnIcon } from 'tdesign-icons-vue-next';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { QQLoginManager } from '../backend/shell';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
token: '',
|
token: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async ({ validateResult, firstError }) => {
|
const handleLoginSuccess = async (credential) => {
|
||||||
if (validateResult === true) {
|
localStorage.setItem('auth', credential);
|
||||||
MessagePlugin.success('登录中...');
|
const loginManager = new QQLoginManager(credential);
|
||||||
await router.push({ path: '/qqlogin' });
|
const isQQLoggedIn = await loginManager.checkQQLoginStatus();
|
||||||
|
if (isQQLoggedIn) {
|
||||||
|
await router.push({ path: '/config' });
|
||||||
} else {
|
} else {
|
||||||
MessagePlugin.error('登录失败');
|
await router.push({ path: '/qqlogin' });
|
||||||
|
}
|
||||||
|
MessagePlugin.success('登录成功');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLoginFailure = (message) => {
|
||||||
|
MessagePlugin.error(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkLoginStatus = async () => {
|
||||||
|
const storedCredential = localStorage.getItem('auth');
|
||||||
|
if (storedCredential) {
|
||||||
|
const loginManager = new QQLoginManager(storedCredential);
|
||||||
|
const isQQLoggedIn = await loginManager.checkQQLoginStatus();
|
||||||
|
if (isQQLoggedIn) {
|
||||||
|
await router.push({ path: '/dashboard/basic-info' });
|
||||||
|
} else {
|
||||||
|
await router.push({ path: '/qqlogin' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
checkLoginStatus();
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async ({ validateResult }) => {
|
||||||
|
if (validateResult === true) {
|
||||||
|
const loginManager = new QQLoginManager('');
|
||||||
|
const credential = await loginManager.loginWithToken(formData.token);
|
||||||
|
if (credential) {
|
||||||
|
await handleLoginSuccess(credential);
|
||||||
|
} else {
|
||||||
|
handleLoginFailure('登录失败,请检查Token');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleLoginFailure('请填写Token');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.login-container {
|
.login-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@ -62,11 +100,6 @@ const onSubmit = async ({ validateResult, firstError }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-message {
|
|
||||||
color: red;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tdesign-demo-block-column {
|
.tdesign-demo-block-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
1
static/assets/index-Cz7mtj1A.css
Normal file
1
static/assets/index-Cz7mtj1A.css
Normal file
File diff suppressed because one or more lines are too long
970
static/assets/index-xw9jld-V.js
Normal file
970
static/assets/index-xw9jld-V.js
Normal file
File diff suppressed because one or more lines are too long
@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + Vue + TS</title>
|
<title>Vite + Vue + TS</title>
|
||||||
<script type="module" crossorigin src="./assets/index-D10_5xOh.js"></script>
|
<script type="module" crossorigin src="./assets/index-xw9jld-V.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-DQOoc4ch.css">
|
<link rel="stylesheet" crossorigin href="./assets/index-Cz7mtj1A.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user