zant-admin 1.0.4 → 2.0.1

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 (94) hide show
  1. package/README.en.md +414 -25
  2. package/README.md +460 -285
  3. package/bin/cli.js +3 -3
  4. package/bin/generator.js +502 -502
  5. package/bin/prompts.js +158 -158
  6. package/bin/utils.js +133 -133
  7. package/package.json +2 -2
  8. package/public/logo.png +0 -0
  9. package/src/App.vue +16 -16
  10. package/src/api/methods/department.js +36 -0
  11. package/src/api/methods/employee.js +22 -0
  12. package/src/api/methods/logError.js +8 -8
  13. package/src/api/methods/logOperation.js +8 -8
  14. package/src/api/methods/login.js +6 -6
  15. package/src/api/methods/position.js +26 -0
  16. package/src/api/methods/quartz.js +36 -36
  17. package/src/api/methods/region.js +16 -16
  18. package/src/api/methods/sysAccount.js +29 -29
  19. package/src/api/methods/sysDict.js +29 -29
  20. package/src/api/methods/sysDictItem.js +26 -26
  21. package/src/api/methods/sysMenu.js +42 -42
  22. package/src/api/methods/sysRole.js +35 -35
  23. package/src/api/methods/sysUser.js +25 -25
  24. package/src/api/methods/system.js +15 -15
  25. package/src/api/request.js +225 -225
  26. package/src/assets/css/style.css +2 -2
  27. package/src/assets/css/zcui.css +1023 -1023
  28. package/src/assets/imgs/logo.png +0 -0
  29. package/src/assets/imgs/md/console.png +0 -0
  30. package/src/assets/imgs/md/login.png +0 -0
  31. package/src/assets/imgs/md/menu.png +0 -0
  32. package/src/assets/imgs/md/serviceMonitoring.png +0 -0
  33. package/src/assets/imgs/md/statistics.png +0 -0
  34. package/src/components/FormTable.vue +5 -19
  35. package/src/components/IconPicker.vue +351 -351
  36. package/src/components/MainPage.vue +838 -838
  37. package/src/components/details/logErrorDetails.vue +58 -58
  38. package/src/components/details/logOperationDetails.vue +76 -76
  39. package/src/components/edit/QuartzEdit.vue +221 -221
  40. package/src/components/edit/SysAccountEdit.vue +185 -185
  41. package/src/components/edit/SysDictEdit.vue +116 -116
  42. package/src/components/edit/SysDictItemEdit.vue +136 -136
  43. package/src/components/edit/SysRoleEdit.vue +111 -111
  44. package/src/components/edit/organizationalStructure/DepartmentEdit.vue +162 -0
  45. package/src/components/edit/organizationalStructure/EmployeeEdit.vue +295 -0
  46. package/src/components/edit/organizationalStructure/PositionEdit.vue +166 -0
  47. package/src/components/edit/sysMenuEdit.vue +2 -1
  48. package/src/config/index.js +74 -74
  49. package/src/directives/permission.js +49 -49
  50. package/src/main.js +37 -37
  51. package/src/router/index.js +4 -6
  52. package/src/stores/config.js +43 -43
  53. package/src/stores/dict.js +33 -33
  54. package/src/stores/menu.js +81 -81
  55. package/src/stores/user.js +21 -21
  56. package/src/utils/baseEcharts.js +661 -661
  57. package/src/utils/dictTemplate.js +26 -26
  58. package/src/utils/regionUtils.js +173 -173
  59. package/src/utils/useFormCRUD.js +59 -59
  60. package/src/views/baiscstatis/center.vue +474 -474
  61. package/src/views/baiscstatis/iframePage.vue +29 -29
  62. package/src/views/baiscstatis/notFound.vue +192 -192
  63. package/src/views/console.vue +821 -821
  64. package/src/views/demo/button.vue +269 -269
  65. package/src/views/demo/importexport.vue +119 -119
  66. package/src/views/demo/region.vue +322 -322
  67. package/src/views/demo/statistics.vue +214 -214
  68. package/src/views/home.vue +6 -6
  69. package/src/views/login.vue +264 -149
  70. package/src/views/operations/log/logError.vue +78 -78
  71. package/src/views/operations/log/logLogin.vue +66 -66
  72. package/src/views/operations/log/logOperation.vue +103 -103
  73. package/src/views/operations/log/logQuartz.vue +56 -56
  74. package/src/views/operations/quartz.vue +179 -179
  75. package/src/views/operations/serviceMonitoring.vue +134 -134
  76. package/src/views/organizationalStructure/department.vue +194 -0
  77. package/src/views/organizationalStructure/employee.vue +234 -0
  78. package/src/views/organizationalStructure/position.vue +196 -0
  79. package/src/views/system/sysAccount.vue +128 -128
  80. package/src/views/system/sysDict.vue +159 -159
  81. package/src/views/system/sysDictItem.vue +118 -118
  82. package/src/views/system/sysMenu.vue +225 -225
  83. package/src/views/system/sysRole.vue +207 -207
  84. package/src/assets/imgs/md/1.png +0 -0
  85. package/src/assets/imgs/md/10.png +0 -0
  86. package/src/assets/imgs/md/11.png +0 -0
  87. package/src/assets/imgs/md/2.png +0 -0
  88. package/src/assets/imgs/md/3.png +0 -0
  89. package/src/assets/imgs/md/4.png +0 -0
  90. package/src/assets/imgs/md/5.png +0 -0
  91. package/src/assets/imgs/md/6.png +0 -0
  92. package/src/assets/imgs/md/7.png +0 -0
  93. package/src/assets/imgs/md/8.png +0 -0
  94. package/src/assets/imgs/md/9.png +0 -0
