1
This commit is contained in:
101
src/stores/auth.js
Normal file
101
src/stores/auth.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
const USERS_KEY = "aiclient_users";
|
||||
const TOKEN_KEY = "aiclient_token";
|
||||
const USER_KEY = "aiclient_current_user";
|
||||
|
||||
function loadUsers() {
|
||||
try {
|
||||
const raw = localStorage.getItem(USERS_KEY);
|
||||
return raw ? JSON.parse(raw) : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function saveUsers(users) {
|
||||
localStorage.setItem(USERS_KEY, JSON.stringify(users));
|
||||
}
|
||||
|
||||
function createToken(username) {
|
||||
return btoa(`${username}:${Date.now()}`);
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore("auth", {
|
||||
state: () => ({
|
||||
token: localStorage.getItem(TOKEN_KEY) || "",
|
||||
currentUser: (() => {
|
||||
try {
|
||||
const raw = localStorage.getItem(USER_KEY);
|
||||
return raw ? JSON.parse(raw) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
}),
|
||||
|
||||
getters: {
|
||||
isAuthenticated: (state) => Boolean(state.token),
|
||||
},
|
||||
|
||||
actions: {
|
||||
register({ username, password, confirmPassword }) {
|
||||
const name = username?.trim();
|
||||
if (!name || !password) {
|
||||
return { ok: false, message: "用户名和密码不能为空" };
|
||||
}
|
||||
if (password !== confirmPassword) {
|
||||
return { ok: false, message: "两次输入的密码不一致" };
|
||||
}
|
||||
if (password.length < 6) {
|
||||
return { ok: false, message: "密码长度至少为 6 位" };
|
||||
}
|
||||
|
||||
const users = loadUsers();
|
||||
if (users.some((u) => u.username === name)) {
|
||||
return { ok: false, message: "用户名已存在" };
|
||||
}
|
||||
|
||||
users.push({ username: name, password });
|
||||
saveUsers(users);
|
||||
|
||||
return this.login({ username: name, password });
|
||||
},
|
||||
|
||||
login({ username, password }) {
|
||||
const name = username?.trim();
|
||||
if (!name || !password) {
|
||||
return { ok: false, message: "用户名和密码不能为空" };
|
||||
}
|
||||
|
||||
const users = loadUsers();
|
||||
const user = users.find((u) => u.username === name);
|
||||
if (!user || user.password !== password) {
|
||||
return { ok: false, message: "用户名或密码错误" };
|
||||
}
|
||||
|
||||
const token = createToken(name);
|
||||
const currentUser = { username: name };
|
||||
|
||||
this.token = token;
|
||||
this.currentUser = currentUser;
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(currentUser));
|
||||
|
||||
return { ok: true, message: "登录成功" };
|
||||
},
|
||||
|
||||
logout() {
|
||||
this.token = "";
|
||||
this.currentUser = null;
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
localStorage.removeItem(USER_KEY);
|
||||
return { ok: true, message: "已退出登录" };
|
||||
},
|
||||
|
||||
// 预留:后续对接 Tauri invoke / HTTP API
|
||||
async loginWithApi(_credentials) {
|
||||
return { ok: false, message: "API 登录尚未实现" };
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user