@lvetechs/create-app 1.0.3 → 1.0.5

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 (59) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +18 -4
  3. package/templates/react/.env +3 -0
  4. package/templates/react/.env.development +3 -0
  5. package/templates/react/.env.production +3 -0
  6. package/templates/react/index.html +1 -1
  7. package/templates/react/package.json +45 -45
  8. package/templates/react/pnpm-lock.yaml +166 -5
  9. package/templates/react/src/hooks/useForm.ts +77 -0
  10. package/templates/react/src/layouts/DefaultLayout.tsx +6 -1
  11. package/templates/react/src/layouts/menuConfig.ts +3 -33
  12. package/templates/react/src/main.tsx +3 -0
  13. package/templates/react/src/router/index.tsx +0 -39
  14. package/templates/react/src/stores/app.ts +141 -3
  15. package/templates/react/src/stores/notification.ts +128 -0
  16. package/templates/react/src/stores/permission.ts +183 -0
  17. package/templates/react/src/stores/user.ts +151 -4
  18. package/templates/react/src/views/home/index.tsx +205 -43
  19. package/templates/react/src/views/system/user/index.tsx +171 -5
  20. package/templates/react/tsconfig.json +1 -1
  21. package/templates/react/vite.config.ts +7 -3
  22. package/templates/vue/.env +2 -2
  23. package/templates/vue/.env.development +2 -2
  24. package/templates/vue/.env.production +2 -2
  25. package/templates/vue/index.html +1 -1
  26. package/templates/vue/package.json +0 -1
  27. package/templates/vue/pnpm-lock.yaml +3307 -3307
  28. package/templates/vue/src/auto-imports.d.ts +5 -0
  29. package/templates/vue/src/layouts/DefaultLayout.vue +2 -3
  30. package/templates/vue/src/layouts/menuConfig.ts +3 -33
  31. package/templates/vue/src/router/index.ts +4 -89
  32. package/templates/vue/src/stores/app.ts +133 -2
  33. package/templates/vue/src/stores/notification.ts +172 -0
  34. package/templates/vue/src/stores/permission.ts +184 -0
  35. package/templates/vue/src/stores/user.ts +109 -2
  36. package/templates/vue/src/views/home/index.vue +8 -8
  37. package/templates/react/_gitignore +0 -25
  38. package/templates/react/src/views/about/index.tsx +0 -40
  39. package/templates/react/src/views/login/index.tsx +0 -138
  40. package/templates/react/src/views/register/index.tsx +0 -143
  41. package/templates/react/src/views/result/fail.tsx +0 -39
  42. package/templates/react/src/views/result/success.tsx +0 -35
  43. package/templates/react/src/views/screen/index.tsx +0 -120
  44. package/templates/react/src/views/system/log/login.tsx +0 -51
  45. package/templates/react/src/views/system/log/operation.tsx +0 -47
  46. package/templates/react/src/views/system/menu/index.tsx +0 -62
  47. package/templates/react/src/views/system/role/index.tsx +0 -63
  48. package/templates/react/tsconfig.node.json +0 -11
  49. package/templates/vue/_gitignore +0 -25
  50. package/templates/vue/src/views/about/index.vue +0 -67
  51. package/templates/vue/src/views/login/index.vue +0 -153
  52. package/templates/vue/src/views/register/index.vue +0 -169
  53. package/templates/vue/src/views/result/fail.vue +0 -92
  54. package/templates/vue/src/views/result/success.vue +0 -92
  55. package/templates/vue/src/views/screen/index.vue +0 -150
  56. package/templates/vue/src/views/system/log/login.vue +0 -51
  57. package/templates/vue/src/views/system/log/operation.vue +0 -47
  58. package/templates/vue/src/views/system/menu/index.vue +0 -58
  59. package/templates/vue/src/views/system/role/index.vue +0 -59
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvetechs/create-app",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "快速创建 Vue 3 / React 18 项目的脚手架工具",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -257,10 +257,24 @@ async function init() {
257
257
  const displayName = targetDir // 用户输入的项目名作为显示名
258
258
  const shortName = displayName.charAt(0).toUpperCase() // Logo 折叠时显示首字母
259
259
 
