diff --git a/web/src/composables/useAuth.ts b/web/src/composables/useAuth.ts new file mode 100644 index 0000000..079092d --- /dev/null +++ b/web/src/composables/useAuth.ts @@ -0,0 +1,114 @@ +const API_BASE = 'http://localhost:8082' + +export interface LoginRequest { + username: string + password: string +} + +export interface RegisterRequest { + username: string + password: string + email?: string +} + +export interface LoginResponse { + token: string + user: any +} + +export const useAuth = () => { + const token = localStorage.getItem('token') + const user = localStorage.getItem('user') + + const login = async (data: LoginRequest): Promise => { + const response = await fetch(`${API_BASE}/auth/login`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + + if (!response.ok) { + const error = await response.json() + throw new Error(error.message || 'Login failed') + } + + const result = await response.json() + + // Save token and user info + localStorage.setItem('token', result.token) + localStorage.setItem('user', JSON.stringify(result.user)) + + return result + } + + const register = async (data: RegisterRequest): Promise => { + const response = await fetch(`${API_BASE}/auth/register`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + + if (!response.ok) { + const error = await response.json() + throw new Error(error.message || 'Registration failed') + } + + return await response.json() + } + + const logout = () => { + localStorage.removeItem('token') + localStorage.removeItem('user') + } + + const getToken = () => { + return localStorage.getItem('token') + } + + const getUser = () => { + const userStr = localStorage.getItem('user') + return userStr ? JSON.parse(userStr) : null + } + + const isLoggedIn = () => { + return !!token + } + + const getCurrentUser = async () => { + const token = localStorage.getItem('token') + if (!token) { + throw new Error('Not authenticated') + } + + const response = await fetch(`${API_BASE}/auth/me`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + }) + + if (!response.ok) { + const error = await response.json() + throw new Error(error.message || 'Failed to get user') + } + + const user = await response.json() + localStorage.setItem('user', JSON.stringify(user)) + return user + } + + return { + login, + register, + logout, + getToken, + getUser, + isLoggedIn, + getCurrentUser, + } +} diff --git a/web/src/views/Login.vue b/web/src/views/Login.vue index 531d479..68dc3ce 100644 --- a/web/src/views/Login.vue +++ b/web/src/views/Login.vue @@ -1,8 +1,11 @@ @@ -52,6 +70,12 @@ const handleLogin = () => {
+ +
+ + {{ successMsg }} +
+
diff --git a/web/src/views/Signup.vue b/web/src/views/Signup.vue index ee70b9b..96ade61 100644 --- a/web/src/views/Signup.vue +++ b/web/src/views/Signup.vue @@ -1,8 +1,10 @@ @@ -87,6 +98,12 @@ const goToLogin = () => {
+ +
+ + {{ successMsg }} +
+
diff --git a/web/src/views/tools/useTools.ts b/web/src/views/tools/useTools.ts new file mode 100644 index 0000000..18a1cd1 --- /dev/null +++ b/web/src/views/tools/useTools.ts @@ -0,0 +1,146 @@ +const API_BASE = 'http://localhost:8082' + +// Tool 接口 +export interface Tool { + id: string + name: string + description: string + category: string + provider: string + security_level: string + require_approval: boolean + parameters: string + status: string + created_at?: string + updated_at?: string +} + +export function useTools() { + const tools = ref([]) + const toolsLoading = ref(false) + + // 获取工具列表 + const fetchTools = async (category?: string, status?: string) => { + toolsLoading.value = true + try { + let url = `${API_BASE}/tool/list?` + if (category) url += `category=${category}&` + if (status) url += `status=${status}&` + + const response = await fetch(url) + const data = await response.json() + + if (data.list) { + tools.value = data.list + } + return data.list || [] + } catch (error) { + console.error('Failed to fetch tools:', error) + return [] + } finally { + toolsLoading.value = false + } + } + + // 同步工具到数据库 + const syncTools = async () => { + try { + const response = await fetch(`${API_BASE}/tool/sync`) + const data = await response.json() + await fetchTools() // 重新获取列表 + return data + } catch (error) { + console.error('Failed to sync tools:', error) + throw error + } + } + + // 获取工具详情 + const fetchToolById = async (id: string) => { + try { + const response = await fetch(`${API_BASE}/tool/${id}`) + const data = await response.json() + return data.tool + } catch (error) { + console.error('Failed to fetch tool:', error) + throw error + } + } + + // 创建工具 + const createTool = async (tool: Partial) => { + try { + const response = await fetch(`${API_BASE}/tool/add`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(tool), + }) + const data = await response.json() + await fetchTools() // 重新获取列表 + return data + } catch (error) { + console.error('Failed to create tool:', error) + throw error + } + } + + // 更新工具 + const updateTool = async (id: string, tool: Partial) => { + try { + const response = await fetch(`${API_BASE}/tool/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(tool), + }) + const data = await response.json() + await fetchTools() // 重新获取列表 + return data + } catch (error) { + console.error('Failed to update tool:', error) + throw error + } + } + + // 删除工具 + const deleteTool = async (id: string) => { + try { + const response = await fetch(`${API_BASE}/tool/${id}`, { + method: 'DELETE', + }) + const data = await response.json() + await fetchTools() // 重新获取列表 + return data + } catch (error) { + console.error('Failed to delete tool:', error) + throw error + } + } + + // 按分类获取工具 + const getToolsByCategory = (category: string) => { + return tools.value.filter(tool => tool.category === category) + } + + // 获取所有分类 + const categories = computed(() => { + const cats = new Set(tools.value.map(tool => tool.category)) + return Array.from(cats) + }) + + return { + tools, + toolsLoading, + categories, + fetchTools, + syncTools, + fetchToolById, + createTool, + updateTool, + deleteTool, + getToolsByCategory, + } +}