create-young-proj 0.10.1 → 0.10.2
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/README.md +6 -0
- package/package.json +1 -1
- package/template-nuxt-admin/components/TopUser.vue +4 -4
- package/template-nuxt-admin/components/YoungChangePassword.vue +5 -5
- package/template-nuxt-admin/components/layout/SideBar.vue +2 -1
- package/template-nuxt-admin/composables/api.ts +4 -19
- package/template-nuxt-admin/composables/user.ts +21 -3
- package/template-nuxt-admin/middleware/auth.global.ts +11 -4
- package/template-nuxt-admin/package.json +1 -1
- package/template-nuxt-admin/pages/login.vue +4 -2
- package/template-nuxt-admin/utils/tool.ts +46 -70
package/README.md
CHANGED
package/package.json
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-07-21 16:31:41
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-09-08 10:35:46
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<script lang="ts" setup>
|
8
|
-
const
|
8
|
+
const user = useUserStore()
|
9
|
+
const { avatar, nick } = storeToRefs(user)
|
9
10
|
|
10
11
|
function loginOut() {
|
11
12
|
showDialog({
|
@@ -13,8 +14,7 @@ function loginOut() {
|
|
13
14
|
message: '确认退出登录?',
|
14
15
|
showCancelButton: true,
|
15
16
|
}).then(() => {
|
16
|
-
|
17
|
-
cookie.value = undefined
|
17
|
+
user.removeToken()
|
18
18
|
navigateTo(`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`)
|
19
19
|
}).catch(() => null)
|
20
20
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-07-24 14:21:55
|
4
|
-
* @LastEditTime: 2023-08
|
4
|
+
* @LastEditTime: 2023-09-08 10:34:56
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<script lang="ts" setup>
|
@@ -33,7 +33,7 @@ const form = reactive<LoginForm>({
|
|
33
33
|
password: '',
|
34
34
|
})
|
35
35
|
|
36
|
-
const
|
36
|
+
const user = useUserStore()
|
37
37
|
|
38
38
|
const formRef = ref<FormInstance>()
|
39
39
|
function sure() {
|
@@ -41,11 +41,11 @@ function sure() {
|
|
41
41
|
if (valid) {
|
42
42
|
await apis.post.changePassword(form)
|
43
43
|
hide()
|
44
|
-
|
44
|
+
showNotify({
|
45
45
|
message: '密码修改成功,请重新登录',
|
46
|
+
type: 'success',
|
46
47
|
})
|
47
|
-
|
48
|
-
cookie.value = undefined
|
48
|
+
user.removeToken()
|
49
49
|
const redirect = location.pathname === '/login' ? '/' : encodeURIComponent(location.href.replace(location.origin, ''))
|
50
50
|
navigateTo(`/login?redirect=${redirect}`)
|
51
51
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-07-21 12:25:23
|
4
|
-
* @LastEditTime: 2023-09-
|
4
|
+
* @LastEditTime: 2023-09-08 09:11:37
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<script lang="ts" setup>
|
@@ -68,6 +68,7 @@ const { isCollapse, nav_arr } = storeToRefs(useNavStore())
|
|
68
68
|
|
69
69
|
:deep(.el-scrollbar__wrap) {
|
70
70
|
overflow-x: hidden;
|
71
|
+
height: calc(100vh - $base-nav-bar-height);
|
71
72
|
|
72
73
|
.el-menu {
|
73
74
|
border: 0;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-06-20 17:14:58
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-09-08 10:09:03
|
5
5
|
* @Description:
|
6
6
|
*/
|
7
7
|
import { useHttp } from '@bluesyoung/http'
|
@@ -29,25 +29,10 @@ const http = useHttp<{
|
|
29
29
|
},
|
30
30
|
fail: (err: any) => {
|
31
31
|
console.log('🚀 ~ file: api.ts:28 ~ err:', err)
|
32
|
-
const
|
32
|
+
const user = useUserStore()
|
33
33
|
if (err?.response?.status === 401) {
|
34
|
-
|
35
|
-
|
36
|
-
message: '未登录或登录过期,请登录后再继续!',
|
37
|
-
showCancelButton: true,
|
38
|
-
})
|
39
|
-
.then(() => {
|
40
|
-
cookie.value && (cookie.value.uuid = '')
|
41
|
-
navigateTo(
|
42
|
-
`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`,
|
43
|
-
)
|
44
|
-
})
|
45
|
-
.catch(() => {
|
46
|
-
navigateTo({
|
47
|
-
path: '/',
|
48
|
-
replace: true,
|
49
|
-
})
|
50
|
-
})
|
34
|
+
user.removeToken()
|
35
|
+
checkLogin(true)
|
51
36
|
|
52
37
|
throw err
|
53
38
|
}
|
@@ -1,18 +1,34 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-06-21 12:03:42
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-09-08 10:33:28
|
5
5
|
* @Description:
|
6
6
|
*/
|
7
7
|
export const useUserStore = defineStore('useUserStore', () => {
|
8
8
|
const cookie = useLocalStorage<UserLoginRes>('token', {} as UserLoginRes)
|
9
9
|
|
10
|
-
const hasLogin = computed(() => !!cookie.value?.uuid)
|
11
10
|
const avatar = computed(() => cookie.value?.headimgurl)
|
12
11
|
const nick = computed(() => cookie.value?.nickname)
|
13
|
-
const token = computed(() =>
|
12
|
+
const token = computed(() => {
|
13
|
+
if (!validateToken())
|
14
|
+
removeToken()
|
15
|
+
|
16
|
+
return cookie.value?.token
|
17
|
+
})
|
18
|
+
const hasLogin = computed(() => !!token.value)
|
14
19
|
|
15
20
|
const SaveFlag = useLocalStorage('n天免登', true)
|
21
|
+
const Exptime = useLocalStorage('token过期时间', 0)
|
22
|
+
|
23
|
+
function validateToken() {
|
24
|
+
const now = Date.now()
|
25
|
+
const exp = Exptime.value
|
26
|
+
return now < exp
|
27
|
+
}
|
28
|
+
|
29
|
+
function removeToken() {
|
30
|
+
cookie.value = undefined
|
31
|
+
}
|
16
32
|
|
17
33
|
return {
|
18
34
|
cookie,
|
@@ -21,6 +37,8 @@ export const useUserStore = defineStore('useUserStore', () => {
|
|
21
37
|
nick,
|
22
38
|
token,
|
23
39
|
SaveFlag,
|
40
|
+
Exptime,
|
41
|
+
removeToken,
|
24
42
|
}
|
25
43
|
})
|
26
44
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-07-21 10:02:19
|
4
|
-
* @LastEditTime: 2023-08
|
4
|
+
* @LastEditTime: 2023-09-08 10:10:28
|
5
5
|
* @Description:
|
6
6
|
*/
|
7
7
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
@@ -30,12 +30,19 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
30
30
|
|
31
31
|
if (!hasLogin.value && to.path !== '/login') {
|
32
32
|
// 页面需要登录,但是未登录
|
33
|
-
|
34
|
-
|
33
|
+
showNotify({
|
34
|
+
type: 'danger',
|
35
|
+
message: '未登录或登录过期,请重新登录',
|
36
|
+
})
|
37
|
+
return navigateTo(`/login?redirect=${encodeURIComponent(to.fullPath)}`, {
|
38
|
+
replace: true,
|
39
|
+
})
|
35
40
|
}
|
36
41
|
else if (hasLogin.value && to.path === '/login') {
|
37
42
|
// 已登录进入登录页
|
38
|
-
return navigateTo('/'
|
43
|
+
return navigateTo('/', {
|
44
|
+
replace: true,
|
45
|
+
})
|
39
46
|
}
|
40
47
|
else {
|
41
48
|
nav_arr.value.length === 0 && (await generateNavData())
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-07-21 10:03:11
|
4
|
-
* @LastEditTime: 2023-08
|
4
|
+
* @LastEditTime: 2023-09-08 10:03:40
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<script lang="ts" setup>
|
@@ -24,7 +24,7 @@ const {
|
|
24
24
|
NUXT_PUBLIC_CURRENT_VERSION: Version,
|
25
25
|
} = window.__YOUNG_ENV__
|
26
26
|
|
27
|
-
const { SaveFlag, hasLogin, cookie } = storeToRefs(useUserStore())
|
27
|
+
const { SaveFlag, hasLogin, cookie, Exptime } = storeToRefs(useUserStore())
|
28
28
|
|
29
29
|
const loginType = ref<'account' | 'code'>('account')
|
30
30
|
|
@@ -46,6 +46,8 @@ function loginHandler() {
|
|
46
46
|
const data = await apis.post.login(form)
|
47
47
|
if (data) {
|
48
48
|
cookie.value = data
|
49
|
+
// 三天后过期
|
50
|
+
Exptime.value = Date.now() + 1000 * 60 * 60 * 24 * 3
|
49
51
|
height.value > width.value && enter()
|
50
52
|
showSuccessToast('登录成功!')
|
51
53
|
navigateTo('/')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-05-28 16:01:24
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-09-08 10:12:37
|
5
5
|
* @Description:
|
6
6
|
*/
|
7
7
|
import { randomId } from '@bluesyoung/utils'
|
@@ -55,16 +55,6 @@ export const WindowSize = reactive({
|
|
55
55
|
'2xl': useMediaQuery('(min-width: 1536px)'),
|
56
56
|
})
|
57
57
|
|
58
|
-
/**
|
59
|
-
* 分页是否超过一页
|
60
|
-
*/
|
61
|
-
export function moreThanOnePage(query: {
|
62
|
-
total: number
|
63
|
-
limit: number
|
64
|
-
}) {
|
65
|
-
return query.total > query.limit
|
66
|
-
}
|
67
|
-
|
68
58
|
/**
|
69
59
|
* 当前浏览器是否支持下载
|
70
60
|
*/
|
@@ -81,23 +71,16 @@ export function checkLogin(force = true) {
|
|
81
71
|
const { hasLogin } = storeToRefs(useUserStore())
|
82
72
|
|
83
73
|
if (!hasLogin.value) {
|
84
|
-
force
|
85
|
-
|
86
|
-
|
87
|
-
message: '
|
88
|
-
showCancelButton: true,
|
74
|
+
if (force) {
|
75
|
+
showNotify({
|
76
|
+
type: 'danger',
|
77
|
+
message: '未登录或登录过期,请登录后再试',
|
89
78
|
})
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
.catch(() => {
|
96
|
-
navigateTo({
|
97
|
-
path: '/',
|
98
|
-
replace: true,
|
99
|
-
})
|
100
|
-
})
|
79
|
+
|
80
|
+
navigateTo(`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`, {
|
81
|
+
replace: true,
|
82
|
+
})
|
83
|
+
}
|
101
84
|
return false
|
102
85
|
}
|
103
86
|
else {
|
@@ -122,61 +105,54 @@ export function useScrollOver(distance = 40) {
|
|
122
105
|
*/
|
123
106
|
export async function generateNavData() {
|
124
107
|
const { hasLogin } = storeToRefs(useUserStore())
|
125
|
-
if (
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
return navigateTo('/login')
|
132
|
-
}
|
133
|
-
|
134
|
-
// 清除没有子元素的children
|
135
|
-
const clearChildren = (arr: NavArrItem[]) => {
|
136
|
-
for (const item of arr) {
|
137
|
-
if (
|
138
|
-
item?.children?.length === 0
|
108
|
+
if (checkLogin(true)) {
|
109
|
+
// 清除没有子元素的children
|
110
|
+
const clearChildren = (arr: NavArrItem[]) => {
|
111
|
+
for (const item of arr) {
|
112
|
+
if (
|
113
|
+
item?.children?.length === 0
|
139
114
|
|| item.children?.filter(n => +n.visible === 1).length === 0
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
115
|
+
)
|
116
|
+
delete item.children
|
117
|
+
else if (item.children)
|
118
|
+
clearChildren(item.children)
|
119
|
+
}
|
120
|
+
return arr
|
144
121
|
}
|
145
|
-
return arr
|
146
|
-
}
|
147
122
|
|
148
|
-
|
123
|
+
const { nav_arr, flat_nav_arr, auth_routes } = storeToRefs(useNavStore())
|
149
124
|
|
150
|
-
|
151
|
-
|
125
|
+
const tree = await apis.get.getUserMenuTree()
|
126
|
+
const menu = Object.values(tree)
|
152
127
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
}
|
159
|
-
for (const item of arr) {
|
160
|
-
if (item.component) {
|
161
|
-
role_route.push(item.component);
|
162
|
-
+item.visible === 1 && flat_nav_arr.value.push(item)
|
128
|
+
let role_route: string[] = []
|
129
|
+
const generateRoleRoute = (arr: NavArrItem[], num?: number): string[] => {
|
130
|
+
if (num === 1) {
|
131
|
+
role_route = []
|
132
|
+
flat_nav_arr.value = []
|
163
133
|
}
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
134
|
+
for (const item of arr) {
|
135
|
+
if (item.component) {
|
136
|
+
role_route.push(item.component);
|
137
|
+
+item.visible === 1 && flat_nav_arr.value.push(item)
|
138
|
+
}
|
139
|
+
// 子节点递归遍历
|
140
|
+
if (Array.isArray(item.children) && item.children.length > 0) {
|
141
|
+
const part = JSON.parse(JSON.stringify(item.children))
|
142
|
+
// 尾递归优化
|
143
|
+
generateRoleRoute(part)
|
144
|
+
}
|
169
145
|
}
|
146
|
+
return role_route
|
170
147
|
}
|
171
|
-
return role_route
|
172
|
-
}
|
173
148
|
|
174
|
-
|
149
|
+
auth_routes.value = generateRoleRoute(menu, 1)
|
175
150
|
|
176
|
-
|
151
|
+
/**
|
177
152
|
* 最终导航数组
|
178
153
|
*/
|
179
|
-
|
154
|
+
nav_arr.value = clearChildren(menu.filter(item => +item.visible === 1))
|
155
|
+
}
|
180
156
|
}
|
181
157
|
|
182
158
|
/**
|