diff --git a/src/AuthRoute.tsx b/src/AuthRoute.tsx index c131a0b..dcf5b83 100644 --- a/src/AuthRoute.tsx +++ b/src/AuthRoute.tsx @@ -1,6 +1,6 @@ import { PRODUCTION_NAME } from '@/constants/common.constants' -import { getLoginStatus } from '@/utils/auth' -import { getRedirectUrl } from '@/utils/common' +import { getRedirectUrl } from '@/util/route' +import { getLoginStatus } from '@/util/auth' const AuthRoute = () => { const matches = useMatches() diff --git a/src/components/common/sidebar/SidebarFooter.tsx b/src/components/common/sidebar/SidebarFooter.tsx index 20d0fe4..6e1c9bb 100644 --- a/src/components/common/sidebar/SidebarFooter.tsx +++ b/src/components/common/sidebar/SidebarFooter.tsx @@ -1,8 +1,8 @@ import React from 'react' import Icon from '@ant-design/icons' import { COLOR_ERROR } from '@/constants/common.constants' -import { getRedirectUrl } from '@/utils/common' -import { getLoginStatus, getNickname, logout } from '@/utils/auth' +import { getRedirectUrl } from '@/util/route' +import { getLoginStatus, getNickname, logout } from '@/util/auth' const SidebarFooter: React.FC = () => { const matches = useMatches() diff --git a/src/components/common/sidebar/index.tsx b/src/components/common/sidebar/index.tsx index 281eb1a..cf8e542 100644 --- a/src/components/common/sidebar/index.tsx +++ b/src/components/common/sidebar/index.tsx @@ -1,7 +1,7 @@ import React from 'react' import Icon from '@ant-design/icons' import '@/assets/css/components/common/sidebar.scss' -import { getLocalStorage, setLocalStorage } from '@/utils/common' +import { getLocalStorage, setLocalStorage } from '@/util/browser' import SidebarSeparate from '@/components/common/sidebar/SidebarSeparate' import SidebarFooter from '@/components/common/sidebar/SidebarFooter' diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 65506a2..4fd39b2 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -6,8 +6,8 @@ import { PERMISSION_USER_DISABLE, PERMISSION_USERNAME_NOT_FOUND } from '@/constants/common.constants' -import { utcToLocalTime, setToken } from '@/utils/common' -import { getUserInfo, login } from '@/utils/auth' +import { utcToLocalTime } from '@/util/datetime' +import { getUserInfo, login, setToken } from '@/util/auth' const Login: React.FC = () => { const [messageApi, contextHolder] = message.useMessage() diff --git a/src/pages/UserFramework.tsx b/src/pages/UserFramework.tsx index b88ff73..830c463 100644 --- a/src/pages/UserFramework.tsx +++ b/src/pages/UserFramework.tsx @@ -1,7 +1,7 @@ import React from 'react' import '@/assets/css/pages/tools-framework.scss' import user from '@/router/user' -import { hasPathPermission } from '@/utils/auth' +import { hasPathPermission } from '@/util/auth' import FitFullScreen from '@/components/common/FitFullScreen' import Sidebar from '@/components/common/sidebar' import SidebarItemList from '@/components/common/sidebar/SidebarItemList' diff --git a/src/pages/system/Group.tsx b/src/pages/system/Group.tsx index 2563fed..5658fc4 100644 --- a/src/pages/system/Group.tsx +++ b/src/pages/system/Group.tsx @@ -10,8 +10,8 @@ import { DATABASE_SELECT_SUCCESS, DATABASE_UPDATE_SUCCESS } from '@/constants/common.constants' -import { utcToLocalTime } from '@/utils/common' -import { useUpdatedEffect } from '@/utils/hooks' +import { useUpdatedEffect } from '@/util/hooks' +import { utcToLocalTime } from '@/util/datetime' import { r_sys_group_add, r_sys_group_change_status, diff --git a/src/pages/system/Log.tsx b/src/pages/system/Log.tsx index e530c95..c5e1425 100644 --- a/src/pages/system/Log.tsx +++ b/src/pages/system/Log.tsx @@ -5,8 +5,8 @@ import { COLOR_FONT_SECONDARY, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants' -import { dayjsToUtc, utcToLocalTime } from '@/utils/common' -import { useUpdatedEffect } from '@/utils/hooks' +import { useUpdatedEffect } from '@/util/hooks' +import { dayjsToUtc, utcToLocalTime } from '@/util/datetime' import { r_sys_log_get } from '@/services/system' import FitFullScreen from '@/components/common/FitFullScreen' import Card from '@/components/common/Card' diff --git a/src/pages/system/Role.tsx b/src/pages/system/Role.tsx index 652f9cf..cf34831 100644 --- a/src/pages/system/Role.tsx +++ b/src/pages/system/Role.tsx @@ -10,8 +10,9 @@ import { DATABASE_SELECT_SUCCESS, DATABASE_UPDATE_SUCCESS } from '@/constants/common.constants' -import { utcToLocalTime, powerListToPowerTree } from '@/utils/common' -import { useUpdatedEffect } from '@/utils/hooks' +import { useUpdatedEffect } from '@/util/hooks' +import { utcToLocalTime } from '@/util/datetime' +import { powerListToPowerTree } from '@/util/auth.tsx' import { r_sys_role_add, r_sys_role_change_status, diff --git a/src/pages/system/User.tsx b/src/pages/system/User.tsx index ebc6a69..42afc11 100644 --- a/src/pages/system/User.tsx +++ b/src/pages/system/User.tsx @@ -11,8 +11,8 @@ import { DATABASE_SELECT_SUCCESS, DATABASE_UPDATE_SUCCESS } from '@/constants/common.constants' -import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/utils/common' -import { useUpdatedEffect } from '@/utils/hooks' +import { useUpdatedEffect } from '@/util/hooks' +import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/util/datetime' import { r_sys_group_get_list, r_sys_role_get_list, diff --git a/src/router/system.tsx b/src/router/system.tsx index 4bdc155..2f8197a 100644 --- a/src/router/system.tsx +++ b/src/router/system.tsx @@ -1,6 +1,6 @@ import React from 'react' -const user: RouteJsonObject[] = [ +const system: RouteJsonObject[] = [ { path: '', absolutePath: '/system', @@ -61,4 +61,4 @@ const user: RouteJsonObject[] = [ } ] -export default user +export default system diff --git a/src/services/api/avatar.ts b/src/services/api/avatar.tsx similarity index 100% rename from src/services/api/avatar.ts rename to src/services/api/avatar.tsx diff --git a/src/services/index.tsx b/src/services/index.tsx index ab8ca04..1b890c9 100644 --- a/src/services/index.tsx +++ b/src/services/index.tsx @@ -7,7 +7,7 @@ import { PERMISSION_TOKEN_RENEW_SUCCESS, PERMISSION_UNAUTHORIZED } from '@/constants/common.constants' -import { getToken, removeToken, setToken } from '@/utils/common' +import { getToken, setToken, removeToken } from '@/util/auth' const service: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_API_URL, diff --git a/src/utils/common.tsx b/src/util/auth.tsx similarity index 51% rename from src/utils/common.tsx rename to src/util/auth.tsx index c58a74a..b9e3d3f 100644 --- a/src/utils/common.tsx +++ b/src/util/auth.tsx @@ -1,85 +1,28 @@ -import ReactDOM from 'react-dom/client' -import moment from 'moment' -import dayjs from 'dayjs' import _ from 'lodash' -import { STORAGE_TOKEN_KEY, STORAGE_USER_INFO_KEY } from '@/constants/common.constants' -import LoadingMask from '@/components/common/LoadingMask' +import { + STORAGE_TOKEN_KEY, + STORAGE_USER_INFO_KEY, + DATABASE_SELECT_SUCCESS +} from '@/constants/common.constants' +import { floorNumber, randomColor, randomFloat, randomInt } from '@/util/common' +import { getLocalStorage, removeLocalStorage, setLocalStorage } from '@/util/browser' +import { getFullTitle } from '@/util/route' +import { r_sys_user_info } from '@/services/system' +import { r_auth_login, r_auth_logout } from '@/services/auth' -export const getQueryVariable = (variable: string) => { - const query = window.location.search.substring(1) - const vars = query.split('&') - for (const value of vars) { - const pair = value.split('=') - if (pair[0] === variable) { - return decodeURIComponent(pair[1].replace(/\+/g, ' ')) - } - } - return null -} - -export const setCookie = ( - name: string, - value: string, - daysToLive: number | null, - path: string | null -) => { - let cookie = `${name}=${encodeURIComponent(value)}` - - if (typeof daysToLive === 'number') { - cookie = `${cookie}; max-age=${daysToLive * 24 * 60 * 60}` - } - - if (typeof path === 'string') { - cookie = `${cookie}; path=${path}` - } - - document.cookie = cookie -} - -export const setLocalStorage = (name: string, value: string) => { - localStorage.setItem(name, value) -} +let captcha: Captcha export const setToken = (token: string) => { setLocalStorage(STORAGE_TOKEN_KEY, token) } -export const getCookie = (name: string) => { - const cookieArr = document.cookie.split(';') - - for (const cookie of cookieArr) { - const cookiePair = cookie.split('=') - if (cookiePair[0].trim() === name) { - return decodeURIComponent(cookiePair[1]) - } - } - - return null -} - -export const getLocalStorage = (name: string) => { - return localStorage.getItem(name) -} - -export const getToken = () => { - return getLocalStorage(STORAGE_TOKEN_KEY) -} - -export const removeCookie = (name: string) => { - document.cookie = `${name}=; max-age=0` -} - -export const removeLocalStorage = (name: string) => { - localStorage.removeItem(name) -} - export const removeToken = () => { removeLocalStorage(STORAGE_USER_INFO_KEY) removeLocalStorage(STORAGE_TOKEN_KEY) } -export const clearLocalStorage = () => { - localStorage.clear() +export const getToken = () => { + return getLocalStorage(STORAGE_TOKEN_KEY) } export const getCaptcha = (width: number, high: number, num: number) => { @@ -122,68 +65,102 @@ export const getCaptcha = (width: number, high: number, num: number) => { } } -const randomInt = (start: number, end: number) => { - if (start > end) { - const t = start - start = end - end = t +export const login = async (username: string, password: string) => { + return await r_auth_login(username, password) +} + +export const logout = async () => { + return r_auth_logout().finally(() => { + removeToken() + }) +} + +export const getLoginStatus = () => { + return getLocalStorage(STORAGE_TOKEN_KEY) !== null +} + +export const getUserInfo = async (): Promise => { + if (getLocalStorage(STORAGE_USER_INFO_KEY) !== null) { + return new Promise((resolve) => { + resolve( + JSON.parse(getLocalStorage(STORAGE_USER_INFO_KEY) as string) as UserWithPowerInfoVo + ) + }) } - start = Math.ceil(start) - end = Math.floor(end) - return start + Math.floor(Math.random() * (end - start)) + return requestUserInfo() } -const randomFloat = (start: number, end: number) => { - return start + Math.random() * (end - start) -} +export const requestUserInfo = async () => { + let user: UserWithPowerInfoVo | null -const randomColor = (start: number, end: number) => { - return `rgb(${randomInt(start, end)},${randomInt(start, end)},${randomInt(start, end)})` -} - -export const getRedirectUrl = (path: string, redirectUrl: string): string => { - return `${path}?redirect=${encodeURIComponent(redirectUrl)}` -} - -export const getNowLocalTime = (format: string = 'yyyy-MM-DD HH:mm:ssZ') => { - return moment().local().format(format) -} - -export const getNowUtc = () => { - return moment().toISOString() -} - -export const utcToLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => { - return moment.utc(utcTime).local().format(format) -} - -export const dayjsToLocalTime = (date: dayjs.Dayjs, format: string = 'YYYY-MM-DD HH:mm:ssZ') => { - return date.format(format) -} - -export const dayjsToUtc = (date: dayjs.Dayjs) => { - return date.toISOString() -} - -export const localTimeToUtc = (localTime: string) => { - return moment(localTime).toISOString() -} - -export const isPastTime = (utcTime: string) => { - return moment.utc(utcTime).isBefore(moment.now()) -} - -export const floorNumber = (num: number, digits: number) => { - if (digits > 0) { - return Math.floor(num / Math.pow(10, digits - 1)) * Math.pow(10, digits - 1) - } else { - const regExpMatchArray = num.toString().match(new RegExp('^\\d\\.\\d{' + -digits + '}')) - if (regExpMatchArray !== null) { - return parseFloat(regExpMatchArray[0]).toFixed(-digits) - } else { - return num + await r_sys_user_info().then((value) => { + const response = value.data + if (response.code === DATABASE_SELECT_SUCCESS) { + user = response.data + setLocalStorage(STORAGE_USER_INFO_KEY, JSON.stringify(user)) } + }) + + return new Promise((resolve, reject) => { + if (user) { + resolve(user) + } + reject(user) + }) +} + +export const getNickname = async () => { + const user = await getUserInfo() + + return user.userInfo.nickname +} + +export const getUsername = async () => { + const user = await getUserInfo() + + return user.username +} + +export const getPermissionPath = (): string[] => { + const s = getLocalStorage(STORAGE_USER_INFO_KEY) + if (s === null) { + return [] } + + const user = JSON.parse(s) as UserWithPowerInfoVo + const paths: string[] = [] + user.menus.forEach((menu) => { + paths.push(menu.url) + }) + + return paths +} + +export const hasPathPermission = (path: string) => { + return getPermissionPath().indexOf(path) !== -1 +} + +/* +export const getAuthRoute = (route: RouteJsonObject[]): RouteJsonObject[] => { + return route.map((value) => { + if (value.absolutePath) { + value.absolutePath + } + if (value.children) { + value.children = getAuthRoute(value.children) + } + return value + }) +} +*/ + +export const getCaptchaSrc = () => { + captcha = getCaptcha(300, 150, 4) + return captcha.base64Src +} + +export const verifyCaptcha = (value: string) => { + return captcha.value.toLowerCase() === value.replace(/\s*/g, '').toLowerCase() } export const powerListToPowerTree = ( @@ -283,35 +260,3 @@ const parentToTree = (data: _DataNode[]): _DataNode[] => { return parents } - -const getFullTitle = (data: _DataNode, preTitle?: string) => { - data.fullTitle = `${preTitle ? `${preTitle}-` : ''}${data.title as string}` - data.children && - data.children.forEach((value) => { - getFullTitle(value, data.fullTitle) - }) - - return data -} - -export const showLoadingMask = (id: string) => { - if (document.querySelector(`#${id}`)) { - return - } - - const container = document.createElement('div') - document.body.appendChild(container) - container.id = id - container.setAttribute( - 'style', - 'position: fixed; width: 100vw; height: 100vh; z-index: 10000; left: 0; top: 0;' - ) - - return ReactDOM.createRoot(container).render() -} - -export const removeLoadingMask = (id: string) => { - document.querySelectorAll(`#${id}`).forEach((value) => { - value.parentNode?.removeChild(value) - }) -} diff --git a/src/util/browser.tsx b/src/util/browser.tsx new file mode 100644 index 0000000..5b8457d --- /dev/null +++ b/src/util/browser.tsx @@ -0,0 +1,63 @@ +export const getQueryVariable = (variable: string) => { + const query = window.location.search.substring(1) + const vars = query.split('&') + for (const value of vars) { + const pair = value.split('=') + if (pair[0] === variable) { + return decodeURIComponent(pair[1].replace(/\+/g, ' ')) + } + } + return null +} + +export const setCookie = ( + name: string, + value: string, + daysToLive: number | null, + path: string | null +) => { + let cookie = `${name}=${encodeURIComponent(value)}` + + if (typeof daysToLive === 'number') { + cookie = `${cookie}; max-age=${daysToLive * 24 * 60 * 60}` + } + + if (typeof path === 'string') { + cookie = `${cookie}; path=${path}` + } + + document.cookie = cookie +} + +export const getCookie = (name: string) => { + const cookieArr = document.cookie.split(';') + + for (const cookie of cookieArr) { + const cookiePair = cookie.split('=') + if (cookiePair[0].trim() === name) { + return decodeURIComponent(cookiePair[1]) + } + } + + return null +} + +export const removeCookie = (name: string) => { + document.cookie = `${name}=; max-age=0` +} + +export const setLocalStorage = (name: string, value: string) => { + localStorage.setItem(name, value) +} + +export const getLocalStorage = (name: string) => { + return localStorage.getItem(name) +} + +export const removeLocalStorage = (name: string) => { + localStorage.removeItem(name) +} + +export const clearLocalStorage = () => { + localStorage.clear() +} diff --git a/src/util/common.tsx b/src/util/common.tsx new file mode 100644 index 0000000..88bf514 --- /dev/null +++ b/src/util/common.tsx @@ -0,0 +1,56 @@ +import ReactDOM from 'react-dom/client' +import LoadingMask from '@/components/common/LoadingMask' + +export const randomInt = (start: number, end: number) => { + if (start > end) { + const t = start + start = end + end = t + } + start = Math.ceil(start) + end = Math.floor(end) + return start + Math.floor(Math.random() * (end - start)) +} + +export const randomFloat = (start: number, end: number) => { + return start + Math.random() * (end - start) +} + +export const randomColor = (start: number, end: number) => { + return `rgb(${randomInt(start, end)},${randomInt(start, end)},${randomInt(start, end)})` +} + +export const floorNumber = (num: number, digits: number) => { + if (digits > 0) { + return Math.floor(num / Math.pow(10, digits - 1)) * Math.pow(10, digits - 1) + } else { + const regExpMatchArray = num.toString().match(new RegExp('^\\d\\.\\d{' + -digits + '}')) + if (regExpMatchArray !== null) { + return parseFloat(regExpMatchArray[0]).toFixed(-digits) + } else { + return num + } + } +} + +export const showLoadingMask = (id: string) => { + if (document.querySelector(`#${id}`)) { + return + } + + const container = document.createElement('div') + document.body.appendChild(container) + container.id = id + container.setAttribute( + 'style', + 'position: fixed; width: 100vw; height: 100vh; z-index: 10000; left: 0; top: 0;' + ) + + return ReactDOM.createRoot(container).render() +} + +export const removeLoadingMask = (id: string) => { + document.querySelectorAll(`#${id}`).forEach((value) => { + value.parentNode?.removeChild(value) + }) +} diff --git a/src/util/datetime.tsx b/src/util/datetime.tsx new file mode 100644 index 0000000..b88ade6 --- /dev/null +++ b/src/util/datetime.tsx @@ -0,0 +1,30 @@ +import moment from 'moment/moment' +import dayjs from 'dayjs' + +export const getNowLocalTime = (format: string = 'yyyy-MM-DD HH:mm:ssZ') => { + return moment().local().format(format) +} + +export const getNowUtc = () => { + return moment().toISOString() +} + +export const utcToLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => { + return moment.utc(utcTime).local().format(format) +} + +export const dayjsToLocalTime = (date: dayjs.Dayjs, format: string = 'YYYY-MM-DD HH:mm:ssZ') => { + return date.format(format) +} + +export const dayjsToUtc = (date: dayjs.Dayjs) => { + return date.toISOString() +} + +export const localTimeToUtc = (localTime: string) => { + return moment(localTime).toISOString() +} + +export const isPastTime = (utcTime: string) => { + return moment.utc(utcTime).isBefore(moment.now()) +} diff --git a/src/utils/hooks.tsx b/src/util/hooks.tsx similarity index 100% rename from src/utils/hooks.tsx rename to src/util/hooks.tsx diff --git a/src/util/route.tsx b/src/util/route.tsx new file mode 100644 index 0000000..e8a6489 --- /dev/null +++ b/src/util/route.tsx @@ -0,0 +1,13 @@ +export const getRedirectUrl = (path: string, redirectUrl: string): string => { + return `${path}?redirect=${encodeURIComponent(redirectUrl)}` +} + +export const getFullTitle = (data: _DataNode, preTitle?: string) => { + data.fullTitle = `${preTitle ? `${preTitle}-` : ''}${data.title as string}` + data.children && + data.children.forEach((value) => { + getFullTitle(value, data.fullTitle) + }) + + return data +} diff --git a/src/utils/auth.ts b/src/utils/auth.ts deleted file mode 100644 index d85501f..0000000 --- a/src/utils/auth.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { - STORAGE_TOKEN_KEY, - STORAGE_USER_INFO_KEY, - DATABASE_SELECT_SUCCESS -} from '@/constants/common.constants' -import { getCaptcha, getLocalStorage, removeToken, setLocalStorage } from './common' -import { r_sys_user_info } from '@/services/system' -import { r_auth_login, r_auth_logout } from '@/services/auth' - -let captcha: Captcha - -export const login = async (username: string, password: string) => { - return await r_auth_login(username, password) -} - -export const logout = async () => { - return r_auth_logout().finally(() => { - removeToken() - }) -} - -export const getLoginStatus = () => { - return getLocalStorage(STORAGE_TOKEN_KEY) !== null -} - -export const getUserInfo = async (): Promise => { - if (getLocalStorage(STORAGE_USER_INFO_KEY) !== null) { - return new Promise((resolve) => { - resolve( - JSON.parse(getLocalStorage(STORAGE_USER_INFO_KEY) as string) as UserWithPowerInfoVo - ) - }) - } - return requestUserInfo() -} - -export const requestUserInfo = async () => { - let user: UserWithPowerInfoVo | null - - await r_sys_user_info().then((value) => { - const response = value.data - if (response.code === DATABASE_SELECT_SUCCESS) { - user = response.data - setLocalStorage(STORAGE_USER_INFO_KEY, JSON.stringify(user)) - } - }) - - return new Promise((resolve, reject) => { - if (user) { - resolve(user) - } - reject(user) - }) -} - -export const getNickname = async () => { - const user = await getUserInfo() - - return user.userInfo.nickname -} - -export const getUsername = async () => { - const user = await getUserInfo() - - return user.username -} - -export const getPermissionPath = (): string[] => { - const s = getLocalStorage(STORAGE_USER_INFO_KEY) - if (s === null) { - return [] - } - - const user = JSON.parse(s) as UserWithPowerInfoVo - const paths: string[] = [] - user.menus.forEach((menu) => { - paths.push(menu.url) - }) - - return paths -} - -export const hasPathPermission = (path: string) => { - return getPermissionPath().indexOf(path) !== -1 -} - -/* -export const getAuthRoute = (route: RouteJsonObject[]): RouteJsonObject[] => { - return route.map((value) => { - if (value.absolutePath) { - value.absolutePath - } - if (value.children) { - value.children = getAuthRoute(value.children) - } - return value - }) -} -*/ - -export const getCaptchaSrc = () => { - captcha = getCaptcha(300, 150, 4) - return captcha.base64Src -} - -export const verifyCaptcha = (value: string) => { - return captcha.value.toLowerCase() === value.replace(/\s*/g, '').toLowerCase() -}