@gx-design-vue/create-gx-cli 0.1.14 → 0.1.16

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 (124) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +7 -4
  3. package/src/main.js +7 -7
  4. package/template-mobile-vant-cli/.env +3 -0
  5. package/template-mobile-vant-cli/.env.development +4 -6
  6. package/template-mobile-vant-cli/.env.pro +16 -7
  7. package/template-mobile-vant-cli/.env.production +21 -9
  8. package/template-mobile-vant-cli/commitlint.config.cjs +32 -0
  9. package/template-mobile-vant-cli/config/default/defaultSettings.ts +70 -0
  10. package/template-mobile-vant-cli/config/default/network.ts +10 -0
  11. package/template-mobile-vant-cli/config/default/proxy.ts +50 -0
  12. package/template-mobile-vant-cli/config/default/theme.ts +3 -0
  13. package/template-mobile-vant-cli/config/index.ts +11 -0
  14. package/template-mobile-vant-cli/eslint.config.js +10 -2
  15. package/template-mobile-vant-cli/index.html +22 -21
  16. package/template-mobile-vant-cli/{build → internal/vite-config/generate}/generateModifyVars.ts +1 -1
  17. package/template-mobile-vant-cli/internal/vite-config/rollupOptions/index.ts +22 -0
  18. package/template-mobile-vant-cli/internal/vite-config/util/hash.ts +17 -0
  19. package/template-mobile-vant-cli/internal/vite-config/util/index.ts +132 -0
  20. package/template-mobile-vant-cli/internal/vite-config/vite/cdn.ts +65 -0
  21. package/template-mobile-vant-cli/{build → internal/vite-config/vite}/optimizer.ts +9 -1
  22. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/appConfig.ts +91 -0
  23. package/template-mobile-vant-cli/{build → internal/vite-config/vite}/plugin/autoImport.ts +7 -3
  24. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/compress.ts +31 -0
  25. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/html.ts +32 -0
  26. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/index.ts +74 -0
  27. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/visualizer.ts +14 -0
  28. package/template-mobile-vant-cli/internal/vite-config/vite/plugin/viteNotice.ts +40 -0
  29. package/template-mobile-vant-cli/mock/config/permissions.ts +15 -0
  30. package/template-mobile-vant-cli/mock/config/user/id.ts +5 -0
  31. package/template-mobile-vant-cli/mock/config/user/index.ts +96 -0
  32. package/template-mobile-vant-cli/mock/index.ts +55 -0
  33. package/template-mobile-vant-cli/mock/routers/table/index.fake.ts +22 -0
  34. package/template-mobile-vant-cli/mock/routers/user/account.fake.ts +52 -0
  35. package/template-mobile-vant-cli/mock/routers/user/index.fake.ts +46 -0
  36. package/template-mobile-vant-cli/mock/utils/crypto.ts +21 -0
  37. package/template-mobile-vant-cli/mock/utils/table.ts +96 -0
  38. package/template-mobile-vant-cli/mock/utils/util.ts +91 -0
  39. package/template-mobile-vant-cli/package.json +51 -34
  40. package/template-mobile-vant-cli/public/css/default.css +54 -0
  41. package/template-mobile-vant-cli/src/App.vue +6 -2
  42. package/template-mobile-vant-cli/src/assets/logo.png +0 -0
  43. package/template-mobile-vant-cli/src/components/PageContainer/ProSkeleton.tsx +1 -1
  44. package/template-mobile-vant-cli/src/components/PageContainer/index.tsx +108 -16
  45. package/template-mobile-vant-cli/src/components/PageContainer/style.module.less +5 -2
  46. package/template-mobile-vant-cli/src/components/TabsMenu/index.vue +45 -0
  47. package/template-mobile-vant-cli/src/core/gx-design/index.ts +1 -1
  48. package/template-mobile-vant-cli/src/core/index.ts +0 -7
  49. package/template-mobile-vant-cli/src/design/color.less +1 -0
  50. package/template-mobile-vant-cli/src/design/config.less +5 -0
  51. package/template-mobile-vant-cli/src/design/index.less +1 -1
  52. package/template-mobile-vant-cli/src/design/mixin.less +65 -0
  53. package/template-mobile-vant-cli/src/design/reset.less +16 -132
  54. package/template-mobile-vant-cli/src/hooks/web/usePageLoading.ts +7 -9
  55. package/template-mobile-vant-cli/src/layout/{BasicLayout.vue → BasicLayout/index.vue} +3 -1
  56. package/template-mobile-vant-cli/src/layout/BasicLayout/style.less +3 -0
  57. package/template-mobile-vant-cli/src/layout/UserLayout/index.vue +18 -0
  58. package/template-mobile-vant-cli/src/layout/UserLayout/style.module.less +36 -0
  59. package/template-mobile-vant-cli/src/main.ts +16 -9
  60. package/template-mobile-vant-cli/src/pages/Account/details.vue +13 -0
  61. package/template-mobile-vant-cli/src/pages/Account/index.vue +102 -0
  62. package/template-mobile-vant-cli/src/pages/{home.vue → Home/index.vue} +5 -5
  63. package/template-mobile-vant-cli/src/pages/user/login/index.vue +74 -0
  64. package/template-mobile-vant-cli/src/plugins/dayjs/index.ts +3 -0
  65. package/template-mobile-vant-cli/src/plugins/index.ts +2 -0
  66. package/template-mobile-vant-cli/src/router/guard/index.ts +18 -0
  67. package/template-mobile-vant-cli/src/router/guard/permissions.ts +41 -0
  68. package/template-mobile-vant-cli/src/router/guard/stateGuard.ts +10 -0
  69. package/template-mobile-vant-cli/src/router/index.ts +21 -15
  70. package/template-mobile-vant-cli/src/router/routes/index.ts +46 -0
  71. package/template-mobile-vant-cli/src/router/routes/modules/dataSource.ts +32 -0
  72. package/template-mobile-vant-cli/src/services/userCenter/account.ts +42 -0
  73. package/template-mobile-vant-cli/src/services/userCenter/index.ts +28 -0
  74. package/template-mobile-vant-cli/src/store/index.ts +4 -1
  75. package/template-mobile-vant-cli/src/store/modules/global.ts +6 -13
  76. package/template-mobile-vant-cli/src/store/modules/user.ts +107 -0
  77. package/template-mobile-vant-cli/src/utils/accessToken.ts +97 -0
  78. package/template-mobile-vant-cli/src/utils/crypto/index.ts +3 -4
  79. package/template-mobile-vant-cli/src/utils/env.ts +2 -2
  80. package/template-mobile-vant-cli/src/utils/pageTitle.ts +12 -6
  81. package/template-mobile-vant-cli/src/utils/request/XHR.ts +9 -11
  82. package/template-mobile-vant-cli/src/utils/request/axiosCancel.ts +5 -5
  83. package/template-mobile-vant-cli/src/utils/request/checkStatus.ts +18 -2
  84. package/template-mobile-vant-cli/src/utils/request/index.ts +36 -23
  85. package/template-mobile-vant-cli/src/utils/storage.ts +49 -32
  86. package/template-mobile-vant-cli/src/utils/validate.ts +31 -36
  87. package/template-mobile-vant-cli/tsconfig.json +17 -9
  88. package/template-mobile-vant-cli/types/auto-imports.d.ts +18 -2
  89. package/template-mobile-vant-cli/types/components.d.ts +2 -7
  90. package/template-mobile-vant-cli/types/config.d.ts +56 -0
  91. package/template-mobile-vant-cli/types/global.d.ts +62 -21
  92. package/template-mobile-vant-cli/types/mock.d.ts +34 -0
  93. package/template-mobile-vant-cli/types/module.d.ts +33 -0
  94. package/template-mobile-vant-cli/types/response.d.ts +3 -1
  95. package/template-mobile-vant-cli/types/system.d.ts +58 -0
  96. package/template-mobile-vant-cli/types/vant-import.d.ts +16 -5
  97. package/template-mobile-vant-cli/unocss.config.ts +120 -66
  98. package/template-mobile-vant-cli/vite.config.ts +78 -81
  99. package/template-mobile-vant-cli/build/cdn.ts +0 -5
  100. package/template-mobile-vant-cli/build/plugin/html.ts +0 -26
  101. package/template-mobile-vant-cli/build/plugin/index.ts +0 -42
  102. package/template-mobile-vant-cli/build/plugin/mock.ts +0 -14
  103. package/template-mobile-vant-cli/build/plugin/viteMock/client.ts +0 -88
  104. package/template-mobile-vant-cli/build/plugin/viteMock/createMockServer.ts +0 -271
  105. package/template-mobile-vant-cli/build/plugin/viteMock/index.ts +0 -69
  106. package/template-mobile-vant-cli/build/plugin/viteMock/types.ts +0 -48
  107. package/template-mobile-vant-cli/build/plugin/viteMock/utils.ts +0 -48
  108. package/template-mobile-vant-cli/build/script/postBuild.ts +0 -14
  109. package/template-mobile-vant-cli/mock/_createProductionServer.ts +0 -19
  110. package/template-mobile-vant-cli/mock/utils.ts +0 -9
  111. package/template-mobile-vant-cli/postcss.config.cjs +0 -8
  112. package/template-mobile-vant-cli/prettier.config.cjs +0 -18
  113. package/template-mobile-vant-cli/public/js/flexible.js +0 -44
  114. package/template-mobile-vant-cli/src/core/vant-design/index.ts +0 -4
  115. package/template-mobile-vant-cli/src/design/vant.less +0 -2
  116. package/template-mobile-vant-cli/src/global.less +0 -1
  117. package/template-mobile-vant-cli/src/layout/basicLayout.less +0 -11
  118. package/template-mobile-vant-cli/src/router/routes.ts +0 -20
  119. package/template-mobile-vant-cli/src/router/typings.ts +0 -8
  120. package/template-mobile-vant-cli/src/settings/index.ts +0 -10
  121. package/template-mobile-vant-cli/src/utils/crypto/base64.ts +0 -101
  122. package/template-mobile-vant-cli/types/ant-design-import.d.ts +0 -13
  123. package/template-mobile-vant-cli/types/plugins-auto-import.d.ts +0 -14
  124. /package/template-mobile-vant-cli/{mock/datasSource/api/index.ts → src/design/vant/index.less} +0 -0
