Merge branch 'master' into mixins
# Conflicts: # ballcat-codegen/ballcat-codegen-frontend/src/views/gen/codegen/GenerateModal.vue # ballcat-codegen/ballcat-codegen-frontend/src/views/gen/codegen/GeneratePage.vue
This commit is contained in:
@@ -16,6 +16,7 @@ import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 代码生成器
|
||||
@@ -60,4 +61,14 @@ public class GenerateController {
|
||||
IoUtil.write(response.getOutputStream(), Boolean.TRUE, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成预览代码
|
||||
* @param preGenerateOptionDTO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/preview")
|
||||
public R<Map<String, String>> previewCode(@RequestBody GeneratorOptionDTO preGenerateOptionDTO) {
|
||||
return R.ok(generatorService.previewCode(preGenerateOptionDTO));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.hccake.ballcat.codegen.service;
|
||||
import com.hccake.ballcat.codegen.model.dto.GeneratorOptionDTO;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author hccake
|
||||
@@ -17,4 +18,11 @@ public interface GeneratorService {
|
||||
*/
|
||||
byte[] generatorCode(GeneratorOptionDTO generatorOptionDTO) throws IOException;
|
||||
|
||||
/**
|
||||
* 预览代码
|
||||
* @param preGenerateOptionDTO {@code preGenerateOptionDTO}
|
||||
* @return {@code Map<String, String>}
|
||||
*/
|
||||
Map<String, String> previewCode(GeneratorOptionDTO preGenerateOptionDTO);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.hccake.ballcat.codegen.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.hccake.ballcat.codegen.model.bo.TemplateFile;
|
||||
import com.hccake.ballcat.codegen.model.dto.GeneratorOptionDTO;
|
||||
import com.hccake.ballcat.codegen.model.vo.ColumnInfo;
|
||||
@@ -16,6 +17,7 @@ import org.springframework.stereotype.Service;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
@@ -60,4 +62,24 @@ public class GeneratorServiceImpl implements GeneratorService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> previewCode(GeneratorOptionDTO preGenerateOptionDTO) {
|
||||
// 根据tableName 查询最新的表单配置
|
||||
List<TemplateFile> templateFiles = templateDirectoryEntryService.listTemplateFiles(
|
||||
preGenerateOptionDTO.getTemplateGroupId(), preGenerateOptionDTO.getTemplateFileIds());
|
||||
Assert.notEmpty(templateFiles, "模板组中模板文件为空!");
|
||||
String[] tableNames = preGenerateOptionDTO.getTableNames();
|
||||
Assert.isTrue(ArrayUtil.isNotEmpty(tableNames) && tableNames.length == 1, "预览仅支持单表");
|
||||
// 获取表名
|
||||
String tableName = tableNames[0];
|
||||
// 查询表信息
|
||||
TableInfo tableInfo = tableInfoService.queryTableInfo(tableName);
|
||||
// 查询列信息
|
||||
List<ColumnInfo> columnInfoList = tableInfoService.listColumnInfo(tableName);
|
||||
// 生成代码
|
||||
return GenUtils.previewCode(preGenerateOptionDTO.getTablePrefix(), preGenerateOptionDTO.getGenProperties(),
|
||||
tableInfo, columnInfoList, templateFiles);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,6 +73,32 @@ public class GenUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览代码
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> previewCode(String tablePrefix, Map<String, String> customProperties,
|
||||
TableInfo tableInfo, List<ColumnInfo> columnInfos, List<TemplateFile> templateFiles) {
|
||||
// 预览结果存放
|
||||
Map<String, String> previewData = new HashMap<>();
|
||||
// 根据表信息和字段信息获取对应的配置属性
|
||||
GenerateProperties generateProperties = getGenerateProperties(tableInfo, columnInfos, tablePrefix);
|
||||
// 转换generateProperties为map,模板数据
|
||||
Map<String, Object> map = BeanUtil.beanToMap(generateProperties);
|
||||
// 追加用户自定义属性
|
||||
map.putAll(customProperties);
|
||||
// 模板渲染
|
||||
VelocityContext context = new VelocityContext(map);
|
||||
for (TemplateFile templateFile : templateFiles) {
|
||||
StringWriter sw = new StringWriter();
|
||||
Velocity.evaluate(context, sw, tableInfo.getTableName() + templateFile.getFilePath(),
|
||||
templateFile.getContent());
|
||||
// 模板内容填充
|
||||
previewData.put(StrUtil.format(templateFile.getFileName(), map), sw.toString());
|
||||
}
|
||||
return previewData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表信息和字段信息获取对应的配置属性
|
||||
* @param tableInfo 表信息
|
||||
|
||||
@@ -4075,6 +4075,12 @@
|
||||
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
|
||||
"dev": true
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.18.5",
|
||||
"resolved": "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.18.5.tgz",
|
||||
"integrity": "sha1-0Yo1mGfzeME41oGe38KorNXymCU=",
|
||||
"dev": true
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
|
||||
@@ -7122,10 +7128,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.18.1",
|
||||
"resolved": "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.18.1.tgz",
|
||||
"integrity": "sha1-7SGqAB/mJSuxCj121HVzxlOf4Tw=",
|
||||
"dev": true
|
||||
"version": "10.7.1",
|
||||
"resolved": "https://registry.npm.taobao.org/highlight.js/download/highlight.js-10.7.1.tgz",
|
||||
"integrity": "sha1-qOxBUtsk6mMMkJJ9bK4qRfjsuVU="
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"axios": "^0.19.2",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"core-js": "^3.6.5",
|
||||
"highlight.js": "^10.7.1",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"moment": "^2.26.0",
|
||||
"nprogress": "^0.2.0",
|
||||
|
||||
@@ -9,6 +9,15 @@ export function getTableInfoPage(dsName, query) {
|
||||
})
|
||||
}
|
||||
|
||||
export function preview(dsName, genConfig) {
|
||||
return axios({
|
||||
url: '/preview',
|
||||
method: 'post',
|
||||
data: genConfig,
|
||||
headers: { dsName: dsName }
|
||||
})
|
||||
}
|
||||
|
||||
export function generate(dsName, genConfig) {
|
||||
return axios({
|
||||
url: '/generate',
|
||||
|
||||
@@ -22,7 +22,8 @@ import {
|
||||
Radio,
|
||||
Descriptions,
|
||||
Checkbox,
|
||||
Tooltip
|
||||
Tooltip,
|
||||
Tabs
|
||||
} from 'ant-design-vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
@@ -52,6 +53,7 @@ Vue.use(Radio)
|
||||
Vue.use(Checkbox)
|
||||
Vue.use(Descriptions)
|
||||
Vue.use(Tooltip)
|
||||
Vue.use(Tabs)
|
||||
Vue.prototype.$message = message
|
||||
|
||||
Vue.prototype.FORM_ACTION = {
|
||||
|
||||
@@ -42,6 +42,7 @@ export default {
|
||||
handleClose(e) {
|
||||
this.visible = false
|
||||
this.submitLoading = false
|
||||
this.form.resetFields()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="属性配置"
|
||||
ok-text="确认"
|
||||
cancel-text="取消"
|
||||
:visible="visible"
|
||||
:confirm-loading="submitLoading"
|
||||
:width="900"
|
||||
@ok="handleOk"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<template slot="footer">
|
||||
<a-button @click="handleClose">
|
||||
取消
|
||||
</a-button>
|
||||
<a-button @click="previewCode" v-if="'single' === this.type">
|
||||
预览
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleOk">
|
||||
确认
|
||||
</a-button>
|
||||
</template>
|
||||
<a-modal :title="preview.title" :width="1200" :visible="preview.open" :footer="null" @cancel="closePreviewCode">
|
||||
<a-tabs default-active-key="1" tab-position="left">
|
||||
<a-tab-pane v-for="(value, key) in preview.data" :key="key" :tab="key">
|
||||
<pre><code class="hljs" v-html="highlightedCode(value,key)"></code></pre>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-modal>
|
||||
|
||||
<a-form :form="form" @submit="handleOk">
|
||||
<a-row :gutter="6">
|
||||
<a-col :span="10">
|
||||
@@ -84,7 +101,17 @@ import { PopUpFormMixin } from '@/mixins'
|
||||
import { getSelectData } from '@/api/gen/templategroup'
|
||||
import { getProperties } from '@/api/gen/templateproperty'
|
||||
import { getList as getTemplateFiles } from '@/api/gen/templateinfo'
|
||||
import { generate } from '@/api/gen/generate'
|
||||
import { preview, generate } from '@/api/gen/generate'
|
||||
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/github-gist.css'
|
||||
|
||||
hljs.registerLanguage('java', require('highlight.js/lib/languages/java'))
|
||||
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
|
||||
hljs.registerLanguage('html', require('highlight.js/lib/languages/xml'))
|
||||
hljs.registerLanguage('vue', require('highlight.js/lib/languages/xml'))
|
||||
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
|
||||
hljs.registerLanguage('sql', require('highlight.js/lib/languages/sql'))
|
||||
|
||||
export default {
|
||||
name: 'GenerateModalForm',
|
||||
@@ -114,7 +141,14 @@ export default {
|
||||
templateFileIds: [],
|
||||
checkedList: [],
|
||||
indeterminate: false,
|
||||
checkAll: true
|
||||
checkAll: true,
|
||||
// 预览参数
|
||||
preview: {
|
||||
open: false,
|
||||
title: '代码预览',
|
||||
data: {}
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -127,6 +161,12 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
show(tableNames, type) {
|
||||
this.visible = true
|
||||
this.submitLoading = false
|
||||
this.type = type
|
||||
this.tableNames = tableNames
|
||||
},
|
||||
onTemplateGroupChange(templateGroupId) {
|
||||
getProperties(templateGroupId).then(res => {
|
||||
this.properties = res.data
|
||||
@@ -136,6 +176,35 @@ export default {
|
||||
this.templateFileIds = this.templateFiles.map(x => x.directoryEntryId)
|
||||
})
|
||||
},
|
||||
/** 高亮显示 */
|
||||
highlightedCode(code, key) {
|
||||
var language = key.substring(key.lastIndexOf('.') + 1)
|
||||
const result = hljs.highlight(language, code || '', true)
|
||||
return result.value || ' '
|
||||
},
|
||||
|
||||
previewCode() {
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
this.submitLoading = true
|
||||
preview(this.dsName, this.submitDataProcess(values))
|
||||
.then(res => {
|
||||
this.preview.data = res.data
|
||||
this.preview.open = true
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message.error('代码生成异常')
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
closePreviewCode() {
|
||||
this.preview.open = false
|
||||
this.preview.data = {}
|
||||
},
|
||||
handleOk() {
|
||||
// 钩子函数 处理提交之前处理的事件
|
||||
this.form.validateFields((err, values) => {
|
||||
|
||||
@@ -142,12 +142,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
singleGenerate(record) {
|
||||
this.$refs.generateModal.show({ title: record.tableName })
|
||||
this.$refs.generateModal.show([record.tableName], 'single')
|
||||
},
|
||||
multiGenerate() {
|
||||
const tableNames = this.selectedRowKeys
|
||||
if (tableNames && tableNames.length > 0) {
|
||||
this.$refs.generateModal.show(tableNames)
|
||||
this.$refs.generateModal.show(tableNames, 'multipart-single')
|
||||
} else {
|
||||
this.$message.warning('至少选中一张表')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user