260
- replaceInFiles(root, {
261
- '{{PROJECT_NAME}}': displayName,
262
- '{{PROJECT_SHORT}}': shortName
263
- })
260
+ // replaceInFiles(root, {
261
+ // '{{PROJECT_NAME}}': displayName,
262
+ // '{{PROJECT_SHORT}}': shortName
263
+ // })
264
+
265
+ // 同时替换所有 .env* 文件
266
+ const envFiles = ['.env', '.env.development', '.env.production']
267
+ envFiles.forEach(envFile => {
268
+ const envPath = path.join(root, envFile)
269
+ if (fs.existsSync(envPath)) {
270
+ let content = fs.readFileSync(envPath, 'utf-8')
271
+ content = content.replace(
272
+ /VITE_APP_TITLE=.*/,
273
+ `VITE_APP_TITLE=${displayName}`
274
+ )
275
+ fs.writeFileSync(envPath, content)
276
+ }
277
+ })
264
278
 
265
279
  // 输出完成信息
266
280
  const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
@@ -0,0 +1,3 @@
1
+ # 基础环境变量
2
+ VITE_APP_TITLE=My React App
3
+ VITE_APP_BASE_API=/api
@@ -0,0 +1,3 @@
1
+ # 开发环境
2
+ VITE_APP_TITLE=My React App (Dev)
3
+ VITE_APP_BASE_API=/api
@@ -0,0 +1,3 @@
1
+ # 生产环境
2
+ VITE_APP_TITLE=My React App
3
+ VITE_APP_BASE_API=https://api.example.com
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>{{PROJECT_NAME}}</title>
7
+ <title>%VITE_APP_TITLE%</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="root"></div>
@@ -1,45 +1,45 @@
1
- {
2
- "name": "my-react-app",
3
- "private": true,
4
- "version": "0.1.0",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite",
8
- "build": "tsc -b && vite build",
9
- "preview": "vite preview",
10
- "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
11
- "format": "prettier --write src/"
12
- },
13
- "dependencies": {
14
- "react": "^18.3.1",
15
- "react-dom": "^18.3.1",
16
- "react-router-dom": "^6.23.0",
17
- "zustand": "^4.5.2",
18
- "axios": "^1.6.8",
19
- "nprogress": "^0.2.0",
20
- "dayjs": "^1.11.10",
21
- "clsx": "^2.1.0"
22
- },
23
- "devDependencies": {
24
- "@vitejs/plugin-react": "^4.2.1",
25
- "vite": "^5.2.0",
26
- "typescript": "^5.4.3",
27
- "@types/react": "^18.3.1",
28
- "@types/react-dom": "^18.3.0",
29
- "@types/nprogress": "^0.2.3",
30
- "sass": "^1.72.0",
31
- "tailwindcss": "^3.4.3",
32
- "postcss": "^8.4.38",
33
- "autoprefixer": "^10.4.19",
34
- "eslint": "^8.57.0",
35
- "eslint-plugin-react-hooks": "^4.6.0",
36
- "eslint-plugin-react-refresh": "^0.4.6",
37
- "@typescript-eslint/eslint-plugin": "^7.3.1",
38
- "@typescript-eslint/parser": "^7.3.1",
39
- "prettier": "^3.2.5",
40
- "prettier-plugin-tailwindcss": "^0.5.12",
41
- "eslint-config-prettier": "^9.1.0",
42
- "eslint-plugin-prettier": "^5.1.3"
43
- }
44
- }
45
-
1
+ {
2
+ "name": "my-react-app",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "tsc -b && vite build",
8
+ "preview": "vite preview",
9
+ "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
10
+ "format": "prettier --write src/"
11
+ },
12
+ "dependencies": {
13
+ "axios": "^1.6.8",
14
+ "clsx": "^2.1.0",
15
+ "dayjs": "^1.11.10",
16
+ "nprogress": "^0.2.0",
17
+ "react": "^18.3.1",
18
+ "react-dom": "^18.3.1",
19
+ "react-router-dom": "^6.23.0",
20
+ "zustand": "^4.5.2"
21
+ },
22
+ "devDependencies": {
23
+ "@lvetechs/ui-lib": "^1.1.7",
24
+ "@types/node": "^25.2.3",
25
+ "@types/nprogress": "^0.2.3",
26
+ "@types/react": "^18.3.1",
27
+ "@types/react-dom": "^18.3.0",
28
+ "@typescript-eslint/eslint-plugin": "^7.3.1",
29
+ "@typescript-eslint/parser": "^7.3.1",
30
+ "@vitejs/plugin-react": "^4.2.1",
31
+ "autoprefixer": "^10.4.19",
32
+ "eslint": "^8.57.0",
33
+ "eslint-config-prettier": "^9.1.0",
34
+ "eslint-plugin-prettier": "^5.1.3",
35
+ "eslint-plugin-react-hooks": "^4.6.0",
36
+ "eslint-plugin-react-refresh": "^0.4.6",
37
+ "postcss": "^8.4.38",
38
+ "prettier": "^3.2.5",
39
+ "prettier-plugin-tailwindcss": "^0.5.12",
40
+ "sass": "^1.72.0",
41
+ "tailwindcss": "^3.4.3",
42
+ "typescript": "^5.4.3",
43
+ "vite": "^5.2.0"
44
+ }
45
+ }
@@ -33,6 +33,12 @@ importers:
33
33
  specifier: ^4.5.2
