|
|
@@ -1,23 +1,49 @@
|
|
|
-import { useState } from "react";
|
|
|
+import { useState, useEffect } from "react";
|
|
|
import {
|
|
|
Box,
|
|
|
Flex,
|
|
|
TextInput,
|
|
|
Button,
|
|
|
FormControl,
|
|
|
- Checkbox,
|
|
|
+ // Checkbox,
|
|
|
Note,
|
|
|
} from "@contentful/f36-components";
|
|
|
import { useNavigate } from "react-router-dom";
|
|
|
+import { authApi } from "../../services/modules/system";
|
|
|
+import { setToken, setUserInfo } from "../../utils/auth";
|
|
|
+import { useAuth } from "../../contexts/AuthContext";
|
|
|
import styles from "./index.module.css";
|
|
|
|
|
|
export default function LoginPage() {
|
|
|
- const [account, setAccount] = useState("");
|
|
|
- const [password, setPassword] = useState("");
|
|
|
- const [rememberMe, setRememberMe] = useState(false);
|
|
|
+ const [account, setAccount] = useState("内容中心管理员");
|
|
|
+ const [password, setPassword] = useState("zyh931015$");
|
|
|
+ const [captcha, setCaptcha] = useState("");
|
|
|
+ const [captchaKey, setCaptchaKey] = useState("");
|
|
|
+ const [captchaImage, setCaptchaImage] = useState("");
|
|
|
+ // const [rememberMe, setRememberMe] = useState(false);
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
const [errorMessage, setErrorMessage] = useState("");
|
|
|
const navigate = useNavigate();
|
|
|
+ const { refreshAuth } = useAuth();
|
|
|
+
|
|
|
+ // 获取验证码
|
|
|
+ const fetchCaptcha = async () => {
|
|
|
+ const checkKey =
|
|
|
+ new Date().getTime() + Math.random().toString(36).slice(-4); // 1629428467008;
|
|
|
+ setCaptchaKey(checkKey);
|
|
|
+ try {
|
|
|
+ const result = await authApi.getCaptcha(checkKey);
|
|
|
+ setCaptchaImage(result);
|
|
|
+ setCaptcha(""); // 清空验证码输入
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取验证码失败:", error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 页面加载时获取验证码
|
|
|
+ useEffect(() => {
|
|
|
+ fetchCaptcha();
|
|
|
+ }, []);
|
|
|
|
|
|
const handleLogin = async (e: React.FormEvent) => {
|
|
|
e.preventDefault();
|
|
|
@@ -26,27 +52,44 @@ export default function LoginPage() {
|
|
|
setErrorMessage("");
|
|
|
|
|
|
// 验证表单 - 只检查必填
|
|
|
- if (!account.trim() || !password.trim()) {
|
|
|
- setErrorMessage("账号或密码不能为空");
|
|
|
+ if (!account.trim() || !password.trim() || !captcha.trim()) {
|
|
|
+ setErrorMessage("账号、密码或验证码不能为空");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
try {
|
|
|
- // TODO: 实现登录逻辑
|
|
|
- console.log("Login:", { account, password, rememberMe });
|
|
|
+ // 调用登录接口
|
|
|
+ const result = await authApi.login({
|
|
|
+ username: account,
|
|
|
+ password,
|
|
|
+ captcha,
|
|
|
+ checkKey: captchaKey,
|
|
|
+ });
|
|
|
|
|
|
- // 模拟登录失败
|
|
|
- // setErrorMessage("账号或密码错误");
|
|
|
+ console.log("登录成功:", result);
|
|
|
|
|
|
- // 模拟登录成功后跳转
|
|
|
- setTimeout(() => {
|
|
|
- navigate("/content-model");
|
|
|
- }, 1000);
|
|
|
- } catch (error) {
|
|
|
+ // 保存 token(使用与 JeecgBoot 前端相同的 key)
|
|
|
+ if (result.token) {
|
|
|
+ setToken(result.token);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存用户信息
|
|
|
+ if (result.userInfo) {
|
|
|
+ setUserInfo(result.userInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新权限数据(加载菜单)
|
|
|
+ await refreshAuth();
|
|
|
+
|
|
|
+ // 跳转到首页
|
|
|
+ navigate("/content-model");
|
|
|
+ } catch (error: any) {
|
|
|
console.error("登录失败:", error);
|
|
|
- setErrorMessage("登录失败,请稍后重试");
|
|
|
+ setErrorMessage(error.message || "登录失败,请稍后重试");
|
|
|
+ // 刷新验证码
|
|
|
+ fetchCaptcha();
|
|
|
} finally {
|
|
|
setLoading(false);
|
|
|
}
|
|
|
@@ -68,16 +111,12 @@ export default function LoginPage() {
|
|
|
{/* 登录表单 */}
|
|
|
<Box className={styles.formContainer}>
|
|
|
<form onSubmit={handleLogin}>
|
|
|
- <Flex flexDirection="column" gap="spacingL">
|
|
|
+ <Flex flexDirection="column" gap="spacingS">
|
|
|
{/* 错误提示 */}
|
|
|
- {errorMessage && (
|
|
|
- <Note variant="warning">
|
|
|
- {errorMessage}
|
|
|
- </Note>
|
|
|
- )}
|
|
|
+ {errorMessage && <Note variant="warning">{errorMessage}</Note>}
|
|
|
|
|
|
{/* account */}
|
|
|
- <FormControl>
|
|
|
+ <FormControl className={styles.form_control}>
|
|
|
<FormControl.Label>账号</FormControl.Label>
|
|
|
<TextInput
|
|
|
// type="account"
|
|
|
@@ -94,7 +133,7 @@ export default function LoginPage() {
|
|
|
</FormControl>
|
|
|
|
|
|
{/* Password */}
|
|
|
- <FormControl>
|
|
|
+ <FormControl className={styles.form_control}>
|
|
|
<FormControl.Label>密码</FormControl.Label>
|
|
|
<TextInput
|
|
|
type="password"
|
|
|
@@ -110,13 +149,48 @@ export default function LoginPage() {
|
|
|
/>
|
|
|
</FormControl>
|
|
|
|
|
|
+ {/* Captcha */}
|
|
|
+ <FormControl className={styles.form_control}>
|
|
|
+ <FormControl.Label>验证码</FormControl.Label>
|
|
|
+ <Flex gap="spacingS" alignItems="center">
|
|
|
+ <Box className={styles.captchaInputWrapper}>
|
|
|
+ <TextInput
|
|
|
+ value={captcha}
|
|
|
+ onChange={(e) => {
|
|
|
+ setCaptcha(e.target.value);
|
|
|
+ // 清除错误提示
|
|
|
+ if (errorMessage) {
|
|
|
+ setErrorMessage("");
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ placeholder="请输入验证码"
|
|
|
+ />
|
|
|
+ </Box>
|
|
|
+ <Box
|
|
|
+ onClick={fetchCaptcha}
|
|
|
+ className={styles.captchaImage}
|
|
|
+ >
|
|
|
+ {captchaImage ? (
|
|
|
+ <img
|
|
|
+ src={captchaImage}
|
|
|
+ alt="验证码"
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <span className={styles.captchaPlaceholder}>
|
|
|
+ 点击刷新
|
|
|
+ </span>
|
|
|
+ )}
|
|
|
+ </Box>
|
|
|
+ </Flex>
|
|
|
+ </FormControl>
|
|
|
+
|
|
|
{/* Remember me */}
|
|
|
- <Checkbox
|
|
|
+ {/* <Checkbox
|
|
|
isChecked={rememberMe}
|
|
|
onChange={() => setRememberMe(!rememberMe)}
|
|
|
>
|
|
|
Remember me
|
|
|
- </Checkbox>
|
|
|
+ </Checkbox> */}
|
|
|
|
|
|
{/* Login Button */}
|
|
|
<Button
|