新增模板组新建、编辑、复制功能

This commit is contained in:
b2baccline
2020-06-29 17:52:24 +08:00
parent 2625eca4e5
commit 7fc1f7a252
12 changed files with 372 additions and 57 deletions

View File

@@ -40,7 +40,7 @@ export function putObj(obj) {
export function getSelectData() { export function getSelectData() {
return axios({ return axios({
url: '/gen/datasource/config/select', url: '/gen/datasource-config/select',
method: 'get' method: 'get'
}) })
} }

View File

@@ -37,3 +37,10 @@ export function putObj(obj) {
data: obj data: obj
}) })
} }
export function getSelectData() {
return axios({
url: '/gen/template/group/select',
method: 'get'
})
}

View File

@@ -16,8 +16,10 @@ export default {
// 提交按钮防止重复提交 // 提交按钮防止重复提交
submitLoading: false, submitLoading: false,
addObj: function() {}, reqFunctions: {
putObj: function() {} create: function() {},
update: function() {}
}
} }
}, },
methods: { methods: {
@@ -65,12 +67,12 @@ export default {
handleSubmit(e) { handleSubmit(e) {
// 钩子函数 处理提交之前处理的事件 // 钩子函数 处理提交之前处理的事件
this.beforeStartSubmit() this.beforeStartSubmit()
const req = this.formAction === this.FORM_ACTION.CREATE ? this.addObj : this.putObj const reqFunction = this.reqFunctions[this.formAction]
e.preventDefault() e.preventDefault()
this.form.validateFields((err, values) => { this.form.validateFields((err, values) => {
if (!err) { if (!err) {
this.submitLoading = true this.submitLoading = true
req(this.submitDataProcess(values)) reqFunction(this.submitDataProcess(values))
.then(res => { .then(res => {
if (res.code === 200) { if (res.code === 200) {
this.$message.success(res.msg) this.$message.success(res.msg)

View File

@@ -4,6 +4,7 @@ export default {
mixins: [FormMixin], mixins: [FormMixin],
data() { data() {
return { return {
title: '',
visible: false, visible: false,
labelCol: { labelCol: {
xs: { span: 8 }, xs: { span: 8 },
@@ -18,17 +19,19 @@ export default {
} }
}, },
methods: { methods: {
show() { show(title) {
this.visible = true this.visible = true
this.submitLoading = false this.submitLoading = false
this.title = title
}, },
add() { add(title) {
this.buildCreatedForm() this.buildCreatedForm()
this.show() this.show(title)
}, },
update(record) { update(record, title) {
this.buildUpdatedForm(record) this.buildUpdatedForm(record)
this.show() this.show(title)
}, },
/*eslint-disable*/ /*eslint-disable*/
submitSuccess(res) { submitSuccess(res) {

View File

@@ -29,7 +29,7 @@ const routes = [
path: '/gen/codegen', path: '/gen/codegen',
name: 'CodeGen', name: 'CodeGen',
meta: { title: '代码生成器' }, meta: { title: '代码生成器' },
component: () => import(/* webpackChunkName: "gen" */ '../views/gen/codegen/CodeGenPage') component: () => import(/* webpackChunkName: "gen" */ '../views/gen/codegen/GeneratePage')
}, },
{ {
path: '/gen/template/group', path: '/gen/template/group',

View File

@@ -0,0 +1,149 @@
<template>
<a-modal
title="属性配置"
ok-text="确认"
cancel-text="取消"
:visible="visible"
:confirm-loading="submitLoading"
@ok="handleOk"
@cancel="handleClose"
width="60%"
>
<a-form :form="form" @submit="handleOk">
<a-row :gutter="16">
<a-col :span="8">
<a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" label="模板组">
<a-select
@change="onTemplateGroupChange"
v-decorator="[
'templateGroupId',
{
initialValue: defaultTemplateGroupId,
rules: [{ required: true, message: '必须选择一个模板组' }]
}
]"
>
<a-select-option v-for="item in templateGroupSelectData" :key="Number(item.value)">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="16">
<a-divider orientation="left">
系统属性
</a-divider>
<a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" label="表前缀">
<a-input v-decorator="['tablePrefix']" placeholder="填写则会将表名的前缀截取后,再生成类名" />
</a-form-item>
<a-divider orientation="left">
自定义属性
</a-divider>
<a-form-item v-for="item in properties" :label-col="labelCol" :wrapper-col="wrapperCol" :label="item.propKey">
<a-input
v-decorator="[
'genProperties.' + item.propKey,
{ rules: [{ required: item.required === 1, message: item.title + '不能为空' }] }
]"
:placeholder="'请输入' + item.title"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-modal>
</template>
<script>
import { FormModalMixin } from '@/mixins'
import { getSelectData } from '@/api/gen/templategroup'
import { getProperties } from '@/api/gen/templateproperty'
import { generate } from '@/api/gen/generate'
export default {
name: 'GenerateModal',
mixins: [FormModalMixin],
props: {
dsName: String
},
data() {
return {
labelCol: {
xs: { span: 12 },
sm: { span: 24 },
lg: { span: 6 }
},
wrapperCol: {
xs: { span: 12 },
sm: { span: 24 },
lg: { span: 18 }
},
defaultTemplateGroupId: 1,
tableNames: [],
templateGroupSelectData: [],
properties: []
}
},
mounted() {
getSelectData().then(res => {
this.templateGroupSelectData = res.data
})
this.onTemplateGroupChange(this.defaultTemplateGroupId)
},
methods: {
show(tableNames) {
this.visible = true
this.submitLoading = false
this.tableNames = tableNames
},
onTemplateGroupChange(templateGroupId) {
getProperties(templateGroupId).then(res => {
this.properties = res.data
})
},
handleOk() {
// 钩子函数 处理提交之前处理的事件
this.form.validateFields((err, values) => {
if (!err) {
this.submitLoading = true
generate(this.dsName, this.submitDataProcess(values))
.then(fileBlob => {
const blob = new Blob([fileBlob])
const fileName = 'BallCat-CodeGen.zip'
const eLink = document.createElement('a')
if ('download' in eLink) {
// 非IE下载
eLink.download = fileName
eLink.style.display = 'none'
eLink.href = URL.createObjectURL(blob)
document.body.appendChild(eLink)
eLink.click()
URL.revokeObjectURL(eLink.href) // 释放URL 对象
document.body.removeChild(eLink)
} else {
// IE10+下载
navigator.msSaveBlob(blob, fileName)
}
})
.catch(() => {
this.$message.error('代码生成异常')
})
.finally(() => {
this.submitLoading = false
})
}
})
},
submitDataProcess(data) {
data.tableNames = this.tableNames
return data
}
}
}
</script>
<style scoped>
.ant-form-item {
margin-bottom: 8px;
}
</style>

View File

@@ -42,7 +42,7 @@
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<div class="table-operator"> <div class="table-operator">
<a-button type="primary" icon="download" @click="handleGenerate()">批量生成</a-button> <a-button type="primary" icon="download" @click="multiGenerate()">批量生成</a-button>
</div> </div>
<!--数据表格区域--> <!--数据表格区域-->
@@ -60,22 +60,32 @@
> >
<span slot="action-slot" slot-scope="text, record"> <span slot="action-slot" slot-scope="text, record">
<template> <template>
<a @click="handleGenerate(record)">生成</a> <a @click="singleGenerate(record)">生成</a>
</template> </template>
</span> </span>
</a-table> </a-table>
</div> </div>
</a-card> </a-card>
<generate-modal
ref="generateModal"
:dsName="dsName"
:bodyStyle="{
padding: '12px 24px'
}"
></generate-modal>
</div> </div>
</template> </template>
<script> <script>
import { TablePageMixin } from '@/mixins' import { TablePageMixin } from '@/mixins'
import { getTableInfoPage, generate } from '@/api/gen/generate' import { getTableInfoPage } from '@/api/gen/generate'
import { getSelectData } from '@/api/gen/datasourceconfig' import { getSelectData } from '@/api/gen/datasourceconfig'
import GenerateModal from './GenerateModal'
export default { export default {
name: 'CodegenPage', name: 'GeneratePage',
components: { GenerateModal },
mixins: [TablePageMixin], mixins: [TablePageMixin],
data() { data() {
return { return {
@@ -131,25 +141,18 @@ export default {
} }
}, },
methods: { methods: {
handleGenerate() { singleGenerate(record) {
generate(this.dsName, { tableNames: this.selectedRowKeys }).then(fileBlob => { this.$refs.generateModal.show([record.tableName])
const blob = new Blob([fileBlob]) //this.handleGenerate([record.tableName])
const fileName = 'BallCat-CodeGen.zip' },
const eLink = document.createElement('a') multiGenerate() {
if ('download' in eLink) { const tableNames = this.selectedRowKeys
// IE console.log(tableNames)
eLink.download = fileName if (tableNames && tableNames.length > 0) {
eLink.style.display = 'none' this.handleGenerate(tableNames)
eLink.href = URL.createObjectURL(blob) } else {
document.body.appendChild(eLink) this.$message.warning('至少选中一张表')
eLink.click() }
URL.revokeObjectURL(eLink.href) // URL
document.body.removeChild(eLink)
} else {
// IE10+
navigator.msSaveBlob(blob, fileName)
}
})
} }
} }
} }

View File

@@ -64,12 +64,67 @@
目前只支持 Velocity具体语法请参看其官网 目前只支持 Velocity具体语法请参看其官网
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
<a-descriptions title="默认属性"> <a-descriptions title="系统提供属性">
<a-descriptions-item label="currentTime">
当前系统时间
</a-descriptions-item>
<a-descriptions-item label="tableName">
当前表名
</a-descriptions-item>
<a-descriptions-item label="comments">
当前表备注
</a-descriptions-item>
<a-descriptions-item label="classname">
类名小驼峰形式首字母小写
</a-descriptions-item>
<a-descriptions-item label="className">
类名大驼峰形式首字母大写
</a-descriptions-item>
<a-descriptions-item label="pathName">
类名全字母小写
</a-descriptions-item>
<a-descriptions-item label="tableAlias">
表别名类名各单词首字母小写组合
</a-descriptions-item>
<a-descriptions-item label="pk">
主键的列属性
</a-descriptions-item>
<a-descriptions-item label="columns">
列属性的 List 集合
</a-descriptions-item>
</a-descriptions>
<a-descriptions title="列属性详情">
<a-descriptions-item label="columnName">
列名
</a-descriptions-item>
<a-descriptions-item label="comments">
列备注
</a-descriptions-item>
<a-descriptions-item label="dataType">
列数据类型
</a-descriptions-item>
<a-descriptions-item label="columnType">
列类型(数据类型+长度等信息)
</a-descriptions-item>
<a-descriptions-item label="attrName">
列对应属性名首字母小写
</a-descriptions-item>
<a-descriptions-item label="capitalizedAttrName">
列对应属性名首字母大写
</a-descriptions-item>
<a-descriptions-item label="attrType">
列对应Java类型
</a-descriptions-item>
<a-descriptions-item label="extra">
列的额外属性如自增
</a-descriptions-item>
</a-descriptions>
<a-descriptions title="用户填写属性">
<a-descriptions-item label="tablePrefix"> <a-descriptions-item label="tablePrefix">
表前缀代码生成时截取此前缀后再生成类名 表前缀代码生成时截取此前缀后再生成类名
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
<a-descriptions title="自定义属性"> <a-descriptions title="用户自定义属性">
<template v-for="item in this.properties"> <template v-for="item in this.properties">
<a-descriptions-item :label="item.propKey"> <a-descriptions-item :label="item.propKey">
{{ item.remarks ? item.title + '' + item.remarks : item.title }} {{ item.remarks ? item.title + '' + item.remarks : item.title }}
@@ -150,8 +205,8 @@ import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/dracula.css' import 'codemirror/theme/dracula.css'
import 'codemirror/mode/velocity/velocity.js' import 'codemirror/mode/velocity/velocity.js'
//import { TablePageMixin } from '@/mixins' //import { TablePageMixin } from '@/mixins'
import renameModel from './TemplateGroupRenameModel.vue' import renameModel from './TemplateEntryRenameModal.vue'
import removeModel from './TemplateGroupRemoveTree.vue' import removeModel from './TemplateEntryRemoveModal.vue'
export default { export default {
name: 'TemplateDirectoryEntryPage', name: 'TemplateDirectoryEntryPage',
@@ -238,17 +293,33 @@ export default {
} }
} }
}, },
watch: {
templateGroupId() {
this.initPage()
}
},
created() { created() {
this.pageLoad(true) this.initPage()
getProperties(this.templateGroupId).then(res => {
this.properties = res.data
})
this.heightClient = document.documentElement.clientHeight || document.body.clientHeight this.heightClient = document.documentElement.clientHeight || document.body.clientHeight
this.heightClient = this.heightClient - 210 this.heightClient = this.heightClient - 210
this.splitPane.height = this.heightClient + 'px' this.splitPane.height = this.heightClient + 'px'
}, },
methods: { methods: {
pageLoad(firstInit) { /**
* 页面初始化
* 1. 更新 Entry Tree
* 2. 更新自定义属性展示
*/
initPage() {
this.treeLoad(true)
getProperties(this.templateGroupId).then(res => {
this.properties = res.data
})
},
/**
* 加载 Entry Tree
*/
treeLoad(firstInit) {
getList(this.templateGroupId).then(res => { getList(this.templateGroupId).then(res => {
this.treeData = listToTree(res.data, 0, (treeNode, item) => { this.treeData = listToTree(res.data, 0, (treeNode, item) => {
treeNode.isLeaf = item.type === 2 treeNode.isLeaf = item.type === 2
@@ -338,7 +409,7 @@ export default {
.then(res => { .then(res => {
if (res.code === 200) { if (res.code === 200) {
this.$message.success('移动成功!') this.$message.success('移动成功!')
this.pageLoad() this.treeLoad()
} else { } else {
this.$message.error(res.msg) this.$message.error(res.msg)
} }
@@ -368,7 +439,7 @@ export default {
* 表单提交后进行重新load不更新展开的文件 * 表单提交后进行重新load不更新展开的文件
*/ */
submitSuccess() { submitSuccess() {
this.pageLoad() this.treeLoad()
}, },
backToPage(needRefresh) { backToPage(needRefresh) {
this.$emit('backToPage', needRefresh) this.$emit('backToPage', needRefresh)

View File

@@ -0,0 +1,56 @@
<template>
<a-modal :title="title" :visible="visible" :confirm-loading="submitLoading" @ok="handleOk" @cancel="handleClose">
<a-form :form="form" @submit="handleOk">
<a-form-item v-if="formAction === this.FORM_ACTION.UPDATE" style="display: none">
<a-input v-decorator="['id']" />
</a-form-item>
<a-form-item v-if="formAction === 'copy'" :label-col="labelCol" :wrapper-col="wrapperCol" label="源模板组">
<span>{{ resourceGroupName }}</span>
</a-form-item>
<a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" label="名称">
<a-input
v-decorator="['name', { rules: [{ required: true, message: '模板组名称不能为空' }] }]"
placeholder="请输入模板组名称"
/>
</a-form-item>
<a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" label="备注信息">
<a-textarea v-decorator="['remarks']" placeholder="请输入模板组备注信息" />
</a-form-item>
</a-form>
</a-modal>
</template>
<script>
import { FormModalMixin } from '@/mixins'
import { addObj, putObj } from '@/api/gen/templategroup'
export default {
mixins: [FormModalMixin],
data() {
return {
reqFunctions: {
create: addObj,
update: putObj,
copy: function(data) {
return addObj(data)
}
},
resourceGroupId: '',
resourceGroupName: ''
}
},
methods: {
handleOk(e) {
this.handleSubmit(e)
},
copy(record, title) {
this.form.resetFields()
this.formAction = 'copy'
this.resourceGroupId = record.id
this.resourceGroupName = record.name
this.show(title)
}
}
}
</script>

View File

@@ -47,11 +47,18 @@
:loading="loading" :loading="loading"
@change="handleTableChange" @change="handleTableChange"
> >
<span slot="template-action-slot" slot-scope="text, record">
<template>
<a @click="editEntry(record, '编辑模板组 - ' + record.name)">模板编辑</a>
<a-divider type="vertical" />
<a @click="editProperties(record)">属性配置</a>
</template>
</span>
<span slot="action-slot" slot-scope="text, record"> <span slot="action-slot" slot-scope="text, record">
<template> <template>
<a @click="handleEdit(record, '编辑模板组 - ' + record.name)">模板编辑</a> <a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a @click="handleShowItem(record)">属性配置</a> <a @click="handleCopy(record)">复制</a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a-popconfirm title="确认要删除吗?" @confirm="() => handleDel(record)"> <a-popconfirm title="确认要删除吗?" @confirm="() => handleDel(record)">
<a href="javascript:;">删除</a> <a href="javascript:;">删除</a>
@@ -77,19 +84,23 @@
<div v-if="itemModalInited"> <div v-if="itemModalInited">
<template-property-modal ref="propertyModal"></template-property-modal> <template-property-modal ref="propertyModal"></template-property-modal>
</div> </div>
<!--模板组表单弹窗-->
<template-group-form-modal ref="formModal" @reloadPageTable="reloadTable"></template-group-form-modal>
</div> </div>
</template> </template>
<script> <script>
import { getPage, delObj } from '@/api/gen/templategroup' import { getPage, delObj } from '@/api/gen/templategroup'
import FormPage from './TemplateGroupForm' import FormPage from './TemplateEntryForm'
import TemplatePropertyModal from './TemplatePropertyModal' import TemplatePropertyModal from './TemplatePropertyModal'
import { TablePageMixin } from '@/mixins' import { TablePageMixin } from '@/mixins'
import TemplateGroupFormModal from './TemplateGroupFormModal'
export default { export default {
name: 'TemplateGroupPage', name: 'TemplateGroupPage',
mixins: [TablePageMixin], mixins: [TablePageMixin],
components: { FormPage, TemplatePropertyModal }, components: { TemplateGroupFormModal, FormPage, TemplatePropertyModal },
data() { data() {
return { return {
getPage: getPage, getPage: getPage,
@@ -104,6 +115,10 @@ export default {
title: '名称', title: '名称',
dataIndex: 'name' dataIndex: 'name'
}, },
{
title: '备注信息',
dataIndex: 'remarks'
},
{ {
title: '创建时间', title: '创建时间',
dataIndex: 'createTime', dataIndex: 'createTime',
@@ -111,16 +126,16 @@ export default {
sorter: true sorter: true
}, },
{ {
title: '更新时间', title: '模板组操作',
dataIndex: 'updateTime', dataIndex: 'templateAction',
width: '150px', width: '150px',
sorter: true scopedSlots: { customRender: 'action-slot' }
}, },
{ {
title: '操作', title: '模板操作',
dataIndex: 'action', dataIndex: 'action',
width: '200px', width: '150px',
scopedSlots: { customRender: 'action-slot' } scopedSlots: { customRender: 'template-action-slot' }
} }
], ],
@@ -129,12 +144,21 @@ export default {
} }
}, },
methods: { methods: {
handleEdit(record, title) { handleAdd() {
this.$refs.formModal.add('新建模板组')
},
handleEdit(record) {
this.$refs.formModal.update(record, '编辑模板组')
},
handleCopy(record) {
this.$refs.formModal.copy(record, '复制模板组')
},
editEntry(record, title) {
this.switchPage() this.switchPage()
this.cardTitle = title || '修改' this.cardTitle = title || '修改'
this.templateGroupId = record.id this.templateGroupId = record.id
}, },
handleShowItem(record) { editProperties(record) {
if (!this.itemModalInited) { if (!this.itemModalInited) {
this.itemModalInited = true this.itemModalInited = true
} }