34
34
  version: 4.5.7(@types/react@18.3.28)(react@18.3.1)
35
35
  devDependencies:
36
+ '@lvetechs/ui-lib':
37
+ specifier: ^1.1.7
38
+ version: 1.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.28(typescript@5.9.3))
39
+ '@types/node':
40
+ specifier: ^25.2.3
41
+ version: 25.2.3
36
42
  '@types/nprogress':
37
43
  specifier: ^0.2.3
38
44
  version: 0.2.3
@@ -50,7 +56,7 @@ importers:
50
56
  version: 7.18.0(eslint@8.57.1)(typescript@5.9.3)
51
57
  '@vitejs/plugin-react':
52
58
  specifier: ^4.2.1
53
- version: 4.7.0(vite@5.4.21(sass@1.97.3))
59
+ version: 4.7.0(vite@5.4.21(@types/node@25.2.3)(sass@1.97.3))
54
60
  autoprefixer:
55
61
  specifier: ^10.4.19
56
62
  version: 10.4.24(postcss@8.5.6)
@@ -89,7 +95,7 @@ importers:
89
95
  version: 5.9.3
90
96
  vite:
91
97
  specifier: ^5.2.0
92
- version: 5.4.21(sass@1.97.3)
98
+ version: 5.4.21(@types/node@25.2.3)(sass@1.97.3)
93
99
 
94
100
  packages:
95
101
 
@@ -365,6 +371,13 @@ packages:
365
371
  '@jridgewell/trace-mapping@0.3.31':
366
372
  resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
367
373
 
374
+ '@lvetechs/ui-lib@1.1.7':
375
+ resolution: {integrity: sha512-BH3QmLcLxK9A7C5mAs/pLovO9ZJ2MBlxjJhdMCElxMn935OQ0TXhrVmHI39asST5xAmTNeSyDMXLVuS3eNuu6w==}
376
+ peerDependencies:
377
+ react: ^18.0.0
378
+ react-dom: ^18.0.0
379
+ vue: ^3.0.0
380
+
368
381
  '@nodelib/fs.scandir@2.1.5':
369
382
  resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
370
383
  engines: {node: '>= 8'}
@@ -610,6 +623,9 @@ packages:
610
623
  '@types/estree@1.0.8':
611
624
  resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
612
625
 
626
+ '@types/node@25.2.3':
627
+ resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==}
628
+
613
629
  '@types/nprogress@0.2.3':
614
630
  resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
615
631
 
@@ -691,6 +707,35 @@ packages:
691
707
  peerDependencies:
692
708
  vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
693
709
 