@@ -0,0 +1,46 @@
1
+ import { createMockRoute } from '../../../mock'
2
+ import { accessTokens, accounts } from '../../config/user'
3
+ import { createrToken } from '../../utils/util'
4
+
5
+ export default createMockRoute([
6
+ {
7
+ url: '/user/login',
8
+ method: 'post',
9
+ carryToken: false,
10
+ callback: ({ body }) => {
11
+ const { userName, password } = body
12
+ const accessToken = accessTokens[userName]
13
+ if (accounts[userName] !== password || !accessToken) {
14
+ return {
15
+ code: 500,
16
+ msg: '帐户或密码不正确。'
17
+ }
18
+ }
19
+ return {
20
+ code: 200,
21
+ msg: 'success',
22
+ data: {
23
+ token: createrToken(accessToken),
24
+ expiresIn: 720
25
+ }
26
+ }
27
+ }
28
+ },
29
+ {
30
+ url: '/user/register',
31
+ method: 'post',
32
+ carryToken: false,
33
+ callback: () => {
34
+ return {
35
+ code: 200,
36
+ msg: '模拟注册成功'
37
+ }
38
+ }
39
+ },
40
+ {
41
+ url: '/user/logout',
42
+ method: 'get',
43
+ timeout: 200,
44
+ callback: null
45
+ }
46
+ ])
@@ -0,0 +1,21 @@
1
+ import { Base64, isArray, isJSONStr, isObject } from '@gx-design-vue/pro-utils'
2
+
3
+ const cryptoBase64 = new Base64()
4
+
5
+ // 加密方法
6
+ export function Encrypt(word: string | object) {
7
+ let str: string
8
+ if (isObject(word) || isArray(word)) {
9
+ str = JSON.stringify(word)
10
+ } else {
11
+ str = word as string
12
+ }
13
+
14
+ return cryptoBase64.encode(str as string)
15
+ }
16
+
17
+ // 解密方法
18
+ export function Decrypt(word: string) {
19
+ const decryptedStr = cryptoBase64.decode(word)
20
+ return isJSONStr(decryptedStr) ? JSON.parse(decryptedStr) : decryptedStr
21
+ }
@@ -0,0 +1,96 @@
1
+ import { getRandomNumber } from '@gx-design-vue/pro-utils'
2
+ import dayjs from 'dayjs'
3
+ import { cloneDeep } from 'lodash-es'
4
+ import Mockjs from 'mockjs'
5
+ import { getArraryList } from './util'
6
+
7
+ export interface ListItem {
8
+ createTime: string | null;
9
+ id: number;
10
+ }
11
+
12
+ export interface ListSearchParams {
13
+ pageNum?: number;
14
+ pageSize?: number;
15
+ sord?: 'asc' | 'desc';
16
+ sidx?: 'createTime';
17
+ }
18
+
19
+ export function initContent<T>(
20
+ max,
21
+ callbackParams?: (key: number) => Omit<T, 'id' | 'createTime'> & Partial<ListItem>
22
+ ): (Omit<T, 'id' | 'createTime'> & ListItem)[] {
23
+ const mockParams = (index: number) => ({
24
+ id: index + 1,
25
+ uuid: getRandomNumber().uuid(10),
26
+ createTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
27
+ }) as any
28
+ const list: (T & ListItem)[] = getArraryList(max, index => mockParams(index))
29
+
30
+ return list.map((item, index) => {
31
+ return {
32
+ ...item,
33
+ createTime: dayjs()
34
+ .subtract(Mockjs.Random.integer(3, 60), 'day')
35
+ .subtract(Mockjs.Random.integer(2, 6), 'hour')
36
+ .subtract(Mockjs.Random.integer(1, 59), 'minute')
37
+ .subtract(Mockjs.Random.integer(1, 59), 'second')
38
+ .format('YYYY-MM-DD HH:mm:ss'),
39
+ ...callbackParams?.(index)
40
+ }
41
+ })
42
+ }
43
+
44
+ export function handlePageList<T>(
45
+ dataSource: T[],
46
+ { pageNum, pageSize, callBack }: {
47
+ pageNum: number;
48
+ pageSize: number;
49
+ callBack?: (data: T[]) => T[]
50
+ }
51
+ ): T[] {
52
+ if (callBack)
53
+ dataSource = callBack?.(dataSource)
54
+ return cloneDeep(dataSource).filter(
55
+ (_, sort) => (sort < pageNum * pageSize) && (sort >= pageSize * (pageNum - 1))
56
+ )
57
+ }
58
+
59
+ export function compareToMaxTime(obj1, obj2, key, type: 0 | 1 = 0) {
60
+ const val1 = obj1[key]
61
+ const val2 = obj2[key]
62
+ let result = 0
63
+ if (dayjs(val1).isBefore(dayjs(val2))) {
64
+ result = type === 0 ? -1 : 0
65
+ } else if (dayjs(val1).isAfter(dayjs(val2))) {
66
+ result = type === 0 ? 0 : (-1)
67
+ }
68
+ return result
69
+ }
70
+
71
+ export function postDataSource<T>(
72
+ dataSource: (Omit<T, 'id' | 'createTime'> & ListItem)[],
73
+ type: 'delete' | 'add' | 'update' = 'update',
74
+ options?: { key?: string; params: Partial<(Omit<T, 'id' | 'createTime'> & ListItem)> }
75
+ ) {
76
+ if (type === 'update') {
77
+ dataSource = dataSource.map((item: any) => {
78
+ // @ts-ignore
79
+ if (options?.params?.[options.key] === item[options?.key])
80
+ return { ...item, ...options?.params }
81
+ return item
82
+ })
83
+ }
84
+ if (type === 'add') {
85
+ dataSource.unshift({
86
+ ...options?.params as (Omit<T, 'id' | 'createTime'> & ListItem),
87
+ id: dataSource.length + 1
88
+ })
89
+ }
90
+ if (type === 'delete') {
91
+ // @ts-ignore
92
+ dataSource = dataSource.filter(item => options?.params?.[options.key] !== item[options?.key])
93
+ }
94
+
95
+ return dataSource
96
+ }
@@ -0,0 +1,91 @@
1
+ import Mockjs from 'mockjs'
2
+ import { defaultSettings } from '@gx-config'
3
+ import { deepMerge, isObject, getRandomNumber } from '@gx-design-vue/pro-utils'
4
+ import { toLower } from 'lodash-es'
5
+ import { tokenAccount, userList } from '../config/user'
6
+ import userIds from '../config/user/id'
7
+ import { Decrypt, Encrypt } from './crypto'
8
+
9
+ const { mock, token } = defaultSettings
10
+
11
+ export function handleRandomImage(width = 50, height = 50) {
12
+ return `https://picsum.photos/${width}/${height}?random=${getRandomNumber().uuid(10)}`
13
+ }
14
+
15
+ export function getMobile() {
16
+ const mobile_prefix = [ '134', '135', '136', '137', '138', '139', '150', '151',
17
+ '152', '157', '158', '159', '130', '131', '132', '155', '156', '133', '153' ]
18
+ return getMockRandowList(mobile_prefix) + Mockjs.mock(/\d{8}/)
19
+ }
20
+
21
+ export function getTokenBuUserId(token) {
22
+ return Number(Object.keys(tokenAccount).find(item => tokenAccount[item] === token))
23
+ }
24
+
25
+ export function getToken(headers: RequestHeater): string | undefined {
26
+ return headers?.[toLower(token.name)]
27
+ }
28
+
29
+ export function tokenByUserInfo(token): UserDetails {
30
+ return Decrypt(token)
31
+ }
32
+
33
+ export function createrToken(token) {
34
+ const userInfo = userList.find(item => item.user?.userId === getTokenBuUserId(token))
35
+ return Encrypt({ userId: userInfo?.user?.userId })
36
+ }
37
+
38
+ export function checkToken(token) {
39
+ if (mock.checkToken === -1) return true
40
+ if (token) {
41
+ if (mock.checkToken === 0) return true
42
+
43
+ const useInfo: UserDetails = tokenByUserInfo(token)
44
+ return useInfo ? useInfo?.userId && userIds.some(item => useInfo?.userId === item.id) : false
45
+ }
46
+ return false
47
+ }
48
+
49
+ export const checkBackDataFun = (
50
+ config: Partial<ResponseResult>,
51
+ token: string,
52
+ merageRoot?: boolean
53
+ ): ResponseResult => {
54
+ let result: Partial<ResponseResult> = {
55
+ code: 200,
56
+ data: null
57
+ }
58
+ if (isObject(config)) {
59
+ const { data } = config
60
+ if (merageRoot) {
61
+ result = deepMerge(result, config, {
62
+ omitEmpty: false,
63
+ omitNil: false
64
+ })
65
+ } else {
66
+ result.data = config
67
+ }
68
+ if (data) {
69
+ result.data = data
70
+ }
71
+ } else {
72
+ result.data = config as any
73
+ }
74
+
75
+ const invaiteToken = checkToken(token)
76
+
77
+ return deepMerge<ResponseResult>(result as unknown as ResponseResult, {
78
+ code: invaiteToken ? 200 : 401,
79
+ message: invaiteToken
80
+ ? (result.message || result.code) ? 'success' : 'Request failed'
81
+ : 'Invalid token!'
82
+ })
83
+ }
84
+
85
+ export function getArraryList<T>(length: number, callback: (key: number) => T) {
86
+ return Array.from({ length }).map((_, key) => callback(key))
87
+ }
88
+
89
+ export function getMockRandowList<T = any>(data: T[]) {
90
+ return data[Mockjs.Random.integer(0, data.length - 1)] as T
91
+ }
@@ -1,57 +1,74 @@
1
1
  {
2
- "name": "gx-mobile-cli",
2
+ "name": "gx-vant-mobile",
3
3
  "version": "0.0.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
- "dev": "vite",
6
+ "bootstrap": "pnpm i",
7
+ "dev": "pnpm run start:dev",
8
+ "start:dev": "cross-env VITE_APP_ENV=dev vite",
7
9
  "start:pro": "cross-env VITE_APP_ENV=pro vite",
8
10
  "build": "vite build",
9
11
  "build:pro": "vite build --mode pro",
10
- "preview": "vite preview"
12
+ "report": "cross-env REPORT=true npm run build",
13
+ "preview": "vite preview",
14
+ "clean:lib": "rimraf pnpm-lock.yaml && rimraf node_modules",
15
+ "lint": "eslint .",
16
+ "lint:fix": "eslint . --fix"
11
17
  },
