系统功能板块setup改造完成

This commit is contained in:
piexlmax
2021-12-30 20:48:57 +08:00
parent 512e91e2bc
commit 8c2b6b2bc0
7 changed files with 563 additions and 534 deletions
@@ -30,7 +30,6 @@
style="width:100%"
placeholder="请选择field数据类型"
clearable
@change="getDbfdOptions"
>
<el-option
v-for="item in typeOptions"
@@ -79,103 +78,109 @@
</div>
</template>
<script>
<script setup>
import { toLowerCase, toSQLLine } from '@/utils/stringFun'
import { getSysDictionaryList } from '@/api/sysDictionary'
import warningBar from '@/components/warningBar/warningBar.vue'
import { ref, defineProps, defineExpose } from 'vue-demi'
const props = defineProps({
dialogMiddle: {
type: Object,
default: function() {
return {}
}
}
})
const middleDate = ref({})
const dictOptions = ref([])
const typeSearchOptions = ref([
{
label: '=',
value: '='
},
{
label: '<>',
value: '<>'
},
{
label: '>',
value: '>'
},
{
label: '<',
value: '<'
},
{
label: 'LIKE',
value: 'LIKE'
}
])
const typeOptions = ref([
{
label: '字符串',
value: 'string'
},
{
label: '整型',
value: 'int'
},
{
label: '布尔值',
value: 'bool'
},
{
label: '浮点型',
value: 'float64'
},
{
label: '时间',
value: 'time.Time'
}
])
const rules = ref({
fieldName: [
{ required: true, message: '请输入field英文名', trigger: 'blur' }
],
fieldDesc: [
{ required: true, message: '请输入field中文名', trigger: 'blur' }
],
fieldJson: [
{ required: true, message: '请输入field格式化json', trigger: 'blur' }
],
columnName: [
{ required: true, message: '请输入数据库字段', trigger: 'blur' }
],
fieldType: [
{ required: true, message: '请选择field数据类型', trigger: 'blur' }
]
})
const init = async() => {
middleDate.value = props.dialogMiddle
const dictRes = await getSysDictionaryList({
page: 1,
pageSize: 999999
})
dictOptions.value = dictRes.data.list
}
init()
const autoFill = () => {
middleDate.value.fieldJson = toLowerCase(middleDate.value.fieldName)
middleDate.value.columnName = toSQLLine(middleDate.value.fieldJson)
}
const fieldDialogFrom = ref(null)
defineExpose({ fieldDialogFrom })
</script>
<script>
export default {
name: 'FieldDialog',
components: { warningBar },
props: {
dialogMiddle: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
middleDate: {},
dictOptions: [],
typeSearchOptions: [
{
label: '=',
value: '='
},
{
label: '<>',
value: '<>'
},
{
label: '>',
value: '>'
},
{
label: '<',
value: '<'
},
{
label: 'LIKE',
value: 'LIKE'
}
],
typeOptions: [
{
label: '字符串',
value: 'string'
},
{
label: '整型',
value: 'int'
},
{
label: '布尔值',
value: 'bool'
},
{
label: '浮点型',
value: 'float64'
},
{
label: '时间',
value: 'time.Time'
}
],
rules: {
fieldName: [
{ required: true, message: '请输入field英文名', trigger: 'blur' }
],
fieldDesc: [
{ required: true, message: '请输入field中文名', trigger: 'blur' }
],
fieldJson: [
{ required: true, message: '请输入field格式化json', trigger: 'blur' }
],
columnName: [
{ required: true, message: '请输入数据库字段', trigger: 'blur' }
],
fieldType: [
{ required: true, message: '请选择field数据类型', trigger: 'blur' }
]
}
}
},
async created() {
this.middleDate = this.dialogMiddle
const dictRes = await getSysDictionaryList({
page: 1,
pageSize: 999999
})
this.dictOptions = dictRes.data.list
},
methods: {
autoFill() {
this.middleDate.fieldJson = toLowerCase(this.middleDate.fieldName)
this.middleDate.columnName = toSQLLine(this.middleDate.fieldJson)
},
}
name: 'FieldDialog'
}
</script>
@@ -8,70 +8,78 @@
</div>
</template>
<script>
<script setup>
import marked from 'marked'
import hljs from 'highlight.js'
// import 'highlight.js/styles/atelier-cave-light.css';
import 'highlight.js/styles/atelier-plateau-light.css'
export default {
props: {
previewCode: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
activeName: ''
}
},
mounted() {
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code) {
return hljs.highlightAuto(code).value
},
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
})
for (const key in this.previewCode) {
if (this.activeName === '') {
this.activeName = key
}
document.getElementById(key).innerHTML = marked(this.previewCode[key])
}
},
methods: {
selectText() {
const element = document.getElementById(this.activeName)
if (document.body.createTextRange) {
const range = document.body.createTextRange()
range.moveToElementText(element)
range.select()
} else if (window.getSelection) {
const selection = window.getSelection()
const range = document.createRange()
range.selectNodeContents(element)
selection.removeAllRanges()
selection.addRange(range)
} else {
alert('none')
}
},
copy() {
this.selectText()
document.execCommand('copy')
this.$message.success('复制成功')
import { onMounted, ref } from 'vue-demi'
import { ElMessage } from 'element-plus'
import { defineProps, defineExpose } from 'vue'
const props = defineProps({
previewCode: {
type: Object,
default() {
return {}
}
}
})
onMounted(() => {
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function(code) {
return hljs.highlightAuto(code).value
},
pedantic: false,
gfm: true,
tables: true,
breaks: false,
sanitize: false,
smartLists: true,
smartypants: false,
xhtml: false
})
for (const key in props.previewCode) {
if (this.activeName === '') {
this.activeName = key
}
document.getElementById(key).innerHTML = marked(props.previewCode[key])
}
})
const activeName = ref('')
const selectText = () => {
const element = document.getElementById(activeName.value)
if (document.body.createTextRange) {
const range = document.body.createTextRange()
range.moveToElementText(element)
range.select()
} else if (window.getSelection) {
const selection = window.getSelection()
const range = document.createRange()
range.selectNodeContents(element)
selection.removeAllRanges()
selection.addRange(range)
} else {
alert('none')
}
}
const copy = () => {
selectText()
document.execCommand('copy')
ElMessage.success('复制成功')
}
defineExpose({ copy })
</script>
<script>
export default {
}
</script>
+249 -242
View File
@@ -14,7 +14,7 @@
</template>
<el-form ref="getTableForm" style="margin-top:24px" :inline="true" :model="dbform" label-width="120px">
<el-form-item label="数据库名" prop="structName">
<el-select v-model="dbform.dbName" filterable placeholder="请选择数据库" @change="getTable">
<el-select v-model="dbform.dbName" filterable placeholder="请选择数据库" @change="getTableFunc">
<el-option
v-for="item in dbOptions"
:key="item.database"
@@ -39,7 +39,7 @@
</el-select>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="getColumn">使用此表创建</el-button>
<el-button size="mini" type="primary" @click="getColumnFunc">使用此表创建</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
@@ -61,7 +61,7 @@
<el-input v-model="form.description" placeholder="中文描述作为自动api描述" />
</el-form-item>
<el-form-item label="文件名称" prop="packageName">
<el-input v-model="form.packageName" placeholder="生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)" @blur="toLowerCase(form,'packageName')" />
<el-input v-model="form.packageName" placeholder="生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)" @blur="toLowerCaseFunc(form,'packageName')" />
</el-form-item>
<el-form-item>
<template #label>
@@ -138,7 +138,7 @@
</div>
<!-- 组件弹窗 -->
<el-dialog v-model="dialogFlag" title="组件内容">
<FieldDialog v-if="dialogFlag" ref="fieldDialog" :dialog-middle="dialogMiddle" />
<FieldDialog v-if="dialogFlag" ref="fieldDialogNode" :dialog-middle="dialogMiddle" />
<template #footer>
<div class="dialog-footer">
<el-button size="mini" @click="closeDialog">取 消</el-button>
@@ -155,7 +155,7 @@
<el-button size="mini" type="primary" @click="copy">复制</el-button>
</div>
</template>
<PreviewCodeDialog v-if="previewFlag" ref="preview" :preview-code="preViewCode" />
<PreviewCodeDialog v-if="previewFlag" ref="previewNode" :preview-code="preViewCode" />
<template #footer>
<div class="dialog-footer" style="padding-top:14px;padding-right:14px">
<el-button size="small" type="primary" @click="previewFlag = false">确 定</el-button>
@@ -165,7 +165,8 @@
</div>
</template>
<script>
<script setup>
const fieldTemplate = {
fieldName: '',
fieldDesc: '',
@@ -184,240 +185,230 @@ import PreviewCodeDialog from '@/view/systemTools/autoCode/component/previewCode
import { toUpperCase, toHump, toSQLLine, toLowerCase } from '@/utils/stringFun'
import { createTemp, getDB, getTable, getColumn, preview, getMeta } from '@/api/autoCode'
import { getDict } from '@/utils/dictionary'
import { ref, getCurrentInstance } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
export default {
name: 'AutoCode',
components: {
FieldDialog,
PreviewCodeDialog
},
data() {
return {
activeNames: [''],
preViewCode: {},
dbform: {
dbName: '',
tableName: ''
},
dbOptions: [],
tableOptions: [],
addFlag: '',
fdMap: {},
form: {
structName: '',
tableName: '',
packageName: '',
abbreviation: '',
description: '',
autoCreateApiToSql: false,
autoMoveFile: false,
fields: []
},
rules: {
structName: [
{ required: true, message: '请输入结构体名称', trigger: 'blur' }
],
abbreviation: [
{ required: true, message: '请输入结构体简称', trigger: 'blur' }
],
description: [
{ required: true, message: '请输入结构体描述', trigger: 'blur' }
],
packageName: [
{
required: true,
message: '文件名称:sysXxxxXxxx',
trigger: 'blur'
}
]
},
dialogMiddle: {},
bk: {},
dialogFlag: false,
previewFlag: false
const route = useRoute()
const activeNames = ref([''])
const preViewCode = ref({})
const dbform = ref({
dbName: '',
tableName: ''
})
const dbOptions = ref([])
const tableOptions = ref([])
const addFlag = ref('')
const fdMap = ref({})
const form = ref({
structName: '',
tableName: '',
packageName: '',
abbreviation: '',
description: '',
autoCreateApiToSql: false,
autoMoveFile: false,
fields: []
})
const rules = ref({
structName: [
{ required: true, message: '请输入结构体名称', trigger: 'blur' }
],
abbreviation: [
{ required: true, message: '请输入结构体简称', trigger: 'blur' }
],
description: [
{ required: true, message: '请输入结构体描述', trigger: 'blur' }
],
packageName: [
{
required: true,
message: '文件名称:sysXxxxXxxx',
trigger: 'blur'
}
},
created() {
this.getDb()
this.setFdMap()
const id = this.$route.params.id
if (id) {
this.getAutoCodeJson(id)
]
})
const dialogMiddle = ref({})
const bk = ref({})
const dialogFlag = ref(false)
const previewFlag = ref(false)
const toLowerCaseFunc = (form, key) => {
form[key] = toLowerCase(form[key])
}
const previewNode = ref(null)
const selectText = () => {
previewNode.value.selectText()
}
const copy = () => {
previewNode.value.copy()
}
const editAndAddField = (item) => {
dialogFlag.value = true
if (item) {
addFlag.value = 'edit'
bk.value = JSON.parse(JSON.stringify(item))
dialogMiddle.value = item
} else {
addFlag.value = 'add'
dialogMiddle.value = JSON.parse(JSON.stringify(fieldTemplate))
}
}
const moveUpField = (index) => {
if (index === 0) {
return
}
const oldUpField = form.value.fields[index - 1]
form.value.fields.splice(index - 1, 1)
form.value.fields.splice(index, 0, oldUpField)
}
const moveDownField = (index) => {
const fCount = form.value.fields.length
if (index === fCount - 1) {
return
}
const oldDownField = form.value.fields[index + 1]
form.value.fields.splice(index + 1, 1)
form.value.fields.splice(index, 0, oldDownField)
}
const currentInstance = getCurrentInstance()
const enterDialog = () => {
currentInstance.refs.fieldDialogNode.fieldDialogFrom.validate(valid => {
if (valid) {
dialogMiddle.value.fieldName = toUpperCase(
dialogMiddle.value.fieldName
)
if (addFlag.value === 'add') {
form.value.fields.push(dialogMiddle.value)
}
dialogFlag.value = false
} else {
return false
}
},
methods: {
toLowerCase(form, key) {
form[key] = toLowerCase(form[key])
},
selectText() {
this.$refs.preview.selectText()
},
copy() {
this.$refs.preview.copy()
},
editAndAddField(item) {
this.dialogFlag = true
if (item) {
this.addFlag = 'edit'
this.bk = JSON.parse(JSON.stringify(item))
this.dialogMiddle = item
})
}
const closeDialog = () => {
if (addFlag.value === 'edit') {
dialogMiddle.value = bk.value
}
dialogFlag.value = false
}
const deleteField = (index) => {
form.value.fields.splice(index, 1)
}
const autoCodeForm = ref(null)
const enterForm = async(isPreview) => {
if (form.value.fields.length <= 0) {
ElMessage({
type: 'error',
message: '请填写至少一个field'
})
return false
}
if (
form.value.fields.some(item => item.fieldName === form.value.structName)
) {
ElMessage({
type: 'error',
message: '存在与结构体同名的字段'
})
return false
}
autoCodeForm.value.validate(async valid => {
if (valid) {
for (const key in form.value) {
if (typeof form.value[key] === 'string') {
form.value[key] = form.value[key].trim()
}
}
form.value.structName = toUpperCase(form.value.structName)
if (form.value.tableName) { form.value.tableName = form.value.tableName.replace(' ', '') }
if (form.value.structName === form.value.abbreviation) {
ElMessage({
type: 'error',
message: 'structName和struct简称不能相同'
})
return false
}
form.value.humpPackageName = toSQLLine(form.value.packageName)
if (isPreview) {
const data = await preview(form.value)
preViewCode.value = data.data.autoCode
previewFlag.value = true
} else {
this.addFlag = 'add'
this.dialogMiddle = JSON.parse(JSON.stringify(fieldTemplate))
}
},
moveUpField(index) {
if (index === 0) {
return
}
const oldUpField = this.form.fields[index - 1]
this.form.fields.splice(index - 1, 1)
this.form.fields.splice(index, 0, oldUpField)
},
moveDownField(index) {
const fCount = this.form.fields.length
if (index === fCount - 1) {
return
}
const oldDownField = this.form.fields[index + 1]
this.form.fields.splice(index + 1, 1)
this.form.fields.splice(index, 0, oldDownField)
},
enterDialog() {
this.$refs.fieldDialog.$refs.fieldDialogFrom.validate(valid => {
if (valid) {
this.dialogMiddle.fieldName = toUpperCase(
this.dialogMiddle.fieldName
)
if (this.addFlag === 'add') {
this.form.fields.push(this.dialogMiddle)
}
this.dialogFlag = false
const data = await createTemp(form.value)
if (data.headers?.success === 'false') {
return
} else {
return false
}
})
},
closeDialog() {
if (this.addFlag === 'edit') {
this.dialogMiddle = this.bk
}
this.dialogFlag = false
},
deleteField(index) {
this.form.fields.splice(index, 1)
},
async enterForm(isPreview) {
if (this.form.fields.length <= 0) {
this.$message({
type: 'error',
message: '请填写至少一个field'
})
return false
}
if (
this.form.fields.some(item => item.fieldName === this.form.structName)
) {
this.$message({
type: 'error',
message: '存在与结构体同名的字段'
})
return false
}
this.$refs.autoCodeForm.validate(async valid => {
if (valid) {
for (const key in this.form) {
if (typeof this.form[key] === 'string') {
this.form[key] = this.form[key].trim()
}
}
this.form.structName = toUpperCase(this.form.structName)
if (this.form.tableName) { this.form.tableName = this.form.tableName.replace(' ', '') }
if (this.form.structName === this.form.abbreviation) {
this.$message({
type: 'error',
message: 'structName和struct简称不能相同'
if (form.value.autoMoveFile) {
ElMessage({
type: 'success',
message: '自动化代码创建成功,自动移动成功'
})
return false
return
}
this.form.humpPackageName = toSQLLine(this.form.packageName)
if (isPreview) {
const data = await preview(this.form)
this.preViewCode = data.data.autoCode
this.previewFlag = true
} else {
const data = await createTemp(this.form)
if (data.headers?.success === 'false') {
return
} else {
if (this.form.autoMoveFile) {
this.$message({
type: 'success',
message: '自动化代码创建成功,自动移动成功'
})
return
}
this.$message({
type: 'success',
message: '自动化代码创建成功,正在下载'
})
}
const blob = new Blob([data])
const fileName = 'ginvueadmin.zip'
if ('download' in document.createElement('a')) {
// 不是IE浏览器
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
} else {
// IE 10+
window.navigator.msSaveBlob(blob, fileName)
}
}
ElMessage({
type: 'success',
message: '自动化代码创建成功,正在下载'
})
}
const blob = new Blob([data])
const fileName = 'ginvueadmin.zip'
if ('download' in document.createElement('a')) {
// 不是IE浏览器
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
} else {
return false
// IE 10+
window.navigator.msSaveBlob(blob, fileName)
}
})
},
async getDb() {
const res = await getDB()
if (res.code === 0) {
this.dbOptions = res.data.dbs
}
},
async getTable() {
const res = await getTable({ dbName: this.dbform.dbName })
if (res.code === 0) {
this.tableOptions = res.data.tables
}
this.dbform.tableName = ''
},
async getColumn() {
const gormModelList = ['id', 'created_at', 'updated_at', 'deleted_at']
const res = await getColumn(this.dbform)
if (res.code === 0) {
const tbHump = toHump(this.dbform.tableName)
this.form.structName = toUpperCase(tbHump)
this.form.tableName = this.dbform.tableName
this.form.packageName = tbHump
this.form.abbreviation = tbHump
this.form.description = tbHump + '表'
this.form.autoCreateApiToSql = true
this.form.fields = []
res.data.columns &&
} else {
return false
}
})
}
const getDbFunc = async() => {
const res = await getDB()
if (res.code === 0) {
dbOptions.value = res.data.dbs
}
}
const getTableFunc = async() => {
const res = await getTable({ dbName: dbform.value.dbName })
if (res.code === 0) {
tableOptions.value = res.data.tables
}
dbform.value.tableName = ''
}
const getColumnFunc = async() => {
const gormModelList = ['id', 'created_at', 'updated_at', 'deleted_at']
const res = await getColumn(dbform.value)
if (res.code === 0) {
const tbHump = toHump(dbform.value.tableName)
form.value.structName = toUpperCase(tbHump)
form.value.tableName = dbform.value.tableName
form.value.packageName = tbHump
form.value.abbreviation = tbHump
form.value.description = tbHump + '表'
form.value.autoCreateApiToSql = true
form.value.fields = []
res.data.columns &&
res.data.columns.forEach(item => {
if (!gormModelList.some(gormfd => gormfd === item.columnName)) {
const fbHump = toHump(item.columnName)
this.form.fields.push({
form.value.fields.push({
fieldName: toUpperCase(fbHump),
fieldDesc: item.columnComment || fbHump + '字段',
fieldType: this.fdMap[item.dataType],
fieldType: fdMap.value[item.dataType],
dataType: item.dataType,
fieldJson: fbHump,
dataTypeLong: item.dataTypeLong && item.dataTypeLong.split(',')[0],
@@ -428,25 +419,41 @@ export default {
})
}
})
}
},
async setFdMap() {
const fdTypes = ['string', 'int', 'bool', 'float64', 'time.Time']
fdTypes.forEach(async fdtype => {
const res = await getDict(fdtype)
res && res.forEach(item => {
this.fdMap[item.label] = fdtype
})
})
},
async getAutoCodeJson(id) {
const res = await getMeta({ id: Number(id) })
if (res.code === 0) {
this.form = JSON.parse(res.data.meta)
}
}
}
}
const setFdMap = async() => {
const fdTypes = ['string', 'int', 'bool', 'float64', 'time.Time']
fdTypes.forEach(async fdtype => {
const res = await getDict(fdtype)
res && res.forEach(item => {
fdMap.value[item.label] = fdtype
})
})
}
const getAutoCodeJson = async(id) => {
const res = await getMeta({ id: Number(id) })
if (res.code === 0) {
form.value = JSON.parse(res.data.meta)
}
}
const init = () => {
getDbFunc()
setFdMap()
const id = route.params.id
if (id) {
getAutoCodeJson(id)
}
}
init()
</script>
<script>
export default {
name: 'AutoCode'
}
</script>
<style scoped lang="scss">