710
+ '@vue/compiler-core@3.5.28':
711
+ resolution: {integrity: sha512-kviccYxTgoE8n6OCw96BNdYlBg2GOWfBuOW4Vqwrt7mSKWKwFVvI8egdTltqRgITGPsTFYtKYfxIG8ptX2PJHQ==}
712
+
713
+ '@vue/compiler-dom@3.5.28':
714
+ resolution: {integrity: sha512-/1ZepxAb159jKR1btkefDP+J2xuWL5V3WtleRmxaT+K2Aqiek/Ab/+Ebrw2pPj0sdHO8ViAyyJWfhXXOP/+LQA==}
715
+
716
+ '@vue/compiler-sfc@3.5.28':
717
+ resolution: {integrity: sha512-6TnKMiNkd6u6VeVDhZn/07KhEZuBSn43Wd2No5zaP5s3xm8IqFTHBj84HJah4UepSUJTro5SoqqlOY22FKY96g==}
718
+
719
+ '@vue/compiler-ssr@3.5.28':
720
+ resolution: {integrity: sha512-JCq//9w1qmC6UGLWJX7RXzrGpKkroubey/ZFqTpvEIDJEKGgntuDMqkuWiZvzTzTA5h2qZvFBFHY7fAAa9475g==}
721
+
722
+ '@vue/reactivity@3.5.28':
723
+ resolution: {integrity: sha512-gr5hEsxvn+RNyu9/9o1WtdYdwDjg5FgjUSBEkZWqgTKlo/fvwZ2+8W6AfKsc9YN2k/+iHYdS9vZYAhpi10kNaw==}
724
+
725
+ '@vue/runtime-core@3.5.28':
726
+ resolution: {integrity: sha512-POVHTdbgnrBBIpnbYU4y7pOMNlPn2QVxVzkvEA2pEgvzbelQq4ZOUxbp2oiyo+BOtiYlm8Q44wShHJoBvDPAjQ==}
727
+
728
+ '@vue/runtime-dom@3.5.28':
729
+ resolution: {integrity: sha512-4SXxSF8SXYMuhAIkT+eBRqOkWEfPu6nhccrzrkioA6l0boiq7sp18HCOov9qWJA5HML61kW8p/cB4MmBiG9dSA==}
730
+
731
+ '@vue/server-renderer@3.5.28':
732
+ resolution: {integrity: sha512-pf+5ECKGj8fX95bNincbzJ6yp6nyzuLDhYZCeFxUNp8EBrQpPpQaLX3nNCp49+UbgbPun3CeVE+5CXVV1Xydfg==}
733
+ peerDependencies:
734
+ vue: 3.5.28
735
+
736
+ '@vue/shared@3.5.28':
737
+ resolution: {integrity: sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ==}
738
+
694
739
  acorn-jsx@5.3.2:
695
740
  resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
696
741
  peerDependencies:
@@ -876,6 +921,10 @@ packages:
876
921
  electron-to-chromium@1.5.286:
877
922
  resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==}
878
923
 
924
+ entities@7.0.1:
925
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
926
+ engines: {node: '>=0.12'}
927
+
879
928
  es-define-property@1.0.1:
880
929
  resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
881
930
  engines: {node: '>= 0.4'}
@@ -966,6 +1015,9 @@ packages:
966
1015
  resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
967
1016
  engines: {node: '>=4.0'}
968
1017
 
1018
+ estree-walker@2.0.2:
1019
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1020
+
969
1021
  esutils@2.0.3:
970
1022
  resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
971
1023
  engines: {node: '>=0.10.0'}
@@ -1206,6 +1258,14 @@ packages:
1206
1258
  lru-cache@5.1.1:
1207
1259
  resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
1208
1260
 
1261
+ lucide-react@0.563.0:
1262
+ resolution: {integrity: sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==}
1263
+ peerDependencies:
1264
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
1265
+
1266
+ magic-string@0.30.21:
1267
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
1268
+
1209
1269
  math-intrinsics@1.1.0:
1210
1270
  resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
1211
1271
  engines: {node: '>= 0.4'}
@@ -1613,6 +1673,9 @@ packages:
1613
1673
  engines: {node: '>=14.17'}
1614
1674
  hasBin: true
1615
1675
 
1676
+ undici-types@7.16.0:
1677
+ resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
1678
+
1616
1679
  update-browserslist-db@1.2.3:
1617
1680
  resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
1618
1681
  hasBin: true
@@ -1661,6 +1724,14 @@ packages:
1661
1724
  terser:
1662
1725
  optional: true
1663
1726
 
1727
+ vue@3.5.28:
1728
+ resolution: {integrity: sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg==}
1729
+ peerDependencies:
1730
+ typescript: '*'
1731
+ peerDependenciesMeta:
1732
+ typescript:
1733
+ optional: true
1734
+
1664
1735
  which@2.0.2:
1665
1736
  resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1666