12
18
  "dependencies": {
13
- "@gx-design-vue/pro-hooks": "^0.2.0-beta.20",
14
- "@gx-design-vue/pro-utils": "^0.2.0-beta.28",
15
- "@vueuse/core": "^10.7.2",
16
- "@vueuse/shared": "^10.7.2",
19
+ "@gx-design-vue/pro-hooks": "^0.2.0-beta.43",
20
+ "@gx-design-vue/pro-utils": "^0.2.0-beta.61",
21
+ "@multiavatar/multiavatar": "^1.0.7",
22
+ "@vueuse/core": "^12.0.0",
23
+ "@vueuse/shared": "^12.0.0",
17
24
  "axios": "^1.6.7",
18
25
  "crypto-js": "^4.1.1",
19
- "dayjs": "^1.11.6",
26
+ "dayjs": "^1.11.13",
20
27
  "lodash-es": "^4.17.21",
21
- "pinia": "2.1.7",
28
+ "pinia": "^2.2.6",
22
29
  "qs": "^6.11.0",
23
- "vant": "^4.8.8",
24
- "unocss": "^0.58.5",
25
- "vue": "^3.5.0",
26
- "vue-router": "^4.1.6"
30
+ "unocss": "^0.65.1",
31
+ "vant": "^4.9.15",
32
+ "vue": "^3.5.13",
33
+ "vue-router": "^4.5.0"
27
34
  },
