【新增】新增代码生成功能 开源版V1.1

pull/22/head
小诺 2020-12-25 18:18:30 +08:00 committed by 小诺
parent eed39d3dba
commit 3ccbd635c9
42 changed files with 3469 additions and 1 deletions

View File

@ -1000,3 +1000,28 @@ CREATE TABLE `sys_vis_log` (
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Table structure for `sys_code_generate`
-- ----------------------------
DROP TABLE IF EXISTS `sys_code_generate`;
CREATE TABLE `sys_code_generate` (
`id` bigint(20) NOT NULL COMMENT '主键',
`author_name` varchar(255) NOT NULL COMMENT '作者姓名',
`class_name` varchar(255) NOT NULL COMMENT '类名',
`table_prefix` varchar(255) NOT NULL COMMENT '是否移除表前缀',
`generate_type` varchar(255) NOT NULL COMMENT '生成位置类型',
`table_name` varchar(255) NOT NULL COMMENT '数据库表名',
`package_name` varchar(255) DEFAULT NULL COMMENT '包名称',
`bus_name` varchar(255) DEFAULT NULL COMMENT '业务名',
`table_comment` varchar(255) DEFAULT NULL COMMENT '功能名',
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_user` bigint(20) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='代码生成基础配置';
-- ----------------------------
-- Records of sys_code_generate
-- ----------------------------

View File

@ -0,0 +1,106 @@
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
import { axios } from '@/utils/request'
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGeneratePage (parameter) {
return axios({
url: '/codeGenerate/page',
method: 'get',
params: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateAdd (parameter) {
return axios({
url: '/codeGenerate/add',
method: 'post',
data: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateEdit (parameter) {
return axios({
url: '/codeGenerate/edit',
method: 'post',
data: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateDelete (parameter) {
return axios({
url: '/codeGenerate/delete',
method: 'post',
data: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateInformationList (parameter) {
return axios({
url: '/codeGenerate/InformationList',
method: 'get',
params: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateRunLocal (parameter) {
return axios({
url: '/codeGenerate/runLocal',
method: 'post',
data: parameter
})
}
/**
*
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateRunDown (parameter) {
return axios({
url: '/codeGenerate/runDown',
method: 'get',
params: parameter,
responseType: 'blob'
})
}

View File

@ -0,0 +1,244 @@
<template>
<a-modal
title="新增代码生成配置"
:width="900"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="生成表"
has-feedback
>
<a-select style="width: 100%" placeholder="请选择数据库表" v-decorator="['tableName', {rules: [{ required: true, message: '' }]}]" >
<a-select-option v-for="(item,index) in tableNameData" :key="index" :value="item.tableName" @click="tableNameSele(item)">{{ item.tableName }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="移除前缀"
>
<a-radio-group v-decorator="['tablePrefix',{rules: [{ required: true, message: '' }]}]" >
<a-radio v-for="(item,index) in tablePrefixData" :key="index" :value="item.code" @click="tablePrefixRadio(item.code)">{{ item.name }}</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="功能名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入功能名" v-decorator="['tableComment', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
label="类名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入类名" v-decorator="['className', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="业务名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入业务名" v-decorator="['busName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="生成方式"
>
<a-radio-group v-decorator="['generateType',{rules: [{ required: true, message: '' }]}]" >
<a-radio v-for="(item,index) in generateTypeData" :key="index" :value="item.code" @click="generateTypeRadio(item.code)">{{ item.name }}</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="作者姓名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入作者姓名" v-decorator="['authorName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24" v-show="packageNameShow">
<a-form-item
label="代码包名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入代码包名" v-decorator="['packageName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { codeGenerateInformationList, codeGenerateAdd } from '@/api/modular/gen/codeGenerateManage'
export default {
data () {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 15 }
},
visible: false,
tableNameData: [],
tablePrefixData: [],
generateTypeData: [],
confirmLoading: false,
tablePrefixValue: 'N',
tableNameValue: '',
packageNameShow: true,
form: this.$form.createForm(this)
}
},
methods: {
//
add () {
this.visible = true
this.codeGenerateInformationList()
this.dataTypeItem()
this.selectedByDefault()
},
/**
* 默认选中项
*/
selectedByDefault () {
this.form.getFieldDecorator('packageName', { initialValue: 'com.cn.xiaonuo' })
this.form.getFieldDecorator('tablePrefix', { valuePropName: 'checked', initialValue: 'N' })
this.form.getFieldDecorator('generateType', { valuePropName: 'checked', initialValue: '1' })
},
/**
* 获得所有数据库的表
*/
codeGenerateInformationList () {
codeGenerateInformationList().then((res) => {
this.tableNameData = res.data
})
},
/**
* 获取字典数据
*/
dataTypeItem () {
this.tablePrefixData = this.$options.filters['dictData']('yes_or_no')
this.generateTypeData = this.$options.filters['dictData']('code_gen_create_type')
},
/**
* 提交表单
*/
handleSubmit () {
const { form: { validateFields } } = this
validateFields((errors, values) => {
if (!errors) {
this.confirmLoading = true
codeGenerateAdd(values).then((res) => {
if (res.success) {
this.$message.success('新增成功')
this.$emit('ok', values)
this.handleCancel()
} else {
this.$message.error('新增失败:' + res.message)
}
}).finally((res) => {
this.confirmLoading = false
})
}
})
},
handleCancel () {
this.form.resetFields()
this.visible = false
//
this.form.getFieldDecorator('className', { initialValue: '' })
this.form.getFieldDecorator('busName', { initialValue: '' })
this.form.getFieldDecorator('tableComment', { initialValue: '' })
},
/**
* 选择数据库列表
*/
tableNameSele (item) {
this.tableNameValue = item.tableName
this.form.getFieldDecorator('tableComment', { initialValue: item.tableComment })
this.settingDefaultValue()
},
/**
* 选择是否移除前缀触发
*/
tablePrefixRadio (tablePrefixType) {
this.tablePrefixValue = tablePrefixType
this.settingDefaultValue()
},
/**
* 设置默认值
*/
settingDefaultValue () {
const tableName = this.classNameToHump()
this.form.getFieldDecorator('className', { initialValue: tableName })
this.form.getFieldDecorator('busName', { initialValue: tableName.toLowerCase() })
},
/**
* 设置类名为数据库表的驼峰命名
*/
classNameToHump () {
const arr = this.tableNameValue.toLowerCase().split('_')
if (this.tablePrefixValue === 'Y') {
arr.splice(0, 1)
}
for (let i = 0; i < arr.length; i++) {
// charAt()slice()
arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1)
}
return arr.join('')
},
/**
* 选择生成方式
*/
generateTypeRadio (generateType) {
if (generateType === '1') {
this.packageNameShow = true
} else {
this.packageNameShow = false
this.form.setFieldsValue({ packageName: 'com.cn.xiaonuo' })
}
}
}
}
</script>

View File

@ -0,0 +1,253 @@
<template>
<a-modal
title="编辑代码生成配置"
:width="900"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item v-show="false"><a-input v-decorator="['id']" /></a-form-item>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="生成表"
has-feedback
>
<a-select style="width: 100%" placeholder="请选择数据库表" v-decorator="['tableName', {rules: [{ required: true, message: '' }]}]" >
<a-select-option v-for="(item,index) in tableNameData" :key="index" :value="item.tableName" @click="tableNameSele(item)">{{ item.tableName }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="移除前缀"
>
<a-radio-group v-decorator="['tablePrefix',{rules: [{ required: true, message: '' }]}]" >
<a-radio v-for="(item,index) in tablePrefixData" :key="index" :value="item.code" @click="tablePrefixRadio(item.code)">{{ item.name }}</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="功能名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入功能名" v-decorator="['tableComment', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
label="类名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入类名" v-decorator="['className', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="业务名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入业务名" v-decorator="['busName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="生成方式"
>
<a-radio-group v-decorator="['generateType',{rules: [{ required: true, message: '' }]}]" >
<a-radio v-for="(item,index) in generateTypeData" :key="index" :value="item.code" @click="generateTypeRadio(item.code)">{{ item.name }}</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :md="12" :sm="24">
<a-form-item
label="作者姓名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入作者姓名" v-decorator="['authorName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
<a-col :md="12" :sm="24" v-show="packageNameShow">
<a-form-item
label="代码包名"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入代码包名" v-decorator="['packageName', {rules: [{required: true, message: ''}]}]" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { codeGenerateInformationList, codeGenerateEdit } from '@/api/modular/gen/codeGenerateManage'
export default {
data () {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 15 }
},
visible: false,
tableNameData: [],
tablePrefixData: [],
generateTypeData: [],
confirmLoading: false,
tablePrefixValue: 'N',
tableNameValue: '',
packageNameShow: true,
form: this.$form.createForm(this)
}
},
methods: {
//
edit (record) {
this.visible = true
this.codeGenerateInformationList()
this.dataTypeItem()
setTimeout(() => {
this.form.setFieldsValue(
{
id: record.id,
tableName: record.tableName,
tablePrefix: record.tablePrefix,
tableComment: record.tableComment,
className: record.className,
busName: record.busName,
generateType: record.generateType,
authorName: record.authorName,
packageName: record.packageName
}
)
}, 100)
this.tableNameValue = record.tableName
this.tablePrefixValue = record.tablePrefix
},
/**
* 获得所有数据库的表
*/
codeGenerateInformationList () {
codeGenerateInformationList().then((res) => {
this.tableNameData = res.data
})
},
/**
* 获取字典数据
*/
dataTypeItem () {
this.tablePrefixData = this.$options.filters['dictData']('yes_or_no')
this.generateTypeData = this.$options.filters['dictData']('code_gen_create_type')
},
/**
* 提交表单
*/
handleSubmit () {
const { form: { validateFields } } = this
validateFields((errors, values) => {
if (!errors) {
this.confirmLoading = true
codeGenerateEdit(values).then((res) => {
if (res.success) {
this.$message.success('编辑成功')
this.$emit('ok', values)
this.handleCancel()
} else {
this.$message.error('编辑失败' + res.message)
}
}).finally((res) => {
this.confirmLoading = false
})
}
})
},
handleCancel () {
this.form.resetFields()
this.visible = false
},
/**
* 选择数据库列表
*/
tableNameSele (item) {
this.tableNameValue = item.tableName
this.form.setFieldsValue({ className: item.tableComment })
this.settingDefaultValue()
},
/**
* 选择是否移除前缀触发
*/
tablePrefixRadio (tablePrefixType) {
this.tablePrefixValue = tablePrefixType
this.settingDefaultValue()
},
/**
* 设置默认值
*/
settingDefaultValue () {
const tableName = this.classNameToHump()
this.form.setFieldsValue(
{
className: tableName,
busName: tableName.toLowerCase()
}
)
},
/**
* 设置类名为数据库表的驼峰命名
*/
classNameToHump () {
const arr = this.tableNameValue.toLowerCase().split('_')
if (this.tablePrefixValue === 'Y') {
arr.splice(0, 1)
}
for (let i = 0; i < arr.length; i++) {
// charAt()slice()
arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1)
}
return arr.join('')
},
/**
* 选择生成方式
*/
generateTypeRadio (generateType) {
if (generateType === '1') {
this.packageNameShow = true
} else {
this.packageNameShow = false
this.form.setFieldsValue({ packageName: 'com.cn.xiaonuo' })
}
}
}
}
</script>

View File

@ -0,0 +1,219 @@
<template>
<a-card :bordered="false">
<a-spin :spinning="Loading">
<div class="table-page-search-wrapper" v-if="hasPerm('codeGenerate:page')">
<a-form layout="inline">
<a-row :gutter="48">
<a-col :md="8" :sm="24">
<a-form-item label="表名称" >
<a-input v-model="queryParam.tableName" allow-clear placeholder="请输入表名称"/>
</a-form-item>
</a-col>
<a-col :md="8" :sm="24">
<a-button type="primary" @click="$refs.table.refresh(true)"></a-button>
<a-button style="margin-left: 8px" @click="() => queryParam = {}">重置</a-button>
</a-col>
</a-row>
</a-form>
</div>
<div class="table-operator" v-if="hasPerm('codeGenerate:add')" >
<a-button type="primary" v-if="hasPerm('codeGenerate:add')" icon="plus" @click="$refs.addForm.add()"></a-button>
</div>
<s-table
ref="table"
size="default"
:columns="columns"
:data="loadData"
:alert="true"
:rowKey="(record) => record.id"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
>
<span slot="tableName" slot-scope="text">
<ellipsis :length="10" tooltip>{{ text }}</ellipsis>
</span>
<span slot="packageName" slot-scope="text">
<ellipsis :length="10" tooltip>{{ text }}</ellipsis>
</span>
<span slot="tablePrefix" slot-scope="text">
<ellipsis :length="10" tooltip>{{ 'yes_or_no' | dictType(text) }}</ellipsis>
</span>
<span slot="generateType" slot-scope="text">
<ellipsis :length="10" tooltip>{{ 'code_gen_create_type' | dictType(text) }}</ellipsis>
</span>
<span slot="action" slot-scope="text, record">
<span v-if="record.generateType === '1'">
<a v-if="hasPerm('codeGenerate:runDown')" @click="runDownCodeGenerate(record)"></a>
</span>
<span v-else>
<a-popconfirm v-if="hasPerm('codeGenerate:runLocal')" placement="topRight" title="确定生成代码到本项目?" @confirm="() => runLocalCodeGenerate(record)">
<a>开始生成</a>
</a-popconfirm>
</span>
<a-divider type="vertical" v-if="hasPerm('codeGenerate:edit') & hasPerm('codeGenerate:runLocal') || hasPerm('codeGenerate:runDown') "/>
<a v-if="hasPerm('codeGenerate:edit')" @click="$refs.editForm.edit(record)"></a>
<a-divider type="vertical" v-if="hasPerm('codeGenerate:edit') & hasPerm('codeGenerate:delete')"/>
<a-popconfirm v-if="hasPerm('codeGenerate:delete')" placement="topRight" title="确认删除?" @confirm="() => codeGenerateDelete(record)">
<a>删除</a>
</a-popconfirm>
</span>
</s-table>
<add-form ref="addForm" @ok="handleOk" v-if="hasPerm('codeGenerate:add')"/>
<edit-form ref="editForm" @ok="handleOk" v-if="hasPerm('codeGenerate:edit')"/>
</a-spin>
</a-card>
</template>
<script>
import { STable, Ellipsis } from '@/components'
import { codeGeneratePage, codeGenerateDelete, codeGenerateRunDown, codeGenerateRunLocal } from '@/api/modular/gen/codeGenerateManage'
import addForm from './addForm'
import editForm from './editForm'
export default {
components: {
STable,
Ellipsis,
addForm,
editForm
},
data () {
return {
//
queryParam: {},
//
columns: [
{
title: '表名称',
dataIndex: 'tableName',
scopedSlots: { customRender: 'tableName' }
},
{
title: '代码包名',
dataIndex: 'packageName',
scopedSlots: { customRender: 'packageName' }
},
{
title: '业务名',
dataIndex: 'busName'
},
{
title: '类名',
dataIndex: 'className'
},
{
title: '功能名',
dataIndex: 'tableComment'
},
{
title: '作者姓名',
dataIndex: 'authorName'
},
{
title: '表前缀移除',
dataIndex: 'tablePrefix',
scopedSlots: { customRender: 'tablePrefix' }
},
{
title: '生成方式',
dataIndex: 'generateType',
scopedSlots: { customRender: 'generateType' }
}
],
loadData: parameter => {
return codeGeneratePage(Object.assign(parameter, this.queryParam)).then((res) => {
return res
})
},
selectedRowKeys: [],
selectedRows: [],
Loading: false,
jdbcDriverList: []
}
},
created () {
if (this.hasPerm('codeGenerate:edit') || this.hasPerm('codeGenerate:delete')) {
this.columns.push({
title: '操作',
width: '200px',
dataIndex: 'action',
scopedSlots: { customRender: 'action' }
})
}
},
methods: {
/**
* 开始生成代码生成压缩包
*/
runDownCodeGenerate (record) {
this.Loading = true
codeGenerateRunDown({ id: record.id }).then((res) => {
this.Loading = false
this.downloadfile(res)
// eslint-disable-next-line handle-callback-err
}).catch((err) => {
this.Loading = false
this.$message.error('下载错误:获取文件流错误')
})
},
downloadfile (res) {
var blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
var contentDisposition = res.headers['content-disposition']
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
var result = patt.exec(contentDisposition)
var filename = result[1]
var downloadElement = document.createElement('a')
var href = window.URL.createObjectURL(blob) //
var reg = /^["](.*)["]$/g
downloadElement.style.display = 'none'
downloadElement.href = href
downloadElement.download = decodeURI(filename.replace(reg, '$1')) //
document.body.appendChild(downloadElement)
downloadElement.click() //
document.body.removeChild(downloadElement) //
window.URL.revokeObjectURL(href)
},
/**
* 开始生成代码本地项目
*/
runLocalCodeGenerate (record) {
codeGenerateRunLocal(record).then((res) => {
if (res.success) {
this.$message.success('生成成功')
this.$refs.table.refresh()
} else {
this.$message.error('生成失败:' + res.message)
}
})
},
codeGenerateDelete (record) {
this.Loading = true
codeGenerateDelete([{ id: record.id }]).then((res) => {
if (res.success) {
this.$message.success('删除成功')
this.$refs.table.refresh()
} else {
this.$message.error('删除失败:' + res.message)
}
}).catch((err) => {
this.$message.error('删除错误:' + err.message)
}).finally((res) => {
this.Loading = false
})
},
handleOk () {
this.$refs.table.refresh()
},
onSelectChange (selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
}
}
}
</script>
<style lang="less">
.table-operator {
margin-bottom: 18px;
}
button {
margin-right: 8px;
}
</style>

View File

@ -18,6 +18,7 @@
<modules>
<module>xiaonuo-core</module>
<module>xiaonuo-system</module>
<module>xiaonuo-gen</module>
</modules>
</project>

View File

@ -27,7 +27,7 @@ package com.cn.xiaonuo.core.consts;
/**
*
*
* @author xuyuxiang
* @author xuyuxiang yubaoshan
* @date 2020/3/11 16:51
*/
public interface CommonConstant {
@ -106,4 +106,9 @@ public interface CommonConstant {
* header
*/
String REQUEST_NO_HEADER_NAME = "Request-No";
/**
* URL
*/
String DATABASE_URL_NAME = "DATABASE_URL_NAME";
}

View File

@ -0,0 +1 @@
** 代码生成 **

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.xiaonuo</groupId>
<artifactId>xiaonuo-base</artifactId>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>xiaonuo-gen</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>cn.xiaonuo</groupId>
<artifactId>xiaonuo-core</artifactId>
<version>1.1.0</version>
</dependency>
<!-- 依赖底层核心 -->
<dependency>
<groupId>cn.xiaonuo</groupId>
<artifactId>xiaonuo-system</artifactId>
<version>1.1.0</version>
</dependency>
<!-- 代码生成引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -0,0 +1,116 @@
package com.cn.xiaonuo.generate.core.config;
/**
*
*
* @author yubaoshan
* @date 2020-12-19 02:30:56
*/
public class Config {
/**
* vm
*/
public static String templatePath = "template/";
/**
*
*/
public static String DB_TABLE_COM_KRY = "PRI";
/**
* modular
*/
public static String MODULAR_NAME = "modular";
/**
*
*/
public static final boolean FLAG = false;
/**
*
*/
public static String BASE_MODULAR_NAME = "xiaonuo-main";
/**
* java
*/
public static String BASE_JAVA_PAHT = "\\src\\main\\java\\";
/**
* vue
*/
public static String BASE_VUE_PAHT = "\\_web\\src\\";
/**
*
*/
public static String controllerPath;
public static String entityPath;
public static String enumsPath;
public static String mapperPath;
public static String mappingPath;
public static String paramPath;
public static String servicePath;
public static String serviceImplPath;
public static String manageJsPath;
public static String vueIndexPath;
public static String vueAddFromPath;
public static String vueEditFromPath;
/**
*
*/
public static String[] xnCodeGenFilePath (String busName, String packageName) {
String packageNameString = packageName.replace(".","\\") + "\\";
controllerPath = BASE_JAVA_PAHT + packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "controller" + "\\";
entityPath = BASE_JAVA_PAHT + packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "entity" + "\\";
enumsPath = BASE_JAVA_PAHT+ packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "enums" + "\\";
mapperPath = BASE_JAVA_PAHT + packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "mapper" + "\\";
mappingPath = mapperPath + "\\" + "mapping" + "\\";
paramPath = BASE_JAVA_PAHT+ "\\" + packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "param" + "\\";
servicePath = BASE_JAVA_PAHT+ "\\" + packageNameString + MODULAR_NAME + "\\" + busName + "\\" + "service" + "\\";
serviceImplPath = servicePath + "\\" + "impl" + "\\";
manageJsPath = BASE_VUE_PAHT + "\\" + "api\\" + MODULAR_NAME + "\\main\\" + busName + "\\";
vueIndexPath = BASE_VUE_PAHT + "\\" + "views\\main\\" + busName + "\\";
vueAddFromPath = BASE_VUE_PAHT + "\\" + "views\\main\\" + busName + "\\";
vueEditFromPath = BASE_VUE_PAHT + "\\" + "views\\main\\" + busName + "\\";
return new String[] {
controllerPath, entityPath, enumsPath, mapperPath, mappingPath, paramPath, servicePath, serviceImplPath, manageJsPath, vueIndexPath, vueAddFromPath, vueEditFromPath
};
}
/**
*
*/
public static String[] xnCodeGenTempFile = {
"Controller.java.vm",
"entity.java.vm",
"ExceptionEnum.java.vm",
"Mapper.java.vm",
"Mapper.xml.vm",
"Param.java.vm",
"Service.java.vm",
"ServiceImpl.java.vm",
"Manage.js.vm",
"index.vue.vm",
"addForm.vue.vm",
"editForm.vue.vm",
};
/**
*
*/
public static String getLocalPath () {
return System.getProperty("user.dir") + "\\" + BASE_MODULAR_NAME + "\\";
}
/**
* vue
*/
public static String getLocalFrontPath () {
return System.getProperty("user.dir") + "\\" ;
}
}

View File

@ -0,0 +1,52 @@
package com.cn.xiaonuo.generate.core.context;
import com.cn.xiaonuo.generate.core.param.XnCodeGenParam;
import org.apache.velocity.VelocityContext;
/**
*
*
* @author yubaoshan
* @date 2020121702:04:56
*/
public class XnVelocityContext {
/**
*
*
* @author yubaoshan
* @date 2020121702:04:56
*/
public VelocityContext createVelContext (XnCodeGenParam xnCodeGenParam) {
VelocityContext velocityContext = new VelocityContext();
// 取得类名
String DomainName = xnCodeGenParam.getClassName();
String domainName = DomainName.substring(0,1).toLowerCase()+DomainName.substring(1);
// 类名称
velocityContext.put("ClassName",DomainName);
// 类名(首字母小写)
velocityContext.put("className",domainName);
// 功能名
velocityContext.put("functionName",xnCodeGenParam.getFunctionName());
// 包名称
velocityContext.put("packageName",xnCodeGenParam.getPackageName());
// 模块名称
velocityContext.put("modularName",xnCodeGenParam.getModularNane());
// 业务名
velocityContext.put("busName",xnCodeGenParam.getBusName());
// 作者姓名
velocityContext.put("authorName", xnCodeGenParam.getAuthorName());
// 代码生成时间
velocityContext.put("createDateString", xnCodeGenParam.getCreateTimeString());
// 数据库表名
velocityContext.put("tableName", xnCodeGenParam.getTableName());
// 数据库字段
velocityContext.put("tableField", xnCodeGenParam.getTableField());
return velocityContext;
}
}

View File

@ -0,0 +1,39 @@
package com.cn.xiaonuo.generate.core.enums;
import lombok.Getter;
/**
*
*
* @author yubaoshan
* @date 2020121700:11:40
*/
@Getter
public enum TableFilteredFieldsEnum {
CREATE_TIME("create_time"),
UPDATE_TIME("update_time"),
CREATE_USER("create_user"),
UPDATE_USER("update_user");
private final String propertyName;
TableFilteredFieldsEnum(String propertyName) {
this.propertyName = propertyName;
}
/**
*
*
* @author yubaoshan
* @date 2020121700:11:40
*/
public static boolean contains(String propertyName) {
for (TableFilteredFieldsEnum gunsFilteredFieldsEnum : TableFilteredFieldsEnum.values()) {
if (gunsFilteredFieldsEnum.propertyName.equals(propertyName)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,48 @@
package com.cn.xiaonuo.generate.core.param;
import lombok.Data;
/**
*
*
* @author yubaoshan
* @date 2020121700:08:40
*/
@Data
public class TableField {
/**
*
*/
public String columnName;
/**
*
*/
public String dataType;
/**
*
*/
public String columnComment;
/**
*
*/
public String columnKey;
/**
*
*/
public String columnKeyName;
/**
* Java(String,Integer,Date)
*/
private String javaType;
/**
*
*/
private Boolean primaryKeyFlag = false;
}

View File

@ -0,0 +1,94 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.core.param;
import com.cn.xiaonuo.generate.core.config.Config;
import lombok.Data;
import java.util.List;
@Data
public class XnCodeGenParam {
/**
*
*/
private String authorName;
/**
*
*/
private String className;
/**
*
*/
private String functionName;
/**
*
*/
private String tablePrefix;
/**
*
*/
private String generateType;
/**
*
*/
private String tableName;
/**
*
*/
private String tableNameAss;
/**
*
*/
private String packageName;
/**
* String
*/
private String createTimeString;
/**
*
*/
private List<TableField> tableField;
/**
*
*/
private String modularNane = Config.MODULAR_NAME;
/**
*
*/
private String busName;
}

View File

@ -0,0 +1,55 @@
package com.cn.xiaonuo.generate.core.tool;
/**
* javasql
*
* @author yubaoshan
* @date 2020-12-17 23:42
*/
public class JavaSqlTool {
/**
* JAVA
*
* @author yubaoshan
* @date 2020-12-17 23:42
*/
public static String sqlToJava (String sqlType) {
if( sqlType == null || sqlType.trim().length() == 0 ) return sqlType;
sqlType = sqlType.toLowerCase();
switch(sqlType){
case "nvarchar":return "String";
case "char":return "String";
case "varchar":return "String";
case "text":return "String";
case "nchar":return "String";
case "blob":return "byte[]";
case "integer":return "Long";
case "int":return "Integer";
case "tinyint":return "Integer";
case "smallint":return "Integer";
case "mediumint":return "Integer";
case "bit":return "Boolean";
case "bigint":return "Long";
case "float":return "Fload";
case "double":return "Double";
case "decimal":return "BigDecimal";
case "boolean":return "Boolean";
case "id":return "Long";
case "date":return "Date";
case "datetime":return "Date";
case "year":return "Date";
case "time":return "Time";
case "timestamp":return "Timestamp";
case "numeric":return "BigDecimal";
case "real":return "BigDecimal";
case "money":return "Double";
case "smallmoney":return "Double";
case "image":return "byte[]";
default:
System.out.println("-----------------》转化失败:未发现的类型" + sqlType);
break;
}
return sqlType;
}
}

View File

@ -0,0 +1,48 @@
package com.cn.xiaonuo.generate.core.tool;
/**
*
*
* @author yubaoshan
* @date 2020-12-17 23:55
*/
public class NamingConTool {
/**
* 线
*
* @author yubaoshan
* @date 2020-12-17 23:55
*/
public static String UnderlineToHump(String para, String prefix){
StringBuilder result=new StringBuilder();
String a[]=para.split("_");
for(String s:a){
if(result.length()==0){
result.append(s.toLowerCase());
}else{
result.append(s.substring(0, 1).toUpperCase());
result.append(s.substring(1).toLowerCase());
}
}
return result.toString();
}
/**
* 线
*
* @author yubaoshan
* @date 2020-12-17 23:55
*/
public static String HumpToUnderline(String para){
StringBuilder sb=new StringBuilder(para);
int temp=0;//偏移量第i个下划线的位置是 当前的位置+ 偏移量i-1,第一个下划线偏移量是0
for(int i=0;i<para.length();i++){
if(Character.isUpperCase(para.charAt(i))){
sb.insert(i+temp, "_");
temp+=1;
}
}
return sb.toString().toLowerCase();
}
}

View File

@ -0,0 +1,27 @@
package com.cn.xiaonuo.generate.core.tool;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* String
*
* @author yubaoshan
* @date 2020-12-17 23:42
*/
public class StringDateTool {
/**
*
*
* @author yubaoshan
* @date 2020-12-17 23:42
*/
public static String getStringDate() {
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(currentTime);
return dateString;
}
}

View File

@ -0,0 +1,73 @@
package com.cn.xiaonuo.generate.core.util;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.app.Velocity;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*
* @author yubaoshan
* @Date 2020121623:29:53
*/
public class Util {
/**
* vm
*
* @author yubaoshan
* @Date 2020121623:29:53
*/
public static void initVelocity() {
Properties properties = new Properties();
try {
properties.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
properties.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
properties.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
Velocity.init(properties);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
*
*
* @author yubaoshan
* @Date 2020121623:29:53
*/
public static void DownloadGen(HttpServletResponse response, byte[] bytes) throws IOException {
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"xiaonuoVue.zip\"");
response.addHeader("Content-Length", "" + bytes.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(bytes, response.getOutputStream());
}
/**
* i
*
* @param string
* @param i i
* @param str
* @author yubaoshan
* @date 2020121623:29:53
*/
public static int getIndex(String string, int i, String str) {
Matcher slashMatcher = Pattern.compile(str).matcher(string);
int mIdx = 0;
while (slashMatcher.find()) {
mIdx++;
//当"/"符号第三次出现的位置
if (mIdx == i) {
break;
}
}
return slashMatcher.start();
}
}

View File

@ -0,0 +1,149 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.controller;
import com.cn.xiaonuo.core.annotion.BusinessLog;
import com.cn.xiaonuo.core.annotion.Permission;
import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import com.cn.xiaonuo.core.pojo.response.ResponseData;
import com.cn.xiaonuo.core.pojo.response.SuccessResponseData;
import com.cn.xiaonuo.generate.modular.entity.CodeGenerate;
import com.cn.xiaonuo.generate.modular.param.CodeGenerateParam;
import com.cn.xiaonuo.generate.modular.service.CodeGenerateService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
*
*
* @auther yubaoshan
* @date 12/15/20 11:20 PM
*/
@RestController
public class CodeGenerateController {
@Resource
private CodeGenerateService codeGenerateService;
/**
*
*
* @author yubaoshan
* @date 2020121620:58:48
*/
@Permission
@GetMapping("/codeGenerate/page")
@BusinessLog(title = "代码生成配置_查询", opType = LogAnnotionOpTypeEnum.QUERY)
public PageResult<CodeGenerate> page(CodeGenerateParam codeGenerateParam) {
return codeGenerateService.page(codeGenerateParam);
}
/**
*
*
* @auther yubaoshan
* @date 12/15/20 11:20 PM
*/
@Permission
@PostMapping("/codeGenerate/add")
@BusinessLog(title = "代码生成配置_增加", opType = LogAnnotionOpTypeEnum.ADD)
public ResponseData add(@RequestBody @Validated(CodeGenerateParam.add.class) CodeGenerateParam codeGenerateParam) {
this.codeGenerateService.add(codeGenerateParam);
return new SuccessResponseData();
}
/**
*
*
* @auther yubaoshan
* @date 2020121620:56:19
*/
@Permission
@PostMapping("/codeGenerate/edit")
@BusinessLog(title = "代码生成配置_编辑", opType = LogAnnotionOpTypeEnum.EDIT)
public ResponseData edit(@RequestBody @Validated(CodeGenerateParam.add.class) CodeGenerateParam codeGenerateParam) {
codeGenerateService.edit(codeGenerateParam);
return new SuccessResponseData();
}
/**
*
*
* @author yubaoshan
* @date 2020121622:13:32
*/
@Permission
@PostMapping("/codeGenerate/delete")
@BusinessLog(title = "代码生成配置_删除", opType = LogAnnotionOpTypeEnum.DELETE)
public ResponseData delete(@RequestBody @Validated(CodeGenerateParam.delete.class) List<CodeGenerateParam> codeGenerateParamList) {
codeGenerateService.delete(codeGenerateParamList);
return new SuccessResponseData();
}
/**
*
*
* @author yubaoshan
* @date 2020-12-16 01:55:48
*/
@Permission
@GetMapping("/codeGenerate/InformationList")
@BusinessLog(title = "数据库表列表_查询", opType = LogAnnotionOpTypeEnum.QUERY)
public ResponseData InformationList() {
return ResponseData.success(codeGenerateService.InformationTableList());
}
/**
*
*
* @auther yubaoshan
* @date 12/15/20 11:20 PM
*/
@Permission
@PostMapping("/codeGenerate/runLocal")
@BusinessLog(title = "代码生成_本地项目", opType = LogAnnotionOpTypeEnum.OTHER)
public ResponseData runLocal(@RequestBody @Validated(CodeGenerateParam.detail.class) CodeGenerateParam codeGenerateParam) {
this.codeGenerateService.runLocal(codeGenerateParam);
return new SuccessResponseData();
}
/**
*
*
* @auther yubaoshan
* @date 12/15/20 11:20 PM
*/
@Permission
@GetMapping("/codeGenerate/runDown")
@BusinessLog(title = "代码生成_下载方式", opType = LogAnnotionOpTypeEnum.OTHER)
public void runDown(@Validated(CodeGenerateParam.detail.class) CodeGenerateParam codeGenerateParam, HttpServletResponse response) {
this.codeGenerateService.runDown(codeGenerateParam, response);
}
}

View File

@ -0,0 +1,89 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author yubaoshan
* @date 2020121621:04:37
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("sys_code_generate")
public class CodeGenerate extends BaseEntity {
/**
*
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
*
*/
private String authorName;
/**
*
*/
private String className;
/**
*
*/
private String tablePrefix;
/**
*
*/
private String generateType;
/**
*
*/
private String tableName;
/**
*
*/
private String packageName;
/**
*
*/
private String busName;
/**
*
*/
private String tableComment;
}

View File

@ -0,0 +1,75 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.enums;
import com.cn.xiaonuo.core.annotion.ExpEnumType;
import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum;
import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory;
import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant;
/**
*
*
* @author yubaoshan
* @date 2020121621:21:14
*/
@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_APP_EXCEPTION_ENUM)
public enum CodeGenerateExceptionEnum implements AbstractBaseExceptionEnum {
/**
*
*/
CODE_GEN_NOT_EXIST(1, "代码生成基础配置不存在"),
/**
*
*/
CODE_GEN_NOT_PATH(2,"本地生成代码输出路径错误"),
/**
*
*/
CODE_GEN_TABLE_NOT_PRI(3,"请检查此数据表中主键的定义");
private final Integer code;
private final String message;
CodeGenerateExceptionEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
@Override
public Integer getCode() {
return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code);
}
@Override
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,57 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.mapper;
import com.cn.xiaonuo.generate.modular.entity.CodeGenerate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cn.xiaonuo.generate.modular.result.InforMationColumnsResult;
import com.cn.xiaonuo.generate.modular.result.InformationResult;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*
*
* @author yubaoshan
* @date 2020121621:07:28
*/
public interface CodeGenerateMapper extends BaseMapper<CodeGenerate> {
/**
*
*
* @author yubaoshan
* @date 2020121720:06:05
*/
List<InformationResult> selectInformationTable(@Param("dbName") String dbName);
/**
*
*
* @author yubaoshan
* @date 2020121720:06:05
*/
List<InforMationColumnsResult> selectInformationColumns(@Param("dbName") String dbName, @Param("tableName") String tableName);
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.xiaonuo.generate.modular.mapper.CodeGenerateMapper">
<resultMap id="informationResult" type="com.cn.xiaonuo.generate.modular.result.InformationResult">
<result column="table_name" property="tableName" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="table_comment" property="tableComment" />
</resultMap>
<resultMap id="inforMationColumnsResult" type="com.cn.xiaonuo.generate.modular.result.InforMationColumnsResult">
<result column="column_name" property="columnName" />
<result column="data_type" property="dataType" />
<result column="column_comment" property="columnComment" />
<result column="column_key" property="columnKey" />
</resultMap>
<!-- 查询指定库中所有表 -->
<select id="selectInformationTable" parameterType="String" resultMap="informationResult">
select table_name,create_time,update_time,table_comment
from information_schema.tables
where
table_schema = '${dbName}'
</select>
<!-- 查询指定表中所有字段 -->
<select id="selectInformationColumns" parameterType="String" resultMap="inforMationColumnsResult">
select
column_name,data_type,column_comment,column_key
from information_schema.columns
where
table_schema = '${dbName}' and table_name = '${tableName}';
</select>
</mapper>

View File

@ -0,0 +1,98 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.param;
import com.cn.xiaonuo.core.pojo.base.param.BaseParam;
import com.cn.xiaonuo.core.validation.flag.FlagValue;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
*
*
* @author yubaoshan
* @date 2020121620:41:21
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class CodeGenerateParam extends BaseParam {
/**
*
*/
@NotNull(message = "id不能为空请检查id参数", groups = {edit.class, delete.class, detail.class})
private Long id;
/**
*
*/
@NotBlank(message = "作者姓名不能为空请检查authorName参数", groups = {BaseParam.add.class, edit.class})
private String authorName;
/**
*
*/
@NotBlank(message = "类名不能为空请检查className参数", groups = {BaseParam.add.class, edit.class})
private String className;
/**
*
*/
@NotBlank(message = "是否移除表前缀不能为空请检查tablePrefix参数", groups = {BaseParam.add.class, edit.class})
@FlagValue(message = "是否移除表前缀格式错误正确格式应该Y或者N请检查tablePrefix参数", groups = {add.class, edit.class})
private String tablePrefix;
/**
*
*/
@NotBlank(message = "生成方式不能为空请检查generateType参数", groups = {BaseParam.add.class, edit.class})
private String generateType;
/**
*
*/
@NotBlank(message = "数据库表名不能为空请检查tableName参数", groups = {BaseParam.add.class, edit.class})
private String tableName;
/**
*
*/
private String packageName;
/**
*
*/
@NotBlank(message = "业务名不能为空请检查busName参数", groups = {BaseParam.add.class, edit.class})
private String busName;
/**
*
*/
@NotBlank(message = "功能名不能为空请检查tableComment参数", groups = {BaseParam.add.class, edit.class})
private String tableComment;
}

View File

@ -0,0 +1,34 @@
package com.cn.xiaonuo.generate.modular.result;
import lombok.Data;
/**
*
*
* @author yubaoshan
* @date 2020121720:00:31
*/
@Data
public class InforMationColumnsResult {
/**
*
*/
public String columnName;
/**
*
*/
public String dataType;
/**
*
*/
public String columnComment;
/**
*
*/
public String columnKey;
}

View File

@ -0,0 +1,34 @@
package com.cn.xiaonuo.generate.modular.result;
import lombok.Data;
/**
*
*
* @author yubaoshan
* @date 2020121720:01:56
*/
@Data
public class InformationResult {
/**
*
*/
public String tableName;
/**
*
*/
public String createTime;
/**
*
*/
public String updateTime;
/**
*
*/
public String tableComment;
}

View File

@ -0,0 +1,106 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import com.cn.xiaonuo.generate.modular.entity.CodeGenerate;
import com.cn.xiaonuo.generate.modular.param.CodeGenerateParam;
import com.cn.xiaonuo.generate.modular.result.InformationResult;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* service
*
* @author yubaoshan
* @date 2020121621:03:15
*/
public interface CodeGenerateService extends IService<CodeGenerate> {
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
PageResult<CodeGenerate> page(CodeGenerateParam codeGenerateParam);
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
void add(CodeGenerateParam codeGenerateParam);
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
void delete(List<CodeGenerateParam> codeGenerateParamList);
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
void edit(CodeGenerateParam codeGenerateParam);
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
CodeGenerate detail(CodeGenerateParam codeGenerateParam);
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
List<InformationResult> InformationTableList ();
/**
*
*
* @author yubaoshan
* @date 2020121621:03:15
*/
void runLocal(CodeGenerateParam codeGenerateParam);
/**
* zip
*
* @author yubaoshan
* @date 2020121621:03:15
*/
void runDown(CodeGenerateParam codeGenerateParam, HttpServletResponse response);
}

View File

@ -0,0 +1,368 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuoAPACHE LICENSE 2.0使
1.LICENSE
2.XiaoNuo
3.
4. https://gitee.com/xiaonuobase/xiaonuo-layui
5. https://gitee.com/xiaonuobase/xiaonuo-layui
6.XiaoNuo https://www.xiaonuo.vip
*/
package com.cn.xiaonuo.generate.modular.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.core.consts.CommonConstant;
import com.cn.xiaonuo.core.context.constant.ConstantContext;
import com.cn.xiaonuo.core.exception.ServiceException;
import com.cn.xiaonuo.core.factory.PageFactory;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import com.cn.xiaonuo.generate.core.context.XnVelocityContext;
import com.cn.xiaonuo.generate.core.param.TableField;
import com.cn.xiaonuo.generate.core.param.XnCodeGenParam;
import com.cn.xiaonuo.generate.core.tool.JavaSqlTool;
import com.cn.xiaonuo.generate.core.tool.NamingConTool;
import com.cn.xiaonuo.generate.core.tool.StringDateTool;
import com.cn.xiaonuo.generate.core.config.Config;
import com.cn.xiaonuo.generate.core.enums.TableFilteredFieldsEnum;
import com.cn.xiaonuo.generate.core.util.Util;
import com.cn.xiaonuo.generate.modular.entity.CodeGenerate;
import com.cn.xiaonuo.generate.modular.enums.CodeGenerateExceptionEnum;
import com.cn.xiaonuo.generate.modular.mapper.CodeGenerateMapper;
import com.cn.xiaonuo.generate.modular.param.CodeGenerateParam;
import com.cn.xiaonuo.generate.modular.result.InforMationColumnsResult;
import com.cn.xiaonuo.generate.modular.result.InformationResult;
import com.cn.xiaonuo.generate.modular.service.CodeGenerateService;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* service
*
* @author yubaoshan
* @date 2020121621:31:57
*/
@Service
public class CodeGenerateServiceImpl extends ServiceImpl<CodeGenerateMapper, CodeGenerate> implements CodeGenerateService {
/**
*
*/
private static String TEMP_SUFFIX = ".vm";
/**
*
*/
private static String ENCODED = "UTF-8";
/**
*
*/
private static String ADD_FORM_PAGE_NAME = "addForm.vue";
private static String EDIT_FORM_PAGE_NAME = "editForm.vue";
private static String INDEX_PAGE_NAME = "index.vue";
private static String MANAGE_JS_NAME = "Manage.js";
private static String JAVA_SUFFIX = ".java";
private static String TEMP_ENTITY_NAME = "entity";
@Override
public PageResult<CodeGenerate> page(CodeGenerateParam codeGenerateParam) {
QueryWrapper<CodeGenerate> queryWrapper = new QueryWrapper<>();
if (ObjectUtil.isNotNull(codeGenerateParam)) {
//根据表名模糊查询
if (ObjectUtil.isNotEmpty(codeGenerateParam.getTableName())) {
queryWrapper.lambda().like(CodeGenerate::getTableName, codeGenerateParam.getTableName());
}
}
return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
}
@Override
public void add(CodeGenerateParam codeGenerateParam) {
CodeGenerate codeGenerate = new CodeGenerate();
BeanUtil.copyProperties(codeGenerateParam, codeGenerate);
if (!vldTablePri(codeGenerate.getTableName())) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_TABLE_NOT_PRI);
}
this.save(codeGenerate);
}
@Override
public void delete(List<CodeGenerateParam> codeGenerateParamList) {
codeGenerateParamList.forEach(codeGenerateParam -> {
this.removeById(codeGenerateParam.getId());
});
}
@Override
public void edit(CodeGenerateParam codeGenerateParam) {
CodeGenerate codeGenerate = this.queryCodeGenerate(codeGenerateParam);
BeanUtil.copyProperties(codeGenerateParam, codeGenerate);
if (!vldTablePri(codeGenerate.getTableName())) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_TABLE_NOT_PRI);
}
this.updateById(codeGenerate);
}
@Override
public CodeGenerate detail(CodeGenerateParam codeGenerateParam) {
return this.queryCodeGenerate(codeGenerateParam);
}
/**
*
*
* @author yubaoshan
* @date 2020121621:19:10
*/
private CodeGenerate queryCodeGenerate(CodeGenerateParam codeGenerateParam) {
CodeGenerate codeGenerate = this.getById(codeGenerateParam.getId());
if (ObjectUtil.isNull(codeGenerate)) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_NOT_EXIST);
}
return codeGenerate;
}
@Override
public List<InformationResult> InformationTableList () {
String databaseUrl = ConstantContext.me().getStr(CommonConstant.DATABASE_URL_NAME);
String dbName = databaseUrl.substring(Util.getIndex(databaseUrl, 3, "/") + 1, databaseUrl.indexOf("?"));
return this.baseMapper.selectInformationTable(dbName);
}
@Override
public void runLocal(CodeGenerateParam codeGenerateParam) {
XnCodeGenParam xnCodeGenParam = copyParams(codeGenerateParam);
codeGenLocal(xnCodeGenParam);
}
@Override
public void runDown(CodeGenerateParam codeGenerateParam, HttpServletResponse response) {
XnCodeGenParam xnCodeGenParam = copyParams(codeGenerateParam);
downloadCode(xnCodeGenParam, response);
}
/**
*
*
* @author yubaoshan
* @date 20201223 0032
*/
private boolean vldTablePri (String tableName) {
String databaseUrl = ConstantContext.me().getStr(CommonConstant.DATABASE_URL_NAME);
String dbName = databaseUrl.substring(Util.getIndex(databaseUrl, 3, "/") + 1, databaseUrl.indexOf("?"));
List<InforMationColumnsResult> inforMationColumnsResultList = this.baseMapper.selectInformationColumns(dbName, tableName);
for (int a = 0; a < inforMationColumnsResultList.size(); a++) {
if (inforMationColumnsResultList.get(a).columnKey.equals(Config.DB_TABLE_COM_KRY)) {
return true;
}
}
return false;
}
/**
*
*
* @author yubaoshan
* @date 20201223 0032
*/
private void downloadCode(XnCodeGenParam xnCodeGenParam, HttpServletResponse response) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
codeGenDown(xnCodeGenParam, zipOutputStream);
IOUtils.closeQuietly(zipOutputStream);
outputStream.toByteArray();
try {
Util.DownloadGen(response, outputStream.toByteArray());
} catch (Exception e) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_NOT_PATH);
}
}
/**
* 使
*
* @author yubaoshan
* @date 20201217 2330
*/
private XnCodeGenParam copyParams (CodeGenerateParam codeGenerateParam) {
CodeGenerate codeGenerate = this.queryCodeGenerate(codeGenerateParam);
String databaseUrl = ConstantContext.me().getStr(CommonConstant.DATABASE_URL_NAME);
String dbName = databaseUrl.substring(Util.getIndex(databaseUrl, 3, "/") + 1, databaseUrl.indexOf("?"));
List<InforMationColumnsResult> inforMationColumnsResultList = this.baseMapper.selectInformationColumns(dbName, codeGenerate.getTableName());
XnCodeGenParam param = new XnCodeGenParam();
List<TableField> tableFieldList = new ArrayList<TableField>();
inforMationColumnsResultList.forEach(item -> {
TableField tableField = new TableField();
BeanUtil.copyProperties(item, tableField);
if (tableField.getColumnKey().equals(Config.DB_TABLE_COM_KRY)) {
tableField.setPrimaryKeyFlag(true);
String columnName = NamingConTool.UnderlineToHump(item.getColumnName(),"");
tableField.setColumnKeyName(columnName.substring(0,1).toUpperCase() + columnName.substring(1,columnName.length()));
}
// 字段类型转换Java类型
tableField.setJavaType(JavaSqlTool.sqlToJava(item.getDataType()));
// 字段名称转换
tableField.setColumnName(NamingConTool.UnderlineToHump(item.getColumnName(), codeGenerate.getTablePrefix()));
// 过滤掉通用字段
if (!TableFilteredFieldsEnum.contains(item.getColumnName())) {
tableFieldList.add(tableField);
}
});
BeanUtil.copyProperties(codeGenerate, param);
// 功能名
param.setFunctionName(codeGenerate.getTableComment());
param.setTableField(tableFieldList);
param.setCreateTimeString(StringDateTool.getStringDate());
return param;
}
/**
*
*/
private void codeGenLocal (XnCodeGenParam xnCodeGenParam) {
XnVelocityContext context = new XnVelocityContext();
//初始化参数
Properties properties=new Properties();
//设置velocity资源加载方式为class
properties.setProperty("resource.loader", "class");
//设置velocity资源加载方式为file时的处理类
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
//实例化一个VelocityEngine对象
VelocityEngine velocityEngine=new VelocityEngine(properties);
String[] filePath = Config.xnCodeGenFilePath(xnCodeGenParam.getClassName().toLowerCase(), xnCodeGenParam.getPackageName());
for (int i = 0; i < filePath.length; i++) {
String templateName = Config.xnCodeGenTempFile[i];
String fileBaseName = ResetFileBaseName(xnCodeGenParam.getClassName(),
templateName.substring(templateName.indexOf("/") + 1, templateName.lastIndexOf(TEMP_SUFFIX)));
String path = Config.getLocalPath ();
// 前端VUE位置有所变化
if (fileBaseName.contains(INDEX_PAGE_NAME) || fileBaseName.contains(ADD_FORM_PAGE_NAME) ||
fileBaseName.contains(EDIT_FORM_PAGE_NAME) ||fileBaseName.contains(MANAGE_JS_NAME)) {
path = Config.getLocalFrontPath();
}
File file = new File(path + filePath[i] + fileBaseName);
//判断是否覆盖存在的文件
if(file.exists() && !Config.FLAG){
continue;
}
//获取父目录
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
try {
Writer writer = new FileWriter(file);
velocityEngine.mergeTemplate(Config.templatePath + templateName,ENCODED,context.createVelContext(xnCodeGenParam),writer);
writer.close();
} catch (Exception e) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_NOT_PATH);
}
}
}
/**
* ZIP
*/
private void codeGenDown (XnCodeGenParam xnCodeGenParam,ZipOutputStream zipOutputStream) {
Util.initVelocity();
XnVelocityContext context = new XnVelocityContext();
String[] filePath = Config.xnCodeGenFilePath(xnCodeGenParam.getClassName().toLowerCase(), xnCodeGenParam.getPackageName());
for (int a = 0; a < filePath.length; a++) {
String templateName = Config.xnCodeGenTempFile[a];
String fileBaseName = ResetFileBaseName(xnCodeGenParam.getClassName(),
templateName.substring(templateName.indexOf("/") + 1, templateName.lastIndexOf(TEMP_SUFFIX)));
XnZipOutputStream(context.createVelContext(xnCodeGenParam),
Config.templatePath + templateName,
filePath[a] + fileBaseName,
zipOutputStream);
}
}
/**
*
*/
private static String ResetFileBaseName (String className,String fileName) {
String fileBaseName = className + fileName;
// 实体类名称单独处理
if (fileBaseName.contains(TEMP_ENTITY_NAME)) {
return className + JAVA_SUFFIX;
}
// 首页index.vue界面
if (fileBaseName.contains(INDEX_PAGE_NAME)) {
return INDEX_PAGE_NAME;
}
// 表单界面名称
if (fileBaseName.contains(ADD_FORM_PAGE_NAME)) {
return ADD_FORM_PAGE_NAME;
}
if (fileBaseName.contains(EDIT_FORM_PAGE_NAME)) {
return EDIT_FORM_PAGE_NAME;
}
// js名称
if (fileBaseName.contains(MANAGE_JS_NAME)) {
return className.substring(0,1).toLowerCase() + className.substring(1) + MANAGE_JS_NAME;
}
return fileBaseName;
}
/**
* ZIP
*/
private void XnZipOutputStream (VelocityContext velContext,String tempName, String fileBaseName, ZipOutputStream zipOutputStream) {
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(tempName, ENCODED);
tpl.merge(velContext, sw);
try {
// 添加到zip
zipOutputStream.putNextEntry(new ZipEntry(fileBaseName));
IOUtils.write(sw.toString(), zipOutputStream, ENCODED);
IOUtils.closeQuietly(sw);
zipOutputStream.flush();
zipOutputStream.closeEntry();
} catch (IOException e) {
throw new ServiceException(CodeGenerateExceptionEnum.CODE_GEN_NOT_PATH);
}
}
}

View File

@ -0,0 +1,137 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.controller;
import com.cn.xiaonuo.core.annotion.BusinessLog;
import com.cn.xiaonuo.core.annotion.Permission;
import com.cn.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import com.cn.xiaonuo.core.pojo.response.ResponseData;
import com.cn.xiaonuo.core.pojo.response.SuccessResponseData;
import ${packageName}.${modularName}.${busName}.entity.${ClassName};
import ${packageName}.${modularName}.${busName}.param.${ClassName}Param;
import ${packageName}.${modularName}.${busName}.service.${ClassName}Service;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource;
import java.util.List;
/**
* ${functionName}控制器
*
* @author ${authorName}
* @date ${createDateString}
*/
@Controller
public class ${ClassName}Controller {
@Resource
private ${ClassName}Service ${className}Service;
/**
* 查询${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@GetMapping("/${className}/page")
@BusinessLog(title = "${functionName}_查询", opType = LogAnnotionOpTypeEnum.QUERY)
public PageResult<${ClassName}> page(${ClassName}Param ${className}Param) {
return ${className}Service.page(${className}Param);
}
/**
* 添加${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@PostMapping("/${className}/add")
@BusinessLog(title = "${functionName}_增加", opType = LogAnnotionOpTypeEnum.ADD)
public ResponseData add(@RequestBody @Validated(${ClassName}Param.add.class) ${ClassName}Param ${className}Param) {
${className}Service.add(${className}Param);
return new SuccessResponseData();
}
/**
* 删除${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@PostMapping("/${className}/delete")
@BusinessLog(title = "${functionName}_删除", opType = LogAnnotionOpTypeEnum.DELETE)
public ResponseData delete(@RequestBody @Validated(${ClassName}Param.delete.class) List<${ClassName}Param> ${className}ParamList) {
${className}Service.delete(${className}ParamList);
return new SuccessResponseData();
}
/**
* 编辑${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@PostMapping("/${className}/edit")
@BusinessLog(title = "${functionName}_编辑", opType = LogAnnotionOpTypeEnum.EDIT)
public ResponseData edit(@RequestBody @Validated(${ClassName}Param.edit.class) ${ClassName}Param ${className}Param) {
${className}Service.edit(${className}Param);
return new SuccessResponseData();
}
/**
* 查看${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@GetMapping("/${className}/detail")
@BusinessLog(title = "${functionName}_查看", opType = LogAnnotionOpTypeEnum.DETAIL)
public ResponseData detail(@Validated(${ClassName}Param.detail.class) ${ClassName}Param ${className}Param) {
return new SuccessResponseData(${className}Service.detail(${className}Param));
}
/**
* ${functionName}列表
*
* @author ${authorName}
* @date ${createDateString}
*/
@Permission
@GetMapping("/${className}/list")
@BusinessLog(title = "${functionName}_列表", opType = LogAnnotionOpTypeEnum.QUERY)
public ResponseData list(${ClassName}Param ${className}Param) {
return new SuccessResponseData(${className}Service.list(${className}Param));
}
}

View File

@ -0,0 +1,64 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.enums;
import com.cn.xiaonuo.core.annotion.ExpEnumType;
import com.cn.xiaonuo.core.exception.enums.abs.AbstractBaseExceptionEnum;
import com.cn.xiaonuo.core.factory.ExpEnumCodeFactory;
import com.cn.xiaonuo.sys.core.consts.SysExpEnumConstant;
/**
* ${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@ExpEnumType(module = SysExpEnumConstant.XIAONUO_SYS_MODULE_EXP_CODE, kind = SysExpEnumConstant.SYS_POS_EXCEPTION_ENUM)
public enum ${ClassName}ExceptionEnum implements AbstractBaseExceptionEnum {
/**
* 数据不存在
*/
NOT_EXIST(1, "此数据不存在");
private final Integer code;
private final String message;
${ClassName}ExceptionEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
@Override
public Integer getCode() {
return ExpEnumCodeFactory.getExpEnumCode(this.getClass(), code);
}
@Override
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,71 @@
import { axios } from '@/utils/request'
/**
* 查询${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
export function ${className}Page (parameter) {
return axios({
url: '/${className}/page',
method: 'get',
params: parameter
})
}
/**
* ${functionName}列表
*
* @author ${authorName}
* @date ${createDateString}
*/
export function ${className}List (parameter) {
return axios({
url: '/${className}/list',
method: 'get',
params: parameter
})
}
/**
* 添加${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
export function ${className}Add (parameter) {
return axios({
url: '/${className}/add',
method: 'post',
data: parameter
})
}
/**
* 编辑${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
export function ${className}Edit (parameter) {
return axios({
url: '/${className}/edit',
method: 'post',
data: parameter
})
}
/**
* 删除${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
export function ${className}Delete (parameter) {
return axios({
url: '/${className}/delete',
method: 'post',
data: parameter
})
}

View File

@ -0,0 +1,37 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${packageName}.${modularName}.${busName}.entity.${ClassName};
/**
* ${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${packageName}.${modularName}.${busName}.mapper.${ClassName}Mapper">
</mapper>

View File

@ -0,0 +1,48 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.param;
import com.cn.xiaonuo.core.pojo.base.param.BaseParam;
import lombok.Data;
import java.util.*;
/**
* ${functionName}参数类
*
* @author ${authorName}
* @date ${createDateString}
*/
@Data
public class ${ClassName}Param extends BaseParam {
#foreach ($column in $tableField)
/**
* ${column.columnComment}
*/
private ${column.javaType} ${column.columnName};
#end
}

View File

@ -0,0 +1,88 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import ${packageName}.${modularName}.${busName}.entity.${ClassName};
import ${packageName}.${modularName}.${busName}.param.${ClassName}Param;
import java.util.List;
/**
* ${functionName}service接口
*
* @author ${authorName}
* @date ${createDateString}
*/
public interface ${ClassName}Service extends IService<${ClassName}> {
/**
* 查询${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
PageResult<${ClassName}> page(${ClassName}Param ${className}Param);
/**
* ${functionName}列表
*
* @author ${authorName}
* @date ${createDateString}
*/
List<${ClassName}> list(${ClassName}Param ${className}Param);
/**
* 添加${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
void add(${ClassName}Param ${className}Param);
/**
* 删除${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
void delete(List<${ClassName}Param> ${className}ParamList);
/**
* 编辑${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
void edit(${ClassName}Param ${className}Param);
/**
* 查看${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
${ClassName} detail(${ClassName}Param ${className}Param);
}

View File

@ -0,0 +1,136 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.core.consts.CommonConstant;
import com.cn.xiaonuo.core.enums.CommonStatusEnum;
import com.cn.xiaonuo.core.exception.ServiceException;
import com.cn.xiaonuo.core.factory.PageFactory;
import com.cn.xiaonuo.core.pojo.page.PageResult;
import ${packageName}.${modularName}.${busName}.entity.${ClassName};
import ${packageName}.${modularName}.${busName}.enums.${ClassName}ExceptionEnum;
import ${packageName}.${modularName}.${busName}.mapper.${ClassName}Mapper;
import ${packageName}.${modularName}.${busName}.param.${ClassName}Param;
import ${packageName}.${modularName}.${busName}.service.${ClassName}Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* ${functionName}service接口实现类
*
* @author ${authorName}
* @date ${createDateString}
*/
@Service
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements ${ClassName}Service {
@Override
public PageResult<${ClassName}> page(${ClassName}Param ${className}Param) {
QueryWrapper<${ClassName}> queryWrapper = new QueryWrapper<>();
if (ObjectUtil.isNotNull(${className}Param)) {
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
// 根据条件 模糊查询
if (ObjectUtil.isNotEmpty(${className}Param.get${column.columnKeyName}())) {
queryWrapper.lambda().like(${ClassName}::get${column.columnKeyName}, ${className}Param.get${column.columnKeyName}());
}
#end
#end
}
return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
}
@Override
public List<${ClassName}> list(${ClassName}Param ${className}Param) {
LambdaQueryWrapper<${ClassName}> queryWrapper = new LambdaQueryWrapper<>();
if (ObjectUtil.isNotNull(${className}Param)) {
//根据条件模糊查询
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
if (ObjectUtil.isNotEmpty(${className}Param.get${column.columnKeyName}())) {
queryWrapper.eq(${ClassName}::get${column.columnKeyName}, ${className}Param.get${column.columnKeyName}());
}
#end
#end
}
return this.list(queryWrapper);
}
@Override
public void add(${ClassName}Param ${className}Param) {
${ClassName} ${className} = new ${ClassName}();
BeanUtil.copyProperties(${className}Param, ${className});
this.save(${className});
}
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(List<${ClassName}Param> ${className}ParamList) {
${className}ParamList.forEach(${className}Param -> {
${ClassName} ${className} = this.query${ClassName}(${className}Param);
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
this.removeById(${className}.get${column.columnKeyName}());
});
#end
#end
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(${ClassName}Param ${className}Param) {
${ClassName} ${className} = this.query${ClassName}(${className}Param);
BeanUtil.copyProperties(${className}Param, ${className});
this.updateById(${className});
}
@Override
public ${ClassName} detail(${ClassName}Param ${className}Param) {
return this.query${ClassName}(${className}Param);
}
/**
* 获取${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
private ${ClassName} query${ClassName}(${ClassName}Param ${className}Param) {
${ClassName} ${className} = this.getById(${className}Param.getId());
if (ObjectUtil.isNull(${className})) {
throw new ServiceException(${ClassName}ExceptionEnum.NOT_EXIST);
}
return ${className};
}
}

View File

@ -0,0 +1,84 @@
<template>
<a-modal
title="新增${functionName}"
:width="900"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
#foreach ($column in $tableField)
#if (!${column.primaryKeyFlag})
<a-form-item
label="${column.columnComment}"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入${column.columnComment}" v-decorator="['${column.columnName}', {rules: [{required: true, message: '请输入${column.columnComment}'}]}]" />
</a-form-item>
#end
#end
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { ${className}Add } from '@/api/modular/main/${busName}/${className}Manage'
export default {
data () {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 15 }
},
visible: false,
confirmLoading: false,
form: this.$form.createForm(this)
}
},
methods: {
// 初始化方法
add (record) {
this.visible = true
},
/**
* 提交表单
*/
handleSubmit () {
const { form: { validateFields } } = this
this.confirmLoading = true
validateFields((errors, values) => {
if (!errors) {
${className}Add(values).then((res) => {
if (res.success) {
this.$message.success('新增成功')
this.confirmLoading = false
this.$emit('ok', values)
this.handleCancel()
} else {
this.$message.error('新增失败')// + res.message
}
}).finally((res) => {
this.confirmLoading = false
})
} else {
this.confirmLoading = false
}
})
},
handleCancel () {
this.form.resetFields()
this.visible = false
}
}
}
</script>

View File

@ -0,0 +1,96 @@
<template>
<a-modal
title="编辑${functionName}"
:width="900"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
<a-form-item v-show="false">
<a-input v-decorator="['${column.columnName}']" />
</a-form-item>
#else
<a-form-item
label="${column.columnComment}"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
has-feedback
>
<a-input placeholder="请输入${column.columnComment}" v-decorator="['${column.columnName}', {rules: [{required: true, message: '请输入${column.columnComment}'}]}]" />
</a-form-item>
#end
#end
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { ${className}Edit } from '@/api/modular/main/${busName}/${className}Manage'
export default {
data () {
return {
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 15 }
},
visible: false,
confirmLoading: false,
form: this.$form.createForm(this)
}
},
methods: {
// 初始化方法
edit (record) {
this.visible = true
setTimeout(() => {
this.form.setFieldsValue(
{
#foreach ($column in $tableField)
${column.columnName}: record.${column.columnName}#if($foreach.hasNext),
#end
#end
}
)
}, 100)
},
handleSubmit () {
const { form: { validateFields } } = this
this.confirmLoading = true
validateFields((errors, values) => {
if (!errors) {
${className}Edit(values).then((res) => {
if (res.success) {
this.$message.success('编辑成功')
this.confirmLoading = false
this.$emit('ok', values)
this.handleCancel()
} else {
this.$message.error('编辑失败')// + res.message
}
}).finally((res) => {
this.confirmLoading = false
})
} else {
this.confirmLoading = false
}
})
},
handleCancel () {
this.form.resetFields()
this.visible = false
}
}
}
</script>

View File

@ -0,0 +1,60 @@
/*
Copyright [2020] [https://www.xiaonuo.vip]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
XiaoNuo采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改XiaoNuo源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/xiaonuo-layui
6.若您的项目无法满足以上几点可申请商业授权获取XiaoNuo商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/
package ${packageName}.${modularName}.${busName}.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.cn.xiaonuo.core.pojo.base.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.*;
/**
* ${functionName}
*
* @author ${authorName}
* @date ${createDateString}
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("${tableName}")
public class ${ClassName} extends BaseEntity {
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
private ${column.javaType} ${column.columnName};
#else
/**
* ${column.columnComment}
*/
private ${column.javaType} ${column.columnName};
#end
#end
}

View File

@ -0,0 +1,135 @@
<template>
<a-card :bordered="false">
<div class="table-page-search-wrapper" v-if="hasPerm('${className}:page')">
<a-form layout="inline">
<a-row :gutter="48">
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
<a-col :md="8" :sm="24">
<a-form-item label="${column.columnComment}" >
<a-input v-model="queryParam.${column.columnName}" allow-clear placeholder="请输入${column.columnComment}"/>
</a-form-item>
</a-col>
#end
#end
<a-col :md="!advanced && 8 || 24" :sm="24">
<span class="table-page-search-submitButtons" :style="advanced && { float: 'right', overflow: 'hidden' } || {} ">
<a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
<a-button style="margin-left: 8px" @click="() => queryParam = {}">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class="table-operator" v-if="hasPerm('${className}:add')" >
<a-button type="primary" v-if="hasPerm('${className}:add')" icon="plus" @click="$refs.addForm.add()">新增${functionName}</a-button>
</div>
<s-table
ref="table"
size="default"
:columns="columns"
:data="loadData"
:alert="true"
#foreach ($column in $tableField)
#if (${column.primaryKeyFlag})
:rowKey="(record) => record.${column.columnName}"
#end
#end
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
>
<span slot="action" slot-scope="text, record">
<a v-if="hasPerm('${className}:edit')" @click="$refs.editForm.edit(record)">编辑</a>
<a-divider type="vertical" v-if="hasPerm('${className}:edit') & hasPerm('${className}:delete')"/>
<a-popconfirm v-if="hasPerm('${className}:delete')" placement="topRight" title="确认删除?" @confirm="() => ${className}Delete(record)">
<a>删除</a>
</a-popconfirm>
</span>
</s-table>
<add-form ref="addForm" @ok="handleOk" />
<edit-form ref="editForm" @ok="handleOk" />
</a-card>
</template>
<script>
import { STable } from '@/components'
import { ${className}Page, ${className}Delete } from '@/api/modular/main/${busName}/${className}Manage'
import addForm from './addForm.vue'
import editForm from './editForm.vue'
export default {
components: {
STable,
addForm,
editForm
},
data () {
return {
// 高级搜索 展开/关闭
advanced: false,
// 查询参数
queryParam: {},
// 表头
columns: [
#foreach ($column in $tableField)
#if (!${column.primaryKeyFlag})
{
title: '${column.columnComment}',
dataIndex: '${column.columnName}'
}#if($foreach.hasNext),
#end
#end
#end
],
// 加载数据方法 必须为 Promise 对象
loadData: parameter => {
return ${className}Page(Object.assign(parameter, this.queryParam)).then((res) => {
return res.data
})
},
selectedRowKeys: [],
selectedRows: []
}
},
created () {
if (this.hasPerm('${className}:edit') || this.hasPerm('${className}:delete')) {
this.columns.push({
title: '操作',
width: '150px',
dataIndex: 'action',
scopedSlots: { customRender: 'action' }
})
}
},
methods: {
${className}Delete (record) {
${className}Delete(record).then((res) => {
if (res.success) {
this.$message.success('删除成功')
this.$refs.table.refresh()
} else {
this.$message.error('删除失败') // + res.message
}
})
},
toggleAdvanced () {
this.advanced = !this.advanced
},
handleOk () {
this.$refs.table.refresh()
},
onSelectChange (selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
}
}
}
</script>
<style lang="less">
.table-operator {
margin-bottom: 18px;
}
button {
margin-right: 8px;
}
</style>

View File

@ -30,6 +30,7 @@ import cn.hutool.db.Entity;
import cn.hutool.db.handler.EntityListHandler;
import cn.hutool.db.sql.SqlExecutor;
import cn.hutool.log.Log;
import com.cn.xiaonuo.core.consts.CommonConstant;
import com.cn.xiaonuo.core.context.constant.ConstantContext;
import com.cn.xiaonuo.core.enums.CommonStatusEnum;
import com.cn.xiaonuo.core.exception.ServiceException;
@ -76,6 +77,9 @@ public class ConstantsInitListener implements ApplicationListener<ApplicationCon
String dataSourceUsername = environment.getProperty("spring.datasource.username");
String dataSourcePassword = environment.getProperty("spring.datasource.password");
// 缓存中放入datasource链接代码生成时候使用
ConstantContext.putConstant(CommonConstant.DATABASE_URL_NAME, dataSourceUrl);
// 如果有为空的配置,终止执行
if (ObjectUtil.hasEmpty(dataSourceUrl, dataSourceUsername, dataSourcePassword)) {
throw new ServiceException(SysConfigExceptionEnum.DATA_SOURCE_NOT_EXIST);

View File

@ -23,6 +23,13 @@
<version>1.1.0</version>
</dependency>
<!-- 代码生成模块 -->
<dependency>
<groupId>cn.xiaonuo</groupId>
<artifactId>xiaonuo-gen</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>