1737
  engines: {node: '>= 8'}
@@ -1934,6 +2005,13 @@ snapshots:
1934
2005
  '@jridgewell/resolve-uri': 3.1.2
1935
2006
  '@jridgewell/sourcemap-codec': 1.5.5
1936
2007
 
2008
+ '@lvetechs/ui-lib@1.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.28(typescript@5.9.3))':
2009
+ dependencies:
2010
+ lucide-react: 0.563.0(react@18.3.1)
2011
+ react: 18.3.1
2012
+ react-dom: 18.3.1(react@18.3.1)
2013
+ vue: 3.5.28(typescript@5.9.3)
2014
+
1937
2015
  '@nodelib/fs.scandir@2.1.5':
1938
2016
  dependencies:
1939
2017
  '@nodelib/fs.stat': 2.0.5
@@ -2111,6 +2189,10 @@ snapshots:
2111
2189
 
2112
2190
  '@types/estree@1.0.8': {}
2113
2191
 
2192
+ '@types/node@25.2.3':
2193
+ dependencies:
2194
+ undici-types: 7.16.0
2195
+
2114
2196
  '@types/nprogress@0.2.3': {}
2115
2197
 
2116
2198
  '@types/prop-types@15.7.15': {}
@@ -2207,7 +2289,7 @@ snapshots:
2207
2289
 
2208
2290
  '@ungap/structured-clone@1.3.0': {}
2209
2291
 
2210
- '@vitejs/plugin-react@4.7.0(vite@5.4.21(sass@1.97.3))':
2292
+ '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.2.3)(sass@1.97.3))':
2211
2293
  dependencies:
2212
2294
  '@babel/core': 7.29.0
2213
2295
  '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
@@ -2215,10 +2297,64 @@ snapshots:
2215
2297
  '@rolldown/pluginutils': 1.0.0-beta.27
2216
2298
  '@types/babel__core': 7.20.5
2217
2299
  react-refresh: 0.17.0
2218
- vite: 5.4.21(sass@1.97.3)
2300
+ vite: 5.4.21(@types/node@25.2.3)(sass@1.97.3)
2219
2301
  transitivePeerDependencies:
2220
2302
  - supports-color
2221
2303
 
2304
+ '@vue/compiler-core@3.5.28':
2305
+ dependencies:
2306
+ '@babel/parser': 7.29.0
2307
+ '@vue/shared': 3.5.28
2308
+ entities: 7.0.1
2309
+ estree-walker: 2.0.2
2310
+ source-map-js: 1.2.1
2311
+
2312
+ '@vue/compiler-dom@3.5.28':
2313
+ dependencies:
2314
+ '@vue/compiler-core': 3.5.28
2315
+ '@vue/shared': 3.5.28
2316
+
2317
+ '@vue/compiler-sfc@3.5.28':
2318
+ dependencies:
2319
+ '@babel/parser': 7.29.0
2320
+ '@vue/compiler-core': 3.5.28
2321
+ '@vue/compiler-dom': 3.5.28
2322
+ '@vue/compiler-ssr': 3.5.28
2323
+ '@vue/shared': 3.5.28
2324
+ estree-walker: 2.0.2
2325
+ magic-string: 0.30.21
2326
+ postcss: 8.5.6
2327
+ source-map-js: 1.2.1
2328
+
2329
+ '@vue/compiler-ssr@3.5.28':
2330
+ dependencies:
2331
+ '@vue/compiler-dom': 3.5.28
2332
+ '@vue/shared': 3.5.28
2333
+
2334
+ '@vue/reactivity@3.5.28':
2335
+ dependencies:
2336
+ '@vue/shared': 3.5.28
2337
+
2338
+ '@vue/runtime-core@3.5.28':
2339
+ dependencies:
2340
+ '@vue/reactivity': 3.5.28
2341
+ '@vue/shared': 3.5.28
2342
+
2343
+ '@vue/runtime-dom@3.5.28':
2344
+ dependencies:
2345
+ '@vue/reactivity': 3.5.28
2346
+ '@vue/runtime-core': 3.5.28
2347
+ '@vue/shared': 3.5.28
2348
+ csstype: 3.2.3
2349
+
2350
+ '@vue/server-renderer@3.5.28(vue@3.5.28(typescript@5.9.3))':
2351
+ dependencies:
2352
+ '@vue/compiler-ssr': 3.5.28
2353
+ '@vue/shared': 3.5.28
2354
+ vue: 3.5.28(typescript@5.9.3)
2355
+
2356
+ '@vue/shared@3.5.28': {}
2357
+
2222
2358
  acorn-jsx@5.3.2(acorn@8.15.0):
