diff --git a/config/vite.config.base.ts b/config/vite.config.base.ts index 25cfa362f3a817646b4bd3b082263c0dff47efe5..c17d93cd3b8f0fede3a7eb4eef724a19625d3e79 100644 --- a/config/vite.config.base.ts +++ b/config/vite.config.base.ts @@ -16,10 +16,6 @@ export default defineConfig({ find: 'assets', replacement: resolve(__dirname, '../src/assets'), }, - { - find: 'vue-i18n', - replacement: 'vue-i18n/dist/vue-i18n.cjs.js', // Resolve the i18n warning issue - }, { find: 'vue', replacement: 'vue/dist/vue.esm-bundler.js', // compile template diff --git a/config/vite.config.prod.ts b/config/vite.config.prod.ts index d87d78ad45a3650cd3734a6b19bb3548816c2a73..bf7593b14dcf8c497c61796f0b240bdb3d87a9a8 100644 --- a/config/vite.config.prod.ts +++ b/config/vite.config.prod.ts @@ -22,7 +22,7 @@ export default mergeConfig( manualChunks: { arco: ['@arco-design/web-vue'], chart: ['echarts', 'vue-echarts'], - vue: ['vue', 'vue-router', 'pinia', '@vueuse/core', 'vue-i18n'], + vue: ['vue', 'vue-router', 'pinia', '@vueuse/core'], }, }, }, diff --git a/package.json b/package.json index e4c0fb06e213b15a2e77e0685c953821487eceec..d24067768e5e2dd52c94646b2ca224fa8e3772ce 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint src --fix --ext .js,.ts,.jsx,.tsx,.vue" }, "dependencies": { - "@arco-design/web-vue": "^2.30.2", + "@arco-design/web-vue": "^2.35.3", "@types/mockjs": "^1.0.4", "@vueuse/core": "^7.3.0", "arco-design-pro-vue": "^2.5.7", @@ -28,7 +28,6 @@ "query-string": "^7.0.1", "vue": "^3.2.31", "vue-echarts": "^6.0.0", - "vue-i18n": "^9.2.0-beta.17", "vue-router": "^4.0.14" }, "devDependencies": { diff --git a/src/App.vue b/src/App.vue index e0629b14d390a67e78ef5328ed1657766f6e26a0..b4f72f820c45956b635618e39455d1864e70bd05 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,26 +1,11 @@ diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..fe47e68c41711c6ed9c84405081ffa4bf1e3492e --- /dev/null +++ b/src/api/auth/index.ts @@ -0,0 +1,39 @@ +import axios from 'axios' +import website from '@/config/website' +import { LoginData, ResToken } from '@/types/modules/system' +import qs from 'query-string' +import { clearToken } from '@/utils/auth' + +const contentPath = '/auth/oauth' + +export function login(data: LoginData) { + clearToken() + const grantType = website?.grantTypes?.password || 'password' + const basicAuth = `Basic ${window.btoa(website.traditionLoginClient)}` + return axios.post('/auth/oauth/token', qs.stringify(data), { + headers: { + Authorization: basicAuth, + }, + params: { + grant_type: grantType, + }, + }) +} + +export function refreshToken(refresh_token: string) { + const grantType = website?.grantTypes?.refresh_token || 'refresh_token' + const basicAuth = `Basic ${window.btoa(website.traditionLoginClient)}` + return axios.post('/auth/oauth/token', { + headers: { + Authorization: basicAuth, + }, + params: { + grant_type: grantType, + refresh_token, + }, + }) +} + +export function logout() { + return axios.post(`${contentPath}/logout`) +} diff --git a/src/api/interceptor.ts b/src/api/interceptor.ts index 590b96885601c180f34131224e9a71b0924e69f6..29168b2d1fd4afec98f23837019b5b29407f7fa9 100644 --- a/src/api/interceptor.ts +++ b/src/api/interceptor.ts @@ -2,8 +2,8 @@ import axios from 'axios' import type { AxiosRequestConfig, AxiosResponse } from 'axios' import { Message, Modal } from '@arco-design/web-vue' import { useUserStore } from '@/store' -import { getToken } from '@/utils/auth' -import { Response } from '@/api/types' +import { clearToken, getToken } from '@/utils/auth' +import { Response } from '@/types/global' if (import.meta.env.VITE_API_BASE_URL) { axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL @@ -27,8 +27,7 @@ axios.interceptors.request.use( (error) => { // do something Promise.reject(error) - } - , + }, ) // add response interceptors axios.interceptors.response.use( @@ -63,8 +62,11 @@ axios.interceptors.response.use( return res }, (error) => { + if ([40101].includes(error?.response?.data?.code)) { + clearToken() + } Message.error({ - content: error.msg || 'Request Error', + content: error?.response?.data?.message || 'Request Error', duration: 5 * 1000, }) return Promise.reject(error) diff --git a/src/api/system/authority/index.ts b/src/api/system/authority/index.ts index b6ee74f9a5f8dbb80154ef49fc5fcef44f158039..e5bf2497d9922c5597fa1442eaebe0012442551a 100644 --- a/src/api/system/authority/index.ts +++ b/src/api/system/authority/index.ts @@ -1,22 +1,29 @@ import axios from 'axios' -import { AuthorityDto, AuthorityVo } from '@/types/modules/system' +import type { AuthorityDto, AuthorityVo } from '@/types/modules/system' +import type { RouteRecordNormalized } from 'vue-router' + +const contentPath = '/system/authority' export function create(authorityDto: AuthorityDto) { - return axios.post('/system/authority', authorityDto) + return axios.post(`${contentPath}`, authorityDto) } export function updateById(authorityDto: AuthorityDto) { - return axios.put('/system/authority', authorityDto) + return axios.put(`${contentPath}`, authorityDto) } export function deleteById(id: number) { - return axios.delete(`/system/authority/${id}`) + return axios.delete(`${contentPath}/${id}`) } export function getById(id: number) { - return axios.get(`/system/authority/${id}`) + return axios.get(`${contentPath}/${id}`) } export function getTreeData() { - return axios.get('/system/authority/tree') + return axios.get(`${contentPath}/tree`) +} + +export function getMenuList() { + return axios.get(`${contentPath}/menu`) } diff --git a/src/api/system/role-authority.ts b/src/api/system/role-authority/index.ts similarity index 47% rename from src/api/system/role-authority.ts rename to src/api/system/role-authority/index.ts index f899cc33ed5a2eb95e7e3768ed0d924cfefb6b6e..7ef8b1e00eafb6d4b0e5ee993dccdef5a8b1046f 100644 --- a/src/api/system/role-authority.ts +++ b/src/api/system/role-authority/index.ts @@ -1,9 +1,11 @@ import axios from 'axios' +const contentPath = '/system/role-authority' + export function getAuthoritiesIdByRoleId(id: number) { - return axios.get(`/system/role-authority/${id}`) + return axios.get(`${contentPath}/${id}`) } export function grantAuthorities(roleId: number, authoritiesId: number[]) { - return axios.post(`/system/role-authority/grant/${roleId}`, authoritiesId) + return axios.post(`${contentPath}/grant/${roleId}`, authoritiesId) } diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts index 34155dfaa321efa92631d87ca3da5ac2ffef79ae..1288dcaa1ebef7794839ef2506b788316034fb97 100644 --- a/src/api/system/role/index.ts +++ b/src/api/system/role/index.ts @@ -1,22 +1,24 @@ import axios from 'axios' -import { RoleDto, RoleVo } from '@/api/system/types' +import type { RoleDto, RoleVo } from '@/types/modules/system' -export function getRolesTree(deep = 3) { - return axios.get(`/system/role/tree/${deep}`) -} - -export function getById(id: number) { - return axios.get(`/system/role/${id}`) -} +const contentPath = '/system/role' export function create(roleDto: RoleDto) { - return axios.post('/system/role/', roleDto) + return axios.post(`${contentPath}`, roleDto) } export function updateById(roleDto: RoleDto) { - return axios.put('/system/role/', roleDto) + return axios.put(`${contentPath}`, roleDto) } export function deleteById(id: number) { - return axios.delete(`/system/role/${id}`) + return axios.delete(`${contentPath}/${id}`) +} + +export function getRolesTree(deep = 3) { + return axios.get(`${contentPath}/tree/${deep}`) +} + +export function getById(id: number) { + return axios.get(`${contentPath}/${id}`) } diff --git a/src/api/system/types.ts b/src/api/system/types.ts deleted file mode 100644 index 131f47c643309a0c4a80ceec46549770e7948969..0000000000000000000000000000000000000000 --- a/src/api/system/types.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { TreeNode } from '@/types/global' - -export interface LoginData { - username: string - password: string -} - -export interface ResToken { - access_token: string, - token_type: string, - refresh_token: string, - scope: string -} - -export interface UserInfo { - id?: number - username?: string - nickname?: string - avatar?: string - phone?: string - email?: string - gender?: number - createTime?: string - updateTime?: string - roles: string[] - authorities: string[] -} - -/** - * VO - */ -export interface RoleVo extends TreeNode{ - name?: string - code?: string - createTime?: string - updateTime?: string -} - -export interface UserVO { - id?: number - username?: string - nickname?: string - gender?: number - phone?: string - email?: string - avatar?: string - roles: RoleVo[] - nonLocked?: boolean - enabled?: boolean - createTime?: string - updateTime?: string -} - -/** - * DTO - */ -export interface UserDto { - id?: number - username?: string - nickname?: string - password?: string - gender?: number - phone?: string - email?: string - avatar?: string - rolesId: number[] - nonLocked?: boolean - enabled?: boolean -} - -export interface RoleDto extends TreeNode{ - name?: string - code?: string -} diff --git a/src/api/system/user/index.ts b/src/api/system/user/index.ts index 38a3a9fe8a6f5b1cc311ff827ca02455267c8c52..3ca3a84c14ee2803144f9e975f8c297931ca183f 100644 --- a/src/api/system/user/index.ts +++ b/src/api/system/user/index.ts @@ -1,56 +1,31 @@ import axios from 'axios' -import type { RouteRecordNormalized } from 'vue-router' -import qs from 'query-string' -import website from '@/config/website' -import { - LoginData, - ResToken, UserDto, +import type { Pagination } from '@/types/global' +import type { + UserDto, UserInfo, UserVO, -} from '@/api/system/types' -import { ResPage } from '@/api/types' +} from '@/types/modules/system' -export function login(data: LoginData) { - const grantType = website?.grantTypes?.password || 'password' - const basicAuth = `Basic ${window.btoa(website.traditionLoginClient)}` - return axios.post('/auth/oauth/token', qs.stringify(data), { - headers: { - Authorization: basicAuth, - }, - params: { - grant_type: grantType, - }, - }) -} +const contentPath = '/system/user' -export function refreshToken(refresh_token: string) { - const grantType = website?.grantTypes?.refresh_token || 'refresh_token' - const basicAuth = `Basic ${window.btoa(website.traditionLoginClient)}` - return axios.post('/auth/oauth/token', { - headers: { - Authorization: basicAuth, - }, - params: { - grant_type: grantType, - refresh_token, - }, - }) +export function create(userDto: UserDto) { + return axios.post(`${contentPath}`, userDto) } -export function logout() { - return axios.post('/api/user/logout') +export function updateById(userDto: UserDto) { + return axios.put(`${contentPath}`, userDto) } -export function getUserInfo() { - return axios.get('/system/user/info') +export function deleteById(id: number) { + return axios.delete(`${contentPath}/${id}`) } -export function getMenuList() { - return axios.get('/system/authority/menu') +export function getById(id: number) { + return axios.get(`${contentPath}/${id}`) } export function listWithPagination(page: number, size: number, params: object) { - return axios.get('/system/user/pagination', { + return axios.get(`${contentPath}/pagination`, { params: { page, size, @@ -59,18 +34,6 @@ export function listWithPagination(page: number, size: number, params: object) { }) } -export function getById(id: number) { - return axios.get(`/system/user/${id}`) -} - -export function deleteById(id: number) { - return axios.delete(`/system/user/${id}`) -} - -export function create(userDto: UserDto) { - return axios.post('/system/user/', userDto) -} - -export function updateById(userDto: UserDto) { - return axios.put('/system/user/', userDto) +export function getUserInfo() { + return axios.get(`${contentPath}/info`) } diff --git a/src/api/types.ts b/src/api/types.ts deleted file mode 100644 index 44837819f4f532ef9c66e3c7b65012b6677f49cf..0000000000000000000000000000000000000000 --- a/src/api/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface Response { - code: number - message: string - data: T - timestamp: number | null -} - -export interface ResPage { - content: [] - pageable: object - totalElements: number - totalPages: number - last: number - number: number - size: number - sort: object - numberOfElements: number - first: boolean - empty: boolean -} diff --git a/src/components/breadcrumb/index.vue b/src/components/breadcrumb/index.vue index 0cf6adf8995d646eb0e9d519e33ed45810d1061b..30f561577b57cf31eef4622df8bfd04c0169dbb6 100644 --- a/src/components/breadcrumb/index.vue +++ b/src/components/breadcrumb/index.vue @@ -4,7 +4,7 @@ - {{ $t(item) }} + {{ item }} diff --git a/src/components/chart/index.vue b/src/components/chart/index.vue index 8ea3f4126205d29e8bcad5744165db1469adc220..81246da1be03b75788cc6f8e8f479d0a27f20aa1 100644 --- a/src/components/chart/index.vue +++ b/src/components/chart/index.vue @@ -10,7 +10,6 @@ diff --git a/src/components/tab-bar/locale/en-US.ts b/src/components/tab-bar/locale/en-US.ts deleted file mode 100644 index 68076c2c81ab6e73df64a971502298232d7a7b6d..0000000000000000000000000000000000000000 --- a/src/components/tab-bar/locale/en-US.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - 'close.current.tab': 'closeCurrentTab', - 'close.left.tabs': 'closeLeftTabs', - 'close.right.tabs': 'closeRightTabs', - 'close.other.tabs': 'closeOtherTabs', - 'close.all.tabs': 'closeAllTabs', -} diff --git a/src/components/tab-bar/locale/zh-CN.ts b/src/components/tab-bar/locale/zh-CN.ts deleted file mode 100644 index cb9bad6937fc8d878630abdee3903026defeedcb..0000000000000000000000000000000000000000 --- a/src/components/tab-bar/locale/zh-CN.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - 'close.current.tab': '关闭当前标签页', - 'close.left.tabs': '关闭左侧标签页', - 'close.right.tabs': '关闭右侧标签页', - 'close.other.tabs': '关闭其它标签页', - 'close.all.tabs': '关闭全部标签页', -} diff --git a/src/components/tab-bar/tab-item.vue b/src/components/tab-bar/tab-item.vue index a3421673ad06f3850462ec857808649862564df5..a82269bc9c75300b4d36b12b4d5300cf932aab1d 100644 --- a/src/components/tab-bar/tab-item.vue +++ b/src/components/tab-bar/tab-item.vue @@ -6,7 +6,7 @@ @click="goto(itemData)" > - {{ $t(itemData.title) }} + {{ itemData.title }} - {{ $t('close.current.tab') }} + 关闭当前标签页 - {{ $t('close.left.tabs') }} + 关闭左侧标签页 - {{ $t('close.right.tabs') }} + 关闭右侧标签页 - {{ $t('close.other.tabs') }} + 关闭其它标签页 - {{ $t('close.all.tabs') }} + 关闭全部标签页 @@ -45,8 +45,7 @@ import { computed, PropType } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useTabBarStore } from '@/store' import type { TagProps } from '@/store/modules/tab-bar/types' -import { DEFAULT_ROUTE_NAME } from '@/router/routes/index' - +import { DEFAULT_ROUTE_NAME } from '@/router/routes' // eslint-disable-next-line no-shadow enum Eaction { current = 'current', diff --git a/src/hooks/locale.ts b/src/hooks/locale.ts deleted file mode 100644 index aafb1f2a0de634b10cc242545e2e7314945ee98c..0000000000000000000000000000000000000000 --- a/src/hooks/locale.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { computed } from 'vue' -import { useI18n } from 'vue-i18n' -import { Message } from '@arco-design/web-vue' - -export default function useLocale() { - const i18 = useI18n() - const currentLocale = computed(() => i18.locale.value) - const changeLocale = (value: string) => { - i18.locale.value = value - localStorage.setItem('arco-locale', value) - Message.success(i18.t('navbar.action.locale')) - } - return { - currentLocale, - changeLocale, - } -} diff --git a/src/hooks/permission.ts b/src/hooks/permission.ts index 1e600c0722cb99cdd79abefa7451aa0106b6d383..7f6650f4315f513a2719130d55d32b93a9d24919 100644 --- a/src/hooks/permission.ts +++ b/src/hooks/permission.ts @@ -12,12 +12,12 @@ export default function usePermission() { || Boolean(route.meta?.roles?.filter(role => userStore.roles?.includes(role)).length) ) }, - findFirstPermissionRoute(_routers: any, role = 'admin') { + findFirstPermissionRoute(_routers: any, _roles: string[]) { const cloneRouters = [..._routers] while (cloneRouters.length) { const firstElement = cloneRouters.shift() if ( - firstElement?.meta?.roles?.find((el: string[]) => el.includes('*') || el.includes(role)) + firstElement?.meta?.roles?.find((role: string) => role === '*' || _roles.includes(role)) ) return { name: firstElement.name } if (firstElement?.children) { cloneRouters.push(...firstElement.children) diff --git a/src/hooks/request.ts b/src/hooks/request.ts index f54500d2baa726aa24fc0cf6aa5005b4e0a089dd..4aef45a8187966156cef93fc18e6380376e2ce96 100644 --- a/src/hooks/request.ts +++ b/src/hooks/request.ts @@ -1,6 +1,6 @@ import { ref, UnwrapRef } from 'vue' import { AxiosResponse } from 'axios' -import { Response } from '@/api/types' +import { Response } from '@/types/global' import useLoading from './loading' // use to fetch list diff --git a/src/hooks/user.ts b/src/hooks/user.ts index 03e46d8eae74bc7fb873e6c38b5e514be79d4911..79875c1c550b9bbb81e2301c4805d47a9c3c1074 100644 --- a/src/hooks/user.ts +++ b/src/hooks/user.ts @@ -7,16 +7,19 @@ export default function useUser() { const router = useRouter() const userStore = useUserStore() const logout = async (logoutTo?: string) => { - await userStore.logout() - const currentRoute = router.currentRoute.value - Message.success('登出成功') - router.push({ - name: logoutTo || 'login', - query: { - ...router.currentRoute.value.query, - redirect: currentRoute.name as string, - }, - }) + try { + await userStore.logout() + Message.success('登出成功') + } finally { + const currentRoute = router.currentRoute.value + await router.push({ + name: logoutTo || 'login', + query: { + ...router.currentRoute.value.query, + redirect: currentRoute.name as string, + }, + }) + } } return { logout, diff --git a/src/locale/common/en-US.ts b/src/locale/common/en-US.ts deleted file mode 100644 index 78c4a8656d1524c0a0e45879418a71a3b62f4d78..0000000000000000000000000000000000000000 --- a/src/locale/common/en-US.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - 'search': 'Search', - 'reset': 'Reset', - 'create': 'Create', -} diff --git a/src/locale/common/zh-CN.ts b/src/locale/common/zh-CN.ts deleted file mode 100644 index e5bb5e7b1554cc8a90233af44c166207aace3d17..0000000000000000000000000000000000000000 --- a/src/locale/common/zh-CN.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - 'search': '搜索', - 'reset': '重置', - 'create': '添加', -} diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts deleted file mode 100644 index b4f60bfcd8562165f38e7d954e917e504d1d0bc3..0000000000000000000000000000000000000000 --- a/src/locale/en-US.ts +++ /dev/null @@ -1,37 +0,0 @@ -import localeMessageBox from '@/components/message-box/locale/en-US' -import localeTabBar from '@/components/tab-bar/locale/en-US' -import localeLogin from '@/views/login/locale/en-US' - -import localeWorkplace from '@/views/dashboard/workplace/locale/en-US' -import localeUserSystem from '@/views/system/user/locale/en-US' -import localeRoleSystem from '@/views/system/role/locale/en-US' -import localeAuthoritySystem from '@/views/system/authority/locale/en-US' - -import localeCommon from './common/en-US' -import localeSettings from './en-US/settings' - -export default { - 'menu.dashboard': 'Dashboard', - 'menu.monitor': 'Monitor', - 'menu.list': 'List', - 'menu.result': 'Result', - 'menu.exception': 'Exception', - 'menu.form': 'Form', - 'menu.profile': 'Profile', - 'menu.visualization': 'Data Visualization', - 'menu.user': 'User Center', - 'menu.arcoWebsite': 'Arco Design', - 'menu.faq': 'FAQ', - 'navbar.docs': 'Docs', - 'navbar.action.locale': 'Switch to English', - ...localeTabBar, - ...localeSettings, - ...localeMessageBox, - ...localeLogin, - ...localeWorkplace, - ...localeUserSystem, - ...localeRoleSystem, - ...localeAuthoritySystem, - ...localeCommon, - 'menu.system': 'System', -} diff --git a/src/locale/en-US/settings.ts b/src/locale/en-US/settings.ts deleted file mode 100644 index 7f8b369e0f537a5106dc7669b842dead412b5347..0000000000000000000000000000000000000000 --- a/src/locale/en-US/settings.ts +++ /dev/null @@ -1,28 +0,0 @@ -export default { - 'settings.title': 'Settings', - 'settings.themeColor': 'Theme Color', - 'settings.content': 'Content Setting', - 'settings.search': 'Search', - 'settings.language': 'Language', - 'settings.navbar': 'Navbar', - 'settings.menuWidth': 'Menu Width (px)', - 'settings.navbar.theme.toLight': 'Click to use light mode', - 'settings.navbar.theme.toDark': 'Click to use dark mode', - 'settings.navbar.screen.toFull': 'Click to switch to full screen mode', - 'settings.navbar.screen.toExit': 'Click to exit the full screen mode', - 'settings.navbar.alerts': 'alerts', - 'settings.menu': 'Menu', - 'settings.tabBar': 'Tab Bar', - 'settings.footer': 'Footer', - 'settings.otherSettings': 'Other Settings', - 'settings.colorWeak': 'Color Weak', - // eslint-disable-next-line max-len - 'settings.alertContent': 'After the configuration is only temporarily effective, if you want to really affect the project, click the "Copy Settings" button below and replace the configuration in settings.json.', - 'settings.copySettings': 'Copy Settings', - 'settings.copySettings.message': - 'Copy succeeded, please paste to file src/settings.json.', - 'settings.close': 'Close', - 'settings.color.tooltip': - '10 gradient colors generated according to the theme color', - 'settings.menuFromServer': 'Menu From Server', -} diff --git a/src/locale/index.ts b/src/locale/index.ts deleted file mode 100644 index 8781a55c5f145b92f3fe0d5fceb82c8e04032ece..0000000000000000000000000000000000000000 --- a/src/locale/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createI18n } from 'vue-i18n' -import en from './en-US' -import cn from './zh-CN' - -export const LOCALE_OPTIONS = [ - { label: '中文', value: 'zh-CN' }, - { label: 'English', value: 'en-US' }, -] -const defaultLocale = localStorage.getItem('arco-locale') || 'zh-CN' - -const i18n = createI18n({ - locale: defaultLocale, - fallbackLocale: 'en-US', - allowComposition: true, - messages: { - 'en-US': en, - 'zh-CN': cn, - }, -}) - -export default i18n diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts deleted file mode 100644 index 0ab465a4ddb0cfa26ae2a9510ce778541c345c73..0000000000000000000000000000000000000000 --- a/src/locale/zh-CN.ts +++ /dev/null @@ -1,37 +0,0 @@ -import localeMessageBox from '@/components/message-box/locale/zh-CN' -import localeTabBar from '@/components/tab-bar/locale/zh-CN' -import localeLogin from '@/views/login/locale/zh-CN' - -import localeWorkplace from '@/views/dashboard/workplace/locale/zh-CN' -import localeUserSystem from '@/views/system/user/locale/zh-CN' -import localeRoleSystem from '@/views/system/role/locale/zh-CN' -import localeAuthoritySystem from '@/views/system/authority/locale/zh-CN' - -import localeCommon from './common/zh-CN' -import localeSettings from './zh-CN/settings' - -export default { - 'menu.dashboard': '仪表盘', - 'menu.monitor': '实时监控', - 'menu.list': '列表页', - 'menu.result': '结果页', - 'menu.exception': '异常页', - 'menu.form': '表单页', - 'menu.profile': '详情页', - 'menu.visualization': '数据可视化', - 'menu.user': '个人中心', - 'menu.arcoWebsite': 'Arco Design', - 'menu.faq': '常见问题', - 'navbar.docs': '文档中心', - 'navbar.action.locale': '切换为中文', - ...localeTabBar, - ...localeSettings, - ...localeMessageBox, - ...localeLogin, - ...localeWorkplace, - ...localeUserSystem, - ...localeRoleSystem, - ...localeAuthoritySystem, - ...localeCommon, - 'menu.system': '系统管理', -} diff --git a/src/locale/zh-CN/settings.ts b/src/locale/zh-CN/settings.ts deleted file mode 100644 index af2a7b40d76a16e329bbfdc8f292c1677acecbd6..0000000000000000000000000000000000000000 --- a/src/locale/zh-CN/settings.ts +++ /dev/null @@ -1,28 +0,0 @@ -export default { - 'settings.title': '页面配置', - 'settings.themeColor': '主题色', - 'settings.content': '内容区域', - 'settings.search': '搜索', - 'settings.language': '语言', - 'settings.navbar': '导航栏', - 'settings.menuWidth': '菜单宽度 (px)', - 'settings.navbar.theme.toLight': '点击切换为亮色模式', - 'settings.navbar.theme.toDark': '点击切换为暗黑模式', - 'settings.navbar.screen.toFull': '点击切换全屏模式', - 'settings.navbar.screen.toExit': '点击退出全屏模式', - 'settings.navbar.alerts': '消息通知', - 'settings.menu': '菜单栏', - 'settings.tabBar': '多页签', - 'settings.footer': '底部', - 'settings.otherSettings': '其他设置', - 'settings.colorWeak': '色弱模式', - 'settings.alertContent': - '配置之后仅是临时生效,要想真正作用于项目,点击下方的 "复制配置" 按钮,将配置替换到 settings.json 中即可。', - 'settings.copySettings': '复制配置', - 'settings.copySettings.message': - '复制成功,请粘贴到 src/settings.json 文件中', - 'settings.close': '关闭', - 'settings.color.tooltip': - '根据主题颜色生成的 10 个梯度色(将配置复制到项目中,主题色才能对亮色 / 暗黑模式同时生效)', - 'settings.menuFromServer': '菜单来源于后台', -} diff --git a/src/main.ts b/src/main.ts index 8b1b4012c3d80bf16613e78789aeb391de78868b..f6f211b37953f3f0d74b265fbe6845caf802fa45 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,6 @@ import ArcoVueIcon from '@arco-design/web-vue/es/icon' import globalComponents from '@/components' import router from './router' import store from './store' -import i18n from './locale' import directives from './directives' import './mock' import App from './App.vue' @@ -19,7 +18,6 @@ app.use(ArcoVueIcon) app.use(router) app.use(store) -app.use(i18n) app.use(globalComponents) app.use(directives) diff --git a/src/mock/user.ts b/src/mock/user.ts index 0abfe2f645e8257702846ab24373b1a3477c3489..7d42358e41f87cba818ac85a1b6d2c6374c983bb 100644 --- a/src/mock/user.ts +++ b/src/mock/user.ts @@ -73,7 +73,6 @@ setupMock({ path: '/dashboard', name: 'dashboard', meta: { - locale: 'menu.dashboard', requiresAuth: true, icon: 'icon-dashboard', order: 1, @@ -83,7 +82,6 @@ setupMock({ path: 'workplace', name: 'workplace', meta: { - locale: 'menu.workplace', requiresAuth: true, }, }, @@ -91,7 +89,6 @@ setupMock({ path: 'https://arco.design', name: 'arcoWebsite', meta: { - locale: 'menu.arcoWebsite', requiresAuth: true, }, }, diff --git a/src/router/guard/permission.ts b/src/router/guard/permission.ts index fd56600dd906f2e717aeabb7c8d8dde068afd52d..274137719da151c9b97b4db96a2a67d041dbf601 100644 --- a/src/router/guard/permission.ts +++ b/src/router/guard/permission.ts @@ -44,7 +44,7 @@ export default function setupPermissionGuard(router: Router) { // eslint-disable-next-line no-lonely-if if (permissionsAllow) next() else { - const destination = Permission.findFirstPermissionRoute(appRoutes, userStore.role) + const destination = Permission.findFirstPermissionRoute(appRoutes, userStore.roles) || NOT_FOUND next(destination) } diff --git a/src/router/guard/userLoginInfo.ts b/src/router/guard/userLoginInfo.ts index 0d7526bc07c0c66e35c4bdc94f4564e9cec6302c..91480fde5e147274c4ab22cad46498f7a3f88176 100644 --- a/src/router/guard/userLoginInfo.ts +++ b/src/router/guard/userLoginInfo.ts @@ -9,7 +9,7 @@ export default function setupUserLoginInfoGuard(router: Router) { NProgress.start() const userStore = useUserStore() if (isLogin()) { - if (userStore.role) { + if (userStore.roles.length) { next() } else { try { diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts index 9b4a904aa1755e897980534d7c7b0b90f275f684..9025cedebaf377c618ef4c7aa294414487c6ca9f 100644 --- a/src/router/routes/index.ts +++ b/src/router/routes/index.ts @@ -21,7 +21,7 @@ export const appRoutes: RouteRecordNormalized[] = formatModules(modules, []) export const DEFAULT_ROUTE_NAME = 'workplace' export const DEFAULT_ROUTE = { - title: 'menu.dashboard.workplace', + title: '工作台', name: DEFAULT_ROUTE_NAME, fullPath: '/dashboard/workplace', } diff --git a/src/router/routes/modules/dashboard.ts b/src/router/routes/modules/dashboard.ts index 56199664c49f21fea7b64d3fb7d8f8e7e3d3ebdd..a1939cb34b664c0ca3b476ff84cda6bfbeec98ad 100644 --- a/src/router/routes/modules/dashboard.ts +++ b/src/router/routes/modules/dashboard.ts @@ -6,7 +6,6 @@ const DASHBOARD: AppRouteRecordRaw = { name: 'dashboard', component: DEFAULT_LAYOUT, meta: { - locale: 'menu.dashboard', requiresAuth: true, icon: 'icon-dashboard', order: 0, @@ -17,7 +16,6 @@ const DASHBOARD: AppRouteRecordRaw = { name: 'workplace', component: () => import('@/views/dashboard/workplace/index.vue'), meta: { - locale: 'menu.dashboard.workplace', requiresAuth: true, }, }, diff --git a/src/router/routes/modules/system.ts b/src/router/routes/modules/system.ts index 9bea66ffe953e2913e851303853e8426b03c2d0c..e1d2027f4f74cd0b91a0c4d1614f632e0949b485 100644 --- a/src/router/routes/modules/system.ts +++ b/src/router/routes/modules/system.ts @@ -6,7 +6,6 @@ const SYSTEM: AppRouteRecordRaw = { name: 'system', component: DEFAULT_LAYOUT, meta: { - locale: 'menu.system', requiresAuth: true, }, children: [ @@ -15,7 +14,6 @@ const SYSTEM: AppRouteRecordRaw = { name: 'user', component: () => import('@/views/system/user/index.vue'), meta: { - locale: 'menu.system.user', requiresAuth: true, }, }, @@ -24,7 +22,6 @@ const SYSTEM: AppRouteRecordRaw = { name: 'role', component: () => import('@/views/system/role/index.vue'), meta: { - locale: 'menu.system.role', requiresAuth: true, }, }, @@ -33,7 +30,6 @@ const SYSTEM: AppRouteRecordRaw = { name: 'authority', component: () => import('@/views/system/authority/index.vue'), meta: { - locale: 'menu.system.authority', requiresAuth: true, }, }, diff --git a/src/store/modules/app/index.ts b/src/store/modules/app/index.ts index 6651067a294bf3cfd473b5e0f4041b451c3619e4..2d0ca723439912b30c2cf00bce0338148cdb498a 100644 --- a/src/store/modules/app/index.ts +++ b/src/store/modules/app/index.ts @@ -3,7 +3,7 @@ import { Notification } from '@arco-design/web-vue' import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface' import type { RouteRecordNormalized } from 'vue-router' import defaultSettings from '@/config/settings.json' -import { getMenuList } from '@/api/system/user' +import { getMenuList } from '@/api/system/authority' import { AppState } from './types' const useAppStore = defineStore('app', { diff --git a/src/store/modules/tab-bar/index.ts b/src/store/modules/tab-bar/index.ts index e6a9fdc85cf89586c2291d90efc41344995c3c65..2fd981ffd7cb77b21ab65f55bc1ce26abf962081 100644 --- a/src/store/modules/tab-bar/index.ts +++ b/src/store/modules/tab-bar/index.ts @@ -8,7 +8,7 @@ const formatTag = (route: RouteLocationNormalized): TagProps => { name, meta, fullPath, query, } = route return { - title: meta.locale || '', + title: meta.locale || String(name) || '', name: String(name), fullPath, query, diff --git a/src/store/modules/user/index.ts b/src/store/modules/user/index.ts index 6e0aedd98a5ad5a14fff17b9da0d46a5b8500db2..3f54570431408f03515cf1bc7d43bbe963e12806 100644 --- a/src/store/modules/user/index.ts +++ b/src/store/modules/user/index.ts @@ -1,12 +1,9 @@ import { defineStore } from 'pinia' import { setToken, clearToken } from '@/utils/auth' import { removeRouteListener } from '@/utils/route-listener' -import { LoginData, UserInfo } from '@/api/system/types' -import { - login as userLogin, - logout as userLogout, - getUserInfo, -} from '@/api/system/user' +import { LoginData, UserInfo } from '@/types/modules/system' +import { getUserInfo } from '@/api/system/user' +import { login as userLogin, logout as logoutApi } from '@/api/auth' import useAppStore from '../app' const useUserStore = defineStore('user', { @@ -67,7 +64,7 @@ const useUserStore = defineStore('user', { // Logout async logout() { try { - await userLogout() + await logoutApi() } finally { this.logoutCallBack() } diff --git a/src/types/global.ts b/src/types/global.ts index bb0f14470917d83af6d398ec3b2cd274bead6281..9c8b2653ebf800984c0b827fec322a14c65e8e0a 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -25,12 +25,6 @@ export interface PostData { url: string; } -export interface Pagination { - current: number; - pageSize: number; - total?: number; -} - export type TimeRanger = [string, string]; export interface GeneralChart { @@ -38,6 +32,27 @@ export interface GeneralChart { data: Array<{ name: string; value: number[] }>; } +export interface Response { + code: number + message: string + data: T + timestamp?: number +} + +export interface Pagination { + content: [] + pageable: object + totalElements: number + totalPages: number + last: number + number: number + size: number + sort: object + numberOfElements: number + first: boolean + empty: boolean +} + /** * 树形数据节点 */ diff --git a/src/types/modules/system.ts b/src/types/modules/system.ts index 2db19c11aece465636a793004caaef7c54929fa3..8b912103e50608d4eff231721b37abb483d65970 100644 --- a/src/types/modules/system.ts +++ b/src/types/modules/system.ts @@ -1,12 +1,70 @@ import { TreeNode } from '@/types/global' -export interface AuthorityVo extends TreeNode { +export interface LoginData { + username: string + password: string +} + +export interface ResToken { + access_token: string, + token_type: string, + refresh_token: string, + scope: string +} + +export interface UserInfo { + id?: number + username?: string + nickname?: string + avatar?: string + phone?: string + email?: string + gender?: number + createTime?: string + updateTime?: string + roles: string[] + authorities: string[] +} + +export interface RoleVo extends TreeNode { + name?: string + code?: string + createTime?: string + updateTime?: string +} + +export interface UserVO { + id?: number + username?: string + nickname?: string + gender?: number + phone?: string + email?: string + avatar?: string + roles: RoleVo[] + nonLocked?: boolean + enabled?: boolean + createTime?: string + updateTime?: string +} + +export interface UserDto { + id?: number + username?: string + nickname?: string + password?: string + gender?: number + phone?: string + email?: string + avatar?: string + rolesId: number[] + nonLocked?: boolean + enabled?: boolean +} + +export interface RoleDto extends TreeNode { name?: string code?: string - icon?: string - type?: number - path?: string - meta?: string } export interface Meta { @@ -17,7 +75,16 @@ export interface Meta { order?: number } -export interface AuthorityDto extends TreeNode{ +export interface AuthorityVo extends TreeNode { + name?: string + code?: string + icon?: string + type?: number + path?: string + meta?: Meta +} + +export interface AuthorityDto extends TreeNode { id?: number name?: string code?: string diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 132aeda0595282cf497555a3d6e9118c0182f2b8..4d720c2ed7ac99dfe27e4c91d668b21cffab86fc 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,4 +1,4 @@ -import { ResToken } from '@/api/system/types' +import { ResToken } from '@/types/modules/system' const TOKEN_KEY = 'token' diff --git a/src/views/dashboard/workplace/components/announcement.vue b/src/views/dashboard/workplace/components/announcement.vue index 3d96db3e2a871fd0e6b1151d9a27cd6bd043c200..5c18c1c222db4d2672d20f827203b51bd32dfe81 100644 --- a/src/views/dashboard/workplace/components/announcement.vue +++ b/src/views/dashboard/workplace/components/announcement.vue @@ -1,12 +1,12 @@ diff --git a/src/views/system/user/locale/en-US.ts b/src/views/system/user/locale/en-US.ts deleted file mode 100644 index cd66244f5bfe075a8ebc34d1dc30d97216cbe32c..0000000000000000000000000000000000000000 --- a/src/views/system/user/locale/en-US.ts +++ /dev/null @@ -1,21 +0,0 @@ -export default { - 'menu.system.user': 'User System', - 'userTable.form.label.id': 'number', - 'userTable.form.label.username': 'username', - 'userTable.form.label.phone': 'phone', - 'userTable.form.label.gender': 'gender', - 'userTable.form.placeholder.id': 'Please enter user number', - 'userTable.form.placeholder.username': 'Please enter username', - 'userTable.form.placeholder.phone': 'Please enter user phone', - 'userTable.form.placeholder.gender': 'Please enter user gender', - 'all': 'All', - 'male': 'male', - 'female': 'female', - 'userTable.operation.create': 'Create', - 'userTable.operation.import': 'Import', - 'userTable.operation.download': 'Download', - 'userTable.columns.operations': 'Operations', - 'userTable.columns.operations.info': 'Info', - 'userTable.columns.operations.edit': 'Edit', - 'userTable.columns.operations.delete': 'Delete', -} diff --git a/src/views/system/user/locale/zh-CN.ts b/src/views/system/user/locale/zh-CN.ts deleted file mode 100644 index 0f86e03ba8dd7dd159b24e48399ee43ff75320c2..0000000000000000000000000000000000000000 --- a/src/views/system/user/locale/zh-CN.ts +++ /dev/null @@ -1,21 +0,0 @@ -export default { - 'menu.system.user': '用户管理', - 'userTable.form.label.id': '编号', - 'userTable.form.label.username': '用户名', - 'userTable.form.label.phone': '手机号', - 'userTable.form.label.gender': '性别', - 'userTable.form.placeholder.id': '请输入用户编号', - 'userTable.form.placeholder.username': '请输入用户名', - 'userTable.form.placeholder.phone': '请输入用户手机号', - 'userTable.form.placeholder.gender': '请输入用户性别', - 'all': '全部', - 'male': '男', - 'female': '女', - 'userTable.operation.create': '新建', - 'userTable.operation.import': '批量导入', - 'userTable.operation.download': '下载', - 'userTable.columns.operations': '操作', - 'userTable.columns.operations.info': '预览', - 'userTable.columns.operations.edit': '编辑', - 'userTable.columns.operations.delete': '删除', -}