From cb8536b77509a38e04594bc57fb93555c048c30b Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期六, 08 二月 2025 15:52:30 +0800
Subject: [PATCH] #
---
rsf-admin/src/api/auth/index.js | 18 ++
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java | 21 +-
rsf-admin/src/page/user/UserCreate.jsx | 6
rsf-admin/src/page/settings/BaseSettings.jsx | 251 ++++++++++++++++++++++++++++++++++++-----
rsf-admin/src/page/login/Login.jsx | 4
rsf-admin/src/page/user/UserEdit.jsx | 6
rsf-admin/src/page/settings/index.jsx | 14 +
rsf-admin/src/page/user/UserList.jsx | 6
8 files changed, 265 insertions(+), 61 deletions(-)
diff --git a/rsf-admin/src/api/auth/index.js b/rsf-admin/src/api/auth/index.js
index 2d73737..b3a2cc8 100644
--- a/rsf-admin/src/api/auth/index.js
+++ b/rsf-admin/src/api/auth/index.js
@@ -22,4 +22,20 @@
return res.data.data;
}
return Promise.reject(new Error(res.data.msg));
-}
\ No newline at end of file
+}
+
+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));
+}
diff --git a/rsf-admin/src/page/login/Login.jsx b/rsf-admin/src/page/login/Login.jsx
index fe3123a..aa0ccbe 100644
--- a/rsf-admin/src/page/login/Login.jsx
+++ b/rsf-admin/src/page/login/Login.jsx
@@ -16,7 +16,7 @@
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';
@@ -28,7 +28,7 @@
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);
diff --git a/rsf-admin/src/page/settings/BaseSettings.jsx b/rsf-admin/src/page/settings/BaseSettings.jsx
index 78edbda..95c5a7f 100644
--- a/rsf-admin/src/page/settings/BaseSettings.jsx
+++ b/rsf-admin/src/page/settings/BaseSettings.jsx
@@ -1,57 +1,238 @@
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>
-
)
}
diff --git a/rsf-admin/src/page/settings/index.jsx b/rsf-admin/src/page/settings/index.jsx
index 63e48b6..bc2364c 100644
--- a/rsf-admin/src/page/settings/index.jsx
+++ b/rsf-admin/src/page/settings/index.jsx
@@ -21,15 +21,17 @@
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(() => {
@@ -38,7 +40,10 @@
}, [authProvider, navigate]);
useEffect(() => {
- }, [value]);
+ queryUserInfo().then(res => {
+ setUserInfo(res);
+ })
+ }, []);
return (
<>
@@ -50,7 +55,7 @@
flexGrow: 1,
bgcolor: 'background.paper',
display: 'flex',
- height: 224,
+ // height: 224,
border: `1px solid #${theme[0] === 'light' ? 'ddd' : '333'}`,
borderRadius: 2
}}
@@ -82,6 +87,7 @@
</Tabs>
<BaseSettings
value={value}
+ userInfo={userInfo}
/>
<SecuritySettings
value={value}
diff --git a/rsf-admin/src/page/user/UserCreate.jsx b/rsf-admin/src/page/user/UserCreate.jsx
index 5a129ed..c0c9a04 100644
--- a/rsf-admin/src/page/user/UserCreate.jsx
+++ b/rsf-admin/src/page/user/UserCreate.jsx
@@ -155,9 +155,9 @@
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>
diff --git a/rsf-admin/src/page/user/UserEdit.jsx b/rsf-admin/src/page/user/UserEdit.jsx
index b5b48b1..f040af2 100644
--- a/rsf-admin/src/page/user/UserEdit.jsx
+++ b/rsf-admin/src/page/user/UserEdit.jsx
@@ -134,9 +134,9 @@
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
diff --git a/rsf-admin/src/page/user/UserList.jsx b/rsf-admin/src/page/user/UserList.jsx
index 63f81bd..25fd5bd 100644
--- a/rsf-admin/src/page/user/UserList.jsx
+++ b/rsf-admin/src/page/user/UserList.jsx
@@ -88,9 +88,9 @@
<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" />,
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
index 78b2069..d1744e9 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
@@ -14,10 +14,8 @@
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.*;
@@ -45,6 +43,8 @@
private RoleMenuService roleMenuService;
@Resource
private TenantService tenantService;
+ @Autowired
+ private UserRoleService userRoleService;
@PostMapping("/login")
public R login(@RequestBody LoginParam param, HttpServletRequest request) {
@@ -74,7 +74,9 @@
@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")
@@ -85,9 +87,8 @@
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());
// 涓嶈兘淇敼鐨勫瓧娈�
@@ -97,14 +98,14 @@
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");
--
Gitblit v1.9.1