初始化地区合伙人

This commit is contained in:
wangxiaowei
2026-03-10 14:22:40 +08:00
commit 4304624e92
599 changed files with 42117 additions and 0 deletions

View File

@ -0,0 +1,531 @@
<template>
<div class="code-edit">
<el-card class="!border-none" shadow="never">
<el-page-header content="编辑数据表" @back="$router.back()" />
</el-card>
<el-card class="mt-4 !border-none" shadow="never">
<el-form
ref="formRef"
class="ls-form"
:model="formData"
label-width="100px"
:rules="rules"
>
<el-tabs v-model="activeName">
<el-tab-pane label="基础信息" name="base">
<el-form-item label="表名称" prop="table_name">
<div class="w-80">
<el-input
v-model="formData.table_name"
placeholder="请输入表名称"
clearable
/>
</div>
</el-form-item>
<el-form-item label="表描述" prop="table_comment">
<div class="w-80">
<el-input
v-model="formData.table_comment"
placeholder="请输入表描述"
clearable
/>
</div>
</el-form-item>
<el-form-item label="作者">
<div class="w-80">
<el-input v-model="formData.author" clearable />
</div>
</el-form-item>
<el-form-item label="备注">
<div class="w-80">
<el-input
v-model="formData.remark"
class="w-full"
type="textarea"
:autosize="{ minRows: 4, maxRows: 4 }"
maxlength="200"
show-word-limit
clearable
/>
</div>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="字段管理" name="column">
<el-table :data="formData.table_column">
<el-table-column label="字段列名" prop="column_name" />
<el-table-column label="字段描述" prop="column_comment" min-width="120">
<template v-slot="{ row }">
<el-input v-model="row.column_comment" clearable />
</template>
</el-table-column>
<el-table-column label="物理类型" prop="column_type" />
<el-table-column label="必填" width="80">
<template v-slot="{ row }">
<el-checkbox
v-model="row.is_required"
:true-value="1"
:false-value="0"
/>
</template>
</el-table-column>
<el-table-column label="插入" width="80">
<template v-slot="{ row }">
<el-checkbox
v-model="row.is_insert"
:true-value="1"
:false-value="0"
/>
</template>
</el-table-column>
<el-table-column label="编辑" width="80">
<template v-slot="{ row }">
<el-checkbox
v-model="row.is_update"
:true-value="1"
:false-value="0"
/>
</template>
</el-table-column>
<el-table-column label="列表" width="80">
<template v-slot="{ row }">
<el-checkbox
v-model="row.is_lists"
:true-value="1"
:false-value="0"
/>
</template>
</el-table-column>
<el-table-column label="查询" width="80">
<template v-slot="{ row }">
<el-checkbox
v-model="row.is_query"
:true-value="1"
:false-value="0"
/>
</template>
</el-table-column>
<el-table-column label="查询方式">
<template v-slot="{ row }">
<el-select v-model="row.query_type">
<el-option label="=" value="=" />
<el-option label="!=" value="!=" />
<el-option label=">" value=">" />
<el-option label=">=" value=">=" />
<el-option label="<" value="<" />
<el-option label="<=" value="<=" />
<el-option label="LIKE" value="like" />
<el-option label="BETWEEN" value="between" />
</el-select>
</template>
</el-table-column>
<el-table-column label="显示类型" min-width="120">
<template v-slot="{ row }">
<el-select v-model="row.view_type">
<el-option label="文本框" value="input" />
<el-option label="文本域" value="textarea" />
<el-option label="下拉框" value="select" />
<el-option label="单选框" value="radio" />
<el-option label="复选框" value="checkbox" />
<el-option label="日期控件" value="datetime" />
<el-option label="图片选择控件" value="imageSelect" />
<el-option label="富文本控件" value="editor" />
</el-select>
</template>
</el-table-column>
<el-table-column label="字典类型" min-width="120">
<template v-slot="{ row }">
<el-select
v-model="row.dict_type"
clearable
:disabled="
!(
row.view_type == 'select' ||
row.view_type == 'radio' ||
row.view_type == 'checkbox'
)
"
placeholder="字典类型"
>
<el-option
v-for="(item, index) in optionsData.dict_type"
:key="index"
:label="item.name"
:value="item.type"
:disabled="!item.status"
/>
</el-select>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="生成配置" name="config">
<el-form-item label="模板类型" prop="template_type">
<el-radio-group v-model="formData.template_type">
<el-radio :value="0">单表curd</el-radio>
<el-radio :value="1">树表curd</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="删除类型" prop="delete.type">
<el-radio-group v-model="formData.delete.type">
<el-radio :value="0">物理删除</el-radio>
<el-radio :value="1">软删除</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="删除字段"
prop="delete.name"
v-if="formData.delete.type == 1"
>
<el-select class="w-80" v-model="formData.delete.name" clearable>
<el-option
v-for="item in formData.table_column"
:key="item.id"
:value="item.column_name"
:label="`${item.column_name}${item.column_comment}`"
/>
</el-select>
</el-form-item>
<template v-if="formData.template_type == 1">
<el-form-item label="树表ID" prop="treePrimary">
<div>
<el-select
class="w-80"
v-model="formData.tree.tree_id"
clearable
>
<el-option
v-for="item in formData.table_column"
:key="item.id"
:value="item.column_name"
:label="`${item.column_name}${item.column_comment}`"
/>
</el-select>
<div class="form-tips">指定树表的主要ID一般为主键</div>
</div>
</el-form-item>
<el-form-item label="树表父ID" prop="treeParent">
<div>
<el-select
class="w-80"
v-model="formData.tree.tree_pid"
clearable
>
<el-option
v-for="item in formData.table_column"
:key="item.id"
:value="item.column_name"
:label="`${item.column_name}${item.column_comment}`"
/>
</el-select>
<div class="form-tips">指定树表的父ID比如parent_id</div>
</div>
</el-form-item>
<el-form-item label="树名称" prop="treeName">
<el-select class="w-80" v-model="formData.tree.tree_name" clearable>
<el-option
v-for="item in formData.table_column"
:key="item.id"
:value="item.column_name"
:label="`${item.column_name}${item.column_comment}`"
/>
</el-select>
</el-form-item>
</template>
<el-form-item label="类描述">
<div class="w-80">
<div>
<el-input
v-model="formData.class_comment"
placeholder="请输入文件描述"
clearable
/>
</div>
<div class="form-tips">
<div>
填写test,生成文件描述为test控制器(test逻辑/test模型)
</div>
</div>
</div>
</el-form-item>
<el-form-item label="生成方式" prop="generate_type">
<el-radio-group v-model="formData.generate_type">
<el-radio :value="0">压缩包下载</el-radio>
<el-radio :value="1">生成到模块</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="模块名" prop="module_name">
<div class="w-80">
<el-input
v-model="formData.module_name"
placeholder="请输入模块名"
clearable
/>
<div class="form-tips">生成文件所在模块</div>
</div>
</el-form-item>
<el-form-item label="类目录">
<div class="w-80">
<div>
<el-input
v-model="formData.class_dir"
placeholder="请输入文件所在目录"
clearable
/>
</div>
<div class="form-tips">
<div>
填写test,则在app/模块名/controller/test下生成控制器
</div>
</div>
</div>
</el-form-item>
<el-form-item label="父级菜单" prop="menu.pid">
<el-tree-select
class="w-80"
v-model="formData.menu.pid"
:data="optionsData.menu"
clearable
node-key="id"
:props="{
label: 'name'
}"
default-expand-all
placeholder="请选择父级菜单"
check-strictly
/>
</el-form-item>
<el-form-item label="菜单名称" prop="menu.name">
<div class="w-80">
<el-input
v-model="formData.menu.name"
placeholder="请输入菜单名称"
clearable
/>
</div>
</el-form-item>
<el-form-item label="菜单构建" prop="menu.type" required>
<div>
<el-radio-group v-model="formData.menu.type">
<el-radio :value="1">自动构建</el-radio>
<el-radio :value="0">手动添加</el-radio>
</el-radio-group>
<div class="form-tips">
自动构建自动执行生成菜单sql手动添加自行添加菜单
</div>
</div>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="关联配置" name="relations">
<el-button type="primary" @click="showEditPopup('add')">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增关联
</el-button>
<div class="mt-4">
<el-table :data="formData.relations" size="small">
<el-table-column prop="type" label="关联类型">
<template #default="{ row }">
<dict-value :value="row.type" :options="relationTypes" />
</template>
</el-table-column>
<el-table-column prop="name" label="关联名称" />
<el-table-column prop="model" label="关联模型" />
<el-table-column prop="local_key" label="关联键">
<template #default="{ row }">
<dict-value
:value="row.local_key"
:options="formData.table_column"
:config="{
label: 'column_comment',
value: 'column_name'
}"
/>
</template>
</el-table-column>
<el-table-column prop="foreign_key" label="外键" />
<el-table-column label="操作">
<template #default="{ row, $index }">
<el-button
link
type="primary"
@click="showEditPopup('edit', row, $index)"
>
编辑
</el-button>
<el-button link type="danger" @click="handelDelete($index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<relations-add
:column="formData.table_column"
:types="relationTypes"
v-if="showEdit"
ref="editRef"
@add="handleAdd"
@edit="handleEdit"
@close="showEdit = false"
/>
</div>
</el-tab-pane>
</el-tabs>
</el-form>
</el-card>
<footer-btns>
<el-button type="primary" @click="onSubmit">保存</el-button>
</footer-btns>
</div>
</template>
<script lang="ts" setup name="tableEdit">
import type { FormInstance } from 'element-plus'
import { cloneDeep } from 'lodash'
import { menuAll } from '@/api/perms/menu'
import { dictTypeAll } from '@/api/setting/dict'
import { generateEdit, tableDetail } from '@/api/tools/code'
import { useDictOptions } from '@/hooks/useDictOptions'
import feedback from '@/utils/feedback'
import RelationsAdd from '../components/relations-add.vue'
const route = useRoute()
const router = useRouter()
const activeName = ref('column')
const showEdit = ref(false)
const relationTypes = [
{
name: '一对一',
value: 'has_one'
},
{
name: '一对多',
value: 'has_many'
}
]
const formData = reactive({
id: '',
table_name: '',
table_comment: '',
author: '',
remark: '',
template_type: 0,
generate_type: 0,
module_name: '',
class_dir: '',
class_comment: '',
table_column: [] as any[],
menu: {
pid: 0,
name: '',
type: 0
},
tree: {
tree_id: 0,
tree_pid: 0,
tree_name: 0
},
delete: {
name: '',
type: 0
},
relations: [] as any[]
})
let editIndex = 0
const formRef = shallowRef<FormInstance>()
const editRef = shallowRef<InstanceType<typeof RelationsAdd>>()
const rules = reactive({
table_name: [{ required: true, message: '请输入表名称' }],
table_comment: [{ required: true, message: '请输入表描述' }],
module_name: [{ required: true, message: '请输入模块名' }],
generate_type: [{ required: true, trigger: 'change' }],
template_type: [{ required: true, trigger: 'change' }],
['menu.pid']: [{ required: true, message: '请选择父级菜单' }],
['menu.name']: [{ required: true, message: '请输入菜单名称' }],
['delete.type']: [{ required: true, trigger: 'change' }],
['delete.name']: [{ required: true, message: '请选择删除字段' }]
})
const showEditPopup = async (type: string, data?: any, index?: number) => {
showEdit.value = true
await nextTick()
if (data && index !== undefined) {
editRef.value?.setFormData(data)
editIndex = index
}
editRef.value?.open(type)
}
const handleAdd = (data: any) => {
const newData = cloneDeep(toRaw(data))
formData.relations.push(newData)
}
const handleEdit = async (data: any) => {
const newData = cloneDeep(toRaw(data))
console.log(editIndex)
formData.relations.splice(editIndex, 1, newData)
}
const handelDelete = (index: number) => {
formData.relations.splice(index, 1)
}
const getDetails = async () => {
const data = await tableDetail({
id: route.query.id
})
Object.keys(formData).forEach((key) => {
//@ts-ignore
formData[key] = data[key]
})
watch(
() => formData.generate_type,
(value) => {
if (value == 1) {
feedback
.confirm('生成到模块方式如遇同名文件会覆盖旧文件,确定要选择此方式吗?')
.catch(() => {
formData.generate_type = 0
})
}
}
)
}
const { optionsData } = useDictOptions<{
dict_type: any[]
menu: any[]
}>({
dict_type: {
api: dictTypeAll
},
menu: {
api: menuAll,
transformData(data) {
const menu = { id: 0, name: '顶级', children: [] }
menu.children = data
return [menu]
}
}
})
const onSubmit = async () => {
try {
await formRef.value?.validate()
await generateEdit(formData)
router.back()
} catch (error: any) {
for (const err in error) {
const isInRules = Object.keys(rules).includes(err)
isInRules && feedback.msgError(error[err][0]?.message)
}
}
}
getDetails()
</script>

