From d06df946ee95dfb99a6ead6e85f6769cc253e315 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@gmail.com>
Date: 星期日, 09 二月 2025 23:11:49 +0800
Subject: [PATCH] #

---
 rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java |    2 
 rsf-admin/src/page/settings/SecuritySettings.jsx                                      |  224 +++++++++++++++++++-------------------------
 rsf-admin/src/page/settings/BaseSettings.jsx                                          |   14 ++
 rsf-admin/src/i18n/zh.js                                                              |   17 +++
 rsf-admin/src/i18n/en.js                                                              |   13 ++
 5 files changed, 137 insertions(+), 133 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index 658395c..d35a323 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -231,6 +231,19 @@
                 register: 'REGISTER',
             },
         },
+        settings: {
+            resetPwd: {
+                currPwd: 'Current Password',
+                newPwd: 'New Password',
+                confirmNewPwd: 'Confirm Password',
+                resetBtn: 'Reset',
+                tip: {
+                    pwdInputLimit: "New Password must be 6-13 characters long and include both letters and numbers.",
+                    pwdNotSameAsOld: "New Password cannot be the same as the Current Password.",
+                    pwdNotMatch: "New Password and Confirm Password do not match.",
+                }
+            }
+        },
     }
 };
 
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index d724f43..3f15f93 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -227,10 +227,23 @@
             tenant: '鍏徃',
             confirmPwd: '纭瀵嗙爜',
             button: {
-                login: 'LOG IN',
-                register: 'REGISTER',
+                login: '鐧诲綍',
+                register: '娉ㄥ唽',
             },
         },
+        settings: {
+            resetPwd: {
+                currPwd: '褰撳墠瀵嗙爜',
+                newPwd: '鏂板瘑鐮�',
+                confirmNewPwd: '纭鏂板瘑鐮�',
+                resetBtn: '閲嶇疆瀵嗙爜',
+                tip: {
+                    pwdInputLimit: "瀵嗙爜蹇呴』涓�6-13浣�,涓斿繀椤诲寘鍚瓧姣嶅拰鏁板瓧",
+                    pwdNotSameAsOld: "鏂板瘑鐮佷笉鑳戒笌褰撳墠瀵嗙爜鐩稿悓",
+                    pwdNotMatch: "纭瀵嗙爜涓嶄竴鑷�",
+                }
+            }
+        },
     }
 };
 
diff --git a/rsf-admin/src/page/settings/BaseSettings.jsx b/rsf-admin/src/page/settings/BaseSettings.jsx
index bb680be..775e0d5 100644
--- a/rsf-admin/src/page/settings/BaseSettings.jsx
+++ b/rsf-admin/src/page/settings/BaseSettings.jsx
@@ -26,7 +26,19 @@
     const notify = useNotify();
     const { children, userInfo } = props;
 
