@xubill/xx-cli 2.0.4
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.md +181 -0
- package/bin/cli.js +89 -0
- package/lib/core/base-plugin.js +292 -0
- package/lib/core/index.js +550 -0
- package/lib/plugins/ai.js +295 -0
- package/lib/plugins/config-manager.js +165 -0
- package/lib/plugins/history.js +108 -0
- package/lib/plugins/plugin-manager.js +700 -0
- package/lib/utils/config-manager.js +185 -0
- package/lib/utils/history-manager.js +119 -0
- package/lib/utils/logger.js +28 -0
- package/lib/utils/plugin-config.js +158 -0
- package/lib/utils/plugins-helper.js +276 -0
- package/lib/utils/transformers/getInput.js +76 -0
- package/lib/utils/transformers/index.js +43 -0
- package/lib/utils/transformers/renderLists.js +94 -0
- package/lib/utils/transformers/sfcMaterial.js +113 -0
- package/lib/utils/transformers/transformFilter.js +95 -0
- package/lib/utils/transformers/transformList.js +120 -0
- package/lib/utils/transformers/transformMock.js +43 -0
- package/lib/utils/transformers/transformRoutes.js +36 -0
- package/lib/utils/transformers/transformTable.js +81 -0
- package/lib/utils/transformers/transformTemplate.js +129 -0
- package/lib/utils/validator.js +96 -0
- package/package.json +68 -0
- package/plugin-development-new.md +565 -0
- package/plugin-development-old.md +447 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件辅助工具
|
|
3
|
+
* 提供与 BasePlugin 相同的通用功能,供新的插件实现方式使用
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const ConfigManager = require('./config-manager');
|
|
7
|
+
const chalk = require('chalk').default;
|
|
8
|
+
const ora = require('ora').default;;
|
|
9
|
+
const clipboardy = require('clipboardy').default;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 插件辅助类
|
|
13
|
+
* @param {string} pluginName - 插件名称
|
|
14
|
+
* @param {Object} options - 选项
|
|
15
|
+
*/
|
|
16
|
+
class PluginsHelper {
|
|
17
|
+
constructor(pluginName, options = {}) {
|
|
18
|
+
this.pluginName = pluginName;
|
|
19
|
+
this.homeDir = process.env.HOME || process.env.USERPROFILE || process.cwd();
|
|
20
|
+
this.configManager = new ConfigManager(pluginName, options);
|
|
21
|
+
this.spinner = null;
|
|
22
|
+
this.progressTotal = 0;
|
|
23
|
+
this.progressCurrent = 0;
|
|
24
|
+
this.hooks = {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 显示加载状态
|
|
29
|
+
* @param {string} text - 加载文本
|
|
30
|
+
*/
|
|
31
|
+
startLoading(text) {
|
|
32
|
+
this.spinner = ora(text).start();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 停止加载状态
|
|
37
|
+
* @param {string} text - 成功文本
|
|
38
|
+
*/
|
|
39
|
+
stopLoading(text) {
|
|
40
|
+
if (this.spinner) {
|
|
41
|
+
this.spinner.succeed(text);
|
|
42
|
+
this.spinner = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 显示错误状态
|
|
48
|
+
* @param {string} text - 错误文本
|
|
49
|
+
*/
|
|
50
|
+
showError(text) {
|
|
51
|
+
if (this.spinner) {
|
|
52
|
+
this.spinner.fail(text);
|
|
53
|
+
this.spinner = null;
|
|
54
|
+
} else {
|
|
55
|
+
console.error(chalk.red(`❌ ${text}`));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 启动进度条
|
|
61
|
+
* @param {string} text - 进度条文本
|
|
62
|
+
* @param {number} total - 总进度值
|
|
63
|
+
*/
|
|
64
|
+
startProgressBar(text, total = 100) {
|
|
65
|
+
this.spinner = ora({
|
|
66
|
+
text,
|
|
67
|
+
spinner: 'arc',
|
|
68
|
+
color: 'cyan'
|
|
69
|
+
}).start();
|
|
70
|
+
this.progressTotal = total;
|
|
71
|
+
this.progressCurrent = 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 更新进度条
|
|
76
|
+
* @param {number} current - 当前进度值
|
|
77
|
+
* @param {string} text - 进度条文本
|
|
78
|
+
*/
|
|
79
|
+
updateProgressBar(current, text) {
|
|
80
|
+
if (this.spinner && this.progressTotal > 0) {
|
|
81
|
+
this.progressCurrent = current;
|
|
82
|
+
const percentage = Math.min(Math.round((current / this.progressTotal) * 100), 100);
|
|
83
|
+
this.spinner.text = `${text || ''} ${percentage}%`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 停止进度条
|
|
89
|
+
* @param {string} text - 完成文本
|
|
90
|
+
*/
|
|
91
|
+
stopProgressBar(text) {
|
|
92
|
+
if (this.spinner) {
|
|
93
|
+
this.spinner.succeed(text);
|
|
94
|
+
this.spinner = null;
|
|
95
|
+
this.progressTotal = 0;
|
|
96
|
+
this.progressCurrent = 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 显示成功信息
|
|
102
|
+
* @param {string} text - 成功文本
|
|
103
|
+
*/
|
|
104
|
+
showSuccess(text) {
|
|
105
|
+
console.log(chalk.green(`✅ ${text}`));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 显示警告信息
|
|
110
|
+
* @param {string} text - 警告文本
|
|
111
|
+
*/
|
|
112
|
+
showWarning(text) {
|
|
113
|
+
console.log(chalk.yellow(`⚠️ ${text}`));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 显示信息
|
|
118
|
+
* @param {string} text - 信息文本
|
|
119
|
+
*/
|
|
120
|
+
showInfo(text) {
|
|
121
|
+
console.log(chalk.blue(`${text}`));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 加载配置
|
|
126
|
+
* @param {string} configName - 配置名称
|
|
127
|
+
* @param {Object} cliOptions - 命令行选项
|
|
128
|
+
* @returns {Object} 合并后的配置对象
|
|
129
|
+
*/
|
|
130
|
+
loadConfig(configName = 'config', cliOptions = {}) {
|
|
131
|
+
return this.configManager.loadConfig(configName, cliOptions);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 保存配置
|
|
136
|
+
* @param {Object} config - 配置对象
|
|
137
|
+
* @param {string} configName - 配置名称
|
|
138
|
+
* @param {boolean} isGlobal - 是否保存到全局配置
|
|
139
|
+
*/
|
|
140
|
+
saveConfig(config, configName = 'config', isGlobal = true) {
|
|
141
|
+
this.configManager.saveConfig(config, configName, isGlobal);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 验证配置
|
|
146
|
+
* @param {Object} config - 配置对象
|
|
147
|
+
* @param {Object} schema - 配置 schema
|
|
148
|
+
* @returns {Object} 验证结果
|
|
149
|
+
*/
|
|
150
|
+
validateConfig(config, schema) {
|
|
151
|
+
return this.configManager.validateConfig(config, schema);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 错误处理
|
|
156
|
+
* @param {Error} error - 错误对象
|
|
157
|
+
* @param {string} message - 错误消息
|
|
158
|
+
*/
|
|
159
|
+
handleError(error, message = '操作失败') {
|
|
160
|
+
this.showError(`${message}: ${error.message}`);
|
|
161
|
+
// 可以添加错误日志记录等逻辑
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 执行异步操作
|
|
166
|
+
* @param {Function} fn - 异步函数
|
|
167
|
+
* @param {string} loadingText - 加载文本
|
|
168
|
+
* @param {string} successText - 成功文本
|
|
169
|
+
* @param {string} errorText - 错误文本
|
|
170
|
+
* @returns {Promise<any>}
|
|
171
|
+
*/
|
|
172
|
+
async executeAsync(fn, loadingText, successText, errorText) {
|
|
173
|
+
try {
|
|
174
|
+
this.startLoading(loadingText);
|
|
175
|
+
const result = await fn();
|
|
176
|
+
this.stopLoading(successText);
|
|
177
|
+
return result;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
this.handleError(error, errorText);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* 注册钩子
|
|
186
|
+
* @param {string} event - 事件名称
|
|
187
|
+
* @param {Function} callback - 回调函数
|
|
188
|
+
*/
|
|
189
|
+
registerHook(event, callback) {
|
|
190
|
+
if (!this.hooks) {
|
|
191
|
+
this.hooks = {};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!this.hooks[event]) {
|
|
195
|
+
this.hooks[event] = [];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.hooks[event].push(callback);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 触发钩子
|
|
203
|
+
* @param {string} event - 事件名称
|
|
204
|
+
* @param {*} data - 事件数据
|
|
205
|
+
* @returns {Promise<Array>} 钩子执行结果
|
|
206
|
+
*/
|
|
207
|
+
async triggerHook(event, data) {
|
|
208
|
+
if (!this.hooks || !this.hooks[event]) {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const results = [];
|
|
213
|
+
for (const callback of this.hooks[event]) {
|
|
214
|
+
try {
|
|
215
|
+
const result = await callback(data);
|
|
216
|
+
results.push(result);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
this.handleError(error, `执行钩子 ${event} 时出错`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return results;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 检查是否注册了指定钩子
|
|
227
|
+
* @param {string} event - 事件名称
|
|
228
|
+
* @returns {boolean} 是否注册了钩子
|
|
229
|
+
*/
|
|
230
|
+
hasHook(event) {
|
|
231
|
+
return this.hooks && this.hooks[event] && this.hooks[event].length > 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 复制文本到剪贴板
|
|
236
|
+
* @param {string} text - 要复制的文本
|
|
237
|
+
* @param {string} successMessage - 成功消息
|
|
238
|
+
* @returns {Promise<boolean>} 是否复制成功
|
|
239
|
+
*/
|
|
240
|
+
async copyToClipboard(text, successMessage) {
|
|
241
|
+
try {
|
|
242
|
+
// 尝试不同的 clipboardy API 调用方式
|
|
243
|
+
if (clipboardy.default && typeof clipboardy.default.write === 'function') {
|
|
244
|
+
await clipboardy.default.write(text);
|
|
245
|
+
} else if (typeof clipboardy.write === 'function') {
|
|
246
|
+
await clipboardy.write(text);
|
|
247
|
+
} else if (typeof clipboardy.writeSync === 'function') {
|
|
248
|
+
clipboardy.writeSync(text);
|
|
249
|
+
} else {
|
|
250
|
+
throw new Error('clipboardy API 不可用');
|
|
251
|
+
}
|
|
252
|
+
if (successMessage) {
|
|
253
|
+
this.showSuccess(successMessage);
|
|
254
|
+
}
|
|
255
|
+
return true;
|
|
256
|
+
} catch (error) {
|
|
257
|
+
this.showWarning(`复制到剪贴板失败: ${error.message}`);
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* 创建插件辅助实例
|
|
265
|
+
* @param {string} pluginName - 插件名称
|
|
266
|
+
* @param {Object} options - 选项
|
|
267
|
+
* @returns {PluginsHelper} 插件辅助实例
|
|
268
|
+
*/
|
|
269
|
+
function createPluginsHelper(pluginName, options = {}) {
|
|
270
|
+
return new PluginsHelper(pluginName, options);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
module.exports = {
|
|
274
|
+
PluginsHelper,
|
|
275
|
+
createPluginsHelper
|
|
276
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 获取输入配置
|
|
3
|
+
* 处理用户输入的模板配置,转换为标准格式
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 处理模板配置
|
|
8
|
+
* @param {Object} config - 原始模板配置
|
|
9
|
+
* @returns {Object} 处理后的模板配置
|
|
10
|
+
*/
|
|
11
|
+
function processTemplateConfig(config) {
|
|
12
|
+
// 确保配置对象存在
|
|
13
|
+
if (!config) {
|
|
14
|
+
return {
|
|
15
|
+
dir: '.lists',
|
|
16
|
+
pages: {},
|
|
17
|
+
routes: { isRender: false },
|
|
18
|
+
mock: false
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 处理默认值
|
|
23
|
+
return {
|
|
24
|
+
dir: config.dir || '.lists',
|
|
25
|
+
pages: config.pages || {},
|
|
26
|
+
routes: {
|
|
27
|
+
isRender: config.routes?.isRender ?? false,
|
|
28
|
+
...config.routes
|
|
29
|
+
},
|
|
30
|
+
mock: config.mock ?? false,
|
|
31
|
+
templateType: config.templateType || 'element-ui'
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 处理页面配置
|
|
37
|
+
* @param {Object} pageConfig - 原始页面配置
|
|
38
|
+
* @returns {Object} 处理后的页面配置
|
|
39
|
+
*/
|
|
40
|
+
function processPageConfig(pageConfig) {
|
|
41
|
+
// 确保配置对象存在
|
|
42
|
+
if (!pageConfig) {
|
|
43
|
+
return {
|
|
44
|
+
template: {
|
|
45
|
+
cn: '列表页面',
|
|
46
|
+
en: 'list',
|
|
47
|
+
top: false,
|
|
48
|
+
bottom: false,
|
|
49
|
+
select: false,
|
|
50
|
+
btn: []
|
|
51
|
+
},
|
|
52
|
+
filter: {},
|
|
53
|
+
table: {}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 处理默认值
|
|
58
|
+
return {
|
|
59
|
+
template: {
|
|
60
|
+
cn: pageConfig.template?.cn || '列表页面',
|
|
61
|
+
en: pageConfig.template?.en || 'list',
|
|
62
|
+
top: pageConfig.template?.top ?? false,
|
|
63
|
+
bottom: pageConfig.template?.bottom ?? false,
|
|
64
|
+
select: pageConfig.template?.select ?? false,
|
|
65
|
+
btn: pageConfig.template?.btn || [],
|
|
66
|
+
...pageConfig.template
|
|
67
|
+
},
|
|
68
|
+
filter: pageConfig.filter || {},
|
|
69
|
+
table: pageConfig.table || {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = {
|
|
74
|
+
processTemplateConfig,
|
|
75
|
+
processPageConfig
|
|
76
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transformers 统一入口
|
|
3
|
+
* 导出所有转换逻辑方法
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导出筛选器转换
|
|
7
|
+
const { transformFilter, generateFieldName } = require('./transformFilter');
|
|
8
|
+
|
|
9
|
+
// 导出表格转换
|
|
10
|
+
const { transformTable } = require('./transformTable');
|
|
11
|
+
|
|
12
|
+
// 导出列表页面转换
|
|
13
|
+
const { transformList } = require('./transformList');
|
|
14
|
+
|
|
15
|
+
// 导出路由转换
|
|
16
|
+
const { transformRoutes } = require('./transformRoutes');
|
|
17
|
+
|
|
18
|
+
// 导出 Mock 数据转换
|
|
19
|
+
const { transformMock } = require('./transformMock');
|
|
20
|
+
|
|
21
|
+
// 导出渲染列表页面
|
|
22
|
+
const { renderLists } = require('./renderLists');
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
// 筛选器相关
|
|
26
|
+
transformFilter,
|
|
27
|
+
generateFieldName,
|
|
28
|
+
|
|
29
|
+
// 表格相关
|
|
30
|
+
transformTable,
|
|
31
|
+
|
|
32
|
+
// 列表页面相关
|
|
33
|
+
transformList,
|
|
34
|
+
|
|
35
|
+
// 路由相关
|
|
36
|
+
transformRoutes,
|
|
37
|
+
|
|
38
|
+
// Mock 数据相关
|
|
39
|
+
transformMock,
|
|
40
|
+
|
|
41
|
+
// 渲染相关
|
|
42
|
+
renderLists
|
|
43
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 渲染列表页面的主入口
|
|
3
|
+
* 协调各个转换模块,生成完整的页面文件
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导入转换模块
|
|
7
|
+
const { processTemplateConfig, processPageConfig } = require('./getInput');
|
|
8
|
+
const { getSfcMaterial, getTransformersByType } = require('./sfcMaterial');
|
|
9
|
+
const { transformList } = require('./transformList');
|
|
10
|
+
const { transformRoutes } = require('./transformRoutes');
|
|
11
|
+
const { transformMock } = require('./transformMock');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 渲染列表页面
|
|
15
|
+
* @param {Object} config - 模板配置
|
|
16
|
+
* @returns {Object} 生成的文件内容
|
|
17
|
+
*/
|
|
18
|
+
function renderLists(config) {
|
|
19
|
+
// 处理模板配置
|
|
20
|
+
const processedConfig = processTemplateConfig(config);
|
|
21
|
+
|
|
22
|
+
// 获取模板类型
|
|
23
|
+
const templateType = processedConfig.templateType;
|
|
24
|
+
|
|
25
|
+
// 获取组件材料
|
|
26
|
+
const material = getSfcMaterial(templateType);
|
|
27
|
+
|
|
28
|
+
// 获取转换函数
|
|
29
|
+
const transformers = getTransformersByType(templateType);
|
|
30
|
+
|
|
31
|
+
const results = {
|
|
32
|
+
pages: {},
|
|
33
|
+
routes: null,
|
|
34
|
+
mock: {}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// 处理每个页面
|
|
38
|
+
const pages = processedConfig.pages;
|
|
39
|
+
for (const [pageName, pageConfig] of Object.entries(pages)) {
|
|
40
|
+
// 处理页面配置
|
|
41
|
+
const processedPageConfig = processPageConfig(pageConfig);
|
|
42
|
+
const { template, filter, table } = processedPageConfig;
|
|
43
|
+
|
|
44
|
+
// 生成 Vue 文件内容
|
|
45
|
+
const vueContent = transformList(template, filter, table, material);
|
|
46
|
+
results.pages[pageName] = {
|
|
47
|
+
content: vueContent,
|
|
48
|
+
fileName: `${template.en}.vue`
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// 生成 Mock 数据(如果需要)
|
|
52
|
+
if (processedConfig.mock) {
|
|
53
|
+
const mockContent = transformMock(template);
|
|
54
|
+
results.mock[pageName] = {
|
|
55
|
+
content: mockContent,
|
|
56
|
+
fileName: `${template.en}.mock.js`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 生成路由配置(如果需要)
|
|
62
|
+
if (processedConfig.routes?.isRender) {
|
|
63
|
+
const routesContent = transformRoutes(processedConfig);
|
|
64
|
+
results.routes = {
|
|
65
|
+
content: routesContent,
|
|
66
|
+
fileName: 'routes.js'
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return results;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 渲染单个页面
|
|
75
|
+
* @param {Object} pageConfig - 页面配置
|
|
76
|
+
* @param {string} templateType - 模板类型
|
|
77
|
+
* @returns {string} Vue 文件内容
|
|
78
|
+
*/
|
|
79
|
+
function renderSinglePage(pageConfig, templateType = 'element-ui') {
|
|
80
|
+
// 处理页面配置
|
|
81
|
+
const processedPageConfig = processPageConfig(pageConfig);
|
|
82
|
+
const { template, filter, table } = processedPageConfig;
|
|
83
|
+
|
|
84
|
+
// 获取组件材料
|
|
85
|
+
const material = getSfcMaterial(templateType);
|
|
86
|
+
|
|
87
|
+
// 生成 Vue 文件内容
|
|
88
|
+
return transformList(template, filter, table, material);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
renderLists,
|
|
93
|
+
renderSinglePage
|
|
94
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组件材料管理
|
|
3
|
+
* 定义不同模板类型的组件标签映射
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 获取组件材料
|
|
8
|
+
* @param {string} templateType - 模板类型
|
|
9
|
+
* @returns {Object} 组件材料配置
|
|
10
|
+
*/
|
|
11
|
+
function getSfcMaterial(templateType = 'element-ui') {
|
|
12
|
+
const materials = {
|
|
13
|
+
'element-ui': {
|
|
14
|
+
form: {
|
|
15
|
+
wrapper: 'el-form',
|
|
16
|
+
item: 'el-form-item',
|
|
17
|
+
input: 'el-input',
|
|
18
|
+
select: 'el-select',
|
|
19
|
+
option: 'el-option',
|
|
20
|
+
datePicker: 'el-date-picker',
|
|
21
|
+
button: 'el-button'
|
|
22
|
+
},
|
|
23
|
+
table: {
|
|
24
|
+
wrapper: 'el-table',
|
|
25
|
+
column: 'el-table-column',
|
|
26
|
+
pagination: 'el-pagination'
|
|
27
|
+
},
|
|
28
|
+
layout: {
|
|
29
|
+
container: 'el-container',
|
|
30
|
+
header: 'el-header',
|
|
31
|
+
main: 'el-main',
|
|
32
|
+
footer: 'el-footer',
|
|
33
|
+
row: 'el-row',
|
|
34
|
+
col: 'el-col'
|
|
35
|
+
},
|
|
36
|
+
button: 'el-button'
|
|
37
|
+
},
|
|
38
|
+
'antd': {
|
|
39
|
+
form: {
|
|
40
|
+
wrapper: 'a-form',
|
|
41
|
+
item: 'a-form-item',
|
|
42
|
+
input: 'a-input',
|
|
43
|
+
select: 'a-select',
|
|
44
|
+
option: 'a-select-option',
|
|
45
|
+
datePicker: 'a-date-picker',
|
|
46
|
+
button: 'a-button'
|
|
47
|
+
},
|
|
48
|
+
table: {
|
|
49
|
+
wrapper: 'a-table',
|
|
50
|
+
column: 'a-table-column',
|
|
51
|
+
pagination: 'a-pagination'
|
|
52
|
+
},
|
|
53
|
+
layout: {
|
|
54
|
+
container: 'a-layout',
|
|
55
|
+
header: 'a-layout-header',
|
|
56
|
+
main: 'a-layout-content',
|
|
57
|
+
footer: 'a-layout-footer',
|
|
58
|
+
row: 'a-row',
|
|
59
|
+
col: 'a-col'
|
|
60
|
+
},
|
|
61
|
+
button: 'a-button'
|
|
62
|
+
},
|
|
63
|
+
'element-plus': {
|
|
64
|
+
form: {
|
|
65
|
+
wrapper: 'el-form',
|
|
66
|
+
item: 'el-form-item',
|
|
67
|
+
input: 'el-input',
|
|
68
|
+
select: 'el-select',
|
|
69
|
+
option: 'el-option',
|
|
70
|
+
datePicker: 'el-date-picker',
|
|
71
|
+
button: 'el-button'
|
|
72
|
+
},
|
|
73
|
+
table: {
|
|
74
|
+
wrapper: 'el-table',
|
|
75
|
+
column: 'el-table-column',
|
|
76
|
+
pagination: 'el-pagination'
|
|
77
|
+
},
|
|
78
|
+
layout: {
|
|
79
|
+
container: 'el-container',
|
|
80
|
+
header: 'el-header',
|
|
81
|
+
main: 'el-main',
|
|
82
|
+
footer: 'el-footer',
|
|
83
|
+
row: 'el-row',
|
|
84
|
+
col: 'el-col'
|
|
85
|
+
},
|
|
86
|
+
button: 'el-button'
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return materials[templateType] || materials['element-ui'];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 根据模板类型获取转换器
|
|
95
|
+
* @param {string} templateType - 模板类型
|
|
96
|
+
* @returns {Object} 转换器映射
|
|
97
|
+
*/
|
|
98
|
+
function getTransformersByType(templateType = 'element-ui') {
|
|
99
|
+
// 这里可以根据需要返回不同模板类型的特定转换器
|
|
100
|
+
// 目前使用通用转换器,后续可以扩展
|
|
101
|
+
return {
|
|
102
|
+
list: require('./transformList'),
|
|
103
|
+
filter: require('./transformFilter'),
|
|
104
|
+
table: require('./transformTable'),
|
|
105
|
+
routes: require('./transformRoutes'),
|
|
106
|
+
mock: require('./transformMock')
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
getSfcMaterial,
|
|
112
|
+
getTransformersByType
|
|
113
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 筛选器转换逻辑
|
|
3
|
+
* 将筛选器配置转换为 HTML 内容
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 生成字段名
|
|
8
|
+
* @param {string} label - 标签名称
|
|
9
|
+
* @returns {string} 字段名
|
|
10
|
+
*/
|
|
11
|
+
function generateFieldName(label) {
|
|
12
|
+
// 中文标签映射
|
|
13
|
+
const chineseMap = {
|
|
14
|
+
'用户名': 'username',
|
|
15
|
+
'状态': 'status',
|
|
16
|
+
'创建时间': 'createTime',
|
|
17
|
+
'邮箱': 'email',
|
|
18
|
+
'手机号': 'phone',
|
|
19
|
+
'地址': 'address',
|
|
20
|
+
'ID': 'id',
|
|
21
|
+
'名称': 'name',
|
|
22
|
+
'类型': 'type',
|
|
23
|
+
'描述': 'description',
|
|
24
|
+
'备注': 'remark'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// 如果有映射,直接返回
|
|
28
|
+
if (chineseMap[label]) {
|
|
29
|
+
return chineseMap[label];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 否则,移除空格并转换为小写
|
|
33
|
+
return label.toLowerCase().replace(/\s+/g, '');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 生成筛选器内容
|
|
38
|
+
* @param {Object} filter - 筛选器配置
|
|
39
|
+
* @param {Object} material - 组件材料
|
|
40
|
+
* @returns {string} 筛选器 HTML 内容
|
|
41
|
+
*/
|
|
42
|
+
function transformFilter(filter, material) {
|
|
43
|
+
let content = '';
|
|
44
|
+
for (const [label, type] of Object.entries(filter || {})) {
|
|
45
|
+
// 生成英文字段名
|
|
46
|
+
const fieldName = generateFieldName(label);
|
|
47
|
+
switch (type) {
|
|
48
|
+
case 'input':
|
|
49
|
+
content += `
|
|
50
|
+
<${material.form.item} label="${label}">
|
|
51
|
+
<${material.form.input} v-model="searchForm.${fieldName}" placeholder="请输入${label}"></${material.form.input}>
|
|
52
|
+
</${material.form.item}>`;
|
|
53
|
+
break;
|
|
54
|
+
case 'select':
|
|
55
|
+
content += `
|
|
56
|
+
<${material.form.item} label="${label}">
|
|
57
|
+
<${material.form.select} v-model="searchForm.${fieldName}" placeholder="请选择${label}">
|
|
58
|
+
<${material.form.option} label="选项1" value="1"></${material.form.option}>
|
|
59
|
+
<${material.form.option} label="选项2" value="2"></${material.form.option}>
|
|
60
|
+
</${material.form.select}>
|
|
61
|
+
</${material.form.item}>`;
|
|
62
|
+
break;
|
|
63
|
+
case 'date':
|
|
64
|
+
content += `
|
|
65
|
+
<${material.form.item} label="${label}">
|
|
66
|
+
<${material.form.datePicker} v-model="searchForm.${fieldName}" type="date" placeholder="选择日期"></${material.form.datePicker}>
|
|
67
|
+
</${material.form.item}>`;
|
|
68
|
+
break;
|
|
69
|
+
case 'daterange':
|
|
70
|
+
content += `
|
|
71
|
+
<${material.form.item} label="${label}">
|
|
72
|
+
<${material.form.datePicker} v-model="searchForm.${fieldName}" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></${material.form.datePicker}>
|
|
73
|
+
</${material.form.item}>`;
|
|
74
|
+
break;
|
|
75
|
+
case 'datetime':
|
|
76
|
+
content += `
|
|
77
|
+
<${material.form.item} label="${label}">
|
|
78
|
+
<${material.form.datePicker} v-model="searchForm.${fieldName}" type="datetime" placeholder="选择日期时间"></${material.form.datePicker}>
|
|
79
|
+
</${material.form.item}>`;
|
|
80
|
+
break;
|
|
81
|
+
case 'datetimerange':
|
|
82
|
+
content += `
|
|
83
|
+
<${material.form.item} label="${label}">
|
|
84
|
+
<${material.form.datePicker} v-model="searchForm.${fieldName}" type="datetimerange" range-separator="至" start-placeholder="开始日期时间" end-placeholder="结束日期时间"></${material.form.datePicker}>
|
|
85
|
+
</${material.form.item}>`;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return content;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = {
|
|
93
|
+
transformFilter,
|
|
94
|
+
generateFieldName
|
|
95
|
+
};
|