feat: oss config

This commit is contained in:
dap 2024-09-18 15:19:37 +08:00
parent 64218084bb
commit ad342810e3
7 changed files with 374 additions and 4 deletions

View File

@ -0,0 +1,41 @@
import type { OssConfig } from './model';
import type { ID, IDS, PageQuery } from '#/api/common';
import { requestClient } from '#/api/request';
enum Api {
ossConfigChangeStatus = '/resource/oss/config/changeStatus',
ossConfigList = '/resource/oss/config/list',
root = '/resource/oss/config',
}
// 获取OSS配置列表
export function ossConfigList(params?: PageQuery) {
return requestClient.get<OssConfig[]>(Api.ossConfigList, { params });
}
// 获取OSS配置的信息
export function ossConfigInfo(ossConfigId: ID) {
return requestClient.get<OssConfig>(`${Api.root}/${ossConfigId}`);
}
// 添加新的OSS配置
export function ossConfigAdd(data: any) {
return requestClient.postWithMsg<void>(Api.root, data);
}
// 更新现有的OSS配置
export function ossConfigUpdate(data: any) {
return requestClient.putWithMsg<void>(Api.root, data);
}
// 删除OSS配置
export function ossConfigRemove(ossConfigIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${ossConfigIds}`);
}
// 更改OSS配置的状态
export function ossConfigChangeStatus(data: any) {
return requestClient.putWithMsg(Api.ossConfigChangeStatus, data);
}

View File

@ -0,0 +1,16 @@
export interface OssConfig {
ossConfigId: number;
configKey: string;
accessKey: string;
secretKey: string;
bucketName: string;
prefix: string;
endpoint: string;
domain: string;
isHttps: string;
region: string;
status: string;
ext1: string;
remark: string;
accessPolicy: string;
}

View File

@ -33,6 +33,30 @@ const profileRoute: RouteRecordStringComponent[] = [
},
],
},
{
component: 'BasicLayout',
meta: {
hideChildrenInMenu: true,
hideInMenu: true,
title: 'oss配置',
},
name: 'OssConfig',
path: '/',
redirect: '/system/oss-config',
children: [
{
component: '/system/oss-config/index',
meta: {
activePath: '/system/oss',
icon: 'mingcute:profile-line',
keepAlive: true,
title: 'oss配置',
},
name: 'OssConfigIndex',
path: '/system/oss-config',
},
],
},
];
/**

View File

@ -0,0 +1,173 @@
import { DictEnum } from '@vben/constants';
import { type FormSchemaGetter, z } from '#/adapter';
import { getDictOptions } from '#/utils/dict';
const accessPolicyOptions = [
{ color: 'orange', label: '私有', value: '0' },
{ color: 'green', label: '公开', value: '1' },
{ color: 'blue', label: '自定义', value: '2' },
];
export const drawerSchema: FormSchemaGetter = () => [
{
component: 'Input',
dependencies: {
show: () => false,
triggerFields: [''],
},
fieldName: 'ossConfigId',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider1',
labelClass: 'w-0',
renderComponentContent: () => ({
default: () => '基本信息',
}),
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'configKey',
label: '配置名称',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'endpoint',
label: '服务地址',
renderComponentContent: (formModel) => ({
addonBefore: () => (formModel.isHttps === 'Y' ? 'https://' : 'http://'),
}),
rules: z
.string({ message: '请输入服务地址' })
.refine(
(domain) =>
!(domain.startsWith('http://') || domain.startsWith('https://')),
{ message: '请输入正确的域名, 不需要http(s)' },
),
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'domain',
label: '自定义域名',
rules: z
.string()
.refine(
(domain) =>
!(domain.startsWith('http://') || domain.startsWith('https://')),
{ message: '请输入正确的域名, 不需要http(s)' },
)
.optional(),
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider2',
labelClass: 'w-0',
renderComponentContent: () => ({
default: () => '认证信息',
}),
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'accessKey',
label: 'accessKey',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'secretKey',
label: 'secretKey',
rules: 'required',
},
{
component: 'Divider',
componentProps: {
orientation: 'center',
},
fieldName: 'divider3',
labelClass: 'w-0',
renderComponentContent: () => ({
default: () => '其他信息',
}),
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'bucketName',
label: '桶名称',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'prefix',
label: '前缀',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
options: accessPolicyOptions,
optionType: 'button',
},
defaultValue: '0',
fieldName: 'accessPolicy',
formItemClass: 'col-span-3 lg:col-span-2',
label: '权限桶类型',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
options: getDictOptions(DictEnum.SYS_YES_NO),
optionType: 'button',
},
defaultValue: 'N',
fieldName: 'isHttps',
formItemClass: 'col-span-3 lg:col-span-1',
label: '是否https',
rules: 'required',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入',
},
fieldName: 'region',
label: '区域',
},
{
component: 'Textarea',
componentProps: {
placeholder: '请输入',
},
fieldName: 'remark',
label: '备注',
},
];

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
import { Page, useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import ossConfigDrawer from './oss-config-drawer.vue';
const [OssConfigDrawer, drawerApi] = useVbenDrawer({
connectedComponent: ossConfigDrawer,
});
function handleAdd() {
drawerApi.setData({ update: false });
drawerApi.open();
}
</script>
<template>
<Page>
<a-button type="primary" @click="handleAdd">
{{ $t('pages.common.add') }}
</a-button>
<OssConfigDrawer />
</Page>
</template>

View File

@ -0,0 +1,88 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '#/adapter';
import { ossConfigAdd, ossConfigUpdate } from '#/api/system/oss-config';
import { drawerSchema } from './data';
const emit = defineEmits<{ reload: [] }>();
interface DrawerProps {
update: boolean;
record?: any;
}
const isUpdate = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
formItemClass: 'col-span-3',
labelWidth: 100,
},
schema: drawerSchema(),
showDefaultActions: false,
wrapperClass: 'grid-cols-3',
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
onCancel: handleCancel,
onConfirm: handleConfirm,
async onOpenChange(isOpen) {
if (!isOpen) {
return null;
}
drawerApi.drawerLoading(true);
const { record, update } = drawerApi.getData() as DrawerProps;
isUpdate.value = update;
if (update && record) {
for (const key in record) {
await formApi.setFieldValue(key, record[key]);
}
}
drawerApi.drawerLoading(false);
},
});
async function handleConfirm() {
try {
drawerApi.drawerLoading(true);
const { valid } = await formApi.validate();
if (!valid) {
return;
}
const data = await formApi.getValues();
console.log(data);
await (isUpdate.value ? ossConfigUpdate(data) : ossConfigAdd(data));
emit('reload');
await handleCancel();
} catch (error) {
console.error(error);
} finally {
drawerApi.drawerLoading(false);
}
}
async function handleCancel() {
drawerApi.close();
await formApi.resetForm();
}
</script>
<template>
<BasicDrawer :title="title" class="w-[650px]">
<BasicForm />
</BasicDrawer>
</template>
<style lang="scss" scoped>
:deep(.ant-divider) {
margin: 8px 0;
}
</style>

View File

@ -1,9 +1,13 @@
<script setup lang="ts">
import CommonSkeleton from '#/views/common';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
const router = useRouter();
</script>
<template>
<div>
<CommonSkeleton />
</div>
<Page>
<a-button @click="() => router.push('/system/oss-config')">配置</a-button>
</Page>
</template>