xto-fronted 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.development +7 -7
- package/.env.production +7 -7
- package/dist/assets/403-AFBQifUI.js +1 -0
- package/dist/assets/403-BHEXXbt2.css +1 -0
- package/dist/assets/404-Ct_A1n7S.css +1 -0
- package/dist/assets/404-WFvpcD2_.js +1 -0
- package/dist/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
- package/dist/assets/index-1juADvYN.js +2 -0
- package/dist/assets/index-4-QoJAgA.css +1 -0
- package/dist/assets/index-B-sX4Ru0.js +1 -0
- package/dist/assets/index-BHwEwbkp.js +1 -0
- package/dist/assets/index-BMcziU5a.css +1 -0
- package/dist/assets/index-BRR97dc6.js +1 -0
- package/dist/assets/index-BTsRosKu.js +1 -0
- package/dist/assets/index-BZA0ksjx.css +1 -0
- package/dist/assets/index-BpV_8nl0.js +1 -0
- package/dist/assets/index-BvzhR4zp.js +1 -0
- package/dist/assets/index-CUh_s55Z.css +1 -0
- package/dist/assets/index-CVjdnIgR.css +1 -0
- package/dist/assets/index-CYq57-zj.js +1 -0
- package/dist/assets/index-CZAlkDIC.css +1 -0
- package/dist/assets/index-CkL3sVAQ.js +2 -0
- package/dist/assets/index-CtrKVYJb.css +1 -0
- package/dist/assets/index-Cz2P_bsS.js +1 -0
- package/dist/assets/index-D9wlAuR_.js +1 -0
- package/dist/assets/index-DawJb02s.css +1 -0
- package/dist/assets/index-DfFR6NLf.js +1 -0
- package/dist/assets/index-Do3gMkWw.js +2 -0
- package/dist/assets/index-DwVgMO8e.js +1 -0
- package/dist/assets/index-GDP-IkXE.css +1 -0
- package/dist/assets/index-Iaz1ZzPC.js +2 -0
- package/dist/assets/index-PfV8pzQz.css +1 -0
- package/dist/assets/index-Swfu6yvD.css +1 -0
- package/dist/assets/index-Te8_PRgJ.js +1 -0
- package/dist/assets/index-WyZ91RLx.css +1 -0
- package/dist/assets/index-tFYRoFdE.js +1 -0
- package/dist/assets/vendor-42ANG6Sg.js +6 -0
- package/dist/assets/vite-Dw-pgLOX.js +1 -0
- package/dist/assets/vue-vendor-Br-l7wbK.js +29 -0
- package/dist/assets/xto-base-C-IBqjVs.js +1 -0
- package/dist/assets/xto-base-C6eqMPdO.css +1 -0
- package/dist/assets/xto-business--V1F5Gwb.css +1 -0
- package/dist/assets/xto-core-DZK7Cyg0.js +1 -0
- package/dist/assets/xto-data-BFpiDgJi.js +1 -0
- package/dist/assets/xto-data-CnAQAQH2.css +1 -0
- package/dist/assets/xto-feedback-B7ipsTfz.js +1 -0
- package/dist/assets/xto-feedback-DBwJzoTj.css +1 -0
- package/dist/assets/xto-form-CrsyAjyr.css +1 -0
- package/dist/assets/xto-form-NRjKKNcY.js +1 -0
- package/dist/assets/xto-layout-BqU8RuWL.css +1 -0
- package/dist/assets/xto-navigation-BiSaXPfr.js +1 -0
- package/dist/assets/xto-navigation-C1cnSL2E.css +1 -0
- package/dist/assets/xto-navigation-CBPg4dCc.css +1 -0
- package/dist/assets/xto-navigation-CKabFu9d.js +1 -0
- package/dist/index.html +28 -0
- package/package.json +85 -85
- package/src/api/auth.ts +25 -25
- package/src/api/system.ts +66 -66
- package/src/assets/styles/_dark.scss +524 -406
- package/src/assets/styles/index.scss +8 -0
- package/src/components/Layout/Header.vue +968 -973
- package/src/components/Layout/Sidebar.vue +283 -273
- package/src/components/Layout/TopMenu.vue +186 -0
- package/src/components/Layout/index.vue +60 -3
- package/src/composables/useApp.ts +61 -61
- package/src/composables/useAuth.ts +16 -16
- package/src/directives/permission.ts +27 -27
- package/src/env.d.ts +18 -18
- package/src/index.ts +47 -47
- package/src/router/dynamicRoutes.ts +162 -162
- package/src/router/guards.ts +128 -128
- package/src/router/index.ts +79 -79
- package/src/stores/auth.ts +65 -65
- package/src/stores/menu.ts +48 -48
- package/src/stores/user.ts +50 -50
- package/src/types/api.d.ts +80 -80
- package/src/utils/auth.ts +99 -99
- package/src/utils/config.ts +80 -80
- package/src/utils/permission.ts +32 -32
- package/src/utils/request.ts +124 -124
- package/src/views/login/index.vue +194 -194
- package/vite.config.ts +135 -135
package/src/router/index.ts
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 路由配置
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createRouter, createWebHistory } from 'vue-router'
|
|
6
|
-
import { staticRoutes, errorRoute } from './staticRoutes'
|
|
7
|
-
import { layoutRoute } from './dynamicRoutes'
|
|
8
|
-
import { hasToken } from '@/utils/auth'
|
|
9
|
-
import { getAppId } from '@/utils/config'
|
|
10
|
-
import { useUserStore } from '@/stores/user'
|
|
11
|
-
import { useMenuStore } from '@/stores/menu'
|
|
12
|
-
import { useAppStore } from '@/stores/app'
|
|
13
|
-
import { mockMenuData } from './dynamicRoutes'
|
|
14
|
-
|
|
15
|
-
const router = createRouter({
|
|
16
|
-
history: createWebHistory(),
|
|
17
|
-
routes: [...staticRoutes, layoutRoute, errorRoute],
|
|
18
|
-
scrollBehavior: () => ({ left: 0, top: 0 })
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
// 白名单路由
|
|
22
|
-
const whiteList = ['/login', '/404', '/403']
|
|
23
|
-
|
|
24
|
-
// 路由守卫
|
|
25
|
-
router.beforeEach(async (to, _from, next) => {
|
|
26
|
-
const appStore = useAppStore()
|
|
27
|
-
|
|
28
|
-
// 初始化主题
|
|
29
|
-
appStore.initTheme()
|
|
30
|
-
|
|
31
|
-
// 已登录
|
|
32
|
-
if (hasToken()) {
|
|
33
|
-
if (to.path === '/login') {
|
|
34
|
-
// 已登录,跳转到首页
|
|
35
|
-
next({ path: '/' })
|
|
36
|
-
} else {
|
|
37
|
-
// 设置用户信息(如果未设置)
|
|
38
|
-
const userStore = useUserStore()
|
|
39
|
-
if (!userStore.isLoggedIn) {
|
|
40
|
-
userStore.setUserInfo({
|
|
41
|
-
appId: getAppId(),
|
|
42
|
-
userId: '1',
|
|
43
|
-
userName: '管理员',
|
|
44
|
-
departmentName: '技术部',
|
|
45
|
-
email: 'admin@example.com',
|
|
46
|
-
mobilePhone: '13800138000',
|
|
47
|
-
positionName: '管理员',
|
|
48
|
-
avatar: ''
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
// 设置菜单
|
|
52
|
-
const menuStore = useMenuStore()
|
|
53
|
-
menuStore.setMenuList(mockMenuData)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 添加缓存页面
|
|
57
|
-
if (to.name && to.meta.keepAlive) {
|
|
58
|
-
appStore.addCachedView(to.name as string)
|
|
59
|
-
}
|
|
60
|
-
next()
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
// 未登录
|
|
64
|
-
if (whiteList.includes(to.path)) {
|
|
65
|
-
next()
|
|
66
|
-
} else {
|
|
67
|
-
next('/login')
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
export function resetRouter() {
|
|
73
|
-
const newRouter = createRouter({
|
|
74
|
-
history: createWebHistory(),
|
|
75
|
-
routes: [...staticRoutes, layoutRoute, errorRoute]
|
|
76
|
-
})
|
|
77
|
-
;(router as any).matcher = (newRouter as any).matcher
|
|
78
|
-
}
|
|
79
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 路由配置
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createRouter, createWebHistory } from 'vue-router'
|
|
6
|
+
import { staticRoutes, errorRoute } from './staticRoutes'
|
|
7
|
+
import { layoutRoute } from './dynamicRoutes'
|
|
8
|
+
import { hasToken } from '@/utils/auth'
|
|
9
|
+
import { getAppId } from '@/utils/config'
|
|
10
|
+
import { useUserStore } from '@/stores/user'
|
|
11
|
+
import { useMenuStore } from '@/stores/menu'
|
|
12
|
+
import { useAppStore } from '@/stores/app'
|
|
13
|
+
import { mockMenuData } from './dynamicRoutes'
|
|
14
|
+
|
|
15
|
+
const router = createRouter({
|
|
16
|
+
history: createWebHistory(),
|
|
17
|
+
routes: [...staticRoutes, layoutRoute, errorRoute],
|
|
18
|
+
scrollBehavior: () => ({ left: 0, top: 0 })
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 白名单路由
|
|
22
|
+
const whiteList = ['/login', '/404', '/403']
|
|
23
|
+
|
|
24
|
+
// 路由守卫
|
|
25
|
+
router.beforeEach(async (to, _from, next) => {
|
|
26
|
+
const appStore = useAppStore()
|
|
27
|
+
|
|
28
|
+
// 初始化主题
|
|
29
|
+
appStore.initTheme()
|
|
30
|
+
|
|
31
|
+
// 已登录
|
|
32
|
+
if (hasToken()) {
|
|
33
|
+
if (to.path === '/login') {
|
|
34
|
+
// 已登录,跳转到首页
|
|
35
|
+
next({ path: '/' })
|
|
36
|
+
} else {
|
|
37
|
+
// 设置用户信息(如果未设置)
|
|
38
|
+
const userStore = useUserStore()
|
|
39
|
+
if (!userStore.isLoggedIn) {
|
|
40
|
+
userStore.setUserInfo({
|
|
41
|
+
appId: getAppId(),
|
|
42
|
+
userId: '1',
|
|
43
|
+
userName: '管理员',
|
|
44
|
+
departmentName: '技术部',
|
|
45
|
+
email: 'admin@example.com',
|
|
46
|
+
mobilePhone: '13800138000',
|
|
47
|
+
positionName: '管理员',
|
|
48
|
+
avatar: ''
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// 设置菜单
|
|
52
|
+
const menuStore = useMenuStore()
|
|
53
|
+
menuStore.setMenuList(mockMenuData)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 添加缓存页面
|
|
57
|
+
if (to.name && to.meta.keepAlive) {
|
|
58
|
+
appStore.addCachedView(to.name as string)
|
|
59
|
+
}
|
|
60
|
+
next()
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
// 未登录
|
|
64
|
+
if (whiteList.includes(to.path)) {
|
|
65
|
+
next()
|
|
66
|
+
} else {
|
|
67
|
+
next('/login')
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
export function resetRouter() {
|
|
73
|
+
const newRouter = createRouter({
|
|
74
|
+
history: createWebHistory(),
|
|
75
|
+
routes: [...staticRoutes, layoutRoute, errorRoute]
|
|
76
|
+
})
|
|
77
|
+
;(router as any).matcher = (newRouter as any).matcher
|
|
78
|
+
}
|
|
79
|
+
|
|
80
80
|
export default router
|
package/src/stores/auth.ts
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 认证状态
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { defineStore } from 'pinia'
|
|
6
|
-
import { ref, computed } from 'vue'
|
|
7
|
-
import { getToken, clearToken, setTokenInfo, hasToken, type TokenInfo } from '@/utils/auth'
|
|
8
|
-
|
|
9
|
-
export const useAuthStore = defineStore('auth', () => {
|
|
10
|
-
// 状态
|
|
11
|
-
const token = ref<string | null>(getToken())
|
|
12
|
-
const isLoggedIn = computed(() => hasToken())
|
|
13
|
-
|
|
14
|
-
// 应用配置
|
|
15
|
-
const baseUrl = ref<string>('')
|
|
16
|
-
const appId = ref<string>('')
|
|
17
|
-
const clientId = ref<string>('')
|
|
18
|
-
const loginPath = ref<string>('/login')
|
|
19
|
-
|
|
20
|
-
// 设置 token(参考 tineco-ui)
|
|
21
|
-
const login = (tokenInfo: TokenInfo) => {
|
|
22
|
-
token.value = tokenInfo.access_token
|
|
23
|
-
setTokenInfo(tokenInfo)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// 登出
|
|
27
|
-
const logout = () => {
|
|
28
|
-
token.value = null
|
|
29
|
-
clearToken()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 设置 API 基础路径
|
|
33
|
-
const setBaseUrl = (url: string) => {
|
|
34
|
-
baseUrl.value = url
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 设置应用 ID
|
|
38
|
-
const setAppId = (id: string) => {
|
|
39
|
-
appId.value = id
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// 设置客户端 ID
|
|
43
|
-
const setClientId = (id: string) => {
|
|
44
|
-
clientId.value = id
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// 设置登录页路径
|
|
48
|
-
const setLoginPath = (path: string) => {
|
|
49
|
-
loginPath.value = path
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
token,
|
|
54
|
-
isLoggedIn,
|
|
55
|
-
baseUrl,
|
|
56
|
-
appId,
|
|
57
|
-
clientId,
|
|
58
|
-
loginPath,
|
|
59
|
-
login,
|
|
60
|
-
logout,
|
|
61
|
-
setBaseUrl,
|
|
62
|
-
setAppId,
|
|
63
|
-
setClientId,
|
|
64
|
-
setLoginPath
|
|
65
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 认证状态
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { defineStore } from 'pinia'
|
|
6
|
+
import { ref, computed } from 'vue'
|
|
7
|
+
import { getToken, clearToken, setTokenInfo, hasToken, type TokenInfo } from '@/utils/auth'
|
|
8
|
+
|
|
9
|
+
export const useAuthStore = defineStore('auth', () => {
|
|
10
|
+
// 状态
|
|
11
|
+
const token = ref<string | null>(getToken())
|
|
12
|
+
const isLoggedIn = computed(() => hasToken())
|
|
13
|
+
|
|
14
|
+
// 应用配置
|
|
15
|
+
const baseUrl = ref<string>('')
|
|
16
|
+
const appId = ref<string>('')
|
|
17
|
+
const clientId = ref<string>('')
|
|
18
|
+
const loginPath = ref<string>('/login')
|
|
19
|
+
|
|
20
|
+
// 设置 token(参考 tineco-ui)
|
|
21
|
+
const login = (tokenInfo: TokenInfo) => {
|
|
22
|
+
token.value = tokenInfo.access_token
|
|
23
|
+
setTokenInfo(tokenInfo)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 登出
|
|
27
|
+
const logout = () => {
|
|
28
|
+
token.value = null
|
|
29
|
+
clearToken()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 设置 API 基础路径
|
|
33
|
+
const setBaseUrl = (url: string) => {
|
|
34
|
+
baseUrl.value = url
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 设置应用 ID
|
|
38
|
+
const setAppId = (id: string) => {
|
|
39
|
+
appId.value = id
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 设置客户端 ID
|
|
43
|
+
const setClientId = (id: string) => {
|
|
44
|
+
clientId.value = id
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 设置登录页路径
|
|
48
|
+
const setLoginPath = (path: string) => {
|
|
49
|
+
loginPath.value = path
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
token,
|
|
54
|
+
isLoggedIn,
|
|
55
|
+
baseUrl,
|
|
56
|
+
appId,
|
|
57
|
+
clientId,
|
|
58
|
+
loginPath,
|
|
59
|
+
login,
|
|
60
|
+
logout,
|
|
61
|
+
setBaseUrl,
|
|
62
|
+
setAppId,
|
|
63
|
+
setClientId,
|
|
64
|
+
setLoginPath
|
|
65
|
+
}
|
|
66
66
|
})
|
package/src/stores/menu.ts
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 菜单状态
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { defineStore } from 'pinia'
|
|
6
|
-
import { ref, computed } from 'vue'
|
|
7
|
-
import type { MenuItem } from '@/types/api'
|
|
8
|
-
import { local } from '@/utils/storage'
|
|
9
|
-
|
|
10
|
-
const MENU_LIST_KEY = 'menu_list'
|
|
11
|
-
|
|
12
|
-
// 首页菜单(参考 tineco-ui)
|
|
13
|
-
const indexMenu: MenuItem = {
|
|
14
|
-
menuCode: 'home',
|
|
15
|
-
menuName: '首页',
|
|
16
|
-
menuUrl: '/dashboard',
|
|
17
|
-
icon: 'home',
|
|
18
|
-
closable: false,
|
|
19
|
-
isDefault: false,
|
|
20
|
-
isOut: false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const useMenuStore = defineStore('menu', () => {
|
|
24
|
-
// 状态
|
|
25
|
-
const menuList = ref<MenuItem[]>(local.get<MenuItem[]>(MENU_LIST_KEY) || [])
|
|
26
|
-
|
|
27
|
-
// 计算属性
|
|
28
|
-
const hasMenu = computed(() => menuList.value.length > 0)
|
|
29
|
-
|
|
30
|
-
// 设置菜单
|
|
31
|
-
const setMenuList = (menus: MenuItem[]) => {
|
|
32
|
-
// 添加首页菜单到开头
|
|
33
|
-
menuList.value = [indexMenu, ...menus]
|
|
34
|
-
local.set(MENU_LIST_KEY, menuList.value)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 清除菜单
|
|
38
|
-
const clearMenu = () => {
|
|
39
|
-
menuList.value = []
|
|
40
|
-
local.remove(MENU_LIST_KEY)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
menuList,
|
|
45
|
-
hasMenu,
|
|
46
|
-
setMenuList,
|
|
47
|
-
clearMenu
|
|
48
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 菜单状态
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { defineStore } from 'pinia'
|
|
6
|
+
import { ref, computed } from 'vue'
|
|
7
|
+
import type { MenuItem } from '@/types/api'
|
|
8
|
+
import { local } from '@/utils/storage'
|
|
9
|
+
|
|
10
|
+
const MENU_LIST_KEY = 'menu_list'
|
|
11
|
+
|
|
12
|
+
// 首页菜单(参考 tineco-ui)
|
|
13
|
+
const indexMenu: MenuItem = {
|
|
14
|
+
menuCode: 'home',
|
|
15
|
+
menuName: '首页',
|
|
16
|
+
menuUrl: '/dashboard',
|
|
17
|
+
icon: 'home',
|
|
18
|
+
closable: false,
|
|
19
|
+
isDefault: false,
|
|
20
|
+
isOut: false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const useMenuStore = defineStore('menu', () => {
|
|
24
|
+
// 状态
|
|
25
|
+
const menuList = ref<MenuItem[]>(local.get<MenuItem[]>(MENU_LIST_KEY) || [])
|
|
26
|
+
|
|
27
|
+
// 计算属性
|
|
28
|
+
const hasMenu = computed(() => menuList.value.length > 0)
|
|
29
|
+
|
|
30
|
+
// 设置菜单
|
|
31
|
+
const setMenuList = (menus: MenuItem[]) => {
|
|
32
|
+
// 添加首页菜单到开头
|
|
33
|
+
menuList.value = [indexMenu, ...menus]
|
|
34
|
+
local.set(MENU_LIST_KEY, menuList.value)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 清除菜单
|
|
38
|
+
const clearMenu = () => {
|
|
39
|
+
menuList.value = []
|
|
40
|
+
local.remove(MENU_LIST_KEY)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
menuList,
|
|
45
|
+
hasMenu,
|
|
46
|
+
setMenuList,
|
|
47
|
+
clearMenu
|
|
48
|
+
}
|
|
49
49
|
})
|
package/src/stores/user.ts
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 用户状态
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { defineStore } from 'pinia'
|
|
6
|
-
import { ref, computed } from 'vue'
|
|
7
|
-
import type { UserInfo } from '@/types/api'
|
|
8
|
-
import { local } from '@/utils/storage'
|
|
9
|
-
|
|
10
|
-
const USER_INFO_KEY = 'user_info'
|
|
11
|
-
|
|
12
|
-
export const useUserStore = defineStore('user', () => {
|
|
13
|
-
// 状态
|
|
14
|
-
const userInfo = ref<UserInfo | null>(local.get<UserInfo>(USER_INFO_KEY))
|
|
15
|
-
|
|
16
|
-
// 计算属性
|
|
17
|
-
const isLoggedIn = computed(() => !!userInfo.value)
|
|
18
|
-
const userId = computed(() => userInfo.value?.userId || '')
|
|
19
|
-
const userName = computed(() => userInfo.value?.userName || '')
|
|
20
|
-
const departmentName = computed(() => userInfo.value?.departmentName || '')
|
|
21
|
-
const email = computed(() => userInfo.value?.email || '')
|
|
22
|
-
const mobilePhone = computed(() => userInfo.value?.mobilePhone || '')
|
|
23
|
-
const positionName = computed(() => userInfo.value?.positionName || '')
|
|
24
|
-
const avatar = computed(() => userInfo.value?.avatar || '')
|
|
25
|
-
|
|
26
|
-
// 设置用户信息
|
|
27
|
-
const setUserInfo = (info: UserInfo) => {
|
|
28
|
-
userInfo.value = info
|
|
29
|
-
local.set(USER_INFO_KEY, info)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 清除用户信息
|
|
33
|
-
const clearUserInfo = () => {
|
|
34
|
-
userInfo.value = null
|
|
35
|
-
local.remove(USER_INFO_KEY)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
userInfo,
|
|
40
|
-
isLoggedIn,
|
|
41
|
-
userId,
|
|
42
|
-
userName,
|
|
43
|
-
departmentName,
|
|
44
|
-
email,
|
|
45
|
-
mobilePhone,
|
|
46
|
-
positionName,
|
|
47
|
-
avatar,
|
|
48
|
-
setUserInfo,
|
|
49
|
-
clearUserInfo
|
|
50
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 用户状态
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { defineStore } from 'pinia'
|
|
6
|
+
import { ref, computed } from 'vue'
|
|
7
|
+
import type { UserInfo } from '@/types/api'
|
|
8
|
+
import { local } from '@/utils/storage'
|
|
9
|
+
|
|
10
|
+
const USER_INFO_KEY = 'user_info'
|
|
11
|
+
|
|
12
|
+
export const useUserStore = defineStore('user', () => {
|
|
13
|
+
// 状态
|
|
14
|
+
const userInfo = ref<UserInfo | null>(local.get<UserInfo>(USER_INFO_KEY))
|
|
15
|
+
|
|
16
|
+
// 计算属性
|
|
17
|
+
const isLoggedIn = computed(() => !!userInfo.value)
|
|
18
|
+
const userId = computed(() => userInfo.value?.userId || '')
|
|
19
|
+
const userName = computed(() => userInfo.value?.userName || '')
|
|
20
|
+
const departmentName = computed(() => userInfo.value?.departmentName || '')
|
|
21
|
+
const email = computed(() => userInfo.value?.email || '')
|
|
22
|
+
const mobilePhone = computed(() => userInfo.value?.mobilePhone || '')
|
|
23
|
+
const positionName = computed(() => userInfo.value?.positionName || '')
|
|
24
|
+
const avatar = computed(() => userInfo.value?.avatar || '')
|
|
25
|
+
|
|
26
|
+
// 设置用户信息
|
|
27
|
+
const setUserInfo = (info: UserInfo) => {
|
|
28
|
+
userInfo.value = info
|
|
29
|
+
local.set(USER_INFO_KEY, info)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 清除用户信息
|
|
33
|
+
const clearUserInfo = () => {
|
|
34
|
+
userInfo.value = null
|
|
35
|
+
local.remove(USER_INFO_KEY)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
userInfo,
|
|
40
|
+
isLoggedIn,
|
|
41
|
+
userId,
|
|
42
|
+
userName,
|
|
43
|
+
departmentName,
|
|
44
|
+
email,
|
|
45
|
+
mobilePhone,
|
|
46
|
+
positionName,
|
|
47
|
+
avatar,
|
|
48
|
+
setUserInfo,
|
|
49
|
+
clearUserInfo
|
|
50
|
+
}
|
|
51
51
|
})
|
package/src/types/api.d.ts
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API 通用类型定义
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// 基础响应
|
|
6
|
-
export interface ApiResponse<T = unknown> {
|
|
7
|
-
code: number
|
|
8
|
-
data: T
|
|
9
|
-
message: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 分页请求参数
|
|
13
|
-
export interface PageParams {
|
|
14
|
-
page: number
|
|
15
|
-
pageSize: number
|
|
16
|
-
[key: string]: unknown
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// 分页响应
|
|
20
|
-
export interface PageResponse<T> {
|
|
21
|
-
list: T[]
|
|
22
|
-
total: number
|
|
23
|
-
page: number
|
|
24
|
-
pageSize: number
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 用户信息(参考 tineco-ui)
|
|
28
|
-
export interface UserInfo {
|
|
29
|
-
appId: string
|
|
30
|
-
userId: string
|
|
31
|
-
userName: string
|
|
32
|
-
departmentName?: string
|
|
33
|
-
email?: string
|
|
34
|
-
mobilePhone?: string
|
|
35
|
-
positionName?: string
|
|
36
|
-
avatar?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// 登录请求参数(参考 tineco-ui)
|
|
40
|
-
export interface LoginParams {
|
|
41
|
-
appId: string
|
|
42
|
-
clientId: string
|
|
43
|
-
uid: string
|
|
44
|
-
password: string
|
|
45
|
-
code?: boolean
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 登录响应(参考 tineco-ui)
|
|
49
|
-
export interface LoginResult {
|
|
50
|
-
access_token: string
|
|
51
|
-
token_type: string
|
|
52
|
-
refresh_token: string
|
|
53
|
-
expires_time: number
|
|
54
|
-
refresh_time: number
|
|
55
|
-
code?: string
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 菜单项(参考 tineco-ui)
|
|
59
|
-
export interface MenuItem {
|
|
60
|
-
menuCode: string
|
|
61
|
-
menuName: string
|
|
62
|
-
menuUrl: string
|
|
63
|
-
icon?: string
|
|
64
|
-
closable?: boolean
|
|
65
|
-
isDefault?: boolean
|
|
66
|
-
isOut?: boolean
|
|
67
|
-
type?: number // 1 为按钮,其他为菜单
|
|
68
|
-
children?: MenuItem[]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// 角色信息
|
|
72
|
-
export interface RoleInfo {
|
|
73
|
-
id: number | string
|
|
74
|
-
name: string
|
|
75
|
-
code: string
|
|
76
|
-
description?: string
|
|
77
|
-
status: number
|
|
78
|
-
permissions: string[]
|
|
79
|
-
createTime?: string
|
|
80
|
-
updateTime?: string
|
|
1
|
+
/**
|
|
2
|
+
* API 通用类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// 基础响应
|
|
6
|
+
export interface ApiResponse<T = unknown> {
|
|
7
|
+
code: number
|
|
8
|
+
data: T
|
|
9
|
+
message: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 分页请求参数
|
|
13
|
+
export interface PageParams {
|
|
14
|
+
page: number
|
|
15
|
+
pageSize: number
|
|
16
|
+
[key: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 分页响应
|
|
20
|
+
export interface PageResponse<T> {
|
|
21
|
+
list: T[]
|
|
22
|
+
total: number
|
|
23
|
+
page: number
|
|
24
|
+
pageSize: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 用户信息(参考 tineco-ui)
|
|
28
|
+
export interface UserInfo {
|
|
29
|
+
appId: string
|
|
30
|
+
userId: string
|
|
31
|
+
userName: string
|
|
32
|
+
departmentName?: string
|
|
33
|
+
email?: string
|
|
34
|
+
mobilePhone?: string
|
|
35
|
+
positionName?: string
|
|
36
|
+
avatar?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 登录请求参数(参考 tineco-ui)
|
|
40
|
+
export interface LoginParams {
|
|
41
|
+
appId: string
|
|
42
|
+
clientId: string
|
|
43
|
+
uid: string
|
|
44
|
+
password: string
|
|
45
|
+
code?: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 登录响应(参考 tineco-ui)
|
|
49
|
+
export interface LoginResult {
|
|
50
|
+
access_token: string
|
|
51
|
+
token_type: string
|
|
52
|
+
refresh_token: string
|
|
53
|
+
expires_time: number
|
|
54
|
+
refresh_time: number
|
|
55
|
+
code?: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 菜单项(参考 tineco-ui)
|
|
59
|
+
export interface MenuItem {
|
|
60
|
+
menuCode: string
|
|
61
|
+
menuName: string
|
|
62
|
+
menuUrl: string
|
|
63
|
+
icon?: string
|
|
64
|
+
closable?: boolean
|
|
65
|
+
isDefault?: boolean
|
|
66
|
+
isOut?: boolean
|
|
67
|
+
type?: number // 1 为按钮,其他为菜单
|
|
68
|
+
children?: MenuItem[]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 角色信息
|
|
72
|
+
export interface RoleInfo {
|
|
73
|
+
id: number | string
|
|
74
|
+
name: string
|
|
75
|
+
code: string
|
|
76
|
+
description?: string
|
|
77
|
+
status: number
|
|
78
|
+
permissions: string[]
|
|
79
|
+
createTime?: string
|
|
80
|
+
updateTime?: string
|
|
81
81
|
}
|