#
vincentlu
2025-02-07 54d6fc96a8ef1e9903a7362c97a00e504c174ab3
#
4个文件已修改
1个文件已添加
274 ■■■■■ 已修改文件
rsf-admin/src/App.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/config/authProvider.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/login/index1.jsx 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/App.jsx
@@ -16,7 +16,7 @@
import DataProvider from "./config/dataProvider";
import Dashboard from "./page/dashboard/Dashboard";
import Settings from "./page/settings/Settings";
import Login from "./page/login";
import Login from "./page/login/index1";
import * as Common from './utils/common'
import { themes } from './themes/themes';
import { SPA_NAME, SPA_VERSION, DEFAULT_THEME_NAME, DEFAULT_THEME_MODE, DATA_PROVIDER_SPRING } from "./config/setting";
rsf-admin/src/config/authProvider.js
@@ -6,12 +6,11 @@
const AuthProvider = {
  // login
  login: async ({ username, password }) => {
  login: async ({ username, password, tenantId }) => {
    const { accessToken, user } = await login({
      username: username,
      password: password,
      tenantId: 1,
      tenantId: tenantId,
    });
    if (user && accessToken) {
rsf-admin/src/i18n/en.js
@@ -221,6 +221,9 @@
    page: {
        login: {
            tenant: 'Tenant',
            button: {
                login: 'LOG IN',
            },
        },
    }
};
rsf-admin/src/i18n/zh.js
@@ -221,6 +221,9 @@
    page: {
        login: {
            tenant: '租户',
            button: {
                login: 'LOG IN',
            },
        },
    }
};
rsf-admin/src/page/login/index1.jsx
New file
@@ -0,0 +1,261 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { useLocation } from 'react-router-dom';
import {
    Box,
    AppBar,
    Card,
    Toolbar,
    CircularProgress,
    Typography,
    Tabs,
    Tab,
    Button
} from '@mui/material';
import {
    Form,
    required,
    TextInput,
    useTranslate,
    useLogin,
    useNotify,
    SelectInput,
} from 'react-admin';
import { useForm, Controller } from 'react-hook-form';
import { LOGIN_BACKGROUND } from '@/config/setting';
import { tenants } from '@/api/auth';
const Login = () => {
    const translate = useTranslate();
    const [tab, setTab] = useState(0)
    const [tenantList, setTenantList] = useState([]);
    useEffect(() => {
        tenants().then(data => {
            setTenantList(data);
        })
    }, []);
    return (
        <Box
            sx={{
                display: 'flex',
                flexDirection: 'column',
                minHeight: '100vh',
                alignItems: 'center',
                justifyContent: 'flex-start',
                // justifyContent: 'center',
                background: `url(/login_bg.jpg)`, // https://unsplash.com/
                backgroundRepeat: 'no-repeat',
                backgroundSize: 'cover',
            }
            }
        >
            <video
                autoPlay
                loop
                muted
                style={{
                    position: 'fixed',
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%',
                    // objectFit: 'cover',
                    // objectFit: 'contain',
                    objectFit: 'fill',
                    // objectFit: 'scale-down',
                    zIndex: 0,
                }}
            >
                {LOGIN_BACKGROUND === 'media' && (
                    <source src="/login_bg.mp4" type="video/mp4" />
                )}
            </video>
            <Card sx={{
                width: 400,
                marginTop: '6em',
                zIndex: 1
            }}>
                <div>
                    <AppBar position="static" sx={{ backgroundColor: '#3D4BA7' }}>
                        <Toolbar>
                            <Typography variant="h6" color="inherit">Welcome</Typography>
                        </Toolbar>
                    </AppBar>
                </div>
                <Tabs
                    value={tab}
                    onChange={(event, value) => {
                        setTab(value);
                    }}
                    indicatorColor="primary"
                    textColor="primary"
                    variant="fullWidth"
                >
                    <Tab label="Login" sx={{ fontSize: '.8em' }} />
                    <Tab label="Register" sx={{ fontSize: '.8em' }} />
                </Tabs>
                <LoginForm
                    tab={tab}
                    tenantList={tenantList}
                />
                <RegisterForm
                    tab={tab}
                    tenantList={tenantList}
                />
                <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>
                    <Typography variant="caption" align="center">rsf - sever</Typography>
                </Box>
            </Card>
        </Box >
    );
};
const LoginForm = (props) => {
    const translate = useTranslate();
    const notify = useNotify();
    const login = useLogin();
    const location = useLocation();
    const { tab, tenantList } = props;
    const [loading, setLoading] = useState(false);
    const [tenantId, setTenantId] = useState(null);
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [btnDisable, setBtnDisable] = useState(true);
    useEffect(() => {
        if (tenantList.length > 0) {
            setTenantId(tenantList[0].id);
        }
        setBtnDisable(!(tenantId && username && password))
    }, [tenantList, username, password]);
    const handleSubmit = (auth) => {
        console.log(auth);
        setLoading(true);
        // js native confirm && root
        login(
            auth,
            location.state ? (location.state).nextPathname : '/'
        ).catch((error) => {
            setLoading(false);
            notify(
                typeof error === 'string'
                    ? error
                    : typeof error === 'undefined' || !error.message
                        ? 'ra.auth.sign_in_error'
                        : error.message,
                {
                    type: 'error',
                    messageArgs: {
                        _:
                            typeof error === 'string'
                                ? error
                                : error && error.message
                                    ? error.message
                                    : undefined,
                    },
                }
            );
            setUsername(auth.username)
        });
    };
    return (
        <>
            <Form
                onSubmit={handleSubmit}
                noValidate
            >
                <Box
                    hidden={tab !== 0}
                    p={2}
                    display="flex"
                    justifyContent="center"
                    flexDirection='column'
                >
                    <Box width="60%">
                        <SelectInput
                            label="page.login.tenant"
                            source="tenantId"
                            variant="standard"
                            choices={tenantList.map(item => ({
                                id: item.id,
                                name: item.name
                            }))}
                            validate={required()}
                            defaultValue={tenantId}
                            onChange={e => setTenantId(e.target.value)}
                            sx={{ marginTop: 0, marginBottom: 0 }}
                        />
                    </Box>
                    <TextInput
                        label={translate('ra.auth.username')}
                        source="username"
                        variant="standard"
                        disabled={loading}
                        validate={required()}
                        value={username}
                        onChange={e => setUsername(e.target.value)}
                        autoFocus
                        sx={{ marginTop: 0, marginBottom: 0 }}
                    />
                    <TextInput
                        label={translate('ra.auth.password')}
                        source="password"
                        variant="standard"
                        type="password"
                        disabled={loading}
                        validate={required()}
                        value={password}
                        onChange={e => setPassword(e.target.value)}
                        sx={{ marginTop: 0, marginBottom: 0 }}
                    />
                    <Button
                        variant="contained"
                        type="submit"
                        disabled={loading || btnDisable}
                        fullWidth
                        sx={{
                            backgroundColor: "#3D4BA7"
                        }}
                    >
                        {loading && (
                            <CircularProgress size={25} thickness={2} />
                        )}
                        {translate('page.login.button.login')}
                    </Button>
                    <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box>
                </Box >
            </Form>
        </>
    )
}
const RegisterForm = (props) => {
    return (
        <>
            <Box
                hidden={props.tab !== 1}
            >
                Register
            </Box >
        </>
    )
}
export default Login;