mirror of
https://github.com/chaitin/MonkeyCode.git
synced 2026-02-15 13:13:41 +08:00
@@ -9,7 +9,7 @@ const OtherBread = {
|
||||
chat: { title: '对话记录', to: '/chat' },
|
||||
completion: { title: '补全记录', to: '/completion' },
|
||||
model: { title: '模型管理', to: '/model' },
|
||||
user: { title: '用户管理', to: '/user' },
|
||||
user: { title: '成员管理', to: '/user' },
|
||||
admin: { title: '管理员', to: '/admin' },
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ const menus = [
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
label: '用户管理',
|
||||
label: '成员管理',
|
||||
value: '/user',
|
||||
pathname: 'user',
|
||||
icon: 'icon-yonghuguanli1',
|
||||
|
||||
@@ -78,6 +78,9 @@ const ModelItem = ({
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
transition: 'all 0.3s ease',
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px',
|
||||
borderColor: data.is_active ? 'success.main' : 'transparent',
|
||||
boxShadow:
|
||||
'0px 0px 10px 0px rgba(68, 80, 91, 0.1), 0px 0px 2px 0px rgba(68, 80, 91, 0.1)',
|
||||
'&:hover': {
|
||||
|
||||
@@ -72,98 +72,90 @@ const User = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap={2}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid size={6} container>
|
||||
<Grid size={12}>
|
||||
<StyledCard>
|
||||
<StyledLabel>强制成员启用两步认证</StyledLabel>
|
||||
<Switch
|
||||
checked={data?.force_two_factor_auth}
|
||||
onChange={(e) => {
|
||||
updateSetting({ force_two_factor_auth: e.target.checked });
|
||||
}}
|
||||
/>
|
||||
</StyledCard>
|
||||
</Grid>
|
||||
<Grid size={12}>
|
||||
<StyledCard>
|
||||
<StyledLabel>禁止成员使用密码登录</StyledLabel>
|
||||
<Switch
|
||||
checked={data?.disable_password_login}
|
||||
onChange={(e) =>
|
||||
updateSetting({ disable_password_login: e.target.checked })
|
||||
<Stack gap={2} direction={'row'}>
|
||||
<Stack gap={2} direction={'column'}>
|
||||
<MemberManage />
|
||||
</Stack>
|
||||
<Stack gap={2} direction={'column'}>
|
||||
<Card >
|
||||
<StyledLabel>第三方登录</StyledLabel>
|
||||
<Stack
|
||||
direction='row'
|
||||
alignItems='center'
|
||||
spacing={2}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
onClick={() => {
|
||||
if (dingdingCheck) {
|
||||
onDisabledDingdingLogin();
|
||||
} else {
|
||||
setDingdingLoginSettingModalOpen(true);
|
||||
}
|
||||
/>
|
||||
</StyledCard>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid size={6} container>
|
||||
<Grid size={12}>
|
||||
<Card sx={{ height: '100%' }}>
|
||||
<StyledLabel>第三方登录</StyledLabel>
|
||||
<Stack
|
||||
direction='row'
|
||||
alignItems='center'
|
||||
spacing={2}
|
||||
sx={{ mt: 2, height: 'calc(100% - 40px)' }}
|
||||
>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
onClick={() => {
|
||||
if (dingdingCheck) {
|
||||
onDisabledDingdingLogin();
|
||||
} else {
|
||||
setDingdingLoginSettingModalOpen(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} checked={dingdingCheck} />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-dingding' sx={{ fontSize: 18 }}></Icon>
|
||||
钉钉
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Button>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
disabled
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} disabled />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-weixin' sx={{ fontSize: 18 }}></Icon>
|
||||
微信
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Button>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
disabled
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} disabled />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-github' sx={{ fontSize: 18 }}></Icon>
|
||||
GitHub
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Button>
|
||||
}}
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} checked={dingdingCheck} />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-dingding' sx={{ fontSize: 18 }}></Icon>
|
||||
钉钉
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Button>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
disabled
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} disabled />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-weixin' sx={{ fontSize: 18 }}></Icon>
|
||||
微信
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Button>
|
||||
<Button
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
sx={{ gap: 3 }}
|
||||
disabled
|
||||
>
|
||||
<Radio size='small' sx={{ p: 0.5 }} disabled />
|
||||
<Stack direction='row' alignItems='center' gap={2}>
|
||||
<Stack direction='row' alignItems='center' gap={1}>
|
||||
<Icon type='icon-github' sx={{ fontSize: 18 }}></Icon>
|
||||
GitHub
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Card>
|
||||
<StyledCard>
|
||||
<StyledLabel>禁止成员使用密码登录</StyledLabel>
|
||||
<Switch
|
||||
checked={data?.disable_password_login}
|
||||
onChange={(e) =>
|
||||
updateSetting({ disable_password_login: e.target.checked })
|
||||
}
|
||||
/>
|
||||
</StyledCard>
|
||||
<StyledCard>
|
||||
<StyledLabel>强制成员启用两步认证</StyledLabel>
|
||||
<Switch
|
||||
checked={data?.force_two_factor_auth}
|
||||
onChange={(e) => {
|
||||
updateSetting({ force_two_factor_auth: e.target.checked });
|
||||
}}
|
||||
/>
|
||||
</StyledCard>
|
||||
<LoginHistory />
|
||||
</Stack>
|
||||
|
||||
<MemberManage />
|
||||
<LoginHistory />
|
||||
<DingingLoginSettingModal
|
||||
open={dingdingLoginSettingModalOpen}
|
||||
onClose={() => setDingdingLoginSettingModalOpen(false)}
|
||||
|
||||
@@ -11,10 +11,11 @@ import {
|
||||
TextField,
|
||||
Chip,
|
||||
Paper,
|
||||
ButtonBase,
|
||||
Link,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Table, MenuSelect, Modal, message } from '@c-x/ui';
|
||||
import InviteUserModal from './inviteUserModal';
|
||||
@@ -23,6 +24,7 @@ import { ConstsUserStatus, DomainUser } from '@/api/types';
|
||||
import dayjs from 'dayjs';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import ErrorRoundedIcon from '@mui/icons-material/ErrorRounded';
|
||||
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
||||
|
||||
const ResetPasswordModal = ({
|
||||
open,
|
||||
@@ -248,40 +250,39 @@ const MemberManage = () => {
|
||||
{
|
||||
title: '账号',
|
||||
dataIndex: 'username',
|
||||
},
|
||||
{
|
||||
title: '两步认证',
|
||||
dataIndex: 'two_step_auth',
|
||||
render: (text) => {
|
||||
return text ? (
|
||||
<Chip label='启动' color='success' size='small' />
|
||||
) : (
|
||||
<Chip label='未启用' size='small' />
|
||||
);
|
||||
render: (text, record) => {
|
||||
return <>
|
||||
<Stack>
|
||||
<Link onClick={() => navigate(`/dashboard/member/${record.id}`)} sx={{
|
||||
'&:hover': {
|
||||
color: 'info.main',
|
||||
},
|
||||
cursor: 'pointer'
|
||||
}}>
|
||||
<Stack direction={'row'}>
|
||||
<AccountCircleIcon fontSize='small' sx={{ mr: 1, lineHeight: 24 }}/>
|
||||
<Typography>{text}</Typography>
|
||||
</Stack>
|
||||
</Link>
|
||||
<Typography color='text.auxiliary'>{record.email}</Typography>
|
||||
</Stack>
|
||||
</>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '最近活跃时间',
|
||||
title: '加入时间',
|
||||
dataIndex: 'created_at',
|
||||
width: 120,
|
||||
render: (text) => {
|
||||
return dayjs.unix(text).fromNow();
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '最近活跃',
|
||||
dataIndex: 'last_active_at',
|
||||
render: (text) => {
|
||||
return dayjs.unix(text).format('YYYY-MM-DD HH:mm:ss');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '统计使用情况',
|
||||
dataIndex: 'status',
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<ButtonBase
|
||||
disableRipple
|
||||
onClick={() => navigate(`/dashboard/member/${record.id}`)}
|
||||
sx={{
|
||||
color: 'info.main',
|
||||
}}
|
||||
>
|
||||
点击查看
|
||||
</ButtonBase>
|
||||
);
|
||||
width: 120,
|
||||
render: (text, record) => {
|
||||
return record.last_active_at === 0 ? '从未使用' : dayjs.unix(text).fromNow();
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user