-    const { control, handleSubmit, watch, setValue, getValues, formState: { isDirty } } = useForm();
+    const {
+        control,
+        handleSubmit,
+        watch,
+        setValue,
+        getValues,
+        reset,
+        formState: {
+            errors,
+            isDirty,
+        }
+    } = useForm();
+
     const [loading, setLoading] = useState(false);
 
     useEffect(() => {
diff --git a/rsf-admin/src/page/settings/SecuritySettings.jsx b/rsf-admin/src/page/settings/SecuritySettings.jsx
index 0943613..9ef9bd9 100644
--- a/rsf-admin/src/page/settings/SecuritySettings.jsx
+++ b/rsf-admin/src/page/settings/SecuritySettings.jsx
@@ -6,58 +6,55 @@
 import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
 import {
     Stack,
-    Grid,
     Box,
     Typography,
     TextField,
     Button,
-    FormControl,
-    InputLabel,
-    Select,
-    MenuItem,
-    FormHelperText,
     CircularProgress,
+    InputAdornment,
+    IconButton,
 } from '@mui/material';
 import { updateUserInfo } from '@/api/auth';
-import avatar from '/avatar.jpg'
+import Visibility from '@mui/icons-material/Visibility';
+import VisibilityOff from '@mui/icons-material/VisibilityOff';
 
 const SecuritySettings = (props) => {
     const translate = useTranslate();
     const notify = useNotify();
-    const { children, userInfo } = props;
+    const { userInfo } = props;
 
-    const { control, handleSubmit, watch, setValue, getValues, formState: { isDirty } } = useForm();
+    const { control, handleSubmit, watch, setValue, getValues, reset, formState: { errors }, setError } = useForm();
+
+    const oldPasswordVal = watch('oldPassword');
+    const newPasswordVal = watch('newPassword');
+    const confirmPasswordVal = watch('confirmPassword');
+
     const [loading, setLoading] = useState(false);
+    const [showOldPassword, setShowOldPassword] = useState(false);
+    const [showNewPassword, setShowNewPassword] = useState(false);
 
     useEffect(() => {
         if (userInfo) {
-            setValue("username", userInfo.username || "", { shouldDirty: false });
-            setValue("nickname", userInfo.nickname || "", { shouldDirty: false });
-            setValue("sex", userInfo.sex ?? "", { shouldDirty: false });
-            setValue("code", userInfo.code || "", { shouldDirty: false });
-            setValue("phone", userInfo.phone || "", { shouldDirty: false });
-            setValue("email", userInfo.email || "", { shouldDirty: false });
-            setValue("realName", userInfo.realName || "", { shouldDirty: false });
-            setValue("idCard", userInfo.idCard || "", { shouldDirty: false });
         }
     }, [userInfo, setValue])
 
     const onSubmit = (data) => {
+        console.log(data);
+        return false;
+
         setLoading(true);
         updateUserInfo({ id: userInfo.id, ...data }).then(res => {
             setLoading(false);
             const { code, msg, data } = res;
             if (code === 200) {
                 notify(msg, { type: 'success', messageArgs: { _: msg } });
-                const userToPersist = {
-                    avatar: avatar,
-                    fullName: data.nickname,
-                    id: data.id,
-                    username: data.username
-                }
-                localStorage.setItem("user", JSON.stringify(userToPersist));
+                reset();
             } else {
                 notify(msg, { type: 'error', messageArgs: { _: msg } });
+                setError('oldPassword', {
+                    type: 'server', // make no sense
+                    message: res.msg,
+                });
             }
         }).catch((error) => {
             setLoading(false);
@@ -84,156 +81,125 @@
                     }}
                 >
                     <Controller
-                        name="username"
+                        name="oldPassword"
                         control={control}
                         defaultValue=""
-                        rules={{ required: true }}
+                        rules={{ required: translate('ra.validation.required') }}
                         render={({ field, fieldState: { error } }) => (
                             <TextField
                                 {...field}
-                                label={translate('table.field.user.username')}
+                                label={translate('page.settings.resetPwd.currPwd')}
+                                type={showOldPassword ? 'text' : 'password'}
                                 variant="outlined"
                                 autoComplete="off"
-                                helperText={error ? translate('ra.validation.required') : ""}
-                                disabled
+                                error={Boolean(errors.oldPassword)}
+                                helperText={errors.oldPassword?.message || ""}
+                                InputProps={{
+                                    endAdornment: (
+                                        <InputAdornment position="end">
+                                            <IconButton
+                                                aria-label="toggle password visibility"
+                                                onClick={() => setShowOldPassword((show) => !show)}
+                                                onMouseDown={(event) => { event.preventDefault() }}
+                                                edge="end"
+                                            >
+                                                {showOldPassword ? <VisibilityOff /> : <Visibility />}
+                                            </IconButton>
+                                        </InputAdornment>
+                                    ),
+                                }}
                             />
                         )}
                     />
                     <Controller
-                        name="nickname"
-                        control={control}
-                        defaultValue=""
-                        rules={{ required: true }}
-                        render={({ field, fieldState: { error } }) => (
-                            <TextField
-                                {...field}
-                                label={translate('table.field.user.nickname')}
-                                variant="outlined"
-                                autoComplete="off"
-                                error={!!error}
-                                helperText={error ? translate('ra.validation.required') : ""}
-                            />
-                        )}
-                    />
-                    <Controller
-                        name="sex"
-                        control={control}
-                        defaultValue=""
-                        rules={{ required: true }}
-                        render={({ field, fieldState: { error } }) => (
-                            <FormControl fullWidth variant="outlined" error={!!error}>
-                                <InputLabel>{translate('table.field.user.sex')}</InputLabel>
-                                <Select
-                                    {...field}
-                                    label={translate('table.field.user.sex')}
-                                >
-                                    <MenuItem value={0}>
-                                        <em>{translate('table.field.user.sexes.unknown')}</em>
-                                    </MenuItem>
-                                    <MenuItem value={1}>{translate('table.field.user.sexes.male')}</MenuItem>
-                                    <MenuItem value={2}>{translate('table.field.user.sexes.female')}</MenuItem>
-                                </Select>
-                                {error && <FormHelperText>{translate('ra.validation.required')}</FormHelperText>}
-                            </FormControl>
-                        )}
-                    />
-                    <Controller
-                        name="code"
-                        control={control}
-                        defaultValue=""
-                        rules={{ required: false }}
-                        render={({ field, fieldState: { error } }) => (
-                            <TextField
-                                {...field}
-                                label={translate('table.field.user.code')}
-                                variant="outlined"
-                                autoComplete="off"
-                                error={!!error}
-                                helperText={error ? translate('ra.validation.required') : ""}
-                            />
-                        )}
-                    />
-                    <Controller
-                        name="phone"
-                        control={control}
-                        defaultValue=""
-                        rules={{ required: false }}
-                        render={({ field, fieldState: { error } }) => (
-                            <TextField
-                                {...field}
-                                label={translate('table.field.user.phone')}
-                                variant="outlined"
-                                autoComplete="off"
-                                error={!!error}
-                                helperText={error ? translate('ra.validation.required') : ""}
-                            />
-                        )}
-                    />
-                    <Controller
-                        name="email"
+                        name="newPassword"
                         control={control}
                         defaultValue=""
                         rules={{
-                            required: false,
+                            required: translate('ra.validation.required'),
                             pattern: {
-                                value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
-                                message: translate("ra.validation.email"),
+                                value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,13}$/,
+                                message: translate('page.settings.resetPwd.tip.pwdInputLimit'),
                             },
+                            validate: (value) => {
+                                if (value === oldPasswordVal) {
+                                    return translate('page.settings.resetPwd.tip.pwdNotSameAsOld');
+                                }
+                                return true;
+                            }
                         }}
                         render={({ field, fieldState: { error } }) => (
                             <TextField
                                 {...field}
-                                label={translate('table.field.user.email')}
+                                label={translate('page.settings.resetPwd.newPwd')}
+                                type={showNewPassword ? 'text' : 'password'}
                                 variant="outlined"
                                 autoComplete="off"
-                                error={!!error}
-                                helperText={error ? error.message : ""}
+                                error={Boolean(errors.newPassword)}
+                                helperText={errors.newPassword?.message || ""}
+                                InputProps={{
+                                    endAdornment: (
+                                        <InputAdornment position="end">
+                                            <IconButton
+                                                aria-label="toggle password visibility"
+                                                onClick={() => setShowNewPassword((show) => !show)}
+                                                onMouseDown={(event) => { event.preventDefault() }}
+                                                edge="end"
+                                            >
+                                                {showNewPassword ? <VisibilityOff /> : <Visibility />}
+                                            </IconButton>
+                                        </InputAdornment>
+                                    ),
+                                }}
                             />
                         )}
                     />
                     <Controller
-                        name="realName"
+                        name="confirmPassword"
                         control={control}
                         defaultValue=""
-                        rules={{ required: false }}
+                        rules={{
+                            required: translate('ra.validation.required'),
+                            validate: value =>
+                                value === newPasswordVal || translate('page.settings.resetPwd.tip.pwdNotMatch'),
+                        }}
                         render={({ field, fieldState: { error } }) => (
                             <TextField
                                 {...field}
-                                label={translate('table.field.user.realName')}
+                                label={translate('page.settings.resetPwd.confirmNewPwd')}
+                                type={showNewPassword ? 'text' : 'password'}
                                 variant="outlined"
                                 autoComplete="off"
-                                error={!!error}
-                                helperText={error ? translate('ra.validation.required') : ""}
-                            />
-                        )}
-                    />
-                    <Controller
-                        name="idCard"
-                        control={control}
-                        defaultValue=""
-                        rules={{ required: false }}
-                        render={({ field, fieldState: { error } }) => (
-                            <TextField
-                                {...field}
-                                label={translate('table.field.user.idCard')}
-                                variant="outlined"
-                                autoComplete="off"
-                                error={!!error}
-                                helperText={error ? translate('ra.validation.required') : ""}
+                                error={Boolean(errors.confirmPassword)}
+                                helperText={errors.confirmPassword?.message || ""}
+                                InputProps={{
+                                    endAdornment: (
+                                        <InputAdornment position="end">
+                                            <IconButton
+                                                aria-label="toggle password visibility"
+                                                onClick={() => setShowNewPassword((show) => !show)}
+                                                onMouseDown={(event) => { event.preventDefault() }}
+                                                edge="end"
+                                            >
+                                                {showNewPassword ? <VisibilityOff /> : <Visibility />}
+                                            </IconButton>
+                                        </InputAdornment>
+                                    ),
+                                }}
                             />
                         )}
                     />
                     <Button
                         type="submit"
                         variant="contained"
-                        disabled={loading || !isDirty}
+                        disabled={loading || !(oldPasswordVal && newPasswordVal && confirmPasswordVal)}
                         sx={{
                             alignSelf: 'flex-start',
                             width: '120px'
                         }}
                     >
                         {loading && <CircularProgress size={25} thickness={2} />}
-                        {translate('ra.action.save')}
+                        {translate('page.settings.resetPwd.resetBtn')}
                     </Button>
                 </Stack>
             </form>
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
index 383a5b0..7e7c009 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
@@ -107,7 +107,7 @@
 
     @OperationLog("Reset Password")
     @PostMapping("/auth/password")
-    public R updatePassword(@RequestBody UpdatePasswordParam param) {
+    public R resetPassword(@RequestBody UpdatePasswordParam param) {
         if (Cools.isEmpty(param.getOldPassword(), param.getPassword())) {
             return R.error("Parameters Cannot Be Empty");
         }

--
Gitblit v1.9.1