diff --git a/Admin.NET/Admin.NET.Core/Service/DataBase/SysDbBackupService.cs b/Admin.NET/Admin.NET.Core/Service/DataBase/SysDbBackupService.cs
index af5d0e5e..33201621 100644
--- a/Admin.NET/Admin.NET.Core/Service/DataBase/SysDbBackupService.cs
+++ b/Admin.NET/Admin.NET.Core/Service/DataBase/SysDbBackupService.cs
@@ -4,6 +4,7 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+using System.IO.Compression;
using DbType = SqlSugar.DbType;
namespace Admin.NET.Core.Service;
@@ -176,7 +177,7 @@ public class SysDbBackupService : IDynamicApiController, ITransient
///
/// 下载备份 🔖
///
- ///
+ /// 备份文件名
[ApiDescriptionSettings(Name = "Download"), HttpGet]
[DisplayName("下载备份")]
[AllowAnonymous]
@@ -187,4 +188,45 @@ public class SysDbBackupService : IDynamicApiController, ITransient
var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
return new FileStreamResult(fs, "application/octet-stream") { FileDownloadName = fileName };
}
+
+ ///
+ /// 压缩备份 🔖
+ ///
+ /// 备份文件名
+ /// 压缩后的文件路径
+ [ApiDescriptionSettings(Name = "Compress"), HttpPost]
+ [DisplayName("压缩备份文件")]
+ public async Task Compress([FromQuery] string fileName)
+ {
+ var sourcePath = Path.Combine(_backupDir, fileName);
+ if (!File.Exists(sourcePath)) return;
+
+ // 生成临时文件路径
+ var tempPath = Path.Combine(Path.GetTempPath(), $"{Path.GetFileNameWithoutExtension(fileName)}.zip");
+ var finalPath = Path.Combine(_backupDir, $"{Path.GetFileNameWithoutExtension(fileName)}.zip");
+
+ try
+ {
+ // 使用临时路径进行压缩
+ await Task.Run(() =>
+ {
+ using var zip = new ZipArchive(new FileStream(tempPath, FileMode.Create), ZipArchiveMode.Create);
+ var entry = zip.CreateEntry(fileName);
+ using var entryStream = entry.Open();
+ using var fileStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read);
+ fileStream.CopyTo(entryStream);
+ });
+
+ // 压缩成功后,将临时文件移动到目标路径
+ File.Move(tempPath, finalPath);
+ }
+ catch (Exception ex)
+ {
+ // 清理临时文件
+ if (File.Exists(tempPath))
+ File.Delete(tempPath);
+
+ throw;
+ }
+ }
}
\ No newline at end of file
diff --git a/Web/src/api-services/apis/sys-db-backup-api.ts b/Web/src/api-services/apis/sys-db-backup-api.ts
index dcee4d19..ab253ae9 100644
--- a/Web/src/api-services/apis/sys-db-backup-api.ts
+++ b/Web/src/api-services/apis/sys-db-backup-api.ts
@@ -72,6 +72,54 @@ export const SysDbBackupApiAxiosParamCreator = function (configuration?: Configu
options: localVarRequestOptions,
};
},
+ /**
+ *
+ * @summary 压缩备份 🔖
+ * @param {string} [fileName] 备份文件名
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ apiSysDbBackupCompressPost: async (fileName?: string, options: AxiosRequestConfig = {}): Promise => {
+ const localVarPath = `/api/sysDbBackup/compress`;
+ // use dummy base URL string because the URL constructor only accepts absolute URLs.
+ const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+ let baseOptions;
+ if (configuration) {
+ baseOptions = configuration.baseOptions;
+ }
+ const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+ const localVarHeaderParameter = {} as any;
+ const localVarQueryParameter = {} as any;
+
+ // authentication Bearer required
+ // http bearer authentication required
+ if (configuration && configuration.accessToken) {
+ const accessToken = typeof configuration.accessToken === 'function'
+ ? await configuration.accessToken()
+ : await configuration.accessToken;
+ localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+ }
+
+ if (fileName !== undefined) {
+ localVarQueryParameter['fileName'] = fileName;
+ }
+
+ const query = new URLSearchParams(localVarUrlObj.search);
+ for (const key in localVarQueryParameter) {
+ query.set(key, localVarQueryParameter[key]);
+ }
+ for (const key in options.params) {
+ query.set(key, options.params[key]);
+ }
+ localVarUrlObj.search = (new URLSearchParams(query)).toString();
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+ localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
+ return {
+ url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+ options: localVarRequestOptions,
+ };
+ },
/**
*
* @summary 删除备份 🔖
@@ -123,7 +171,7 @@ export const SysDbBackupApiAxiosParamCreator = function (configuration?: Configu
/**
*
* @summary 下载备份 🔖
- * @param {string} fileName
+ * @param {string} fileName 备份文件名
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
@@ -235,6 +283,20 @@ export const SysDbBackupApiFp = function(configuration?: Configuration) {
return axios.request(axiosRequestArgs);
};
},
+ /**
+ *
+ * @summary 压缩备份 🔖
+ * @param {string} [fileName] 备份文件名
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ async apiSysDbBackupCompressPost(fileName?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> {
+ const localVarAxiosArgs = await SysDbBackupApiAxiosParamCreator(configuration).apiSysDbBackupCompressPost(fileName, options);
+ return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+ const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+ return axios.request(axiosRequestArgs);
+ };
+ },
/**
*
* @summary 删除备份 🔖
@@ -252,7 +314,7 @@ export const SysDbBackupApiFp = function(configuration?: Configuration) {
/**
*
* @summary 下载备份 🔖
- * @param {string} fileName
+ * @param {string} fileName 备份文件名
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
@@ -295,6 +357,16 @@ export const SysDbBackupApiFactory = function (configuration?: Configuration, ba
async apiSysDbBackupAddPost(configId?: string, options?: AxiosRequestConfig): Promise> {
return SysDbBackupApiFp(configuration).apiSysDbBackupAddPost(configId, options).then((request) => request(axios, basePath));
},
+ /**
+ *
+ * @summary 压缩备份 🔖
+ * @param {string} [fileName] 备份文件名
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ async apiSysDbBackupCompressPost(fileName?: string, options?: AxiosRequestConfig): Promise> {
+ return SysDbBackupApiFp(configuration).apiSysDbBackupCompressPost(fileName, options).then((request) => request(axios, basePath));
+ },
/**
*
* @summary 删除备份 🔖
@@ -308,7 +380,7 @@ export const SysDbBackupApiFactory = function (configuration?: Configuration, ba
/**
*
* @summary 下载备份 🔖
- * @param {string} fileName
+ * @param {string} fileName 备份文件名
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
@@ -345,6 +417,17 @@ export class SysDbBackupApi extends BaseAPI {
public async apiSysDbBackupAddPost(configId?: string, options?: AxiosRequestConfig) : Promise> {
return SysDbBackupApiFp(this.configuration).apiSysDbBackupAddPost(configId, options).then((request) => request(this.axios, this.basePath));
}
+ /**
+ *
+ * @summary 压缩备份 🔖
+ * @param {string} [fileName] 备份文件名
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ * @memberof SysDbBackupApi
+ */
+ public async apiSysDbBackupCompressPost(fileName?: string, options?: AxiosRequestConfig) : Promise> {
+ return SysDbBackupApiFp(this.configuration).apiSysDbBackupCompressPost(fileName, options).then((request) => request(this.axios, this.basePath));
+ }
/**
*
* @summary 删除备份 🔖
@@ -359,7 +442,7 @@ export class SysDbBackupApi extends BaseAPI {
/**
*
* @summary 下载备份 🔖
- * @param {string} fileName
+ * @param {string} fileName 备份文件名
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysDbBackupApi
diff --git a/Web/src/views/system/database/dbBackup.vue b/Web/src/views/system/database/dbBackup.vue
index e52b5c9b..5ffd17cf 100644
--- a/Web/src/views/system/database/dbBackup.vue
+++ b/Web/src/views/system/database/dbBackup.vue
@@ -28,6 +28,7 @@
删除
+ 压缩
下载
@@ -63,7 +64,7 @@ const options = useVxeTable(
{ field: 'fileName', title: '文件名称', minWidth: 200, showOverflow: 'tooltip' },
{ field: 'size', title: '文件大小', width: 150, showOverflow: 'tooltip', slots: { default: 'row_size' } },
{ field: 'createTime', title: '备份时间', width: 200, showOverflow: 'tooltip', slots: { default: 'row_createTime' } },
- { field: 'buttons', title: '操作', fixed: 'right', width: 150, showOverflow: true, slots: { default: 'row_buttons' } },
+ { field: 'buttons', title: '操作', fixed: 'right', width: 200, showOverflow: true, slots: { default: 'row_buttons' } },
],
},
{
@@ -145,6 +146,23 @@ const handleDownload = (row: any) => {
tempLink.click();
document.body.removeChild(tempLink);
};
+
+// 压缩备份
+const handleCompress = async (row: any) => {
+ try {
+ await ElMessageBox.confirm(`确定要压缩备份:【${row.fileName}】吗?`, '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'info',
+ });
+
+ state.loading = true;
+ await getAPI(SysDbBackupApi).apiSysDbBackupCompressPost(row.fileName, { timeout: 0 /**永不超时 */ });
+ await xGrid.value?.commitProxy('reload');
+ } finally {
+ state.loading = false;
+ }
+};