Feat(Hint): Support dark mode
This commit is contained in:
@@ -4,6 +4,7 @@ import BaseStyles from '@/assets/css/base.style'
|
|||||||
import CommonStyles from '@/assets/css/common.style'
|
import CommonStyles from '@/assets/css/common.style'
|
||||||
import { COLOR_PRODUCTION } from '@/constants/common.constants'
|
import { COLOR_PRODUCTION } from '@/constants/common.constants'
|
||||||
import { getRouter } from '@/router'
|
import { getRouter } from '@/router'
|
||||||
|
import { init } from '@/util/common'
|
||||||
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
|
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
|
||||||
|
|
||||||
export const AppContext = createContext({
|
export const AppContext = createContext({
|
||||||
@@ -12,10 +13,14 @@ export const AppContext = createContext({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
const [messageInstance, messageHolder] = message.useMessage()
|
||||||
|
const [notificationInstance, notificationHolder] = notification.useNotification()
|
||||||
|
const [modalInstance, modalHolder] = AntdModal.useModal()
|
||||||
const [routerState, setRouterState] = useState(getRouter)
|
const [routerState, setRouterState] = useState(getRouter)
|
||||||
const [isDarkMode, setIsDarkMode] = useState(false)
|
const [isDarkMode, setIsDarkMode] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
init(messageInstance, notificationInstance, modalInstance)
|
||||||
const darkThemeMq = window.matchMedia('(prefers-color-scheme: dark)')
|
const darkThemeMq = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
setIsDarkMode(darkThemeMq.matches)
|
setIsDarkMode(darkThemeMq.matches)
|
||||||
const listener = (ev: MediaQueryListEvent) => {
|
const listener = (ev: MediaQueryListEvent) => {
|
||||||
@@ -59,6 +64,9 @@ const App = () => {
|
|||||||
<RouterProvider router={routerState} />
|
<RouterProvider router={routerState} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</AppContext.Provider>
|
</AppContext.Provider>
|
||||||
|
{messageHolder}
|
||||||
|
{notificationHolder}
|
||||||
|
{modalHolder}
|
||||||
</AntdConfigProvider>
|
</AntdConfigProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export default createGlobalStyle(() => ({
|
|||||||
li: { listStyle: 'none' },
|
li: { listStyle: 'none' },
|
||||||
img: { border: 0, verticalAlign: 'middle' },
|
img: { border: 0, verticalAlign: 'middle' },
|
||||||
button: { cursor: 'pointer' },
|
button: { cursor: 'pointer' },
|
||||||
a: { color: '#666', textDecoration: 'none' },
|
a: { color: '#666', textDecoration: 'none', whiteSpace: 'nowrap' },
|
||||||
'button, input': {
|
'button, input': {
|
||||||
fontFamily:
|
fontFamily:
|
||||||
'Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\\5B8B\\4F53", sans-serif',
|
'Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\\5B8B\\4F53", sans-serif',
|
||||||
|
|||||||
@@ -4,9 +4,15 @@ import useStyles from '@/assets/css/components/common/card.style'
|
|||||||
type CardProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
|
type CardProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
|
||||||
|
|
||||||
const Card = forwardRef<HTMLDivElement, CardProps>(({ className, ...props }, ref) => {
|
const Card = forwardRef<HTMLDivElement, CardProps>(({ className, ...props }, ref) => {
|
||||||
const { styles, cx } = useStyles()
|
const { styles } = useStyles()
|
||||||
|
|
||||||
return <div className={cx(styles.cardBox, className)} {...props} ref={ref} />
|
return (
|
||||||
|
<div
|
||||||
|
className={`${styles.cardBox}${className ? ` ${className}` : ''}`}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
export default Card
|
export default Card
|
||||||
|
|||||||
@@ -6,15 +6,11 @@ interface FitCenterProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FitCenter = ({ className, vertical, ...props }: FitCenterProps) => {
|
const FitCenter = ({ className, vertical, ...props }: FitCenterProps) => {
|
||||||
const { styles, cx } = useStyles()
|
const { styles } = useStyles()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={`${styles.fitCenter}${vertical ? ' flex-vertical' : ' flex-horizontal'}${className ? ` ${className}` : ''}`}
|
||||||
styles.fitCenter,
|
|
||||||
className,
|
|
||||||
vertical ? ' flex-vertical' : ' flex-horizontal'
|
|
||||||
)}
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ interface FitFullscreenProps
|
|||||||
|
|
||||||
const FitFullscreen = forwardRef<HTMLDivElement, FitFullscreenProps>(
|
const FitFullscreen = forwardRef<HTMLDivElement, FitFullscreenProps>(
|
||||||
({ zIndex, backgroundColor, className, style, ...props }, ref) => {
|
({ zIndex, backgroundColor, className, style, ...props }, ref) => {
|
||||||
const { styles, cx } = useStyles()
|
const { styles } = useStyles()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(styles.fitFullscreen, className)}
|
className={`${styles.fitFullscreen}${className ? ` ${className}` : ''}`}
|
||||||
style={{
|
style={{
|
||||||
zIndex,
|
zIndex,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
|||||||
@@ -8,15 +8,11 @@ interface FlexBoxProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>,
|
|||||||
|
|
||||||
const FlexBox = forwardRef<HTMLDivElement, FlexBoxProps>(
|
const FlexBox = forwardRef<HTMLDivElement, FlexBoxProps>(
|
||||||
({ className, direction, gap, style, ...props }, ref) => {
|
({ className, direction, gap, style, ...props }, ref) => {
|
||||||
const { styles, cx } = useStyles()
|
const { styles } = useStyles()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={`${styles.flexBox}${direction === 'horizontal' ? ' flex-horizontal' : ' flex-vertical'}${className ? ` ${className}` : ''}`}
|
||||||
styles.flexBox,
|
|
||||||
className,
|
|
||||||
direction === 'horizontal' ? 'flex-horizontal' : 'flex-vertical'
|
|
||||||
)}
|
|
||||||
style={{ gap, ...style }}
|
style={{ gap, ...style }}
|
||||||
{...props}
|
{...props}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
ref={rootRef}
|
ref={rootRef}
|
||||||
className={cx(styles.hideScrollbarSelection, className)}
|
className={`${styles.hideScrollbarSelection}${className ? ` ${className}` : ''}`}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
style={{
|
style={{
|
||||||
width: `calc(${maskRef.current?.clientWidth}px + ${verticalScrollbarWidth}px)`,
|
width: `calc(${maskRef.current?.clientWidth}px + ${verticalScrollbarWidth}px)`,
|
||||||
@@ -571,7 +571,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
|
|||||||
className={cx(
|
className={cx(
|
||||||
styles.scrollbar,
|
styles.scrollbar,
|
||||||
styles.verticalScrollbar,
|
styles.verticalScrollbar,
|
||||||
isVerticalScrollbarAutoHide ? ` ${styles.hide}` : ''
|
isVerticalScrollbarAutoHide ? styles.hide : ''
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
height: maskRef.current
|
height: maskRef.current
|
||||||
@@ -619,7 +619,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
|
|||||||
className={cx(
|
className={cx(
|
||||||
styles.scrollbar,
|
styles.scrollbar,
|
||||||
styles.horizontalScrollbar,
|
styles.horizontalScrollbar,
|
||||||
isHorizontalScrollbarAutoHide ? ` ${styles.hide}` : ''
|
isHorizontalScrollbarAutoHide ? styles.hide : ''
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
width: maskRef.current
|
width: maskRef.current
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import useStyles from '@/assets/css/components/common/sidebar/footer.style'
|
import useStyles from '@/assets/css/components/common/sidebar/footer.style'
|
||||||
import { SidebarContext } from '@/components/common/Sidebar/index'
|
import { SidebarContext } from '@/components/common/Sidebar/index'
|
||||||
|
import { notification } from '@/util/common'
|
||||||
import { getRedirectUrl } from '@/util/route'
|
import { getRedirectUrl } from '@/util/route'
|
||||||
import { getAvatar, getLoginStatus, getNickname, removeToken } from '@/util/auth'
|
import { getAvatar, getLoginStatus, getNickname, removeToken } from '@/util/auth'
|
||||||
import { navigateToLogin, navigateToUser } from '@/util/navigation'
|
import { navigateToLogin, navigateToUser } from '@/util/navigation'
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
|
|||||||
import protocolCheck from 'custom-protocol-check'
|
import protocolCheck from 'custom-protocol-check'
|
||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import useStyles from '@/assets/css/components/tools/store-card.style'
|
import useStyles from '@/assets/css/components/tools/store-card.style'
|
||||||
import {
|
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
DATABASE_SELECT_SUCCESS
|
import { message, modal, checkDesktop, omitTextByByte } from '@/util/common'
|
||||||
} from '@/constants/common.constants'
|
|
||||||
import { checkDesktop, omitTextByByte } from '@/util/common'
|
|
||||||
import { getLoginStatus, getUserId } from '@/util/auth'
|
import { getLoginStatus, getUserId } from '@/util/auth'
|
||||||
import {
|
import {
|
||||||
getAndroidUrl,
|
getAndroidUrl,
|
||||||
@@ -67,7 +65,6 @@ const StoreCard = ({
|
|||||||
}: StoreCardProps) => {
|
}: StoreCardProps) => {
|
||||||
const { styles, theme } = useStyles()
|
const { styles, theme } = useStyles()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const cardRef = useRef<HTMLDivElement>(null)
|
const cardRef = useRef<HTMLDivElement>(null)
|
||||||
const [favorite_, setFavorite_] = useState<boolean>(favorite)
|
const [favorite_, setFavorite_] = useState<boolean>(favorite)
|
||||||
const [userId, setUserId] = useState('')
|
const [userId, setUserId] = useState('')
|
||||||
@@ -90,6 +87,7 @@ const StoreCard = ({
|
|||||||
if (platform === 'ANDROID') {
|
if (platform === 'ANDROID') {
|
||||||
void modal.confirm({
|
void modal.confirm({
|
||||||
centered: true,
|
centered: true,
|
||||||
|
keyboard: false,
|
||||||
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
|
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
|
||||||
title: 'Android 端',
|
title: 'Android 端',
|
||||||
content: (
|
content: (
|
||||||
@@ -211,6 +209,7 @@ const StoreCard = ({
|
|||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
void modal.confirm({
|
void modal.confirm({
|
||||||
centered: true,
|
centered: true,
|
||||||
|
keyboard: false,
|
||||||
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
|
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
|
||||||
title: 'Android 端',
|
title: 'Android 端',
|
||||||
content: (
|
content: (
|
||||||
@@ -281,123 +280,117 @@ const StoreCard = ({
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Draggable
|
||||||
<Draggable
|
id={`${author.username}:${toolId}:${ver}:${platform}`}
|
||||||
id={`${author.username}:${toolId}:${ver}:${platform}`}
|
data={{
|
||||||
data={{
|
icon,
|
||||||
icon,
|
toolName,
|
||||||
toolName,
|
toolId,
|
||||||
toolId,
|
authorUsername: author.username,
|
||||||
authorUsername: author.username,
|
ver: '',
|
||||||
ver: '',
|
platform
|
||||||
platform
|
}}
|
||||||
}}
|
>
|
||||||
|
<Card
|
||||||
|
style={{ overflow: 'visible', ...style }}
|
||||||
|
ref={cardRef}
|
||||||
|
{...props}
|
||||||
|
onClick={handleCardOnClick}
|
||||||
>
|
>
|
||||||
<Card
|
<FlexBox className={styles.root}>
|
||||||
style={{ overflow: 'visible', ...style }}
|
<div className={styles.header}>
|
||||||
ref={cardRef}
|
<div className={styles.version}>
|
||||||
{...props}
|
<AntdTag>
|
||||||
onClick={handleCardOnClick}
|
{platform.slice(0, 1)}-{ver}
|
||||||
>
|
</AntdTag>
|
||||||
<FlexBox className={styles.root}>
|
</div>
|
||||||
<div className={styles.header}>
|
<div className={styles.operation}>
|
||||||
<div className={styles.version}>
|
{(!isInstalled || isAvailableUpdate) && (
|
||||||
<AntdTag>
|
<AntdTooltip title={isAvailableUpdate ? '更新' : '安装'}>
|
||||||
{platform.slice(0, 1)}-{ver}
|
|
||||||
</AntdTag>
|
|
||||||
</div>
|
|
||||||
<div className={styles.operation}>
|
|
||||||
{(!isInstalled || isAvailableUpdate) && (
|
|
||||||
<AntdTooltip title={isAvailableUpdate ? '更新' : '安装'}>
|
|
||||||
<Icon
|
|
||||||
component={IconOxygenDownload}
|
|
||||||
onClick={handleOnInstallBtnClick}
|
|
||||||
disabled={isInstalling}
|
|
||||||
/>
|
|
||||||
</AntdTooltip>
|
|
||||||
)}
|
|
||||||
{platform !== 'ANDROID' && supportPlatform.includes('ANDROID') && (
|
|
||||||
<AntdTooltip title={'Android 端'}>
|
|
||||||
<Icon
|
|
||||||
component={IconOxygenMobile}
|
|
||||||
onClick={handleOnAndroidBtnClick}
|
|
||||||
/>
|
|
||||||
</AntdTooltip>
|
|
||||||
)}
|
|
||||||
{platform === 'DESKTOP' && supportPlatform.includes('WEB') && (
|
|
||||||
<AntdTooltip title={'Web 端'}>
|
|
||||||
<Icon
|
|
||||||
component={IconOxygenBrowser}
|
|
||||||
onClick={handleOnWebBtnClick}
|
|
||||||
/>
|
|
||||||
</AntdTooltip>
|
|
||||||
)}
|
|
||||||
{platform === 'WEB' && supportPlatform.includes('DESKTOP') && (
|
|
||||||
<AntdTooltip title={'桌面端'}>
|
|
||||||
<Icon
|
|
||||||
component={IconOxygenDesktop}
|
|
||||||
onClick={handleOnDesktopBtnClick}
|
|
||||||
/>
|
|
||||||
</AntdTooltip>
|
|
||||||
)}
|
|
||||||
<AntdTooltip title={'源码'}>
|
|
||||||
<Icon
|
<Icon
|
||||||
component={IconOxygenCode}
|
component={IconOxygenDownload}
|
||||||
onClick={handleOnSourceBtnClick}
|
onClick={handleOnInstallBtnClick}
|
||||||
|
disabled={isInstalling}
|
||||||
/>
|
/>
|
||||||
</AntdTooltip>
|
</AntdTooltip>
|
||||||
{author.id !== userId && (
|
|
||||||
<AntdTooltip title={favorite_ ? '取消收藏' : '收藏'}>
|
|
||||||
<Icon
|
|
||||||
component={
|
|
||||||
favorite_ ? IconOxygenStarFilled : IconOxygenStar
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
color: favorite_ ? theme.colorPrimary : undefined
|
|
||||||
}}
|
|
||||||
onClick={handleOnStarBtnClick}
|
|
||||||
/>
|
|
||||||
</AntdTooltip>
|
|
||||||
)}
|
|
||||||
<DragHandle />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.icon}>
|
|
||||||
<img src={`data:image/svg+xml;base64,${icon}`} alt={'Icon'} />
|
|
||||||
</div>
|
|
||||||
<div className={styles.info}>
|
|
||||||
<div className={styles.toolName} title={toolName}>
|
|
||||||
{toolName}
|
|
||||||
</div>
|
|
||||||
<div>{`ID: ${toolId}`}</div>
|
|
||||||
{toolDesc && (
|
|
||||||
<div className={styles.toolDesc} title={toolDesc}>
|
|
||||||
{omitTextByByte(toolDesc, 64)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
{platform !== 'ANDROID' && supportPlatform.includes('ANDROID') && (
|
||||||
{showAuthor && (
|
<AntdTooltip title={'Android 端'}>
|
||||||
<div className={styles.author} onClick={handleOnClickAuthor}>
|
<Icon
|
||||||
<div className={styles.avatar}>
|
component={IconOxygenMobile}
|
||||||
<AntdAvatar
|
onClick={handleOnAndroidBtnClick}
|
||||||
src={
|
|
||||||
<AntdImage
|
|
||||||
preview={false}
|
|
||||||
src={`data:image/png;base64,${author.userInfo.avatar}`}
|
|
||||||
alt={'Avatar'}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
style={{ background: theme.colorBgLayout }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</AntdTooltip>
|
||||||
<div className={styles.authorName}>{author.userInfo.nickname}</div>
|
)}
|
||||||
|
{platform === 'DESKTOP' && supportPlatform.includes('WEB') && (
|
||||||
|
<AntdTooltip title={'Web 端'}>
|
||||||
|
<Icon
|
||||||
|
component={IconOxygenBrowser}
|
||||||
|
onClick={handleOnWebBtnClick}
|
||||||
|
/>
|
||||||
|
</AntdTooltip>
|
||||||
|
)}
|
||||||
|
{platform === 'WEB' && supportPlatform.includes('DESKTOP') && (
|
||||||
|
<AntdTooltip title={'桌面端'}>
|
||||||
|
<Icon
|
||||||
|
component={IconOxygenDesktop}
|
||||||
|
onClick={handleOnDesktopBtnClick}
|
||||||
|
/>
|
||||||
|
</AntdTooltip>
|
||||||
|
)}
|
||||||
|
<AntdTooltip title={'源码'}>
|
||||||
|
<Icon component={IconOxygenCode} onClick={handleOnSourceBtnClick} />
|
||||||
|
</AntdTooltip>
|
||||||
|
{author.id !== userId && (
|
||||||
|
<AntdTooltip title={favorite_ ? '取消收藏' : '收藏'}>
|
||||||
|
<Icon
|
||||||
|
component={
|
||||||
|
favorite_ ? IconOxygenStarFilled : IconOxygenStar
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
color: favorite_ ? theme.colorPrimary : undefined
|
||||||
|
}}
|
||||||
|
onClick={handleOnStarBtnClick}
|
||||||
|
/>
|
||||||
|
</AntdTooltip>
|
||||||
|
)}
|
||||||
|
<DragHandle />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.icon}>
|
||||||
|
<img src={`data:image/svg+xml;base64,${icon}`} alt={'Icon'} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.info}>
|
||||||
|
<div className={styles.toolName} title={toolName}>
|
||||||
|
{toolName}
|
||||||
|
</div>
|
||||||
|
<div>{`ID: ${toolId}`}</div>
|
||||||
|
{toolDesc && (
|
||||||
|
<div className={styles.toolDesc} title={toolDesc}>
|
||||||
|
{omitTextByByte(toolDesc, 64)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</FlexBox>
|
</div>
|
||||||
</Card>
|
{showAuthor && (
|
||||||
</Draggable>
|
<div className={styles.author} onClick={handleOnClickAuthor}>
|
||||||
{contextHolder}
|
<div className={styles.avatar}>
|
||||||
</>
|
<AntdAvatar
|
||||||
|
src={
|
||||||
|
<AntdImage
|
||||||
|
preview={false}
|
||||||
|
src={`data:image/png;base64,${author.userInfo.avatar}`}
|
||||||
|
alt={'Avatar'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
style={{ background: theme.colorBgLayout }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={styles.authorName}>{author.userInfo.nickname}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</FlexBox>
|
||||||
|
</Card>
|
||||||
|
</Draggable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
PERMISSION_USER_NOT_FOUND,
|
PERMISSION_USER_NOT_FOUND,
|
||||||
SYSTEM_INVALID_CAPTCHA_CODE
|
SYSTEM_INVALID_CAPTCHA_CODE
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { navigateToLogin } from '@/util/navigation'
|
import { navigateToLogin } from '@/util/navigation'
|
||||||
import { r_auth_forget, r_auth_retrieve } from '@/services/auth'
|
import { r_auth_forget, r_auth_retrieve } from '@/services/auth'
|
||||||
import { AppContext } from '@/App'
|
import { AppContext } from '@/App'
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
PERMISSION_USERNAME_NOT_FOUND,
|
PERMISSION_USERNAME_NOT_FOUND,
|
||||||
SYSTEM_INVALID_CAPTCHA_CODE
|
SYSTEM_INVALID_CAPTCHA_CODE
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, notification, modal } from '@/util/common'
|
||||||
import { getUserInfo, setToken } from '@/util/auth'
|
import { getUserInfo, setToken } from '@/util/auth'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import {
|
import {
|
||||||
@@ -26,7 +27,6 @@ import FlexBox from '@/components/common/FlexBox'
|
|||||||
|
|
||||||
const SignIn = () => {
|
const SignIn = () => {
|
||||||
const { styles } = useStyles()
|
const { styles } = useStyles()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const { refreshRouter, isDarkMode } = useContext(AppContext)
|
const { refreshRouter, isDarkMode } = useContext(AppContext)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
@@ -82,8 +82,7 @@ const SignIn = () => {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case PERMISSION_LOGIN_SUCCESS:
|
case PERMISSION_LOGIN_SUCCESS:
|
||||||
setToken(data?.token ?? '')
|
setToken(data?.token ?? '')
|
||||||
void message.success('登录成功')
|
message.success('登录成功').then(() => {
|
||||||
setTimeout(() => {
|
|
||||||
void getUserInfo().then((user) => {
|
void getUserInfo().then((user) => {
|
||||||
refreshRouter()
|
refreshRouter()
|
||||||
navigateToRedirect(navigate, searchParams, '/repository')
|
navigateToRedirect(navigate, searchParams, '/repository')
|
||||||
@@ -109,7 +108,7 @@ const SignIn = () => {
|
|||||||
placement: 'topRight'
|
placement: 'topRight'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, 1500)
|
})
|
||||||
break
|
break
|
||||||
case PERMISSION_NEED_TWO_FACTOR:
|
case PERMISSION_NEED_TWO_FACTOR:
|
||||||
twoFactorForm.resetFields()
|
twoFactorForm.resetFields()
|
||||||
@@ -299,7 +298,6 @@ const SignIn = () => {
|
|||||||
</div>
|
</div>
|
||||||
</AntdForm>
|
</AntdForm>
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
{contextHolder}
|
|
||||||
</FitCenter>
|
</FitCenter>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
SYSTEM_INVALID_CAPTCHA_CODE,
|
SYSTEM_INVALID_CAPTCHA_CODE,
|
||||||
SYSTEM_MATCH_SENSITIVE_WORD
|
SYSTEM_MATCH_SENSITIVE_WORD
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { getLoginStatus, setToken } from '@/util/auth'
|
import { getLoginStatus, setToken } from '@/util/auth'
|
||||||
import { navigateToLogin } from '@/util/navigation'
|
import { navigateToLogin } from '@/util/navigation'
|
||||||
import { r_auth_register, r_auth_resend } from '@/services/auth'
|
import { r_auth_register, r_auth_resend } from '@/services/auth'
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
PERMISSION_VERIFY_SUCCESS,
|
PERMISSION_VERIFY_SUCCESS,
|
||||||
SYSTEM_MATCH_SENSITIVE_WORD
|
SYSTEM_MATCH_SENSITIVE_WORD
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
|
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
|
||||||
import { navigateToLogin, navigateToRedirect, navigateToRepository } from '@/util/navigation'
|
import { navigateToLogin, navigateToRedirect, navigateToRepository } from '@/util/navigation'
|
||||||
import { r_auth_resend, r_auth_verify } from '@/services/auth'
|
import { r_auth_resend, r_auth_verify } from '@/services/auth'
|
||||||
@@ -125,13 +126,12 @@ const Verify = () => {
|
|||||||
const response = res.data
|
const response = res.data
|
||||||
switch (response.code) {
|
switch (response.code) {
|
||||||
case PERMISSION_VERIFY_SUCCESS:
|
case PERMISSION_VERIFY_SUCCESS:
|
||||||
void message.success('恭喜你,完成了')
|
message.success('恭喜你,完成了').then(() => {
|
||||||
setTimeout(() => {
|
|
||||||
void requestUserInfo().then(() => {
|
void requestUserInfo().then(() => {
|
||||||
refreshRouter()
|
refreshRouter()
|
||||||
navigateToRedirect(navigate, searchParams, '/repository')
|
navigateToRedirect(navigate, searchParams, '/repository')
|
||||||
})
|
})
|
||||||
}, 1500)
|
})
|
||||||
break
|
break
|
||||||
case SYSTEM_MATCH_SENSITIVE_WORD:
|
case SYSTEM_MATCH_SENSITIVE_WORD:
|
||||||
void message.error('昵称包含敏感词,请重试')
|
void message.error('昵称包含敏感词,请重试')
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import {
|
import {
|
||||||
@@ -27,7 +28,6 @@ import Card from '@/components/common/Card'
|
|||||||
|
|
||||||
const Group = () => {
|
const Group = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [form] = AntdForm.useForm<GroupAddEditParam>()
|
const [form] = AntdForm.useForm<GroupAddEditParam>()
|
||||||
const formValues = AntdForm.useWatch([], form)
|
const formValues = AntdForm.useWatch([], form)
|
||||||
const [newFormValues, setNewFormValues] = useState<GroupAddEditParam>()
|
const [newFormValues, setNewFormValues] = useState<GroupAddEditParam>()
|
||||||
@@ -246,7 +246,7 @@ const Group = () => {
|
|||||||
centered: true,
|
centered: true,
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
title: '确定删除',
|
title: '确定删除',
|
||||||
content: `确定删除角色 ${value.name} 吗?`
|
content: `确定删除用户组 ${value.name} 吗?`
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
(confirmed) => {
|
(confirmed) => {
|
||||||
@@ -300,7 +300,7 @@ const Group = () => {
|
|||||||
getGroup()
|
getGroup()
|
||||||
break
|
break
|
||||||
case DATABASE_DUPLICATE_KEY:
|
case DATABASE_DUPLICATE_KEY:
|
||||||
void message.error('已存在相同名称的角色')
|
void message.error('已存在相同名称的用户组')
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('更新失败,请稍后重试')
|
void message.error('更新失败,请稍后重试')
|
||||||
@@ -321,7 +321,7 @@ const Group = () => {
|
|||||||
getGroup()
|
getGroup()
|
||||||
break
|
break
|
||||||
case DATABASE_DUPLICATE_KEY:
|
case DATABASE_DUPLICATE_KEY:
|
||||||
void message.error('已存在相同名称的角色')
|
void message.error('已存在相同名称的用户组')
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('添加失败,请稍后重试')
|
void message.error('添加失败,请稍后重试')
|
||||||
@@ -563,6 +563,7 @@ const Group = () => {
|
|||||||
rowKey={(record) => record.id}
|
rowKey={(record) => record.id}
|
||||||
pagination={tableParams.pagination}
|
pagination={tableParams.pagination}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
scroll={{ x: true }}
|
||||||
onChange={handleOnTableChange}
|
onChange={handleOnTableChange}
|
||||||
rowSelection={
|
rowSelection={
|
||||||
hasPermission('system:group:delete:multiple')
|
hasPermission('system:group:delete:multiple')
|
||||||
@@ -657,7 +658,6 @@ const Group = () => {
|
|||||||
>
|
>
|
||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
{contextHolder}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ChangeEvent, KeyboardEvent } from 'react'
|
|||||||
import { useTheme } from 'antd-style'
|
import { useTheme } from 'antd-style'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { dayjsToUtc, utcToLocalTime } from '@/util/datetime'
|
import { dayjsToUtc, utcToLocalTime } from '@/util/datetime'
|
||||||
import { r_sys_log_get } from '@/services/system'
|
import { r_sys_log_get } from '@/services/system'
|
||||||
import FitFullscreen from '@/components/common/FitFullscreen'
|
import FitFullscreen from '@/components/common/FitFullscreen'
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { hasPermission, powerListToPowerTree } from '@/util/auth'
|
import { hasPermission, powerListToPowerTree } from '@/util/auth'
|
||||||
import {
|
import {
|
||||||
@@ -27,7 +28,6 @@ import Card from '@/components/common/Card'
|
|||||||
|
|
||||||
const Role = () => {
|
const Role = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [form] = AntdForm.useForm<RoleAddEditParam>()
|
const [form] = AntdForm.useForm<RoleAddEditParam>()
|
||||||
const formValues = AntdForm.useWatch([], form)
|
const formValues = AntdForm.useWatch([], form)
|
||||||
const [newFormValues, setNewFormValues] = useState<RoleAddEditParam>()
|
const [newFormValues, setNewFormValues] = useState<RoleAddEditParam>()
|
||||||
@@ -572,6 +572,7 @@ const Role = () => {
|
|||||||
rowKey={(record) => record.id}
|
rowKey={(record) => record.id}
|
||||||
pagination={tableParams.pagination}
|
pagination={tableParams.pagination}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
scroll={{ x: true }}
|
||||||
onChange={handleOnTableChange}
|
onChange={handleOnTableChange}
|
||||||
rowSelection={
|
rowSelection={
|
||||||
hasPermission('system:role:delete:multiple')
|
hasPermission('system:role:delete:multiple')
|
||||||
@@ -664,7 +665,6 @@ const Role = () => {
|
|||||||
>
|
>
|
||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
{contextHolder}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { message } from '@/util/common'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import { r_sys_settings_base_get, r_sys_settings_base_update } from '@/services/system'
|
import { r_sys_settings_base_get, r_sys_settings_base_update } from '@/services/system'
|
||||||
import SettingsCard from '@/components/system/SettingCard'
|
import SettingsCard from '@/components/system/SettingCard'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import {
|
import {
|
||||||
r_sys_settings_mail_get,
|
r_sys_settings_mail_get,
|
||||||
@@ -8,7 +9,6 @@ import {
|
|||||||
import SettingsCard from '@/components/system/SettingCard'
|
import SettingsCard from '@/components/system/SettingCard'
|
||||||
|
|
||||||
const Mail = () => {
|
const Mail = () => {
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [mailForm] = AntdForm.useForm<MailSettingsParam>()
|
const [mailForm] = AntdForm.useForm<MailSettingsParam>()
|
||||||
const mailFormValues = AntdForm.useWatch([], mailForm)
|
const mailFormValues = AntdForm.useWatch([], mailForm)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
@@ -114,59 +114,56 @@ const Mail = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<SettingsCard
|
||||||
<SettingsCard
|
icon={IconOxygenEmail}
|
||||||
icon={IconOxygenEmail}
|
title={'邮件'}
|
||||||
title={'邮件'}
|
loading={isLoading}
|
||||||
loading={isLoading}
|
onReset={handleOnReset}
|
||||||
onReset={handleOnReset}
|
onSave={handleOnSave}
|
||||||
onSave={handleOnSave}
|
modifyOperationCode={['system:settings:modify:mail']}
|
||||||
modifyOperationCode={['system:settings:modify:mail']}
|
expand={
|
||||||
expand={
|
<AntdButton onClick={handleOnTest} title={'测试'}>
|
||||||
<AntdButton onClick={handleOnTest} title={'测试'}>
|
<Icon component={IconOxygenTest} />
|
||||||
<Icon component={IconOxygenTest} />
|
</AntdButton>
|
||||||
</AntdButton>
|
}
|
||||||
}
|
>
|
||||||
|
<AntdForm
|
||||||
|
form={mailForm}
|
||||||
|
labelCol={{ flex: '8em' }}
|
||||||
|
disabled={!hasPermission('system:settings:modify:mail')}
|
||||||
>
|
>
|
||||||
<AntdForm
|
<AntdForm.Item label={'SMTP 服务器'} name={'host'}>
|
||||||
form={mailForm}
|
<AntdInput placeholder={'请输入 SMTP 服务器'} />
|
||||||
labelCol={{ flex: '8em' }}
|
</AntdForm.Item>
|
||||||
disabled={!hasPermission('system:settings:modify:mail')}
|
<AntdForm.Item label={'端口号'} name={'port'}>
|
||||||
>
|
<AntdInputNumber
|
||||||
<AntdForm.Item label={'SMTP 服务器'} name={'host'}>
|
min={0}
|
||||||
<AntdInput placeholder={'请输入 SMTP 服务器'} />
|
max={65535}
|
||||||
</AntdForm.Item>
|
style={{ width: '100%' }}
|
||||||
<AntdForm.Item label={'端口号'} name={'port'}>
|
placeholder={'请输入端口号'}
|
||||||
<AntdInputNumber
|
/>
|
||||||
min={0}
|
</AntdForm.Item>
|
||||||
max={65535}
|
<AntdForm.Item label={'安全类型'} name={'securityType'}>
|
||||||
style={{ width: '100%' }}
|
<AntdSelect placeholder={'请选择安全类型'}>
|
||||||
placeholder={'请输入端口号'}
|
<AntdSelect.Option key={'None'}>None</AntdSelect.Option>
|
||||||
/>
|
<AntdSelect.Option key={'SSL/TLS'}>SSL/TLS</AntdSelect.Option>
|
||||||
</AntdForm.Item>
|
<AntdSelect.Option key={'StartTls'}>StartTls</AntdSelect.Option>
|
||||||
<AntdForm.Item label={'安全类型'} name={'securityType'}>
|
</AntdSelect>
|
||||||
<AntdSelect placeholder={'请选择安全类型'}>
|
</AntdForm.Item>
|
||||||
<AntdSelect.Option key={'None'}>None</AntdSelect.Option>
|
<AntdForm.Item label={'用户名'} name={'username'}>
|
||||||
<AntdSelect.Option key={'SSL/TLS'}>SSL/TLS</AntdSelect.Option>
|
<AntdInput placeholder={'请输入用户名'} />
|
||||||
<AntdSelect.Option key={'StartTls'}>StartTls</AntdSelect.Option>
|
</AntdForm.Item>
|
||||||
</AntdSelect>
|
<AntdForm.Item label={'密码'} name={'password'}>
|
||||||
</AntdForm.Item>
|
<AntdInput.Password placeholder={'请输入密码'} />
|
||||||
<AntdForm.Item label={'用户名'} name={'username'}>
|
</AntdForm.Item>
|
||||||
<AntdInput placeholder={'请输入用户名'} />
|
<AntdForm.Item label={'发送者'} name={'from'}>
|
||||||
</AntdForm.Item>
|
<AntdInput placeholder={'请输入发送者'} />
|
||||||
<AntdForm.Item label={'密码'} name={'password'}>
|
</AntdForm.Item>
|
||||||
<AntdInput.Password placeholder={'请输入密码'} />
|
<AntdForm.Item label={'发送者名称'} name={'fromName'}>
|
||||||
</AntdForm.Item>
|
<AntdInput placeholder={'请输入发送者名称'} />
|
||||||
<AntdForm.Item label={'发送者'} name={'from'}>
|
</AntdForm.Item>
|
||||||
<AntdInput placeholder={'请输入发送者'} />
|
</AntdForm>
|
||||||
</AntdForm.Item>
|
</SettingsCard>
|
||||||
<AntdForm.Item label={'发送者名称'} name={'fromName'}>
|
|
||||||
<AntdInput placeholder={'请输入发送者名称'} />
|
|
||||||
</AntdForm.Item>
|
|
||||||
</AntdForm>
|
|
||||||
</SettingsCard>
|
|
||||||
{contextHolder}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ChangeEvent } from 'react'
|
import { ChangeEvent } from 'react'
|
||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import { DATABASE_DUPLICATE_KEY, DATABASE_INSERT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_DUPLICATE_KEY, DATABASE_INSERT_SUCCESS } from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import {
|
import {
|
||||||
r_sys_settings_sensitive_add,
|
r_sys_settings_sensitive_add,
|
||||||
r_sys_settings_sensitive_delete,
|
r_sys_settings_sensitive_delete,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { message } from '@/util/common'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import { r_sys_settings_two_factor_get, r_sys_settings_two_factor_update } from '@/services/system'
|
import { r_sys_settings_two_factor_get, r_sys_settings_two_factor_update } from '@/services/system'
|
||||||
import SettingsCard from '@/components/system/SettingCard'
|
import SettingsCard from '@/components/system/SettingCard'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import useStyles from '@/assets/css/pages/system/statistics/common.style'
|
import useStyles from '@/assets/css/pages/system/statistics/common.style'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { r_sys_statistics_hardware } from '@/services/system'
|
import { r_sys_statistics_hardware } from '@/services/system'
|
||||||
import FlexBox from '@/components/common/FlexBox'
|
import FlexBox from '@/components/common/FlexBox'
|
||||||
import StatisticsCard from '@/components/system/StatisticsCard'
|
import StatisticsCard from '@/components/system/StatisticsCard'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import useStyles from '@/assets/css/pages/system/statistics/common.style'
|
import useStyles from '@/assets/css/pages/system/statistics/common.style'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { r_sys_statistics_software } from '@/services/system'
|
import { r_sys_statistics_software } from '@/services/system'
|
||||||
import FlexBox from '@/components/common/FlexBox'
|
import FlexBox from '@/components/common/FlexBox'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import editorExtraLibs from '@/util/editorExtraLibs'
|
import editorExtraLibs from '@/util/editorExtraLibs'
|
||||||
@@ -43,7 +44,6 @@ const Base = () => {
|
|||||||
({ currentLocation, nextLocation }) =>
|
({ currentLocation, nextLocation }) =>
|
||||||
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
|
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
|
||||||
)
|
)
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [tableParams, setTableParams] = useState<TableParam>({
|
const [tableParams, setTableParams] = useState<TableParam>({
|
||||||
pagination: {
|
pagination: {
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -1093,6 +1093,7 @@ const Base = () => {
|
|||||||
expandedRowRender,
|
expandedRowRender,
|
||||||
onExpand: handleOnExpand
|
onExpand: handleOnExpand
|
||||||
}}
|
}}
|
||||||
|
scroll={{ x: true }}
|
||||||
onChange={handleOnTableChange}
|
onChange={handleOnTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -1134,7 +1135,6 @@ const Base = () => {
|
|||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
</FitFullscreen>
|
</FitFullscreen>
|
||||||
{contextHolder}
|
|
||||||
<AntdModal
|
<AntdModal
|
||||||
open={blocker.state === 'blocked'}
|
open={blocker.state === 'blocked'}
|
||||||
title={'未保存'}
|
title={'未保存'}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import {
|
import {
|
||||||
r_sys_tool_category_add,
|
r_sys_tool_category_add,
|
||||||
@@ -20,7 +21,6 @@ import HideScrollbar from '@/components/common/HideScrollbar'
|
|||||||
|
|
||||||
const Category = () => {
|
const Category = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [form] = AntdForm.useForm<ToolCategoryAddEditParam>()
|
const [form] = AntdForm.useForm<ToolCategoryAddEditParam>()
|
||||||
const formValues = AntdForm.useWatch([], form)
|
const formValues = AntdForm.useWatch([], form)
|
||||||
const [newFormValues, setNewFormValues] = useState<ToolCategoryAddEditParam>()
|
const [newFormValues, setNewFormValues] = useState<ToolCategoryAddEditParam>()
|
||||||
@@ -298,6 +298,7 @@ const Category = () => {
|
|||||||
columns={categoryColumns}
|
columns={categoryColumns}
|
||||||
rowKey={(record) => record.id}
|
rowKey={(record) => record.id}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
scroll={{ x: true }}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -313,7 +314,6 @@ const Category = () => {
|
|||||||
>
|
>
|
||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
{contextHolder}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Draggable from 'react-draggable'
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import useStyles from '@/assets/css/pages/system/tools/code.style'
|
import useStyles from '@/assets/css/pages/system/tools/code.style'
|
||||||
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
import { checkDesktop } from '@/util/common'
|
import { message, modal, checkDesktop } from '@/util/common'
|
||||||
import { navigateToExecute, navigateToRepository } from '@/util/navigation'
|
import { navigateToExecute, navigateToRepository } from '@/util/navigation'
|
||||||
import editorExtraLibs from '@/util/editorExtraLibs'
|
import editorExtraLibs from '@/util/editorExtraLibs'
|
||||||
import { r_sys_tool_get_one } from '@/services/system'
|
import { r_sys_tool_get_one } from '@/services/system'
|
||||||
@@ -17,7 +17,6 @@ const Code = () => {
|
|||||||
const { styles } = useStyles()
|
const { styles } = useStyles()
|
||||||
const { isDarkMode } = useContext(AppContext)
|
const { isDarkMode } = useContext(AppContext)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [files, setFiles] = useState<IFiles>({})
|
const [files, setFiles] = useState<IFiles>({})
|
||||||
@@ -106,7 +105,6 @@ const Code = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Draggable>
|
</Draggable>
|
||||||
</FitFullscreen>
|
</FitFullscreen>
|
||||||
{contextHolder}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import useStyles from '@/assets/css/pages/system/tools/execute.style'
|
import useStyles from '@/assets/css/pages/system/tools/execute.style'
|
||||||
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { navigateToTools } from '@/util/navigation'
|
import { navigateToTools } from '@/util/navigation'
|
||||||
import { r_sys_tool_get_one } from '@/services/system'
|
import { r_sys_tool_get_one } from '@/services/system'
|
||||||
import FitFullscreen from '@/components/common/FitFullscreen'
|
import FitFullscreen from '@/components/common/FitFullscreen'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import editorExtraLibs from '@/util/editorExtraLibs'
|
import editorExtraLibs from '@/util/editorExtraLibs'
|
||||||
@@ -41,7 +42,6 @@ const Template = () => {
|
|||||||
({ currentLocation, nextLocation }) =>
|
({ currentLocation, nextLocation }) =>
|
||||||
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
|
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
|
||||||
)
|
)
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [tableParams, setTableParams] = useState<TableParam>({
|
const [tableParams, setTableParams] = useState<TableParam>({
|
||||||
pagination: {
|
pagination: {
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -1078,7 +1078,6 @@ const Template = () => {
|
|||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
</FitFullscreen>
|
</FitFullscreen>
|
||||||
{contextHolder}
|
|
||||||
<AntdModal
|
<AntdModal
|
||||||
open={blocker.state === 'blocked'}
|
open={blocker.state === 'blocked'}
|
||||||
title={'未保存'}
|
title={'未保存'}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
DATABASE_UPDATE_SUCCESS,
|
DATABASE_UPDATE_SUCCESS,
|
||||||
TOOL_NOT_UNDER_REVIEW
|
TOOL_NOT_UNDER_REVIEW
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { navigateToCode } from '@/util/navigation'
|
import { navigateToCode } from '@/util/navigation'
|
||||||
import {
|
import {
|
||||||
r_sys_tool_delete,
|
r_sys_tool_delete,
|
||||||
@@ -28,7 +29,6 @@ import Permission from '@/components/common/Permission'
|
|||||||
const Tools = () => {
|
const Tools = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [tableParams, setTableParams] = useState<TableParam>({
|
const [tableParams, setTableParams] = useState<TableParam>({
|
||||||
pagination: {
|
pagination: {
|
||||||
current: 1,
|
current: 1,
|
||||||
@@ -574,27 +574,25 @@ const Tools = () => {
|
|||||||
columns={dataColumns}
|
columns={dataColumns}
|
||||||
pagination={tableParams.pagination}
|
pagination={tableParams.pagination}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
scroll={{ x: true }}
|
||||||
onChange={handleOnTableChange}
|
onChange={handleOnTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<FitFullscreen>
|
||||||
<FitFullscreen>
|
<HideScrollbar
|
||||||
<HideScrollbar
|
style={{ padding: 20 }}
|
||||||
style={{ padding: 20 }}
|
isShowVerticalScrollbar
|
||||||
isShowVerticalScrollbar
|
autoHideWaitingTime={1000}
|
||||||
autoHideWaitingTime={1000}
|
>
|
||||||
>
|
<FlexBox gap={20}>
|
||||||
<FlexBox gap={20}>
|
{toolbar}
|
||||||
{toolbar}
|
{table}
|
||||||
{table}
|
</FlexBox>
|
||||||
</FlexBox>
|
</HideScrollbar>
|
||||||
</HideScrollbar>
|
</FitFullscreen>
|
||||||
</FitFullscreen>
|
|
||||||
{contextHolder}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
DATABASE_SELECT_SUCCESS,
|
DATABASE_SELECT_SUCCESS,
|
||||||
DATABASE_UPDATE_SUCCESS
|
DATABASE_UPDATE_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, modal } from '@/util/common'
|
||||||
import { hasPermission } from '@/util/auth'
|
import { hasPermission } from '@/util/auth'
|
||||||
import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/util/datetime'
|
import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/util/datetime'
|
||||||
import {
|
import {
|
||||||
@@ -35,7 +36,6 @@ interface ChangePasswordFields extends UserUpdatePasswordParam {
|
|||||||
|
|
||||||
const User = () => {
|
const User = () => {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
|
|
||||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
|
||||||
const [isDrawerEdit, setIsDrawerEdit] = useState(false)
|
const [isDrawerEdit, setIsDrawerEdit] = useState(false)
|
||||||
@@ -972,6 +972,7 @@ const User = () => {
|
|||||||
rowKey={(record) => record.id}
|
rowKey={(record) => record.id}
|
||||||
pagination={tableParams.pagination}
|
pagination={tableParams.pagination}
|
||||||
loading={isLoadingUserData}
|
loading={isLoadingUserData}
|
||||||
|
scroll={{ x: true }}
|
||||||
onChange={handleOnTableChange}
|
onChange={handleOnTableChange}
|
||||||
rowSelection={
|
rowSelection={
|
||||||
hasPermission('system:user:delete:multiple')
|
hasPermission('system:user:delete:multiple')
|
||||||
@@ -1031,7 +1032,6 @@ const User = () => {
|
|||||||
>
|
>
|
||||||
{addAndEditForm}
|
{addAndEditForm}
|
||||||
</AntdDrawer>
|
</AntdDrawer>
|
||||||
{contextHolder}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
DATABASE_INSERT_SUCCESS,
|
DATABASE_INSERT_SUCCESS,
|
||||||
DATABASE_SELECT_SUCCESS
|
DATABASE_SELECT_SUCCESS
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { navigateToEdit } from '@/util/navigation'
|
import { navigateToEdit } from '@/util/navigation'
|
||||||
import {
|
import {
|
||||||
r_tool_category_get,
|
r_tool_category_get,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
TOOL_HAS_BEEN_PUBLISHED,
|
TOOL_HAS_BEEN_PUBLISHED,
|
||||||
TOOL_UNDER_REVIEW
|
TOOL_UNDER_REVIEW
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { navigateToRepository } from '@/util/navigation'
|
import { navigateToRepository } from '@/util/navigation'
|
||||||
import editorExtraLibs from '@/util/editorExtraLibs'
|
import editorExtraLibs from '@/util/editorExtraLibs'
|
||||||
import { r_tool_category_get, r_tool_detail, r_tool_update } from '@/services/tool'
|
import { r_tool_category_get, r_tool_detail, r_tool_update } from '@/services/tool'
|
||||||
@@ -121,12 +122,14 @@ const Edit = () => {
|
|||||||
getTool()
|
getTool()
|
||||||
break
|
break
|
||||||
case TOOL_UNDER_REVIEW:
|
case TOOL_UNDER_REVIEW:
|
||||||
void message.error('保存失败:工具审核中')
|
message.error('保存失败:工具审核中').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
case TOOL_HAS_BEEN_PUBLISHED:
|
case TOOL_HAS_BEEN_PUBLISHED:
|
||||||
void message.error('保存失败:工具已发布')
|
message.error('保存失败:工具已发布').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('保存失败,请稍后重试')
|
void message.error('保存失败,请稍后重试')
|
||||||
@@ -182,12 +185,14 @@ const Edit = () => {
|
|||||||
getTool()
|
getTool()
|
||||||
break
|
break
|
||||||
case TOOL_UNDER_REVIEW:
|
case TOOL_UNDER_REVIEW:
|
||||||
void message.error('保存失败:工具审核中')
|
message.error('保存失败:工具审核中').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
case TOOL_HAS_BEEN_PUBLISHED:
|
case TOOL_HAS_BEEN_PUBLISHED:
|
||||||
void message.error('保存失败:工具已发布')
|
message.error('保存失败:工具已发布').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('保存失败,请稍后重试')
|
void message.error('保存失败,请稍后重试')
|
||||||
@@ -239,17 +244,20 @@ const Edit = () => {
|
|||||||
setHasEdited(false)
|
setHasEdited(false)
|
||||||
break
|
break
|
||||||
case 'PROCESSING':
|
case 'PROCESSING':
|
||||||
void message.warning('工具审核中,请勿修改')
|
message.warning('工具审核中,请勿修改').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.warning('请先创建新版本后编辑工具')
|
message.warning('请先创建新版本后编辑工具').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case DATABASE_NO_RECORD_FOUND:
|
case DATABASE_NO_RECORD_FOUND:
|
||||||
void message.error('未找到指定工具')
|
message.error('未找到指定工具').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('获取工具信息失败,请稍后重试')
|
void message.error('获取工具信息失败,请稍后重试')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { UIEvent } from 'react'
|
import { UIEvent } from 'react'
|
||||||
import useStyles from '@/assets/css/pages/tools/local.style'
|
import useStyles from '@/assets/css/pages/tools/local.style'
|
||||||
import { checkDesktop } from '@/util/common'
|
import { message, checkDesktop } from '@/util/common'
|
||||||
import { l_tool_get } from '@/services/tool'
|
import { l_tool_get } from '@/services/tool'
|
||||||
import FlexBox from '@/components/common/FlexBox'
|
import FlexBox from '@/components/common/FlexBox'
|
||||||
import FitFullscreen from '@/components/common/FitFullscreen'
|
import FitFullscreen from '@/components/common/FitFullscreen'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import useStyles from '@/assets/css/pages/tools/source.style'
|
import useStyles from '@/assets/css/pages/tools/source.style'
|
||||||
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { getLoginStatus } from '@/util/auth'
|
import { getLoginStatus } from '@/util/auth'
|
||||||
import { navigateToRepository, navigateToSource } from '@/util/navigation'
|
import { navigateToRepository, navigateToSource } from '@/util/navigation'
|
||||||
import editorExtraLibs from '@/util/editorExtraLibs'
|
import editorExtraLibs from '@/util/editorExtraLibs'
|
||||||
@@ -52,8 +53,9 @@ const Source = () => {
|
|||||||
render(response.data!)
|
render(response.data!)
|
||||||
break
|
break
|
||||||
case DATABASE_NO_RECORD_FOUND:
|
case DATABASE_NO_RECORD_FOUND:
|
||||||
void message.error('未找到指定工具')
|
void message.error('未找到指定工具').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('获取工具信息失败,请稍后重试')
|
void message.error('获取工具信息失败,请稍后重试')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { UIEvent } from 'react'
|
import { UIEvent } from 'react'
|
||||||
import useStyles from '@/assets/css/pages/tools/store.style'
|
import useStyles from '@/assets/css/pages/tools/store.style'
|
||||||
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
import { checkDesktop } from '@/util/common'
|
import { message, checkDesktop } from '@/util/common'
|
||||||
import { r_tool_store_get } from '@/services/tool'
|
import { r_tool_store_get } from '@/services/tool'
|
||||||
import FlexBox from '@/components/common/FlexBox'
|
import FlexBox from '@/components/common/FlexBox'
|
||||||
import FitFullscreen from '@/components/common/FitFullscreen'
|
import FitFullscreen from '@/components/common/FitFullscreen'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import useStyles from '@/assets/css/pages/tools/user.style'
|
import useStyles from '@/assets/css/pages/tools/user.style'
|
||||||
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
import { checkDesktop } from '@/util/common'
|
import { message, checkDesktop } from '@/util/common'
|
||||||
import { navigateToRoot } from '@/util/navigation'
|
import { navigateToRoot } from '@/util/navigation'
|
||||||
import { r_sys_user_info_get_basic } from '@/services/system'
|
import { r_sys_user_info_get_basic } from '@/services/system'
|
||||||
import { r_tool_store_get_by_username } from '@/services/tool'
|
import { r_tool_store_get_by_username } from '@/services/tool'
|
||||||
@@ -40,7 +40,7 @@ const User = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
void message.loading({ content: '加载中', key: 'LOADING', duration: 0 })
|
void message.loading({ content: '加载中……', key: 'LOADING', duration: 0 })
|
||||||
|
|
||||||
void r_sys_user_info_get_basic(username!)
|
void r_sys_user_info_get_basic(username!)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -51,10 +51,9 @@ const User = () => {
|
|||||||
getTool(1)
|
getTool(1)
|
||||||
break
|
break
|
||||||
case DATABASE_NO_RECORD_FOUND:
|
case DATABASE_NO_RECORD_FOUND:
|
||||||
void message.warning('用户不存在')
|
void message.warning('用户不存在').then(() => {
|
||||||
setTimeout(() => {
|
|
||||||
navigateToRoot(navigate)
|
navigateToRoot(navigate)
|
||||||
}, 3000)
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('获取失败请稍后重试')
|
void message.error('获取失败请稍后重试')
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import useStyles from '@/assets/css/pages/tools/view.style'
|
import useStyles from '@/assets/css/pages/tools/view.style'
|
||||||
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { getLoginStatus } from '@/util/auth'
|
import { getLoginStatus } from '@/util/auth'
|
||||||
import {
|
import {
|
||||||
navigateToInstall,
|
navigateToInstall,
|
||||||
@@ -101,8 +102,9 @@ const View = () => {
|
|||||||
render(response.data!)
|
render(response.data!)
|
||||||
break
|
break
|
||||||
case DATABASE_NO_RECORD_FOUND:
|
case DATABASE_NO_RECORD_FOUND:
|
||||||
void message.error('未找到指定工具')
|
void message.error('未找到指定工具').then(() => {
|
||||||
navigateToRepository(navigate)
|
navigateToRepository(navigate)
|
||||||
|
})
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('获取工具信息失败,请稍后重试')
|
void message.error('获取工具信息失败,请稍后重试')
|
||||||
@@ -121,8 +123,9 @@ const View = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (username === '!' && !getLoginStatus()) {
|
if (username === '!' && !getLoginStatus()) {
|
||||||
void message.error('未登录')
|
void message.error('未登录').then(() => {
|
||||||
navigateToRoot(navigate)
|
navigateToRoot(navigate)
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (username !== '!' && ver) {
|
if (username !== '!' && ver) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
TOOL_SUBMIT_SUCCESS,
|
TOOL_SUBMIT_SUCCESS,
|
||||||
TOOL_UNDER_REVIEW
|
TOOL_UNDER_REVIEW
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
import { checkDesktop } from '@/util/common'
|
import { message, modal, checkDesktop } from '@/util/common'
|
||||||
import { getLoginStatus } from '@/util/auth'
|
import { getLoginStatus } from '@/util/auth'
|
||||||
import { navigateToEdit, navigateToSource, navigateToView } from '@/util/navigation'
|
import { navigateToEdit, navigateToSource, navigateToView } from '@/util/navigation'
|
||||||
import {
|
import {
|
||||||
@@ -204,7 +204,6 @@ const ToolCard = ({ tools, onDelete, onUpgrade, onSubmit, onCancel }: ToolCardPr
|
|||||||
const Tools = () => {
|
const Tools = () => {
|
||||||
const { styles } = useStyles()
|
const { styles } = useStyles()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [currentPage, setCurrentPage] = useState(0)
|
const [currentPage, setCurrentPage] = useState(0)
|
||||||
const [hasNextPage, setHasNextPage] = useState(false)
|
const [hasNextPage, setHasNextPage] = useState(false)
|
||||||
@@ -537,77 +536,72 @@ const Tools = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<FitFullscreen>
|
||||||
<FitFullscreen>
|
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={1000}>
|
||||||
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={1000}>
|
<FlexBox direction={'vertical'} className={styles.root}>
|
||||||
<FlexBox direction={'vertical'} className={styles.root}>
|
<FlexBox direction={'horizontal'} className={styles.ownContent}>
|
||||||
<FlexBox direction={'horizontal'} className={styles.ownContent}>
|
<UrlCard icon={IconOxygenNewProject} url={'/create'}>
|
||||||
<UrlCard icon={IconOxygenNewProject} url={'/create'}>
|
创建工具
|
||||||
创建工具
|
</UrlCard>
|
||||||
</UrlCard>
|
{toolData &&
|
||||||
{toolData &&
|
Object.values(
|
||||||
Object.values(
|
toolData.reduce((result: Record<string, ToolVo[]>, item) => {
|
||||||
toolData.reduce((result: Record<string, ToolVo[]>, item) => {
|
result[item.toolId] = result[item.toolId] || []
|
||||||
result[item.toolId] = result[item.toolId] || []
|
result[item.toolId].push(item)
|
||||||
result[item.toolId].push(item)
|
return result
|
||||||
return result
|
}, {})
|
||||||
}, {})
|
).map((value) => (
|
||||||
).map((value) => (
|
<ToolCard
|
||||||
<ToolCard
|
key={JSON.stringify(value)}
|
||||||
key={JSON.stringify(value)}
|
tools={value}
|
||||||
tools={value}
|
onDelete={handleOnDeleteTool}
|
||||||
onDelete={handleOnDeleteTool}
|
onUpgrade={handleOnUpgradeTool}
|
||||||
onUpgrade={handleOnUpgradeTool}
|
onSubmit={handleOnSubmitTool}
|
||||||
onSubmit={handleOnSubmitTool}
|
onCancel={handleOnCancelTool}
|
||||||
onCancel={handleOnCancelTool}
|
/>
|
||||||
/>
|
))}
|
||||||
))}
|
{hasNextPage && <LoadMoreCard onClick={handleOnLoadMore} />}
|
||||||
{hasNextPage && <LoadMoreCard onClick={handleOnLoadMore} />}
|
</FlexBox>
|
||||||
</FlexBox>
|
{starToolData.length ? (
|
||||||
{starToolData.length ? (
|
<>
|
||||||
<>
|
<FlexBox direction={'horizontal'} className={styles.favoriteDivider}>
|
||||||
<FlexBox
|
<div />
|
||||||
direction={'horizontal'}
|
<div className={styles.dividerText}>收藏</div>
|
||||||
className={styles.favoriteDivider}
|
<div />
|
||||||
>
|
</FlexBox>
|
||||||
<div />
|
<FlexBox direction={'horizontal'} className={styles.starContent}>
|
||||||
<div className={styles.dividerText}>收藏</div>
|
{starToolData
|
||||||
<div />
|
?.reduce((previousValue: ToolVo[], currentValue) => {
|
||||||
</FlexBox>
|
if (
|
||||||
<FlexBox direction={'horizontal'} className={styles.starContent}>
|
!previousValue.some(
|
||||||
{starToolData
|
|
||||||
?.reduce((previousValue: ToolVo[], currentValue) => {
|
|
||||||
if (
|
|
||||||
!previousValue.some(
|
|
||||||
(value) =>
|
|
||||||
value.author.id ===
|
|
||||||
currentValue.author.id &&
|
|
||||||
value.toolId === currentValue.toolId
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
previousValue.push(currentValue)
|
|
||||||
}
|
|
||||||
return previousValue
|
|
||||||
}, [])
|
|
||||||
.map((item) => {
|
|
||||||
const tools = starToolData.filter(
|
|
||||||
(value) =>
|
(value) =>
|
||||||
value.author.id === item.author.id &&
|
value.author.id === currentValue.author.id &&
|
||||||
value.toolId === item.toolId
|
value.toolId === currentValue.toolId
|
||||||
)
|
)
|
||||||
const webTool = tools.find(
|
) {
|
||||||
(value) => value.platform === 'WEB'
|
previousValue.push(currentValue)
|
||||||
)
|
}
|
||||||
const desktopTool = tools.find(
|
return previousValue
|
||||||
(value) => value.platform === 'DESKTOP'
|
}, [])
|
||||||
)
|
.map((item) => {
|
||||||
const androidTool = tools.find(
|
const tools = starToolData.filter(
|
||||||
(value) => value.platform === 'ANDROID'
|
(value) =>
|
||||||
)
|
value.author.id === item.author.id &&
|
||||||
const firstTool =
|
value.toolId === item.toolId
|
||||||
(checkDesktop()
|
)
|
||||||
? desktopTool || webTool
|
const webTool = tools.find(
|
||||||
: webTool || desktopTool) || androidTool
|
(value) => value.platform === 'WEB'
|
||||||
|
)
|
||||||
|
const desktopTool = tools.find(
|
||||||
|
(value) => value.platform === 'DESKTOP'
|
||||||
|
)
|
||||||
|
const androidTool = tools.find(
|
||||||
|
(value) => value.platform === 'ANDROID'
|
||||||
|
)
|
||||||
|
const firstTool =
|
||||||
|
(checkDesktop()
|
||||||
|
? desktopTool || webTool
|
||||||
|
: webTool || desktopTool) || androidTool
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StoreCard
|
<StoreCard
|
||||||
@@ -643,8 +637,6 @@ const Tools = () => {
|
|||||||
</FlexBox>
|
</FlexBox>
|
||||||
</HideScrollbar>
|
</HideScrollbar>
|
||||||
</FitFullscreen>
|
</FitFullscreen>
|
||||||
{contextHolder}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { arrayMove, SortableContext } from '@dnd-kit/sortable'
|
|||||||
import type { DragEndEvent } from '@dnd-kit/core/dist/types'
|
import type { DragEndEvent } from '@dnd-kit/core/dist/types'
|
||||||
import useStyles from '@/assets/css/pages/tools-framework.style'
|
import useStyles from '@/assets/css/pages/tools-framework.style'
|
||||||
import { tools } from '@/router/tools'
|
import { tools } from '@/router/tools'
|
||||||
import { checkDesktop, getToolMenuItem, saveToolMenuItem } from '@/util/common'
|
import { message, checkDesktop, getToolMenuItem, saveToolMenuItem } from '@/util/common'
|
||||||
import { getViewPath } from '@/util/navigation'
|
import { getViewPath } from '@/util/navigation'
|
||||||
import FitFullscreen from '@/components/common/FitFullscreen'
|
import FitFullscreen from '@/components/common/FitFullscreen'
|
||||||
import Sidebar from '@/components/common/Sidebar'
|
import Sidebar from '@/components/common/Sidebar'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
PERMISSION_ACCESS_DENIED,
|
PERMISSION_ACCESS_DENIED,
|
||||||
PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR
|
PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message, notification, modal } from '@/util/common'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { getUserInfo, removeToken } from '@/util/auth'
|
import { getUserInfo, removeToken } from '@/util/auth'
|
||||||
import { r_sys_user_info_change_password, r_sys_user_info_update } from '@/services/system'
|
import { r_sys_user_info_change_password, r_sys_user_info_update } from '@/services/system'
|
||||||
@@ -21,7 +22,6 @@ import HideScrollbar from '@/components/common/HideScrollbar'
|
|||||||
|
|
||||||
const User = () => {
|
const User = () => {
|
||||||
const { styles, theme } = useStyles()
|
const { styles, theme } = useStyles()
|
||||||
const [modal, contextHolder] = AntdModal.useModal()
|
|
||||||
const [form] = AntdForm.useForm<UserInfoUpdateParam>()
|
const [form] = AntdForm.useForm<UserInfoUpdateParam>()
|
||||||
const formValues = AntdForm.useWatch([], form)
|
const formValues = AntdForm.useWatch([], form)
|
||||||
const [twoFactorForm] = AntdForm.useForm<{ twoFactorCode: string }>()
|
const [twoFactorForm] = AntdForm.useForm<{ twoFactorCode: string }>()
|
||||||
@@ -180,7 +180,6 @@ const User = () => {
|
|||||||
const response = res.data
|
const response = res.data
|
||||||
switch (response.code) {
|
switch (response.code) {
|
||||||
case DATABASE_UPDATE_SUCCESS:
|
case DATABASE_UPDATE_SUCCESS:
|
||||||
void message.success('密码修改成功,请重新登录')
|
|
||||||
removeToken()
|
removeToken()
|
||||||
notification.info({
|
notification.info({
|
||||||
message: '已退出登录',
|
message: '已退出登录',
|
||||||
@@ -191,9 +190,9 @@ const User = () => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
message.success('密码修改成功,请重新登录').then(() => {
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
}, 1500)
|
})
|
||||||
resolve()
|
resolve()
|
||||||
break
|
break
|
||||||
case PERMISSION_ACCESS_DENIED:
|
case PERMISSION_ACCESS_DENIED:
|
||||||
@@ -312,7 +311,7 @@ const User = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
void message.loading({ content: '加载中', key: 'LOADING', duration: 0 })
|
void message.loading({ content: '加载中……', key: 'LOADING', duration: 0 })
|
||||||
void r_auth_two_factor_create()
|
void r_auth_two_factor_create()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
message.destroy('LOADING')
|
message.destroy('LOADING')
|
||||||
@@ -447,192 +446,180 @@ const User = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<FitFullscreen>
|
||||||
<FitFullscreen>
|
<HideScrollbar
|
||||||
<HideScrollbar
|
isShowVerticalScrollbar
|
||||||
isShowVerticalScrollbar
|
autoHideWaitingTime={1000}
|
||||||
autoHideWaitingTime={1000}
|
className={styles.root}
|
||||||
className={styles.root}
|
>
|
||||||
>
|
<Card className={styles.content}>
|
||||||
<Card className={styles.content}>
|
<FlexBox className={styles.info} direction={'horizontal'}>
|
||||||
<FlexBox className={styles.info} direction={'horizontal'}>
|
<AntdTooltip title={'点击获取新头像'}>
|
||||||
<AntdTooltip title={'点击获取新头像'}>
|
<div className={styles.avatarBox}>
|
||||||
<div className={styles.avatarBox}>
|
<AntdAvatar
|
||||||
<AntdAvatar
|
src={
|
||||||
src={
|
<img
|
||||||
<img
|
src={`data:image/png;base64,${avatar}`}
|
||||||
src={`data:image/png;base64,${avatar}`}
|
alt={'Avatar'}
|
||||||
alt={'Avatar'}
|
/>
|
||||||
/>
|
}
|
||||||
}
|
size={144}
|
||||||
size={144}
|
style={{
|
||||||
style={{
|
background: theme.colorBgLayout,
|
||||||
background: theme.colorBgLayout,
|
cursor: 'pointer'
|
||||||
cursor: 'pointer'
|
}}
|
||||||
}}
|
className={styles.avatar}
|
||||||
className={styles.avatar}
|
onClick={handleOnChangeAvatar}
|
||||||
onClick={handleOnChangeAvatar}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</AntdTooltip>
|
||||||
</AntdTooltip>
|
<FlexBox className={styles.infoName}>
|
||||||
<FlexBox className={styles.infoName}>
|
<div className={styles.nickname}>
|
||||||
<div className={styles.nickname}>
|
{userWithPowerInfoVo?.userInfo.nickname}
|
||||||
{userWithPowerInfoVo?.userInfo.nickname}
|
</div>
|
||||||
</div>
|
<a
|
||||||
<a
|
className={styles.url}
|
||||||
className={styles.url}
|
onClick={handleOnCopyToClipboard(userWithPowerInfoVo?.username)}
|
||||||
onClick={handleOnCopyToClipboard(userWithPowerInfoVo?.username)}
|
>
|
||||||
>
|
{userWithPowerInfoVo?.username &&
|
||||||
{userWithPowerInfoVo?.username &&
|
new URL(
|
||||||
new URL(
|
`/store/${userWithPowerInfoVo.username}`,
|
||||||
`/store/${userWithPowerInfoVo.username}`,
|
import.meta.env.VITE_UI_URL
|
||||||
import.meta.env.VITE_UI_URL
|
).href}
|
||||||
).href}
|
<Icon component={IconOxygenCopy} />
|
||||||
<Icon component={IconOxygenCopy} />
|
</a>
|
||||||
</a>
|
|
||||||
</FlexBox>
|
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
<FlexBox direction={'horizontal'} className={styles.header}>
|
</FlexBox>
|
||||||
<div className={styles.title}>档案管理</div>
|
<FlexBox direction={'horizontal'} className={styles.header}>
|
||||||
<FlexBox className={styles.operation} direction={'horizontal'}>
|
<div className={styles.title}>档案管理</div>
|
||||||
<AntdButton onClick={handleOnReset} loading={isLoading}>
|
<FlexBox className={styles.operation} direction={'horizontal'}>
|
||||||
重置
|
<AntdButton onClick={handleOnReset} loading={isLoading}>
|
||||||
</AntdButton>
|
重置
|
||||||
<AntdButton
|
</AntdButton>
|
||||||
onClick={handleOnSave}
|
<AntdButton
|
||||||
type={'primary'}
|
onClick={handleOnSave}
|
||||||
disabled={isLoading || !isSubmittable}
|
type={'primary'}
|
||||||
>
|
disabled={isLoading || !isSubmittable}
|
||||||
保存
|
>
|
||||||
</AntdButton>
|
保存
|
||||||
</FlexBox>
|
</AntdButton>
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
<div className={styles.divider} />
|
</FlexBox>
|
||||||
<FlexBox className={styles.list}>
|
<div className={styles.divider} />
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
<FlexBox className={styles.list}>
|
||||||
<div className={styles.label}>昵称</div>
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
<div className={styles.input}>
|
<div className={styles.label}>昵称</div>
|
||||||
<AntdForm form={form}>
|
<div className={styles.input}>
|
||||||
<AntdForm.Item
|
<AntdForm form={form}>
|
||||||
name={'nickname'}
|
<AntdForm.Item
|
||||||
rules={[
|
name={'nickname'}
|
||||||
{ required: true, whitespace: true },
|
rules={[
|
||||||
{ min: 3, message: '昵称至少为3个字符' }
|
{ required: true, whitespace: true },
|
||||||
]}
|
{ min: 3, message: '昵称至少为3个字符' }
|
||||||
style={{ marginBottom: 0 }}
|
]}
|
||||||
>
|
style={{ marginBottom: 0 }}
|
||||||
<AntdInput
|
>
|
||||||
maxLength={20}
|
|
||||||
showCount
|
|
||||||
disabled={isLoading}
|
|
||||||
placeholder={'请输入昵称'}
|
|
||||||
/>
|
|
||||||
</AntdForm.Item>
|
|
||||||
</AntdForm>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>用户名</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdInput disabled value={userWithPowerInfoVo?.username} />
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>邮箱</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdInput
|
|
||||||
disabled
|
|
||||||
value={userWithPowerInfoVo?.userInfo.email}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>注册时间</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdInput
|
|
||||||
disabled
|
|
||||||
value={utcToLocalTime(
|
|
||||||
userWithPowerInfoVo?.createTime ?? ''
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
</FlexBox>
|
|
||||||
<div className={styles.divider} />
|
|
||||||
<FlexBox className={styles.list}>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>上次登录 IP</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdInput disabled value={userWithPowerInfoVo?.lastLoginIp} />
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>上次登录时间</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdInput
|
|
||||||
disabled
|
|
||||||
value={utcToLocalTime(
|
|
||||||
userWithPowerInfoVo?.lastLoginTime ?? ''
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>密码</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdSpace.Compact>
|
|
||||||
<AntdInput disabled value={'********'} />
|
|
||||||
<AntdButton
|
|
||||||
type={'primary'}
|
|
||||||
title={'更改密码'}
|
|
||||||
disabled={isLoading}
|
|
||||||
onClick={handleOnChangePassword}
|
|
||||||
>
|
|
||||||
<Icon component={IconOxygenRefresh} />
|
|
||||||
</AntdButton>
|
|
||||||
</AntdSpace.Compact>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
<FlexBox className={styles.row} direction={'horizontal'}>
|
|
||||||
<div className={styles.label}>双因素</div>
|
|
||||||
<div className={styles.input}>
|
|
||||||
<AntdSpace.Compact>
|
|
||||||
<AntdInput
|
<AntdInput
|
||||||
disabled
|
maxLength={20}
|
||||||
style={{
|
showCount
|
||||||
color: userWithPowerInfoVo?.twoFactor
|
disabled={isLoading}
|
||||||
? theme.colorPrimary
|
placeholder={'请输入昵称'}
|
||||||
: undefined
|
/>
|
||||||
}}
|
</AntdForm.Item>
|
||||||
value={
|
</AntdForm>
|
||||||
userWithPowerInfoVo?.twoFactor ? '已设置' : '未设置'
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>用户名</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdInput disabled value={userWithPowerInfoVo?.username} />
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>邮箱</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdInput disabled value={userWithPowerInfoVo?.userInfo.email} />
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>注册时间</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdInput
|
||||||
|
disabled
|
||||||
|
value={utcToLocalTime(userWithPowerInfoVo?.createTime ?? '')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
</FlexBox>
|
||||||
|
<div className={styles.divider} />
|
||||||
|
<FlexBox className={styles.list}>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>上次登录 IP</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdInput disabled value={userWithPowerInfoVo?.lastLoginIp} />
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>上次登录时间</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdInput
|
||||||
|
disabled
|
||||||
|
value={utcToLocalTime(userWithPowerInfoVo?.lastLoginTime ?? '')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>密码</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdSpace.Compact>
|
||||||
|
<AntdInput disabled value={'********'} />
|
||||||
|
<AntdButton
|
||||||
|
type={'primary'}
|
||||||
|
title={'更改密码'}
|
||||||
|
disabled={isLoading}
|
||||||
|
onClick={handleOnChangePassword}
|
||||||
|
>
|
||||||
|
<Icon component={IconOxygenRefresh} />
|
||||||
|
</AntdButton>
|
||||||
|
</AntdSpace.Compact>
|
||||||
|
</div>
|
||||||
|
</FlexBox>
|
||||||
|
<FlexBox className={styles.row} direction={'horizontal'}>
|
||||||
|
<div className={styles.label}>双因素</div>
|
||||||
|
<div className={styles.input}>
|
||||||
|
<AntdSpace.Compact>
|
||||||
|
<AntdInput
|
||||||
|
disabled
|
||||||
|
style={{
|
||||||
|
color: userWithPowerInfoVo?.twoFactor
|
||||||
|
? theme.colorPrimary
|
||||||
|
: undefined
|
||||||
|
}}
|
||||||
|
value={userWithPowerInfoVo?.twoFactor ? '已设置' : '未设置'}
|
||||||
|
/>
|
||||||
|
<AntdButton
|
||||||
|
type={'primary'}
|
||||||
|
title={userWithPowerInfoVo?.twoFactor ? '解绑' : '绑定'}
|
||||||
|
disabled={isLoading}
|
||||||
|
onClick={handleOnChangeTwoFactor(
|
||||||
|
userWithPowerInfoVo?.twoFactor ?? false
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
component={
|
||||||
|
userWithPowerInfoVo?.twoFactor
|
||||||
|
? IconOxygenUnlock
|
||||||
|
: IconOxygenLock
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<AntdButton
|
</AntdButton>
|
||||||
type={'primary'}
|
</AntdSpace.Compact>
|
||||||
title={userWithPowerInfoVo?.twoFactor ? '解绑' : '绑定'}
|
</div>
|
||||||
disabled={isLoading}
|
|
||||||
onClick={handleOnChangeTwoFactor(
|
|
||||||
userWithPowerInfoVo?.twoFactor ?? false
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
component={
|
|
||||||
userWithPowerInfoVo?.twoFactor
|
|
||||||
? IconOxygenUnlock
|
|
||||||
: IconOxygenLock
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</AntdButton>
|
|
||||||
</AntdSpace.Compact>
|
|
||||||
</div>
|
|
||||||
</FlexBox>
|
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
</Card>
|
</FlexBox>
|
||||||
</HideScrollbar>
|
</Card>
|
||||||
</FitFullscreen>
|
</HideScrollbar>
|
||||||
{contextHolder}
|
</FitFullscreen>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
PERMISSION_UNAUTHORIZED,
|
PERMISSION_UNAUTHORIZED,
|
||||||
SYSTEM_REQUEST_TOO_FREQUENT
|
SYSTEM_REQUEST_TOO_FREQUENT
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
|
import { message } from '@/util/common'
|
||||||
import { getRedirectUrl } from '@/util/route'
|
import { getRedirectUrl } from '@/util/route'
|
||||||
import { getToken, setToken, removeToken } from '@/util/auth'
|
import { getToken, setToken, removeToken } from '@/util/auth'
|
||||||
|
|
||||||
@@ -68,34 +69,36 @@ service.interceptors.response.use(
|
|||||||
switch (response.data.code) {
|
switch (response.data.code) {
|
||||||
case PERMISSION_UNAUTHORIZED:
|
case PERMISSION_UNAUTHORIZED:
|
||||||
removeToken()
|
removeToken()
|
||||||
void message.error({
|
message
|
||||||
content: (
|
.error({
|
||||||
<>
|
content: (
|
||||||
<strong>未登录</strong>
|
<>
|
||||||
</>
|
<strong>未登录</strong>
|
||||||
),
|
</>
|
||||||
key: 'NO_LOGIN'
|
),
|
||||||
})
|
key: 'NO_LOGIN'
|
||||||
setTimeout(() => {
|
})
|
||||||
location.reload()
|
.then(() => {
|
||||||
}, 1500)
|
location.reload()
|
||||||
|
})
|
||||||
throw response?.data
|
throw response?.data
|
||||||
case PERMISSION_TOKEN_ILLEGAL:
|
case PERMISSION_TOKEN_ILLEGAL:
|
||||||
case PERMISSION_TOKEN_HAS_EXPIRED:
|
case PERMISSION_TOKEN_HAS_EXPIRED:
|
||||||
removeToken()
|
removeToken()
|
||||||
void message.error({
|
message
|
||||||
content: (
|
.error({
|
||||||
<>
|
content: (
|
||||||
<strong>登录已过期</strong>
|
<>
|
||||||
</>
|
<strong>登录已过期</strong>
|
||||||
),
|
</>
|
||||||
key: 'LOGIN_HAS_EXPIRED'
|
),
|
||||||
})
|
key: 'LOGIN_HAS_EXPIRED'
|
||||||
setTimeout(() => {
|
})
|
||||||
location.replace(
|
.then(() => {
|
||||||
getRedirectUrl('/login', `${location.pathname}${location.search}`)
|
location.replace(
|
||||||
)
|
getRedirectUrl('/login', `${location.pathname}${location.search}`)
|
||||||
}, 1500)
|
)
|
||||||
|
})
|
||||||
throw response?.data
|
throw response?.data
|
||||||
case PERMISSION_ACCESS_DENIED:
|
case PERMISSION_ACCESS_DENIED:
|
||||||
void message.error({
|
void message.error({
|
||||||
|
|||||||
@@ -3,6 +3,25 @@ import { floor } from 'lodash'
|
|||||||
import { STORAGE_TOOL_MENU_ITEM_KEY } from '@/constants/common.constants'
|
import { STORAGE_TOOL_MENU_ITEM_KEY } from '@/constants/common.constants'
|
||||||
import { getLocalStorage, setLocalStorage } from '@/util/browser'
|
import { getLocalStorage, setLocalStorage } from '@/util/browser'
|
||||||
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
|
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
|
||||||
|
import { MessageInstance } from 'antd/es/message/interface'
|
||||||
|
import { NotificationInstance } from 'antd/es/notification/interface'
|
||||||
|
import { HookAPI } from 'antd/es/modal/useModal'
|
||||||
|
|
||||||
|
let message: MessageInstance
|
||||||
|
let notification: NotificationInstance
|
||||||
|
let modal: HookAPI
|
||||||
|
|
||||||
|
export const init = (
|
||||||
|
messageInstance: MessageInstance,
|
||||||
|
notificationInstance: NotificationInstance,
|
||||||
|
modalInstance: HookAPI
|
||||||
|
) => {
|
||||||
|
message = messageInstance
|
||||||
|
notification = notificationInstance
|
||||||
|
modal = modalInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
export { message, notification, modal }
|
||||||
|
|
||||||
export const randomInt = (start: number, end: number) => {
|
export const randomInt = (start: number, end: number) => {
|
||||||
if (start > end) {
|
if (start > end) {
|
||||||
|
|||||||
Reference in New Issue
Block a user