zant-admin 1.0.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.
- package/README.en.md +36 -0
- package/README.md +248 -0
- package/SCAFFOLD_README.md +215 -0
- package/bin/cli.js +99 -0
- package/bin/generator.js +503 -0
- package/bin/prompts.js +159 -0
- package/bin/utils.js +134 -0
- package/package.json +74 -0
- package/public/logo.png +0 -0
- package/src/App.vue +16 -0
- package/src/api/methods/logError.js +8 -0
- package/src/api/methods/logOperation.js +8 -0
- package/src/api/methods/login.js +6 -0
- package/src/api/methods/quartz.js +36 -0
- package/src/api/methods/region.js +16 -0
- package/src/api/methods/sysAccount.js +30 -0
- package/src/api/methods/sysDict.js +29 -0
- package/src/api/methods/sysDictItem.js +26 -0
- package/src/api/methods/sysMenu.js +42 -0
- package/src/api/methods/sysRole.js +35 -0
- package/src/api/methods/sysUser.js +25 -0
- package/src/api/methods/system.js +16 -0
- package/src/api/request.js +225 -0
- package/src/assets/css/style.css +70 -0
- package/src/assets/css/zcui.css +340 -0
- package/src/assets/imgs/loginbackground.svg +69 -0
- package/src/assets/imgs/logo.png +0 -0
- package/src/assets/imgs/md/1.png +0 -0
- package/src/assets/imgs/md/10.png +0 -0
- package/src/assets/imgs/md/11.png +0 -0
- package/src/assets/imgs/md/2.png +0 -0
- package/src/assets/imgs/md/3.png +0 -0
- package/src/assets/imgs/md/4.png +0 -0
- package/src/assets/imgs/md/5.png +0 -0
- package/src/assets/imgs/md/6.png +0 -0
- package/src/assets/imgs/md/7.png +0 -0
- package/src/assets/imgs/md/8.png +0 -0
- package/src/assets/imgs/md/9.png +0 -0
- package/src/components/FormTable.vue +875 -0
- package/src/components/IconPicker.vue +344 -0
- package/src/components/MainPage.vue +957 -0
- package/src/components/details/logErrorDetails.vue +58 -0
- package/src/components/details/logOperationDetails.vue +76 -0
- package/src/components/edit/QuartzEdit.vue +221 -0
- package/src/components/edit/SysAccountEdit.vue +178 -0
- package/src/components/edit/SysDictEdit.vue +114 -0
- package/src/components/edit/SysDictItemEdit.vue +134 -0
- package/src/components/edit/SysRoleEdit.vue +109 -0
- package/src/components/edit/sysMenuEdit.vue +305 -0
- package/src/config/index.js +74 -0
- package/src/directives/permission.js +45 -0
- package/src/main.js +38 -0
- package/src/router/index.js +270 -0
- package/src/stores/config.js +37 -0
- package/src/stores/dict.js +33 -0
- package/src/stores/menu.js +57 -0
- package/src/stores/user.js +21 -0
- package/src/utils/baseEcharts.js +661 -0
- package/src/utils/dictTemplate.js +26 -0
- package/src/utils/regionUtils.js +169 -0
- package/src/utils/useFormCRUD.js +60 -0
- package/src/views/baiscstatis/center.vue +463 -0
- package/src/views/baiscstatis/iframePage.vue +31 -0
- package/src/views/baiscstatis/notFound.vue +192 -0
- package/src/views/console.vue +771 -0
- package/src/views/demo/importexport.vue +123 -0
- package/src/views/demo/region.vue +240 -0
- package/src/views/demo/statistics.vue +195 -0
- package/src/views/home.vue +7 -0
- package/src/views/login.vue +272 -0
- package/src/views/operations/log/logError.vue +78 -0
- package/src/views/operations/log/logLogin.vue +66 -0
- package/src/views/operations/log/logOperation.vue +103 -0
- package/src/views/operations/log/logQuartz.vue +57 -0
- package/src/views/operations/quartz.vue +181 -0
- package/src/views/operations/serviceMonitoring.vue +134 -0
- package/src/views/system/sysAccount.vue +123 -0
- package/src/views/system/sysDict.vue +156 -0
- package/src/views/system/sysDictItem.vue +118 -0
- package/src/views/system/sysMenu.vue +223 -0
- package/src/views/system/sysRole.vue +184 -0
- package/templates/env.production +2 -0
package/bin/generator.js
ADDED
|
@@ -0,0 +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
|
+
}
|
|
503
|
+
}
|
package/bin/prompts.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 交互式命令行提示
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 创建交互式命令行界面
|
|
9
|
+
*/
|
|
10
|
+
export function createPromptInterface() {
|
|
11
|
+
const rl = readline.createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return rl;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 询问问题
|
|
21
|
+
*/
|
|
22
|
+
export function question(rl, query) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
rl.question(query, resolve);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 关闭命令行界面
|
|
30
|
+
*/
|
|
31
|
+
export function closePrompt(rl) {
|
|
32
|
+
rl.close();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 收集项目配置信息
|
|
37
|
+
*/
|
|
38
|
+
export async function collectProjectConfig(projectName) {
|
|
39
|
+
const rl = createPromptInterface();
|
|
40
|
+
|
|
41
|
+
console.log('\n🎯 项目配置向导');
|
|
42
|
+
console.log('='.repeat(50));
|
|
43
|
+
|
|
44
|
+
const config = {
|
|
45
|
+
projectName,
|
|
46
|
+
description: '',
|
|
47
|
+
author: '',
|
|
48
|
+
template: 'default',
|
|
49
|
+
features: []
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
// 询问项目描述
|
|
54
|
+
config.description = await question(rl, '📝 请输入项目描述: ') || '基于 Vue 3 + Vite + Ant Design Vue 的前端管理系统';
|
|
55
|
+
|
|
56
|
+
// 询问作者名称
|
|
57
|
+
config.author = await question(rl, '👤 请输入作者名称 (可选): ');
|
|
58
|
+
|
|
59
|
+
// 选择模板类型
|
|
60
|
+
console.log('\n📋 请选择项目模板:');
|
|
61
|
+
console.log('1. 默认模板 (推荐) - 包含完整的管理系统功能');
|
|
62
|
+
console.log('2. 基础模板 - 仅包含核心功能');
|
|
63
|
+
console.log('3. 完整模板 - 包含所有示例和高级功能');
|
|
64
|
+
|
|
65
|
+
const templateChoice = await question(rl, '请选择 (1-3, 默认 1): ');
|
|
66
|
+
|
|
67
|
+
switch (templateChoice) {
|
|
68
|
+
case '2':
|
|
69
|
+
config.template = 'basic';
|
|
70
|
+
break;
|
|
71
|
+
case '3':
|
|
72
|
+
config.template = 'full';
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
config.template = 'default';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 选择功能特性
|
|
79
|
+
console.log('\n✨ 请选择要包含的功能特性 (可多选):');
|
|
80
|
+
console.log('1. 用户管理模块');
|
|
81
|
+
console.log('2. 权限管理模块');
|
|
82
|
+
console.log('3. 数据可视化图表');
|
|
83
|
+
console.log('4. 文件上传功能');
|
|
84
|
+
console.log('5. 国际化支持');
|
|
85
|
+
|
|
86
|
+
const featureChoices = await question(rl, '请输入功能编号 (用逗号分隔, 如 1,3,5): ');
|
|
87
|
+
|
|
88
|
+
if (featureChoices) {
|
|
89
|
+
const choices = featureChoices.split(',').map(c => c.trim());
|
|
90
|
+
|
|
91
|
+
choices.forEach(choice => {
|
|
92
|
+
switch (choice) {
|
|
93
|
+
case '1':
|
|
94
|
+
config.features.push('user-management');
|
|
95
|
+
break;
|
|
96
|
+
case '2':
|
|
97
|
+
config.features.push('permission-management');
|
|
98
|
+
break;
|
|
99
|
+
case '3':
|
|
100
|
+
config.features.push('data-visualization');
|
|
101
|
+
break;
|
|
102
|
+
case '4':
|
|
103
|
+
config.features.push('file-upload');
|
|
104
|
+
break;
|
|
105
|
+
case '5':
|
|
106
|
+
config.features.push('i18n-support');
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 确认配置
|
|
113
|
+
console.log('\n📊 配置摘要:');
|
|
114
|
+
console.log(` 项目名称: ${config.projectName}`);
|
|
115
|
+
console.log(` 项目描述: ${config.description}`);
|
|
116
|
+
console.log(` 作者名称: ${config.author || '未指定'}`);
|
|
117
|
+
console.log(` 项目模板: ${getTemplateName(config.template)}`);
|
|
118
|
+
console.log(` 功能特性: ${config.features.length > 0 ? config.features.join(', ') : '默认功能'}`);
|
|
119
|
+
|
|
120
|
+
const confirm = await question(rl, '\n✅ 确认创建项目? (y/N): ');
|
|
121
|
+
|
|
122
|
+
if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
|
|
123
|
+
console.log('❌ 项目创建已取消');
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return config;
|
|
128
|
+
|
|
129
|
+
} finally {
|
|
130
|
+
closePrompt(rl);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 获取模板显示名称
|
|
136
|
+
*/
|
|
137
|
+
function getTemplateName(template) {
|
|
138
|
+
const templates = {
|
|
139
|
+
'default': '默认模板',
|
|
140
|
+
'basic': '基础模板',
|
|
141
|
+
'full': '完整模板'
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return templates[template] || template;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 询问是否跳过依赖安装
|
|
149
|
+
*/
|
|
150
|
+
export async function askSkipInstall() {
|
|
151
|
+
const rl = createPromptInterface();
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const answer = await question(rl, '\n📦 是否跳过依赖安装? (y/N): ');
|
|
155
|
+
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
156
|
+
} finally {
|
|
157
|
+
closePrompt(rl);
|
|
158
|
+
}
|
|
159
|
+
}
|