Files
gin-vue-admin/web/src/view/systemTools/autoCode/component/fieldDialog.vue
PiexlMax(奇淼 86cffba4aa Beta:发布v2.7.5测试版本 (#1896)
* 生产环境时移除console

* 更新第三方库道最新版本,修正导致的兼容问题

* feat: 版本号变更,修复自动化历史的结构体描述

* feat: 放弃element的按需引用,增加自定义表单组件,替换原始的iframe引入模式。

* feat: 放开表单生成器的key输入

* feat: 自动化代码关联属性支持跨数据库关联

* fixed: 修复跨库关联模板

* feat: 允许清空跨数据关联的业务库选项

* feat: 增加用户搜索功能

* feat: 允许单条API同步
---------

Co-authored-by: task <121913992@qq.com>
Co-authored-by: task <ms.yangdan@gmail.com>
2024-09-30 21:27:16 +08:00

493 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<warning-bar title="id , created_at , updated_at , deleted_at 会自动生成请勿重复创建。搜索时如果条件为LIKE只支持字符串" />
<el-form
ref="fieldDialogForm"
:model="middleDate"
label-width="120px"
label-position="right"
:rules="rules"
class="grid grid-cols-2"
>
<el-form-item
label="字段名称"
prop="fieldName"
>
<el-input
v-model="middleDate.fieldName"
autocomplete="off"
style="width:80%"
/>
<el-button
style="width:18%;margin-left:2%"
@click="autoFill"
>
<span style="font-size: 12px">自动填充</span>
</el-button>
</el-form-item>
<el-form-item
label="字段中文名"
prop="fieldDesc"
>
<el-input
v-model="middleDate.fieldDesc"
autocomplete="off"
/>
</el-form-item>
<el-form-item
label="字段JSON"
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="字段类型"
prop="fieldType"
>
<el-select
v-model="middleDate.fieldType"
style="width:100%"
placeholder="请选择字段类型"
clearable
@change="clearOther"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
/>
</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="字段查询条件"
prop="fieldSearchType"
>
<el-select
v-model="middleDate.fieldSearchType"
:disabled="middleDate.fieldType === 'json'"
style="width:100%"
placeholder="请选择字段查询条件"
clearable
>
<el-option
v-for="item in typeSearchOptions"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="canSelect(item.value)"
/>
</el-select>
</el-form-item>
<el-form-item
label="关联字典"
prop="dictType"
>
<el-select
v-model="middleDate.dictType"
style="width:100%"
:disabled="middleDate.fieldType!=='string'"
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-input
v-model="middleDate.defaultValue"
placeholder="请输入默认值"
/>
</el-form-item>
<el-form-item label="主键">
<el-checkbox v-model="middleDate.primaryKey" />
</el-form-item>
<el-form-item
label="索引类型"
prop="fieldIndexType"
>
<el-select
v-model="middleDate.fieldIndexType"
:disabled="middleDate.fieldType === 'json'"
style="width:100%"
placeholder="请选择字段索引类型"
clearable
>
<el-option
v-for="item in typeIndexOptions"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="canSelect(item.value)"
/>
</el-select>
</el-form-item>
<el-form-item label="前端新建/编辑">
<el-switch v-model="middleDate.form" />
</el-form-item>
<el-form-item label="前端表格列">
<el-switch v-model="middleDate.table" />
</el-form-item>
<el-form-item label="前端详情">
<el-switch v-model="middleDate.desc" />
</el-form-item>
<el-form-item label="导入/导出">
<el-switch v-model="middleDate.excel" />
</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-switch v-model="middleDate.fieldSearchHide" :disabled="!middleDate.fieldSearchType" />
</el-form-item>
<el-form-item label="校验失败文案">
<el-input v-model="middleDate.errorText" />
</el-form-item>
</el-form>
<el-collapse v-model="activeNames">
<el-collapse-item
title="数据源配置(此配置为高级配置,如编程基础不牢,可能导致自动化代码不可用)"
name="1"
>
<el-row :gutter="8">
<el-col
:span="4"
>
<el-select
v-model="middleDate.dataSource.dbName"
placeholder="数据库【不填则为GVA库】"
@change="dbNameChange"
clearable
>
<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-col>
<el-col
:span="4"
>
<el-select
v-model="middleDate.dataSource.association"
placeholder="关联模式"
@change="associationChange"
>
<el-option
label="一对一"
:value="1"
/>
<el-option
label="一对多"
:value="2"
/>
</el-select>
</el-col>
<el-col :span="5">
<el-select
v-model="middleDate.dataSource.table" placeholder="请选择数据源表"
filterable allow-create @focus="getDBTableList" @change="selectDB"
>
<el-option
v-for="item in dbTableList" :key="item.tableName" :label="item.tableName"
:value="item.tableName"
/>
</el-select>
</el-col>
<el-col :span="5">
<el-select v-model="middleDate.dataSource.value" placeholder="请先选择需要存储的数据">
<template #label="{ value }">
<span>存储: </span>
<span style="font-weight: bold">{{ value }}</span>
</template>
<el-option v-for="item in dbColumnList" :key="item.columnName" :value="item.columnName">
<span style="float: left"> <el-tag :type="item.isPrimary ? 'primary' : 'info'">
{{ item.isPrimary ? "主&emsp;键" : "非主键" }}
</el-tag> {{ item.columnName }}</span>
<span
style="
float: right;
margin-left:5px;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>
类型{{ item.type }} <block v-if="item.comment != ''">字段说明{{ item.comment }}</block>
</span>
</el-option>
</el-select>
</el-col>
<el-col :span="5">
<el-select v-model="middleDate.dataSource.label" placeholder="请先选择需要展示的数据">
<template #label="{ value }">
<span>展示: </span>
<span style="font-weight: bold">{{ value }}</span>
</template>
<el-option v-for="item in dbColumnList" :key="item.columnName" :value="item.columnName">
<span style="float: left"> <el-tag :type="item.isPrimary ? 'primary' : 'info'">
{{ item.isPrimary ? "主&emsp;键" : "非主键" }}
</el-tag> {{ item.columnName }}</span>
<span
style="
float: right;
margin-left:5px;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>
类型{{ item.type }} <span v-if="item.comment != ''">字段说明{{ item.comment }}</span>
</span>
</el-option>
</el-select>
<!-- <el-input v-model="middleDate.dataSource.label" placeholder="展示用字段" /> -->
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import { toLowerCase, toSQLLine } from '@/utils/stringFun'
import { getSysDictionaryList } from '@/api/sysDictionary'
import WarningBar from '@/components/warningBar/warningBar.vue'
import { ref,onMounted } from 'vue'
import { ElMessageBox } from 'element-plus'
import {getColumn, getDB, getTable} from "@/api/autoCode";
defineOptions({
name: 'FieldDialog'
})
const props = defineProps({
dialogMiddle: {
type: Object,
default: function() {
return {}
}
},
typeOptions: {
type: Array,
default: function() {
return []
}
},
typeSearchOptions: {
type: Array,
default: function() {
return []
}
},
typeIndexOptions: {
type: Array,
default: function() {
return []
}
},
})
const activeNames = ref([])
const middleDate = ref({})
const dictOptions = ref([])
const dbList = ref([])
const getDbFunc = async() => {
const res = await getDB()
if (res.code === 0) {
dbList.value = res.data.dbList
}
}
const validateDataTypeLong = (rule, value, callback) => {
const regex = /^('([^']*)'(?:,'([^']+)'*)*)$/;
if (middleDate.value.fieldType == "enum" && !regex.test(value)) {
callback(new Error("枚举值校验错误"));
} else {
callback();
}
};
const rules = ref({
fieldName: [
{ required: true, message: '请输入字段英文名', trigger: 'blur' }
],
fieldDesc: [
{ required: true, message: '请输入字段中文名', trigger: 'blur' }
],
fieldJson: [
{ required: true, message: '请输入字段格式化json', trigger: 'blur' }
],
columnName: [
{ required: true, message: '请输入数据库字段', trigger: 'blur' }
],
fieldType: [
{ required: true, message: '请选择字段类型', trigger: 'blur' }
],
dataTypeLong: [
{ validator: validateDataTypeLong, trigger: "blur" }
],
})
const init = async() => {
middleDate.value = props.dialogMiddle
const dictRes = await getSysDictionaryList({
page: 1,
pageSize: 999999
})
dictOptions.value = dictRes.data
}
init()
const autoFill = () => {
middleDate.value.fieldJson = toLowerCase(middleDate.value.fieldName)
middleDate.value.columnName = toSQLLine(middleDate.value.fieldJson)
}
const canSelect = (item) => {
const fieldType = middleDate.value.fieldType
if (fieldType !== 'string' && item === 'LIKE') {
return true
}
if ((fieldType !== 'int' && fieldType !== 'time.Time' && fieldType !== 'float64') && (item === 'BETWEEN' || item === 'NOT BETWEEN')) {
return true
}
return false
}
const clearOther = () => {
middleDate.value.fieldSearchType = ''
middleDate.value.dictType = ''
}
const associationChange = (val) => {
if (val === 2) {
ElMessageBox.confirm(
'一对多关联模式下数据类型会改变为数组后端表现为json具体表现为数组模式是否继续',
'提示',
{
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
middleDate.value.fieldType = 'array'
}).catch(() => {
middleDate.value.dataSource.association = 1
})
}
}
const dbNameChange = () => {
getDBTableList()
middleDate.value.dataSource.table = ''
middleDate.value.dataSource.value = ''
middleDate.value.dataSource.label = ''
}
const dbTableList = ref([])
const getDBTableList = async () => {
const res = await getTable({ businessDB: middleDate.value.dataSource.dbName })
if (res.code === 0) {
let list = res.data.tables; // 确保这里正确获取到 tables 数组
dbTableList.value = list.map(item => ({
tableName: item.tableName,
value: item.tableName // 这里假设 value 也是 tableName如果不同请调整
}));
}
middleDate.value.dataSource.value = ''
middleDate.value.dataSource.label = ''
}
const dbColumnList = ref([])
const selectDB = async (val) => {
middleDate.value.dataSource.table = val
const res = await getColumn({
businessDB: middleDate.value.dataSource.dbName,
tableName: val
})
if (res.code === 0) {
let list = res.data.columns; // 确保这里正确获取到 tables 数组
dbColumnList.value = list.map(item => ({
columnName: item.columnName,
value: item.columnName,
type: item.dataType,
isPrimary: item.primaryKey,
comment: item.columnComment
}));
if (dbColumnList.value.length > 0) {
middleDate.value.dataSource.label = dbColumnList.value[0].columnName
middleDate.value.dataSource.value = dbColumnList.value[0].columnName
}
}
}
const fieldDialogForm = ref(null)
defineExpose({ fieldDialogForm })
onMounted(()=>{
getDbFunc()
if(middleDate.value.dataSource.table){
selectDB(middleDate.value.dataSource.table)
}
})
</script>