代码生成、优化

This commit is contained in:
吕金泽
2022-03-27 22:44:48 +08:00
parent 43976afbee
commit 178e024cf8
115 changed files with 1140 additions and 302 deletions
@@ -44,7 +44,7 @@
})
function reload(){
tableRef.value.reloadList()
tableRef.value.reload()
}
function selectionChange(columns) {
@@ -1,6 +1,6 @@
<template>
<div>
<el-row style="margin-bottom: 6px">
<el-row style="margin-bottom: 6px" v-if="toolbar">
<el-button type="primary" @click="addRow">添加一行</el-button>
</el-row>
<mb-table ref="magicTable" v-bind="tableOptions">
@@ -22,7 +22,7 @@
<script setup>
import { reactive, ref, watch } from 'vue'
import { reactive, ref, watch, nextTick } from 'vue'
const emit = defineEmits(['update:modelValue', 'change'])
@@ -47,6 +47,10 @@ const props = defineProps({
page: {
type: Boolean,
default: false
},
toolbar: {
type: Boolean,
default: true
}
})
@@ -90,7 +94,6 @@ watch(() => props.modelValue, (value) => {
function addRow(){
tableOptions.data.push({})
magicTable.value.reloadList()
}
function dataChange() {
@@ -145,14 +145,14 @@ function sortChange(column) {
order = null
}
newWhere.orderBy = order
reloadList()
reload()
}
function selectionChange(columns) {
emit('selection-change', columns)
}
function reloadList() {
function reload() {
if (props.url) {
newWhere.current = 1
listCurrent.value = 1
@@ -207,7 +207,7 @@ function keyup(){
watch(() => props.data, () => {
listCurrent.value = 1
handlerData()
})
},{ deep: true })
watch(() => props.where,() => {
renderWhere()
@@ -225,7 +225,7 @@ onMounted(() => {
}
})
defineExpose({ reloadList })
defineExpose({ reload })
</script>
@@ -140,7 +140,7 @@ export default {
this.$delete('file/delete', { url: encodeURI(url) })
},
handlePreview(file) {
window.open(this.$global.filePrefix + file.response.data.url)
window.open(this.$global.baseApi + file.response.data.url)
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
@@ -13,8 +13,8 @@
:style="{ width: width.replace('px', '') + 'px', height: height.replace('px', '') + 'px' }"
>
<el-image
:src="$global.filePrefix + element"
:preview-src-list="[$global.filePrefix + element]"
:src="$global.baseApi + element"
:preview-src-list="[$global.baseApi + element]"
/>
<div class="tools">
<div class="shadow" @click="handleRemove(element)">
@@ -227,7 +227,7 @@ export default {
})
},
beforeCropper(url) {
this.cropperOption.img = this.$global.filePrefix + url
this.cropperOption.img = this.$global.baseApi + url
this.cropperOption.relativeImg = url
this.$refs.cropperDialog.show()
},
+1 -1
View File
@@ -6,7 +6,7 @@
</div>
<div class="header-right">
<div class="avatar">
<el-avatar :size="40" fit="contain" :src="$global.filePrefix + $global.user.info.headPortrait">
<el-avatar :size="40" fit="contain" :src="$global.baseApi + $global.user.info.headPortrait">
{{ !$global.user.info.headPortrait ? $global.user.info.name.substring(0,1) : '' }}
</el-avatar>
<el-dropdown>
+1 -1
View File
@@ -34,7 +34,7 @@ router.beforeEach(async(to, from, next) => {
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
await getUserInfo()
await common.getDictData()
await common.loadConfig()
// await common.loadConfig()
// generate accessible routes map based on roles
await generateRoutes().then(accessRoutes => {
global.user.permissionRoutes.push(...accessRoutes)
+8 -8
View File
@@ -158,14 +158,14 @@ common.getUrl = (url, data) => {
return url
}
common.loadConfig = async() => {
await request({
url: 'config/list'
}).then(res => {
const { data } = res
global.filePrefix = data.filePrefix
})
}
// common.loadConfig = async() => {
// await request({
// url: 'config/list'
// }).then(res => {
// const { data } = res
// global.filePrefix = data.filePrefix
// })
// }
common.setDefaultValue = (obj, attr, value) => {
obj[attr] = obj[attr] === undefined ? value : obj[attr]
@@ -0,0 +1,6 @@
function gen(groupPath, data){
var magic = {}
}
export default gen
+50 -11
View File
@@ -26,35 +26,39 @@ function gen(groupPath, data){
}],
table: {
url: '${groupPath}/list',
where: {
`
where: {`
for(var i in data){
var d = data[i]
if(d.query){
html += `
${d.columnName}: {
label: '${d.columnComment}'
},
`
},`
}
}
html = html.substring(0, html.length - 1)
html += `
},
cols: [
`
cols: [`
for(var i in data){
var d = data[i]
if(d.list){
html += `
if(d.dictType){
html += `
{
dictType: '${d.dictType}',`
}else{
html += `
{
`
}
html += `
field: '${d.columnName}',
label: '${d.columnComment}'
},
`
},`
}
}
html += `
{
html += `{
label: '操作',
type: 'btns',
width: 140,
@@ -85,7 +89,42 @@ function gen(groupPath, data){
]
}
]
}
})
`
html += `
const formOptions = reactive({
detail: {
request: {
url: '${groupPath}/get'
}
},
form: {
request: {
url: "${groupPath}/save",
method: "post"
},
rows: [{
gutter: 24,
cols: [`
for(var i in data){
var d = data[i]
if(d.save){
html += `{
span: 12,
name: '${d.columnName}',
label: '${d.columnComment}',
${d.component}
},`
}
}
html = html.substring(0, html.length - 1)
html += `]
}]
}
})
`
console.log(html)
}
export default gen
+1 -1
View File
@@ -8,7 +8,7 @@ export default {
info: {},
permissionRoutes: []
},
filePrefix: '',
baseApi: import.meta.env.VITE_APP_BASE_API,
visitedViews: reactive([]),
tabValue: ref('')
}
@@ -12,12 +12,12 @@ import genCode from '@/scripts/gen/gen-mb-list.js'
const { proxy } = getCurrentInstance()
const tableDatas = reactive([])
proxy.$get('/code/gen/columns', { tableName: 'sys_user' }).then(res => {
proxy.$get('/code/gen/columns', { tableName: 'sys_test' }).then(res => {
var columns = res.data.columns
var primary = res.data.primary
columns.forEach(it => {
tableDatas.push({
columnName: it.columnName,
columnName: it.columnName.replace(/\_(\w)/g, (all, letter) => letter.toUpperCase()),
columnComment: it.columnComment,
dataType: it.dataType
})
@@ -99,34 +99,61 @@ const cols = reactive([{
props: {
options: [{
label: '单行文本框',
value: 'input'
value: `component: 'input'`
},{
label: '多行文本框',
value: 'textarea'
value: `component: 'input',
props: {
type: 'textarea'
}
`
},{
label: '单选下拉框',
value: 'radioSelect'
value: `component: 'select'`
},{
label: '多选下拉框',
value: 'multipleSelect'
value: `component: 'select',
props: {
multiple: true
}
`
},{
label: '单选按钮',
value: 'radio'
label: '单选',
value: `component: 'radio-group'`
},{
label: '复选框',
value: 'checkbox'
value: `component: 'checkbox-group'`
},{
label: '日期选择',
value: 'date'
value: `component: 'date'`
},{
label: '日期时间',
value: 'datetime'
value: `component: 'date',
props: {
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss'
}
`
},{
label: '图片上传',
value: 'uploadImage'
value: `component: 'upload-image'`
},{
label: '文件上传',
value: 'uploadFile'
value: `component: 'upload-file'`
},{
label: '多图片上传',
value: `component: 'upload-image',
props: {
multiple: true
}
`
},{
label: '多文件上传',
value: `component: 'upload-file',
props: {
multiple: true
}
`
}]
}
}, {
@@ -140,7 +167,7 @@ const cols = reactive([{
}])
function gen(){
genCode('user', tableDatas)
genCode('test', tableDatas)
}
function getData(){
@@ -119,13 +119,8 @@ const listOptions = reactive({
})
const formOptions = reactive({
detail: {
// request: {
// url: 'user/get'
// },
handlerFormData: (formData) => {
proxy.$get('user/roles', { userId: formData.id }).then((res) => {
formData.roles = res.data.join(',')
})
request: {
url: 'user/get'
}
},
form: {
@@ -145,18 +140,11 @@ const formOptions = reactive({
span: 12,
name: 'username',
label: '登录名称',
rules: [{ required: true, message: '请输入登录名称', trigger: 'change' }],
props: {
autocomplete: 'new-password'
}
rules: [{ required: true, message: '请输入登录名称', trigger: 'change' }]
}, {
span: 12,
name: 'password',
label: '密码',
props: {
type: 'password',
autocomplete: 'new-password'
}
label: '密码'
}]
},{
gutter: 24,
+317 -18
View File
@@ -1,27 +1,326 @@
<template>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="基本信息" name="basic">
<el-row :gutter="24">
<el-col :span="24">
<el-form-item label="分组名称">
<el-input v-model="formData.groupName"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="字段信息" name="field">
</el-tab-pane>
<el-tab-pane label="生成信息" name="gen">
</el-tab-pane>
</el-tabs>
<el-form ref="dataForm" :model="genInfo" :rules="genInfoRules" label-position="right" label-width="120px">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="表信息" name="basic">
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="表名" prop="tableName">
<mb-select v-model="genInfo.tableName" :options="tables" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="描述" prop="tableComment">
<el-input v-model="genInfo.tableComment" />
</el-form-item>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="字段信息" name="field">
<el-button type="primary" @click="getData" style="margin-bottom: 10px">获取数据</el-button>
<el-button type="primary" @click="gen" style="margin-bottom: 10px">代码生成</el-button>
<mb-editor-table v-model="genInfo.columns" :cols="cols" :show-no="false" :operation="false" :toolbar="false" />
</el-tab-pane>
<el-tab-pane label="生成信息" name="gen">
<el-row :gutter="24">
<el-col :span="24">
<el-form-item label="生成模板" prop="info.template">
<mb-select v-model="genInfo.info.template" :options="[{ label: '单表(增删改查)', value: 'singleTable' }]" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="info.moduleName">
<template #label>
模块名称
<el-tooltip content="第一级分组名称,例如:系统功能" placement="top">
<el-icon><ElQuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input v-model="genInfo.info.moduleName"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="info.modulePath">
<template #label>
模块路径
<el-tooltip content="第一级分组的路径,例如:/system" placement="top">
<el-icon><ElQuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input v-model="genInfo.info.modulePath"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="info.businessName">
<template #label>
功能名称
<el-tooltip content="第二级分组名称,例如:菜单管理" placement="top">
<el-icon><ElQuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input v-model="genInfo.info.businessName"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="info.businessPath">
<template #label>
功能路径
<el-tooltip content="第二级分组路径,例如:/menu" placement="top">
<el-icon><ElQuestionFilled /></el-icon>
</el-tooltip>
</template>
<el-input v-model="genInfo.info.businessPath"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</el-form>
</template>
<script setup>
import {reactive, ref} from 'vue'
import {reactive, ref, watch, getCurrentInstance, defineExpose, onMounted} from 'vue'
import genCode from '@/scripts/gen/gen-mb-list.js'
const { proxy } = getCurrentInstance()
const dataForm = ref()
const tables = ref([])
const emit = defineEmits(['reload'])
const genInfoRules = reactive({
tableName: [{ required: true, message: '请选择表', trigger: 'change' }],
tableComment: [{ required: true, message: '请输入描述', trigger: 'change' }],
'info.template': [{ required: true, message: '请选择模板', trigger: 'change' }],
'info.moduleName': [{ required: true, message: '请输入模块名称', trigger: 'change' }],
'info.modulePath': [{ required: true, message: '请输入模块路径', trigger: 'change' }],
'info.businessName': [{ required: true, message: '请输入功能名称', trigger: 'change' }],
'info.businessPath': [{ required: true, message: '请输入功能路径', trigger: 'change' }]
})
const genInfo = ref({
tableName: '',
tableComment: '',
info: {
moduleName: '',
modulePath: '',
businessName: '',
businessPath: '',
template: 'singleTable'
},
columns: []
})
async function watchTableName(){
await proxy.$get('/code/gen/tables').then(res => {
tables.value = res.data
})
watch(() => genInfo.value.tableName, (value) => {
genInfo.value.tableComment = tables.value.filter(it => it.value == value)[0].label.replace(value, '').replace('(','').replace(')','')
genInfo.value.columns = []
proxy.$get('/code/gen/columns', { tableName: value }).then(res => {
var columns = res.data.columns
var primary = res.data.primary
columns.forEach(it => {
genInfo.value.columns.push({
columnName: it.columnName.replace(/\_(\w)/g, (all, letter) => letter.toUpperCase()),
columnComment: it.columnComment,
columnType: it.columnType,
component: `component: 'input'`,
where: 'eq',
save: true,
query: true,
list: true,
required: it.required == 1
})
})
})
})
}
const activeName = ref('basic')
const formData = reactive({
groupName: ''
})
const cols = reactive([{
field: 'columnName',
label: '列名'
}, {
field: 'columnComment',
label: '列说明',
component: 'input'
}, {
field: 'columnType',
label: '字段类型'
}, {
field: 'save',
label: '保存',
component: 'switch',
width: '80px'
}, {
field: 'list',
label: '列表',
component: 'switch',
width: '80px'
}, {
field: 'query',
label: '查询',
component: 'switch',
width: '80px'
}, {
field: 'where',
label: '匹配方式',
component: 'select',
props: {
options: [{
label: 'eq',
value: 'eq'
},{
label: 'ne',
value: 'ne'
},{
label: 'lt',
value: 'lt'
},{
label: 'lte',
value: 'lte'
},{
label: 'gt',
value: 'gt'
},{
label: 'gte',
value: 'gte'
},{
label: 'in',
value: 'in'
},{
label: 'notIn',
value: 'notIn'
},{
label: 'like',
value: 'like'
},{
label: 'notLike',
value: 'notLike'
}]
}
}, {
field: 'required',
label: '必填',
component: 'switch',
width: '80px'
}, {
field: 'component',
label: '控件类型',
component: 'select',
props: {
options: [{
label: '单行文本框',
value: `component: 'input'`
},{
label: '多行文本框',
value: `component: 'input',
props: {
type: 'textarea'
}
`
},{
label: '单选下拉框',
value: `component: 'select'`
},{
label: '多选下拉框',
value: `component: 'select',
props: {
multiple: true
}
`
},{
label: '单选框',
value: `component: 'radio-group'`
},{
label: '复选框',
value: `component: 'checkbox-group'`
},{
label: '日期选择',
value: `component: 'date'`
},{
label: '日期时间',
value: `component: 'date',
props: {
type: 'datetime',
format: 'YYYY-MM-DD HH:mm:ss'
}
`
},{
label: '图片上传',
value: `component: 'upload-image'`
},{
label: '文件上传',
value: `component: 'upload-file'`
},{
label: '多图片上传',
value: `component: 'upload-image',
props: {
multiple: true
}
`
},{
label: '多文件上传',
value: `component: 'upload-file',
props: {
multiple: true
}
`
}]
}
}, {
component: 'select',
field: 'dictType',
label: '字典类型',
props: {
url: 'dict/all',
showValue: true
}
}])
function gen(){
genCode('test', genInfo.value.columns)
}
function getData(){
console.log(genInfo.value.columns)
}
function save(d){
dataForm.value.validate((valid) => {
if (valid) {
var formData = {...genInfo.value}
formData.info = JSON.stringify(genInfo.value.info)
formData.columns = JSON.stringify(genInfo.value.columns)
d.loading()
proxy.$post('/code/gen/save', formData).then(() => {
d.hideLoading()
proxy.$notify({
title: '成功',
message: d.title + '成功',
type: 'success',
duration: 2000
})
emit('reload')
d.hide()
}).catch(() => d.hideLoading())
}else{
proxy.$message.error('表单校验未通过,请重新检查提交内容')
}
})
}
function getDetail(id){
proxy.$get('/code/gen/get', { id: id }).then(res => {
var formData = {...res.data}
formData.info = JSON.parse(formData.info)
formData.columns = JSON.parse(formData.columns)
genInfo.value = formData
watchTableName()
})
}
defineExpose({ save, getDetail, watchTableName })
</script>
@@ -1,15 +1,15 @@
<template>
<mb-list ref="magicList" v-bind="listOptions" />
<mb-dialog ref="formDialog" title="配置" @confirm-click="magicForm.save($event)" width="50%">
<mb-dialog ref="formDialog" title="配置" @confirm-click="magicForm.save($event)" width="1400px">
<template #content>
<code-gen-form />
<code-gen-form ref="magicForm" @reload="magicList.reload" />
</template>
</mb-dialog>
</template>
<script setup>
import codeGenForm from './code-gen-form.vue'
import { ref, reactive, getCurrentInstance } from 'vue'
import {ref, reactive, getCurrentInstance, nextTick} from 'vue'
const { proxy } = getCurrentInstance()
const formDialog = ref()
const magicList = ref()
@@ -20,10 +20,23 @@
permission: 'code:gen:save',
click: () => {
formDialog.value.show()
nextTick(() => magicForm.value.watchTableName())
}
}],
table: {
url: 'code/gen/list',
where: {
tableName: {
label: '表名'
},
tableComment: {
label: '描述'
},
createDate: {
label: '创建时间',
type: 'daterange'
}
},
cols: [
{
field: 'tableName',
@@ -31,6 +44,12 @@
},{
field: 'tableComment',
label: '描述'
},{
field: 'createDate',
label: '创建时间'
},{
field: 'updateDate',
label: '更新时间'
}, {
label: '操作',
type: 'btns',
@@ -44,6 +63,7 @@
icon: 'ElEdit',
click: (row) => {
formDialog.value.show()
nextTick(() => magicForm.value.getDetail(row.id))
}
}, {
permission: 'code:gen:delete',
@@ -51,11 +71,11 @@
type: 'text',
icon: 'ElDelete',
click: (row) => {
// proxy.$common.handleDelete({
// url: 'user/delete',
// id: row.id,
// done: () => magicList.value.reload()
// })
proxy.$common.handleDelete({
url: 'code/gen/delete',
id: row.id,
done: () => magicList.value.reload()
})
}
}
]
@@ -1,3 +1,3 @@
<template>
<iframe :src="$global.filePrefix + 'magic/web/index.html'" width="100%" height="100%" frameborder="0"></iframe>
<iframe :src="$global.baseApi + 'magic/web/index.html'" width="100%" height="100%" frameborder="0"></iframe>
</template>
@@ -138,7 +138,7 @@ const formDialog = ref()
const dataForm = ref()
function reloadTable() {
table.value.reloadList()
table.value.reload()
}
function getTemp() {
@@ -181,7 +181,7 @@ function getTemp() {
}
function reloadTable() {
table.value.reloadList()
table.value.reload()
}
function getSort() {
@@ -119,7 +119,7 @@ const getTemp = () => {
isShow: 1,
pid: 0,
icon: '',
keepAlive: 1,
keepAlive: 0,
componentName: ''
}
}
@@ -1,3 +1,3 @@
<template>
<iframe :src="$global.filePrefix + 'druid/index.html'" width="100%" height="100%" frameborder="0"></iframe>
<iframe :src="$global.baseApi + 'druid/index.html'" width="100%" height="100%" frameborder="0"></iframe>
</template>
@@ -62,6 +62,6 @@
]
})
function reloadTable(){
table.value.reloadList()
table.value.reload()
}
</script>
@@ -61,6 +61,6 @@
]
})
function reloadTable(){
table.value.reloadList()
table.value.reload()
}
</script>
@@ -186,7 +186,7 @@ watch(() => temp.value.permission,() => {
})
function reloadTable() {
table.value.reloadList()
table.value.reload()
}
function getTemp(){
@@ -66,7 +66,7 @@ function getTemp() {
}
function reloadTable() {
table.value.reloadList()
table.value.reload()
}
function handleCreate() {
@@ -53,6 +53,7 @@ const emit = defineEmits(['reload-table'])
const { proxy } = getCurrentInstance()
const rules = reactive({
name: [{ required: true, message: '请输入姓名/昵称', trigger: 'change' }],
username: [{ required: true, message: '请输入登录名称', trigger: 'change' }],
roles: [{ required: true, message: '请选择角色', trigger: 'change' }],
officeId: [{ required: true, message: '请选择组织机构', trigger: 'change' }]
@@ -193,7 +193,7 @@ function selectionChange(columns) {
function reloadTable() {
userFormDialog.value.hide()
table.value.reloadList()
table.value.reload()
}
function handleCreate() {