143 lines
3.3 KiB
Vue
143 lines
3.3 KiB
Vue
<script setup lang="ts">
|
||
import { computed, ref } from 'vue';
|
||
|
||
import { useVbenModal } from '@vben/common-ui';
|
||
|
||
import { message } from 'ant-design-vue';
|
||
|
||
import { useVbenForm } from '#/adapter/form';
|
||
|
||
import { addIndexApi } from '../api';
|
||
|
||
defineOptions({
|
||
name: 'AddIndexModal',
|
||
});
|
||
|
||
const tableName = ref('');
|
||
const columns = ref<any[]>([]);
|
||
const reloadCallback = ref<(() => void) | null>(null);
|
||
|
||
const columnOptions = computed(() => {
|
||
return columns.value.map((col) => ({
|
||
label: col.comment || col.name,
|
||
value: col.name,
|
||
}));
|
||
});
|
||
|
||
// 索引类型选项
|
||
const indexTypeOptions = [
|
||
{ label: 'BTREE', value: 'BTREE' },
|
||
{ label: 'HASH', value: 'HASH' },
|
||
{ label: 'FULLTEXT', value: 'FULLTEXT' },
|
||
{ label: 'SPATIAL', value: 'SPATIAL' },
|
||
];
|
||
|
||
const [Form, formApi] = useVbenForm({
|
||
wrapperClass: 'grid-cols-12',
|
||
commonConfig: {
|
||
formItemClass: 'col-span-12',
|
||
componentProps: {
|
||
class: 'w-full',
|
||
},
|
||
},
|
||
layout: 'horizontal',
|
||
schema: [
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'name',
|
||
label: '索引名',
|
||
formItemClass: 'col-span-12',
|
||
componentProps: {
|
||
placeholder: '请输入索引名',
|
||
},
|
||
rules: 'required',
|
||
},
|
||
{
|
||
component: 'Select',
|
||
fieldName: 'columns',
|
||
label: '选择字段',
|
||
formItemClass: 'col-span-12',
|
||
componentProps: {
|
||
mode: 'multiple',
|
||
placeholder: '请选择字段',
|
||
options: columnOptions,
|
||
},
|
||
rules: 'required',
|
||
},
|
||
{
|
||
component: 'Switch',
|
||
fieldName: 'unique',
|
||
label: '唯一索引',
|
||
formItemClass: 'col-span-12',
|
||
},
|
||
{
|
||
component: 'Select',
|
||
fieldName: 'type',
|
||
label: '索引类型',
|
||
formItemClass: 'col-span-12',
|
||
componentProps: {
|
||
options: indexTypeOptions,
|
||
placeholder: '请选择索引类型(默认BTREE)',
|
||
},
|
||
},
|
||
],
|
||
showDefaultActions: false,
|
||
});
|
||
|
||
const [Modal, modalApi] = useVbenModal({
|
||
fullscreenButton: false,
|
||
draggable: true,
|
||
onCancel() {
|
||
modalApi.close();
|
||
},
|
||
onConfirm: async () => {
|
||
const valid = await formApi.validate();
|
||
if (valid.valid) {
|
||
const values = await formApi.getValues();
|
||
if (!values.columns || values.columns.length === 0) {
|
||
message.warning('请选择字段');
|
||
return;
|
||
}
|
||
modalApi.setState({ loading: true, confirmLoading: true });
|
||
try {
|
||
await addIndexApi({
|
||
table_name: tableName.value,
|
||
index_name: values.name,
|
||
columns: values.columns,
|
||
unique: values.unique || false,
|
||
type: values.type || 'BTREE',
|
||
});
|
||
message.success('添加成功');
|
||
reloadCallback.value?.();
|
||
modalApi.close();
|
||
} catch (error: any) {
|
||
message.error(error.message || '添加失败');
|
||
} finally {
|
||
modalApi.setState({ loading: false, confirmLoading: false });
|
||
}
|
||
}
|
||
},
|
||
onOpenChange(isOpen: boolean) {
|
||
if (isOpen) {
|
||
const data = modalApi.getData<{
|
||
tableName: string;
|
||
columns: any[];
|
||
reload: () => void;
|
||
}>();
|
||
if (data) {
|
||
tableName.value = data.tableName;
|
||
columns.value = data.columns;
|
||
reloadCallback.value = data.reload;
|
||
formApi.resetFields();
|
||
}
|
||
}
|
||
},
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<Modal title="添加索引" class="w-[500px]">
|
||
<Form />
|
||
</Modal>
|
||
</template>
|