View File

@ -0,0 +1,223 @@
<template>
<div class="code-generation">
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="formData" inline>
<el-form-item class="w-[280px]" label="表名称">
<el-input v-model="formData.table_name" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="表描述">
<el-input v-model="formData.table_comment" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
<div class="flex">
<data-table
v-perms="['tools.generator/selectTable']"
class="inline-block mr-[10px]"
@success="getLists"
>
<el-button type="primary">
<template #icon>
<icon name="el-icon-Plus" />
</template>
导入数据表
</el-button>
</data-table>
<el-button
v-perms="['tools.generator/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
type="danger"
>
<template #icon>
<icon name="el-icon-Delete" />
</template>
删除
</el-button>
<el-button
v-perms="['tools.generator/generate']"
:disabled="!selectData.length"
@click="handleGenerate(selectData)"
>
生成代码
</el-button>
</div>
<div class="mt-4">
<el-table
:data="pager.lists"
size="large"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="表名称" prop="table_name" min-width="180" />
<el-table-column label="表描述" prop="table_comment" min-width="180" />
<el-table-column label="创建时间" prop="create_time" min-width="180" />
<el-table-column label="更新时间" prop="update_time" min-width="180" />
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<div class="flex items-center">
<el-button
v-perms="['tools.generator/preview']"
type="primary"
link
@click="handlePreview(row.id)"
>
预览
</el-button>
<el-button type="primary" link>
<router-link
v-perms="['tools.generator/edit']"
:to="{
path: getRoutePath('tools.generator/edit'),
query: {
id: row.id
}
}"
>
编辑
</router-link>
</el-button>
<el-dropdown
class="ml-2"
@command="handleCommand($event, row)"
v-perms="[
'tools.generator/generate',
'tools.generator/syncColumn',
'tools.generator/delete'
]"
>
<el-button type="primary" link>
更多
<icon name="el-icon-ArrowDown" :size="14" />
</el-button>
<template #dropdown>
<el-dropdown-menu>
<div v-perms="['tools.generator/generate']">
<el-dropdown-item command="generate">
<el-button type="primary" link>
生成代码
</el-button>
</el-dropdown-item>
</div>
<div v-perms="['tools.generator/syncColumn']">
<el-dropdown-item command="sync">
<el-button type="primary" link>
同步
</el-button>
</el-dropdown-item>
</div>
<div v-perms="['tools.generator/delete']">
<el-dropdown-item command="delete">
<el-button type="danger" link> 删除 </el-button>
</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<code-preview
v-if="previewState.show"
v-model="previewState.show"
:code="previewState.code"
/>
</div>
</template>
<script lang="ts" setup name="codeGenerate">
import {
generateCode,
generateDelete,
generatePreview,
generateTable,
syncColumn
} from '@/api/tools/code'
import { usePaging } from '@/hooks/usePaging'
import { getRoutePath } from '@/router'
import { isProdMode } from '@/utils/env'
import feedback from '@/utils/feedback'
import CodePreview from '../components/code-preview.vue'
import DataTable from '../components/data-table.vue'
const formData = reactive({
table_name: '',
table_comment: ''
})
const previewState = reactive({
show: false,
loading: false,
code: []
})
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: generateTable,
params: formData
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
const handleSync = async (id: number) => {
await feedback.confirm('确定要同步表结构?')
await syncColumn({ id })
}
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await generateDelete({ id })
getLists()
}
const handlePreview = async (id: number) => {
const data: any = await generatePreview({ id })
previewState.code = data
previewState.show = true
}
const hasGenerateTypeInModule = (data: any[]) => {
return data.some((item) => item.generate_type == 1)
}
const handleGenerate = async (selectData: any[]) => {
if (isProdMode() && hasGenerateTypeInModule(selectData)) {
return feedback.msgError('生成方式为生成到模块,请在前端开发模式下使用,详细参考文档')
}
const data: any = await generateCode({ id: selectData })
if (data.file) {
window.open(data.file, '_blank')
}
}
const handleCommand = (command: any, row: any) => {
switch (command) {
case 'generate':
handleGenerate([row.id])
break
case 'sync':
handleSync(row.id)
break
case 'delete':
handleDelete(row.id)
}
}
getLists()
</script>

