@qhr123/sa2kit 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/auth/index.d.mts +104 -0
- package/dist/auth/index.d.ts +104 -0
- package/dist/auth/index.js +186 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +183 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/chunk-TLXAIOXP.js +476 -0
- package/dist/chunk-TLXAIOXP.js.map +1 -0
- package/dist/chunk-WUTGV44D.mjs +466 -0
- package/dist/chunk-WUTGV44D.mjs.map +1 -0
- package/dist/config/index.d.mts +64 -0
- package/dist/config/index.d.ts +64 -0
- package/dist/config/index.js +136 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +128 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/i18n/index.d.mts +5 -5
- package/dist/i18n/index.d.ts +5 -5
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/index.mjs +2 -2
- package/dist/i18n/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +29 -6
- package/dist/index.mjs +1 -2
- package/dist/storage/index.d.mts +162 -3
- package/dist/storage/index.d.ts +162 -3
- package/dist/storage/index.js +34 -2
- package/dist/storage/index.mjs +1 -1
- package/package.json +23 -7
- package/dist/chunk-3R73CUAY.js +0 -80
- package/dist/chunk-3R73CUAY.js.map +0 -1
- package/dist/chunk-4JTIYLS6.js +0 -88
- package/dist/chunk-4JTIYLS6.js.map +0 -1
- package/dist/chunk-C7VOMO3L.mjs +0 -77
- package/dist/chunk-C7VOMO3L.mjs.map +0 -1
- package/dist/chunk-M7CA3DTF.mjs +0 -86
- package/dist/chunk-M7CA3DTF.mjs.map +0 -1
- package/dist/hooks/index.d.mts +0 -30
- package/dist/hooks/index.d.ts +0 -30
- package/dist/hooks/index.js +0 -18
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/index.mjs +0 -5
- package/dist/hooks/index.mjs.map +0 -1
- package/dist/types-BaZccpvk.d.mts +0 -48
- package/dist/types-BaZccpvk.d.ts +0 -48
package/README.md
CHANGED
|
@@ -194,7 +194,7 @@ import { LanguageSwitcher } from '@qhr123/sa2kit/i18n';
|
|
|
194
194
|
<LanguageSwitcher variant="icon" />
|
|
195
195
|
|
|
196
196
|
// With custom className and callback
|
|
197
|
-
<LanguageSwitcher
|
|
197
|
+
<LanguageSwitcher
|
|
198
198
|
variant="buttons"
|
|
199
199
|
className="my-custom-class"
|
|
200
200
|
onLanguageChange={(locale) => {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth 模块类型定义
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 用户基础信息
|
|
8
|
+
*/
|
|
9
|
+
interface User {
|
|
10
|
+
id: string;
|
|
11
|
+
email: string;
|
|
12
|
+
username: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* API 客户端基础接口
|
|
17
|
+
*/
|
|
18
|
+
interface BaseApiClient {
|
|
19
|
+
isAuthenticated(): Promise<boolean>;
|
|
20
|
+
getCurrentUser(): Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
data?: User;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
login(email: string, password: string): Promise<{
|
|
26
|
+
success: boolean;
|
|
27
|
+
data?: {
|
|
28
|
+
user: User;
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}>;
|
|
32
|
+
register(email: string, password: string, username: string): Promise<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
data?: {
|
|
35
|
+
user: User;
|
|
36
|
+
};
|
|
37
|
+
error?: string;
|
|
38
|
+
}>;
|
|
39
|
+
logout(): Promise<void>;
|
|
40
|
+
clearUserData(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 登录表单数据接口
|
|
44
|
+
*/
|
|
45
|
+
interface LoginFormData {
|
|
46
|
+
email: string;
|
|
47
|
+
password: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 注册表单数据接口
|
|
51
|
+
*/
|
|
52
|
+
interface RegisterFormData {
|
|
53
|
+
email: string;
|
|
54
|
+
password: string;
|
|
55
|
+
username: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 认证操作结果接口
|
|
59
|
+
*/
|
|
60
|
+
interface AuthResult {
|
|
61
|
+
success: boolean;
|
|
62
|
+
error?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* useAuth Hook 返回值接口
|
|
66
|
+
*/
|
|
67
|
+
interface UseAuthReturn {
|
|
68
|
+
user: User | null;
|
|
69
|
+
isLoggedIn: boolean;
|
|
70
|
+
loading: boolean;
|
|
71
|
+
checkingAuth: boolean;
|
|
72
|
+
error: string | null;
|
|
73
|
+
login: (email: string, password: string) => Promise<AuthResult>;
|
|
74
|
+
register: (email: string, password: string, username: string) => Promise<AuthResult>;
|
|
75
|
+
logout: () => Promise<void>;
|
|
76
|
+
refresh: () => Promise<void>;
|
|
77
|
+
clearError: () => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
|
|
81
|
+
/**
|
|
82
|
+
* 表单验证 Hook
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
|
|
87
|
+
* email: '',
|
|
88
|
+
* password: ''
|
|
89
|
+
* })
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
|
|
93
|
+
values: T;
|
|
94
|
+
errors: Partial<Record<keyof T, string>>;
|
|
95
|
+
touched: Partial<Record<keyof T, boolean>>;
|
|
96
|
+
handleChange: (field: keyof T, value: any) => void;
|
|
97
|
+
handleBlur: (field: keyof T) => void;
|
|
98
|
+
validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
|
|
99
|
+
reset: () => void;
|
|
100
|
+
setValues: React.Dispatch<React.SetStateAction<T>>;
|
|
101
|
+
setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export { type AuthResult, type BaseApiClient, type LoginFormData, type RegisterFormData, type UseAuthReturn, type User, useAuth, useAuthForm };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth 模块类型定义
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 用户基础信息
|
|
8
|
+
*/
|
|
9
|
+
interface User {
|
|
10
|
+
id: string;
|
|
11
|
+
email: string;
|
|
12
|
+
username: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* API 客户端基础接口
|
|
17
|
+
*/
|
|
18
|
+
interface BaseApiClient {
|
|
19
|
+
isAuthenticated(): Promise<boolean>;
|
|
20
|
+
getCurrentUser(): Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
data?: User;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
login(email: string, password: string): Promise<{
|
|
26
|
+
success: boolean;
|
|
27
|
+
data?: {
|
|
28
|
+
user: User;
|
|
29
|
+
};
|
|
30
|
+
error?: string;
|
|
31
|
+
}>;
|
|
32
|
+
register(email: string, password: string, username: string): Promise<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
data?: {
|
|
35
|
+
user: User;
|
|
36
|
+
};
|
|
37
|
+
error?: string;
|
|
38
|
+
}>;
|
|
39
|
+
logout(): Promise<void>;
|
|
40
|
+
clearUserData(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 登录表单数据接口
|
|
44
|
+
*/
|
|
45
|
+
interface LoginFormData {
|
|
46
|
+
email: string;
|
|
47
|
+
password: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 注册表单数据接口
|
|
51
|
+
*/
|
|
52
|
+
interface RegisterFormData {
|
|
53
|
+
email: string;
|
|
54
|
+
password: string;
|
|
55
|
+
username: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 认证操作结果接口
|
|
59
|
+
*/
|
|
60
|
+
interface AuthResult {
|
|
61
|
+
success: boolean;
|
|
62
|
+
error?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* useAuth Hook 返回值接口
|
|
66
|
+
*/
|
|
67
|
+
interface UseAuthReturn {
|
|
68
|
+
user: User | null;
|
|
69
|
+
isLoggedIn: boolean;
|
|
70
|
+
loading: boolean;
|
|
71
|
+
checkingAuth: boolean;
|
|
72
|
+
error: string | null;
|
|
73
|
+
login: (email: string, password: string) => Promise<AuthResult>;
|
|
74
|
+
register: (email: string, password: string, username: string) => Promise<AuthResult>;
|
|
75
|
+
logout: () => Promise<void>;
|
|
76
|
+
refresh: () => Promise<void>;
|
|
77
|
+
clearError: () => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare function useAuth(apiClient: BaseApiClient): UseAuthReturn;
|
|
81
|
+
/**
|
|
82
|
+
* 表单验证 Hook
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const { values, errors, handleChange, handleBlur, validate } = useAuthForm({
|
|
87
|
+
* email: '',
|
|
88
|
+
* password: ''
|
|
89
|
+
* })
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare function useAuthForm<T extends Record<string, any>>(initialValues: T): {
|
|
93
|
+
values: T;
|
|
94
|
+
errors: Partial<Record<keyof T, string>>;
|
|
95
|
+
touched: Partial<Record<keyof T, boolean>>;
|
|
96
|
+
handleChange: (field: keyof T, value: any) => void;
|
|
97
|
+
handleBlur: (field: keyof T) => void;
|
|
98
|
+
validate: (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => boolean;
|
|
99
|
+
reset: () => void;
|
|
100
|
+
setValues: React.Dispatch<React.SetStateAction<T>>;
|
|
101
|
+
setErrors: React.Dispatch<React.SetStateAction<Partial<Record<keyof T, string>>>>;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export { type AuthResult, type BaseApiClient, type LoginFormData, type RegisterFormData, type UseAuthReturn, type User, useAuth, useAuthForm };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../chunk-DGUM43GV.js');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
function useAuth(apiClient) {
|
|
7
|
+
const [user, setUser] = react.useState(null);
|
|
8
|
+
const [isLoggedIn, setIsLoggedIn] = react.useState(false);
|
|
9
|
+
const [loading, setLoading] = react.useState(false);
|
|
10
|
+
const [checkingAuth, setCheckingAuth] = react.useState(true);
|
|
11
|
+
const [error, setError] = react.useState(null);
|
|
12
|
+
const checkAuthStatus = react.useCallback(async () => {
|
|
13
|
+
try {
|
|
14
|
+
setCheckingAuth(true);
|
|
15
|
+
setError(null);
|
|
16
|
+
const isAuth = await apiClient.isAuthenticated();
|
|
17
|
+
if (isAuth) {
|
|
18
|
+
const response = await apiClient.getCurrentUser();
|
|
19
|
+
if (response.success && response.data) {
|
|
20
|
+
setUser(response.data);
|
|
21
|
+
setIsLoggedIn(true);
|
|
22
|
+
} else {
|
|
23
|
+
await apiClient.clearUserData();
|
|
24
|
+
setUser(null);
|
|
25
|
+
setIsLoggedIn(false);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
setUser(null);
|
|
29
|
+
setIsLoggedIn(false);
|
|
30
|
+
}
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
|
|
33
|
+
setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
|
|
34
|
+
setUser(null);
|
|
35
|
+
setIsLoggedIn(false);
|
|
36
|
+
} finally {
|
|
37
|
+
setCheckingAuth(false);
|
|
38
|
+
}
|
|
39
|
+
}, [apiClient]);
|
|
40
|
+
const login = react.useCallback(
|
|
41
|
+
async (email, password) => {
|
|
42
|
+
setLoading(true);
|
|
43
|
+
setError(null);
|
|
44
|
+
try {
|
|
45
|
+
const response = await apiClient.login(email, password);
|
|
46
|
+
if (response.success && response.data) {
|
|
47
|
+
setUser(response.data.user);
|
|
48
|
+
setIsLoggedIn(true);
|
|
49
|
+
return { success: true };
|
|
50
|
+
} else {
|
|
51
|
+
const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
|
|
52
|
+
setError(errorMsg);
|
|
53
|
+
return { success: false, error: errorMsg };
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
57
|
+
setError(errorMsg);
|
|
58
|
+
return { success: false, error: errorMsg };
|
|
59
|
+
} finally {
|
|
60
|
+
setLoading(false);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
[apiClient]
|
|
64
|
+
);
|
|
65
|
+
const register = react.useCallback(
|
|
66
|
+
async (email, password, username) => {
|
|
67
|
+
setLoading(true);
|
|
68
|
+
setError(null);
|
|
69
|
+
try {
|
|
70
|
+
const response = await apiClient.register(email, password, username);
|
|
71
|
+
if (response.success && response.data) {
|
|
72
|
+
setUser(response.data.user);
|
|
73
|
+
setIsLoggedIn(true);
|
|
74
|
+
return { success: true };
|
|
75
|
+
} else {
|
|
76
|
+
const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
|
|
77
|
+
setError(errorMsg);
|
|
78
|
+
return { success: false, error: errorMsg };
|
|
79
|
+
}
|
|
80
|
+
} catch (err) {
|
|
81
|
+
const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
82
|
+
setError(errorMsg);
|
|
83
|
+
return { success: false, error: errorMsg };
|
|
84
|
+
} finally {
|
|
85
|
+
setLoading(false);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
[apiClient]
|
|
89
|
+
);
|
|
90
|
+
const logout = react.useCallback(async () => {
|
|
91
|
+
setLoading(true);
|
|
92
|
+
setError(null);
|
|
93
|
+
try {
|
|
94
|
+
await apiClient.logout();
|
|
95
|
+
setUser(null);
|
|
96
|
+
setIsLoggedIn(false);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.error("\u767B\u51FA\u5931\u8D25:", err);
|
|
99
|
+
setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
|
|
100
|
+
setUser(null);
|
|
101
|
+
setIsLoggedIn(false);
|
|
102
|
+
} finally {
|
|
103
|
+
setLoading(false);
|
|
104
|
+
}
|
|
105
|
+
}, [apiClient]);
|
|
106
|
+
const clearError = react.useCallback(() => {
|
|
107
|
+
setError(null);
|
|
108
|
+
}, []);
|
|
109
|
+
react.useEffect(() => {
|
|
110
|
+
checkAuthStatus();
|
|
111
|
+
}, [checkAuthStatus]);
|
|
112
|
+
return {
|
|
113
|
+
// 状态
|
|
114
|
+
user,
|
|
115
|
+
isLoggedIn,
|
|
116
|
+
loading,
|
|
117
|
+
checkingAuth,
|
|
118
|
+
error,
|
|
119
|
+
// 操作方法
|
|
120
|
+
login,
|
|
121
|
+
register,
|
|
122
|
+
logout,
|
|
123
|
+
refresh: checkAuthStatus,
|
|
124
|
+
clearError
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function useAuthForm(initialValues) {
|
|
128
|
+
const [values, setValues] = react.useState(initialValues);
|
|
129
|
+
const [errors, setErrors] = react.useState({});
|
|
130
|
+
const [touched, setTouched] = react.useState({});
|
|
131
|
+
const handleChange = react.useCallback(
|
|
132
|
+
(field, value) => {
|
|
133
|
+
setValues((prev) => ({ ...prev, [field]: value }));
|
|
134
|
+
if (errors[field]) {
|
|
135
|
+
setErrors((prev) => {
|
|
136
|
+
const newErrors = { ...prev };
|
|
137
|
+
delete newErrors[field];
|
|
138
|
+
return newErrors;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
[errors]
|
|
143
|
+
);
|
|
144
|
+
const handleBlur = react.useCallback((field) => {
|
|
145
|
+
setTouched((prev) => ({ ...prev, [field]: true }));
|
|
146
|
+
}, []);
|
|
147
|
+
const validate = react.useCallback(
|
|
148
|
+
(validationRules) => {
|
|
149
|
+
const newErrors = {};
|
|
150
|
+
Object.keys(validationRules).forEach((key) => {
|
|
151
|
+
const field = key;
|
|
152
|
+
const rule = validationRules[field];
|
|
153
|
+
if (rule) {
|
|
154
|
+
const error = rule(values[field]);
|
|
155
|
+
if (error) {
|
|
156
|
+
newErrors[field] = error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
setErrors(newErrors);
|
|
161
|
+
return Object.keys(newErrors).length === 0;
|
|
162
|
+
},
|
|
163
|
+
[values]
|
|
164
|
+
);
|
|
165
|
+
const reset = react.useCallback(() => {
|
|
166
|
+
setValues(initialValues);
|
|
167
|
+
setErrors({});
|
|
168
|
+
setTouched({});
|
|
169
|
+
}, [initialValues]);
|
|
170
|
+
return {
|
|
171
|
+
values,
|
|
172
|
+
errors,
|
|
173
|
+
touched,
|
|
174
|
+
handleChange,
|
|
175
|
+
handleBlur,
|
|
176
|
+
validate,
|
|
177
|
+
reset,
|
|
178
|
+
setValues,
|
|
179
|
+
setErrors
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
exports.useAuth = useAuth;
|
|
184
|
+
exports.useAuthForm = useAuthForm;
|
|
185
|
+
//# sourceMappingURL=index.js.map
|
|
186
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/auth/hooks/useAuth.ts"],"names":["useState","useCallback","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { User, BaseApiClient, AuthResult, UseAuthReturn } from '../types';\n\nexport type { User, BaseApiClient, AuthResult, UseAuthReturn };\n\nexport function useAuth(apiClient: BaseApiClient): UseAuthReturn {\n const [user, setUser] = useState<User | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [loading, setLoading] = useState(false);\n const [checkingAuth, setCheckingAuth] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * 检查认证状态\n */\n const checkAuthStatus = useCallback(async () => {\n try {\n setCheckingAuth(true);\n setError(null);\n\n const isAuth = await apiClient.isAuthenticated();\n\n if (isAuth) {\n // 验证 token 并获取用户信息\n const response = await apiClient.getCurrentUser();\n\n if (response.success && response.data) {\n setUser(response.data);\n setIsLoggedIn(true);\n } else {\n // Token 无效,清除登录状态\n await apiClient.clearUserData();\n setUser(null);\n setIsLoggedIn(false);\n }\n } else {\n setUser(null);\n setIsLoggedIn(false);\n }\n } catch (err) {\n console.error('检查登录状态失败:', err);\n setError(err instanceof Error ? err.message : '检查登录状态失败');\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setCheckingAuth(false);\n }\n }, [apiClient]);\n\n /**\n * 用户登录\n */\n const login = useCallback(\n async (email: string, password: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.login(email, password);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '登录失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '登录失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户注册\n */\n const register = useCallback(\n async (email: string, password: string, username: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.register(email, password, username);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '注册失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '注册失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户登出\n */\n const logout = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n await apiClient.logout();\n setUser(null);\n setIsLoggedIn(false);\n } catch (err) {\n console.error('登出失败:', err);\n setError(err instanceof Error ? err.message : '登出失败');\n // 即使登出失败,也清除本地状态\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setLoading(false);\n }\n }, [apiClient]);\n\n /**\n * 清除错误信息\n */\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n // 组件挂载时检查认证状态\n useEffect(() => {\n checkAuthStatus();\n }, [checkAuthStatus]);\n\n return {\n // 状态\n user,\n isLoggedIn,\n loading,\n checkingAuth,\n error,\n\n // 操作方法\n login,\n register,\n logout,\n refresh: checkAuthStatus,\n clearError,\n };\n}\n\n/**\n * 表单验证 Hook\n *\n * @example\n * ```typescript\n * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({\n * email: '',\n * password: ''\n * })\n * ```\n */\nexport function useAuthForm<T extends Record<string, any>>(initialValues: T) {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});\n const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});\n\n const handleChange = useCallback(\n (field: keyof T, value: any) => {\n setValues((prev: T) => ({ ...prev, [field]: value }));\n // 清除该字段的错误\n if (errors[field]) {\n setErrors((prev: Partial<Record<keyof T, string>>) => {\n const newErrors = { ...prev };\n delete newErrors[field];\n return newErrors;\n });\n }\n },\n [errors]\n );\n\n const handleBlur = useCallback((field: keyof T) => {\n setTouched((prev: Partial<Record<keyof T, boolean>>) => ({ ...prev, [field]: true }));\n }, []);\n\n const validate = useCallback(\n (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => {\n const newErrors: Partial<Record<keyof T, string>> = {};\n\n Object.keys(validationRules).forEach((key) => {\n const field = key as keyof T;\n const rule = validationRules[field];\n if (rule) {\n const error = rule(values[field]);\n if (error) {\n newErrors[field] = error;\n }\n }\n });\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n },\n [values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setTouched({});\n }, [initialValues]);\n\n return {\n values,\n errors,\n touched,\n handleChange,\n handleBlur,\n validate,\n reset,\n setValues,\n setErrors,\n };\n}\n\n"]}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import '../chunk-BJTO5JO5.mjs';
|
|
2
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
function useAuth(apiClient) {
|
|
5
|
+
const [user, setUser] = useState(null);
|
|
6
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
const [checkingAuth, setCheckingAuth] = useState(true);
|
|
9
|
+
const [error, setError] = useState(null);
|
|
10
|
+
const checkAuthStatus = useCallback(async () => {
|
|
11
|
+
try {
|
|
12
|
+
setCheckingAuth(true);
|
|
13
|
+
setError(null);
|
|
14
|
+
const isAuth = await apiClient.isAuthenticated();
|
|
15
|
+
if (isAuth) {
|
|
16
|
+
const response = await apiClient.getCurrentUser();
|
|
17
|
+
if (response.success && response.data) {
|
|
18
|
+
setUser(response.data);
|
|
19
|
+
setIsLoggedIn(true);
|
|
20
|
+
} else {
|
|
21
|
+
await apiClient.clearUserData();
|
|
22
|
+
setUser(null);
|
|
23
|
+
setIsLoggedIn(false);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
setUser(null);
|
|
27
|
+
setIsLoggedIn(false);
|
|
28
|
+
}
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25:", err);
|
|
31
|
+
setError(err instanceof Error ? err.message : "\u68C0\u67E5\u767B\u5F55\u72B6\u6001\u5931\u8D25");
|
|
32
|
+
setUser(null);
|
|
33
|
+
setIsLoggedIn(false);
|
|
34
|
+
} finally {
|
|
35
|
+
setCheckingAuth(false);
|
|
36
|
+
}
|
|
37
|
+
}, [apiClient]);
|
|
38
|
+
const login = useCallback(
|
|
39
|
+
async (email, password) => {
|
|
40
|
+
setLoading(true);
|
|
41
|
+
setError(null);
|
|
42
|
+
try {
|
|
43
|
+
const response = await apiClient.login(email, password);
|
|
44
|
+
if (response.success && response.data) {
|
|
45
|
+
setUser(response.data.user);
|
|
46
|
+
setIsLoggedIn(true);
|
|
47
|
+
return { success: true };
|
|
48
|
+
} else {
|
|
49
|
+
const errorMsg = response.error || "\u767B\u5F55\u5931\u8D25";
|
|
50
|
+
setError(errorMsg);
|
|
51
|
+
return { success: false, error: errorMsg };
|
|
52
|
+
}
|
|
53
|
+
} catch (err) {
|
|
54
|
+
const errorMsg = err instanceof Error ? err.message : "\u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
55
|
+
setError(errorMsg);
|
|
56
|
+
return { success: false, error: errorMsg };
|
|
57
|
+
} finally {
|
|
58
|
+
setLoading(false);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
[apiClient]
|
|
62
|
+
);
|
|
63
|
+
const register = useCallback(
|
|
64
|
+
async (email, password, username) => {
|
|
65
|
+
setLoading(true);
|
|
66
|
+
setError(null);
|
|
67
|
+
try {
|
|
68
|
+
const response = await apiClient.register(email, password, username);
|
|
69
|
+
if (response.success && response.data) {
|
|
70
|
+
setUser(response.data.user);
|
|
71
|
+
setIsLoggedIn(true);
|
|
72
|
+
return { success: true };
|
|
73
|
+
} else {
|
|
74
|
+
const errorMsg = response.error || "\u6CE8\u518C\u5931\u8D25";
|
|
75
|
+
setError(errorMsg);
|
|
76
|
+
return { success: false, error: errorMsg };
|
|
77
|
+
}
|
|
78
|
+
} catch (err) {
|
|
79
|
+
const errorMsg = err instanceof Error ? err.message : "\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5";
|
|
80
|
+
setError(errorMsg);
|
|
81
|
+
return { success: false, error: errorMsg };
|
|
82
|
+
} finally {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
[apiClient]
|
|
87
|
+
);
|
|
88
|
+
const logout = useCallback(async () => {
|
|
89
|
+
setLoading(true);
|
|
90
|
+
setError(null);
|
|
91
|
+
try {
|
|
92
|
+
await apiClient.logout();
|
|
93
|
+
setUser(null);
|
|
94
|
+
setIsLoggedIn(false);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error("\u767B\u51FA\u5931\u8D25:", err);
|
|
97
|
+
setError(err instanceof Error ? err.message : "\u767B\u51FA\u5931\u8D25");
|
|
98
|
+
setUser(null);
|
|
99
|
+
setIsLoggedIn(false);
|
|
100
|
+
} finally {
|
|
101
|
+
setLoading(false);
|
|
102
|
+
}
|
|
103
|
+
}, [apiClient]);
|
|
104
|
+
const clearError = useCallback(() => {
|
|
105
|
+
setError(null);
|
|
106
|
+
}, []);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
checkAuthStatus();
|
|
109
|
+
}, [checkAuthStatus]);
|
|
110
|
+
return {
|
|
111
|
+
// 状态
|
|
112
|
+
user,
|
|
113
|
+
isLoggedIn,
|
|
114
|
+
loading,
|
|
115
|
+
checkingAuth,
|
|
116
|
+
error,
|
|
117
|
+
// 操作方法
|
|
118
|
+
login,
|
|
119
|
+
register,
|
|
120
|
+
logout,
|
|
121
|
+
refresh: checkAuthStatus,
|
|
122
|
+
clearError
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function useAuthForm(initialValues) {
|
|
126
|
+
const [values, setValues] = useState(initialValues);
|
|
127
|
+
const [errors, setErrors] = useState({});
|
|
128
|
+
const [touched, setTouched] = useState({});
|
|
129
|
+
const handleChange = useCallback(
|
|
130
|
+
(field, value) => {
|
|
131
|
+
setValues((prev) => ({ ...prev, [field]: value }));
|
|
132
|
+
if (errors[field]) {
|
|
133
|
+
setErrors((prev) => {
|
|
134
|
+
const newErrors = { ...prev };
|
|
135
|
+
delete newErrors[field];
|
|
136
|
+
return newErrors;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
[errors]
|
|
141
|
+
);
|
|
142
|
+
const handleBlur = useCallback((field) => {
|
|
143
|
+
setTouched((prev) => ({ ...prev, [field]: true }));
|
|
144
|
+
}, []);
|
|
145
|
+
const validate = useCallback(
|
|
146
|
+
(validationRules) => {
|
|
147
|
+
const newErrors = {};
|
|
148
|
+
Object.keys(validationRules).forEach((key) => {
|
|
149
|
+
const field = key;
|
|
150
|
+
const rule = validationRules[field];
|
|
151
|
+
if (rule) {
|
|
152
|
+
const error = rule(values[field]);
|
|
153
|
+
if (error) {
|
|
154
|
+
newErrors[field] = error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
setErrors(newErrors);
|
|
159
|
+
return Object.keys(newErrors).length === 0;
|
|
160
|
+
},
|
|
161
|
+
[values]
|
|
162
|
+
);
|
|
163
|
+
const reset = useCallback(() => {
|
|
164
|
+
setValues(initialValues);
|
|
165
|
+
setErrors({});
|
|
166
|
+
setTouched({});
|
|
167
|
+
}, [initialValues]);
|
|
168
|
+
return {
|
|
169
|
+
values,
|
|
170
|
+
errors,
|
|
171
|
+
touched,
|
|
172
|
+
handleChange,
|
|
173
|
+
handleBlur,
|
|
174
|
+
validate,
|
|
175
|
+
reset,
|
|
176
|
+
setValues,
|
|
177
|
+
setErrors
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export { useAuth, useAuthForm };
|
|
182
|
+
//# sourceMappingURL=index.mjs.map
|
|
183
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":";;;AAOO,SAAS,QAAQ,SAAA,EAAyC;AAC/D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAsB,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,IAAI,CAAA;AACrD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AAKtD,EAAA,MAAM,eAAA,GAAkB,YAAY,YAAY;AAC9C,IAAA,IAAI;AACF,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,QAAA,CAAS,IAAI,CAAA;AAEb,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU,eAAA,EAAgB;AAE/C,MAAA,IAAI,MAAA,EAAQ;AAEV,QAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,cAAA,EAAe;AAEhD,QAAA,IAAI,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,EAAM;AACrC,UAAA,OAAA,CAAQ,SAAS,IAAI,CAAA;AACrB,UAAA,aAAA,CAAc,IAAI,CAAA;AAAA,QACpB,CAAA,MAAO;AAEL,UAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,UAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,UAAA,aAAA,CAAc,KAAK,CAAA;AAAA,QACrB;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA,aAAA,CAAc,KAAK,CAAA;AAAA,MACrB;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,qDAAa,GAAG,CAAA;AAC9B,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,kDAAU,CAAA;AACxD,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB,CAAA,SAAE;AACA,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACvB;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAKd,EAAA,MAAM,KAAA,GAAQ,WAAA;AAAA,IACZ,OAAO,OAAe,QAAA,KAA0C;AAC9D,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,QAAA,CAAS,IAAI,CAAA;AAEb,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,KAAA,CAAM,OAAO,QAAQ,CAAA;AAEtD,QAAA,IAAI,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,EAAM;AACrC,UAAA,OAAA,CAAQ,QAAA,CAAS,KAAK,IAAI,CAAA;AAC1B,UAAA,aAAA,CAAc,IAAI,CAAA;AAClB,UAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,QACzB,CAAA,MAAO;AACL,UAAA,MAAM,QAAA,GAAW,SAAS,KAAA,IAAS,0BAAA;AACnC,UAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,UAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS;AAAA,QAC3C;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,QAAA,GAAW,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,kDAAA;AACtD,QAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,QAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS;AAAA,MAC3C,CAAA,SAAE;AACA,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAClB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAKA,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,OAAO,KAAA,EAAe,QAAA,EAAkB,QAAA,KAA0C;AAChF,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,QAAA,CAAS,IAAI,CAAA;AAEb,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,MAAM,SAAA,CAAU,QAAA,CAAS,KAAA,EAAO,UAAU,QAAQ,CAAA;AAEnE,QAAA,IAAI,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,EAAM;AACrC,UAAA,OAAA,CAAQ,QAAA,CAAS,KAAK,IAAI,CAAA;AAC1B,UAAA,aAAA,CAAc,IAAI,CAAA;AAClB,UAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AAAA,QACzB,CAAA,MAAO;AACL,UAAA,MAAM,QAAA,GAAW,SAAS,KAAA,IAAS,0BAAA;AACnC,UAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,UAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS;AAAA,QAC3C;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,QAAA,GAAW,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,kDAAA;AACtD,QAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,QAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS;AAAA,MAC3C,CAAA,SAAE;AACA,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAClB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAKA,EAAA,MAAM,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,MAAA,EAAO;AACvB,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,6BAAS,GAAG,CAAA;AAC1B,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,0BAAM,CAAA;AAEpD,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAKd,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,eAAA,EAAgB;AAAA,EAClB,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AAEpB,EAAA,OAAO;AAAA;AAAA,IAEL,IAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA;AAAA,IAGA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA,EAAS,eAAA;AAAA,IACT;AAAA,GACF;AACF;AAaO,SAAS,YAA2C,aAAA,EAAkB;AAC3E,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAY,aAAa,CAAA;AACrD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAA2C,EAAE,CAAA;AACzE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAA4C,EAAE,CAAA;AAE5E,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,OAAgB,KAAA,KAAe;AAC9B,MAAA,SAAA,CAAU,CAAC,UAAa,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,KAAA,EAAM,CAAE,CAAA;AAEpD,MAAA,IAAI,MAAA,CAAO,KAAK,CAAA,EAAG;AACjB,QAAA,SAAA,CAAU,CAAC,IAAA,KAA2C;AACpD,UAAA,MAAM,SAAA,GAAY,EAAE,GAAG,IAAA,EAAK;AAC5B,UAAA,OAAO,UAAU,KAAK,CAAA;AACtB,UAAA,OAAO,SAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,KAAA,KAAmB;AACjD,IAAA,UAAA,CAAW,CAAC,UAA6C,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,IAAA,EAAK,CAAE,CAAA;AAAA,EACtF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,CAAC,eAAA,KAAkF;AACjF,MAAA,MAAM,YAA8C,EAAC;AAErD,MAAA,MAAA,CAAO,IAAA,CAAK,eAAe,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAC5C,QAAA,MAAM,KAAA,GAAQ,GAAA;AACd,QAAA,MAAM,IAAA,GAAO,gBAAgB,KAAK,CAAA;AAClC,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAChC,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,SAAA,CAAU,KAAK,CAAA,GAAI,KAAA;AAAA,UACrB;AAAA,QACF;AAAA,MACF,CAAC,CAAA;AAED,MAAA,SAAA,CAAU,SAAS,CAAA;AACnB,MAAA,OAAO,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,KAAW,CAAA;AAAA,IAC3C,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM;AAC9B,IAAA,SAAA,CAAU,aAAa,CAAA;AACvB,IAAA,SAAA,CAAU,EAAE,CAAA;AACZ,IAAA,UAAA,CAAW,EAAE,CAAA;AAAA,EACf,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF","file":"index.mjs","sourcesContent":["'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport type { User, BaseApiClient, AuthResult, UseAuthReturn } from '../types';\n\nexport type { User, BaseApiClient, AuthResult, UseAuthReturn };\n\nexport function useAuth(apiClient: BaseApiClient): UseAuthReturn {\n const [user, setUser] = useState<User | null>(null);\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [loading, setLoading] = useState(false);\n const [checkingAuth, setCheckingAuth] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n /**\n * 检查认证状态\n */\n const checkAuthStatus = useCallback(async () => {\n try {\n setCheckingAuth(true);\n setError(null);\n\n const isAuth = await apiClient.isAuthenticated();\n\n if (isAuth) {\n // 验证 token 并获取用户信息\n const response = await apiClient.getCurrentUser();\n\n if (response.success && response.data) {\n setUser(response.data);\n setIsLoggedIn(true);\n } else {\n // Token 无效,清除登录状态\n await apiClient.clearUserData();\n setUser(null);\n setIsLoggedIn(false);\n }\n } else {\n setUser(null);\n setIsLoggedIn(false);\n }\n } catch (err) {\n console.error('检查登录状态失败:', err);\n setError(err instanceof Error ? err.message : '检查登录状态失败');\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setCheckingAuth(false);\n }\n }, [apiClient]);\n\n /**\n * 用户登录\n */\n const login = useCallback(\n async (email: string, password: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.login(email, password);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '登录失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '登录失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户注册\n */\n const register = useCallback(\n async (email: string, password: string, username: string): Promise<AuthResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const response = await apiClient.register(email, password, username);\n\n if (response.success && response.data) {\n setUser(response.data.user);\n setIsLoggedIn(true);\n return { success: true };\n } else {\n const errorMsg = response.error || '注册失败';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : '注册失败,请重试';\n setError(errorMsg);\n return { success: false, error: errorMsg };\n } finally {\n setLoading(false);\n }\n },\n [apiClient]\n );\n\n /**\n * 用户登出\n */\n const logout = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n try {\n await apiClient.logout();\n setUser(null);\n setIsLoggedIn(false);\n } catch (err) {\n console.error('登出失败:', err);\n setError(err instanceof Error ? err.message : '登出失败');\n // 即使登出失败,也清除本地状态\n setUser(null);\n setIsLoggedIn(false);\n } finally {\n setLoading(false);\n }\n }, [apiClient]);\n\n /**\n * 清除错误信息\n */\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n // 组件挂载时检查认证状态\n useEffect(() => {\n checkAuthStatus();\n }, [checkAuthStatus]);\n\n return {\n // 状态\n user,\n isLoggedIn,\n loading,\n checkingAuth,\n error,\n\n // 操作方法\n login,\n register,\n logout,\n refresh: checkAuthStatus,\n clearError,\n };\n}\n\n/**\n * 表单验证 Hook\n *\n * @example\n * ```typescript\n * const { values, errors, handleChange, handleBlur, validate } = useAuthForm({\n * email: '',\n * password: ''\n * })\n * ```\n */\nexport function useAuthForm<T extends Record<string, any>>(initialValues: T) {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<Partial<Record<keyof T, string>>>({});\n const [touched, setTouched] = useState<Partial<Record<keyof T, boolean>>>({});\n\n const handleChange = useCallback(\n (field: keyof T, value: any) => {\n setValues((prev: T) => ({ ...prev, [field]: value }));\n // 清除该字段的错误\n if (errors[field]) {\n setErrors((prev: Partial<Record<keyof T, string>>) => {\n const newErrors = { ...prev };\n delete newErrors[field];\n return newErrors;\n });\n }\n },\n [errors]\n );\n\n const handleBlur = useCallback((field: keyof T) => {\n setTouched((prev: Partial<Record<keyof T, boolean>>) => ({ ...prev, [field]: true }));\n }, []);\n\n const validate = useCallback(\n (validationRules: Partial<Record<keyof T, (value: any) => string | undefined>>) => {\n const newErrors: Partial<Record<keyof T, string>> = {};\n\n Object.keys(validationRules).forEach((key) => {\n const field = key as keyof T;\n const rule = validationRules[field];\n if (rule) {\n const error = rule(values[field]);\n if (error) {\n newErrors[field] = error;\n }\n }\n });\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n },\n [values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setTouched({});\n }, [initialValues]);\n\n return {\n values,\n errors,\n touched,\n handleChange,\n handleBlur,\n validate,\n reset,\n setValues,\n setErrors,\n };\n}\n\n"]}
|