Browse Source

feat(vben5): 保存前检查租户连接字符串

pull/1169/head
colin 12 months ago
parent
commit
5e7b538528
  1. 15
      apps/vben5/packages/@abp/saas/src/api/useTenantsApi.ts
  2. 39
      apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringModal.vue
  3. 6
      apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringTable.vue
  4. 5
      apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringsModal.vue
  5. 25
      apps/vben5/packages/@abp/saas/src/components/tenants/TenantModal.vue
  6. 14
      apps/vben5/packages/@abp/saas/src/components/tenants/TenantTable.vue
  7. 7
      apps/vben5/packages/@abp/saas/src/types/tenants.ts

15
apps/vben5/packages/@abp/saas/src/api/useTenantsApi.ts

@ -2,6 +2,7 @@ import type { ListResultDto, PagedResultDto } from '@abp/core';
import type {
GetTenantPagedListInput,
TenantConnectionStringCheckInput,
TenantConnectionStringDto,
TenantConnectionStringSetInput,
TenantCreateDto,
@ -139,8 +140,22 @@ export function useTenantsApi() {
});
}
/**
*
* @param input
*/
function checkConnectionString(
input: TenantConnectionStringCheckInput,
): Promise<void> {
return request(`/api/saas/tenants/connection-string/check`, {
data: input,
method: 'POST',
});
}
return {
cancel,
checkConnectionString,
createApi,
deleteApi,
deleteConnectionStringApi,

39
apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringModal.vue

@ -1,4 +1,5 @@
<script setup lang="ts">
import type { NameValue } from '@abp/core';
import type { FormExpose } from 'ant-design-vue/es/form/Form';
import type { TenantConnectionStringDto } from '../../types';
@ -8,17 +9,31 @@ import { ref, toValue, useTemplateRef } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Form, Input, Textarea } from 'ant-design-vue';
import { Form, Input, Select, Textarea } from 'ant-design-vue';
import { useTenantsApi } from '../../api/useTenantsApi';
const props = defineProps<{
dataBaseOptions: { label: string; value: string }[];
submit?: (data: TenantConnectionStringDto) => Promise<void>;
}>();
const FormItem = Form.Item;
interface TenantConnectionString extends NameValue<string> {
provider: string;
}
const isEditModal = ref(false);
const form = useTemplateRef<FormExpose>('form');
const formModel = ref({} as TenantConnectionStringDto);
const formModel = ref<TenantConnectionString>({
name: '',
provider: 'MySql',
value: '',
});
const { checkConnectionString } = useTenantsApi();
const [Modal, modalApi] = useVbenModal({
async onConfirm() {
await form.value?.validate();
@ -30,7 +45,10 @@ const [Modal, modalApi] = useVbenModal({
if (isOpen) {
form.value?.resetFields();
const dto = modalApi.getData<TenantConnectionStringDto>();
formModel.value = { ...dto };
formModel.value = {
provider: formModel.value.provider,
...dto,
};
if (dto.name) {
isEditModal.value = true;
title = `${$t('AbpSaas.ConnectionStrings')} - ${dto.name}`;
@ -43,7 +61,13 @@ const [Modal, modalApi] = useVbenModal({
async function onSubmit() {
modalApi.setState({ submitting: true });
try {
props.submit && (await props.submit(toValue(formModel)));
const input = toValue(formModel);
await checkConnectionString({
connectionString: input.value,
name: input.name,
provider: input.provider,
});
props.submit && (await props.submit(input));
modalApi.close();
} finally {
modalApi.setState({ submitting: false });
@ -59,6 +83,13 @@ async function onSubmit() {
:wapper-col="{ span: 20 }"
:model="formModel"
>
<FormItem
required
name="provider"
:label="$t('AbpSaas.DisplayName:DataBaseProvider')"
>
<Select :options="dataBaseOptions" v-model:value="formModel.provider" />
</FormItem>
<FormItem required name="name" :label="$t('AbpSaas.DisplayName:Name')">
<Input
:disabled="isEditModal"

6
apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringTable.vue

@ -14,6 +14,7 @@ import { VxeGrid } from 'vxe-table';
const props = defineProps<{
connectionStrings: TenantConnectionStringDto[];
dataBaseOptions: { label: string; value: string }[];
delete?: (data: TenantConnectionStringDto) => Promise<void>;
submit?: (data: TenantConnectionStringDto) => Promise<void>;
}>();
@ -107,7 +108,10 @@ async function onDelete(row: TenantConnectionStringDto) {
</div>
</template>
</VxeGrid>
<ConnectionStringModal :submit="submit" />
<ConnectionStringModal
:data-base-options="dataBaseOptions"
:submit="submit"
/>
</div>
</template>

5
apps/vben5/packages/@abp/saas/src/components/tenants/ConnectionStringsModal.vue

@ -11,6 +11,10 @@ import { message } from 'ant-design-vue';
import { useTenantsApi } from '../../api/useTenantsApi';
import ConnectionStringTable from './ConnectionStringTable.vue';
defineProps<{
dataBaseOptions: { label: string; value: string }[];
}>();
const connectionStrings = ref<TenantConnectionStringDto[]>([]);
const {
@ -61,6 +65,7 @@ async function onDelete(data: TenantConnectionStringDto) {
<template>
<Modal :title="$t('AbpSaas.ConnectionStrings')">
<ConnectionStringTable
:data-base-options="dataBaseOptions"
:connection-strings="connectionStrings"
:delete="onDelete"
:submit="onChange"

25
apps/vben5/packages/@abp/saas/src/components/tenants/TenantModal.vue

@ -32,10 +32,12 @@ import { useEditionsApi } from '../../api/useEditionsApi';
import { useTenantsApi } from '../../api/useTenantsApi';
import ConnectionStringTable from './ConnectionStringTable.vue';
defineProps<{
dataBaseOptions: { label: string; value: string }[];
}>();
const emits = defineEmits<{
(event: 'change', val: TenantDto): void;
}>();
const FormItem = Form.Item;
const defaultModel = {
@ -79,6 +81,11 @@ const getFormRules = computed(() => {
prefix: 'DisplayName',
resourceName: 'AbpSaas',
}),
provider: fieldRequired({
name: 'DataBaseProvider',
prefix: 'DisplayName',
resourceName: 'AbpSaas',
}),
};
});
/** 启用时间不可晚于禁用时间 */
@ -99,7 +106,8 @@ const getDisabledDisableTime = (current: dayjs.Dayjs) => {
return current && current < dayjs(tenant.value.enableTime).endOf('day');
};
const { cancel, createApi, getApi, updateApi } = useTenantsApi();
const { cancel, checkConnectionString, createApi, getApi, updateApi } =
useTenantsApi();
const { getPagedListApi: getEditions } = useEditionsApi();
const [Modal, modalApi] = useVbenModal({
@ -140,6 +148,12 @@ async function onGet() {
async function onSubmit() {
try {
modalApi.setState({ submitting: true });
if (!tenant.value.useSharedDatabase) {
await checkConnectionString({
connectionString: tenant.value.defaultConnectionString,
provider: tenant.value.provider,
});
}
const api = tenant.value.id
? updateApi(tenant.value.id, tenant.value as TenantUpdateDto)
: createApi(tenant.value as unknown as TenantCreateDto);
@ -284,6 +298,12 @@ onMounted(onSearchEditions);
</Checkbox>
</FormItem>
<template v-if="!tenant.id && !tenant.useSharedDatabase">
<FormItem
name="provider"
:label="$t('AbpSaas.DisplayName:DataBaseProvider')"
>
<Select :options="dataBaseOptions" v-model:value="tenant.provider" />
</FormItem>
<FormItem
name="defaultConnectionString"
:label="$t('AbpSaas.DisplayName:DefaultConnectionString')"
@ -294,6 +314,7 @@ onMounted(onSearchEditions);
/>
</FormItem>
<ConnectionStringTable
:data-base-options="dataBaseOptions"
:connection-strings="tenant.connectionStrings"
:submit="onConnectionChange"
:delete="onConnectionDelete"

14
apps/vben5/packages/@abp/saas/src/components/tenants/TenantTable.vue

@ -6,7 +6,7 @@ import type { VbenFormProps } from '@vben/common-ui';
import type { TenantDto } from '../../types/tenants';
import { defineAsyncComponent, h } from 'vue';
import { defineAsyncComponent, h, reactive } from 'vue';
import { useAccess } from '@vben/access';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
@ -42,6 +42,14 @@ const { isEnabled } = useFeatures();
const { hasAccessByCodes } = useAccess();
const { cancel, deleteApi, getPagedListApi } = useTenantsApi();
const dataBaseOptions = reactive([
{ label: 'MySql', value: 'MySql' },
{ label: 'Oracle', value: 'Oracle' },
{ label: 'Postgres', value: 'Postgres' },
{ label: 'Sqlite', value: 'Sqlite' },
{ label: 'SqlServer', value: 'SqlServer' },
]);
const formOptions: VbenFormProps = {
//
collapsed: false,
@ -272,8 +280,8 @@ const onMenuClick = (row: TenantDto, info: MenuInfo) => {
</div>
</template>
</Grid>
<TenantModal @change="() => query()" />
<TenantConnectionStringsModal />
<TenantModal :data-base-options="dataBaseOptions" @change="() => query()" />
<TenantConnectionStringsModal :data-base-options="dataBaseOptions" />
<TenantFeatureModal />
<TenantChangeDrawer />
</template>

7
apps/vben5/packages/@abp/saas/src/types/tenants.ts

@ -54,12 +54,19 @@ interface TenantCreateDto extends TenantCreateOrUpdateBase {
useSharedDatabase: boolean;
}
interface TenantConnectionStringCheckInput {
connectionString: string;
name?: string;
provider: string;
}
interface TenantUpdateDto
extends IHasConcurrencyStamp,
TenantCreateOrUpdateBase {}
export type {
GetTenantPagedListInput,
TenantConnectionStringCheckInput,
TenantConnectionStringDto,
TenantConnectionStringSetInput,
TenantCreateDto,

Loading…
Cancel
Save