提交 711a986c 作者: 方治民

feat: 拆分 Edit 各个 Tab 组件,新增外键字段设置联动

上级 8c5e6c66
<script lang="ts" setup>
import type { BasicTableProps, VxeGridInstance } from '/@/components/VxeTable'
import type { DatabaseSchema } from '../data'
import { Alert } from 'ant-design-vue'
import { VxeBasicTable } from '/@/components/VxeTable'
import { getDatabaseForeignKeyColumns } from '../data'
import { debounce } from 'lodash-es'
const props = defineProps({
data: {
type: Array as PropType<DatabaseSchema[]>,
required: true,
default: () => [] as DatabaseSchema[],
},
})
const emits = defineEmits(['change'])
const change = debounce(() => emits('change', unref(databaseForeignKeyTable.value?.data)), 500)
watch(
() => props.data,
(data) => {
databaseForeignKeyTableOptions.data = data
},
)
const id = ref<string>('databaseForeignKeyTable')
const databaseForeignKeyTable = ref<VxeGridInstance>()
const databaseForeignKeyTableOptions = reactive<BasicTableProps>({
id: id.value,
// FIXME: 修复表格高度自适应问题
// height: 'auto',
autoResize: true,
stripe: false,
keepSource: true,
showOverflow: true,
rowConfig: { useKey: true, keyField: 'id' },
columns: getDatabaseForeignKeyColumns(change),
data: props.data,
editConfig: { trigger: 'click', mode: 'cell', showStatus: false, beforeEditMethod: ({ row }) => !row.disabled },
})
</script>
<template>
<Alert message="仅支持以 _id 或 Id 为后缀的字段名允许设置外键" type="info" show-icon />
<VxeBasicTable :ref="id" v-bind="databaseForeignKeyTableOptions" />
</template>
<script lang="ts" setup>
import type { ActionItem } from '/@/components/Table'
import type { BasicTableProps, VxeGridInstance } from '/@/components/VxeTable'
import type { DatabaseSchema, TableType } from '../data'
import { TableAction } from '/@/components/Table'
import { VxeBasicTable } from '/@/components/VxeTable'
import { nanoid } from 'nanoid'
import { getDatabaseSchemaColumns } from '../data'
import { useSortable } from '/@/hooks/web/useSortable'
import { debounce } from 'lodash-es'
const props = defineProps({
tableType: {
type: String as PropType<TableType>,
required: true,
},
data: {
type: Array as PropType<DatabaseSchema[]>,
required: true,
default: () => [] as DatabaseSchema[],
},
})
const emits = defineEmits(['change'])
const change = debounce(() => emits('change', unref(databaseSchemaTable.value?.data)), 500)
onMounted(() => {
nextTick(() => {
// 初始化行拖拽
const table = databaseSchemaTable.value
const { initSortable } = useSortable(table?.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
handle: '.drag',
onEnd: async (sortableEvent) => {
const newIndex = sortableEvent.newIndex as number
const oldIndex = sortableEvent.oldIndex as number
const currRow = table.data.splice(oldIndex, 1)[0]
table.data.splice(newIndex, 0, currRow)
databaseSchemaTableOptions.data = [...table.data]
await table?.updateData().finally(change)
},
})
initSortable()
})
})
const id = ref<string>('databaseSchemaTable')
const databaseSchemaTable = ref<VxeGridInstance>()
const databaseSchemaTableOptions = reactive<BasicTableProps>({
id: id.value,
// FIXME: 修复表格高度自适应问题
// height: 'auto',
autoResize: true,
stripe: false,
keepSource: true,
showOverflow: true,
rowConfig: { useKey: true, keyField: 'id' },
checkboxConfig: { checkMethod: ({ row }) => !row.disabled },
columns: getDatabaseSchemaColumns(change),
data: props.data,
editConfig: { trigger: 'click', mode: 'cell', showStatus: false, beforeEditMethod: ({ row }) => !row.disabled },
editRules: {
field: [{ required: true, message: '请输入字段名称' }],
comment: [{ required: true, message: '请输入字段备注' }],
type: [{ required: true, message: '请选择字段类型' }],
},
toolbarConfig: {
buttons: [
{
content: '新增',
buttonRender: {
name: 'AButton',
props: {
type: 'primary',
preIcon: 'mdi:table-row-plus-before',
},
events: {
click: async () => {
const table = databaseSchemaTable.value
const { row } = await table?.insertAt(
{
id: nanoid(),
field: null,
type: null,
comment: null,
len: null,
decimal: null,
pk: false,
empty: false,
transient: true,
},
-1,
)
databaseSchemaTableOptions.data.push(row)
await table?.updateData().finally(change)
await table?.setEditCell(row, 'field')
},
},
},
},
{
content: '删除',
buttonRender: {
name: 'AButton',
props: {
type: 'danger',
preIcon: 'mdi:table-row-remove',
disabled: true,
},
events: {
click: async () => {
const table = databaseSchemaTable.value
const checkedRecords = table?.getCheckboxRecords()
if (!checkedRecords?.length) {
return
}
// 更新数据
databaseSchemaTableOptions.data = databaseSchemaTableOptions.data.filter(
(item) => !checkedRecords?.some((record) => record.id === item.id),
)
await table?.removeCheckboxRow()
await table?.updateData().finally(change)
onDatabaseSchemaCheckboxChange()
},
},
},
},
],
},
})
const onDatabaseSchemaCheckboxChange = () => {
const checkedRecords = databaseSchemaTable.value?.getCheckboxRecords()
databaseSchemaTableOptions.toolbarConfig.buttons[1].buttonRender.props.disabled = !checkedRecords?.length
}
const createDatabaseSchemaTableActions = (record: DatabaseSchema) => {
const actions: ActionItem[] = [
{
icon: 'carbon:arrow-up',
onClick: async () => {
const table = databaseSchemaTable.value
const source = table?.getRowById(record.id)
const oldIndex = table?.getRowIndex(source)
const newIndex = oldIndex - 1 < 0 ? 0 : oldIndex - 1
const currRow = table.data.splice(oldIndex, 1)[0]
table.data.splice(newIndex, 0, currRow)
databaseSchemaTableOptions.data = [...table.data]
await table?.updateData().finally(change)
},
},
{
icon: 'carbon:arrow-down',
onClick: async () => {
const table = databaseSchemaTable.value
const source = table?.getRowById(record.id)
const oldIndex = table?.getRowIndex(source)
const newIndex = oldIndex + 1 > table.data.length - 1 ? table.data.length - 1 : oldIndex + 1
const currRow = table.data.splice(oldIndex, 1)[0]
table.data.splice(newIndex, 0, currRow)
databaseSchemaTableOptions.data = [...table.data]
await table?.updateData().finally(change)
},
},
{
icon: 'carbon:copy',
tooltip: '复制',
onClick: async () => {
const table = databaseSchemaTable.value
const source = table?.getRowById(record.id)
const index = table?.getRowIndex(source)
const { row } = await table?.insertAt({ ...record, id: nanoid() }, source)
databaseSchemaTableOptions.data.splice(index + 1, 0, row)
await table?.updateData().finally(change)
await table?.setEditCell(row, 'field')
},
},
{
icon: 'carbon:trash-can',
tooltip: '删除',
color: 'error',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: async () => {
const table = databaseSchemaTable.value
// 更新数据
databaseSchemaTableOptions.data = databaseSchemaTableOptions.data.filter(
(item) => record.id !== item.id,
)
await table?.updateData().finally(change)
},
},
},
]
return record.field === 'id' ? [] : actions
}
</script>
<template>
<VxeBasicTable
:ref="id"
v-bind="databaseSchemaTableOptions"
@checkbox-change="onDatabaseSchemaCheckboxChange"
@checkbox-all="onDatabaseSchemaCheckboxChange"
>
<template #action="{ row }">
<TableAction outside :actions="createDatabaseSchemaTableActions(row)" />
</template>
</VxeBasicTable>
</template>
......@@ -19,12 +19,12 @@ export const databaseTypeOptions: SelectProps['options'] = [
{
label: '常规主表',
value: 'MasterGeneral',
disabled: true,
disabled: false,
},
{
label: '常规从表',
value: 'SlaveGeneral',
disabled: true,
disabled: false,
},
],
},
......@@ -275,6 +275,7 @@ export interface DatabaseSchema {
type?: FieldType
len?: number
decimal?: number
defaultValue?: string
pk?: boolean
empty?: boolean
transient?: boolean
......@@ -287,7 +288,7 @@ export interface DatabaseSchema {
* 获取数据源字段列表
* @returns Column[]
*/
export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
export function getDatabaseSchemaColumns(change: () => void): VxeGridPropTypes.Columns {
return [
{
type: 'html',
......@@ -316,6 +317,9 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
editRender: {
name: 'AInput',
placeholder: '请点击输入',
events: {
input: change,
},
},
},
{
......@@ -324,6 +328,9 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
editRender: {
name: 'AInput',
placeholder: '请点击输入',
events: {
input: change,
},
},
},
{
......@@ -333,6 +340,9 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
name: 'ASelect',
placeholder: '请点击选择',
optionGroups: fieldTypeOptions,
events: {
change,
},
},
},
{
......@@ -340,6 +350,9 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
field: 'len',
editRender: {
name: 'AInputNumber',
events: {
input: change,
},
},
},
{
......@@ -347,15 +360,35 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
field: 'decimal',
editRender: {
name: 'AInputNumber',
events: {
input: change,
},
},
},
{
title: '默认值',
field: 'defaultValue',
editRender: {
name: 'AInput',
events: {
input: change,
},
},
},
{
title: '是否主键',
field: 'pk',
align: 'center',
width: 100,
slots: {
default: ({ row }) => {
return [<Checkbox v-model:checked={row.pk} disabled={row.disabled || row.disablePK} />]
return [
<Checkbox
v-model:checked={row.pk}
disabled={row.disabled || row.disablePK}
onChange={change}
/>,
]
},
},
},
......@@ -363,9 +396,16 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
title: '允许空值',
field: 'empty',
align: 'center',
width: 100,
slots: {
default: ({ row }) => {
return [<Checkbox v-model:checked={row.empty} disabled={row.disabled || row.disableEmpty} />]
return [
<Checkbox
v-model:checked={row.empty}
disabled={row.disabled || row.disableEmpty}
onChange={change}
/>,
]
},
},
},
......@@ -373,10 +413,15 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
title: '是否同步数据库',
field: 'transient',
align: 'center',
width: 150,
slots: {
default: ({ row }) => {
return [
<Checkbox v-model:checked={row.transient} disabled={row.disabled || row.disableTransient} />,
<Checkbox
v-model:checked={row.transient}
disabled={row.disabled || row.disableTransient}
onChange={change}
/>,
]
},
},
......@@ -391,7 +436,53 @@ export function getDatabaseSchemaColumns(): VxeGridPropTypes.Columns {
]
}
export function getDefaultSchemaFieldDataSourcesByType(type: string): DatabaseSchema[] {
export function getDatabaseForeignKeyColumns(change: () => void): VxeGridPropTypes.Columns {
return [
{
type: 'seq',
align: 'center',
width: 50,
},
{
title: '字段名称',
field: 'field',
},
{
title: '字段备注',
field: 'comment',
},
{
title: '字段类型',
field: 'type',
},
{
title: '外键表',
field: 'foreignTable',
editRender: {
// TODO: 改用 Select 选择外键表,通过接口查询
name: 'AInput',
placeholder: '请点击输入',
events: {
input: change,
},
},
},
{
title: '外键字段',
field: 'foreignField',
editRender: {
name: 'AInput',
placeholder: '请点击输入',
events: {
input: change,
},
},
},
]
}
export type TableType = 'SingleGeneral' | 'MasterGeneral' | 'SlaveGeneral' | 'SingleTimeSeries' | 'BusinessTimeSeries'
export function getDefaultSchemaFieldDataSourcesByType(type: TableType): DatabaseSchema[] {
if (type === 'SingleGeneral') {
return [
{
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论