verou
2025-03-14 d25c8fa670a8fea0977c85f67b13917b3bdefa89
rsf-admin/src/page/settings/SecuritySettings.jsx
@@ -6,56 +6,50 @@
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 { requestResetPassword } from '@/api/auth';
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) => {
    const onSubmit = (params) => {
        setLoading(true);
        updateUserInfo({ id: userInfo.id, ...data }).then(res => {
        requestResetPassword(params).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 if (code === 10001) {
                setError('oldPassword', {
                    message: msg,
                });
            } else {
                notify(msg, { type: 'error', messageArgs: { _: msg } });
            }
@@ -84,156 +78,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>