#
luxiaotao1123
2025-02-09 d06df946ee95dfb99a6ead6e85f6769cc253e315
#
5个文件已修改
270 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/settings/BaseSettings.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/settings/SecuritySettings.jsx 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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.",
                }
            }
        },
    }
};
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: "确认密码不一致",
                }
            }
        },
    }
};
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(() => {
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>
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");
        }