View File

@ -0,0 +1,64 @@
<template>
<div class="code-preview">
<el-dialog v-model="show" width="900px" title="代码预览">
<el-tabs v-model="activeTab">
<el-tab-pane
v-for="(item, index) in code"
:label="item.name"
:name="`index${index}`"
:key="index"
>
<div class="flex" style="height: 50vh">
<el-scrollbar class="flex-1">
<highlightjs autodetect :code="item.content" />
</el-scrollbar>
<div>
<el-button @click="handleCopy(item.content)" type="primary" link>
<template #icon>
<icon name="el-icon-CopyDocument" />
</template>
复制
</el-button>
</div>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import useClipboard from 'vue-clipboard3'
import feedback from '@/utils/feedback'
const props = defineProps<{
modelValue: boolean
code: any[]
}>()
const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void
}>()
const { toClipboard } = useClipboard()
const activeTab = ref('index0')
const handleCopy = async (text: string) => {
try {
await toClipboard(text)
feedback.msgSuccess('复制成功')
} catch (e) {
feedback.msgError('复制失败')
}
}
const show = computed<boolean>({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
</script>

View File

@ -0,0 +1,94 @@
<template>
<div class="data-table">
<popup
ref="popupRef"
:clickModalClose="false"
title="选择表"
width="900px"
:async="true"
@confirm="handleConfirm"
>
<template #trigger>
<slot></slot>
</template>
<el-form class="ls-form" :model="formData" inline>
<el-form-item class="w-[280px]" label="表名称">
<el-input v-model="formData.name" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="表描述">
<el-input v-model="formData.comment" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
<div class="m-4" v-loading="pager.loading">
<el-table
height="400"
size="large"
:data="pager.lists"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="表名称" prop="name" min-width="150" />
<el-table-column label="表描述" prop="comment" min-width="160" />
<el-table-column label="创建时间" prop="create_time" min-width="180" />
</el-table>
</div>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</popup>
</div>
</template>
<script lang="ts" setup>
import { dataTable, selectTable } from '@/api/tools/code'
import Pagination from '@/components/pagination/index.vue'
import Popup from '@/components/popup/index.vue'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
const emit = defineEmits<{
(event: 'success'): void
}>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const formData = reactive({
name: '', // 表名称
comment: '' // 表描述
})
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: dataTable,
params: formData,
size: 10
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ name, comment }) => ({
name,
comment
}))
}
const handleConfirm = async () => {
if (!selectData.value.length) return feedback.msgError('请选择数据表')
await selectTable({
table: selectData.value
})
popupRef.value?.close()
emit('success')
}
watch(
() => popupRef.value?.visible,
(value) => {
if (value) getLists()
}
)
</script>