28
35
  "devDependencies": {
29
- "@antfu/eslint-config": "^2.9.0",
30
- "@types/lodash-es": "^4.17.4",
31
- "@types/node": "^20.11.19",
32
- "@typescript-eslint/eslint-plugin": "^5.20.0",
33
- "@typescript-eslint/parser": "^5.20.0",
34
- "@vitejs/plugin-vue": "^5.0.4",
35
- "@vitejs/plugin-vue-jsx": "^3.1.0",
36
- "autoprefixer": "^10.4.13",
36
+ "@antfu/eslint-config": "^3.11.2",
37
+ "@types/mockjs": "^1.0.10",
38
+ "@commitlint/cli": "^19.5.0",
39
+ "@commitlint/config-conventional": "^19.5.0",
40
+ "@iconify-json/carbon": "^1.2.5",
41
+ "@types/lodash-es": "^4.17.10",
42
+ "@types/node": "^22.8.4",
43
+ "@types/qs": "^6.9.7",
44
+ "@unocss/preset-rem-to-px": "^0.65.3",
45
+ "@vant/auto-import-resolver": "^1.2.1",
46
+ "@vitejs/plugin-legacy": "^6.0.0",
47
+ "@vitejs/plugin-vue": "^5.2.1",
48
+ "@vitejs/plugin-vue-jsx": "^4.1.1",
37
49
  "mockjs": "^1.1.0",
50
+ "autoprefixer": "^10.4.5",
51
+ "bundle-require": "^5.0.0",
38
52
  "cross-env": "^7.0.3",
39
- "connect": "^3.7.0",
40
- "path-to-regexp": "^6.2.1",
41
- "bundle-require": "^4.0.1",
53
+ "husky": "^9.1.6",
42
54
  "less": "^4.1.3",
43
- "less-loader": "^11.1.0",
44
- "postcss": "^8.4.18",
45
- "postcss-html": "^1.5.0",
55
+ "postcss": "^8.4.35",
56
+ "postcss-html": "^1.6.0",
46
57
  "postcss-less": "^6.0.0",
58
+ "postcss-mobile-forever": "^4.3.1",
47
59
  "postcss-pxtorem": "^6.0.0",
48
- "prettier": "^2.7.1",
60
+ "prettier": "^3.3.3",
61
+ "rimraf": "^6.0.1",
62
+ "rollup-plugin-external-globals": "^0.13.0",
63
+ "rollup-plugin-visualizer": "^5.12.0",
49
64
  "typescript": "^5.3.3",
50
- "unplugin-auto-import": "^0.11.4",
51
- "unplugin-vue-components": "^0.22.9",
52
- "vite": "^5.1.4",
53
- "vite-plugin-html": "^3.2.0",
54
- "vite-plugin-vue-setup-extend": "^0.4.0",
55
- "vue-tsc": "^1.8.27"
65
+ "unplugin-auto-import": "^0.19.0",
66
+ "unplugin-turbo-console": "^1.10.4",
67
+ "unplugin-vue-components": "^0.28.0",
68
+ "vite": "^6.0.3",
69
+ "vite-plugin-compression": "0.5.1",
70
+ "vite-plugin-fake-server": "^2.1.4",
71
+ "vite-plugin-html": "^3.2.2",
72
+ "vue-tsc": "^2.1.6"
56
73
  }
