@xubill/xx-cli 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.
Potentially problematic release.
This version of @xubill/xx-cli might be problematic. Click here for more details.
- package/bin/cli.js +87 -0
- package/lib/core/base-plugin.js +292 -0
- package/lib/core/index.js +583 -0
- package/lib/utils/config-manager.js +185 -0
- package/lib/utils/history-manager.js +118 -0
- package/lib/utils/logger.js +28 -0
- package/lib/utils/plugin-config.js +158 -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 +62 -0
- package/readme.md +5 -0
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 列表页面转换逻辑
|
|
3
|
+
* 将页面配置转换为完整的 Vue 组件内容
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导入筛选器和表格转换方法
|
|
7
|
+
const { transformFilter } = require('./transformFilter');
|
|
8
|
+
const { transformTable } = require('./transformTable');
|
|
9
|
+
const { generateTemplateHeader, generateTemplateFooter, generateScriptSection, generateStyleSection } = require('./transformTemplate');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 生成 Vue 文件内容
|
|
13
|
+
* @param {Object} template - 页面模板配置
|
|
14
|
+
* @param {Object} filter - 筛选器配置
|
|
15
|
+
* @param {Object} table - 表格配置
|
|
16
|
+
* @param {Object} material - 组件材料
|
|
17
|
+
* @returns {string} Vue 文件内容
|
|
18
|
+
*/
|
|
19
|
+
function transformList(template, filter, table, material) {
|
|
20
|
+
// 使用默认材料(Element UI)
|
|
21
|
+
const defaultMaterial = {
|
|
22
|
+
form: {
|
|
23
|
+
wrapper: 'el-form',
|
|
24
|
+
item: 'el-form-item',
|
|
25
|
+
input: 'el-input',
|
|
26
|
+
select: 'el-select',
|
|
27
|
+
option: 'el-option',
|
|
28
|
+
datePicker: 'el-date-picker',
|
|
29
|
+
button: 'el-button'
|
|
30
|
+
},
|
|
31
|
+
table: {
|
|
32
|
+
wrapper: 'el-table',
|
|
33
|
+
column: 'el-table-column',
|
|
34
|
+
selection: 'selection',
|
|
35
|
+
index: 'index'
|
|
36
|
+
},
|
|
37
|
+
pagination: 'el-pagination',
|
|
38
|
+
tag: 'el-tag',
|
|
39
|
+
classes: {
|
|
40
|
+
container: 'list-container',
|
|
41
|
+
btnGroup: 'btn-group',
|
|
42
|
+
pagination: 'pagination'
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// 合并材料
|
|
47
|
+
const finalMaterial = { ...defaultMaterial, ...material };
|
|
48
|
+
|
|
49
|
+
// 生成筛选器内容
|
|
50
|
+
const filterContent = transformFilter(filter, finalMaterial);
|
|
51
|
+
|
|
52
|
+
// 生成表格内容
|
|
53
|
+
const tableContent = transformTable(table, finalMaterial);
|
|
54
|
+
|
|
55
|
+
// 生成按钮组
|
|
56
|
+
const btnGroupContent = template.btn?.map(btn => `<${finalMaterial.form.button} type="primary">${btn}</${finalMaterial.form.button}>`).join('\n ') || '';
|
|
57
|
+
|
|
58
|
+
// 生成模板内容
|
|
59
|
+
const templateContent = `<!-- ${template.cn} -->
|
|
60
|
+
<template>
|
|
61
|
+
<div class="${template.en}">
|
|
62
|
+
<!-- 顶部插槽 -->
|
|
63
|
+
${template.top ? '<slot name="filter-top"></slot>' : ''}
|
|
64
|
+
|
|
65
|
+
<!-- 筛选器 -->
|
|
66
|
+
<${finalMaterial.form.wrapper} :inline="true" :model="searchForm" class="demo-form-inline">
|
|
67
|
+
${filterContent}
|
|
68
|
+
<${finalMaterial.form.item}>
|
|
69
|
+
<${finalMaterial.form.button} type="primary" @click="handleSearch">查询</${finalMaterial.form.button}>
|
|
70
|
+
<${finalMaterial.form.button} @click="resetForm">重置</${finalMaterial.form.button}>
|
|
71
|
+
</${finalMaterial.form.item}>
|
|
72
|
+
</${finalMaterial.form.wrapper}>
|
|
73
|
+
|
|
74
|
+
<!-- 按钮组 -->
|
|
75
|
+
<div class="btn-group">
|
|
76
|
+
${btnGroupContent}
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<!-- 表格 -->
|
|
80
|
+
<${finalMaterial.table.wrapper}
|
|
81
|
+
v-loading="loading"
|
|
82
|
+
:data="tableData"
|
|
83
|
+
style="width: 100%"
|
|
84
|
+
${template.select ? '\n @selection-change="handleSelectionChange"' : ''}
|
|
85
|
+
>
|
|
86
|
+
${tableContent}
|
|
87
|
+
</${finalMaterial.table.wrapper}>
|
|
88
|
+
|
|
89
|
+
<!-- 底部插槽 -->
|
|
90
|
+
${template.bottom ? '<slot name="table-bottom"></slot>' : ''}
|
|
91
|
+
|
|
92
|
+
<!-- 分页 -->
|
|
93
|
+
<div class="pagination">
|
|
94
|
+
<${finalMaterial.pagination}
|
|
95
|
+
@size-change="handleSizeChange"
|
|
96
|
+
@current-change="handleCurrentChange"
|
|
97
|
+
:current-page="currentPage"
|
|
98
|
+
:page-sizes="[10, 20, 50, 100]"
|
|
99
|
+
:page-size="pageSize"
|
|
100
|
+
layout="total, sizes, prev, pager, next, jumper"
|
|
101
|
+
:total="total"
|
|
102
|
+
>
|
|
103
|
+
</${finalMaterial.pagination}>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</template>`;
|
|
107
|
+
|
|
108
|
+
// 生成脚本部分
|
|
109
|
+
const scriptContent = generateScriptSection(template, finalMaterial);
|
|
110
|
+
|
|
111
|
+
// 生成样式部分
|
|
112
|
+
const styleContent = generateStyleSection(template, finalMaterial);
|
|
113
|
+
|
|
114
|
+
// 组合所有部分
|
|
115
|
+
return `${templateContent}\n${scriptContent}\n${styleContent}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
transformList
|
|
120
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock 数据转换逻辑
|
|
3
|
+
* 将页面配置转换为 Mock 数据文件内容
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 生成 mock 数据内容
|
|
8
|
+
* @param {Object} template - 页面模板配置
|
|
9
|
+
* @returns {string} mock 数据内容
|
|
10
|
+
*/
|
|
11
|
+
function transformMock(template) {
|
|
12
|
+
return `// Mock 数据
|
|
13
|
+
const Mock = require('mockjs');
|
|
14
|
+
|
|
15
|
+
// 生成模拟数据
|
|
16
|
+
const mockData = Mock.mock({
|
|
17
|
+
'list|10-20': [{
|
|
18
|
+
'id|+1': 1,
|
|
19
|
+
'name': '@cname',
|
|
20
|
+
'email': '@email',
|
|
21
|
+
'phone': /^1[3-9]\d{9}$/,
|
|
22
|
+
'createTime': '@datetime',
|
|
23
|
+
'status|1': ['正常', '禁用']
|
|
24
|
+
}]
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// 导出 mock 数据
|
|
28
|
+
module.exports = {
|
|
29
|
+
'GET /api/${template.en}': {
|
|
30
|
+
code: 200,
|
|
31
|
+
message: 'success',
|
|
32
|
+
data: {
|
|
33
|
+
list: mockData.list,
|
|
34
|
+
total: mockData.list.length
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
transformMock
|
|
43
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由转换逻辑
|
|
3
|
+
* 将页面配置转换为路由配置文件内容
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 生成路由配置内容
|
|
8
|
+
* @param {Object} config - 页面配置
|
|
9
|
+
* @returns {string} 路由配置内容
|
|
10
|
+
*/
|
|
11
|
+
function transformRoutes(config) {
|
|
12
|
+
const routes = [];
|
|
13
|
+
const pages = config.pages || {};
|
|
14
|
+
|
|
15
|
+
for (const [pageName, pageConfig] of Object.entries(pages)) {
|
|
16
|
+
const { template } = pageConfig;
|
|
17
|
+
routes.push({
|
|
18
|
+
path: `/${template.en}`,
|
|
19
|
+
name: template.en,
|
|
20
|
+
component: () => import(`./${template.en}.vue`),
|
|
21
|
+
meta: {
|
|
22
|
+
title: template.cn
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return `// 路由配置
|
|
28
|
+
const routes = ${JSON.stringify(routes, null, 2)};
|
|
29
|
+
|
|
30
|
+
export default routes;
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
transformRoutes
|
|
36
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表格转换逻辑
|
|
3
|
+
* 将表格配置转换为 HTML 内容
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导入生成字段名的方法
|
|
7
|
+
const { generateFieldName } = require('./transformFilter');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 生成表格内容
|
|
11
|
+
* @param {Object} table - 表格配置
|
|
12
|
+
* @param {Object} material - 组件材料
|
|
13
|
+
* @returns {string} 表格 HTML 内容
|
|
14
|
+
*/
|
|
15
|
+
function transformTable(table, material) {
|
|
16
|
+
let content = '';
|
|
17
|
+
for (const [label, type] of Object.entries(table || {})) {
|
|
18
|
+
if (typeof type === 'object') {
|
|
19
|
+
if (type.type === 'operate') {
|
|
20
|
+
content += `
|
|
21
|
+
<${material.table.column} label="${label}" ${type.fixed ? `fixed="${type.fixed}"` : ''} width="180">
|
|
22
|
+
<template slot-scope="scope">
|
|
23
|
+
${type.render?.map(action => `<${material.button} size="small">${action}</${material.button}>`).join('\n ') || ''}
|
|
24
|
+
</template>
|
|
25
|
+
</${material.table.column}>`;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
// 生成英文字段名
|
|
29
|
+
const fieldName = generateFieldName(label);
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'selection':
|
|
32
|
+
content += `
|
|
33
|
+
<${material.table.column} type="selection" width="55"></${material.table.column}>`;
|
|
34
|
+
break;
|
|
35
|
+
case 'index':
|
|
36
|
+
content += `
|
|
37
|
+
<${material.table.column} type="index" label="${label}" width="80"></${material.table.column}>`;
|
|
38
|
+
break;
|
|
39
|
+
case 'text':
|
|
40
|
+
content += `
|
|
41
|
+
<${material.table.column} prop="${fieldName}" label="${label}"></${material.table.column}>`;
|
|
42
|
+
break;
|
|
43
|
+
case 'time':
|
|
44
|
+
case 'date':
|
|
45
|
+
case 'datetime':
|
|
46
|
+
content += `
|
|
47
|
+
<${material.table.column} prop="${fieldName}" label="${label}"></${material.table.column}>`;
|
|
48
|
+
break;
|
|
49
|
+
case 'option':
|
|
50
|
+
content += `
|
|
51
|
+
<${material.table.column} prop="${fieldName}" label="${label}">
|
|
52
|
+
<template slot-scope="scope">
|
|
53
|
+
<el-tag>{{ scope.row.${fieldName} }}</el-tag>
|
|
54
|
+
</template>
|
|
55
|
+
</${material.table.column}>`;
|
|
56
|
+
break;
|
|
57
|
+
case 'link':
|
|
58
|
+
content += `
|
|
59
|
+
<${material.table.column} prop="${fieldName}" label="${label}">
|
|
60
|
+
<template slot-scope="scope">
|
|
61
|
+
<a href="#">{{ scope.row.${fieldName} }}</a>
|
|
62
|
+
</template>
|
|
63
|
+
</${material.table.column}>`;
|
|
64
|
+
break;
|
|
65
|
+
case 'tag':
|
|
66
|
+
content += `
|
|
67
|
+
<${material.table.column} prop="${fieldName}" label="${label}">
|
|
68
|
+
<template slot-scope="scope">
|
|
69
|
+
<el-tag>{{ scope.row.${fieldName} }}</el-tag>
|
|
70
|
+
</template>
|
|
71
|
+
</${material.table.column}>`;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return content;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
transformTable
|
|
81
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模板转换的通用逻辑
|
|
3
|
+
* 提供通用的模板处理功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 转换模板配置
|
|
8
|
+
* @param {Object} template - 模板配置
|
|
9
|
+
* @param {Object} material - 组件材料
|
|
10
|
+
* @returns {Object} 转换后的模板配置
|
|
11
|
+
*/
|
|
12
|
+
function transformTemplateConfig(template, material) {
|
|
13
|
+
return {
|
|
14
|
+
...template,
|
|
15
|
+
// 添加组件材料信息
|
|
16
|
+
material: material,
|
|
17
|
+
// 生成唯一标识
|
|
18
|
+
id: `${template.en}_${Date.now()}`
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 生成模板头部
|
|
24
|
+
* @param {Object} template - 模板配置
|
|
25
|
+
* @returns {string} 模板头部注释
|
|
26
|
+
*/
|
|
27
|
+
function generateTemplateHeader(template) {
|
|
28
|
+
return `<!-- ${template.cn} -->
|
|
29
|
+
<template>
|
|
30
|
+
<div class="${template.en}">`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 生成模板底部
|
|
35
|
+
* @param {Object} template - 模板配置
|
|
36
|
+
* @returns {string} 模板底部
|
|
37
|
+
*/
|
|
38
|
+
function generateTemplateFooter(template) {
|
|
39
|
+
return ` </div>
|
|
40
|
+
</template>`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 生成脚本部分
|
|
45
|
+
* @param {Object} template - 模板配置
|
|
46
|
+
* @param {Object} material - 组件材料
|
|
47
|
+
* @returns {string} 脚本部分
|
|
48
|
+
*/
|
|
49
|
+
function generateScriptSection(template, material) {
|
|
50
|
+
return `<script>
|
|
51
|
+
export default {
|
|
52
|
+
name: '${template.en}',
|
|
53
|
+
data() {
|
|
54
|
+
return {
|
|
55
|
+
searchForm: {},
|
|
56
|
+
tableData: [],
|
|
57
|
+
loading: false,
|
|
58
|
+
currentPage: 1,
|
|
59
|
+
pageSize: 10,
|
|
60
|
+
total: 0,
|
|
61
|
+
${template.select ? 'multipleSelection: [],' : ''}
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
created() {
|
|
65
|
+
this.getList();
|
|
66
|
+
},
|
|
67
|
+
methods: {
|
|
68
|
+
getList() {
|
|
69
|
+
this.loading = true;
|
|
70
|
+
// TODO: 替换为实际接口调用
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
this.tableData = [];
|
|
73
|
+
this.total = 0;
|
|
74
|
+
this.loading = false;
|
|
75
|
+
}, 500);
|
|
76
|
+
},
|
|
77
|
+
handleSearch() {
|
|
78
|
+
this.currentPage = 1;
|
|
79
|
+
this.getList();
|
|
80
|
+
},
|
|
81
|
+
resetForm() {
|
|
82
|
+
this.searchForm = {};
|
|
83
|
+
this.getList();
|
|
84
|
+
},
|
|
85
|
+
${template.select ? `
|
|
86
|
+
handleSelectionChange(val) {
|
|
87
|
+
this.multipleSelection = val;
|
|
88
|
+
},` : ''}
|
|
89
|
+
handleSizeChange(size) {
|
|
90
|
+
this.pageSize = size;
|
|
91
|
+
this.getList();
|
|
92
|
+
},
|
|
93
|
+
handleCurrentChange(current) {
|
|
94
|
+
this.currentPage = current;
|
|
95
|
+
this.getList();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
</script>`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 生成样式部分
|
|
104
|
+
* @param {Object} template - 模板配置
|
|
105
|
+
* @param {Object} material - 组件材料
|
|
106
|
+
* @returns {string} 样式部分
|
|
107
|
+
*/
|
|
108
|
+
function generateStyleSection(template, material) {
|
|
109
|
+
return `<style scoped>
|
|
110
|
+
.${template.en} {
|
|
111
|
+
padding: 20px;
|
|
112
|
+
}
|
|
113
|
+
.btn-group {
|
|
114
|
+
margin: 20px 0;
|
|
115
|
+
}
|
|
116
|
+
.pagination {
|
|
117
|
+
margin-top: 20px;
|
|
118
|
+
text-align: right;
|
|
119
|
+
}
|
|
120
|
+
</style>`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = {
|
|
124
|
+
transformTemplateConfig,
|
|
125
|
+
generateTemplateHeader,
|
|
126
|
+
generateTemplateFooter,
|
|
127
|
+
generateScriptSection,
|
|
128
|
+
generateStyleSection
|
|
129
|
+
};
|