Skip to content

Commit 5825bb2

Browse files
committed
feat(认证表单): 添加头像URL字段和API错误处理
在认证表单中新增头像URL字段,并实现其验证逻辑。同时,添加API请求错误处理,以显示服务器返回的错误信息。登录和注册成功后,分别进行相应的重定向和表单重置操作。
1 parent 573f698 commit 5825bb2

1 file changed

Lines changed: 74 additions & 14 deletions

File tree

blog-web/src/components/solid/AuthForm.tsx

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createSignal, Show } from 'solid-js';
22
import { createStore } from 'solid-js/store';
3+
import http from '../../lib/axios';
34

45
type FormType = 'login' | 'register';
56

@@ -8,6 +9,7 @@ interface FormData {
89
password: string;
910
confirmPassword?: string;
1011
username?: string;
12+
avatar_url?: string;
1113
}
1214

1315
export default function AuthForm() {
@@ -16,13 +18,15 @@ export default function AuthForm() {
1618
email: '',
1719
password: '',
1820
confirmPassword: '',
19-
username: ''
21+
username: '',
22+
avatar_url: ''
2023
});
2124
const [errors, setErrors] = createStore({
2225
email: '',
2326
password: '',
2427
confirmPassword: '',
25-
username: ''
28+
username: '',
29+
avatar_url: ''
2630
});
2731
const [isLoading, setIsLoading] = createSignal(false);
2832

@@ -32,7 +36,8 @@ export default function AuthForm() {
3236
email: '',
3337
password: '',
3438
confirmPassword: '',
35-
username: ''
39+
username: '',
40+
avatar_url: ''
3641
};
3742

3843
// 验证邮箱
@@ -53,7 +58,7 @@ export default function AuthForm() {
5358
isValid = false;
5459
}
5560

56-
// 如果是注册表单,验证确认密码和用户名
61+
// 如果是注册表单,验证确认密码、用户名和头像URL
5762
if (activeTab() === 'register') {
5863
if (!formData.confirmPassword) {
5964
newErrors.confirmPassword = '请确认密码';
@@ -67,45 +72,77 @@ export default function AuthForm() {
6772
newErrors.username = '请输入用户名';
6873
isValid = false;
6974
}
75+
76+
// 验证头像URL(可选,但如果提供则必须是有效的URL)
77+
if (formData.avatar_url && !/^https?:\/\/.+/.test(formData.avatar_url)) {
78+
newErrors.avatar_url = '请输入有效的URL地址';
79+
isValid = false;
80+
}
7081
}
7182

7283
setErrors(newErrors);
7384
return isValid;
7485
};
7586

87+
// 添加错误消息状态
88+
const [apiError, setApiError] = createSignal('');
89+
7690
const handleSubmit = async (e: Event) => {
7791
e.preventDefault();
7892

7993
if (!validateForm()) return;
8094

8195
setIsLoading(true);
96+
setApiError('');
8297

8398
try {
84-
// 这里添加实际的登录/注册逻辑
85-
// 例如使用 fetch 或 axios 发送请求到后端
86-
console.log('提交表单数据:', formData);
99+
let data;
87100

88-
// 模拟API请求延迟
89-
await new Promise(resolve => setTimeout(resolve, 1000));
101+
if (activeTab() === 'login') {
102+
// 登录请求
103+
data = await http.post('/users/login', {
104+
username_or_email: formData.email, // 支持用户名或邮箱登录
105+
password: formData.password
106+
});
107+
} else {
108+
// 注册请求
109+
data = await http.post('/users/register', {
110+
username: formData.username,
111+
email: formData.email,
112+
password: formData.password,
113+
avatar_url: formData.avatar_url
114+
});
115+
}
90116

91117
// 成功后的处理
92118
if (activeTab() === 'login') {
93-
// 登录成功后的处理,例如重定向到首页
119+
// 登录成功后存储JWT令牌
120+
localStorage.setItem('token', data.token);
121+
localStorage.setItem('user', JSON.stringify(data.user));
122+
// 重定向到首页
94123
window.location.href = '/';
95124
} else {
96-
// 注册成功后的处理,例如显示成功消息或自动登录
125+
// 注册成功后切换到登录页
97126
setActiveTab('login');
98-
// 重置表单
127+
// 重置表单,保留邮箱
99128
setFormData({
100129
email: formData.email,
101130
password: '',
102131
confirmPassword: '',
103-
username: ''
132+
username: '',
133+
avatar_url: ''
104134
});
105135
}
106136
} catch (error) {
107137
console.error('提交表单出错:', error);
108-
// 处理错误,例如显示错误消息
138+
// 处理axios错误响应
139+
if ((error as any).response && (error as any).response.data) {
140+
// 服务器返回了错误信息
141+
setApiError((error as any).response.data.message || '请求失败');
142+
} else {
143+
// 其他类型的错误
144+
setApiError(error instanceof Error ? error.message : '请求失败,请稍后重试');
145+
}
109146
} finally {
110147
setIsLoading(false);
111148
}
@@ -146,6 +183,22 @@ export default function AuthForm() {
146183
<span class="label-text-alt text-error">{errors.username}</span>
147184
</label>
148185
</div>
186+
187+
<div class="form-control w-full">
188+
<label class="label">
189+
<span class="label-text">头像URL</span>
190+
</label>
191+
<input
192+
type="text"
193+
placeholder="请输入头像URL地址"
194+
class={`input input-bordered w-full ${errors.avatar_url ? 'input-error' : ''}`}
195+
value={formData.avatar_url || ''}
196+
onInput={(e) => setFormData('avatar_url', e.currentTarget.value)}
197+
/>
198+
<label class="label">
199+
<span class="label-text-alt text-error">{errors.avatar_url}</span>
200+
</label>
201+
</div>
149202
</Show>
150203

151204
<div class="form-control w-full">
@@ -198,6 +251,13 @@ export default function AuthForm() {
198251
</div>
199252
</Show>
200253

254+
<Show when={apiError()}>
255+
<div class="alert alert-error mt-4">
256+
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
257+
<span>{apiError()}</span>
258+
</div>
259+
</Show>
260+
201261
<div class="form-control mt-6">
202262
<button
203263
type="submit"

0 commit comments

Comments
 (0)