create-young-proj 0.13.0 → 1.1.0-alpha.0

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.
Files changed (198) hide show
  1. package/.editorconfig +14 -0
  2. package/.vscode/settings.json +39 -0
  3. package/CHANGELOG.md +256 -0
  4. package/README.md +38 -25
  5. package/build.config.ts +22 -0
  6. package/eslint.config.js +35 -0
  7. package/package.json +10 -15
  8. package/src/index.ts +366 -0
  9. package/template-admin-server/_nvmrc +1 -0
  10. package/template-nuxt-admin/.vscode/settings.json +20 -6
  11. package/template-nuxt-admin/Dockerfile +3 -3
  12. package/template-nuxt-admin/README.md +23 -16
  13. package/template-nuxt-admin/_nvmrc +1 -0
  14. package/template-nuxt-admin/app.vue +10 -2
  15. package/template-nuxt-admin/boot.mjs +7 -7
  16. package/template-nuxt-admin/components/TopSearch.vue +1 -2
  17. package/template-nuxt-admin/components/YoungChangePassword.vue +2 -5
  18. package/template-nuxt-admin/components/YoungCodeInput.vue +1 -2
  19. package/template-nuxt-admin/components/YoungEditor.vue +81 -0
  20. package/template-nuxt-admin/components/ZenMode.vue +21 -0
  21. package/template-nuxt-admin/components/layout/NavBar.vue +3 -2
  22. package/template-nuxt-admin/composables/api.ts +7 -15
  23. package/template-nuxt-admin/composables/icon.ts +1 -3
  24. package/template-nuxt-admin/composables/nav.ts +11 -1
  25. package/template-nuxt-admin/composables/user.ts +3 -1
  26. package/template-nuxt-admin/env.d.ts +8 -8
  27. package/template-nuxt-admin/eslint.config.js +33 -0
  28. package/template-nuxt-admin/layouts/default.vue +45 -7
  29. package/template-nuxt-admin/middleware/auth.global.ts +2 -5
  30. package/template-nuxt-admin/nuxt.config.ts +21 -21
  31. package/template-nuxt-admin/package.json +8 -9
  32. package/template-nuxt-admin/pages/system/api.vue +1 -3
  33. package/template-nuxt-admin/pages/system/hooks/useRole.ts +1 -8
  34. package/template-nuxt-admin/pages/system/menuList.vue +4 -6
  35. package/template-nuxt-admin/pages/system/role.vue +1 -2
  36. package/template-nuxt-admin/pages/system/user.vue +1 -3
  37. package/template-nuxt-admin/public/index.umd.js +74 -0
  38. package/template-nuxt-admin/public/index.umd.js.map +1 -0
  39. package/template-nuxt-admin/server/plugins/env.ts +3 -2
  40. package/template-nuxt-admin/server/utils/index.ts +1 -1
  41. package/template-nuxt-admin/typings/global.d.ts +6 -6
  42. package/template-nuxt-admin/typings/system.d.ts +55 -54
  43. package/template-nuxt-admin/typings/user.d.ts +12 -12
  44. package/template-nuxt-admin/utils/tool.ts +4 -8
  45. package/template-nuxt-admin/yarn.lock +1913 -2002
  46. package/template-nuxt-website/.nvmrc +1 -0
  47. package/template-nuxt-website/.vscode/extensions.json +12 -0
  48. package/template-nuxt-website/.vscode/settings.json +39 -0
  49. package/template-nuxt-website/Dockerfile +41 -0
  50. package/template-nuxt-website/README.md +117 -0
  51. package/template-nuxt-website/_gitignore +26 -0
  52. package/template-nuxt-website/_npmrc +2 -0
  53. package/template-nuxt-website/_nvmrc +1 -0
  54. package/template-nuxt-website/app.vue +66 -0
  55. package/template-nuxt-website/assets/tabbar/event.png +0 -0
  56. package/template-nuxt-website/assets/tabbar/event_active.png +0 -0
  57. package/template-nuxt-website/assets/tabbar/game.png +0 -0
  58. package/template-nuxt-website/assets/tabbar/game_active.png +0 -0
  59. package/template-nuxt-website/assets/tabbar/shop.png +0 -0
  60. package/template-nuxt-website/assets/tabbar/shop_active.png +0 -0
  61. package/template-nuxt-website/assets/tabbar/user.png +0 -0
  62. package/template-nuxt-website/assets/tabbar/user_active.png +0 -0
  63. package/template-nuxt-website/boot.mjs +16 -0
  64. package/template-nuxt-website/components/AboutNav.vue +27 -0
  65. package/template-nuxt-website/components/BreadNav.vue +35 -0
  66. package/template-nuxt-website/components/Follow.vue +48 -0
  67. package/template-nuxt-website/components/FriendLink.vue +36 -0
  68. package/template-nuxt-website/components/mobile/NavBar.vue +50 -0
  69. package/template-nuxt-website/components/top/Extra.vue +50 -0
  70. package/template-nuxt-website/components/top/Nav.vue +87 -0
  71. package/template-nuxt-website/components/young/Banner.vue +100 -0
  72. package/template-nuxt-website/components/young/Footer.vue +44 -0
  73. package/template-nuxt-website/components/young/Header.vue +25 -0
  74. package/template-nuxt-website/components/young/Tabbar.vue +76 -0
  75. package/template-nuxt-website/composables/ad.ts +20 -0
  76. package/template-nuxt-website/composables/config.ts +11 -0
  77. package/template-nuxt-website/composables/nav.ts +30 -0
  78. package/template-nuxt-website/composables/share.ts +22 -0
  79. package/template-nuxt-website/composables/utils.ts +84 -0
  80. package/template-nuxt-website/config/.devrc +11 -0
  81. package/template-nuxt-website/config/.onlinerc +13 -0
  82. package/template-nuxt-website/config/.testrc +11 -0
  83. package/template-nuxt-website/env.d.ts +55 -0
  84. package/template-nuxt-website/error.vue +69 -0
  85. package/template-nuxt-website/eslint.config.js +34 -0
  86. package/template-nuxt-website/layouts/default.vue +80 -0
  87. package/template-nuxt-website/layouts/home.vue +75 -0
  88. package/template-nuxt-website/layouts/tabbar.vue +78 -0
  89. package/template-nuxt-website/nuxt.config.ts +98 -0
  90. package/template-nuxt-website/package.json +41 -0
  91. package/template-nuxt-website/pages/index.html.vue +16 -0
  92. package/template-nuxt-website/pages/index.vue +29 -0
  93. package/template-nuxt-website/pages/match.html.vue +23 -0
  94. package/template-nuxt-website/pages/news/[id].html.vue +57 -0
  95. package/template-nuxt-website/pages/news.html.vue +26 -0
  96. package/template-nuxt-website/pages/shop.html.vue +26 -0
  97. package/template-nuxt-website/public/favicon.ico +0 -0
  98. package/template-nuxt-website/public/robots.txt +2 -0
  99. package/template-nuxt-website/public/svg/image_placeholder.svg +15 -0
  100. package/template-nuxt-website/server/api/get_footer_info.get.ts +52 -0
  101. package/template-nuxt-website/server/api/get_gray_status.get.ts +38 -0
  102. package/template-nuxt-website/server/api/get_head_nav.get.ts +38 -0
  103. package/template-nuxt-website/server/api/get_home_banner.get.ts +28 -0
  104. package/template-nuxt-website/server/api/get_seo_info.get.ts +32 -0
  105. package/template-nuxt-website/server/middleware/platform.ts +11 -0
  106. package/template-nuxt-website/server/plugins/init.ts +147 -0
  107. package/template-nuxt-website/server/tsconfig.json +3 -0
  108. package/template-nuxt-website/server/utils/index.ts +12 -0
  109. package/template-nuxt-website/server/utils/proxy.ts +59 -0
  110. package/template-nuxt-website/tsconfig.json +4 -0
  111. package/template-nuxt-website/typings/banner.d.ts +30 -0
  112. package/template-nuxt-website/typings/nav.d.ts +34 -0
  113. package/template-nuxt-website/typings/system.d.ts +22 -0
  114. package/template-nuxt-website/uno.config.ts +40 -0
  115. package/template-nuxt-website/utils/tool.ts +171 -0
  116. package/template-nuxt-website/yarn.lock +8018 -0
  117. package/template-uni-app/.vscode/settings.json +20 -6
  118. package/template-uni-app/README.md +5 -0
  119. package/template-uni-app/_nvmrc +1 -0
  120. package/template-uni-app/eslint.config.js +35 -0
  121. package/template-uni-app/package.json +22 -21
  122. package/template-uni-app/pnpm-lock.yaml +2557 -1543
  123. package/template-uni-app/src/env.d.ts +6 -6
  124. package/template-uni-app/src/typings/global.d.ts +1 -1
  125. package/template-uni-app/src/utils/modal.ts +2 -2
  126. package/template-uni-app/tsconfig.json +3 -3
  127. package/tsconfig.json +11 -0
  128. package/dist/index.mjs +0 -51
  129. package/template-nuxt-admin/.eslintrc +0 -14
  130. package/template-uni-app/.vscode/.server-controller-port.log +0 -5
  131. package/template-uni-app/dist/dev/mp-weixin/apis/index.js +0 -43
  132. package/template-uni-app/dist/dev/mp-weixin/apis/requests/get.js +0 -10
  133. package/template-uni-app/dist/dev/mp-weixin/apis/requests/index.js +0 -1
  134. package/template-uni-app/dist/dev/mp-weixin/apis/requests/post.js +0 -15
  135. package/template-uni-app/dist/dev/mp-weixin/app.js +0 -92
  136. package/template-uni-app/dist/dev/mp-weixin/app.json +0 -51
  137. package/template-uni-app/dist/dev/mp-weixin/app.wxss +0 -2378
  138. package/template-uni-app/dist/dev/mp-weixin/common/assets.js +0 -13
  139. package/template-uni-app/dist/dev/mp-weixin/common/vendor.js +0 -9166
  140. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.js +0 -22
  141. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.json +0 -4
  142. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.wxml +0 -1
  143. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.wxss +0 -0
  144. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.js +0 -22
  145. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.json +0 -4
  146. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.wxml +0 -1
  147. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.wxss +0 -0
  148. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.js +0 -81
  149. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.json +0 -4
  150. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.wxml +0 -1
  151. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.wxss +0 -108
  152. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.js +0 -55
  153. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.json +0 -4
  154. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.wxml +0 -1
  155. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.wxss +0 -88
  156. package/template-uni-app/dist/dev/mp-weixin/config/enum.js +0 -21
  157. package/template-uni-app/dist/dev/mp-weixin/config/index.js +0 -1
  158. package/template-uni-app/dist/dev/mp-weixin/config/map.js +0 -1
  159. package/template-uni-app/dist/dev/mp-weixin/layouts/default.js +0 -29
  160. package/template-uni-app/dist/dev/mp-weixin/layouts/default.json +0 -6
  161. package/template-uni-app/dist/dev/mp-weixin/layouts/default.wxml +0 -1
  162. package/template-uni-app/dist/dev/mp-weixin/layouts/default.wxss +0 -0
  163. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.js +0 -56
  164. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.json +0 -9
  165. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.wxml +0 -1
  166. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.wxss +0 -0
  167. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.js +0 -98
  168. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.json +0 -4
  169. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.wxml +0 -1
  170. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.wxss +0 -125
  171. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.js +0 -37
  172. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.json +0 -5
  173. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.wxml +0 -1
  174. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.wxss +0 -0
  175. package/template-uni-app/dist/dev/mp-weixin/pages/index.js +0 -50
  176. package/template-uni-app/dist/dev/mp-weixin/pages/index.json +0 -5
  177. package/template-uni-app/dist/dev/mp-weixin/pages/index.wxml +0 -1
  178. package/template-uni-app/dist/dev/mp-weixin/pages/index.wxss +0 -0
  179. package/template-uni-app/dist/dev/mp-weixin/pages/my.js +0 -22
  180. package/template-uni-app/dist/dev/mp-weixin/pages/my.json +0 -3
  181. package/template-uni-app/dist/dev/mp-weixin/pages/my.wxml +0 -1
  182. package/template-uni-app/dist/dev/mp-weixin/pages/my.wxss +0 -0
  183. package/template-uni-app/dist/dev/mp-weixin/project.config.json +0 -55
  184. package/template-uni-app/dist/dev/mp-weixin/project.private.config.json +0 -6
  185. package/template-uni-app/dist/dev/mp-weixin/static/back.png +0 -0
  186. package/template-uni-app/dist/dev/mp-weixin/static/h.png +0 -0
  187. package/template-uni-app/dist/dev/mp-weixin/static/home.png +0 -0
  188. package/template-uni-app/dist/dev/mp-weixin/static/home_active.png +0 -0
  189. package/template-uni-app/dist/dev/mp-weixin/static/more.png +0 -0
  190. package/template-uni-app/dist/dev/mp-weixin/static/my.png +0 -0
  191. package/template-uni-app/dist/dev/mp-weixin/static/my_active.png +0 -0
  192. package/template-uni-app/dist/dev/mp-weixin/static/network.png +0 -0
  193. package/template-uni-app/dist/dev/mp-weixin/store/index.js +0 -8
  194. package/template-uni-app/dist/dev/mp-weixin/store/local/index.js +0 -13
  195. package/template-uni-app/dist/dev/mp-weixin/store/system.js +0 -14
  196. package/template-uni-app/dist/dev/mp-weixin/utils/modal.js +0 -78
  197. package/template-uni-app/dist/dev/mp-weixin/utils/route.js +0 -83
  198. package/template-uni-app/dist/dev/mp-weixin/utils/system.js +0 -27