2223
2359
  dependencies:
2224
2360
  acorn: 8.15.0
@@ -2390,6 +2526,8 @@ snapshots:
2390
2526
 
2391
2527
  electron-to-chromium@1.5.286: {}
2392
2528
 
2529
+ entities@7.0.1: {}
2530
+
2393
2531
  es-define-property@1.0.1: {}
2394
2532
 
2395
2533
  es-errors@1.3.0: {}
@@ -2522,6 +2660,8 @@ snapshots:
2522
2660
 
2523
2661
  estraverse@5.3.0: {}
2524
2662
 
2663
+ estree-walker@2.0.2: {}
2664
+
2525
2665
  esutils@2.0.3: {}
2526
2666
 
2527
2667
  fast-deep-equal@3.1.3: {}
@@ -2737,6 +2877,14 @@ snapshots:
2737
2877
  dependencies:
2738
2878
  yallist: 3.1.1
2739
2879
 
2880
+ lucide-react@0.563.0(react@18.3.1):
2881
+ dependencies:
2882
+ react: 18.3.1
2883
+
2884
+ magic-string@0.30.21:
2885
+ dependencies:
2886
+ '@jridgewell/sourcemap-codec': 1.5.5
2887
+
2740
2888
  math-intrinsics@1.1.0: {}
2741
2889
 
2742
2890
  merge2@1.4.1: {}
@@ -3081,6 +3229,8 @@ snapshots:
3081
3229
 
3082
3230
  typescript@5.9.3: {}
3083
3231
 
3232
+ undici-types@7.16.0: {}
3233
+
3084
3234
  update-browserslist-db@1.2.3(browserslist@4.28.1):
3085
3235
  dependencies:
3086
3236
  browserslist: 4.28.1
@@ -3097,15 +3247,26 @@ snapshots:
3097
3247
 
3098
3248
  util-deprecate@1.0.2: {}
3099
3249
 
3100
- vite@5.4.21(sass@1.97.3):
3250
+ vite@5.4.21(@types/node@25.2.3)(sass@1.97.3):
3101
3251
  dependencies:
3102
3252
  esbuild: 0.21.5
3103
3253
  postcss: 8.5.6
3104
3254
  rollup: 4.57.1
3105
3255
  optionalDependencies:
3256
+ '@types/node': 25.2.3
3106
3257
  fsevents: 2.3.3
3107
3258
  sass: 1.97.3
3108
3259
 
3260
+ vue@3.5.28(typescript@5.9.3):
3261
+ dependencies:
3262
+ '@vue/compiler-dom': 3.5.28
3263
+ '@vue/compiler-sfc': 3.5.28
3264
+ '@vue/runtime-dom': 3.5.28
3265
+ '@vue/server-renderer': 3.5.28(vue@3.5.28(typescript@5.9.3))
3266
+ '@vue/shared': 3.5.28
3267
+ optionalDependencies:
3268
+ typescript: 5.9.3
3269
+
3109
3270
  which@2.0.2:
3110
3271
  dependencies:
3111
3272
  isexe: 2.0.0