View File

@ -0,0 +1,162 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
<el-form-item label="关联类型" prop="type">
<el-select class="flex-1" v-model="formData.type" placeholder="请选择关联类型">
<el-option
v-for="(item, index) in types"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="关联名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入关联名称" />
</el-form-item>
<el-form-item label="关联模型" prop="model">
<el-select class="flex-1" v-model="formData.model" placeholder="请选择关联模型">
<el-option
v-for="item in optionsData.models"
:label="item"
:value="item"
:key="item"
/>
</el-select>
</el-form-item>
<el-form-item label="关联健" prop="local_key">
<el-select
class="flex-1"
v-model="formData.local_key"
clearable
placeholder="请选择关联健"
>
<el-option
v-for="item in column"
:key="item.id"
:value="item.column_name"
:label="`${item.column_name}${item.column_comment}`"
/>
</el-select>
</el-form-item>
<el-form-item label="外键" prop="foreign_key">
<el-input
v-model="formData.foreign_key"
placeholder="关联表外键或中间表的外键"
/>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import type { PropType } from 'vue'
import { getModels } from '@/api/tools/code'
import Popup from '@/components/popup/index.vue'
import { useDictOptions } from '@/hooks/useDictOptions'
defineProps({
column: {
type: Array as PropType<any[]>,
default: () => []
},
types: {
type: Array as PropType<any[]>,
default: () => []
}
})
const emit = defineEmits(['add', 'close', 'edit'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref<'add' | 'edit'>('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑关联' : '新增关联'
})
const formData = reactive({
name: '',
model: '',
type: '',
local_key: '',
foreign_key: ''
})
const formRules = {
name: [
{
required: true,
message: '请输入关联名称'
}
],
type: [
{
required: true,
message: '请选择关联类型'
}
],
model: [
{
required: true,
message: '请选择关联模型'
}
],
local_key: [
{
required: true,
message: '请选择关联健'
}
],
foreign_key: [
{
required: true,
message: '请输入外键'
}
]
}
const { optionsData } = useDictOptions<{
models: any[]
}>({
models: {
api: getModels
}
})
const handleSubmit = async () => {
await formRef.value?.validate()
popupRef.value?.close()
emit(mode.value, formData)
}
const open = (type = 'add') => {
mode.value = type as 'add' | 'edit'
popupRef.value?.open()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData
})
</script>