@@ -0,0 +1,38 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-06-07 14:43:38
4
+ * @LastEditTime: 2023-11-08 09:53:14
5
+ * @Description:
6
+ */
7
+ import { NUXT_PUBLIC_CACHE_TIME } from '~~/composables/config'
8
+
9
+ export default cachedEventHandler(async () => {
10
+ console.log('start get head info')
11
+
12
+ try {
13
+ const nav_arr: NavItem[] = [
14
+ { title: '首页', href: '/' },
15
+ { title: '资讯', href: '/news.html' },
16
+ { title: '赛事', href: '/match.html' },
17
+ { title: '商城', href: '/shop.html' }
18
+ ]
19
+ const fromMobile = process.env.PROJECT_NAME === 'mobile'
20
+
21
+ return {
22
+ logo_url: 'https://master-web-cdn.laiyouxi.com/platform_index/online/744f27a210a9098c79f58d115cc321ea.png',
23
+ kj_logo_url: 'https://master-web-cdn.laiyouxi.com/platform_index/online/83fa32ed0e3f286fccd93dae7d9bee8c.png',
24
+ nav_arr,
25
+ showAd: false,
26
+ img_ad: '',
27
+ img_btn: '',
28
+ site_url: fromMobile ? process.env.VITE_WEBSITE_MOBILE! : process.env.VITE_WEBSITE_PC!,
29
+ }
30
+ }
31
+ catch (error) {
32
+ console.error('get head info fail: ', error)
33
+ return false
34
+ }
35
+ }, {
36
+ maxAge: NUXT_PUBLIC_CACHE_TIME,
37
+ swr: true,
38
+ })
@@ -0,0 +1,28 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-10-07 17:43:38
4
+ * @LastEditTime: 2023-10-09 12:08:35
5
+ * @Description:
6
+ */
7
+ import { NUXT_PUBLIC_CACHE_TIME } from '~~/composables/config'
8
+
9
+ export default cachedEventHandler(async (event) => {
10
+ console.log('start get home banner')
11
+
12
+ try {
13
+ const banners: BannerItem[] = [
14
+ {
15
+ img_url: 'https://master-web-cdn.laiyouxi.com/platform_index/online/files/banner-pc.png'
16
+ }
17
+ ]
18
+
19
+ return banners
20
+ }
21
+ catch (error) {
22
+ console.error('get home banner fail: ', error)
23
+ return false
24
+ }
25
+ }, {
26
+ maxAge: NUXT_PUBLIC_CACHE_TIME,
27
+ swr: true,
28
+ })
@@ -0,0 +1,32 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-06-07 14:29:59
4
+ * @LastEditTime: 2023-11-08 09:51:06
5
+ * @Description:
6
+ */
7
+ import { NUXT_PUBLIC_CACHE_TIME } from '~~/composables/config'
8
+
9
+ export default cachedEventHandler(async (event) => {
10
+ console.log('start get seo info')
11
+
12
+ const { page } = getQuery(event)
13
+ /**
14
+ * 对于特定页面的 seo 进行相应的索引
15
+ */
16
+ console.log('🚀 ~ file: get_seo_info.get.ts:10 ~ cachedEventHandler ~ page:', page)
17
+
18
+ try {
19
+ return {
20
+ keywords: '我是关键字,啦啦啦,哈哈哈',
21
+ description: '我是描述,啦啦啦,哈哈哈',
22
+ title: '我是标题,啦啦啦,哈哈哈',
23
+ } as SeoInfo
24
+ }
25
+ catch (error) {
26
+ console.error('get seo info fail: ', error)
27
+ return false
28
+ }
29
+ }, {
30
+ maxAge: NUXT_PUBLIC_CACHE_TIME * 30,
31
+ swr: true,
32
+ })
@@ -0,0 +1,11 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-10-07 12:11:46
4
+ * @LastEditTime: 2023-11-01 19:09:47
5
+ * @Description:
6
+ */
7
+ export default defineEventHandler((event) => {
8
+ event.context.platformSource = process.env.PROJECT_NAME === 'mobile' ? 'mobile' : 'pc'
9
+ event.context['x-forwarded-for'] = event.node.req.headers['x-forwarded-for'] as string
10
+ event.context['x-real-ip'] = event.node.req.headers['x-real-ip'] as string
11
+ })
@@ -0,0 +1,147 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2022-12-30 17:19:42
4
+ * @LastEditTime: 2023-11-08 10:52:46
5
+ * @Description:
6
+ */
7
+ import { resolve } from 'node:path'
8
+ import { loadConfig } from 'c12'
9
+ import { useYoungLogger } from '@bluesyoung/logger'
10
+
11
+ export default defineNitroPlugin(async (nitroApp) => {
12
+ const env = (process.env.DEPLOY_ENV as 'dev' | 'test' | 'online') || 'dev'
13
+ const { config } = await loadConfig<Record<string, any>>({
14
+ name: env,
15
+ cwd: resolve(process.cwd(), 'config'),
16
+ defaultConfig: {
17
+ // 优先读取环境变量中的版本信息(自己打的 Tag)
18
+ NUXT_PUBLIC_CURRENT_VERSION: process.env.PROJECT_VERSION || 'v0.0.1',
19
+ // 日志等级
20
+ CONSOLA_LEVEL: 1,
21
+ // 此处可以放置通用的环境变量
22
+ VITE_WECHAT_APPID: 'todo: 微信公众号appid',
23
+ VITE_OSS_URL: `https://master-web-cdn.laiyouxi.com/platform_index/${env}/`,
24
+ VITE_VCONSOLE: false,
25
+ /**
26
+ * 当前启动服务的项目
27
+ */
28
+ PROJECT_NAME: 'pc',
29
+ /**
30
+ * 是否禁用自动重定向
31
+ */
32
+ DISABLE_AUTO_LOCATION: false,
33
+ },
34
+ })
35
+
36
+ for (const key in config) {
37
+ if (process.env[key]) {
38
+ console.log('系统环境变量优先: ', key, ' = ', process.env[key], ' -> ', config[key], ' -> ', '覆盖')
39
+ config[key] = process.env[key]
40
+ }
41
+ else {
42
+ process.env[key] = config[key]
43
+ }
44
+ if (!((key.indexOf('NUXT_PUBLIC_') === 0) || (key.indexOf('VITE_') === 0)))
45
+ delete config[key]
46
+ }
47
+
48
+ console.log('------------------------读取配置文件------------------------')
49
+ console.log(config)
50
+ console.log('-------------------------------------------------------------')
51
+
52
+ const IS_PROD = process.env.NODE_ENV !== 'development'
53
+ console.log('🚀 ~ file: init.ts:53 ~ IS_PROD:', IS_PROD)
54
+
55
+ if (IS_PROD) {
56
+ // 格式化日志
57
+ const { consola } = useYoungLogger()
58
+ const logger = consola.create({
59
+ level: +process.env.CONSOLA_LEVEL!,
60
+ })
61
+ logger.wrapConsole()
62
+ }
63
+
64
+ nitroApp.hooks.hook('render:html', async (html, { event }) => {
65
+ const ua = event.node.req.headers['user-agent']
66
+
67
+ console.log('jump status: ', !config!.DISABLE_AUTO_LOCATION, typeof !config!.DISABLE_AUTO_LOCATION)
68
+
69
+ if (ua && (IS_PROD && !config!.DISABLE_AUTO_LOCATION)) {
70
+ const isMobile = /mobile|nokia|iphone|ipad|android|samsung|htc|blackberry/gim.test(ua)
71
+ console.log('🚀 ~ file: init.ts:59 ~ nitroApp.hooks.hook ~ isMobile:', isMobile)
72
+ const fromMobile = process.env.PROJECT_NAME === 'mobile'
73
+ console.log('🚀 ~ file: init.ts:61 ~ nitroApp.hooks.hook ~ fromMobile:', fromMobile)
74
+ if (isMobile && !fromMobile) {
75
+ // 手机访问 PC 网址
76
+ console.log('🚀 ~ file: init.ts:64 ~ nitroApp.hooks.hook ~ 手机访问 PC 网址:')
77
+ event.node.res.setHeader('Location', process.env.VITE_WEBSITE_MOBILE! + event.node.req.url)
78
+ event.node.res.statusCode = 301
79
+ return
80
+ }
81
+ else if (!isMobile && fromMobile) {
82
+ // PC 访问手机网址
83
+ console.log('🚀 ~ file: init.ts:72 ~ nitroApp.hooks.hook ~ PC 访问手机网址:')
84
+ event.node.res.setHeader('Location', process.env.VITE_WEBSITE_PC! + event.node.req.url)
85
+ event.node.res.statusCode = 301
86
+ return
87
+ }
88
+ }
89
+
90
+ // 网站置灰
91
+ try {
92
+ const {
93
+ is_gray,
94
+ scope,
95
+ } = await $fetch('/api/get_gray_status')
96
+ console.log('🚀 ~ get gray status ~ is_gray: %s, scope: %s', is_gray, scope)
97
+
98
+ const pathname = event.node.req.url!.split('?')[0]
99
+ if (is_gray && (scope === '*' || pathname === '/'))
100
+ html.htmlAttrs.push(`style="filter: grayscale(1);"`)
101
+ }
102
+ catch (error) {
103
+ console.error('🚀 ~ set gray error:', error)
104
+ }
105
+
106
+ // 设定视口高度,防止软键盘影响布局
107
+ html.bodyPrepend.push(`
108
+ <script>
109
+ const metaElement = document.querySelector('#viewportMeta');
110
+ metaElement.setAttribute('content', \`maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0,height=\${window.innerHeight}\`);
111
+ </script>
112
+ `)
113
+
114
+ // 注入环境变量
115
+ html.bodyPrepend.push(`
116
+ <!-- 注入环境变量 -->
117
+ <script>window.__YOUNG_ENV__=${JSON.stringify(config)}</script>
118
+ <!-- 更新检测,每分钟一次 -->
119
+ <script>
120
+ const YOUNG_UPDATE_TIMER = setInterval(() => {
121
+ fetch('${getFullAssetsUrl('/get/env')}')
122
+ .then((res) => res.json())
123
+ .then(({ NUXT_PUBLIC_CURRENT_VERSION }) => {
124
+ if (NUXT_PUBLIC_CURRENT_VERSION !== window.__YOUNG_ENV__.NUXT_PUBLIC_CURRENT_VERSION) {
125
+ clearInterval(YOUNG_UPDATE_TIMER);
126
+ alert('版本已更新,点击重新加载页面!');
127
+ window.location.reload();
128
+ }
129
+ });
130
+ }, 6e4);
131
+ </script>
132
+ `)
133
+
134
+ // 微信 sdk
135
+ html.bodyAppend.push(`
136
+ <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" defer></script>
137
+ `)
138
+
139
+ // vconsole 调试
140
+ if ((config as ImportMetaEnv).VITE_VCONSOLE) {
141
+ html.bodyAppend.push(`
142
+ <script src="https://g2021-cdn.laiyouxi.com/image/21Store/admin-img/vconsole.min.js"></script>
143
+ <script>new VConsole()</script>
144
+ `)
145
+ }
146
+ })
147
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../.nuxt/tsconfig.server.json"
3
+ }
@@ -0,0 +1,12 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-05-29 10:29:52
4
+ * @LastEditTime: 2023-11-03 15:45:17
5
+ * @Description:
6
+ */
7
+ export function getFullAssetsUrl(url: string) {
8
+ if (process.env.NODE_ENV === 'development' || !process.env.NUXT_APP_CDN_URL)
9
+ return url
10
+
11
+ return process.env.NUXT_APP_CDN_URL + url
12
+ }
@@ -0,0 +1,59 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-09-27 11:22:08
4
+ * @LastEditTime: 2023-11-01 19:10:45
5
+ * @Description:
6
+ */
7
+ import type { ServerOptions as HTTPProxyOptions } from 'http-proxy'
8
+ import ProxyModule from 'http-proxy'
9
+ import type { H3Event } from 'h3'
10
+
11
+ /**
12
+ * @param target 接口代理的具体地址
13
+ * @param defaults 代理配置
14
+ * @example
15
+ * export default defineEventHandler(async (event) => {
16
+ * const proxy = createTransparentProxy(`http://127.0.0.1:3333`);
17
+ * await proxy.handle(event);
18
+ * });
19
+ */
20
+ export function createTransparentProxy(target: string, defaults: HTTPProxyOptions = {}) {
21
+ const proxy = ProxyModule.createProxy()
22
+ const handle = (event: H3Event, opts: HTTPProxyOptions = {}) => {
23
+ return new Promise<void>((resolve, reject) => {
24
+ proxy.web(event.node.req, event.node.res, { target, ...defaults, ...opts }, (error: any) => {
25
+ if (error.code !== 'ECONNRESET')
26
+ reject(error)
27
+
28
+ resolve()
29
+ })
30
+ })
31
+ }
32
+ return {
33
+ proxy,
34
+ handle,
35
+ }
36
+ }
37
+
38
+ /**
39
+ * 服务端发送的请求
40
+ */
41
+ export function useServerFetch(event: H3Event, prefix = '/index') {
42
+ const BaseServerURL = `${process.env.VITE_BACKEND_SERVER}${prefix}` as const
43
+
44
+ return $fetch.create({
45
+ baseURL: BaseServerURL,
46
+ headers: {
47
+ 'platform-source': event.context.platformSource,
48
+ 'x-real-ip': event.context['x-real-ip']!,
49
+ 'x-forwarded-for': event.context['x-forwarded-for']!,
50
+ },
51
+ async onRequest({ request, options }) {
52
+ const { onRequest, onResponse, onRequestError, onResponseError, ...opts } = options
53
+ console.log('🚀 ~ onRequest ~ request: %o, options: %o', request, opts)
54
+ },
55
+ async onResponse({ response }) {
56
+ console.log('🚀 ~ onResponse ~ data:', response._data)
57
+ },
58
+ })
59
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ // https://nuxt.com/docs/guide/concepts/typescript
3
+ "extends": "./.nuxt/tsconfig.json"
4
+ }
@@ -0,0 +1,30 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-09-27 11:35:38
4
+ * @LastEditTime: 2023-11-08 10:24:29
5
+ * @Description:
6
+ */
7
+ interface BannerItem {
8
+ /**
9
+ * 图片地址
10
+ */
11
+ img_url: string
12
+ /**
13
+ * 图片标题
14
+ */
15
+ title?: string
16
+ /**
17
+ * 安卓跳转地址
18
+ */
19
+ android_url?: string
20
+ /**
21
+ * ios 跳转地址
22
+ */
23
+ ios_url?: string
24
+ /**
25
+ * 是否为视频
26
+ */
27
+ is_video?: boolean
28
+
29
+ type?: number
30
+ }
@@ -0,0 +1,34 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-10-07 15:59:27
4
+ * @LastEditTime: 2023-10-31 17:09:32
5
+ * @Description:
6
+ */
7
+ interface FriendLinkItem {
8
+ title: string
9
+ href: string
10
+ }
11
+
12
+ interface FollowItem {
13
+ icon: string
14
+ name: string
15
+ qrcode: string
16
+ jump?: string
17
+ hidden?: boolean
18
+ }
19
+
20
+ interface AboutNavItem {
21
+ title: string
22
+ url: string
23
+ }
24
+
25
+ interface BreadNavItem {
26
+ title: string
27
+ href: string
28
+ }
29
+
30
+ interface UserCenterNavItem {
31
+ title: string
32
+ icon: string
33
+ to: string
34
+ }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-09-27 12:09:55
4
+ * @LastEditTime: 2023-09-27 12:18:44
5
+ * @Description:
6
+ */
7
+ interface NavItem {
8
+ /**
9
+ * 跳转地址
10
+ */
11
+ href: string
12
+ /**
13
+ * 标题
14
+ */
15
+ title: string
16
+ }
17
+
18
+ interface SeoInfo {
19
+ title: string
20
+ keywords: string
21
+ description: string
22
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2022-06-15 08:59:22
4
+ * @LastEditTime: 2023-05-27 19:36:43
5
+ * @Description:
6
+ */
7
+ import {
8
+ defineConfig,
9
+ presetAttributify,
10
+ presetIcons,
11
+ presetTypography,
12
+ presetUno,
13
+ presetWebFonts,
14
+ transformerDirectives,
15
+ transformerVariantGroup,
16
+ } from 'unocss'
17
+
18
+ export default defineConfig({
19
+ shortcuts: [],
20
+ presets: [
21
+ presetUno(),
22
+ presetAttributify(),
23
+ presetIcons({
24
+ scale: 1.2,
25
+ }),
26
+ presetTypography(),
27
+ presetWebFonts({
28
+ fonts: {
29
+ sans: 'DM Sans',
30
+ serif: 'DM Serif Display',
31
+ mono: 'DM Mono',
32
+ },
33
+ }),
34
+ ],
35
+ transformers: [
36
+ // 不加 enforce 会有 bug
37
+ transformerDirectives({ enforce: 'pre' }),
38
+ transformerVariantGroup(),
39
+ ],
40
+ })
@@ -0,0 +1,171 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-05-28 16:01:24
4
+ * @LastEditTime: 2023-11-08 10:28:46
5
+ * @Description:
6
+ */
7
+ import { randomId } from '@bluesyoung/utils'
8
+ import { reactive } from 'vue'
9
+ import { useMediaQuery } from '@vueuse/core'
10
+
11
+ /**
12
+ * 生成数组的随机索引
13
+ */
14
+ export function getRandomIndex(length: number) {
15
+ return Math.floor(Math.random() * length)
16
+ }
17
+
18
+ /**
19
+ * 设备唯一标识
20
+ */
21
+ export function getUUID() {
22
+ return useLocalStorage('uuid', randomId() + randomId() + randomId() + randomId()).value
23
+ }
24
+
25
+ /**
26
+ * 获取服务器资源地址
27
+ * 第二个参数为默认值,默认返回图片占位符,如果不需要请给第二个参数传入 false
28
+ * 第三个参数代表是否拼接基于 oss 的图片处理参数,默认转换为 webp
29
+ */
30
+ export function getFullServerUrl(
31
+ name?: string,
32
+ _default: string | false = '/svg/image_placeholder.svg',
33
+ processImage = true,
34
+ ) {
35
+ if (!name) {
36
+ if (_default === false)
37
+ return ''
38
+
39
+ else
40
+ return _default
41
+ }
42
+
43
+ if (
44
+ name.startsWith('data:image')
45
+ || name.startsWith('blob:')
46
+ || name.startsWith('http://')
47
+ || name.startsWith('https://')
48
+ || name.startsWith('/_')
49
+ ) {
50
+ if (processImage && !name.startsWith('data:image') && !name.startsWith('blob:') && !name.startsWith('/_')) {
51
+ const u = new URL(name)
52
+ u.searchParams.set('x-oss-process', 'image/quality,Q_75/format,webp')
53
+ return u.toString()
54
+ }
55
+ else {
56
+ return name
57
+ }
58
+ }
59
+
60
+ const u = new URL(name, process.server ? process.env.VITE_OSS_URL : window.__YOUNG_ENV__.VITE_OSS_URL)
61
+ if (processImage)
62
+ u.searchParams.set('x-oss-process', 'image/quality,Q_75/format,webp')
63
+
64
+ return u.toString()
65
+ }
66
+
67
+ /**
68
+ * 微信分享
69
+ */
70
+ export async function useWeChatShare(shareData: {
71
+ title: string
72
+ desc: string
73
+ imgUrl: string
74
+ /**
75
+ * 分享链接
76
+ * @default location.href.split('#')[0]
77
+ */
78
+ link?: string
79
+ }) {
80
+ if (process.server)
81
+ return
82
+
83
+ /**
84
+ * 分享链接
85
+ */
86
+ const link = shareData.link || location.href.split('#')[0]
87
+
88
+ const { jssdkShareSign } = storeToRefs(useShareStore())
89
+
90
+ if (!jssdkShareSign.value.timestamp) {
91
+ // todo: 微信签名
92
+ // const signConf = await fetch('/api/wechat/sign', {
93
+ // method: 'POST',
94
+ // body: JSON.stringify({
95
+ // wxAppId: window.__YOUNG_ENV__.VITE_WECHAT_APPID,
96
+ // url: link,
97
+ // })
98
+ // })
99
+
100
+ // jssdkShareSign.value = {
101
+ // timestamp: `${signConf.timestamp}`, // 必填,生成签名的时间戳
102
+ // nonceStr: signConf.noncestr, // 必填,生成签名的随机串
103
+ // signature: signConf.signature, // 必填,签名
104
+ // }
105
+ }
106
+
107
+ // @ts-expect-error
108
+ wx.config({
109
+ debug: window.__YOUNG_ENV__.VITE_VCONSOLE, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
110
+ appId: window.__YOUNG_ENV__.VITE_WECHAT_APPID, // 必填,公众号的唯一标识
111
+ ...jssdkShareSign.value,
112
+ jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'], // 必填,需要使用的JS接口列表
113
+ openTagList: [], // 可选,需要使用的开放标签列表,例如
114
+ })
115
+
116
+ // @ts-expect-error
117
+ wx.ready(() => {
118
+ // 需在用户可能点击分享按钮前就先调用
119
+ // @ts-expect-error
120
+ wx.updateAppMessageShareData({ link, ...shareData })
121
+ // @ts-expect-error
122
+ wx.updateTimelineShareData({ link, ...shareData })
123
+ })
124
+ }
125
+
126
+ /**
127
+ * html 转 text
128
+ */
129
+ export function html2text(html: string) {
130
+ if (!html)
131
+ return ''
132
+
133
+ return html.toString().replace(/<[^>]+>/g, '')
134
+ }
135
+
136
+ /**
137
+ * 响应式的屏幕大小
138
+ */
139
+ export const WindowSize = reactive({
140
+ 'lt-sm': useMediaQuery('(max-width: 639.9px)'),
141
+ 'sm': useMediaQuery('(min-width: 640px)'),
142
+ 'lt-md': useMediaQuery('(max-width: 767.9px)'),
143
+ 'md': process.server ? true : useMediaQuery('(min-width: 768px)'),
144
+ 'lt-lg': useMediaQuery('(max-width: 1023.9px)'),
145
+ 'lg': useMediaQuery('(min-width: 1024px)'),
146
+ 'lt-xl': useMediaQuery('(max-width: 1279.9px)'),
147
+ 'xl': useMediaQuery('(min-width: 1280px)'),
148
+ 'lt-2xl': useMediaQuery('(max-width: 1535.9px)'),
149
+ '2xl': useMediaQuery('(min-width: 1536px)'),
150
+ })
151
+
152
+ /**
153
+ * 当前浏览器是否支持下载
154
+ */
155
+ export function isSupportDownload() {
156
+ const NotAllowed = [/Alipay/gim, /BYTEDANCE/gim, /DINGTALK/gim, /MICROMESSENGER/gim]
157
+
158
+ return !NotAllowed.some(reg => reg.test(navigator.userAgent))
159
+ }
160
+
161
+ /**
162
+ * 页面滚动是否超过一定距离
163
+ */
164
+ export function useScrollOver(distance = 40) {
165
+ const { y } = useScroll(!process.server ? window : null)
166
+ const scrolled = computed(() => y.value > distance)
167
+
168
+ return {
169
+ scrolled,
170
+ }
171
+ }