@@ -0,0 +1,77 @@
1
+ import { useState, useCallback, ChangeEvent, FormEvent } from 'react'
2
+
3
+ export type FormErrors<T> = Partial<Record<keyof T, string>>
4
+
5
+ export interface UseFormOptions<T> {
6
+ /** 初始表单值 */
7
+ initialValues: T
8
+ /** 校验函数(可选) */
9
+ validate?: (values: T) => FormErrors<T>
10
+ /** 提交成功回调(可选) */
11
+ onSubmit?: (values: T) => void | Promise<void>
12
+ }
13
+
14
+ /**
15
+ * 通用表单 Hook 示例
16
+ *
17
+ * - 管理表单值 values
18
+ * - 简单错误提示 errors
19
+ * - 提供 handleChange / handleSubmit / reset
20
+ */
21
+ export function useForm<T extends Record<string, any>>({
22
+ initialValues,
23
+ validate,
24
+ onSubmit
25
+ }: UseFormOptions<T>) {
26
+ const [values, setValues] = useState<T>(initialValues)
27
+ const [errors, setErrors] = useState<FormErrors<T>>({})
28
+ const [submitting, setSubmitting] = useState(false)
29
+
30
+ const handleChange = useCallback(
31
+ (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
32
+ const { name, value } = e.target
33
+ setValues((prev) => ({
34
+ ...prev,
35
+ [name]: value
36
+ }))
37
+ },
38
+ []
39
+ )
40
+
41
+ const reset = useCallback(() => {
42
+ setValues(initialValues)
43
+ setErrors({})
44
+ }, [initialValues])
45
+
46
+ const handleSubmit = useCallback(
47
+ async () => {
48
+ if (validate) {
49
+ const nextErrors = validate(values)
50
+ setErrors(nextErrors)
51
+ const hasError = Object.values(nextErrors).some(Boolean)
52
+ if (hasError) return false;
53
+ }
54
+
55
+ if (!onSubmit) return
56
+ try {
57
+ setSubmitting(true)
58
+ await onSubmit(values)
59
+ } finally {
60
+ setSubmitting(false)
61
+ }
62
+ },
63
+ [onSubmit, validate, values]
64
+ )
65
+
66
+ return {
67
+ values,
68
+ errors,
69
+ submitting,
70
+ handleChange,
71
+ handleSubmit,
72
+ reset,
73
+ setValues,
74
+ setErrors
75
+ }
76
+ }
77
+
@@ -1,3 +1,8 @@
1
+ /*
2
+ * @Author: linpeng
3
+ * @Date: 2026-02-11 10:55:43
4
+ * @Description:
5
+ */
1
6
  import { Outlet } from 'react-router-dom'
2
7
  import { useAppStore } from '@/stores/app'
3
8
  import SidebarMenu from './components/SidebarMenu'
@@ -12,7 +17,7 @@ export default function DefaultLayout() {
12
17
  <header className="layout-header">
13
18
  <div className="header-left">
14
19
  <div className="logo">
15
- <h1>{sidebarCollapsed ? '{{PROJECT_SHORT}}' : '{{PROJECT_NAME}}'}</h1>
20
+ <h1>{import.meta.env.VITE_APP_TITLE}</h1>
16
21
  </div>
17
22
  <button className="toggle-btn" onClick={toggleSidebar}>
18
23
  {sidebarCollapsed ? '☰' : '✕'}
@@ -24,49 +24,19 @@ export const menuRoutes: MenuItem[] = [
24
24
  {
25
25
  path: '/home',
26
26
  title: '首页',
27
- icon: '🏠'
27
+ icon: ''
28
28
  },
29
29
  {
30
30
  path: '/system',
31
31
  title: '系统管理',
32
- icon: '⚙️',
32
+ icon: '',
33
33
  children: [
34
34
  {
35
35
  path: '/system/user',
36
36
  title: '用户管理',
37
- icon: '👤'
37
+ icon: ''
38
38
  },
39
- {
40
- path: '/system/role',
41
- title: '角色管理',
42
- icon: '🔑'
43
- },
44
- {
45
- path: '/system/menu',
46
- title: '菜单管理',
47
- icon: '📋'
48
- },
49
- {
50
- path: '/system/log',
51
- title: '日志管理',
52
- icon: '📝',
53
- children: [
54
- {
55
- path: '/system/log/operation',
56
- title: '操作日志'
57
- },
58
- {
59
- path: '/system/log/login',
60
- title: '登录日志'
61
- }
62
- ]
63
- }
64
39
  ]
65
- },
66
- {
67
- path: '/about',
68
- title: '关于',
69
- icon: 'ℹ️'
70
40
  }
71
41
  ]
72
42
 
@@ -9,6 +9,9 @@ import './styles/tailwind.css'
9
9
  // 全局样式
10
10
  import './styles/index.scss'
11
11
 
12
+ // @lvetechs/ui-lib 样式
13
+ import '@lvetechs/ui-lib/style.css'
14
+
12
15
  ReactDOM.createRoot(document.getElementById('root')!).render(
13
16
  <React.StrictMode>
14
17
  <BrowserRouter>