57
74
  }
@@ -0,0 +1,54 @@
1
+ :root {
2
+ --van-base-font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Segoe UI, Arial, Roboto, "PingFang SC", "miui", "Hiragino Sans GB", "Microsoft Yahei", sans-serif;
3
+ }
4
+
5
+ body {
6
+ font-family: var(--van-base-font);
7
+ }
8
+
9
+ .gx-toast-loading {
10
+ position: fixed;
11
+ top: 0;
12
+ left: 0;
13
+ width: 100%;
14
+ height: 100%;
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ text-align: center;
19
+ z-index: 9999999999;
20
+ }
21
+ .gx-toast-loading .gx-toast-loading-cont {
22
+ display: flex;
23
+ flex-direction: column;
24
+ justify-content: center;
25
+ align-items: center;
26
+ box-sizing: content-box;
27
+ width: min(23.467vw, 140.8px);
28
+ min-height: min(23.467vw, 140.8px);
29
+ max-width: 70%;
30
+ padding: min(4.267vw, 25.6px);
31
+ border-radius: min(2.133vw, 12.8px);
32
+ background-clip: padding-box;
33
+ color: #fff;
34
+ background-color: rgba(58, 58, 58, 0.9);
35
+ font-size: min(3.733vw, 22.4px);
36
+ line-height: min(5.333vw, 32px);
37
+ }
38
+ .gx-toast-loading .gx-toast-loading-cont .gx-toast-svg {
39
+ margin: 0;
40
+ width: min(8vw, 48px);
41
+ height: min(8vw, 48px);
42
+ display: inline-block;
43
+ animation: spinner-anime 1s linear infinite;
44
+ }
45
+ .gx-toast-loading .gx-toast-loading-cont .gx-toast-svg-text {
46
+ display: inline-block;
47
+ margin-top: min(2.133vw, 12.8px);
48
+ }
49
+
50
+ @keyframes spinner-anime {
51
+ 100% {
52
+ transform: rotate(360deg);
53
+ }
54
+ }
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <div id="gx-pro-mobile">
2
+ <van-config-provider>
3
3
  <router-view />
