11
This commit is contained in:
37
src-tauri/src/auth_session.rs
Normal file
37
src-tauri/src/auth_session.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//! 与前端 localStorage 会话镜像:通过 `sync_auth_session` 命令更新。
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct AuthUser {
|
||||||
|
pub id: i64,
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
struct Inner {
|
||||||
|
token: String,
|
||||||
|
user: Option<AuthUser>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct AuthSession {
|
||||||
|
inner: Mutex<Inner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthSession {
|
||||||
|
pub fn set(&self, token: String, user: Option<AuthUser>) {
|
||||||
|
let mut g = self.inner.lock().expect("auth session mutex poisoned");
|
||||||
|
g.token = token;
|
||||||
|
g.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn token(&self) -> String {
|
||||||
|
self.inner.lock().expect("auth session mutex poisoned").token.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user(&self) -> Option<AuthUser> {
|
||||||
|
self.inner.lock().expect("auth session mutex poisoned").user.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src-tauri/src/commands/auth.rs
Normal file
12
src-tauri/src/commands/auth.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
use tauri::State;
|
||||||
|
|
||||||
|
use crate::auth_session::{AuthSession, AuthUser};
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn sync_auth_session(
|
||||||
|
session: State<'_, AuthSession>,
|
||||||
|
token: String,
|
||||||
|
user: Option<AuthUser>,
|
||||||
|
) {
|
||||||
|
session.set(token, user);
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
|
pub mod auth;
|
||||||
pub mod quickjs;
|
pub mod quickjs;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod asr;
|
pub mod asr;
|
||||||
|
pub mod auth_session;
|
||||||
pub mod chat;
|
pub mod chat;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod ffmpeg;
|
pub mod ffmpeg;
|
||||||
@@ -13,6 +14,7 @@ pub fn run() {
|
|||||||
let _ = env_logger::try_init();
|
let _ = env_logger::try_init();
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.manage(auth_session::AuthSession::default())
|
||||||
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
let _ = window.unminimize();
|
let _ = window.unminimize();
|
||||||
@@ -22,6 +24,7 @@ pub fn run() {
|
|||||||
}))
|
}))
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
commands::auth::sync_auth_session,
|
||||||
commands::quickjs::run_quickjs_script,
|
commands::quickjs::run_quickjs_script,
|
||||||
commands::quickjs::list_quickjs_scripts,
|
commands::quickjs::list_quickjs_scripts,
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -23,11 +23,13 @@ import Dialog from "primevue/dialog";
|
|||||||
import DashboardCard from "./components/dashboard/DashboardCard.vue";
|
import DashboardCard from "./components/dashboard/DashboardCard.vue";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
|
import { useAuthStore } from "./stores/auth.js";
|
||||||
import "./styles/main.css";
|
import "./styles/main.css";
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
app.use(createPinia());
|
const pinia = createPinia();
|
||||||
|
app.use(pinia);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
app.use(PrimeVue, {
|
app.use(PrimeVue, {
|
||||||
theme: {
|
theme: {
|
||||||
@@ -58,4 +60,6 @@ app.component("TabPanel", TabPanel);
|
|||||||
app.component("DashboardCard", DashboardCard);
|
app.component("DashboardCard", DashboardCard);
|
||||||
app.component("Dialog", Dialog);
|
app.component("Dialog", Dialog);
|
||||||
|
|
||||||
|
useAuthStore(pinia).hydrateRustSession();
|
||||||
|
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
|||||||
@@ -1,9 +1,21 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { loginApi, logoutApi, registerApi } from "../api/auth.js";
|
import { loginApi, logoutApi, registerApi } from "../api/auth.js";
|
||||||
|
|
||||||
const TOKEN_KEY = "aiclient_token";
|
const TOKEN_KEY = "aiclient_token";
|
||||||
const USER_KEY = "aiclient_current_user";
|
const USER_KEY = "aiclient_current_user";
|
||||||
|
|
||||||
|
async function syncAuthSessionToRust(token, user) {
|
||||||
|
try {
|
||||||
|
await invoke("sync_auth_session", {
|
||||||
|
token: token || "",
|
||||||
|
user: user ?? null,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// 浏览器独立预览或未就绪的非 Tauri 环境
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function applyTokenResponse(store, res, fallbackMessage) {
|
function applyTokenResponse(store, res, fallbackMessage) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
return { ok: false, message: res.message || fallbackMessage };
|
return { ok: false, message: res.message || fallbackMessage };
|
||||||
@@ -45,6 +57,7 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
this.currentUser = user;
|
this.currentUser = user;
|
||||||
localStorage.setItem(TOKEN_KEY, accessToken);
|
localStorage.setItem(TOKEN_KEY, accessToken);
|
||||||
localStorage.setItem(USER_KEY, JSON.stringify(user));
|
localStorage.setItem(USER_KEY, JSON.stringify(user));
|
||||||
|
syncAuthSessionToRust(accessToken, user);
|
||||||
},
|
},
|
||||||
|
|
||||||
clearSession() {
|
clearSession() {
|
||||||
@@ -52,6 +65,12 @@ export const useAuthStore = defineStore("auth", {
|
|||||||
this.currentUser = null;
|
this.currentUser = null;
|
||||||
localStorage.removeItem(TOKEN_KEY);
|
localStorage.removeItem(TOKEN_KEY);
|
||||||
localStorage.removeItem(USER_KEY);
|
localStorage.removeItem(USER_KEY);
|
||||||
|
syncAuthSessionToRust("", null);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 将当前内存中的会话同步到 Rust(启动时 localStorage 已恢复后调用) */
|
||||||
|
hydrateRustSession() {
|
||||||
|
syncAuthSessionToRust(this.token, this.currentUser);
|
||||||
},
|
},
|
||||||
|
|
||||||
async register({ username, password, confirmPassword }) {
|
async register({ username, password, confirmPassword }) {
|
||||||
|
|||||||
Reference in New Issue
Block a user