| | |
| | | return res.data.data; |
| | | } |
| | | return Promise.reject(new Error(res.data.msg)); |
| | | } |
| | | } |
| | | |
| | | export async function queryUserInfo(_params) { |
| | | const res = await request.get('/auth/user', _params); |
| | | if (res.data.code === 200) { |
| | | return res.data.data; |
| | | } |
| | | return Promise.reject(new Error(res.data.msg)); |
| | | } |
| | | |
| | | export async function updateUserInfo(_params) { |
| | | const res = await request.post('/auth/user', _params); |
| | | if (res.data.code === 200) { |
| | | return res.data; |
| | | } |
| | | return Promise.reject(new Error(res.data.msg)); |
| | | } |
| | |
| | | useLogin, |
| | | useNotify, |
| | | } from 'react-admin'; |
| | | import { useForm, Controller } from 'react-hook-form'; |
| | | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; |
| | | import ProviderChoices from "./ProviderChoices"; |
| | | import Visibility from '@mui/icons-material/Visibility'; |
| | | import VisibilityOff from '@mui/icons-material/VisibilityOff'; |
| | |
| | | const location = useLocation(); |
| | | const { tenantList } = props; |
| | | |
| | | const { control, watch, handleSubmit, setValue } = useForm(); |
| | | const { control, handleSubmit, watch, setValue, getValues } = useForm(); |
| | | |
| | | const [loading, setLoading] = useState(false); |
| | | const [showPassword, setShowPassword] = useState(false); |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { useNavigate } from 'react-router-dom'; |
| | | import { |
| | | Edit, |
| | | SimpleForm, |
| | | FormDataConsumer, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | SaveButton, |
| | | SelectInput, |
| | | Toolbar, |
| | | Labeled, |
| | | NumberField, |
| | | required, |
| | | useRecordContext, |
| | | useTheme, |
| | | useAuthProvider, |
| | | useNotify, |
| | | } from 'react-admin'; |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; |
| | | import { |
| | | Stack, |
| | | Grid, |
| | | Box, |
| | | Typography, |
| | | Card, |
| | | CardContent, |
| | | TextField, |
| | | Button, |
| | | FormControl, |
| | | InputLabel, |
| | | Select, |
| | | MenuItem, |
| | | FormHelperText, |
| | | CircularProgress, |
| | | } from '@mui/material'; |
| | | import { updateUserInfo } from '@/api/auth'; |
| | | |
| | | const BaseSettings = (props) => { |
| | | const { children, value, ...other } = props; |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const { children, value, userInfo } = props; |
| | | |
| | | const { control, handleSubmit, watch, setValue, getValues, formState: { isDirty } } = useForm(); |
| | | const [loading, setLoading] = 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) => { |
| | | 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 } }); |
| | | } else { |
| | | notify(msg, { type: 'error', messageArgs: { _: msg } }); |
| | | } |
| | | }).catch((error) => { |
| | | setLoading(false); |
| | | notify(error.message, { type: 'error', messageArgs: { _: error.message } }); |
| | | console.error(error); |
| | | }) |
| | | } |
| | | |
| | | return ( |
| | | <Box |
| | | hidden={value !== 0} |
| | | sx={{ p: 3 }} |
| | | {...other} |
| | | sx={{ |
| | | p: 3, |
| | | flex: 1, |
| | | overflow: 'auto', |
| | | }} |
| | | > |
| | | <Grid container spacing={6}> |
| | | <Grid item xs={12}> |
| | | {/* https://github.com/themeselection/materio-mui-nextjs-admin-template-free/blob/main/javascript-version/src/views/account-settings/account/AccountDetails.jsx */} |
| | | <Card> |
| | | <CardContent className='mbe-5'> |
| | | <Typography> |
| | | Base Settings |
| | | </Typography> |
| | | </CardContent> |
| | | </Card> |
| | | {/* https://github.com/themeselection/materio-mui-nextjs-admin-template-free/blob/main/javascript-version/src/views/account-settings/account/AccountDetails.jsx */} |
| | | <form onSubmit={handleSubmit(onSubmit)} noValidate> |
| | | <Stack |
| | | direction='column' |
| | | spacing={3} |
| | | sx={{ |
| | | width: '30%', |
| | | pt: 1 |
| | | }} |
| | | > |
| | | <Controller |
| | | name="username" |
| | | control={control} |
| | | defaultValue="" |
| | | rules={{ required: true }} |
| | | render={({ field, fieldState: { error } }) => ( |
| | | <TextField |
| | | {...field} |
| | | label={translate('table.field.user.username')} |
| | | variant="outlined" |
| | | autoComplete="off" |
| | | helperText={error ? translate('ra.validation.required') : ""} |
| | | disabled |
| | | /> |
| | | )} |
| | | /> |
| | | <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" |
| | | control={control} |
| | | defaultValue="" |
| | | rules={{ |
| | | required: false, |
| | | pattern: { |
| | | value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, |
| | | message: translate("ra.validation.email"), |
| | | }, |
| | | }} |
| | | render={({ field, fieldState: { error } }) => ( |
| | | <TextField |
| | | {...field} |
| | | label={translate('table.field.user.email')} |
| | | variant="outlined" |
| | | autoComplete="off" |
| | | error={!!error} |
| | | helperText={error ? error.message : ""} |
| | | /> |
| | | )} |
| | | /> |
| | | <Controller |
| | | name="realName" |
| | | control={control} |
| | | defaultValue="" |
| | | rules={{ required: false }} |
| | | render={({ field, fieldState: { error } }) => ( |
| | | <TextField |
| | | {...field} |
| | | label={translate('table.field.user.realName')} |
| | | 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') : ""} |
| | | /> |
| | | )} |
| | | /> |
| | | <Button |
| | | type="submit" |
| | | variant="contained" |
| | | disabled={loading || !isDirty} |
| | | sx={{ |
| | | alignSelf: 'flex-start', |
| | | width: '120px' |
| | | }} |
| | | > |
| | | {loading && <CircularProgress size={25} thickness={2} />} |
| | | {translate('ra.action.save')} |
| | | </Button> |
| | | </Stack> |
| | | </form> |
| | | |
| | | </Grid> |
| | | </Grid> |
| | | </Box> |
| | | |
| | | ) |
| | | } |
| | | |
| | |
| | | import { useWatch, useFormContext } from "react-hook-form"; |
| | | import { Stack, Grid, Box, Typography, Card, CardContent, Tabs, Tab } from '@mui/material'; |
| | | import * as Common from '@/utils/common'; |
| | | import { } from '@/config/setting'; |
| | | import BaseSettings from "./BaseSettings"; |
| | | import { queryUserInfo } from '@/api/auth'; |
| | | |
| | | const Index = () => { |
| | | const authProvider = useAuthProvider(); |
| | | const navigate = useNavigate(); |
| | | const translate = useTranslate(); |
| | | const theme = useTheme(); |
| | | const [value, setValue] = React.useState(0); |
| | | |
| | | const [value, setValue] = useState(0); |
| | | const [userInfo, setUserInfo] = useState(null); |
| | | |
| | | useEffect(() => { |
| | | authProvider.checkAuth().catch(() => { |
| | |
| | | }, [authProvider, navigate]); |
| | | |
| | | useEffect(() => { |
| | | }, [value]); |
| | | queryUserInfo().then(res => { |
| | | setUserInfo(res); |
| | | }) |
| | | }, []); |
| | | |
| | | return ( |
| | | <> |
| | |
| | | flexGrow: 1, |
| | | bgcolor: 'background.paper', |
| | | display: 'flex', |
| | | height: 224, |
| | | // height: 224, |
| | | border: `1px solid #${theme[0] === 'light' ? 'ddd' : '333'}`, |
| | | borderRadius: 2 |
| | | }} |
| | |
| | | </Tabs> |
| | | <BaseSettings |
| | | value={value} |
| | | userInfo={userInfo} |
| | | /> |
| | | <SecuritySettings |
| | | value={value} |
| | |
| | | label="table.field.user.sex" |
| | | source="sex" |
| | | choices={[ |
| | | { id: 0, name: '未知' }, |
| | | { id: 1, name: '男' }, |
| | | { id: 2, name: '女' }, |
| | | { id: 0, name: 'table.field.user.sexes.unknown' }, |
| | | { id: 1, name: 'table.field.user.sexes.male' }, |
| | | { id: 2, name: 'table.field.user.sexes.female' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | |
| | | label="table.field.user.sex" |
| | | source="sex" |
| | | choices={[ |
| | | { id: 0, name: '未知' }, |
| | | { id: 1, name: '男' }, |
| | | { id: 2, name: '女' }, |
| | | { id: 0, name: 'table.field.user.sexes.unknown' }, |
| | | { id: 1, name: 'table.field.user.sexes.male' }, |
| | | { id: 2, name: 'table.field.user.sexes.female' }, |
| | | ]} |
| | | /> |
| | | <TextInput |
| | |
| | | <TextInput source="code" label="table.field.user.code" />, |
| | | <SelectInput source="sex" label="table.field.user.sex" |
| | | choices={[ |
| | | { id: 0, name: '未知' }, |
| | | { id: 1, name: '男' }, |
| | | { id: 2, name: '女' }, |
| | | { id: 0, name: 'table.field.user.sexes.unknown' }, |
| | | { id: 1, name: "table.field.user.sexes.male" }, |
| | | { id: 2, name: 'table.field.user.sexes.female' }, |
| | | ]} |
| | | />, |
| | | <TextInput source="phone" label="table.field.user.phone" />, |
| | |
| | | import com.vincent.rsf.server.system.entity.Menu; |
| | | import com.vincent.rsf.server.system.entity.User; |
| | | import com.vincent.rsf.server.system.entity.UserLogin; |
| | | import com.vincent.rsf.server.system.service.RoleMenuService; |
| | | import com.vincent.rsf.server.system.service.TenantService; |
| | | import com.vincent.rsf.server.system.service.UserLoginService; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | | import com.vincent.rsf.server.system.service.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | private RoleMenuService roleMenuService; |
| | | @Resource |
| | | private TenantService tenantService; |
| | | @Autowired |
| | | private UserRoleService userRoleService; |
| | | |
| | | @PostMapping("/login") |
| | | public R login(@RequestBody LoginParam param, HttpServletRequest request) { |
| | |
| | | |
| | | @GetMapping("/auth/user") |
| | | public R userInfo() { |
| | | return R.ok(userService.getByIdRel(getLoginUserId())); |
| | | User user = userService.getByIdRel(getLoginUserId()); |
| | | user.setRoles(userRoleService.listByUserId(user.getId())); |
| | | return R.ok(user); |
| | | } |
| | | |
| | | @GetMapping("/auth/menu") |
| | |
| | | return R.ok().add(Utils.toTreeData(voList, 0L, MenuVo::getParentId, MenuVo::getId, MenuVo::setChildren)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('sys:auth:user')") |
| | | @OperationLog |
| | | @PutMapping("/auth/user") |
| | | @OperationLog("Update UserInfo") |
| | | @PostMapping("/auth/user") |
| | | public R updateInfo(@RequestBody User user) { |
| | | user.setId(getLoginUserId()); |
| | | // 不能修改的字段 |
| | |
| | | user.setTenantId(null); |
| | | user.setStatus(null); |
| | | if (userService.updateById(user)) { |
| | | return R.ok().add(userService.getByIdRel(user.getId())); |
| | | return R.ok("Save Success").add(userService.getByIdRel(user.getId())); |
| | | } |
| | | return R.error("Save Fail"); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('sys:auth:password')") |
| | | @OperationLog |
| | | @PutMapping("/auth/password") |
| | | @PostMapping("/auth/password") |
| | | public R updatePassword(@RequestBody UpdatePasswordParam param) { |
| | | if (Cools.isEmpty(param.getOldPassword(), param.getPassword())) { |
| | | return R.error("Parameters Cannot Be Empty"); |