From 2fd817916072018b631c4f608c75ff455efb42a6 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期四, 13 二月 2025 16:36:11 +0800
Subject: [PATCH] #

---
 rsf-admin/src/page/login/Register.jsx |  173 ++++++++++++++++++++++++++++++++-----------
 rsf-admin/src/i18n/zh.js              |    5 +
 rsf-admin/src/i18n/en.js              |    3 
 3 files changed, 136 insertions(+), 45 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index d3640ec..808c6b5 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -229,9 +229,11 @@
             title: 'Welcome',
             footer: 'Footer Goes Here',
             tenant: 'Company',
+            email: 'Email Address',
             username: 'Username',
             password: 'Password',
             confirmPwd: 'Confirm Password',
+            code: 'Verification Code',
             tab: {
                 login: 'SIGN IN',
                 register: 'SIGN UP',
@@ -239,6 +241,7 @@
             button: {
                 login: 'SIGN IN',
                 register: 'SIGN UP',
+                code: 'Send Code',
             },
         },
         settings: {
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 4b5ae98..905a832 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -229,9 +229,11 @@
             title: '娆㈣繋浣跨敤',
             footer: 'Footer Goes Here',
             tenant: '鍏徃',
-            username: '璐﹀彿',
+            email: '閭鍦板潃',
+            username: '鐧诲綍璐﹀彿',
             password: '瀵嗙爜',
             confirmPwd: '纭瀵嗙爜',
+            code: '楠岃瘉鐮�',
             tab: {
                 login: '鐧诲綍',
                 register: '娉ㄥ唽',
@@ -239,6 +241,7 @@
             button: {
                 login: '鐧诲綍',
                 register: '娉ㄥ唽',
+                code: '鑾峰彇楠岃瘉鐮�',
             },
         },
         settings: {
diff --git a/rsf-admin/src/page/login/Register.jsx b/rsf-admin/src/page/login/Register.jsx
index 3e19a4f..881f5be 100644
--- a/rsf-admin/src/page/login/Register.jsx
+++ b/rsf-admin/src/page/login/Register.jsx
@@ -26,23 +26,54 @@
     const notify = useNotify();
     const login = useLogin();
     const location = useLocation();
-    const { systemInfo, tenantList } = props;
+    const { systemInfo } = props;
 
     const { control, watch, handleSubmit, setValue } = useForm();
+
+    const email = watch('email');
+    const username = watch('username');
+    const password = watch('password');
+    const confirmPassword = watch('confirmPassword');
 
     const [loading, setLoading] = useState(false);
     const [showPassword, setShowPassword] = useState(true);
 
-    const username = watch('username');
-    const password = watch('password');
-    const confirmPassword = watch('confirmPassword');
-    const tenantId = watch('tenantId');
 
-    useEffect(() => {
-        if (tenantList.length > 0 && !tenantId) {
-            setValue('tenantId', tenantList[0].id);
+    const [isCounting, setIsCounting] = useState(false);
+    const [countdown, setCountdown] = useState(60);
+
+    // 澶勭悊楠岃瘉鐮佹寜閽偣鍑�
+    const handleSendCode = async () => {
+        // 杩欓噷鍋囪鍙戦�侀獙璇佺爜鐨勮姹�
+        const response = await fetch('/api/send-code');
+        if (response.ok) {
+            setIsCounting(true);
+            localStorage.setItem('codeCountdown', 60); // 瀛樺偍鍊掕鏃跺埌鏈湴
         }
-    }, [tenantList, setValue]);
+    };
+
+    // 鍊掕鏃跺姛鑳�
+    useEffect(() => {
+        const savedCountdown = localStorage.getItem('codeCountdown');
+        if (savedCountdown && !isCounting) {
+            setCountdown(Number(savedCountdown));
+            setIsCounting(true);
+        }
+
+        const interval = setInterval(() => {
+            if (isCounting && countdown > 0) {
+                setCountdown(prev => prev - 1);
+                localStorage.setItem('codeCountdown', countdown - 1);
+            } else if (countdown <= 0) {
+                clearInterval(interval);
+                setIsCounting(false);
+                localStorage.removeItem('codeCountdown'); // 閲嶇疆
+            }
+        }, 1000);
+
+        return () => clearInterval(interval);
+    }, [countdown, isCounting]);
+
 
     const onSubmit = (data) => {
         notify("Registration is not open yet");
@@ -85,34 +116,6 @@
             >
                 <Stack spacing={2}>
                     <Controller
-                        name="tenantId"
-                        control={control}
-                        rules={{ required: true }}
-                        defaultValue={tenantList.length > 0 ? tenantList[0].id : ''}
-                        render={({ field: { onChange, value, ref } }) => {
-                            const selectedTenant = tenantList.find(tenant => tenant.id === value) || null;
-                            return (
-                                <Autocomplete
-                                    options={tenantList}
-                                    getOptionLabel={(option) => option.name}
-                                    value={selectedTenant}
-                                    onChange={(_, newValue) => {
-                                        onChange(newValue ? newValue.id : '');
-                                    }}
-                                    renderInput={(params) => (
-                                        <TextField
-                                            {...params}
-                                            label={translate("page.login.tenant")}
-                                            variant="standard"
-                                            inputRef={ref}
-                                        />
-                                    )}
-                                />
-                            );
-                        }}
-                    />
-
-                    <Controller
                         name="username"
                         control={control}
                         defaultValue=""
@@ -120,7 +123,7 @@
                         render={({ field }) => (
                             <TextField
                                 {...field}
-                                label={translate('ra.auth.username')}
+                                label={translate("page.login.username")}
                                 variant="standard"
                                 disabled={loading}
                                 autoFocus
@@ -133,15 +136,23 @@
                         name="password"
                         control={control}
                         defaultValue=""
-                        rules={{ required: true }}
-                        render={({ field }) => (
+                        rules={{
+                            required: translate('ra.validation.required'),
+                            pattern: {
+                                value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\.]{6,13}$/,
+                                message: translate('page.settings.resetPwd.tip.pwdInputLimit'),
+                            },
+                        }}
+                        render={({ field, fieldState: { error } }) => (
                             <TextField
                                 {...field}
-                                label={translate('ra.auth.password')}
+                                label={translate("page.login.password")}
                                 type={showPassword ? 'text' : 'password'}
                                 variant="standard"
                                 disabled={loading}
                                 autoComplete="off"
+                                error={!!error}
+                                helperText={error?.message || ""}
                                 InputProps={{
                                     endAdornment: (
                                         <InputAdornment position="end">
@@ -164,8 +175,12 @@
                         name="confirmPassword"
                         control={control}
                         defaultValue=""
-                        rules={{ required: true }}
-                        render={({ field }) => (
+                        rules={{
+                            required: translate('ra.validation.required'),
+                            validate: value =>
+                                value === password || translate('page.settings.resetPwd.tip.pwdNotMatch'),
+                        }}
+                        render={({ field, fieldState: { error } }) => (
                             <TextField
                                 {...field}
                                 label={translate('page.login.confirmPwd')}
@@ -173,6 +188,8 @@
                                 variant="standard"
                                 disabled={loading}
                                 autoComplete="off"
+                                error={!!error}
+                                helperText={error?.message || ""}
                                 InputProps={{
                                     endAdornment: (
                                         <InputAdornment position="end">
@@ -191,12 +208,80 @@
                         )}
                     />
 
+                    <Controller
+                        name="email"
+                        control={control}
+                        defaultValue=""
+                        rules={{
+                            required: translate('ra.validation.required'),
+                            pattern: {
+                                value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
+                                message: translate("ra.validation.email"),
+                            },
+                        }}
+                        render={({ field, fieldState: { error } }) => (
+                            <TextField
+                                {...field}
+                                label={translate('page.login.email')}
+                                variant="standard"
+                                disabled={loading}
+                                // autoComplete="off"
+                                error={!!error}
+                                helperText={error ? error.message : ""}
+                            />
+                        )}
+                    />
+
+                    <Box display="flex" alignItems="center" justifyContent='center' width="100%">
+                        <Controller
+                            name="code"
+                            control={control}
+                            defaultValue=""
+                            rules={{
+                                required: translate('ra.validation.required'),
+                            }}
+                            render={({ field, fieldState: { error } }) => (
+                                <TextField
+                                    {...field}
+                                    label={translate('page.login.code')}
+                                    variant="standard"
+                                    disabled={loading}
+                                    autoComplete="off"
+                                    error={!!error}
+                                    helperText={error ? error.message : ""}
+                                    sx={{
+                                        width: '65%',
+                                        mr: 2,
+                                    }}
+                                />
+                            )}
+                        />
+
+                        <Button
+                            variant="outlined"
+                            onClick={handleSendCode}
+                            disabled={isCounting || loading}
+                            sx={{
+                                mt: 1,
+                            }}
+                        >
+                            {isCounting ? (
+                                <>
+                                    <CircularProgress size={20} color="primary" sx={{ marginRight: 1 }} />
+                                    {`${countdown}s`}
+                                </>
+                            ) : (
+                                translate('page.login.button.code')
+                            )}
+                        </Button>
+                    </Box>
+
                     <Box />
 
                     <Button
                         type="submit"
                         variant="contained"
-                        disabled={loading || !(tenantId && username && password && confirmPassword)}
+                        disabled={loading || !(email && username && password && confirmPassword)}
                         sx={{
                             backgroundColor: "#3D4BA7"
                         }}

--
Gitblit v1.9.1