create-young-proj 0.10.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. package/README.md +6 -0
  2. package/dist/index.mjs +9 -9
  3. package/package.json +1 -1
  4. package/template-nuxt-admin/README.md +42 -1
  5. package/template-nuxt-admin/components/TopUser.vue +4 -4
  6. package/template-nuxt-admin/components/YoungChangePassword.vue +5 -5
  7. package/template-nuxt-admin/components/layout/Main.vue +2 -2
  8. package/template-nuxt-admin/components/layout/NavBar.vue +11 -2
  9. package/template-nuxt-admin/components/layout/SideBar.vue +7 -2
  10. package/template-nuxt-admin/components/layout/SubMenu.vue +9 -2
  11. package/template-nuxt-admin/components/layout/TabsBar.vue +4 -5
  12. package/template-nuxt-admin/composables/api.ts +20 -21
  13. package/template-nuxt-admin/composables/nav.ts +20 -3
  14. package/template-nuxt-admin/composables/tags.ts +29 -1
  15. package/template-nuxt-admin/composables/user.ts +21 -3
  16. package/template-nuxt-admin/middleware/auth.global.ts +26 -7
  17. package/template-nuxt-admin/nuxt.config.ts +5 -1
  18. package/template-nuxt-admin/package.json +1 -1
  19. package/template-nuxt-admin/pages/home/[id].vue +2 -2
  20. package/template-nuxt-admin/pages/index.vue +2 -7
  21. package/template-nuxt-admin/pages/login.vue +5 -3
  22. package/template-nuxt-admin/pages/system/menuList.vue +0 -1
  23. package/template-nuxt-admin/public/bg.webp +0 -0
  24. package/template-nuxt-admin/public/favicon.svg +2 -0
  25. package/template-nuxt-admin/public/logo.svg +2 -0
  26. package/template-nuxt-admin/server/plugins/env.ts +3 -4
  27. package/template-nuxt-admin/utils/tool.ts +62 -70
  28. package/template-nuxt-admin/public/favicon.ico +0 -0
  29. package/template-vue-admin/.vscode/extensions.json +0 -10
  30. package/template-vue-admin/.vscode/list-add.code-snippets +0 -108
  31. package/template-vue-admin/.vscode/list-export.code-snippets +0 -72
  32. package/template-vue-admin/.vscode/list.code-snippets +0 -61
  33. package/template-vue-admin/.vscode/settings.json +0 -7
  34. package/template-vue-admin/Dockerfile +0 -42
  35. package/template-vue-admin/README.md +0 -75
  36. package/template-vue-admin/_env +0 -8
  37. package/template-vue-admin/_gitignore +0 -30
  38. package/template-vue-admin/boot.mjs +0 -16
  39. package/template-vue-admin/build/custom-plugin.ts +0 -57
  40. package/template-vue-admin/build/index.ts +0 -7
  41. package/template-vue-admin/build/plugins.ts +0 -59
  42. package/template-vue-admin/config/.devrc +0 -2
  43. package/template-vue-admin/config/.onlinerc +0 -2
  44. package/template-vue-admin/config/.testrc +0 -2
  45. package/template-vue-admin/index.html +0 -21
  46. package/template-vue-admin/nitro.config.ts +0 -19
  47. package/template-vue-admin/package.json +0 -51
  48. package/template-vue-admin/plugins/init.ts +0 -31
  49. package/template-vue-admin/public/vite.svg +0 -1
  50. package/template-vue-admin/rome.json +0 -26
  51. package/template-vue-admin/routes/api/[...all].ts +0 -49
  52. package/template-vue-admin/routes/get/env.ts +0 -18
  53. package/template-vue-admin/src/App.vue +0 -14
  54. package/template-vue-admin/src/apis/delete.ts +0 -36
  55. package/template-vue-admin/src/apis/get.ts +0 -83
  56. package/template-vue-admin/src/apis/index.ts +0 -10
  57. package/template-vue-admin/src/apis/patch.ts +0 -78
  58. package/template-vue-admin/src/apis/post.ts +0 -76
  59. package/template-vue-admin/src/assets/img/login_background.jpg +0 -0
  60. package/template-vue-admin/src/auto-components.d.ts +0 -38
  61. package/template-vue-admin/src/auto-imports.d.ts +0 -302
  62. package/template-vue-admin/src/layouts/blank.vue +0 -9
  63. package/template-vue-admin/src/layouts/default/components/Link.vue +0 -23
  64. package/template-vue-admin/src/layouts/default/components/Logo.vue +0 -20
  65. package/template-vue-admin/src/layouts/default/components/Menu.vue +0 -54
  66. package/template-vue-admin/src/layouts/default/components/NavSearch.vue +0 -52
  67. package/template-vue-admin/src/layouts/default/components/ScrollPane.vue +0 -79
  68. package/template-vue-admin/src/layouts/default/components/TagsView.vue +0 -137
  69. package/template-vue-admin/src/layouts/default/components/TopMenu.vue +0 -21
  70. package/template-vue-admin/src/layouts/default/components/UserCenter.vue +0 -50
  71. package/template-vue-admin/src/layouts/default/index.vue +0 -95
  72. package/template-vue-admin/src/main.ts +0 -46
  73. package/template-vue-admin/src/modules/1-router.ts +0 -48
  74. package/template-vue-admin/src/modules/2-pinia.ts +0 -10
  75. package/template-vue-admin/src/modules/3-net.ts +0 -79
  76. package/template-vue-admin/src/modules/4-auth.ts +0 -124
  77. package/template-vue-admin/src/modules/5-checkupdate.ts +0 -38
  78. package/template-vue-admin/src/shims.d.ts +0 -12
  79. package/template-vue-admin/src/stores/index.ts +0 -9
  80. package/template-vue-admin/src/stores/local/index.ts +0 -31
  81. package/template-vue-admin/src/stores/session/index.ts +0 -63
  82. package/template-vue-admin/src/stores/tags.ts +0 -109
  83. package/template-vue-admin/src/typings/global.d.ts +0 -70
  84. package/template-vue-admin/src/typings/index.ts +0 -13
  85. package/template-vue-admin/src/typings/system.d.ts +0 -46
  86. package/template-vue-admin/src/views/403.vue +0 -33
  87. package/template-vue-admin/src/views/[...all_404].vue +0 -557
  88. package/template-vue-admin/src/views/base/login.vue +0 -194
  89. package/template-vue-admin/src/views/dashboard/[name].vue +0 -28
  90. package/template-vue-admin/src/views/index.vue +0 -25
  91. package/template-vue-admin/src/views/system/api.vue +0 -160
  92. package/template-vue-admin/src/views/system/hooks/useRole.ts +0 -286
  93. package/template-vue-admin/src/views/system/menuList.vue +0 -194
  94. package/template-vue-admin/src/views/system/role.vue +0 -131
  95. package/template-vue-admin/src/views/system/user.vue +0 -192
  96. package/template-vue-admin/src/vite-env.d.ts +0 -52
  97. package/template-vue-admin/tsconfig.json +0 -21
  98. package/template-vue-admin/tsconfig.node.json +0 -9
  99. package/template-vue-admin/unocss.config.ts +0 -47
  100. package/template-vue-admin/vite.config.ts +0 -32
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-07-21 17:13:59
4
- * @LastEditTime: 2023-09-06 16:09:39
4
+ * @LastEditTime: 2023-09-18 14:11:18
5
5
  * @Description:
6
6
  */
7
7
  import type { RouteLocationNormalized } from 'vue-router'
@@ -21,6 +21,34 @@ export function useTabReOpen(cbk: Function = () => console.log('this tab page is
21
21
  cbk()
22
22
  }
23
23
 
24
+ // 不缓存
25
+ export function useTabNoCache(cbk: Function = () => console.log('this tab page is no cache')) {
26
+ const tagState = useTagsStore()
27
+ const route = useRoute()
28
+
29
+ tagState.$onAction(({ name, args, after }) => {
30
+ if (name === 'addView') {
31
+ if (args[0].name === route.name)
32
+ after(() => cbk())
33
+ }
34
+ })
35
+
36
+ cbk()
37
+ }
38
+
39
+ // 关闭,用于替换 onUnmounted
40
+ export function useTabClose(cbk: Function = () => console.log('this tab page is close')) {
41
+ const tagState = useTagsStore()
42
+ const route = useRoute()
43
+
44
+ tagState.$onAction(({ name, args, after }) => {
45
+ if (name === 'delView') {
46
+ if (args[0].name === route.name)
47
+ after(() => cbk())
48
+ }
49
+ })
50
+ }
51
+
24
52
  export const useTagsStore = defineStore('useTagsStore', {
25
53
  state: () => {
26
54
  const visitedViews = ref<RouteLocationNormalized[]>([])
@@ -1,18 +1,34 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-06-21 12:03:42
4
- * @LastEditTime: 2023-07-24 14:05:13
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(() => cookie.value?.token)
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-02 14:57:03
4
+ * @LastEditTime: 2023-09-13 09:45:34
5
5
  * @Description:
6
6
  */
7
7
  export default defineNuxtRouteMiddleware(async (to, from) => {
@@ -9,13 +9,25 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
9
9
  throw createError({ message: '页面不存在', statusCode: 404 })
10
10
 
11
11
  const { hasLogin } = storeToRefs(useUserStore())
12
- const { nav_arr, flat_nav_arr } = storeToRefs(useNavStore())
12
+ const { nav_arr, flat_nav_arr, nodeMap, breadcrumb_arr } = storeToRefs(useNavStore())
13
13
 
14
14
  const changeTitle = () => {
15
- const nav = flat_nav_arr.value.find(item => item.component === to.path)
16
- if (nav && nav.title)
15
+ let nav = flat_nav_arr.value.find(item => item.component === to.path)
16
+
17
+ breadcrumb_arr.value.length = 0
18
+
19
+ if (nav && nav.title) {
17
20
  to.meta.title = nav.title
18
21
 
22
+ while (nav) {
23
+ breadcrumb_arr.value.unshift(nav.title!)
24
+ if (nav.parent_id)
25
+ nav = nodeMap.value.get(nav.parent_id.toString())
26
+ else
27
+ break
28
+ }
29
+ }
30
+
19
31
  document.title = (to.meta.title as string) || window.__YOUNG_ENV__.NUXT_PUBLIC_TITLE
20
32
  }
21
33
 
@@ -30,12 +42,19 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
30
42
 
31
43
  if (!hasLogin.value && to.path !== '/login') {
32
44
  // 页面需要登录,但是未登录
33
- showFailToast('未登录或登录过期,请重新登录')
34
- return navigateTo(`/login?redirect=${encodeURIComponent(to.fullPath)}`)
45
+ showNotify({
46
+ type: 'danger',
47
+ message: '未登录或登录过期,请重新登录',
48
+ })
49
+ return navigateTo(`/login?redirect=${encodeURIComponent(to.fullPath)}`, {
50
+ replace: true,
51
+ })
35
52
  }
36
53
  else if (hasLogin.value && to.path === '/login') {
37
54
  // 已登录进入登录页
38
- return navigateTo('/')
55
+ return navigateTo('/', {
56
+ replace: true,
57
+ })
39
58
  }
40
59
  else {
41
60
  nav_arr.value.length === 0 && (await generateNavData())
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-05-25 19:45:20
4
- * @LastEditTime: 2023-09-06 16:13:06
4
+ * @LastEditTime: 2023-09-16 16:34:29
5
5
  * @Description:
6
6
  */
7
7
  import { resolve } from 'node:path'
@@ -21,6 +21,10 @@ export default defineNuxtConfig({
21
21
  { name: 'creator', content: 'BluesYoung-web' },
22
22
  ],
23
23
  link: [
24
+ {
25
+ rel: 'icon',
26
+ href: '/favicon.svg',
27
+ },
24
28
  {
25
29
  rel: 'preload',
26
30
  as: 'image',
@@ -7,7 +7,7 @@
7
7
  "dev": "nuxt dev --host",
8
8
  "generate": "nuxt generate",
9
9
  "preview": "nuxt preview --host",
10
- "postinstall": "nuxt prepare",
10
+ "postinstall": "nuxt prepare && simple-git-hooks",
11
11
  "lint": "eslint .",
12
12
  "lint:fix": "eslint . --fix"
13
13
  },
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-07-21 17:35:12
4
- * @LastEditTime: 2023-07-28 11:34:29
4
+ * @LastEditTime: 2023-09-15 15:20:25
5
5
  * @Description:
6
6
  -->
7
7
  <script lang="ts" setup>
@@ -14,7 +14,7 @@ definePageMeta({
14
14
  const { nick } = storeToRefs(useUserStore())
15
15
  const { nav_arr } = storeToRefs(useNavStore())
16
16
 
17
- onMounted(() => {
17
+ useTabNoCache(() => {
18
18
  nav_arr.value.length === 0 && generateNavData()
19
19
  })
20
20
  </script>
@@ -1,17 +1,12 @@
1
1
  <!--
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-07-21 09:27:14
4
- * @LastEditTime: 2023-07-23 16:23:00
4
+ * @LastEditTime: 2023-09-18 14:15:35
5
5
  * @Description:
6
6
  -->
7
7
  <script setup lang="ts">
8
8
  definePageMeta({
9
- noCache: true,
10
- })
11
-
12
- navigateTo({
13
- path: '/home/index',
14
- replace: true,
9
+ redirect: '/home/index',
15
10
  })
16
11
  </script>
17
12
 
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-07-21 10:03:11
4
- * @LastEditTime: 2023-08-02 10:39:05
4
+ * @LastEditTime: 2023-09-15 15:19:59
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('/')
@@ -61,7 +63,7 @@ function loginHandler() {
61
63
  })
62
64
  }
63
65
 
64
- onMounted(() => {
66
+ useTabNoCache(() => {
65
67
  if (SaveFlag.value && hasLogin.value) {
66
68
  navigateTo({
67
69
  path: '/',
@@ -284,7 +284,6 @@ useTabReOpen(getList)
284
284
  新建菜单
285
285
  </ElButton>
286
286
  </div>
287
- <br>
288
287
  <!-- 节点列表 -->
289
288
  <YoungTablePro
290
289
  :table-data="tableData" :table-head="tableHead" :tree-props="{ children: 'children' }" row-key="id"
@@ -0,0 +1,2 @@
1
+
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#666" d="M26 2h4v4h-4zm0 6h4v4h-4zm-6-6h4v4h-4zm0 6h4v4h-4z"/><path fill="#666" d="M28 16v6H4V6h12V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6ZM18 28h-4v-4h4Z"/></svg>
@@ -0,0 +1,2 @@
1
+
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#fff" d="M26 2h4v4h-4zm0 6h4v4h-4zm-6-6h4v4h-4zm0 6h4v4h-4z"/><path fill="#fff" d="M28 16v6H4V6h12V4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8v4H8v2h16v-2h-4v-4h8a2 2 0 0 0 2-2v-6ZM18 28h-4v-4h4Z"/></svg>
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2022-12-30 17:19:42
4
- * @LastEditTime: 2023-07-31 17:52:20
4
+ * @LastEditTime: 2023-09-16 16:27:56
5
5
  * @Description:
6
6
  */
7
7
  import { resolve } from 'node:path'
@@ -22,9 +22,8 @@ export default defineNitroPlugin(async (nitroApp) => {
22
22
  NUXT_PUBLIC_TITLE: 'XXX-后台管理系统',
23
23
  NUXT_PUBLIC_SUB_TITLE: '做XXX我们是认真的!',
24
24
  NUXT_PUBLIC_SLOGAN: 'XXXXX, XXXXX',
25
- NUXT_PUBLIC_LOGIN_BG:
26
- 'https://dogefs.s3.ladydaily.com/~/source/unsplash/photo-1688380692117-63178554d76d?ixid=M3wyNjY4NDZ8MHwxfHRvcGljfHxhZXU2ckwtajZld3x8fHx8Mnx8MTY5MDAxMDMzNnw&ixlib=rb-4.0.3&w=1920&h=1080&fmt=webp',
27
- NUXT_PUBLIC_LOGIN_LOGO: 'https://api.iconify.design/logos:nuxt-icon.svg?color=%23f74d49',
25
+ NUXT_PUBLIC_LOGIN_BG: '/bg.webp',
26
+ NUXT_PUBLIC_LOGIN_LOGO: '/logo.svg',
28
27
  },
29
28
  })
30
29
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-05-28 16:01:24
4
- * @LastEditTime: 2023-07-31 14:45:23
4
+ * @LastEditTime: 2023-09-13 09:43:52
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
- && showDialog({
86
- title: '温馨提示',
87
- message: '未登录,请登录后再继续!',
88
- showCancelButton: true,
74
+ if (force) {
75
+ showNotify({
76
+ type: 'danger',
77
+ message: '未登录或登录过期,请登录后再试',
78
+ })
79
+
80
+ navigateTo(`/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`, {
81
+ replace: true,
89
82
  })
90
- .then(() => {
91
- navigateTo(
92
- `/login?redirect=${encodeURIComponent(location.href.replace(location.origin, ''))}`,
93
- )
94
- })
95
- .catch(() => {
96
- navigateTo({
97
- path: '/',
98
- replace: true,
99
- })
100
- })
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 (!hasLogin.value) {
126
- showNotify({
127
- type: 'danger',
128
- message: '登录过期,请重新登录!',
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
- delete item.children
142
- else if (item.children)
143
- clearChildren(item.children)
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
- const { nav_arr, flat_nav_arr, auth_routes } = storeToRefs(useNavStore())
123
+ const { nav_arr, flat_nav_arr, auth_routes } = storeToRefs(useNavStore())
149
124
 
150
- const tree = await apis.get.getUserMenuTree()
151
- const menu = Object.values(tree)
125
+ const tree = await apis.get.getUserMenuTree()
126
+ const menu = Object.values(tree)
152
127
 
153
- let role_route: string[] = []
154
- const generateRoleRoute = (arr: NavArrItem[], num?: number): string[] => {
155
- if (num === 1) {
156
- role_route = []
157
- flat_nav_arr.value = []
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
- if (Array.isArray(item.children) && item.children.length > 0) {
166
- const part = JSON.parse(JSON.stringify(item.children))
167
- // 尾递归优化
168
- generateRoleRoute(part)
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
- auth_routes.value = generateRoleRoute(menu, 1)
149
+ auth_routes.value = generateRoleRoute(menu, 1)
175
150
 
176
- /**
151
+ /**
177
152
  * 最终导航数组
178
153
  */
179
- nav_arr.value = clearChildren(menu.filter(item => +item.visible === 1))
154
+ nav_arr.value = clearChildren(menu.filter(item => +item.visible === 1))
155
+ }
180
156
  }
181
157
 
182
158
  /**
@@ -205,3 +181,19 @@ export function useChangePassword() {
205
181
 
206
182
  vnode.component!.exposed?.show()
207
183
  }
184
+
185
+ /**
186
+ * 修改状态二次确认
187
+ */
188
+ export function useConfirm(cbk: Function, tip = '确定修改状态嘛?', successTip?: string) {
189
+ ElMessageBox.confirm(tip, '提示', {
190
+ type: 'warning',
191
+ confirmButtonText: '确定',
192
+ cancelButtonText: '取消',
193
+ })
194
+ .then(async () => {
195
+ await cbk()
196
+ successTip && ElMessage.success(successTip)
197
+ })
198
+ .catch(() => null)
199
+ }
@@ -1,10 +0,0 @@
1
- {
2
- "recommendations": [
3
- "vue.volar",
4
- "rome.rome",
5
- "obkoro1.korofileheader",
6
- "vue.vscode-typescript-vue-plugin",
7
- "antfu.unocss",
8
- "voorjaar.windicss-intellisense"
9
- ]
10
- }
@@ -1,108 +0,0 @@
1
- {
2
- "list-add-admin": {
3
- "prefix": "list-add",
4
- "body": [
5
- "<route lang=\"yaml\">",
6
- "meta:",
7
- " title: $1",
8
- " authPath: $2",
9
- "</route>",
10
- "",
11
- "<script lang=\"ts\" setup>",
12
- "import { useFormMode, YoungDialog, YoungPagination, YoungTable, YoungSelect } from '@bluesyoung/ui-vue3-element-plus';",
13
- "import type { TableHeadItem, TableDataItem, SelectOptionItem } from '@bluesyoung/ui-vue3-element-plus';",
14
- "import { deepClone } from '@bluesyoung/utils';",
15
- "import { $3 } from '@/typings';",
16
- "import { apis } from '@/modules/3-net';",
17
- "",
18
- "interface Form extends $3 {};",
19
- "const FORM_TEMP: Form = {};",
20
- "const {",
21
- " isAdd,",
22
- " isEdit,",
23
- " edit,",
24
- " del,",
25
- " sure,",
26
- " clear,",
27
- " form,",
28
- " formRef,",
29
- " validForm",
30
- "} = useFormMode<Form>(FORM_TEMP, {",
31
- " addCbk: async () => {",
32
- " const res = await validForm() as boolean;",
33
- " if (res) {",
34
- " const v = deepClone(form.value);",
35
- " // await apis.post.addUserItem(v);",
36
- " ElMessage.success('新增成功!');",
37
- " }",
38
- " return res;",
39
- " },",
40
- " modCbk: async () => {",
41
- " const res = await validForm() as boolean;",
42
- " if (res) {",
43
- " const v = deepClone(form.value);",
44
- " // await apis.patch.changeUserItem(v);",
45
- " ElMessage.success('修改成功!');",
46
- " }",
47
- " return res;",
48
- " },",
49
- " delCbk: async (row) => {",
50
- " // await apis.delete.deleteUser(row.id.toString());",
51
- " ElMessage.success('删除成功!');",
52
- " query.pageNum = 1;",
53
- " },",
54
- " cgEffect: () => getList()",
55
- "});",
56
- "const tableHead: TableHeadItem<Form>[] = [",
57
- " { prop: '', label: '' },",
58
- "];",
59
- "interface Query extends BaseQuery {};",
60
- "const query = reactive<Query>({",
61
- " pageNum: 1,",
62
- " pageSize: 50,",
63
- " total: 0,",
64
- "});",
65
- "",
66
- "const tableData = ref<TableDataItem<Form>[]>([]);",
67
- "const getList = async () => {",
68
- " // const { list, pageNum, pageSize, total } = await apis.get.getUserList(query);",
69
- " // tableData.value = deepClone(list || []);",
70
- " // query.pageNum = +pageNum || 1;",
71
- " // query.pageSize = +pageSize || 50;",
72
- " // query.total = +total || 0;",
73
- "};",
74
- "",
75
- "getList();",
76
- "</script>",
77
- "",
78
- "<template>",
79
- " <div class=\"flex\">",
80
- " <div class=\"m-2\">",
81
- " <ElInput v-model=\"query.\" placeholder=\"请输入\" />",
82
- " </div>",
83
- " <div class=\"m-2\">",
84
- " <ElButton type=\"primary\" @click=\"getList\">搜索</ElButton>",
85
- " </div>",
86
- " <div class=\"m-2\">",
87
- " <ElButton type=\"success\" @click=\"isAdd = true\">添加</ElButton>",
88
- " </div>",
89
- " </div>",
90
- " <div class=\"m-2\">",
91
- " <YoungTable :table-data=\"tableData\" :table-head=\"tableHead\" :table-height=\"680\" />",
92
- " <YoungPagination v-show=\"query.total > 0\" v-model:page=\"query.pageNum\" v-model:limit=\"query.pageSize\"",
93
- " :total=\"query.total\" @page-change=\"getList\" />",
94
- " </div>",
95
- " <YoungDialog :is-add=\"isAdd\" :is-edit=\"isEdit\" width=\"520px\" @sure=\"sure\" @clear=\"clear\">",
96
- " <template #body>",
97
- " <ElForm ref=\"formRef\" :model=\"form\" label-width=\"100px\">",
98
- " <ElFormItem label=\"\" prop=\"\">",
99
- " <ElInput v-model=\"form.\" class=\"!w-300px\" />",
100
- " </ElFormItem>",
101
- " </ElForm>",
102
- " </template>",
103
- " </YoungDialog>",
104
- "</template>",
105
- ],
106
- "description": "list-add-admin"
107
- }
108
- }
@@ -1,72 +0,0 @@
1
- {
2
- "list-export-admin": {
3
- "prefix": "list-export",
4
- "body": [
5
- "<route lang=\"yaml\">",
6
- "meta:",
7
- " title: $1",
8
- " authPath: $2",
9
- "</route>",
10
- "",
11
- "<script lang=\"ts\" setup>",
12
- "import { YoungTable, YoungPagination} from '@bluesyoung/ui-vue3-element-plus';",
13
- "import type { TableDataItem, TableHeadItem } from '@bluesyoung/ui-vue3-element-plus';",
14
- "import type { $3 } from '@/typings';",
15
- "import { apis } from '@/modules/3-net';",
16
- "",
17
- "interface Form extends $3 {};",
18
- "",
19
- "const tableHead: TableHeadItem<Form>[] = [",
20
- " { prop: '', label: '' },",
21
- "];",
22
- "const tableData = ref<TableDataItem<Form>[]>([]);",
23
- "",
24
- "type Query = BaseQuery & Partial<Form>;",
25
- "const query = reactive<Query>({",
26
- " pageNum: 1,",
27
- " pageSize: 10,",
28
- " total: 0,",
29
- "});",
30
- "",
31
- "const getList = async () => {",
32
- " // const { list, pageNum, pageSize, total } = await apis.get.getApiList(query);",
33
- " // tableData.value = deepClone(list || []);",
34
- " // query.pageNum = +pageNum || 1;",
35
- " // query.pageSize = +pageSize || 50;",
36
- " // query.total = +total || 0;",
37
- "};",
38
- "",
39
- "const exportHandler = async () => {",
40
- " const { useExport2Excel } = await import('@bluesyoung/ui-vue3-element-plus');",
41
- " await useExport2Excel({",
42
- " filename: '数据导出',",
43
- " tableHead: tableHead,",
44
- " tableData: tableData.value",
45
- " });",
46
- "};",
47
- "",
48
- "getList();",
49
- "</script>",
50
- "",
51
- "<template>",
52
- " <div class=\"flex\">",
53
- " <div class=\"m-2\">",
54
- " <ElInput v-model=\"query.\" placeholder=\"请输入\" />",
55
- " </div>",
56
- " <div class=\"m-2\">",
57
- " <ElButton type=\"primary\" @click=\"getList\">搜索</ElButton>",
58
- " </div>",
59
- " <div class=\"m-2\">",
60
- " <ElButton :disabled=\"tableData.length <= 0\" type=\"success\" @click=\"exportHandler\">导出</ElButton>",
61
- " </div>",
62
- " </div>",
63
- " <div class=\"m-2\">",
64
- " <YoungTable :table-data=\"tableData\" :table-head=\"tableHead\" :table-height=\"680\" />",
65
- " <YoungPagination v-model:page=\"query.pageNum\" v-model:limit=\"query.pageSize\" :total=\"query.total\"",
66
- " @page-change=\"getList\" />",
67
- " </div>",
68
- "</template>"
69
- ],
70
- "description": "list-export-admin"
71
- }
72
- }