Feat(Hint): Support dark mode

This commit is contained in:
2024-10-23 14:37:43 +08:00
parent dbce6b9cf2
commit 1cdd1e5a93
40 changed files with 567 additions and 554 deletions

View File

@@ -4,6 +4,7 @@ import BaseStyles from '@/assets/css/base.style'
import CommonStyles from '@/assets/css/common.style'
import { COLOR_PRODUCTION } from '@/constants/common.constants'
import { getRouter } from '@/router'
import { init } from '@/util/common'
import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask'
export const AppContext = createContext({
@@ -12,10 +13,14 @@ export const AppContext = createContext({
})
const App = () => {
const [messageInstance, messageHolder] = message.useMessage()
const [notificationInstance, notificationHolder] = notification.useNotification()
const [modalInstance, modalHolder] = AntdModal.useModal()
const [routerState, setRouterState] = useState(getRouter)
const [isDarkMode, setIsDarkMode] = useState(false)
useEffect(() => {
init(messageInstance, notificationInstance, modalInstance)
const darkThemeMq = window.matchMedia('(prefers-color-scheme: dark)')
setIsDarkMode(darkThemeMq.matches)
const listener = (ev: MediaQueryListEvent) => {
@@ -59,6 +64,9 @@ const App = () => {
<RouterProvider router={routerState} />
</Suspense>
</AppContext.Provider>
{messageHolder}
{notificationHolder}
{modalHolder}
</AntdConfigProvider>
)
}

View File

@@ -7,7 +7,7 @@ export default createGlobalStyle(() => ({
li: { listStyle: 'none' },
img: { border: 0, verticalAlign: 'middle' },
button: { cursor: 'pointer' },
a: { color: '#666', textDecoration: 'none' },
a: { color: '#666', textDecoration: 'none', whiteSpace: 'nowrap' },
'button, input': {
fontFamily:
'Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\\5B8B\\4F53", sans-serif',

View File

@@ -4,9 +4,15 @@ import useStyles from '@/assets/css/components/common/card.style'
type CardProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
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

View File

@@ -6,15 +6,11 @@ interface FitCenterProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement
}
const FitCenter = ({ className, vertical, ...props }: FitCenterProps) => {
const { styles, cx } = useStyles()
const { styles } = useStyles()
return (
<div
className={cx(
styles.fitCenter,
className,
vertical ? ' flex-vertical' : ' flex-horizontal'
)}
className={`${styles.fitCenter}${vertical ? ' flex-vertical' : ' flex-horizontal'}${className ? ` ${className}` : ''}`}
{...props}
/>
)

View File

@@ -9,11 +9,11 @@ interface FitFullscreenProps
const FitFullscreen = forwardRef<HTMLDivElement, FitFullscreenProps>(
({ zIndex, backgroundColor, className, style, ...props }, ref) => {
const { styles, cx } = useStyles()
const { styles } = useStyles()
return (
<div
className={cx(styles.fitFullscreen, className)}
className={`${styles.fitFullscreen}${className ? ` ${className}` : ''}`}
style={{
zIndex,
backgroundColor,

View File

@@ -8,15 +8,11 @@ interface FlexBoxProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>,
const FlexBox = forwardRef<HTMLDivElement, FlexBoxProps>(
({ className, direction, gap, style, ...props }, ref) => {
const { styles, cx } = useStyles()
const { styles } = useStyles()
return (
<div
className={cx(
styles.flexBox,
className,
direction === 'horizontal' ? 'flex-horizontal' : 'flex-vertical'
)}
className={`${styles.flexBox}${direction === 'horizontal' ? ' flex-horizontal' : ' flex-vertical'}${className ? ` ${className}` : ''}`}
style={{ gap, ...style }}
{...props}
ref={ref}

View File

@@ -540,7 +540,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
>
<div
ref={rootRef}
className={cx(styles.hideScrollbarSelection, className)}
className={`${styles.hideScrollbarSelection}${className ? ` ${className}` : ''}`}
tabIndex={0}
style={{
width: `calc(${maskRef.current?.clientWidth}px + ${verticalScrollbarWidth}px)`,
@@ -571,7 +571,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
className={cx(
styles.scrollbar,
styles.verticalScrollbar,
isVerticalScrollbarAutoHide ? ` ${styles.hide}` : ''
isVerticalScrollbarAutoHide ? styles.hide : ''
)}
style={{
height: maskRef.current
@@ -619,7 +619,7 @@ const HideScrollbar = forwardRef<HideScrollbarElement, HideScrollbarProps>(
className={cx(
styles.scrollbar,
styles.horizontalScrollbar,
isHorizontalScrollbarAutoHide ? ` ${styles.hide}` : ''
isHorizontalScrollbarAutoHide ? styles.hide : ''
)}
style={{
width: maskRef.current

View File

@@ -1,6 +1,7 @@
import Icon from '@ant-design/icons'
import useStyles from '@/assets/css/components/common/sidebar/footer.style'
import { SidebarContext } from '@/components/common/Sidebar/index'
import { notification } from '@/util/common'
import { getRedirectUrl } from '@/util/route'
import { getAvatar, getLoginStatus, getNickname, removeToken } from '@/util/auth'
import { navigateToLogin, navigateToUser } from '@/util/navigation'

View File

@@ -3,7 +3,7 @@ import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
import protocolCheck from 'custom-protocol-check'
import Icon from '@ant-design/icons'
import useStyles from '@/assets/css/components/tools/store-card.style'
import { checkDesktop, omitTextByByte } from '@/util/common'
import { message, modal, checkDesktop, omitTextByByte } from '@/util/common'
import { getLoginStatus, getUserId } from '@/util/auth'
import {
getAndroidUrl,
@@ -56,7 +56,6 @@ const StoreCard = ({
}: StoreCardProps) => {
const { styles, theme } = useStyles()
const navigate = useNavigate()
const [modal, contextHolder] = AntdModal.useModal()
const cardRef = useRef<HTMLDivElement>(null)
const [favorite_, setFavorite_] = useState<boolean>(favorite)
const [userId, setUserId] = useState('')
@@ -76,6 +75,7 @@ const StoreCard = ({
if (platform === 'ANDROID') {
void modal.confirm({
centered: true,
keyboard: false,
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
title: 'Android 端',
content: (
@@ -144,6 +144,7 @@ const StoreCard = ({
e.stopPropagation()
void modal.confirm({
centered: true,
keyboard: false,
icon: <Icon style={{ color: theme.colorPrimary }} component={IconOxygenInfo} />,
title: 'Android 端',
content: (
@@ -190,7 +191,6 @@ const StoreCard = ({
}
return (
<>
<Draggable
id={`${author.username}:${toolId}:${ver}:${platform}`}
data={{
@@ -241,10 +241,7 @@ const StoreCard = ({
</AntdTooltip>
)}
<AntdTooltip title={'源码'}>
<Icon
component={IconOxygenCode}
onClick={handleOnSourceBtnClick}
/>
<Icon component={IconOxygenCode} onClick={handleOnSourceBtnClick} />
</AntdTooltip>
{author.id !== userId && (
<AntdTooltip title={favorite_ ? '取消收藏' : '收藏'}>
@@ -296,8 +293,6 @@ const StoreCard = ({
</FlexBox>
</Card>
</Draggable>
{contextHolder}
</>
)
}

View File

@@ -9,6 +9,7 @@ import {
PERMISSION_USER_NOT_FOUND,
SYSTEM_INVALID_CAPTCHA_CODE
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { navigateToLogin } from '@/util/navigation'
import { r_auth_forget, r_auth_retrieve } from '@/services/auth'
import { AppContext } from '@/App'

View File

@@ -11,6 +11,7 @@ import {
PERMISSION_USERNAME_NOT_FOUND,
SYSTEM_INVALID_CAPTCHA_CODE
} from '@/constants/common.constants'
import { message, notification, modal } from '@/util/common'
import { getUserInfo, setToken } from '@/util/auth'
import { utcToLocalTime } from '@/util/datetime'
import {
@@ -26,7 +27,6 @@ import FlexBox from '@/components/common/FlexBox'
const SignIn = () => {
const { styles } = useStyles()
const [modal, contextHolder] = AntdModal.useModal()
const { refreshRouter, isDarkMode } = useContext(AppContext)
const navigate = useNavigate()
const [searchParams] = useSearchParams()
@@ -82,8 +82,7 @@ const SignIn = () => {
switch (code) {
case PERMISSION_LOGIN_SUCCESS:
setToken(data?.token ?? '')
void message.success('登录成功')
setTimeout(() => {
message.success('登录成功').then(() => {
void getUserInfo().then((user) => {
refreshRouter()
navigateToRedirect(navigate, searchParams, '/repository')
@@ -109,7 +108,7 @@ const SignIn = () => {
placement: 'topRight'
})
})
}, 1500)
})
break
case PERMISSION_NEED_TWO_FACTOR:
twoFactorForm.resetFields()
@@ -299,7 +298,6 @@ const SignIn = () => {
</div>
</AntdForm>
</FlexBox>
{contextHolder}
</FitCenter>
)
}

View File

@@ -8,6 +8,7 @@ import {
SYSTEM_INVALID_CAPTCHA_CODE,
SYSTEM_MATCH_SENSITIVE_WORD
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { getLoginStatus, setToken } from '@/util/auth'
import { navigateToLogin } from '@/util/navigation'
import { r_auth_register, r_auth_resend } from '@/services/auth'

View File

@@ -6,6 +6,7 @@ import {
PERMISSION_VERIFY_SUCCESS,
SYSTEM_MATCH_SENSITIVE_WORD
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
import { navigateToLogin, navigateToRedirect, navigateToRepository } from '@/util/navigation'
import { r_auth_resend, r_auth_verify } from '@/services/auth'
@@ -125,13 +126,12 @@ const Verify = () => {
const response = res.data
switch (response.code) {
case PERMISSION_VERIFY_SUCCESS:
void message.success('恭喜你,完成了')
setTimeout(() => {
message.success('恭喜你,完成了').then(() => {
void requestUserInfo().then(() => {
refreshRouter()
navigateToRedirect(navigate, searchParams, '/repository')
})
}, 1500)
})
break
case SYSTEM_MATCH_SENSITIVE_WORD:
void message.error('昵称包含敏感词,请重试')

View File

@@ -8,6 +8,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { hasPermission } from '@/util/auth'
import { utcToLocalTime } from '@/util/datetime'
import {
@@ -27,7 +28,6 @@ import Card from '@/components/common/Card'
const Group = () => {
const theme = useTheme()
const [modal, contextHolder] = AntdModal.useModal()
const [form] = AntdForm.useForm<GroupAddEditParam>()
const formValues = AntdForm.useWatch([], form)
const [newFormValues, setNewFormValues] = useState<GroupAddEditParam>()
@@ -246,7 +246,7 @@ const Group = () => {
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除角色 ${value.name} 吗?`
content: `确定删除用户组 ${value.name} 吗?`
})
.then(
(confirmed) => {
@@ -300,7 +300,7 @@ const Group = () => {
getGroup()
break
case DATABASE_DUPLICATE_KEY:
void message.error('已存在相同名称的角色')
void message.error('已存在相同名称的用户组')
break
default:
void message.error('更新失败,请稍后重试')
@@ -321,7 +321,7 @@ const Group = () => {
getGroup()
break
case DATABASE_DUPLICATE_KEY:
void message.error('已存在相同名称的角色')
void message.error('已存在相同名称的用户组')
break
default:
void message.error('添加失败,请稍后重试')
@@ -563,6 +563,7 @@ const Group = () => {
rowKey={(record) => record.id}
pagination={tableParams.pagination}
loading={isLoading}
scroll={{ x: true }}
onChange={handleOnTableChange}
rowSelection={
hasPermission('system:group:delete:multiple')
@@ -657,7 +658,6 @@ const Group = () => {
>
{addAndEditForm}
</AntdDrawer>
{contextHolder}
</>
)
}

View File

@@ -2,6 +2,7 @@ import { ChangeEvent, KeyboardEvent } from 'react'
import { useTheme } from 'antd-style'
import dayjs from 'dayjs'
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
import { message } from '@/util/common'
import { dayjsToUtc, utcToLocalTime } from '@/util/datetime'
import { r_sys_log_get } from '@/services/system'
import FitFullscreen from '@/components/common/FitFullscreen'

View File

@@ -8,6 +8,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import { hasPermission, powerListToPowerTree } from '@/util/auth'
import {
@@ -27,7 +28,6 @@ import Card from '@/components/common/Card'
const Role = () => {
const theme = useTheme()
const [modal, contextHolder] = AntdModal.useModal()
const [form] = AntdForm.useForm<RoleAddEditParam>()
const formValues = AntdForm.useWatch([], form)
const [newFormValues, setNewFormValues] = useState<RoleAddEditParam>()
@@ -572,6 +572,7 @@ const Role = () => {
rowKey={(record) => record.id}
pagination={tableParams.pagination}
loading={isLoading}
scroll={{ x: true }}
onChange={handleOnTableChange}
rowSelection={
hasPermission('system:role:delete:multiple')
@@ -664,7 +665,6 @@ const Role = () => {
>
{addAndEditForm}
</AntdDrawer>
{contextHolder}
</>
)
}

View File

@@ -1,3 +1,4 @@
import { message } from '@/util/common'
import { hasPermission } from '@/util/auth'
import { r_sys_settings_base_get, r_sys_settings_base_update } from '@/services/system'
import SettingsCard from '@/components/system/SettingCard'

View File

@@ -1,4 +1,5 @@
import Icon from '@ant-design/icons'
import { message, modal } from '@/util/common'
import { hasPermission } from '@/util/auth'
import {
r_sys_settings_mail_get,
@@ -8,7 +9,6 @@ import {
import SettingsCard from '@/components/system/SettingCard'
const Mail = () => {
const [modal, contextHolder] = AntdModal.useModal()
const [mailForm] = AntdForm.useForm<MailSettingsParam>()
const mailFormValues = AntdForm.useWatch([], mailForm)
const [isLoading, setIsLoading] = useState(false)
@@ -114,7 +114,6 @@ const Mail = () => {
}, [])
return (
<>
<SettingsCard
icon={IconOxygenEmail}
title={'邮件'}
@@ -165,8 +164,6 @@ const Mail = () => {
</AntdForm.Item>
</AntdForm>
</SettingsCard>
{contextHolder}
</>
)
}

View File

@@ -1,6 +1,7 @@
import { ChangeEvent } from 'react'
import Icon from '@ant-design/icons'
import { DATABASE_DUPLICATE_KEY, DATABASE_INSERT_SUCCESS } from '@/constants/common.constants'
import { message } from '@/util/common'
import {
r_sys_settings_sensitive_add,
r_sys_settings_sensitive_delete,

View File

@@ -1,3 +1,4 @@
import { message } from '@/util/common'
import { hasPermission } from '@/util/auth'
import { r_sys_settings_two_factor_get, r_sys_settings_two_factor_update } from '@/services/system'
import SettingsCard from '@/components/system/SettingCard'

View File

@@ -1,4 +1,5 @@
import useStyles from '@/assets/css/pages/system/statistics/common.style'
import { message } from '@/util/common'
import { r_sys_statistics_hardware } from '@/services/system'
import FlexBox from '@/components/common/FlexBox'
import StatisticsCard from '@/components/system/StatisticsCard'

View File

@@ -1,4 +1,5 @@
import useStyles from '@/assets/css/pages/system/statistics/common.style'
import { message } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import { r_sys_statistics_software } from '@/services/system'
import FlexBox from '@/components/common/FlexBox'

View File

@@ -7,6 +7,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import { hasPermission } from '@/util/auth'
import editorExtraLibs from '@/util/editorExtraLibs'
@@ -43,7 +44,6 @@ const Base = () => {
({ currentLocation, nextLocation }) =>
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
)
const [modal, contextHolder] = AntdModal.useModal()
const [tableParams, setTableParams] = useState<TableParam>({
pagination: {
current: 1,
@@ -1093,6 +1093,7 @@ const Base = () => {
expandedRowRender,
onExpand: handleOnExpand
}}
scroll={{ x: true }}
onChange={handleOnTableChange}
/>
</Card>
@@ -1134,7 +1135,6 @@ const Base = () => {
{addAndEditForm}
</AntdDrawer>
</FitFullscreen>
{contextHolder}
<AntdModal
open={blocker.state === 'blocked'}
title={'未保存'}

View File

@@ -6,6 +6,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import {
r_sys_tool_category_add,
@@ -20,7 +21,6 @@ import HideScrollbar from '@/components/common/HideScrollbar'
const Category = () => {
const theme = useTheme()
const [modal, contextHolder] = AntdModal.useModal()
const [form] = AntdForm.useForm<ToolCategoryAddEditParam>()
const formValues = AntdForm.useWatch([], form)
const [newFormValues, setNewFormValues] = useState<ToolCategoryAddEditParam>()
@@ -298,6 +298,7 @@ const Category = () => {
columns={categoryColumns}
rowKey={(record) => record.id}
loading={isLoading}
scroll={{ x: true }}
pagination={false}
/>
</Card>
@@ -313,7 +314,6 @@ const Category = () => {
>
{addAndEditForm}
</AntdDrawer>
{contextHolder}
</>
)
}

View File

@@ -2,7 +2,7 @@ import Draggable from 'react-draggable'
import Icon from '@ant-design/icons'
import useStyles from '@/assets/css/pages/system/tools/code.style'
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 editorExtraLibs from '@/util/editorExtraLibs'
import { r_sys_tool_get_one } from '@/services/system'
@@ -17,7 +17,6 @@ const Code = () => {
const { styles } = useStyles()
const { isDarkMode } = useContext(AppContext)
const navigate = useNavigate()
const [modal, contextHolder] = AntdModal.useModal()
const { id } = useParams()
const [isLoading, setIsLoading] = useState(false)
const [files, setFiles] = useState<IFiles>({})
@@ -106,7 +105,6 @@ const Code = () => {
</div>
</Draggable>
</FitFullscreen>
{contextHolder}
</>
)
}

View File

@@ -1,5 +1,6 @@
import useStyles from '@/assets/css/pages/system/tools/execute.style'
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
import { message } from '@/util/common'
import { navigateToTools } from '@/util/navigation'
import { r_sys_tool_get_one } from '@/services/system'
import FitFullscreen from '@/components/common/FitFullscreen'

View File

@@ -7,6 +7,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import { hasPermission } from '@/util/auth'
import editorExtraLibs from '@/util/editorExtraLibs'
@@ -41,7 +42,6 @@ const Template = () => {
({ currentLocation, nextLocation }) =>
currentLocation.pathname !== nextLocation.pathname && Object.keys(hasEdited).length > 0
)
const [modal, contextHolder] = AntdModal.useModal()
const [tableParams, setTableParams] = useState<TableParam>({
pagination: {
current: 1,
@@ -1078,7 +1078,6 @@ const Template = () => {
{addAndEditForm}
</AntdDrawer>
</FitFullscreen>
{contextHolder}
<AntdModal
open={blocker.state === 'blocked'}
title={'未保存'}

View File

@@ -7,6 +7,7 @@ import {
DATABASE_UPDATE_SUCCESS,
TOOL_NOT_UNDER_REVIEW
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { navigateToCode } from '@/util/navigation'
import {
r_sys_tool_delete,
@@ -28,7 +29,6 @@ import Permission from '@/components/common/Permission'
const Tools = () => {
const theme = useTheme()
const navigate = useNavigate()
const [modal, contextHolder] = AntdModal.useModal()
const [tableParams, setTableParams] = useState<TableParam>({
pagination: {
current: 1,
@@ -572,13 +572,13 @@ const Tools = () => {
columns={dataColumns}
pagination={tableParams.pagination}
loading={isLoading}
scroll={{ x: true }}
onChange={handleOnTableChange}
/>
</Card>
)
return (
<>
<FitFullscreen>
<HideScrollbar
style={{ padding: 20 }}
@@ -591,8 +591,6 @@ const Tools = () => {
</FlexBox>
</HideScrollbar>
</FitFullscreen>
{contextHolder}
</>
)
}

View File

@@ -9,6 +9,7 @@ import {
DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants'
import { message, modal } from '@/util/common'
import { hasPermission } from '@/util/auth'
import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/util/datetime'
import {
@@ -35,7 +36,6 @@ interface ChangePasswordFields extends UserUpdatePasswordParam {
const User = () => {
const theme = useTheme()
const [modal, contextHolder] = AntdModal.useModal()
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [isDrawerEdit, setIsDrawerEdit] = useState(false)
@@ -972,6 +972,7 @@ const User = () => {
rowKey={(record) => record.id}
pagination={tableParams.pagination}
loading={isLoadingUserData}
scroll={{ x: true }}
onChange={handleOnTableChange}
rowSelection={
hasPermission('system:user:delete:multiple')
@@ -1031,7 +1032,6 @@ const User = () => {
>
{addAndEditForm}
</AntdDrawer>
{contextHolder}
</>
)
}

View File

@@ -5,6 +5,7 @@ import {
DATABASE_INSERT_SUCCESS,
DATABASE_SELECT_SUCCESS
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { navigateToEdit } from '@/util/navigation'
import {
r_tool_category_get,

View File

@@ -8,6 +8,7 @@ import {
TOOL_HAS_BEEN_PUBLISHED,
TOOL_UNDER_REVIEW
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { navigateToRepository } from '@/util/navigation'
import editorExtraLibs from '@/util/editorExtraLibs'
import { r_tool_category_get, r_tool_detail, r_tool_update } from '@/services/tool'
@@ -121,12 +122,14 @@ const Edit = () => {
getTool()
break
case TOOL_UNDER_REVIEW:
void message.error('保存失败:工具审核中')
message.error('保存失败:工具审核中').then(() => {
navigateToRepository(navigate)
})
break
case TOOL_HAS_BEEN_PUBLISHED:
void message.error('保存失败:工具已发布')
message.error('保存失败:工具已发布').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.error('保存失败,请稍后重试')
@@ -182,12 +185,14 @@ const Edit = () => {
getTool()
break
case TOOL_UNDER_REVIEW:
void message.error('保存失败:工具审核中')
message.error('保存失败:工具审核中').then(() => {
navigateToRepository(navigate)
})
break
case TOOL_HAS_BEEN_PUBLISHED:
void message.error('保存失败:工具已发布')
message.error('保存失败:工具已发布').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.error('保存失败,请稍后重试')
@@ -239,17 +244,20 @@ const Edit = () => {
setHasEdited(false)
break
case 'PROCESSING':
void message.warning('工具审核中,请勿修改')
message.warning('工具审核中,请勿修改').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.warning('请先创建新版本后编辑工具')
message.warning('请先创建新版本后编辑工具').then(() => {
navigateToRepository(navigate)
})
}
break
case DATABASE_NO_RECORD_FOUND:
void message.error('未找到指定工具')
message.error('未找到指定工具').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.error('获取工具信息失败,请稍后重试')

View File

@@ -1,5 +1,6 @@
import useStyles from '@/assets/css/pages/tools/source.style'
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
import { message } from '@/util/common'
import { getLoginStatus } from '@/util/auth'
import { navigateToRepository, navigateToSource } from '@/util/navigation'
import editorExtraLibs from '@/util/editorExtraLibs'
@@ -52,8 +53,9 @@ const Source = () => {
render(response.data!)
break
case DATABASE_NO_RECORD_FOUND:
void message.error('未找到指定工具')
void message.error('未找到指定工具').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.error('获取工具信息失败,请稍后重试')

View File

@@ -1,7 +1,7 @@
import { UIEvent } from 'react'
import useStyles from '@/assets/css/pages/tools/store.style'
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 FlexBox from '@/components/common/FlexBox'
import FitFullscreen from '@/components/common/FitFullscreen'

View File

@@ -1,7 +1,7 @@
import Icon from '@ant-design/icons'
import useStyles from '@/assets/css/pages/tools/user.style'
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 { r_sys_user_info_get_basic } from '@/services/system'
import { r_tool_store_get_by_username } from '@/services/tool'
@@ -40,7 +40,7 @@ const User = () => {
return
}
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!)
.then((res) => {
@@ -51,10 +51,9 @@ const User = () => {
getTool(1)
break
case DATABASE_NO_RECORD_FOUND:
void message.warning('用户不存在')
setTimeout(() => {
void message.warning('用户不存在').then(() => {
navigateToRoot(navigate)
}, 3000)
})
break
default:
void message.error('获取失败请稍后重试')

View File

@@ -1,5 +1,6 @@
import useStyles from '@/assets/css/pages/tools/view.style'
import { DATABASE_NO_RECORD_FOUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
import { message } from '@/util/common'
import { getLoginStatus } from '@/util/auth'
import { navigateToRepository, navigateToRoot, navigateToView } from '@/util/navigation'
import { r_tool_detail } from '@/services/tool'
@@ -78,8 +79,9 @@ const View = () => {
render(response.data!)
break
case DATABASE_NO_RECORD_FOUND:
void message.error('未找到指定工具')
void message.error('未找到指定工具').then(() => {
navigateToRepository(navigate)
})
break
default:
void message.error('获取工具信息失败,请稍后重试')
@@ -98,8 +100,9 @@ const View = () => {
return
}
if (username === '!' && !getLoginStatus()) {
void message.error('未登录')
void message.error('未登录').then(() => {
navigateToRoot(navigate)
})
return
}
if (username !== '!' && ver) {

View File

@@ -12,7 +12,7 @@ import {
TOOL_SUBMIT_SUCCESS,
TOOL_UNDER_REVIEW
} from '@/constants/common.constants'
import { checkDesktop } from '@/util/common'
import { message, modal, checkDesktop } from '@/util/common'
import { getLoginStatus } from '@/util/auth'
import { navigateToEdit, navigateToSource, navigateToView } from '@/util/navigation'
import {
@@ -204,7 +204,6 @@ const ToolCard = ({ tools, onDelete, onUpgrade, onSubmit, onCancel }: ToolCardPr
const Tools = () => {
const { styles } = useStyles()
const navigate = useNavigate()
const [modal, contextHolder] = AntdModal.useModal()
const [isLoading, setIsLoading] = useState(false)
const [currentPage, setCurrentPage] = useState(0)
const [hasNextPage, setHasNextPage] = useState(false)
@@ -537,7 +536,6 @@ const Tools = () => {
}, [])
return (
<>
<FitFullscreen>
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={1000}>
<FlexBox direction={'vertical'} className={styles.root}>
@@ -566,10 +564,7 @@ const Tools = () => {
</FlexBox>
{starToolData.length ? (
<>
<FlexBox
direction={'horizontal'}
className={styles.favoriteDivider}
>
<FlexBox direction={'horizontal'} className={styles.favoriteDivider}>
<div />
<div className={styles.dividerText}></div>
<div />
@@ -580,8 +575,7 @@ const Tools = () => {
if (
!previousValue.some(
(value) =>
value.author.id ===
currentValue.author.id &&
value.author.id === currentValue.author.id &&
value.toolId === currentValue.toolId
)
) {
@@ -626,17 +620,13 @@ const Tools = () => {
/>
)
})}
{hasNextStarPage && (
<LoadMoreCard onClick={handleOnLoadMoreStar} />
)}
{hasNextStarPage && <LoadMoreCard onClick={handleOnLoadMoreStar} />}
</FlexBox>
</>
) : undefined}
</FlexBox>
</HideScrollbar>
</FitFullscreen>
{contextHolder}
</>
)
}

View File

@@ -3,7 +3,7 @@ import { arrayMove, SortableContext } from '@dnd-kit/sortable'
import type { DragEndEvent } from '@dnd-kit/core/dist/types'
import useStyles from '@/assets/css/pages/tools-framework.style'
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 FitFullscreen from '@/components/common/FitFullscreen'
import Sidebar from '@/components/common/Sidebar'

View File

@@ -5,6 +5,7 @@ import {
PERMISSION_ACCESS_DENIED,
PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR
} from '@/constants/common.constants'
import { message, notification, modal } from '@/util/common'
import { utcToLocalTime } from '@/util/datetime'
import { getUserInfo, removeToken } from '@/util/auth'
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 { styles, theme } = useStyles()
const [modal, contextHolder] = AntdModal.useModal()
const [form] = AntdForm.useForm<UserInfoUpdateParam>()
const formValues = AntdForm.useWatch([], form)
const [twoFactorForm] = AntdForm.useForm<{ twoFactorCode: string }>()
@@ -180,7 +180,6 @@ const User = () => {
const response = res.data
switch (response.code) {
case DATABASE_UPDATE_SUCCESS:
void message.success('密码修改成功,请重新登录')
removeToken()
notification.info({
message: '已退出登录',
@@ -191,9 +190,9 @@ const User = () => {
/>
)
})
setTimeout(() => {
message.success('密码修改成功,请重新登录').then(() => {
window.location.reload()
}, 1500)
})
resolve()
break
case PERMISSION_ACCESS_DENIED:
@@ -312,7 +311,7 @@ const User = () => {
return
}
setIsLoading(true)
void message.loading({ content: '加载中', key: 'LOADING', duration: 0 })
void message.loading({ content: '加载中……', key: 'LOADING', duration: 0 })
void r_auth_two_factor_create()
.then((res) => {
message.destroy('LOADING')
@@ -447,7 +446,6 @@ const User = () => {
}, [])
return (
<>
<FitFullscreen>
<HideScrollbar
isShowVerticalScrollbar
@@ -540,10 +538,7 @@ const User = () => {
<FlexBox className={styles.row} direction={'horizontal'}>
<div className={styles.label}></div>
<div className={styles.input}>
<AntdInput
disabled
value={userWithPowerInfoVo?.userInfo.email}
/>
<AntdInput disabled value={userWithPowerInfoVo?.userInfo.email} />
</div>
</FlexBox>
<FlexBox className={styles.row} direction={'horizontal'}>
@@ -551,9 +546,7 @@ const User = () => {
<div className={styles.input}>
<AntdInput
disabled
value={utcToLocalTime(
userWithPowerInfoVo?.createTime ?? ''
)}
value={utcToLocalTime(userWithPowerInfoVo?.createTime ?? '')}
/>
</div>
</FlexBox>
@@ -571,9 +564,7 @@ const User = () => {
<div className={styles.input}>
<AntdInput
disabled
value={utcToLocalTime(
userWithPowerInfoVo?.lastLoginTime ?? ''
)}
value={utcToLocalTime(userWithPowerInfoVo?.lastLoginTime ?? '')}
/>
</div>
</FlexBox>
@@ -604,9 +595,7 @@ const User = () => {
? theme.colorPrimary
: undefined
}}
value={
userWithPowerInfoVo?.twoFactor ? '已设置' : '未设置'
}
value={userWithPowerInfoVo?.twoFactor ? '已设置' : '未设置'}
/>
<AntdButton
type={'primary'}
@@ -631,8 +620,6 @@ const User = () => {
</Card>
</HideScrollbar>
</FitFullscreen>
{contextHolder}
</>
)
}

View File

@@ -8,6 +8,7 @@ import {
PERMISSION_UNAUTHORIZED,
SYSTEM_REQUEST_TOO_FREQUENT
} from '@/constants/common.constants'
import { message } from '@/util/common'
import { getRedirectUrl } from '@/util/route'
import { getToken, setToken, removeToken } from '@/util/auth'
@@ -68,7 +69,8 @@ service.interceptors.response.use(
switch (response.data.code) {
case PERMISSION_UNAUTHORIZED:
removeToken()
void message.error({
message
.error({
content: (
<>
<strong></strong>
@@ -76,14 +78,15 @@ service.interceptors.response.use(
),
key: 'NO_LOGIN'
})
setTimeout(() => {
.then(() => {
location.reload()
}, 1500)
})
throw response?.data
case PERMISSION_TOKEN_ILLEGAL:
case PERMISSION_TOKEN_HAS_EXPIRED:
removeToken()
void message.error({
message
.error({
content: (
<>
<strong></strong>
@@ -91,11 +94,11 @@ service.interceptors.response.use(
),
key: 'LOGIN_HAS_EXPIRED'
})
setTimeout(() => {
.then(() => {
location.replace(
getRedirectUrl('/login', `${location.pathname}${location.search}`)
)
}, 1500)
})
throw response?.data
case PERMISSION_ACCESS_DENIED:
void message.error({

View File

@@ -3,6 +3,25 @@ import { floor } from 'lodash'
import { STORAGE_TOOL_MENU_ITEM_KEY } from '@/constants/common.constants'
import { getLocalStorage, setLocalStorage } from '@/util/browser'
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) => {
if (start > end) {