import PropTypes from 'prop-types'; import * as Yup from 'yup'; import { Formik } from 'formik'; import { useTheme } from '@mui/material/styles'; import { useState, useEffect, useCallback } from 'react'; import { format } from 'date-fns'; import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Divider, FormControl, InputLabel, OutlinedInput, InputAdornment, Select, MenuItem, IconButton, FormHelperText, TextField, Typography, Switch, FormControlLabel } from '@mui/material'; import Visibility from '@mui/icons-material/Visibility'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; import { renderQuotaWithPrompt, showSuccess, showError } from 'utils/common'; import { API } from 'utils/api'; const validationSchema = Yup.object().shape({ is_edit: Yup.boolean(), username: Yup.string().required('用户名 不能为空'), display_name: Yup.string(), password: Yup.string().when('is_edit', { is: false, then: Yup.string().required('密码 不能为空'), otherwise: Yup.string() }), group: Yup.string().when('is_edit', { is: false, then: Yup.string().required('用户组 不能为空'), otherwise: Yup.string() }), quota: Yup.number().when('is_edit', { is: false, then: Yup.number().min(0, '额度 不能小于 0'), otherwise: Yup.number() }), expiration_date: Yup.mixed().when('group', { is: (group) => group !== 'default', then: Yup.mixed().test( 'expiration_date-required', '到期时间 不能为空', function (value) { const { expiration_date } = this.parent; return expiration_date === -1 || !!expiration_date; } ), }) }); const originInputs = { is_edit: false, username: '', display_name: '', password: '', group: 'default', quota: 0, expiration_date: null }; const EditModal = ({ open, userId, onCancel, onOk }) => { const theme = useTheme(); const [inputs, setInputs] = useState(originInputs); const [groupOptions, setGroupOptions] = useState([]); const [showPassword, setShowPassword] = useState(false); const submit = async (values, { setErrors, setStatus, setSubmitting }) => { setSubmitting(true); // 将到期时间转换为 Unix 时间戳 if (values.expiration_date && values.expiration_date !== -1) { const date = new Date(values.expiration_date); values.expiration_date = Math.floor(date.getTime() / 1000); // 转换为秒级的 Unix 时间戳 } let res; if (values.is_edit) { res = await API.put(`/api/user/`, { ...values, id: parseInt(userId) }); } else { res = await API.post(`/api/user/`, values); } const { success, message } = res.data; if (success) { if (values.is_edit) { showSuccess('用户更新成功!'); } else { showSuccess('用户创建成功!'); } setSubmitting(false); setStatus({ success: true }); onOk(true); } else { showError(message); setErrors({ submit: message }); } }; const handleClickShowPassword = () => { setShowPassword(!showPassword); }; const handleMouseDownPassword = (event) => { event.preventDefault(); }; const loadUser = useCallback(async () => { let res = await API.get(`/api/user/${userId}`); const { success, message, data } = res.data; if (success) { data.is_edit = true; // 将 Unix 时间戳转换为日期字符串 if (data.expiration_date && data.expiration_date !== -1) { const date = new Date(data.expiration_date * 1000); // 转换为毫秒级的时间戳 data.expiration_date = format(date, 'yyyy-MM-dd'); // 格式化为 date 格式 } setInputs(data); } else { showError(message); } }, [userId]); const fetchGroups = async () => { try { let res = await API.get(`/api/group/`); setGroupOptions(res.data.data); } catch (error) { showError(error.message); } }; useEffect(() => { fetchGroups().then(); if (userId) { loadUser().then(); } else { setInputs(originInputs); } }, [userId, loadUser]); return ( {userId ? '编辑用户' : '新建用户'} {({ errors, handleBlur, handleChange, handleSubmit, setFieldValue, touched, values, isSubmitting }) => (
用户名 {touched.username && errors.username && ( {errors.username} )} 显示名称 {touched.display_name && errors.display_name && ( {errors.display_name} )} 密码 {showPassword ? : } } aria-describedby="helper-text-channel-password-label" /> {touched.password && errors.password && ( {errors.password} )} {values.is_edit && ( <> 额度 {renderQuotaWithPrompt(values.quota)}} onBlur={handleBlur} onChange={handleChange} aria-describedby="helper-text-channel-quota-label" disabled={values.unlimited_quota} /> {touched.quota && errors.quota && ( {errors.quota} )} 分组 {touched.group && errors.group && ( {errors.group} )} )} {values.group !== 'default' && ( {touched.expiration_date && errors.expiration_date && ( {errors.expiration_date} )} setFieldValue('expiration_date', e.target.checked ? -1 : '')} name="permanent" color="primary" /> } label="永不过期" /> )}
)}
); }; export default EditModal; EditModal.propTypes = { open: PropTypes.bool, userId: PropTypes.number, onCancel: PropTypes.func, onOk: PropTypes.func };