#
vincentlu
2025-02-08 cb8536b77509a38e04594bc57fb93555c048c30b
#
8个文件已修改
326 ■■■■ 已修改文件
rsf-admin/src/api/auth/index.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/login/Login.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/settings/BaseSettings.jsx 251 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/settings/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/user/UserCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/user/UserEdit.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/user/UserList.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/api/auth/index.js
@@ -22,4 +22,20 @@
        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));
}
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);
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>
    )
}
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}
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>
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
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" />,
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");