4
- </div>
4
+ </van-config-provider>
5
5
  </template>
6
+
7
+ <style lang="less">
8
+ </style>
9
+
@@ -6,7 +6,7 @@ import 'vant/es/skeleton/style'
6
6
 
7
7
  const Proskeleton: FunctionalComponent<{ line: number; loading: boolean }> = (props, { slots }) => {
8
8
  const renderMapItem = () => {
9
- const show = []
9
+ const show: any[] = []
10
10
  for (let i = 0; i < props.line; i += 1) {
11
11
  show.push(
12
12
  <div class={styles.skeletonItem}>
@@ -1,8 +1,13 @@
1
- import { defineComponent, toRefs, watch } from 'vue'
1
+ import type { SetLoadingParams } from '@gx-mobile/hooks/web/usePageLoading'
2
+ import type { NavBarProps } from 'vant'
3
+ import { classNames, getSlot, getSlotVNode, isFunction, VueNode, WithFalse } from '@gx-design-vue/pro-utils'
2
4
  import { usePageLoading } from '@gx-mobile/hooks/web'
5
+ import { useScroll } from '@vueuse/core'
6
+ import { Icon, NavBar } from 'vant'
7
+ import { defineComponent, ref, type SlotsType, Teleport, toRefs, watch } from 'vue'
3
8
  import ProSkeleton from './ProSkeleton'
4
9
  import styles from './style.module.less'
5
- import type { SetLoadingParams } from '@gx-mobile/hooks/web/usePageLoading'
10
+ import 'vant/es/nav-bar/style'
6
11
 
7
12
  export type PageLoadingTpe = 'toast' | 'skeleton'
8
13
 
@@ -11,10 +16,32 @@ type ChangeLoadingParams<T> = Omit<SetLoadingParams<T>, 'type'> & {
11
16
  }
12
17
 
13
18
  const PageContainer = defineComponent({
14
- name: 'GProPageContainer',
19
+ name: 'GPageContainer',
15
20
  inheritAttrs: false,
16
21
  props: {
17
- loading: Boolean as VuePropType<boolean>,
22
+ loading: {
23
+ type: Boolean as VuePropType<boolean>,
24
+ default: false
25
+ },
26
+ nav: {
27
+ type: [ Boolean, Function, Object, Array ] as VuePropType<WithFalse<VueNode>>,
28
+ default: false
29
+ },
30
+ navProps: Object as VuePropType<NavBarProps>,
31
+ backTop: {
32
+ type: [ Boolean, Function, Object, Array ] as VuePropType<WithFalse<VueNode>>,
33
+ default: false
34
+ },
35
+ wrapperClass: String as VuePropType<string>,
36
+ backTopProps: {
37
+ type: Object as VuePropType<{
38
+ style: CSSProperties;
39
+ count: number;
40
+ }>,
41
+ default: () => ({
42
+ count: 300
43
+ })
44
+ },
18
45
  hiddenSlot: {
19
46
  type: Boolean as VuePropType<boolean>,
20
47
  default: true
@@ -27,19 +54,37 @@ const PageContainer = defineComponent({
27
54
  type: String as VuePropType<PageLoadingTpe>,
28
55
  default: 'toast'
29
56
  },
30
- bgcolor: {
57
+ bgColor: {
31
58
  type: String as VuePropType<string>,
32
- default: '#fafafa'
33
- }
59
+ default: 'var(--van-gray-1)'
60
+ },
61
+ onNavClickLeft: Function as VuePropType<() => void>,
62
+ 'onUpdate:loading': Function as VuePropType<(val: boolean) => void>,
63
+ onScroll: Function as VuePropType<(value: number) => void>
34
64
  },
35
- emits: [ 'update:loading' ],
36
- setup(props, { slots, expose, emit }) {
65
+ slots: Object as SlotsType<{
66
+ default(): void
67
+ backTop(): void
68
+ nav(props: NavBarProps): void
69
+ }>,
70
+ emits: [ 'update:loading', 'scroll', 'navClickLeft' ],
71
+ setup(props, { attrs, slots, expose, emit }) {
72
+ const route = useRoute() as unknown as AppRouteModule
73
+ const router = useRouter()
37
74
  const { loading: loadingRef, loadingType, loadingMsg, hiddenSlot } = toRefs(props)
38
75
 
76
+ const backTopEl = ref()
77
+ const viewScrollRoot = ref()
39
78
  const initStatus = ref(true)
40
-
79
+ const showBackTop = ref(false)
41
80
  const hiddenSlotRef = ref(props.hiddenSlot)
42
81
 
82
+ const navTitle = computed(() => route.meta?.name ?? route.meta?.title as string)
83
+
84
+ const { y } = useScroll(viewScrollRoot, {
85
+ behavior: 'smooth'
86
+ })
87
+
43
88
  const [ loading, setLoading ] = usePageLoading({
44
89
  defaultType: loadingType.value,
45
90
  defaultMessage: loadingMsg.value,
@@ -47,8 +92,7 @@ const PageContainer = defineComponent({
47
92
  })
48
93
 
49
94
  watch(() => loading.value, (val) => {
50
- if (initStatus.value && val)
51
- initStatus.value = false
95
+ if (initStatus.value && val) initStatus.value = false
52
96
  emit('update:loading', val)
53
97
  }, {
54
98
  deep: true,
@@ -77,25 +121,62 @@ const PageContainer = defineComponent({
77
121
  immediate: true
78
122
  })
79
123
 
124
+ watch(() => y.value, (val) => {
125
+ showBackTop.value = val > props.backTopProps?.count
126
+ props.onScroll?.(val)
127
+ })
128
+
129
+ onMounted(() => {
130
+ viewScrollRoot.value = document.querySelector('#basic-layout-content')
131
+ backTopEl.value = document.querySelector('#basic-layout-back-top')
132
+ })
133
+
80
134
  const changeLoading = ({
81
135
  value,
82
136
  message,
83
137
  hiddenSlot
84
138
  }: ChangeLoadingParams<boolean>) => {
85
139
  if (loadingType.value === 'toast') {
86
- hiddenSlotRef.value = hiddenSlot
140
+ hiddenSlotRef.value = !!hiddenSlot
87
141
  setLoading({ value, message, type: loadingType.value })
88
142
  }
89
143
  }
90
144
 
145
+ function navClickLeft() {
146
+ if (props.onNavClickLeft) {
147
+ props.onNavClickLeft()
148
+ } else {
149
+ router.back()
150
+ }
151
+ }
152
+
91
153
  expose({
92
- toggleLoading: changeLoading
154
+ toggleLoading: changeLoading,
155
+ setScrollTop: (val: number) => y.value = val
93
156
  })
94
157
 
95
158
  return () => {
159
+ const navProps = {
160
+ fixed: true,
161
+ placeholder: true,
162
+ leftArrow: true,
163
+ title: navTitle.value,
164
+ ...(props.navProps || {})
165
+ } as NavBarProps
166
+ const navSlot = getSlot(slots, props, 'nav')
167
+ const backTopRender = getSlotVNode(slots, props, 'backTop')
96
168
  return (
97
- <div class={styles.pageContainer} style={{ backgroundColor: props.bgcolor }}>
98
- <div class={styles.pageContainerWrapper}>
169
+ <div class={styles.pageContainer} style={{ backgroundColor: props.bgColor, ...(attrs?.style as any || {}) }}>
170
+ {props.nav !== false && (
171
+ <>
172
+ {isFunction(navSlot)
173
+ ? navSlot?.({ ...navProps })
174
+ : (
175
+ <NavBar{...navProps} onClickLeft={() => navClickLeft()} />
176
+ )}
177
+ </>
178
+ )}
179
+ <div class={classNames(styles.pageContainerWrapper, props.wrapperClass || '')}>
99
180
  {
100
181
  loadingType.value === 'skeleton'
101
182
  ? (
@@ -106,6 +187,17 @@ const PageContainer = defineComponent({
106
187
  : ((!loading.value || !hiddenSlotRef.value) && <>{slots.default?.()}</>)
107
188
  }
108
189
  </div>
190
+ {
191
+ !!backTopEl.value && showBackTop.value && props.backTop !== false && (
192
+ <Teleport to="#basic-layout-back-top">
193
+ {backTopRender || (
194
+ <div class={styles.pageBackTop} onClick={() => y.value = 0} style={props.backTopProps?.style}>
195
+ <Icon name="back-top" class="relative top-1.5px" />
196
+ </div>
197
+ )}
198
+ </Teleport>
199
+ )
200
+ }
109
201
  </div>
110
202
  )
111
203
  }
@@ -1,8 +1,7 @@
1
1
  .pageContainer {
2
2
  width: 100%;
3
- min-height: 100vh;
3
+ min-height: calc(100vh - var(--van-tabbar-height));
4
4
  padding: 15px;
5
- background: var(--van-background-3);
6
5
 
7
6
  .pageContainerWrapper {
8
7
  position: relative;
@@ -12,3 +11,7 @@
12
11
  margin-top: 50px;
13
12
  }
14
13
  }
14
+
15
+ .pageBackTop {
16
+ --at-apply: rd-50\% overflow-hidden flex-center bg-[#4187f2] text-20px text-[#fff] w-45px h-45px right-20px bottom-60px absolute z-100;
17
+ }