package/bin/generator.js CHANGED
@@ -1,503 +1,503 @@
1
- /**
2
- * 项目生成器
3
- * 负责创建和管理项目模板
4
- */
5
-
6
- import fs from 'fs';
7
- import path from 'path';
8
- import {
9
- createDirectory,
10
- copyDirectory,
11
- writeFile,
12
- renderTemplate,
13
- executeCommand,
14
- getProjectRoot,
15
- validateProjectName
16
- } from './utils.js';
17
-
18
- /**
19
- * 创建新项目
20
- */
21
- export async function createProject(projectName, options) {
22
- // 验证项目名称
23
- validateProjectName(projectName);
24
-
25
- const projectPath = path.resolve(process.cwd(), projectName);
26
-
27
- // 检查目录是否已存在
28
- if (fs.existsSync(projectPath)) {
29
- throw new Error(`目录 "${projectName}" 已存在,请选择其他名称`);
30
- }
31
-
32
- // 创建项目目录
33
- createDirectory(projectPath);
34
-
35
- // 根据模板类型生成项目
36
- await generateProjectStructure(projectPath, options);
37
-
38
- // 生成配置文件
39
- await generateConfigFiles(projectPath, projectName, options);
40
-
41
- // 安装依赖(如果未跳过)
42
- if (!options.skipInstall) {
43
- await installDependencies(projectPath);
44
- }
45
- }
46
-
47
- /**
48
- * 生成项目结构
49
- */
50
- async function generateProjectStructure(projectPath, options) {
51
- const templateType = options.template || 'default';
52
- const sourceRoot = getProjectRoot();
53
-
54
- console.log('📁 生成项目结构...');
55
-
56
- // 复制基础文件
57
- const baseFiles = [
58
- 'package.json',
59
- 'vite.config.js',
60
- 'index.html',
61
- 'eslint.config.js',
62
- '.prettierrc.json',
63
- '.gitignore',
64
- '.editorconfig',
65
- 'jsconfig.json'
66
- ];
67
-
68
- baseFiles.forEach(file => {
69
- const sourceFile = path.join(sourceRoot, file);
70
- const targetFile = path.join(projectPath, file);
71
-
72
- if (fs.existsSync(sourceFile)) {
73
- fs.copyFileSync(sourceFile, targetFile);
74
- }
75
- });
76
-
77
- // 复制环境配置文件
78
- const envFiles = ['.env.development', '.env.test'];
79
- envFiles.forEach(file => {
80
- const sourceFile = path.join(sourceRoot, file);
81
- const targetFile = path.join(projectPath, file);
82
-
83
- if (fs.existsSync(sourceFile)) {
84
- fs.copyFileSync(sourceFile, targetFile);
85
- }
86
- });
87
-
88
- // 使用模板生成生产环境配置文件
89
- await generateProductionEnv(projectPath);
90
-
91
- // 复制 public 目录
92
- copyDirectory(path.join(sourceRoot, 'public'), path.join(projectPath, 'public'));
93
-
94
- // 复制 src 目录(根据模板类型)
95
- await copySourceDirectory(sourceRoot, projectPath, templateType);
96
- }
97
-
98
- /**
99
- * 复制源代码目录
100
- */
101
- async function copySourceDirectory(sourceRoot, projectPath, templateType) {
102
- const srcPath = path.join(sourceRoot, 'src');
103
- const targetSrcPath = path.join(projectPath, 'src');
104
-
105
- // 创建 src 目录结构
106
- createDirectory(targetSrcPath);
107
-
108
- // 复制核心文件
109
- const coreFiles = ['main.js', 'App.vue'];
110
- coreFiles.forEach(file => {
111
- const sourceFile = path.join(srcPath, file);
112
- const targetFile = path.join(targetSrcPath, file);
113
-
114
- if (fs.existsSync(sourceFile)) {
115
- fs.copyFileSync(sourceFile, targetFile);
116
- }
117
- });
118
-
119
- // 复制核心目录
120
- const coreDirs = ['api', 'assets', 'config', 'directives', 'router', 'stores', 'utils'];
121
- coreDirs.forEach(dir => {
122
- const sourceDir = path.join(srcPath, dir);
123
- const targetDir = path.join(targetSrcPath, dir);
124
-
125
- if (fs.existsSync(sourceDir)) {
126
- copyDirectory(sourceDir, targetDir);
127
- }
128
- });
129
-
130
- // 根据模板类型处理 components 和 views
131
- await handleTemplateSpecificFiles(srcPath, targetSrcPath, templateType);
132
- }
133
-
134
- /**
135
- * 处理模板特定的文件
136
- */
137
- async function handleTemplateSpecificFiles(srcPath, targetSrcPath, templateType) {
138
- // 复制 components 目录
139
- const componentsSource = path.join(srcPath, 'components');
140
- const componentsTarget = path.join(targetSrcPath, 'components');
141
-
142
- if (fs.existsSync(componentsSource)) {
143
- copyDirectory(componentsSource, componentsTarget);
144
- }
145
-
146
- // 处理 views 目录
147
- const viewsSource = path.join(srcPath, 'views');
148
- const viewsTarget = path.join(targetSrcPath, 'views');
149
-
150
- if (fs.existsSync(viewsSource)) {
151
- if (templateType === 'basic') {
152
- // 基础模板:只保留核心页面
153
- createDirectory(viewsTarget);
154
- const basicViews = ['console.vue', 'home.vue', 'login.vue'];
155
-
156
- basicViews.forEach(view => {
157
- const sourceFile = path.join(viewsSource, view);
158
- const targetFile = path.join(viewsTarget, view);
159
-
160
- if (fs.existsSync(sourceFile)) {
161
- fs.copyFileSync(sourceFile, targetFile);
162
- }
163
- });
164
- } else {
165
- // 默认和完整模板:复制所有页面
166
- copyDirectory(viewsSource, viewsTarget);
167
- }
168
- }
169
- }
170
-
171
- /**
172
- * 生成配置文件
173
- */
174
- async function generateConfigFiles(projectPath, projectName, options) {
175
- console.log('⚙️ 生成配置文件...');
176
-
177
- // 读取并更新 package.json
178
- const packageJsonPath = path.join(projectPath, 'package.json');
179
- if (fs.existsSync(packageJsonPath)) {
180
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
181
-
182
- // 更新项目信息
183
- packageJson.name = projectName;
184
- packageJson.description = options.description;
185
-
186
- if (options.author) {
187
- packageJson.author = options.author;
188
- }
189
-
190
- // 根据功能特性调整依赖
191
- if (options.features && options.features.length > 0) {
192
- await adjustDependencies(packageJson, options.features);
193
- }
194
-
195
- // 移除脚手架特定的配置
196
- delete packageJson.bin;
197
- delete packageJson.main;
198
-
199
- // 写入更新后的 package.json
200
- writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
201
- }
202
-
203
- // 生成 README.md
204
- await generateReadme(projectPath, projectName, options);
205
-
206
- // 根据功能特性生成额外文件
207
- if (options.features && options.features.length > 0) {
208
- await generateFeatureFiles(projectPath, options.features);
209
- }
210
- }
211
-
212
- /**
213
- * 根据功能特性调整依赖
214
- */
215
- async function adjustDependencies(packageJson, features) {
216
- const featureDependencies = {
217
- 'i18n-support': {
218
- dependencies: {
219
- 'vue-i18n': '^9.0.0'
220
- }
221
- },
222
- 'file-upload': {
223
- dependencies: {
224
- 'ant-design-vue': '^4.2.6' // 已包含,确保版本
225
- }
226
- }
227
- };
228
-
229
- features.forEach(feature => {
230
- const deps = featureDependencies[feature];
231
- if (deps && deps.dependencies) {
232
- Object.assign(packageJson.dependencies, deps.dependencies);
233
- }
234
- });
235
- }
236
-
237
- /**
238
- * 根据功能特性生成额外文件
239
- */
240
- async function generateFeatureFiles(projectPath, features) {
241
- const featureGenerators = {
242
- 'i18n-support': generateI18nFiles,
243
- 'user-management': generateUserManagementFiles,
244
- 'permission-management': generatePermissionFiles
245
- };
246
-
247
- for (const feature of features) {
248
- const generator = featureGenerators[feature];
249
- if (generator) {
250
- await generator(projectPath);
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * 生成国际化支持文件
257
- */
258
- async function generateI18nFiles(projectPath) {
259
- console.log('🌐 生成国际化支持文件...');
260
-
261
- // 创建 locales 目录
262
- const localesDir = path.join(projectPath, 'src/locales');
263
- createDirectory(localesDir);
264
-
265
- // 生成中文语言包
266
- const zhCNContent = `{
267
- "common": {
268
- "save": "保存",
269
- "cancel": "取消",
270
- "delete": "删除",
271
- "edit": "编辑",
272
- "add": "添加"
273
- },
274
- "menu": {
275
- "dashboard": "仪表盘",
276
- "user": "用户管理",
277
- "system": "系统管理"
278
- }
279
- }`;
280
-
281
- writeFile(path.join(localesDir, 'zh-CN.json'), zhCNContent);
282
-
283
- // 生成英文语言包
284
- const enUSContent = `{
285
- "common": {
286
- "save": "Save",
287
- "cancel": "Cancel",
288
- "delete": "Delete",
289
- "edit": "Edit",
290
- "add": "Add"
291
- },
292
- "menu": {
293
- "dashboard": "Dashboard",
294
- "user": "User Management",
295
- "system": "System Management"
296
- }
297
- }`;
298
-
299
- writeFile(path.join(localesDir, 'en-US.json'), enUSContent);
300
- }
301
-
302
- /**
303
- * 生成用户管理相关文件
304
- */
305
- async function generateUserManagementFiles(projectPath) {
306
- console.log('👥 生成用户管理文件...');
307
-
308
- // 创建用户管理相关目录
309
- const userViewsDir = path.join(projectPath, 'src/views/system/user');
310
- createDirectory(userViewsDir);
311
-
312
- // 生成用户列表页面
313
- const userListContent = `<template>
314
- <div class="user-management">
315
- <a-card title="用户管理">
316
- <a-table :columns="columns" :data-source="userList">
317
- <template #action="{ record }">
318
- <a-space>
319
- <a-button type="link" @click="handleEdit(record)">编辑</a-button>
320
- <a-button type="link" danger @click="handleDelete(record)">删除</a-button>
321
- </a-space>
322
- </template>
323
- </a-table>
324
- </a-card>
325
- </div>
326
- </template>
327
-
328
- <script setup>
329
- import { ref, onMounted } from 'vue';
330
-
331
- const columns = [
332
- { title: '用户名', dataIndex: 'username' },
333
- { title: '邮箱', dataIndex: 'email' },
334
- { title: '角色', dataIndex: 'role' },
335
- { title: '状态', dataIndex: 'status' },
336
- { title: '操作', slots: { customRender: 'action' } }
337
- ];
338
-
339
- const userList = ref([]);
340
-
341
- onMounted(() => {
342
- // 加载用户数据
343
- loadUserData();
344
- });
345
-
346
- const loadUserData = async () => {
347
- // 模拟数据
348
- userList.value = [
349
- { id: 1, username: 'admin', email: 'admin@example.com', role: '管理员', status: '正常' }
350
- ];
351
- };
352
-
353
- const handleEdit = (record) => {
354
- console.log('编辑用户:', record);
355
- };
356
-
357
- const handleDelete = (record) => {
358
- console.log('删除用户:', record);
359
- };
360
- </script>
361
-
362
- <style scoped>
363
- .user-management {
364
- padding: 20px;
365
- }
366
- </style>`;
367
-
368
- writeFile(path.join(userViewsDir, 'index.vue'), userListContent);
369
- }
370
-
371
- /**
372
- * 生成权限管理相关文件
373
- */
374
- async function generatePermissionFiles(projectPath) {
375
- console.log('🔐 生成权限管理文件...');
376
-
377
- // 创建权限管理相关目录
378
- const permissionViewsDir = path.join(projectPath, 'src/views/system/permission');
379
- createDirectory(permissionViewsDir);
380
-
381
- // 生成权限管理页面
382
- const permissionContent = `<template>
383
- <div class="permission-management">
384
- <a-card title="权限管理">
385
- <p>权限管理功能已生成,请根据业务需求进行开发。</p>
386
- </a-card>
387
- </div>
388
- </template>
389
-
390
- <script setup>
391
- // 权限管理页面逻辑
392
- </script>
393
-
394
- <style scoped>
395
- .permission-management {
396
- padding: 20px;
397
- }
398
- </style>`;
399
-
400
- writeFile(path.join(permissionViewsDir, 'index.vue'), permissionContent);
401
- }
402
-
403
- /**
404
- * 生成生产环境配置文件
405
- */
406
- async function generateProductionEnv(projectPath) {
407
- console.log('🔧 生成生产环境配置文件...');
408
-
409
- const templatePath = path.join(getProjectRoot(), 'templates/env.production');
410
- const targetPath = path.join(projectPath, '.env.production');
411
-
412
- if (fs.existsSync(templatePath)) {
413
- // 使用模板文件
414
- fs.copyFileSync(templatePath, targetPath);
415
- } else {
416
- // 如果模板不存在,创建默认的生产环境配置
417
- const defaultProdConfig = `# 生产环境配置
418
- VITE_BASE_API=http://your-production-server.com/api/
419
-
420
- # 其他生产环境变量
421
- NODE_ENV=production
422
- VITE_APP_TITLE=ZAnt Admin`;
423
-
424
- writeFile(targetPath, defaultProdConfig);
425
- }
426
- }
427
-
428
- /**
429
- * 生成 README.md 文件
430
- */
431
- async function generateReadme(projectPath, projectName, options) {
432
- const readmeContent = `# ${projectName}
433
-
434
- ${options.description}
435
-
436
- ## 技术栈
437
-
438
- - Vue 3 (Composition API)
439
- - Vite 构建工具
440
- - Ant Design Vue UI 组件库
441
- - Pinia 状态管理
442
- - Vue Router 路由管理
443
-
444
- ## 快速开始
445
-
446
- ### 安装依赖
447
- \`\`\`bash
448
- npm install
449
- \`\`\`
450
-
451
- ### 启动开发服务器
452
- \`\`\`bash
453
- npm run dev
454
- \`\`\`
455
-
456
- ### 构建生产版本
457
- \`\`\`bash
458
- npm run build
459
- \`\`\`
460
-
461
- ## 项目结构
462
-
463
- \`\`\`
464
- src/
465
- ├── api/ # 接口请求相关
466
- ├── assets/ # 静态资源文件
467
- ├── components/ # 公共组件
468
- ├── router/ # 路由配置
469
- ├── stores/ # 状态管理
470
- ├── utils/ # 工具函数
471
- ├── views/ # 页面视图
472
- ├── App.vue # 根组件
473
- └── main.js # 入口文件
474
- \`\`\`
475
-
476
- ## 命令说明
477
-
478
- - \`npm run dev\` - 启动开发服务器
479
- - \`npm run build\` - 构建生产版本
480
- - \`npm run preview\` - 预览生产构建
481
- - \`npm run lint\` - 代码检查
482
- - \`npm run format\` - 代码格式化
483
-
484
- ## 许可证
485
-
486
- MIT License
487
- `;
488
-
489
- writeFile(path.join(projectPath, 'README.md'), readmeContent);
490
- }
491
-
492
- /**
493
- * 安装依赖
494
- */
495
- async function installDependencies(projectPath) {
496
- console.log('📦 安装依赖包...');
497
-
498
- const success = executeCommand('npm install', projectPath);
499
-
500
- if (!success) {
501
- console.warn('⚠️ 依赖安装失败,请手动运行: npm install');
502
- }
1
+ /**
2
+ * 项目生成器
3
+ * 负责创建和管理项目模板
4
+ */
5
+
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import {
9
+ createDirectory,
10
+ copyDirectory,
11
+ writeFile,
12
+ renderTemplate,
13
+ executeCommand,
14
+ getProjectRoot,
15
+ validateProjectName
16
+ } from './utils.js';
17
+
18
+ /**
19
+ * 创建新项目
20
+ */
21
+ export async function createProject(projectName, options) {
22
+ // 验证项目名称
23
+ validateProjectName(projectName);
24
+
25
+ const projectPath = path.resolve(process.cwd(), projectName);
26
+
27
+ // 检查目录是否已存在
28
+ if (fs.existsSync(projectPath)) {
29
+ throw new Error(`目录 "${projectName}" 已存在,请选择其他名称`);
30
+ }
31
+
32
+ // 创建项目目录
33
+ createDirectory(projectPath);
34
+
35
+ // 根据模板类型生成项目
36
+ await generateProjectStructure(projectPath, options);
37
+
38
+ // 生成配置文件
39
+ await generateConfigFiles(projectPath, projectName, options);
40
+
41
+ // 安装依赖(如果未跳过)
42
+ if (!options.skipInstall) {
43
+ await installDependencies(projectPath);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * 生成项目结构
49
+ */
50
+ async function generateProjectStructure(projectPath, options) {
51
+ const templateType = options.template || 'default';
52
+ const sourceRoot = getProjectRoot();
53
+
54
+ console.log('📁 生成项目结构...');
55
+
56
+ // 复制基础文件
57
+ const baseFiles = [
58
+ 'package.json',
59
+ 'vite.config.js',
60
+ 'index.html',
61
+ 'eslint.config.js',
62
+ '.prettierrc.json',
63
+ '.gitignore',
64
+ '.editorconfig',
65
+ 'jsconfig.json'
66
+ ];
67
+
68
+ baseFiles.forEach(file => {
69
+ const sourceFile = path.join(sourceRoot, file);
70
+ const targetFile = path.join(projectPath, file);
71
+
72
+ if (fs.existsSync(sourceFile)) {
73
+ fs.copyFileSync(sourceFile, targetFile);
74
+ }
75
+ });
76
+
77
+ // 复制环境配置文件
78
+ const envFiles = ['.env.development', '.env.test'];
79
+ envFiles.forEach(file => {
80
+ const sourceFile = path.join(sourceRoot, file);
81
+ const targetFile = path.join(projectPath, file);
82
+
83
+ if (fs.existsSync(sourceFile)) {
84
+ fs.copyFileSync(sourceFile, targetFile);
85
+ }
86
+ });
87
+
88
+ // 使用模板生成生产环境配置文件
89
+ await generateProductionEnv(projectPath);
90
+
91
+ // 复制 public 目录
92
+ copyDirectory(path.join(sourceRoot, 'public'), path.join(projectPath, 'public'));
93
+
94
+ // 复制 src 目录(根据模板类型)
95
+ await copySourceDirectory(sourceRoot, projectPath, templateType);
96
+ }
97
+
98
+ /**
99
+ * 复制源代码目录
100
+ */
101
+ async function copySourceDirectory(sourceRoot, projectPath, templateType) {
102
+ const srcPath = path.join(sourceRoot, 'src');
103
+ const targetSrcPath = path.join(projectPath, 'src');
104
+
105
+ // 创建 src 目录结构
106
+ createDirectory(targetSrcPath);
107
+
108
+ // 复制核心文件
109
+ const coreFiles = ['main.js', 'App.vue'];
110
+ coreFiles.forEach(file => {
111
+ const sourceFile = path.join(srcPath, file);
112
+ const targetFile = path.join(targetSrcPath, file);
113
+
114
+ if (fs.existsSync(sourceFile)) {
115
+ fs.copyFileSync(sourceFile, targetFile);
116
+ }
117
+ });
118
+
119
+ // 复制核心目录
120
+ const coreDirs = ['api', 'assets', 'config', 'directives', 'router', 'stores', 'utils'];
121
+ coreDirs.forEach(dir => {
122
+ const sourceDir = path.join(srcPath, dir);
123
+ const targetDir = path.join(targetSrcPath, dir);
124
+
125
+ if (fs.existsSync(sourceDir)) {
126
+ copyDirectory(sourceDir, targetDir);
127
+ }
128
+ });
129
+
130
+ // 根据模板类型处理 components 和 views
131
+ await handleTemplateSpecificFiles(srcPath, targetSrcPath, templateType);
132
+ }
133
+
134
+ /**
135
+ * 处理模板特定的文件
136
+ */
137
+ async function handleTemplateSpecificFiles(srcPath, targetSrcPath, templateType) {
138
+ // 复制 components 目录
139
+ const componentsSource = path.join(srcPath, 'components');
140
+ const componentsTarget = path.join(targetSrcPath, 'components');
141
+
142
+ if (fs.existsSync(componentsSource)) {
143
+ copyDirectory(componentsSource, componentsTarget);
144
+ }
145
+
146
+ // 处理 views 目录
147
+ const viewsSource = path.join(srcPath, 'views');
148
+ const viewsTarget = path.join(targetSrcPath, 'views');
149
+
150
+ if (fs.existsSync(viewsSource)) {
151
+ if (templateType === 'basic') {
152
+ // 基础模板:只保留核心页面
153
+ createDirectory(viewsTarget);
154
+ const basicViews = ['console.vue', 'home.vue', 'login.vue'];
155
+
156
+ basicViews.forEach(view => {
157
+ const sourceFile = path.join(viewsSource, view);
158
+ const targetFile = path.join(viewsTarget, view);
159
+
160
+ if (fs.existsSync(sourceFile)) {
161
+ fs.copyFileSync(sourceFile, targetFile);
162
+ }
163
+ });
164
+ } else {
165
+ // 默认和完整模板:复制所有页面
166
+ copyDirectory(viewsSource, viewsTarget);
167
+ }
168
+ }
169
+ }
170
+
171
+ /**
172
+ * 生成配置文件
173
+ */
174
+ async function generateConfigFiles(projectPath, projectName, options) {
175
+ console.log('⚙️ 生成配置文件...');
176
+
177
+ // 读取并更新 package.json
178
+ const packageJsonPath = path.join(projectPath, 'package.json');
179
+ if (fs.existsSync(packageJsonPath)) {
180
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
181
+
182
+ // 更新项目信息
183
+ packageJson.name = projectName;
184
+ packageJson.description = options.description;
185
+
186
+ if (options.author) {
187
+ packageJson.author = options.author;
188
+ }
189
+
190
+ // 根据功能特性调整依赖
191
+ if (options.features && options.features.length > 0) {
192
+ await adjustDependencies(packageJson, options.features);
193
+ }
194
+
195
+ // 移除脚手架特定的配置
196
+ delete packageJson.bin;
197
+ delete packageJson.main;
198
+
199
+ // 写入更新后的 package.json
200
+ writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
201
+ }
202
+
203
+ // 生成 README.md
204
+ await generateReadme(projectPath, projectName, options);
205
+
206
+ // 根据功能特性生成额外文件
207
+ if (options.features && options.features.length > 0) {
208
+ await generateFeatureFiles(projectPath, options.features);
209
+ }
210
+ }
211
+
212
+ /**
213
+ * 根据功能特性调整依赖
214
+ */
215
+ async function adjustDependencies(packageJson, features) {
216
+ const featureDependencies = {
217
+ 'i18n-support': {
218
+ dependencies: {
219
+ 'vue-i18n': '^9.0.0'
220
+ }
221
+ },
222
+ 'file-upload': {
223
+ dependencies: {
224
+ 'ant-design-vue': '^4.2.6' // 已包含,确保版本
225
+ }
226
+ }
227
+ };
228
+
229
+ features.forEach(feature => {
230
+ const deps = featureDependencies[feature];
231
+ if (deps && deps.dependencies) {
232
+ Object.assign(packageJson.dependencies, deps.dependencies);
233
+ }
234
+ });
235
+ }
236
+
237
+ /**
238
+ * 根据功能特性生成额外文件
239
+ */
240
+ async function generateFeatureFiles(projectPath, features) {
241
+ const featureGenerators = {
242
+ 'i18n-support': generateI18nFiles,
243
+ 'user-management': generateUserManagementFiles,
244
+ 'permission-management': generatePermissionFiles
245
+ };
246
+
247
+ for (const feature of features) {
248
+ const generator = featureGenerators[feature];
249
+ if (generator) {
250
+ await generator(projectPath);
251
+ }
252
+ }
253
+ }
254
+
255
+ /**
256
+ * 生成国际化支持文件
257
+ */
258
+ async function generateI18nFiles(projectPath) {
259
+ console.log('🌐 生成国际化支持文件...');
260
+
261
+ // 创建 locales 目录
262
+ const localesDir = path.join(projectPath, 'src/locales');
263
+ createDirectory(localesDir);
264
+
265
+ // 生成中文语言包
266
+ const zhCNContent = `{
267
+ "common": {
268
+ "save": "保存",
269
+ "cancel": "取消",
270
+ "delete": "删除",
271
+ "edit": "编辑",
272
+ "add": "添加"
273
+ },
274
+ "menu": {
275
+ "dashboard": "仪表盘",
276
+ "user": "用户管理",
277
+ "system": "系统管理"
278
+ }
279
+ }`;
280
+
281
+ writeFile(path.join(localesDir, 'zh-CN.json'), zhCNContent);
282
+
283
+ // 生成英文语言包
284
+ const enUSContent = `{
285
+ "common": {
286
+ "save": "Save",
287
+ "cancel": "Cancel",
288
+ "delete": "Delete",
289
+ "edit": "Edit",
290
+ "add": "Add"
291
+ },
292
+ "menu": {
293
+ "dashboard": "Dashboard",
294
+ "user": "User Management",
295
+ "system": "System Management"
296
+ }
297
+ }`;
298
+
299
+ writeFile(path.join(localesDir, 'en-US.json'), enUSContent);
300
+ }
301
+
302
+ /**
303
+ * 生成用户管理相关文件
304
+ */
305
+ async function generateUserManagementFiles(projectPath) {
306
+ console.log('👥 生成用户管理文件...');
307
+
308
+ // 创建用户管理相关目录
309
+ const userViewsDir = path.join(projectPath, 'src/views/system/user');
310
+ createDirectory(userViewsDir);
311
+
312
+ // 生成用户列表页面
313
+ const userListContent = `<template>
314
+ <div class="user-management">
315
+ <a-card title="用户管理">
316
+ <a-table :columns="columns" :data-source="userList">
317
+ <template #action="{ record }">
318
+ <a-space>
319
+ <a-button type="link" @click="handleEdit(record)">编辑</a-button>
320
+ <a-button type="link" danger @click="handleDelete(record)">删除</a-button>
321
+ </a-space>
322
+ </template>
323
+ </a-table>
324
+ </a-card>
325
+ </div>
326
+ </template>
327
+
328
+ <script setup>
329
+ import { ref, onMounted } from 'vue';
330
+
331
+ const columns = [
332
+ { title: '用户名', dataIndex: 'username' },
333
+ { title: '邮箱', dataIndex: 'email' },
334
+ { title: '角色', dataIndex: 'role' },
335
+ { title: '状态', dataIndex: 'status' },
336
+ { title: '操作', slots: { customRender: 'action' } }
337
+ ];
338
+
339
+ const userList = ref([]);
340
+
341
+ onMounted(() => {
342
+ // 加载用户数据
343
+ loadUserData();
344
+ });
345
+
346
+ const loadUserData = async () => {
347
+ // 模拟数据
348
+ userList.value = [
349
+ { id: 1, username: 'admin', email: 'admin@example.com', role: '管理员', status: '正常' }
350
+ ];
351
+ };
352
+
353
+ const handleEdit = (record) => {
354
+ console.log('编辑用户:', record);
355
+ };
356
+
357
+ const handleDelete = (record) => {
358
+ console.log('删除用户:', record);
359
+ };
360
+ </script>
361
+
362
+ <style scoped>
363
+ .user-management {
364
+ padding: 20px;
365
+ }
366
+ </style>`;
367
+
368
+ writeFile(path.join(userViewsDir, 'index.vue'), userListContent);
369
+ }
370
+
371
+ /**
372
+ * 生成权限管理相关文件
373
+ */
374
+ async function generatePermissionFiles(projectPath) {
375
+ console.log('🔐 生成权限管理文件...');
376
+
377
+ // 创建权限管理相关目录
378
+ const permissionViewsDir = path.join(projectPath, 'src/views/system/permission');
379
+ createDirectory(permissionViewsDir);
380
+
381
+ // 生成权限管理页面
382
+ const permissionContent = `<template>
383
+ <div class="permission-management">
384
+ <a-card title="权限管理">
385
+ <p>权限管理功能已生成,请根据业务需求进行开发。</p>
386
+ </a-card>
387
+ </div>
388
+ </template>
389
+
390
+ <script setup>
391
+ // 权限管理页面逻辑
392
+ </script>
393
+
394
+ <style scoped>
395
+ .permission-management {
396
+ padding: 20px;
397
+ }
398
+ </style>`;
399
+
400
+ writeFile(path.join(permissionViewsDir, 'index.vue'), permissionContent);
401
+ }
402
+
403
+ /**
404
+ * 生成生产环境配置文件
405
+ */
406
+ async function generateProductionEnv(projectPath) {
407
+ console.log('🔧 生成生产环境配置文件...');
408
+
409
+ const templatePath = path.join(getProjectRoot(), 'templates/env.production');
410
+ const targetPath = path.join(projectPath, '.env.production');
411
+
412
+ if (fs.existsSync(templatePath)) {
413
+ // 使用模板文件
414
+ fs.copyFileSync(templatePath, targetPath);
415
+ } else {
416
+ // 如果模板不存在,创建默认的生产环境配置
417
+ const defaultProdConfig = `# 生产环境配置
418
+ VITE_BASE_API=http://your-production-server.com/api/
419
+
420
+ # 其他生产环境变量
421
+ NODE_ENV=production
422
+ VITE_APP_TITLE=ZAnt Admin`;
423
+
424
+ writeFile(targetPath, defaultProdConfig);
425
+ }
426
+ }
427
+
428
+ /**
429
+ * 生成 README.md 文件
430
+ */
431
+ async function generateReadme(projectPath, projectName, options) {
432
+ const readmeContent = `# ${projectName}
433
+
434
+ ${options.description}
435
+
436
+ ## 技术栈
437
+
438
+ - Vue 3 (Composition API)
439
+ - Vite 构建工具
440
+ - Ant Design Vue UI 组件库
441
+ - Pinia 状态管理
442
+ - Vue Router 路由管理
443
+
444
+ ## 快速开始
445
+
446
+ ### 安装依赖
447
+ \`\`\`bash
448
+ npm install
449
+ \`\`\`
450
+
451
+ ### 启动开发服务器
452
+ \`\`\`bash
453
+ npm run dev
454
+ \`\`\`
455
+
456
+ ### 构建生产版本
457
+ \`\`\`bash
458
+ npm run build
459
+ \`\`\`
460
+
461
+ ## 项目结构
462
+
463
+ \`\`\`
464
+ src/
465
+ ├── api/ # 接口请求相关
466
+ ├── assets/ # 静态资源文件
467
+ ├── components/ # 公共组件
468
+ ├── router/ # 路由配置
469
+ ├── stores/ # 状态管理
470
+ ├── utils/ # 工具函数
471
+ ├── views/ # 页面视图
472
+ ├── App.vue # 根组件
473
+ └── main.js # 入口文件
474
+ \`\`\`
475
+
476
+ ## 命令说明
477
+
478
+ - \`npm run dev\` - 启动开发服务器
479
+ - \`npm run build\` - 构建生产版本
480
+ - \`npm run preview\` - 预览生产构建
481
+ - \`npm run lint\` - 代码检查
482
+ - \`npm run format\` - 代码格式化
483
+
484
+ ## 许可证
485
+
486
+ MIT License
487
+ `;
488
+
489
+ writeFile(path.join(projectPath, 'README.md'), readmeContent);
490
+ }
491
+
492
+ /**
493
+ * 安装依赖
494
+ */
495
+ async function installDependencies(projectPath) {
496
+ console.log('📦 安装依赖包...');
497
+
498
+ const success = executeCommand('npm install', projectPath);
499
+
500
+ if (!success) {
501
+ console.warn('⚠️ 依赖安装失败,请手动运行: npm install');
502
+ }
503
503
  }