From 1d42b4b69cf9d5f0ac70442345ad52d2b1964eda Mon Sep 17 00:00:00 2001 From: Ryan SU Date: Sat, 2 Sep 2023 10:09:36 +0000 Subject: [PATCH 1/5] refactor: fms tag pages --- src/api/fms/{tag.ts => fileTag.ts} | 12 ++++++------ src/api/fms/model/{tagModel.ts => fileTagModel.ts} | 0 src/views/fms/file/file.data.ts | 2 +- src/views/fms/{tag => fileTag}/TagDrawer.vue | 2 +- src/views/fms/{tag => fileTag}/index.vue | 2 +- src/views/fms/{tag => fileTag}/tag.data.ts | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename src/api/fms/{tag.ts => fileTag.ts} (85%) rename src/api/fms/model/{tagModel.ts => fileTagModel.ts} (100%) rename src/views/fms/{tag => fileTag}/TagDrawer.vue (97%) rename src/views/fms/{tag => fileTag}/index.vue (98%) rename src/views/fms/{tag => fileTag}/tag.data.ts (97%) diff --git a/src/api/fms/tag.ts b/src/api/fms/fileTag.ts similarity index 85% rename from src/api/fms/tag.ts rename to src/api/fms/fileTag.ts index 2d2cca81..814bae15 100644 --- a/src/api/fms/tag.ts +++ b/src/api/fms/fileTag.ts @@ -1,14 +1,14 @@ import { defHttp } from '/@/utils/http/axios'; import { ErrorMessageMode } from '/#/axios'; import { BaseDataResp, BaseListReq, BaseResp, BaseIDsReq, BaseIDReq } from '/@/api/model/baseModel'; -import { TagInfo, TagListResp } from './model/tagModel'; +import { TagInfo, TagListResp } from './model/fileTagModel'; enum Api { - CreateTag = '/fms-api/tag/create', - UpdateTag = '/fms-api/tag/update', - GetTagList = '/fms-api/tag/list', - DeleteTag = '/fms-api/tag/delete', - GetTagById = '/fms-api/tag', + CreateTag = '/fms-api/file_tag/create', + UpdateTag = '/fms-api/file_tag/update', + GetTagList = '/fms-api/file_tag/list', + DeleteTag = '/fms-api/file_tag/delete', + GetTagById = '/fms-api/file_tag', } /** diff --git a/src/api/fms/model/tagModel.ts b/src/api/fms/model/fileTagModel.ts similarity index 100% rename from src/api/fms/model/tagModel.ts rename to src/api/fms/model/fileTagModel.ts diff --git a/src/views/fms/file/file.data.ts b/src/views/fms/file/file.data.ts index 326fa7c0..86eef9e7 100644 --- a/src/views/fms/file/file.data.ts +++ b/src/views/fms/file/file.data.ts @@ -4,7 +4,7 @@ import { setFileStatus } from '/@/api/fms/file'; import { BasicColumn, FormSchema } from '/@/components/Table'; import { useI18n } from '/@/hooks/web/useI18n'; import { formatToDateTime } from '/@/utils/dateUtil'; -import { getTagList } from '/@/api/fms/tag'; +import { getTagList } from '../../../api/fms/fileTag'; const { t } = useI18n(); diff --git a/src/views/fms/tag/TagDrawer.vue b/src/views/fms/fileTag/TagDrawer.vue similarity index 97% rename from src/views/fms/tag/TagDrawer.vue rename to src/views/fms/fileTag/TagDrawer.vue index 71c39f3a..f534fbd3 100644 --- a/src/views/fms/tag/TagDrawer.vue +++ b/src/views/fms/fileTag/TagDrawer.vue @@ -17,7 +17,7 @@ import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; import { useI18n } from 'vue-i18n'; - import { createTag, updateTag } from '/@/api/fms/tag'; + import { createTag, updateTag } from '/@/api/fms/fileTag'; export default defineComponent({ name: 'TagDrawer', diff --git a/src/views/fms/tag/index.vue b/src/views/fms/fileTag/index.vue similarity index 98% rename from src/views/fms/tag/index.vue rename to src/views/fms/fileTag/index.vue index 7efecd96..3db06488 100644 --- a/src/views/fms/tag/index.vue +++ b/src/views/fms/fileTag/index.vue @@ -54,7 +54,7 @@ import { useI18n } from 'vue-i18n'; import { columns, searchFormSchema } from './tag.data'; - import { getTagList, deleteTag } from '/@/api/fms/tag'; + import { getTagList, deleteTag } from '/@/api/fms/fileTag'; export default defineComponent({ name: 'TagManagement', diff --git a/src/views/fms/tag/tag.data.ts b/src/views/fms/fileTag/tag.data.ts similarity index 97% rename from src/views/fms/tag/tag.data.ts rename to src/views/fms/fileTag/tag.data.ts index 06ba0afc..0bf4e858 100644 --- a/src/views/fms/tag/tag.data.ts +++ b/src/views/fms/fileTag/tag.data.ts @@ -1,7 +1,7 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; import { useI18n } from '/@/hooks/web/useI18n'; import { formatToDateTime } from '/@/utils/dateUtil'; -import { updateTag } from '/@/api/fms/tag'; +import { updateTag } from '../../../api/fms/fileTag'; import { Switch } from 'ant-design-vue'; import { h } from 'vue'; From 2d4ef07f72532f1bb7016f7102d5a310972d2aab Mon Sep 17 00:00:00 2001 From: Ryan SU Date: Sun, 3 Sep 2023 05:21:01 +0000 Subject: [PATCH 2/5] feat: cloud file and storage provider --- src/api/fms/cloudFile.ts | 99 ++++++ src/api/fms/model/cloudFileModel.ts | 23 ++ src/api/fms/model/storageProviderModel.ts | 24 ++ src/api/fms/storageProvider.ts | 74 +++++ src/locales/lang/en/fms.ts | 25 ++ src/locales/lang/zh-CN/fms.ts | 25 ++ src/views/fms/cloudFile/CloudFileDrawer.vue | 76 +++++ src/views/fms/cloudFile/cloudFile.data.ts | 165 ++++++++++ src/views/fms/cloudFile/index.vue | 307 ++++++++++++++++++ .../storageProvider/StorageProviderDrawer.vue | 74 +++++ src/views/fms/storageProvider/index.vue | 151 +++++++++ .../storageProvider/storageProvider.data.ts | 141 ++++++++ 12 files changed, 1184 insertions(+) create mode 100644 src/api/fms/cloudFile.ts create mode 100644 src/api/fms/model/cloudFileModel.ts create mode 100644 src/api/fms/model/storageProviderModel.ts create mode 100644 src/api/fms/storageProvider.ts create mode 100644 src/views/fms/cloudFile/CloudFileDrawer.vue create mode 100644 src/views/fms/cloudFile/cloudFile.data.ts create mode 100644 src/views/fms/cloudFile/index.vue create mode 100644 src/views/fms/storageProvider/StorageProviderDrawer.vue create mode 100644 src/views/fms/storageProvider/index.vue create mode 100644 src/views/fms/storageProvider/storageProvider.data.ts diff --git a/src/api/fms/cloudFile.ts b/src/api/fms/cloudFile.ts new file mode 100644 index 00000000..2c3342aa --- /dev/null +++ b/src/api/fms/cloudFile.ts @@ -0,0 +1,99 @@ +import { defHttp } from '/@/utils/http/axios'; +import { ErrorMessageMode, UploadFileParams } from '/#/axios'; +import { + BaseDataResp, + BaseListReq, + BaseResp, + BaseUUIDsReq, + BaseUUIDReq, +} from '/@/api/model/baseModel'; +import { CloudFileInfo, CloudFileListResp } from './model/cloudFileModel'; +import { AxiosProgressEvent } from 'axios'; +import { UploadApiResp } from '../sys/model/uploadModel'; + +enum Api { + CreateCloudFile = '/fms-api/cloud_file/create', + UpdateCloudFile = '/fms-api/cloud_file/update', + GetCloudFileList = '/fms-api/cloud_file/list', + DeleteCloudFile = '/fms-api/cloud_file/delete', + GetCloudFileById = '/fms-api/cloud_file', + uploadFile = '/fms-api/cloud_file/upload', +} + +/** + * @description: Get cloud file list + */ + +export const getCloudFileList = (params: BaseListReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetCloudFileList, params }, + { errorMessageMode: mode }, + ); +}; + +/** + * @description: Create a new cloud file + */ +export const createCloudFile = (params: CloudFileInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.CreateCloudFile, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Update the cloud file + */ +export const updateCloudFile = (params: CloudFileInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.UpdateCloudFile, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Delete cloud files + */ +export const deleteCloudFile = (params: BaseUUIDsReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.DeleteCloudFile, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Get cloud file By ID + */ +export const getCloudFileById = (params: BaseUUIDReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetCloudFileById, params: params }, + { + errorMessageMode: mode, + }, + ); +}; + +/** + * @description: Upload interface + */ +export function uploadApi( + params: UploadFileParams, + onUploadProgress: (progressEvent: AxiosProgressEvent) => void, +) { + return defHttp.uploadFile>( + { + url: Api.uploadFile, + onUploadProgress, + }, + params, + ); +} diff --git a/src/api/fms/model/cloudFileModel.ts b/src/api/fms/model/cloudFileModel.ts new file mode 100644 index 00000000..035374d3 --- /dev/null +++ b/src/api/fms/model/cloudFileModel.ts @@ -0,0 +1,23 @@ +import { BaseListResp } from '/@/api/model/baseModel'; + +/** + * @description: CloudFile info response + */ +export interface CloudFileInfo { + id: string; + createdAt?: number; + updatedAt?: number; + state?: boolean; + name?: string; + url?: string; + size?: number; + fileType?: number; + userId?: string; + providerId?: number; +} + +/** + * @description: CloudFile list response + */ + +export type CloudFileListResp = BaseListResp; diff --git a/src/api/fms/model/storageProviderModel.ts b/src/api/fms/model/storageProviderModel.ts new file mode 100644 index 00000000..1ba3856f --- /dev/null +++ b/src/api/fms/model/storageProviderModel.ts @@ -0,0 +1,24 @@ +import { BaseListResp } from '/@/api/model/baseModel'; + +/** + * @description: StorageProvider info response + */ +export interface StorageProviderInfo { + id: number; + createdAt?: number; + updatedAt?: number; + state?: boolean; + name?: string; + bucket?: string; + providerName?: string; + secretId?: string; + secretKey?: string; + region?: string; + isDefault?: boolean; +} + +/** + * @description: StorageProvider list response + */ + +export type StorageProviderListResp = BaseListResp; diff --git a/src/api/fms/storageProvider.ts b/src/api/fms/storageProvider.ts new file mode 100644 index 00000000..4e0491cd --- /dev/null +++ b/src/api/fms/storageProvider.ts @@ -0,0 +1,74 @@ +import { defHttp } from '/@/utils/http/axios'; +import { ErrorMessageMode } from '/#/axios'; +import { BaseDataResp, BaseListReq, BaseResp, BaseIDsReq, BaseIDReq } from '/@/api/model/baseModel'; +import { StorageProviderInfo, StorageProviderListResp } from './model/storageProviderModel'; + +enum Api { + CreateStorageProvider = '/fms-api/storage_provider/create', + UpdateStorageProvider = '/fms-api/storage_provider/update', + GetStorageProviderList = '/fms-api/storage_provider/list', + DeleteStorageProvider = '/fms-api/storage_provider/delete', + GetStorageProviderById = '/fms-api/storage_provider', +} + +/** + * @description: Get storage provider list + */ + +export const getStorageProviderList = (params: BaseListReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetStorageProviderList, params }, + { errorMessageMode: mode }, + ); +}; + +/** + * @description: Create a new storage provider + */ +export const createStorageProvider = (params: StorageProviderInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.CreateStorageProvider, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Update the storage provider + */ +export const updateStorageProvider = (params: StorageProviderInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.UpdateStorageProvider, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Delete storage providers + */ +export const deleteStorageProvider = (params: BaseIDsReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.DeleteStorageProvider, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Get storage provider By ID + */ +export const getStorageProviderById = (params: BaseIDReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetStorageProviderById, params: params }, + { + errorMessageMode: mode, + }, + ); +}; diff --git a/src/locales/lang/en/fms.ts b/src/locales/lang/en/fms.ts index 541a63da..84da2487 100644 --- a/src/locales/lang/en/fms.ts +++ b/src/locales/lang/en/fms.ts @@ -34,4 +34,29 @@ export default { editTag: 'Edit Tag', tagList: 'Tag List', }, + storageProvider: { + state: 'State', + name: 'Name', + bucket: 'Bucket', + providerName: 'Provider Name', + secretId: 'Secret ID', + secretKey: 'Secret Key', + region: 'Region', + isDefault: 'Is Default', + addStorageProvider: 'Add Storage Provider', + editStorageProvider: 'Edit Storage Provider', + storageProviderList: 'Storage Provider List', + }, + cloudFile: { + state: 'State', + name: 'Name', + url: 'Url', + size: 'Size', + fileType: 'File Type', + userId: 'User ID', + providerId: 'Storage Provider', + addCloudFile: 'Add Cloud File', + editCloudFile: 'Edit Cloud File', + cloudFileList: 'Cloud File List', + }, }; diff --git a/src/locales/lang/zh-CN/fms.ts b/src/locales/lang/zh-CN/fms.ts index 026d795c..0deff448 100644 --- a/src/locales/lang/zh-CN/fms.ts +++ b/src/locales/lang/zh-CN/fms.ts @@ -34,4 +34,29 @@ export default { editTag: '编辑标签', tagList: '标签列表', }, + storageProvider: { + state: '状态', + name: '名称', + bucket: '存储桶', + providerName: '提供商名称', + secretId: 'Secret Id', + secretKey: 'Secret Key', + region: '地区', + isDefault: '是否为默认', + addStorageProvider: '添加云存储提供商', + editStorageProvider: '编辑云存储提供商', + storageProviderList: '云存储提供商列表', + }, + cloudFile: { + state: '状态', + name: '文件名', + url: '地址', + size: '文件大小', + fileType: '文件类型', + userId: '用户 ID', + providerId: '云服务提供商', + addCloudFile: '添加云文件', + editCloudFile: '编辑云文件', + cloudFileList: '云文件列表', + }, }; diff --git a/src/views/fms/cloudFile/CloudFileDrawer.vue b/src/views/fms/cloudFile/CloudFileDrawer.vue new file mode 100644 index 00000000..141ef5ef --- /dev/null +++ b/src/views/fms/cloudFile/CloudFileDrawer.vue @@ -0,0 +1,76 @@ + + diff --git a/src/views/fms/cloudFile/cloudFile.data.ts b/src/views/fms/cloudFile/cloudFile.data.ts new file mode 100644 index 00000000..35110ec9 --- /dev/null +++ b/src/views/fms/cloudFile/cloudFile.data.ts @@ -0,0 +1,165 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { formatToDateTime } from '/@/utils/dateUtil'; +import { updateCloudFile } from '/@/api/fms/cloudFile'; +import { Switch } from 'ant-design-vue'; +import { h } from 'vue'; +import { getStorageProviderList } from '/@/api/fms/storageProvider'; +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: t('fms.cloudFile.name'), + dataIndex: 'name', + width: 50, + }, + { + title: t('fms.cloudFile.size'), + dataIndex: 'size', + width: 30, + customRender: ({ record }) => { + if (record.size > 1073741824) { + return (record.size / 1073741824).toFixed(2) + 'GB'; + } else if (record.size > 1048576) { + return (record.size / 1048576).toFixed(2) + 'MB'; + } else { + return (record.size / 1024).toFixed(2) + 'KB'; + } + }, + }, + { + title: t('fms.cloudFile.fileType'), + dataIndex: 'fileType', + width: 20, + customRender: ({ record }) => { + if (record.fileType === 3) { + return t('fms.file.video'); + } else if (record.fileType === 4) { + return t('fms.file.audio'); + } else if (record.fileType === 2) { + return t('fms.file.image'); + } else { + return t('fms.file.other'); + } + }, + }, + { + title: t('common.status'), + dataIndex: 'state', + width: 20, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.state === true, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + record.pendingStatus = true; + const newState = checked ? true : false; + updateCloudFile({ id: record.id, state: newState }) + .then(() => { + record.state = newState; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + }, + }, + { + title: t('common.createTime'), + dataIndex: 'createdAt', + width: 30, + customRender: ({ record }) => { + return formatToDateTime(record.createdAt); + }, + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'name', + label: t('fms.cloudFile.name'), + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'userId', + label: t('fms.cloudFile.userId'), + component: 'Input', + colProps: { span: 8 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: 'ID', + component: 'Input', + show: false, + }, + + { + field: 'name', + label: t('fms.cloudFile.name'), + component: 'Input', + required: true, + }, + { + field: 'url', + label: t('fms.cloudFile.url'), + component: 'Input', + required: true, + }, + { + field: 'size', + label: t('fms.cloudFile.size'), + component: 'InputNumber', + required: true, + }, + { + field: 'fileType', + label: t('fms.cloudFile.fileType'), + component: 'InputNumber', + required: true, + }, + { + field: 'userId', + label: t('fms.cloudFile.userId'), + component: 'Input', + required: true, + }, + { + field: 'providerId', + label: t('fms.cloudFile.providerId'), + component: 'ApiSelect', + required: true, + defaultValue: 1, + componentProps: { + api: getStorageProviderList, + params: { + page: 1, + pageSize: 1000, + }, + resultField: 'data.data', + labelField: 'name', + valueField: 'id', + }, + }, + { + field: 'state', + label: t('fms.cloudFile.state'), + component: 'RadioButtonGroup', + defaultValue: true, + componentProps: { + options: [ + { label: t('common.on'), value: true }, + { label: t('common.off'), value: false }, + ], + }, + }, +]; diff --git a/src/views/fms/cloudFile/index.vue b/src/views/fms/cloudFile/index.vue new file mode 100644 index 00000000..5654bb11 --- /dev/null +++ b/src/views/fms/cloudFile/index.vue @@ -0,0 +1,307 @@ + + diff --git a/src/views/fms/storageProvider/StorageProviderDrawer.vue b/src/views/fms/storageProvider/StorageProviderDrawer.vue new file mode 100644 index 00000000..40016fcb --- /dev/null +++ b/src/views/fms/storageProvider/StorageProviderDrawer.vue @@ -0,0 +1,74 @@ + + diff --git a/src/views/fms/storageProvider/index.vue b/src/views/fms/storageProvider/index.vue new file mode 100644 index 00000000..25f02a44 --- /dev/null +++ b/src/views/fms/storageProvider/index.vue @@ -0,0 +1,151 @@ + + diff --git a/src/views/fms/storageProvider/storageProvider.data.ts b/src/views/fms/storageProvider/storageProvider.data.ts new file mode 100644 index 00000000..3f6d8810 --- /dev/null +++ b/src/views/fms/storageProvider/storageProvider.data.ts @@ -0,0 +1,141 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { formatToDateTime } from '/@/utils/dateUtil'; +import { updateStorageProvider } from '/@/api/fms/storageProvider'; +import { Switch } from 'ant-design-vue'; +import { h } from 'vue'; +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: t('fms.storageProvider.name'), + dataIndex: 'name', + width: 100, + }, + { + title: t('fms.storageProvider.isDefault'), + dataIndex: 'isDefault', + width: 100, + }, + { + title: t('common.status'), + dataIndex: 'state', + width: 50, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.state === true, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + record.pendingStatus = true; + const newState = checked ? true : false; + updateStorageProvider({ id: record.id, state: newState }) + .then(() => { + record.state = newState; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + }, + }, + { + title: t('common.createTime'), + dataIndex: 'createdAt', + width: 70, + customRender: ({ record }) => { + return formatToDateTime(record.createdAt); + }, + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'name', + label: t('fms.storageProvider.name'), + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'providerName', + label: t('fms.storageProvider.providerName'), + component: 'Input', + colProps: { span: 8 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: 'ID', + component: 'Input', + show: false, + }, + + { + field: 'name', + label: t('fms.storageProvider.name'), + component: 'Input', + required: true, + }, + { + field: 'bucket', + label: t('fms.storageProvider.bucket'), + component: 'Input', + required: true, + }, + { + field: 'providerName', + label: t('fms.storageProvider.providerName'), + component: 'Input', + required: true, + }, + { + field: 'secretId', + label: t('fms.storageProvider.secretId'), + component: 'Input', + required: true, + }, + { + field: 'secretKey', + label: t('fms.storageProvider.secretKey'), + component: 'Input', + required: true, + }, + { + field: 'region', + label: t('fms.storageProvider.region'), + component: 'Input', + required: true, + }, + { + field: 'isDefault', + label: t('fms.storageProvider.isDefault'), + component: 'RadioButtonGroup', + defaultValue: false, + componentProps: { + options: [ + { label: t('common.on'), value: false }, + { label: t('common.off'), value: true }, + ], + }, + required: true, + }, + { + field: 'state', + label: t('fms.storageProvider.state'), + component: 'RadioButtonGroup', + defaultValue: true, + componentProps: { + options: [ + { label: t('common.on'), value: true }, + { label: t('common.off'), value: false }, + ], + }, + }, +]; From 0f0f628891f52c9f4af3d49ed38558016a2c3d78 Mon Sep 17 00:00:00 2001 From: Ryan SU Date: Sun, 3 Sep 2023 08:51:19 +0000 Subject: [PATCH 3/5] feat: cloud file tag --- src/api/fms/cloudFileTag.ts | 74 +++++++++ src/api/fms/model/cloudFileModel.ts | 1 + src/api/fms/model/cloudFileTagModel.ts | 19 +++ src/api/fms/model/storageProviderModel.ts | 1 + src/locales/lang/en/fms.ts | 12 ++ src/locales/lang/zh-CN/fms.ts | 12 ++ .../fms/cloudFileTag/CloudFileTagDrawer.vue | 78 +++++++++ .../fms/cloudFileTag/cloudFileTag.data.ts | 104 ++++++++++++ src/views/fms/cloudFileTag/index.vue | 151 ++++++++++++++++++ .../storageProvider/StorageProviderDrawer.vue | 10 +- .../storageProvider/storageProvider.data.ts | 47 +++++- 11 files changed, 501 insertions(+), 8 deletions(-) create mode 100644 src/api/fms/cloudFileTag.ts create mode 100644 src/api/fms/model/cloudFileTagModel.ts create mode 100644 src/views/fms/cloudFileTag/CloudFileTagDrawer.vue create mode 100644 src/views/fms/cloudFileTag/cloudFileTag.data.ts create mode 100644 src/views/fms/cloudFileTag/index.vue diff --git a/src/api/fms/cloudFileTag.ts b/src/api/fms/cloudFileTag.ts new file mode 100644 index 00000000..658485b6 --- /dev/null +++ b/src/api/fms/cloudFileTag.ts @@ -0,0 +1,74 @@ +import { defHttp } from '/@/utils/http/axios'; +import { ErrorMessageMode } from '/#/axios'; +import { BaseDataResp, BaseListReq, BaseResp, BaseIDsReq, BaseIDReq } from '/@/api/model/baseModel'; +import { CloudFileTagInfo, CloudFileTagListResp } from './model/cloudFileTagModel'; + +enum Api { + CreateCloudFileTag = '/fms-api/cloud_file_tag/create', + UpdateCloudFileTag = '/fms-api/cloud_file_tag/update', + GetCloudFileTagList = '/fms-api/cloud_file_tag/list', + DeleteCloudFileTag = '/fms-api/cloud_file_tag/delete', + GetCloudFileTagById = '/fms-api/cloud_file_tag', +} + +/** + * @description: Get cloud file tag list + */ + +export const getCloudFileTagList = (params: BaseListReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetCloudFileTagList, params }, + { errorMessageMode: mode }, + ); +}; + +/** + * @description: Create a new cloud file tag + */ +export const createCloudFileTag = (params: CloudFileTagInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.CreateCloudFileTag, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Update the cloud file tag + */ +export const updateCloudFileTag = (params: CloudFileTagInfo, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.UpdateCloudFileTag, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Delete cloud file tags + */ +export const deleteCloudFileTag = (params: BaseIDsReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post( + { url: Api.DeleteCloudFileTag, params: params }, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +}; + +/** + * @description: Get cloud file tag By ID + */ +export const getCloudFileTagById = (params: BaseIDReq, mode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + { url: Api.GetCloudFileTagById, params: params }, + { + errorMessageMode: mode, + }, + ); +}; diff --git a/src/api/fms/model/cloudFileModel.ts b/src/api/fms/model/cloudFileModel.ts index 035374d3..03a57646 100644 --- a/src/api/fms/model/cloudFileModel.ts +++ b/src/api/fms/model/cloudFileModel.ts @@ -14,6 +14,7 @@ export interface CloudFileInfo { fileType?: number; userId?: string; providerId?: number; + tagIds?: number[]; } /** diff --git a/src/api/fms/model/cloudFileTagModel.ts b/src/api/fms/model/cloudFileTagModel.ts new file mode 100644 index 00000000..885214d6 --- /dev/null +++ b/src/api/fms/model/cloudFileTagModel.ts @@ -0,0 +1,19 @@ +import { BaseListResp } from '/@/api/model/baseModel'; + +/** + * @description: CloudFileTag info response + */ +export interface CloudFileTagInfo { + id: number; + createdAt?: number; + updatedAt?: number; + status?: number; + name?: string; + remark?: string; +} + +/** + * @description: CloudFileTag list response + */ + +export type CloudFileTagListResp = BaseListResp; diff --git a/src/api/fms/model/storageProviderModel.ts b/src/api/fms/model/storageProviderModel.ts index 1ba3856f..9b397773 100644 --- a/src/api/fms/model/storageProviderModel.ts +++ b/src/api/fms/model/storageProviderModel.ts @@ -13,6 +13,7 @@ export interface StorageProviderInfo { providerName?: string; secretId?: string; secretKey?: string; + folder?: string; region?: string; isDefault?: boolean; } diff --git a/src/locales/lang/en/fms.ts b/src/locales/lang/en/fms.ts index 84da2487..0795270b 100644 --- a/src/locales/lang/en/fms.ts +++ b/src/locales/lang/en/fms.ts @@ -41,11 +41,15 @@ export default { providerName: 'Provider Name', secretId: 'Secret ID', secretKey: 'Secret Key', + folder: 'Folder in cloud', region: 'Region', isDefault: 'Is Default', addStorageProvider: 'Add Storage Provider', editStorageProvider: 'Edit Storage Provider', storageProviderList: 'Storage Provider List', + // help message + nameHelpMessage: 'Make sure that prefix with provider type, such as "tencent-" , "aliyun-"', + folderHelpMessage: 'Sub folder in cloud, can be empty. Prefix with "/", such as "/test"', }, cloudFile: { state: 'State', @@ -59,4 +63,12 @@ export default { editCloudFile: 'Edit Cloud File', cloudFileList: 'Cloud File List', }, + cloudFileTag: { + status: 'Status', + name: 'Name', + remark: 'Remark', + addCloudFileTag: "Add Cloud File's Tag", + editCloudFileTag: "Edit Cloud File's Tag", + cloudFileTagList: "Cloud File's Tag List", + }, }; diff --git a/src/locales/lang/zh-CN/fms.ts b/src/locales/lang/zh-CN/fms.ts index 0deff448..e1ec8e06 100644 --- a/src/locales/lang/zh-CN/fms.ts +++ b/src/locales/lang/zh-CN/fms.ts @@ -41,11 +41,15 @@ export default { providerName: '提供商名称', secretId: 'Secret Id', secretKey: 'Secret Key', + folder: '云服务文件夹', region: '地区', isDefault: '是否为默认', addStorageProvider: '添加云存储提供商', editStorageProvider: '编辑云存储提供商', storageProviderList: '云存储提供商列表', + // help message + nameHelpMessage: '注意名称必须由提供商开头如 tencent- , aliyun-', + folderHelpMessage: '云服务的子文件夹, 可为空, 以 / 开头, 如 /test', }, cloudFile: { state: '状态', @@ -59,4 +63,12 @@ export default { editCloudFile: '编辑云文件', cloudFileList: '云文件列表', }, + cloudFileTag: { + status: '状态', + name: '标签名称', + remark: '备注', + addCloudFileTag: '添加云文件标签', + editCloudFileTag: '编辑云文件标签', + cloudFileTagList: '云文件标签列表', + }, }; diff --git a/src/views/fms/cloudFileTag/CloudFileTagDrawer.vue b/src/views/fms/cloudFileTag/CloudFileTagDrawer.vue new file mode 100644 index 00000000..93e637ea --- /dev/null +++ b/src/views/fms/cloudFileTag/CloudFileTagDrawer.vue @@ -0,0 +1,78 @@ + + diff --git a/src/views/fms/cloudFileTag/cloudFileTag.data.ts b/src/views/fms/cloudFileTag/cloudFileTag.data.ts new file mode 100644 index 00000000..c1259197 --- /dev/null +++ b/src/views/fms/cloudFileTag/cloudFileTag.data.ts @@ -0,0 +1,104 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { formatToDateTime } from '/@/utils/dateUtil'; +import { updateCloudFileTag } from '/@/api/fms/cloudFileTag'; +import { Switch } from 'ant-design-vue'; +import { h } from 'vue'; +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: t('fms.cloudFileTag.name'), + dataIndex: 'name', + width: 50, + }, + { + title: t('fms.cloudFileTag.remark'), + dataIndex: 'remark', + width: 50, + }, + { + title: t('common.status'), + dataIndex: 'status', + width: 20, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 1, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + record.pendingStatus = true; + const newStatus = checked ? 1 : 2; + updateCloudFileTag({ id: record.id, status: newStatus }) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + }, + }, + { + title: t('common.createTime'), + dataIndex: 'createdAt', + width: 30, + customRender: ({ record }) => { + return formatToDateTime(record.createdAt); + }, + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'name', + label: t('fms.cloudFileTag.name'), + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'remark', + label: t('fms.cloudFileTag.remark'), + component: 'Input', + colProps: { span: 8 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: 'ID', + component: 'Input', + show: false, + }, + + { + field: 'name', + label: t('fms.cloudFileTag.name'), + component: 'Input', + required: true, + }, + { + field: 'remark', + label: t('fms.cloudFileTag.remark'), + component: 'Input', + required: true, + }, + { + field: 'status', + label: t('fms.cloudFileTag.status'), + component: 'RadioButtonGroup', + defaultValue: 1, + componentProps: { + options: [ + { label: t('common.on'), value: 1 }, + { label: t('common.off'), value: 2 }, + ], + }, + }, +]; diff --git a/src/views/fms/cloudFileTag/index.vue b/src/views/fms/cloudFileTag/index.vue new file mode 100644 index 00000000..38caef8f --- /dev/null +++ b/src/views/fms/cloudFileTag/index.vue @@ -0,0 +1,151 @@ + + diff --git a/src/views/fms/storageProvider/StorageProviderDrawer.vue b/src/views/fms/storageProvider/StorageProviderDrawer.vue index 40016fcb..ed709180 100644 --- a/src/views/fms/storageProvider/StorageProviderDrawer.vue +++ b/src/views/fms/storageProvider/StorageProviderDrawer.vue @@ -28,7 +28,7 @@ const { t } = useI18n(); const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({ - labelWidth: 90, + labelWidth: 110, baseColProps: { span: 24 }, schemas: formSchema, showActionButtonGroup: false, @@ -48,14 +48,18 @@ }); const getTitle = computed(() => - !unref(isUpdate) ? t('fms.storageProvider.addStorageProvider') : t('fms.storageProvider.editStorageProvider'), + !unref(isUpdate) + ? t('fms.storageProvider.addStorageProvider') + : t('fms.storageProvider.editStorageProvider'), ); async function handleSubmit() { const values = await validate(); setDrawerProps({ confirmLoading: true }); values['id'] = unref(isUpdate) ? Number(values['id']) : 0; - let result = unref(isUpdate) ? await updateStorageProvider(values) : await createStorageProvider(values); + let result = unref(isUpdate) + ? await updateStorageProvider(values) + : await createStorageProvider(values); if (result.code === 0) { closeDrawer(); emit('success'); diff --git a/src/views/fms/storageProvider/storageProvider.data.ts b/src/views/fms/storageProvider/storageProvider.data.ts index 3f6d8810..7b504779 100644 --- a/src/views/fms/storageProvider/storageProvider.data.ts +++ b/src/views/fms/storageProvider/storageProvider.data.ts @@ -4,23 +4,47 @@ import { formatToDateTime } from '/@/utils/dateUtil'; import { updateStorageProvider } from '/@/api/fms/storageProvider'; import { Switch } from 'ant-design-vue'; import { h } from 'vue'; +import { useRedo } from '/@/hooks/web/usePage'; const { t } = useI18n(); export const columns: BasicColumn[] = [ { title: t('fms.storageProvider.name'), dataIndex: 'name', - width: 100, + width: 50, }, { title: t('fms.storageProvider.isDefault'), dataIndex: 'isDefault', - width: 100, + width: 20, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.isDefault === true, + checkedChildren: t('common.yes'), + unCheckedChildren: t('common.no'), + loading: record.pendingStatus, + onChange(checked, _) { + record.pendingStatus = true; + updateStorageProvider({ id: record.id, isDefault: checked as boolean }) + .then(() => { + record.isDefault = checked; + const redo = useRedo(); + redo(); + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + }, }, { title: t('common.status'), dataIndex: 'state', - width: 50, + width: 20, customRender: ({ record }) => { if (!Reflect.has(record, 'pendingStatus')) { record.pendingStatus = false; @@ -47,7 +71,7 @@ export const columns: BasicColumn[] = [ { title: t('common.createTime'), dataIndex: 'createdAt', - width: 70, + width: 30, customRender: ({ record }) => { return formatToDateTime(record.createdAt); }, @@ -82,6 +106,7 @@ export const formSchema: FormSchema[] = [ label: t('fms.storageProvider.name'), component: 'Input', required: true, + helpMessage: t('fms.storageProvider.nameHelpMessage'), }, { field: 'bucket', @@ -92,7 +117,13 @@ export const formSchema: FormSchema[] = [ { field: 'providerName', label: t('fms.storageProvider.providerName'), - component: 'Input', + component: 'Select', + componentProps: { + options: [ + { label: t('mcms.smsProvider.tencent'), value: 'tencent' }, + { label: t('mcms.smsProvider.aliyun'), value: 'aliyun' }, + ], + }, required: true, }, { @@ -107,6 +138,12 @@ export const formSchema: FormSchema[] = [ component: 'Input', required: true, }, + { + field: 'folder', + label: t('fms.storageProvider.folder'), + component: 'Input', + helpMessage: t('fms.storageProvider.folderHelpMessage'), + }, { field: 'region', label: t('fms.storageProvider.region'), From 418d21088a6618fdbe6098eb7702c36491e19e5c Mon Sep 17 00:00:00 2001 From: Ryan SU Date: Sun, 3 Sep 2023 10:15:42 +0000 Subject: [PATCH 4/5] feat: add provider select in cloud file upload --- src/views/fms/cloudFile/index.vue | 27 +++++++++++++++++-- .../storageProvider/storageProvider.data.ts | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/views/fms/cloudFile/index.vue b/src/views/fms/cloudFile/index.vue index 5654bb11..b49c09e3 100644 --- a/src/views/fms/cloudFile/index.vue +++ b/src/views/fms/cloudFile/index.vue @@ -13,12 +13,22 @@