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.
- package/README.en.md +414 -25
- package/README.md +460 -285
- package/bin/cli.js +3 -3
- package/bin/generator.js +502 -502
- package/bin/prompts.js +158 -158
- package/bin/utils.js +133 -133
- package/package.json +2 -2
- package/public/logo.png +0 -0
- package/src/App.vue +16 -16
- package/src/api/methods/department.js +36 -0
- package/src/api/methods/employee.js +22 -0
- package/src/api/methods/logError.js +8 -8
- package/src/api/methods/logOperation.js +8 -8
- package/src/api/methods/login.js +6 -6
- package/src/api/methods/position.js +26 -0
- package/src/api/methods/quartz.js +36 -36
- package/src/api/methods/region.js +16 -16
- package/src/api/methods/sysAccount.js +29 -29
- package/src/api/methods/sysDict.js +29 -29
- package/src/api/methods/sysDictItem.js +26 -26
- package/src/api/methods/sysMenu.js +42 -42
- package/src/api/methods/sysRole.js +35 -35
- package/src/api/methods/sysUser.js +25 -25
- package/src/api/methods/system.js +15 -15
- package/src/api/request.js +225 -225
- package/src/assets/css/style.css +2 -2
- package/src/assets/css/zcui.css +1023 -1023
- package/src/assets/imgs/logo.png +0 -0
- package/src/assets/imgs/md/console.png +0 -0
- package/src/assets/imgs/md/login.png +0 -0
- package/src/assets/imgs/md/menu.png +0 -0
- package/src/assets/imgs/md/serviceMonitoring.png +0 -0
- package/src/assets/imgs/md/statistics.png +0 -0
- package/src/components/FormTable.vue +5 -19
- package/src/components/IconPicker.vue +351 -351
- package/src/components/MainPage.vue +838 -838
- package/src/components/details/logErrorDetails.vue +58 -58
- package/src/components/details/logOperationDetails.vue +76 -76
- package/src/components/edit/QuartzEdit.vue +221 -221
- package/src/components/edit/SysAccountEdit.vue +185 -185
- package/src/components/edit/SysDictEdit.vue +116 -116
- package/src/components/edit/SysDictItemEdit.vue +136 -136
- package/src/components/edit/SysRoleEdit.vue +111 -111
- package/src/components/edit/organizationalStructure/DepartmentEdit.vue +162 -0
- package/src/components/edit/organizationalStructure/EmployeeEdit.vue +295 -0
- package/src/components/edit/organizationalStructure/PositionEdit.vue +166 -0
- package/src/components/edit/sysMenuEdit.vue +2 -1
- package/src/config/index.js +74 -74
- package/src/directives/permission.js +49 -49
- package/src/main.js +37 -37
- package/src/router/index.js +4 -6
- package/src/stores/config.js +43 -43
- package/src/stores/dict.js +33 -33
- package/src/stores/menu.js +81 -81
- package/src/stores/user.js +21 -21
- package/src/utils/baseEcharts.js +661 -661
- package/src/utils/dictTemplate.js +26 -26
- package/src/utils/regionUtils.js +173 -173
- package/src/utils/useFormCRUD.js +59 -59
- package/src/views/baiscstatis/center.vue +474 -474
- package/src/views/baiscstatis/iframePage.vue +29 -29
- package/src/views/baiscstatis/notFound.vue +192 -192
- package/src/views/console.vue +821 -821
- package/src/views/demo/button.vue +269 -269
- package/src/views/demo/importexport.vue +119 -119
- package/src/views/demo/region.vue +322 -322
- package/src/views/demo/statistics.vue +214 -214
- package/src/views/home.vue +6 -6
- package/src/views/login.vue +264 -149
- package/src/views/operations/log/logError.vue +78 -78
- package/src/views/operations/log/logLogin.vue +66 -66
- package/src/views/operations/log/logOperation.vue +103 -103
- package/src/views/operations/log/logQuartz.vue +56 -56
- package/src/views/operations/quartz.vue +179 -179
- package/src/views/operations/serviceMonitoring.vue +134 -134
- package/src/views/organizationalStructure/department.vue +194 -0
- package/src/views/organizationalStructure/employee.vue +234 -0
- package/src/views/organizationalStructure/position.vue +196 -0
- package/src/views/system/sysAccount.vue +128 -128
- package/src/views/system/sysDict.vue +159 -159
- package/src/views/system/sysDictItem.vue +118 -118
- package/src/views/system/sysMenu.vue +225 -225
- package/src/views/system/sysRole.vue +207 -207
- 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/bin/prompts.js
CHANGED
|
@@ -1,159 +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
|
-
}
|
|
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
159
|
}
|
package/bin/utils.js
CHANGED
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 脚手架工具函数
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { execSync } from 'child_process';
|
|
6
|
-
import fs from 'fs';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
|
|
10
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
const __dirname = path.dirname(__filename);
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 检查 Node.js 版本
|
|
15
|
-
*/
|
|
16
|
-
export function checkNodeVersion() {
|
|
17
|
-
const currentNodeVersion = process.versions.node;
|
|
18
|
-
const semver = currentNodeVersion.split('.');
|
|
19
|
-
const major = parseInt(semver[0], 10);
|
|
20
|
-
|
|
21
|
-
if (major < 16) {
|
|
22
|
-
console.error(`❌ 需要 Node.js 16.0.0 或更高版本,当前版本: ${currentNodeVersion}`);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 检查目录是否存在
|
|
29
|
-
*/
|
|
30
|
-
export function checkDirectoryExists(dirPath) {
|
|
31
|
-
return fs.existsSync(dirPath);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 创建目录
|
|
36
|
-
*/
|
|
37
|
-
export function createDirectory(dirPath) {
|
|
38
|
-
if (!checkDirectoryExists(dirPath)) {
|
|
39
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* 复制文件
|
|
45
|
-
*/
|
|
46
|
-
export function copyFile(sourcePath, targetPath) {
|
|
47
|
-
fs.copyFileSync(sourcePath, targetPath);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 复制目录
|
|
52
|
-
*/
|
|
53
|
-
export function copyDirectory(sourceDir, targetDir) {
|
|
54
|
-
createDirectory(targetDir);
|
|
55
|
-
|
|
56
|
-
const files = fs.readdirSync(sourceDir);
|
|
57
|
-
|
|
58
|
-
files.forEach(file => {
|
|
59
|
-
const sourcePath = path.join(sourceDir, file);
|
|
60
|
-
const targetPath = path.join(targetDir, file);
|
|
61
|
-
|
|
62
|
-
const stat = fs.statSync(sourcePath);
|
|
63
|
-
|
|
64
|
-
if (stat.isDirectory()) {
|
|
65
|
-
copyDirectory(sourcePath, targetPath);
|
|
66
|
-
} else {
|
|
67
|
-
copyFile(sourcePath, targetPath);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 读取模板文件
|
|
74
|
-
*/
|
|
75
|
-
export function readTemplateFile(templatePath) {
|
|
76
|
-
const fullPath = path.join(__dirname, '../templates', templatePath);
|
|
77
|
-
return fs.readFileSync(fullPath, 'utf8');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 写入文件
|
|
82
|
-
*/
|
|
83
|
-
export function writeFile(filePath, content) {
|
|
84
|
-
const dir = path.dirname(filePath);
|
|
85
|
-
createDirectory(dir);
|
|
86
|
-
fs.writeFileSync(filePath, content);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* 渲染模板
|
|
91
|
-
*/
|
|
92
|
-
export function renderTemplate(template, data) {
|
|
93
|
-
return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, key) => {
|
|
94
|
-
return data[key] || match;
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* 执行命令
|
|
100
|
-
*/
|
|
101
|
-
export function executeCommand(command, cwd) {
|
|
102
|
-
try {
|
|
103
|
-
execSync(command, {
|
|
104
|
-
cwd,
|
|
105
|
-
stdio: 'inherit',
|
|
106
|
-
encoding: 'utf8'
|
|
107
|
-
});
|
|
108
|
-
return true;
|
|
109
|
-
} catch (error) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* 获取项目根目录
|
|
116
|
-
*/
|
|
117
|
-
export function getProjectRoot() {
|
|
118
|
-
return path.join(__dirname, '..');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 验证项目名称
|
|
123
|
-
*/
|
|
124
|
-
export function validateProjectName(name) {
|
|
125
|
-
if (!name) {
|
|
126
|
-
throw new Error('项目名称不能为空');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
|
|
130
|
-
throw new Error('项目名称只能包含字母、数字、下划线和连字符,且必须以字母开头');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return true;
|
|
1
|
+
/**
|
|
2
|
+
* 脚手架工具函数
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 检查 Node.js 版本
|
|
15
|
+
*/
|
|
16
|
+
export function checkNodeVersion() {
|
|
17
|
+
const currentNodeVersion = process.versions.node;
|
|
18
|
+
const semver = currentNodeVersion.split('.');
|
|
19
|
+
const major = parseInt(semver[0], 10);
|
|
20
|
+
|
|
21
|
+
if (major < 16) {
|
|
22
|
+
console.error(`❌ 需要 Node.js 16.0.0 或更高版本,当前版本: ${currentNodeVersion}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 检查目录是否存在
|
|
29
|
+
*/
|
|
30
|
+
export function checkDirectoryExists(dirPath) {
|
|
31
|
+
return fs.existsSync(dirPath);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 创建目录
|
|
36
|
+
*/
|
|
37
|
+
export function createDirectory(dirPath) {
|
|
38
|
+
if (!checkDirectoryExists(dirPath)) {
|
|
39
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 复制文件
|
|
45
|
+
*/
|
|
46
|
+
export function copyFile(sourcePath, targetPath) {
|
|
47
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 复制目录
|
|
52
|
+
*/
|
|
53
|
+
export function copyDirectory(sourceDir, targetDir) {
|
|
54
|
+
createDirectory(targetDir);
|
|
55
|
+
|
|
56
|
+
const files = fs.readdirSync(sourceDir);
|
|
57
|
+
|
|
58
|
+
files.forEach(file => {
|
|
59
|
+
const sourcePath = path.join(sourceDir, file);
|
|
60
|
+
const targetPath = path.join(targetDir, file);
|
|
61
|
+
|
|
62
|
+
const stat = fs.statSync(sourcePath);
|
|
63
|
+
|
|
64
|
+
if (stat.isDirectory()) {
|
|
65
|
+
copyDirectory(sourcePath, targetPath);
|
|
66
|
+
} else {
|
|
67
|
+
copyFile(sourcePath, targetPath);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 读取模板文件
|
|
74
|
+
*/
|
|
75
|
+
export function readTemplateFile(templatePath) {
|
|
76
|
+
const fullPath = path.join(__dirname, '../templates', templatePath);
|
|
77
|
+
return fs.readFileSync(fullPath, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 写入文件
|
|
82
|
+
*/
|
|
83
|
+
export function writeFile(filePath, content) {
|
|
84
|
+
const dir = path.dirname(filePath);
|
|
85
|
+
createDirectory(dir);
|
|
86
|
+
fs.writeFileSync(filePath, content);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 渲染模板
|
|
91
|
+
*/
|
|
92
|
+
export function renderTemplate(template, data) {
|
|
93
|
+
return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, key) => {
|
|
94
|
+
return data[key] || match;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 执行命令
|
|
100
|
+
*/
|
|
101
|
+
export function executeCommand(command, cwd) {
|
|
102
|
+
try {
|
|
103
|
+
execSync(command, {
|
|
104
|
+
cwd,
|
|
105
|
+
stdio: 'inherit',
|
|
106
|
+
encoding: 'utf8'
|
|
107
|
+
});
|
|
108
|
+
return true;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 获取项目根目录
|
|
116
|
+
*/
|
|
117
|
+
export function getProjectRoot() {
|
|
118
|
+
return path.join(__dirname, '..');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 验证项目名称
|
|
123
|
+
*/
|
|
124
|
+
export function validateProjectName(name) {
|
|
125
|
+
if (!name) {
|
|
126
|
+
throw new Error('项目名称不能为空');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
|
|
130
|
+
throw new Error('项目名称只能包含字母、数字、下划线和连字符,且必须以字母开头');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return true;
|
|
134
134
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zant-admin",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "基于 Vue 3 + Vite + Ant Design Vue 的前端管理系统脚手架",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "基于 Vue 3.5 + Vite + Ant Design Vue 的前端管理系统脚手架",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"zant-admin": "./bin/cli.js"
|
package/public/logo.png
CHANGED
|
Binary file
|
package/src/App.vue
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<a-config-provider :locale="localeStore.locale">
|
|
3
|
-
<section id="app">
|
|
4
|
-
<router-view />
|
|
5
|
-
</section>
|
|
6
|
-
</a-config-provider>
|
|
7
|
-
</template>
|
|
8
|
-
<style></style>
|
|
9
|
-
|
|
10
|
-
<script setup>
|
|
11
|
-
import { configStore } from './stores/config'
|
|
12
|
-
import { dictStore } from './stores/dict'
|
|
13
|
-
const localeStore = configStore()
|
|
14
|
-
const dict = dictStore()
|
|
15
|
-
dict.initDictList()
|
|
16
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<a-config-provider :locale="localeStore.locale">
|
|
3
|
+
<section id="app">
|
|
4
|
+
<router-view />
|
|
5
|
+
</section>
|
|
6
|
+
</a-config-provider>
|
|
7
|
+
</template>
|
|
8
|
+
<style></style>
|
|
9
|
+
|
|
10
|
+
<script setup>
|
|
11
|
+
import { configStore } from './stores/config'
|
|
12
|
+
import { dictStore } from './stores/dict'
|
|
13
|
+
const localeStore = configStore()
|
|
14
|
+
const dict = dictStore()
|
|
15
|
+
dict.initDictList()
|
|
16
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { get, post } from '@/api/request'
|
|
2
|
+
|
|
3
|
+
const department = {
|
|
4
|
+
// 获取下拉框Tree选择框数据无顶级
|
|
5
|
+
getTreeSelectNotopdepartment() {
|
|
6
|
+
return get('department/getTreeSelectNotopdepartment')
|
|
7
|
+
},
|
|
8
|
+
// 获取下拉框Tree选择框数据
|
|
9
|
+
getTreeSelectdepartment() {
|
|
10
|
+
return get('department/getTreeSelectdepartment')
|
|
11
|
+
},
|
|
12
|
+
// 根据id获取信息
|
|
13
|
+
get(params) {
|
|
14
|
+
return get('department/get', params)
|
|
15
|
+
},
|
|
16
|
+
// 新增
|
|
17
|
+
add(params) {
|
|
18
|
+
return post('department/add', params)
|
|
19
|
+
},
|
|
20
|
+
// 修改
|
|
21
|
+
update(params) {
|
|
22
|
+
return post('department/update', params)
|
|
23
|
+
},
|
|
24
|
+
// 获取组织树
|
|
25
|
+
getdepartmentTree() {
|
|
26
|
+
return get('department/getdepartmentTree')
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
//修改启用
|
|
30
|
+
updateIsEnable(params) {
|
|
31
|
+
return get('department/updateIsEnable', params)
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default department
|