feat: 实现首次登录功能,添加用户名和密码输入,更新状态管理

This commit is contained in:
2025-12-18 03:47:58 +08:00
parent 6e1ffe173a
commit ca1c3706b2
4 changed files with 60 additions and 23 deletions

View File

@@ -1,22 +1,20 @@
import { useEffect } from "react";
import { use, useEffect, useState } from "react";
import { Layout } from "./layout"
import { useStore } from "./store";
export const FirstLogin = () => {
const store = useStore();
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
useEffect(() => {
store.initAdmin();
}, []);
const onClickLogin = async () => {
const accountInput = document.getElementById('account') as HTMLInputElement;
const passwordInput = document.getElementById('password') as HTMLInputElement;
const username = accountInput.value;
const password = passwordInput.value;
const res = await store.login(username, password);
if (res.code === 200) {
window.location.reload();
} else {
alert(res.message || '登录失败');
useEffect(() => {
if (store.username) {
setUsername(store.username);
}
}, [store.username]);
const onClickLogin = async () => {
await store.login(username, password);
}
return (
<Layout>
@@ -27,12 +25,14 @@ export const FirstLogin = () => {
<a className="text-gray-700 mx-1" href="https://kevisual.cn">kevisual</a> "全局设置"
<a className="text-gray-700 mx-1 underline" href="../docs/01-login-first/"></a>
</blockquote>
<div className='space-y-4 mt-8'>
<form className='space-y-4 mt-8'>
<div>
<label htmlFor='account' className='block text-sm font-medium text-gray-900 mb-2'> </label>
<input
type='text'
id='account'
onChange={e => setUsername(e.target.value)}
value={username}
placeholder='请输入账号'
className='w-full px-4 py-2 border-2 border-black bg-white text-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent'
/>
@@ -42,6 +42,8 @@ export const FirstLogin = () => {
<input
type='password'
id='password'
onChange={e => setPassword(e.target.value)}
value={password}
placeholder='请输入密码'
className='w-full px-4 py-2 border-2 border-black bg-white text-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent'
/>
@@ -52,9 +54,25 @@ export const FirstLogin = () => {
className='w-full px-4 py-2 bg-black text-white font-medium hover:bg-gray-800 active:bg-gray-900 transition-colors focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2'>
</button>
</div>
</form>
</div>
</div>
</Layout>
);
}
export const Config = () => {
const store = useStore();
useEffect(() => {
store.initAdmin();
}, []);
return (
<Layout>
<div className="p-4">
<pre className="bg-gray-100 p-4 rounded-lg overflow-x-auto">
{JSON.stringify(store.config, null, 2)}
</pre>
</div>
</Layout>
)
}

View File

@@ -1,31 +1,42 @@
import { query } from '@/modules/query';
import { query, queryLogin } from '@/modules/query';
import { create } from 'zustand';
type SettingState = {
username?: string;
initAdmin: () => any;
login: (username: string, password: string) => any;
config?: any;
}
export const useStore = create<SettingState>((set => ({
username: undefined,
config: undefined,
initAdmin: async () => {
const res = await query.post({
path: 'config'
})
console.log('initAdmin', res);
if (res.code === 200) {
const auth = res.data.auth || {}
if (auth.username) {
set({ username: auth.username });
}
set({ config: res.data });
}
},
login: async (username: string, password: string) => {
const res = await query.post({
path: 'admin',
key: 'login',
data: {
username,
password
}
username,
password
});
if (res.code === 200) {
set({ username });
const setToken = await queryLogin.setLoginToken(res.data)
console.log('setToken', setToken);
}
console.log('login res', res);
return res;
}
})));

View File

@@ -1,5 +1,5 @@
import { Query } from '@kevisual/query'
import { QueryClient, Query } from '@kevisual/query'
import { QueryLoginBrowser } from '@kevisual/query-login'
const getUrl = () => {
const host = window.location.host
const isKevisual = host.includes('kevisual');
@@ -10,6 +10,14 @@ const getUrl = () => {
return '/client/router'
}
export const query = new Query({
export const query = new QueryClient({
url: getUrl()
});
export const remoteQuery = new Query({
url: '/api/router'
});
export const queryLogin = new QueryLoginBrowser({
query: remoteQuery
});

View File

@@ -1,8 +1,8 @@
---
import Html from '@/components/html.astro';
import { FirstLogin } from '@/apps/setting/index.tsx';
import { Config } from '@/apps/setting/index.tsx';
---
<Html>
<FirstLogin client:only />
<Config client:only />
</Html>