From 03dbce0ba849005d060af569ffe3a58c0a1e0e45 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期五, 23 五月 2025 14:24:06 +0800 Subject: [PATCH] 盘点再入库 --- rsf-admin/src/page/settings/SecuritySettings.jsx | 227 +++++++++++++++++++++++--------------------------------- 1 files changed, 95 insertions(+), 132 deletions(-) diff --git a/rsf-admin/src/page/settings/SecuritySettings.jsx b/rsf-admin/src/page/settings/SecuritySettings.jsx index 0943613..42aeaad 100644 --- a/rsf-admin/src/page/settings/SecuritySettings.jsx +++ b/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> -- Gitblit v1.9.1