初始化项目
This commit is contained in:
234
src/view/systemTools/autoCode/component/fieldDialog.vue
Normal file
234
src/view/systemTools/autoCode/component/fieldDialog.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<div>
|
||||
<warning-bar title="id , created_at , updated_at , deleted_at 会自动生成请勿重复创建。搜索时如果条件为LIKE只支持字符串" />
|
||||
<el-form
|
||||
ref="fieldDialogFrom"
|
||||
:model="middleDate"
|
||||
label-width="120px"
|
||||
label-position="right"
|
||||
:rules="rules"
|
||||
class="grid-form"
|
||||
>
|
||||
<el-form-item label="Field名称" prop="fieldName">
|
||||
<el-input v-model="middleDate.fieldName" autocomplete="off" style="width:80%" />
|
||||
<el-button size="small" style="width:18%;margin-left:2%" @click="autoFill">
|
||||
<span style="font-size: 12px">自动填充</span>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="Field中文名" prop="fieldDesc">
|
||||
<el-input v-model="middleDate.fieldDesc" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="FieldJSON" prop="fieldJson">
|
||||
<el-input v-model="middleDate.fieldJson" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库字段名" prop="columnName">
|
||||
<el-input v-model="middleDate.columnName" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库字段描述" prop="comment">
|
||||
<el-input v-model="middleDate.comment" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Field数据类型" prop="fieldType">
|
||||
<el-select
|
||||
v-model="middleDate.fieldType"
|
||||
style="width:100%"
|
||||
placeholder="请选择field数据类型"
|
||||
clearable
|
||||
@change="clearOther"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="middleDate.fieldType === 'enum' ? '枚举值' : '类型长度'" prop="dataTypeLong">
|
||||
<el-input v-model="middleDate.dataTypeLong" :placeholder="middleDate.fieldType === 'enum'?`例:'北京','天津'`:'数据库类型长度'" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Field查询条件" prop="fieldSearchType">
|
||||
<el-select
|
||||
v-model="middleDate.fieldSearchType"
|
||||
style="width:100%"
|
||||
placeholder="请选择Field查询条件"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeSearchOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="
|
||||
(middleDate.fieldType!=='string'&&item.value==='LIKE')||
|
||||
((middleDate.fieldType!=='int'&&middleDate.fieldType!=='time.Time'&&middleDate.fieldType!=='float64')&&(item.value==='BETWEEN' || item.value==='NOT BETWEEN'))
|
||||
"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联字典" prop="dictType">
|
||||
<el-select
|
||||
v-model="middleDate.dictType"
|
||||
style="width:100%"
|
||||
:disabled="middleDate.fieldType!=='int'"
|
||||
placeholder="请选择字典"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dictOptions"
|
||||
:key="item.type"
|
||||
:label="`${item.type}(${item.name})`"
|
||||
:value="item.type"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否排序">
|
||||
<el-switch v-model="middleDate.sort" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否必填">
|
||||
<el-switch v-model="middleDate.require" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否可清空">
|
||||
<el-switch v-model="middleDate.clearable" />
|
||||
</el-form-item>
|
||||
<el-form-item label="校验失败文案">
|
||||
<el-input v-model="middleDate.errorText" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { toLowerCase, toSQLLine } from '@/utils/stringFun'
|
||||
import { getSysDictionaryList } from '@/api/sysDictionary'
|
||||
import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
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'
|
||||
},
|
||||
{
|
||||
label: 'BETWEEN',
|
||||
value: 'BETWEEN'
|
||||
},
|
||||
{
|
||||
label: 'NOT BETWEEN',
|
||||
value: 'NOT BETWEEN'
|
||||
}
|
||||
])
|
||||
const typeOptions = ref([
|
||||
{
|
||||
label: '字符串',
|
||||
value: 'string'
|
||||
},
|
||||
{
|
||||
label: '整型',
|
||||
value: 'int'
|
||||
},
|
||||
{
|
||||
label: '布尔值',
|
||||
value: 'bool'
|
||||
},
|
||||
{
|
||||
label: '浮点型',
|
||||
value: 'float64'
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
value: 'time.Time'
|
||||
},
|
||||
{
|
||||
label: '枚举',
|
||||
value: 'enum'
|
||||
}
|
||||
])
|
||||
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 clearOther = () => {
|
||||
middleDate.value.fieldSearchType = ''
|
||||
middleDate.value.dictType = ''
|
||||
}
|
||||
|
||||
const fieldDialogFrom = ref(null)
|
||||
defineExpose({ fieldDialogFrom })
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'FieldDialog'
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.grid-form{
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.click-text{
|
||||
color: #0d84ff;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
93
src/view/systemTools/autoCode/component/previewCodeDialg.vue
Normal file
93
src/view/systemTools/autoCode/component/previewCodeDialg.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="previewCode">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane v-for="(item, key) in previewCode" :key="key" :label="key" :name="key">
|
||||
<div :id="key" class="tab-info" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import marked from 'marked'
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/atelier-plateau-light.css'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
previewCode: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const activeName = ref('')
|
||||
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 (activeName.value === '') {
|
||||
activeName.value = key
|
||||
}
|
||||
document.getElementById(key).innerHTML = marked(props.previewCode[key])
|
||||
}
|
||||
})
|
||||
|
||||
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>
|
||||
|
||||
<style lang="scss">
|
||||
.previewCode {
|
||||
.tab-info {
|
||||
height: 50vh;
|
||||
background: #fff;
|
||||
padding: 0 20px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
723
src/view/systemTools/autoCode/index.vue
Normal file
723
src/view/systemTools/autoCode/index.vue
Normal file
@@ -0,0 +1,723 @@
|
||||
<template>
|
||||
<div>
|
||||
<warning-bar href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" title="此功能为开发环境使用,不建议发布到生产,具体使用效果请看视频https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" />
|
||||
<!-- 从数据库直接获取字段 -->
|
||||
<div class="gva-search-box">
|
||||
<el-collapse v-model="activeNames" style="margin-bottom:12px">
|
||||
<el-collapse-item name="1">
|
||||
<template #title>
|
||||
<div :style="{fontSize:'16px',paddingLeft:'20px'}">
|
||||
点这里从现有数据库创建代码
|
||||
<el-icon class="header-icon ">
|
||||
<pointer />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form ref="getTableForm" style="margin-top:24px" :inline="true" :model="dbform" label-width="120px">
|
||||
<el-form-item label="业务库" prop="selectDBtype">
|
||||
<template #label>
|
||||
<el-tooltip content="注:需要提前到db-list自行配置多数据库,如未配置需配置后重启服务方可使用。(此处可选择对应库表,可理解为从哪个库选择表)" placement="bottom" effect="light">
|
||||
<div> 业务库 <el-icon><QuestionFilled /></el-icon> </div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select v-model="dbform.businessDB" clearable style="width:194px" placeholder="选择业务库" @change="getDbFunc">
|
||||
<el-option
|
||||
v-for="item in dbList"
|
||||
:key="item.aliasName"
|
||||
:value="item.aliasName"
|
||||
:label="item.aliasName"
|
||||
:disabled="item.disable"
|
||||
>
|
||||
<div>
|
||||
<span>{{ item.aliasName }}</span>
|
||||
<span style="float:right;color:#8492a6;font-size:13px">{{ item.dbName }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库名" prop="structName">
|
||||
<el-select v-model="dbform.dbName" clearable filterable placeholder="请选择数据库" @change="getTableFunc">
|
||||
<el-option
|
||||
v-for="item in dbOptions"
|
||||
:key="item.database"
|
||||
:label="item.database"
|
||||
:value="item.database"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="表名" prop="structName">
|
||||
<el-select
|
||||
v-model="dbform.tableName"
|
||||
:disabled="!dbform.dbName"
|
||||
filterable
|
||||
placeholder="请选择表"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in tableOptions"
|
||||
:key="item.tableName"
|
||||
:label="item.tableName"
|
||||
:value="item.tableName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button size="small" type="primary" @click="getColumnFunc">使用此表创建</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
<div class="gva-search-box">
|
||||
<!-- 初始版本自动化代码工具 -->
|
||||
<el-form ref="autoCodeForm" :rules="rules" :model="form" label-width="120px" :inline="true">
|
||||
<el-form-item label="Struct名称" prop="structName">
|
||||
<el-input v-model="form.structName" placeholder="首字母自动转换大写" />
|
||||
</el-form-item>
|
||||
<el-form-item label="TableName" prop="tableName">
|
||||
<el-input v-model="form.tableName" placeholder="指定表名(非必填)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Struct简称" prop="abbreviation">
|
||||
<el-input v-model="form.abbreviation" placeholder="简称会作为入参对象名和路由group" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Struct中文名称" prop="description">
|
||||
<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="toLowerCaseFunc(form,'packageName')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Package(包)" prop="package">
|
||||
<el-select v-model="form.package" style="width:194px">
|
||||
<el-option v-for="item in pkgs" :key="item.ID" :value="item.packageName" :label="item.packageName" />
|
||||
</el-select>
|
||||
<el-icon class="auto-icon" @click="getPkgs"><refresh /></el-icon>
|
||||
<el-icon class="auto-icon" @click="goPkgs"><document-add /></el-icon>
|
||||
</el-form-item>
|
||||
<el-form-item label="业务库" prop="businessDB">
|
||||
<template #label>
|
||||
<el-tooltip content="注:需要提前到db-list自行配置多数据库,此项为空则会使用gva本库创建自动化代码(global.GVA_DB),填写后则会创建指定库的代码(global.MustGetGlobalDBByDBName(dbname))" placement="bottom" effect="light">
|
||||
<div> 业务库 <el-icon><QuestionFilled /></el-icon> </div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select
|
||||
v-model="form.businessDB"
|
||||
style="width:194px"
|
||||
placeholder="选择业务库"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dbList"
|
||||
:key="item.aliasName"
|
||||
:value="item.aliasName"
|
||||
:label="item.aliasName"
|
||||
:disabled="item.disable"
|
||||
>
|
||||
<div>
|
||||
<span>{{ item.aliasName }}</span>
|
||||
<span style="float:right;color:#8492a6;font-size:13px">{{ item.dbName }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<el-tooltip content="注:会自动在结构体添加 created_by updated_by deleted_by,方便用户进行资源权限控制" placement="bottom" effect="light">
|
||||
<div> 创建资源标识 <el-icon><QuestionFilled /></el-icon> </div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-checkbox v-model="form.autoCreateResource" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<el-tooltip content="注:把自动生成的API注册进数据库" placement="bottom" effect="light">
|
||||
<div> 自动创建API </div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-checkbox v-model="form.autoCreateApiToSql" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<el-tooltip content="注:自动迁移生成的文件到yaml配置的对应位置" placement="bottom" effect="light">
|
||||
<div> 自动移动文件 </div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-checkbox v-model="form.autoMoveFile" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<!-- 组件列表 -->
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button size="small" type="primary" @click="editAndAddField()">新增Field</el-button>
|
||||
</div>
|
||||
<el-table :data="form.fields">
|
||||
<el-table-column align="left" type="index" label="序列" width="60" />
|
||||
<el-table-column align="left" prop="fieldName" label="Field名" width="160">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.fieldName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="fieldDesc" label="中文名" width="160">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.fieldDesc" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="require" label="必填">
|
||||
<template #default="{row}"> <el-checkbox v-model="row.require" /></template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="sort" label="排序">
|
||||
<template #default="{row}"> <el-checkbox v-model="row.sort" /> </template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="fieldJson" width="160px" label="FieldJson">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.fieldJson" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="fieldType" label="Field数据类型" width="160">
|
||||
<template #default="{row}">
|
||||
<el-select
|
||||
v-model="row.fieldType"
|
||||
style="width:100%"
|
||||
placeholder="请选择field数据类型"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="dataTypeLong" label="数据库字段长度" width="160">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.dataTypeLong" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="columnName" label="数据库字段" width="160">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.columnName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="comment" label="数据库字段描述" width="160">
|
||||
<template #default="{row}">
|
||||
<el-input v-model="row.columnName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" prop="fieldSearchType" label="搜索条件" width="130">
|
||||
<template #default="{row}">
|
||||
<el-select
|
||||
v-model="row.fieldSearchType"
|
||||
style="width:100%"
|
||||
placeholder="请选择Field查询条件"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeSearchOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="
|
||||
(row.fieldType!=='string'&&item.value==='LIKE')||
|
||||
((row.fieldType!=='int'&&row.fieldType!=='time.Time'&&row.fieldType!=='float64')&&(item.value==='BETWEEN' || item.value==='NOT BETWEEN'))
|
||||
"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="操作" width="300" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
icon="edit"
|
||||
@click="editAndAddField(scope.row)"
|
||||
>高级编辑</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
:disabled="scope.$index === 0"
|
||||
@click="moveUpField(scope.$index)"
|
||||
>上移</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
:disabled="(scope.$index + 1) === form.fields.length"
|
||||
@click="moveDownField(scope.$index)"
|
||||
>下移</el-button>
|
||||
<el-popover v-model="scope.row.visible" placement="top">
|
||||
<p>确定删除吗?</p>
|
||||
<div style="text-align: right; margin-top: 8px;">
|
||||
<el-button size="small" type="primary" link @click="scope.row.visible = false">取消</el-button>
|
||||
<el-button type="primary" size="small" @click="deleteField(scope.$index)">确定</el-button>
|
||||
</div>
|
||||
<template #reference>
|
||||
<el-button size="small" type="primary" link icon="delete" @click="scope.row.visible = true">删除</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 组件列表 -->
|
||||
<div class="gva-btn-list justify-content-flex-end auto-btn-list">
|
||||
<el-button size="small" type="primary" @click="enterForm(true)">预览代码</el-button>
|
||||
<el-button size="small" type="primary" @click="enterForm(false)">生成代码</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 组件弹窗 -->
|
||||
<el-dialog v-model="dialogFlag" width="70%" title="组件内容">
|
||||
<FieldDialog v-if="dialogFlag" ref="fieldDialogNode" :dialog-middle="dialogMiddle" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button size="small" @click="closeDialog">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="previewFlag">
|
||||
<template #header>
|
||||
<div class="previewCodeTool">
|
||||
<p>操作栏:</p>
|
||||
<el-button size="small" type="primary" @click="selectText">全选</el-button>
|
||||
<el-button size="small" type="primary" @click="copy">复制</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import FieldDialog from '@/view/systemTools/autoCode/component/fieldDialog.vue'
|
||||
import PreviewCodeDialog from '@/view/systemTools/autoCode/component/previewCodeDialg.vue'
|
||||
import { toUpperCase, toHump, toSQLLine, toLowerCase } from '@/utils/stringFun'
|
||||
import { createTemp, getDB, getTable, getColumn, preview, getMeta, getPackageApi } from '@/api/autoCode'
|
||||
import { getDict } from '@/utils/dictionary'
|
||||
import { ref, getCurrentInstance, reactive, watch, toRaw } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||
|
||||
const typeOptions = ref([
|
||||
{
|
||||
label: '字符串',
|
||||
value: 'string'
|
||||
},
|
||||
{
|
||||
label: '整型',
|
||||
value: 'int'
|
||||
},
|
||||
{
|
||||
label: '布尔值',
|
||||
value: 'bool'
|
||||
},
|
||||
{
|
||||
label: '浮点型',
|
||||
value: 'float64'
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
value: 'time.Time'
|
||||
},
|
||||
{
|
||||
label: '枚举',
|
||||
value: 'enum'
|
||||
}
|
||||
])
|
||||
|
||||
const typeSearchOptions = ref([
|
||||
{
|
||||
label: '=',
|
||||
value: '='
|
||||
},
|
||||
{
|
||||
label: '<>',
|
||||
value: '<>'
|
||||
},
|
||||
{
|
||||
label: '>',
|
||||
value: '>'
|
||||
},
|
||||
{
|
||||
label: '<',
|
||||
value: '<'
|
||||
},
|
||||
{
|
||||
label: 'LIKE',
|
||||
value: 'LIKE'
|
||||
},
|
||||
{
|
||||
label: 'BETWEEN',
|
||||
value: 'BETWEEN'
|
||||
},
|
||||
{
|
||||
label: 'NOT BETWEEN',
|
||||
value: 'NOT BETWEEN'
|
||||
}
|
||||
])
|
||||
|
||||
const fieldTemplate = {
|
||||
fieldName: '',
|
||||
fieldDesc: '',
|
||||
fieldType: '',
|
||||
dataType: '',
|
||||
fieldJson: '',
|
||||
columnName: '',
|
||||
dataTypeLong: '',
|
||||
comment: '',
|
||||
require: false,
|
||||
sort: false,
|
||||
errorText: '',
|
||||
clearable: true,
|
||||
fieldSearchType: '',
|
||||
dictType: ''
|
||||
}
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const activeNames = reactive([])
|
||||
const preViewCode = ref({})
|
||||
const dbform = ref({
|
||||
businessDB: '',
|
||||
dbName: '',
|
||||
tableName: ''
|
||||
})
|
||||
const tableOptions = ref([])
|
||||
const addFlag = ref('')
|
||||
const fdMap = ref({})
|
||||
const form = ref({
|
||||
structName: '',
|
||||
tableName: '',
|
||||
packageName: '',
|
||||
package: '',
|
||||
abbreviation: '',
|
||||
description: '',
|
||||
businessDB: '',
|
||||
autoCreateApiToSql: true,
|
||||
autoMoveFile: true,
|
||||
autoCreateResource: 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'
|
||||
}
|
||||
],
|
||||
package: [
|
||||
{ required: true, message: '请选择package', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
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)
|
||||
form.value.tableName = form.value.tableName.replace(' ', '')
|
||||
if (!form.value.tableName) {
|
||||
form.value.tableName = toSQLLine(toLowerCase(form.value.structName))
|
||||
}
|
||||
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 {
|
||||
const data = await createTemp(form.value)
|
||||
if (data.headers?.success === 'false') {
|
||||
return
|
||||
} else {
|
||||
if (form.value.autoMoveFile) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '自动化代码创建成功,自动移动成功'
|
||||
})
|
||||
return
|
||||
}
|
||||
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 {
|
||||
// IE 10+
|
||||
window.navigator.msSaveBlob(blob, fileName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const dbList = ref([])
|
||||
const dbOptions = ref([])
|
||||
|
||||
const getDbFunc = async() => {
|
||||
dbform.value.dbName = ''
|
||||
dbform.value.tableName = ''
|
||||
const res = await getDB({ businessDB: dbform.value.businessDB })
|
||||
if (res.code === 0) {
|
||||
dbOptions.value = res.data.dbs
|
||||
dbList.value = res.data.dbList
|
||||
}
|
||||
}
|
||||
const getTableFunc = async() => {
|
||||
const res = await getTable({ businessDB: dbform.value.businessDB, 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) {
|
||||
let dbtype = ''
|
||||
if (dbform.value.businessDB !== '') {
|
||||
const dbtmp = dbList.value.find(item => item.aliasName === dbform.value.businessDB)
|
||||
console.log(dbtmp)
|
||||
const dbraw = toRaw(dbtmp)
|
||||
console.log(dbraw)
|
||||
dbtype = dbraw.dbtype
|
||||
}
|
||||
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.autoMoveFile = true
|
||||
form.value.fields = []
|
||||
res.data.columns &&
|
||||
res.data.columns.forEach(item => {
|
||||
if (!gormModelList.some(gormfd => gormfd === item.columnName)) {
|
||||
const fbHump = toHump(item.columnName)
|
||||
form.value.fields.push({
|
||||
fieldName: toUpperCase(fbHump),
|
||||
fieldDesc: item.columnComment || fbHump + '字段',
|
||||
fieldType: fdMap.value[item.dataType],
|
||||
dataType: item.dataType,
|
||||
fieldJson: fbHump,
|
||||
dataTypeLong: item.dataTypeLong && item.dataTypeLong.split(',')[0],
|
||||
columnName: dbtype == 'oracle' ? item.columnName.toUpperCase() : item.columnName,
|
||||
comment: item.columnComment,
|
||||
require: false,
|
||||
errorText: '',
|
||||
clearable: true,
|
||||
fieldSearchType: '',
|
||||
dictType: ''
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
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 pkgs = ref([])
|
||||
const getPkgs = async() => {
|
||||
const res = await getPackageApi()
|
||||
if (res.code === 0) {
|
||||
pkgs.value = res.data.pkgs
|
||||
}
|
||||
}
|
||||
|
||||
const goPkgs = () => {
|
||||
router.push({ name: 'autoPkg' })
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
getDbFunc()
|
||||
setFdMap()
|
||||
getPkgs()
|
||||
const id = route.params.id
|
||||
if (id) {
|
||||
getAutoCodeJson(id)
|
||||
}
|
||||
}
|
||||
init()
|
||||
|
||||
watch(() => route.params.id, (id) => {
|
||||
if (route.name === 'autoCodeEdit') {
|
||||
init()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'AutoCode'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.previewCodeTool {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
.button-box {
|
||||
padding: 10px 20px;
|
||||
.el-button {
|
||||
margin-right: 20px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.auto-btn-list{
|
||||
margin-top: 16px;
|
||||
}
|
||||
.auto-icon{
|
||||
margin-left: 6px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
188
src/view/systemTools/autoCodeAdmin/index.vue
Normal file
188
src/view/systemTools/autoCodeAdmin/index.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button size="small" type="primary" icon="plus" @click="goAutoCode(null)">新增</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData">
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55"
|
||||
/>
|
||||
<el-table-column align="left" label="id" width="60" prop="ID" />
|
||||
<el-table-column align="left" label="日期" width="180">
|
||||
<template #default="scope">{{ formatDate(scope.row.CreatedAt) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="结构体名" min-width="150" prop="structName" />
|
||||
<el-table-column align="left" label="结构体描述" min-width="150" prop="structCNName" />
|
||||
<el-table-column align="left" label="表名称" min-width="150" prop="tableName" />
|
||||
<el-table-column align="left" label="回滚标记" min-width="150" prop="flag">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
v-if="scope.row.flag"
|
||||
type="danger"
|
||||
size="small"
|
||||
effect="dark"
|
||||
>
|
||||
已回滚
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else
|
||||
size="small"
|
||||
type="success"
|
||||
effect="dark"
|
||||
>
|
||||
未回滚
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="操作" min-width="240">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-button size="small" type="primary" link :disabled="scope.row.flag === 1" @click="rollbackFunc(scope.row,true)">回滚(删表)</el-button>
|
||||
<el-button size="small" type="primary" link :disabled="scope.row.flag === 1" @click="rollbackFunc(scope.row,false)">回滚(不删表)</el-button>
|
||||
<el-button size="small" type="primary" link @click="goAutoCode(scope.row)">复用</el-button>
|
||||
<el-button size="small" type="primary" link @click="deleteRow(scope.row)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="gva-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 30, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AutoCodeAdmin',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { getSysHistory, rollback, delSysHistory } from '@/api/autoCode.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ref } from 'vue'
|
||||
import { formatDate } from '@/utils/format'
|
||||
const router = useRouter()
|
||||
|
||||
const page = ref(1)
|
||||
const total = ref(0)
|
||||
const pageSize = ref(10)
|
||||
const tableData = ref([])
|
||||
|
||||
// 分页
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val
|
||||
getTableData()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
page.value = val
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 查询
|
||||
const getTableData = async() => {
|
||||
const table = await getSysHistory({
|
||||
page: page.value,
|
||||
pageSize: pageSize.value
|
||||
})
|
||||
if (table.code === 0) {
|
||||
tableData.value = table.data.list
|
||||
total.value = table.data.total
|
||||
page.value = table.data.page
|
||||
pageSize.value = table.data.pageSize
|
||||
}
|
||||
}
|
||||
|
||||
getTableData()
|
||||
|
||||
const deleteRow = async(row) => {
|
||||
ElMessageBox.confirm('此操作将删除本历史, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
const res = await delSysHistory({ id: Number(row.ID) })
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('删除成功')
|
||||
getTableData()
|
||||
}
|
||||
})
|
||||
}
|
||||
const rollbackFunc = async(row, flag) => {
|
||||
if (flag) {
|
||||
ElMessageBox.confirm(`此操作将删除自动创建的文件和api(会删除表!!!), 是否继续?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
ElMessageBox.confirm(`此操作将删除自动创建的文件和api(会删除表!!!), 请继续确认!!!`, '会删除表', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
ElMessageBox.confirm(`此操作将删除自动创建的文件和api(会删除表!!!), 请继续确认!!!`, '会删除表', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
const res = await rollback({ id: Number(row.ID), deleteTable: flag })
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('回滚成功')
|
||||
getTableData()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
ElMessageBox.confirm(`此操作将删除自动创建的文件和api, 是否继续?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
const res = await rollback({ id: Number(row.ID), deleteTable: flag })
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('回滚成功')
|
||||
getTableData()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const goAutoCode = (row) => {
|
||||
if (row) {
|
||||
router.push({ name: 'autoCodeEdit', params: {
|
||||
id: row.ID
|
||||
}})
|
||||
} else {
|
||||
router.push({ name: 'autoCode' })
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.button-box {
|
||||
padding: 10px 20px;
|
||||
.el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.el-tag--mini {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.warning {
|
||||
color: #dc143c;
|
||||
}
|
||||
</style>
|
||||
160
src/view/systemTools/autoPkg/autoPkg.vue
Normal file
160
src/view/systemTools/autoPkg/autoPkg.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div>
|
||||
<warning-bar href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" title="此功能为开发环境使用,不建议发布到生产,具体使用效果请看视频https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" />
|
||||
<div class="gva-table-box">
|
||||
<div class="gva-btn-list">
|
||||
<el-button size="small" type="primary" icon="plus" @click="openDialog('addApi')">新增</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData">
|
||||
<el-table-column align="left" label="id" width="60" prop="ID" />
|
||||
<el-table-column align="left" label="包名" width="150" prop="packageName" />
|
||||
<el-table-column align="left" label="展示名" width="150" prop="label" />
|
||||
<el-table-column align="left" label="描述" min-width="150" prop="desc" />
|
||||
|
||||
<el-table-column align="left" label="操作" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="delete"
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
@click="deleteApiFunc(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="dialogFormVisible" :before-close="closeDialog" title="创建Package">
|
||||
<warning-bar title="新增Pkg用于自动化代码使用" />
|
||||
<el-form ref="pkgForm" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="包名" prop="packageName">
|
||||
<el-input v-model="form.packageName" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="展示名" prop="label">
|
||||
<el-input v-model="form.label" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="desc">
|
||||
<el-input v-model="form.desc" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button size="small" @click="closeDialog">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AutoPkg',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
createPackageApi,
|
||||
getPackageApi,
|
||||
deletePackageApi,
|
||||
} from '@/api/autoCode'
|
||||
import { ref } from 'vue'
|
||||
import WarningBar from '@/components/warningBar/warningBar.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const form = ref({
|
||||
packageName: '',
|
||||
label: '',
|
||||
desc: '',
|
||||
})
|
||||
|
||||
const validateNum = (rule, value, callback) => {
|
||||
if ((/^\d+$/.test(value[0]))) {
|
||||
callback(new Error('不能够以数字开头'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const rules = ref({
|
||||
packageName: [
|
||||
{ required: true, message: '请输入包名', trigger: 'blur' },
|
||||
{ validator: validateNum, trigger: 'blur' }
|
||||
],
|
||||
})
|
||||
|
||||
const dialogFormVisible = ref(false)
|
||||
const openDialog = () => {
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
dialogFormVisible.value = false
|
||||
form.value = {
|
||||
packageName: '',
|
||||
label: '',
|
||||
desc: '',
|
||||
}
|
||||
}
|
||||
|
||||
const pkgForm = ref(null)
|
||||
const enterDialog = async() => {
|
||||
pkgForm.value.validate(async valid => {
|
||||
if (valid) {
|
||||
const res = await createPackageApi(form.value)
|
||||
if (res.code === 0) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '添加成功',
|
||||
showClose: true
|
||||
})
|
||||
}
|
||||
getTableData()
|
||||
closeDialog()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const tableData = ref([])
|
||||
const getTableData = async() => {
|
||||
const table = await getPackageApi()
|
||||
if (table.code === 0) {
|
||||
tableData.value = table.data.pkgs
|
||||
}
|
||||
}
|
||||
|
||||
const deleteApiFunc = async(row) => {
|
||||
ElMessageBox.confirm('此操作仅删除数据库中的pkg存储,后端相应目录结构请自行删除与数据库保持一致!', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async() => {
|
||||
const res = await deletePackageApi(row)
|
||||
if (res.code === 0) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
})
|
||||
getTableData()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getTableData()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.button-box {
|
||||
padding: 10px 20px;
|
||||
.el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.warning {
|
||||
color: #dc143c;
|
||||
}
|
||||
</style>
|
||||
220
src/view/systemTools/autoPlug/autoPlug.vue
Normal file
220
src/view/systemTools/autoPlug/autoPlug.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="gva-table-box">
|
||||
<el-form label-width="140px" class="plug-form">
|
||||
<el-form-item label="插件名">
|
||||
<el-input v-model="form.plugName" placeholder="必填(英文大写字母开头)" @blur="titleCase" />
|
||||
</el-form-item>
|
||||
<el-form-item label="路由组">
|
||||
<el-input v-model="form.routerGroup" placeholder="将会作为插件路由组使用" />
|
||||
</el-form-item>
|
||||
<el-form-item label="使用全局属性">
|
||||
<el-checkbox v-model="form.hasGlobal" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.hasGlobal" label="全局属性">
|
||||
<div v-for="(i,k) in form.global" :key="k" class="plug-row">
|
||||
<span>
|
||||
<el-input v-model="i.key" placeholder="key 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-select v-model="i.type" placeholder="type 必填">
|
||||
<el-option label="string" value="string" />
|
||||
<el-option label="int" value="int" />
|
||||
<el-option label="float32" value="float32" />
|
||||
<el-option label="float64" value="float64" />
|
||||
<el-option label="bool" value="bool" />
|
||||
</el-select>
|
||||
</span>
|
||||
<span>
|
||||
<el-input v-model="i.desc" placeholder="备注 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Plus" circle @click="addkv(form.global)" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Minus" circle @click="minkv(form.global,k)" />
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="使用Request">
|
||||
<el-checkbox v-model="form.hasRequest" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.hasRequest" label="Request">
|
||||
<div v-for="(i,k) in form.request" :key="k" class="plug-row">
|
||||
<span>
|
||||
<el-input v-model="i.key" placeholder="key 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-select v-model="i.type" placeholder="type 必填">
|
||||
<el-option label="string" value="string" />
|
||||
<el-option label="int" value="int" />
|
||||
<el-option label="float32" value="float32" />
|
||||
<el-option label="float64" value="float64" />
|
||||
<el-option label="bool" value="bool" />
|
||||
</el-select>
|
||||
</span>
|
||||
<span>
|
||||
<el-input v-model="i.desc" placeholder="备注 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Plus" circle @click="addkv(form.request)" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Minus" circle @click="minkv(form.request,k)" />
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="使用Response">
|
||||
<el-checkbox v-model="form.hasResponse" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.hasResponse" label="Response">
|
||||
<div v-for="(i,k) in form.response" :key="k" class="plug-row">
|
||||
<span>
|
||||
<el-input v-model="i.key" placeholder="key 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-select v-model="i.type" placeholder="type 必填">
|
||||
<el-option label="string" value="string" />
|
||||
<el-option label="int" value="int" />
|
||||
<el-option label="float32" value="float32" />
|
||||
<el-option label="float64" value="float64" />
|
||||
<el-option label="bool" value="bool" />
|
||||
</el-select>
|
||||
</span>
|
||||
<span>
|
||||
<el-input v-model="i.desc" placeholder="备注 必填" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Plus" circle @click="addkv(form.response)" />
|
||||
</span>
|
||||
<span>
|
||||
<el-button :icon="Minus" circle @click="minkv(form.response,k)" />
|
||||
</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="createPlug">创建</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { toUpperCase } from '@/utils/stringFun'
|
||||
|
||||
import {
|
||||
Plus,
|
||||
Minus
|
||||
} from '@element-plus/icons-vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
import { createPlugApi } from '@/api/autoCode.js'
|
||||
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const form = reactive({
|
||||
plugName: '',
|
||||
routerGroup: '',
|
||||
hasGlobal: true,
|
||||
hasRequest: true,
|
||||
hasResponse: true,
|
||||
global: [{
|
||||
key: '',
|
||||
type: '',
|
||||
desc: '',
|
||||
}],
|
||||
request: [{
|
||||
key: '',
|
||||
type: '',
|
||||
desc: '',
|
||||
}],
|
||||
response: [{
|
||||
key: '',
|
||||
type: '',
|
||||
desc: '',
|
||||
}]
|
||||
})
|
||||
|
||||
const titleCase = () => {
|
||||
form.plugName = toUpperCase(form.plugName)
|
||||
}
|
||||
|
||||
const createPlug = async() => {
|
||||
if (!form.plugName || !form.routerGroup) {
|
||||
ElMessage.error('插件名称和插件路由组为必填项')
|
||||
return
|
||||
}
|
||||
if (form.hasGlobal) {
|
||||
const intercept = form.global.some(i => {
|
||||
if (!i.key || !i.type) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (intercept) {
|
||||
ElMessage.error('全局属性的key和type为必填项')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (form.hasRequest) {
|
||||
const intercept = form.request.some(i => {
|
||||
if (!i.key || !i.type) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (intercept) {
|
||||
ElMessage.error('请求属性的key和type为必填项')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (form.hasResponse) {
|
||||
const intercept = form.response.some(i => {
|
||||
if (!i.key || !i.type) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (intercept) {
|
||||
ElMessage.error('响应属性的key和type为必填项')
|
||||
return
|
||||
}
|
||||
}
|
||||
const res = await createPlugApi(form)
|
||||
if (res.code === 0) {
|
||||
ElMessageBox('创建成功,插件已自动写入后端plugin目录下,请按照自己的逻辑进行创造')
|
||||
}
|
||||
}
|
||||
|
||||
const addkv = (arr) => {
|
||||
arr.push({
|
||||
key: '',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
|
||||
const minkv = (arr, key) => {
|
||||
if (arr.length === 1) {
|
||||
ElMessage.warning('至少有一个全局属性')
|
||||
return
|
||||
}
|
||||
arr.splice(key, 1)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.plug-form{
|
||||
width: 680px;
|
||||
}
|
||||
.plug-row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
&+&{
|
||||
margin-top: 12px;
|
||||
}
|
||||
&>span{
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
17
src/view/systemTools/formCreate/index.vue
Normal file
17
src/view/systemTools/formCreate/index.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div style="height:80vh">
|
||||
<iframe width="100%" height="100%" :src="`${basePath}:${basePort}/form-generator/#/`" frameborder="0" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FormGenerator'
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const basePath = ref(import.meta.env.VITE_BASE_PATH)
|
||||
const basePort = ref(import.meta.env.VITE_SERVER_PORT)
|
||||
</script>
|
||||
21
src/view/systemTools/index.vue
Normal file
21
src/view/systemTools/index.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition mode="out-in" name="el-fade-in-linear">
|
||||
<keep-alive :include="routerStore.keepAliveRouters">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'System'
|
||||
}
|
||||
</script>
|
||||
<script setup>
|
||||
import { useRouterStore } from '@/pinia/modules/router'
|
||||
const routerStore = useRouterStore()
|
||||
</script>
|
||||
44
src/view/systemTools/installPlugin/index.vue
Normal file
44
src/view/systemTools/installPlugin/index.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
drag
|
||||
:action="`${path}/autoCode/installPlugin`"
|
||||
:headers="{'x-token':userStore.token}"
|
||||
:show-file-list="false"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleSuccess"
|
||||
name="plug"
|
||||
>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
拖拽或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
请把安装包的zip拖拽至此处上传
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useUserStore } from '@/pinia/modules/user'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const userStore = useUserStore()
|
||||
const path = ref(import.meta.env.VITE_BASE_API)
|
||||
|
||||
const handleSuccess = (res) => {
|
||||
if (res.code === 0) {
|
||||
let msg = ``
|
||||
res.data && res.data.forEach((item, index) => {
|
||||
msg += `${index + 1}.${item.msg}\n`
|
||||
})
|
||||
alert(msg)
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
463
src/view/systemTools/system/system.vue
Normal file
463
src/view/systemTools/system/system.vue
Normal file
@@ -0,0 +1,463 @@
|
||||
<template>
|
||||
<div class="system">
|
||||
<el-form ref="form" :model="config" label-width="240px">
|
||||
<!-- System start -->
|
||||
<el-collapse v-model="activeNames">
|
||||
<el-collapse-item title="系统配置" name="1">
|
||||
<el-form-item label="环境值">
|
||||
<!-- <el-input v-model="config.system.env" />-->
|
||||
<el-select v-model="config.system.env" style="width:100%">
|
||||
<el-option value="public" />
|
||||
<el-option value="develop" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="端口值">
|
||||
<el-input v-model.number="config.system.addr" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库类型">
|
||||
<el-select v-model="config.system['db-type']" style="width:100%">
|
||||
<el-option value="mysql" />
|
||||
<el-option value="pgsql" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Oss类型">
|
||||
<el-select v-model="config.system['oss-type']" style="width:100%">
|
||||
<el-option value="local" />
|
||||
<el-option value="qiniu" />
|
||||
<el-option value="tencent-cos" />
|
||||
<el-option value="aliyun-oss" />
|
||||
<el-option value="huawei-obs" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="多点登录拦截">
|
||||
<el-checkbox v-model="config.system['use-multipoint']">开启</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="开启redis">
|
||||
<el-checkbox v-model="config.system['use-redis']">开启</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="限流次数">
|
||||
<el-input-number v-model.number="config.system['iplimit-count']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="限流时间">
|
||||
<el-input-number v-model.number="config.system['iplimit-time']" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="jwt签名" name="2">
|
||||
<el-form-item label="jwt签名">
|
||||
<el-input v-model="config.jwt['signing-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="有效期">
|
||||
<el-input v-model="config.jwt['expires-time']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="缓冲期">
|
||||
<el-input v-model="config.jwt['buffer-time']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="签发者">
|
||||
<el-input v-model="config.jwt.issuer" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="Zap日志配置" name="3">
|
||||
<el-form-item label="级别">
|
||||
<el-input v-model.number="config.zap.level" />
|
||||
</el-form-item>
|
||||
<el-form-item label="输出">
|
||||
<el-input v-model="config.zap.format" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日志前缀">
|
||||
<el-input v-model="config.zap.prefix" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日志文件夹">
|
||||
<el-input v-model="config.zap.director" />
|
||||
</el-form-item>
|
||||
<el-form-item label="编码级">
|
||||
<el-input v-model="config.zap['encode-level']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="栈名">
|
||||
<el-input v-model="config.zap['stacktrace-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日志留存时间(默认以天为单位)">
|
||||
<el-input v-model.number="config.zap['max-age']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示行">
|
||||
<el-checkbox v-model="config.zap['show-line']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="输出控制台">
|
||||
<el-checkbox v-model="config.zap['log-in-console']" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="Redis admin数据库配置" name="4">
|
||||
<el-form-item label="库">
|
||||
<el-input v-model.number="config.redis.db" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="config.redis.addr" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="config.redis.password" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="邮箱配置" name="5">
|
||||
<el-form-item label="接收者邮箱">
|
||||
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔" />
|
||||
</el-form-item>
|
||||
<el-form-item label="端口">
|
||||
<el-input v-model.number="config.email.port" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发送者邮箱">
|
||||
<el-input v-model="config.email.from" />
|
||||
</el-form-item>
|
||||
<el-form-item label="host">
|
||||
<el-input v-model="config.email.host" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否为ssl">
|
||||
<el-checkbox v-model="config.email['is-ssl']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="secret">
|
||||
<el-input v-model="config.email.secret" />
|
||||
</el-form-item>
|
||||
<el-form-item label="测试邮件">
|
||||
<el-button @click="email">测试邮件</el-button>
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="验证码配置" name="7">
|
||||
<el-form-item label="字符长度">
|
||||
<el-input v-model.number="config.captcha['key-long']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="平台宽度">
|
||||
<el-input v-model.number="config.captcha['img-width']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片高度">
|
||||
<el-input v-model.number="config.captcha['img-height']" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="数据库配置" name="9">
|
||||
<template v-if="config.system['db-type'] === 'mysql'">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="config.mysql.username" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="config.mysql.password" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="config.mysql.path" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库">
|
||||
<el-input v-model="config.mysql['db-name']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="前缀">
|
||||
<el-input v-model="config.mysql['refix']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="复数表">
|
||||
<el-switch v-model="config.mysql['singular']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="引擎">
|
||||
<el-input v-model="config.mysql['engine']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="maxIdleConns">
|
||||
<el-input v-model.number="config.mysql['max-idle-conns']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="maxOpenConns">
|
||||
<el-input v-model.number="config.mysql['max-open-conns']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="写入日志">
|
||||
<el-checkbox v-model="config.mysql['log-zap']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日志模式">
|
||||
<el-input v-model="config.mysql['log-mode']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="config.system.dbType === 'pgsql'">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="config.pgsql.username" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="config.pgsql.password" />
|
||||
</el-form-item>
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="config.pgsql.path" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数据库">
|
||||
<el-input v-model="config.pgsql.dbname" />
|
||||
</el-form-item>
|
||||
<el-form-item label="前缀">
|
||||
<el-input v-model="config.pgsql['refix']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="复数表">
|
||||
<el-switch v-model="config.pgsql['singular']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="引擎">
|
||||
<el-input v-model="config.pgsql['engine']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="maxIdleConns">
|
||||
<el-input v-model.number="config.pgsql['max-idle-conns']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="maxOpenConns">
|
||||
<el-input v-model.number="config.pgsql['max-open-conns']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="写入日志">
|
||||
<el-checkbox v-model="config.pgsql['log-zap']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日志模式">
|
||||
<el-input v-model="config.pgsql['log-mode']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="oss配置" name="10">
|
||||
<template v-if="config.system['oss-type'] === 'local'">
|
||||
<h2>本地文件配置</h2>
|
||||
<el-form-item label="本地文件访问路径">
|
||||
<el-input v-model="config.local.path" />
|
||||
</el-form-item>
|
||||
<el-form-item label="本地文件存储路径">
|
||||
<el-input v-model="config.local['store-path']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="config.system['oss-type'] === 'qiniu'">
|
||||
<h2>qiniu上传配置</h2>
|
||||
<el-form-item label="存储区域">
|
||||
<el-input v-model="config.qiniu.zone" />
|
||||
</el-form-item>
|
||||
<el-form-item label="空间名称">
|
||||
<el-input v-model="config.qiniu.bucket" />
|
||||
</el-form-item>
|
||||
<el-form-item label="CDN加速域名">
|
||||
<el-input v-model="config.qiniu['img-path']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否使用https">
|
||||
<el-checkbox v-model="config.qiniu['use-https']">开启</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="accessKey">
|
||||
<el-input v-model="config.qiniu['access-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="secretKey">
|
||||
<el-input v-model="config.qiniu['secret-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上传是否使用CDN上传加速">
|
||||
<el-checkbox v-model="config.qiniu['use-cdn-domains']">开启</el-checkbox>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="config.system['oss-type'] === 'tencent-cos'">
|
||||
<h2>腾讯云COS上传配置</h2>
|
||||
<el-form-item label="存储桶名称">
|
||||
<el-input v-model="config['tencent-cos']['bucket']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属地域">
|
||||
<el-input v-model="config['tencent-cos'].region" />
|
||||
</el-form-item>
|
||||
<el-form-item label="secretID">
|
||||
<el-input v-model="config['tencent-cos']['secret-id']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="secretKey">
|
||||
<el-input v-model="config['tencent-cos']['secret-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="路径前缀">
|
||||
<el-input v-model="config['tencent-cos']['path-prefix']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="访问域名">
|
||||
<el-input v-model="config['tencent-cos']['base-url']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="config.system['oss-type'] === 'aliyun-oss'">
|
||||
<h2>阿里云OSS上传配置</h2>
|
||||
<el-form-item label="区域">
|
||||
<el-input v-model="config['aliyun-oss'].endpoint" />
|
||||
</el-form-item>
|
||||
<el-form-item label="accessKeyId">
|
||||
<el-input v-model="config['aliyun-oss']['access-key-id']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="accessKeySecret">
|
||||
<el-input v-model="config['aliyun-oss']['access-key-secret']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="存储桶名称">
|
||||
<el-input v-model="config['aliyun-oss']['bucket-name']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="访问域名">
|
||||
<el-input v-model="config['aliyun-oss']['bucket-url']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="config.system['oss-type'] === 'huawei-obs'">
|
||||
<h2>华为云Obs上传配置</h2>
|
||||
<el-form-item label="路径">
|
||||
<el-input v-model="config['hua-wei-obs'].path" />
|
||||
</el-form-item>
|
||||
<el-form-item label="存储桶名称">
|
||||
<el-input v-model="config['hua-wei-obs'].bucket" />
|
||||
</el-form-item>
|
||||
<el-form-item label="区域">
|
||||
<el-input v-model="config['hua-wei-obs'].endpoint" />
|
||||
</el-form-item>
|
||||
<el-form-item label="accessKey">
|
||||
<el-input v-model="config['hua-wei-obs']['access-key']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="secretKey">
|
||||
<el-input v-model="config['hua-wei-obs']['secret-key']" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="Excel上传配置" name="11">
|
||||
<el-form-item label="合成目标地址">
|
||||
<el-input v-model="config.excel.dir" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="自动化代码配置" name="12">
|
||||
<el-form-item label="是否自动重启(linux)">
|
||||
<el-checkbox v-model="config.autocode['transfer-restart']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="root(项目根路径)">
|
||||
<el-input v-model="config.autocode.root" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="Server(后端代码地址)">
|
||||
<el-input v-model="config.autocode['transfer-restart']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SApi(后端api文件夹地址)">
|
||||
<el-input v-model="config.autocode['server-api']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SInitialize(后端Initialize文件夹)">
|
||||
<el-input v-model="config.autocode['server-initialize']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SModel(后端Model文件地址)">
|
||||
<el-input v-model="config.autocode['server-model']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SRequest(后端Request文件夹地址)">
|
||||
<el-input v-model="config.autocode['server-request']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SRouter(后端Router文件夹地址)">
|
||||
<el-input v-model="config.autocode['server-router']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SService(后端Service文件夹地址)">
|
||||
<el-input v-model="config.autocode['server-service']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Web(前端文件夹地址)">
|
||||
<el-input v-model="config.autocode.web" />
|
||||
</el-form-item>
|
||||
<el-form-item label="WApi(后端WApi文件夹地址)">
|
||||
<el-input v-model="config.autocode['web-api']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="WForm(后端WForm文件夹地址)">
|
||||
<el-input v-model="config.autocode['web-form']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="WTable(后端WTable文件夹地址)">
|
||||
<el-input v-model="config.autocode['web-table']" />
|
||||
</el-form-item>
|
||||
</el-collapse-item>
|
||||
|
||||
<el-collapse-item title="Timer(定时任务)" name="13">
|
||||
<el-form-item label="Start(是否启用)">
|
||||
<el-checkbox v-model="config.timer['start']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Spec(CRON表达式)">
|
||||
<el-input v-model="config.timer.spec" />
|
||||
</el-form-item>
|
||||
<template v-for="(item,k) in config.timer.detail">
|
||||
<div v-for="(key,k2) in item" :key="k2">
|
||||
<el-form-item :key="k+k2" :label="k2">
|
||||
<el-input v-model="item[k2]" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-form>
|
||||
<div class="gva-btn-list">
|
||||
<el-button type="primary" size="small" @click="update">立即更新</el-button>
|
||||
<el-button type="primary" size="small" @click="reload">重启服务(开发中)</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Config'
|
||||
}
|
||||
</script>
|
||||
<script setup>
|
||||
import { getSystemConfig, setSystemConfig } from '@/api/system'
|
||||
import { emailTest } from '@/api/email'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const activeNames = reactive([])
|
||||
const config = ref({
|
||||
system: {
|
||||
'iplimit-count': 0,
|
||||
'iplimit-time': 0
|
||||
},
|
||||
jwt: {},
|
||||
mysql: {},
|
||||
pgsql: {},
|
||||
excel: {},
|
||||
autocode: {},
|
||||
redis: {},
|
||||
qiniu: {},
|
||||
'tencent-cos': {},
|
||||
'aliyun-oss': {},
|
||||
'hua-wei-obs': {},
|
||||
captcha: {},
|
||||
zap: {},
|
||||
local: {},
|
||||
email: {},
|
||||
timer: {
|
||||
detail: {}
|
||||
}
|
||||
})
|
||||
|
||||
const initForm = async() => {
|
||||
const res = await getSystemConfig()
|
||||
if (res.code === 0) {
|
||||
config.value = res.data.config
|
||||
}
|
||||
}
|
||||
initForm()
|
||||
const reload = () => {}
|
||||
const update = async() => {
|
||||
const res = await setSystemConfig({ config: config.value })
|
||||
if (res.code === 0) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '配置文件设置成功'
|
||||
})
|
||||
await initForm()
|
||||
}
|
||||
}
|
||||
const email = async() => {
|
||||
const res = await emailTest()
|
||||
if (res.code === 0) {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '邮件发送成功'
|
||||
})
|
||||
await initForm()
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '邮件发送失败'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.system {
|
||||
background: #fff;
|
||||
padding:36px;
|
||||
border-radius: 2px;
|
||||
h2 {
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
font-size: 16px;
|
||||
box-shadow: -4px 0px 0px 0px #e7e8e8;
|
||||
}
|
||||
::v-deep(.el-input-number__increase){
|
||||
top:5px !important;
|
||||
}
|
||||
.gva-btn-list{
|
||||
margin-top:16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user