This is an automated email from the ASF dual-hosted git repository.
jinsongzhou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git
The following commit(s) were added to refs/heads/master by this push:
new b513bb124 [AMORO-3369] fix download error (#3463)
b513bb124 is described below
commit b513bb124db92beb0cd11ee0d9c55278e2a585cf
Author: xiaomo <[email protected]>
AuthorDate: Wed Mar 12 17:34:30 2025 +0800
[AMORO-3369] fix download error (#3463)
* [AMORO-3369] fix download error
* chore: update file name
---
amoro-web/src/utils/request.ts | 83 +++++++++++++++++++++++----------
amoro-web/src/views/catalogs/Detail.vue | 9 ++--
2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/amoro-web/src/utils/request.ts b/amoro-web/src/utils/request.ts
index cf79e04dd..e60f22d85 100644
--- a/amoro-web/src/utils/request.ts
+++ b/amoro-web/src/utils/request.ts
@@ -104,7 +104,7 @@ instance.interceptors.response.use(
}
// Actively cancel the request without throwing an error
if (axios.isCancel(error)) {
- return new Promise(() => {}) // Returns a Promise object in the
"pending" state, if it is not passed down, it may cause memory leaks
+ return new Promise(() => { }) // Returns a Promise object in the
"pending" state, if it is not passed down, it may cause memory leaks
}
return Promise.reject(error)
},
@@ -178,29 +178,29 @@ const request: any = function (options:
CustomAxiosRequestConfig) {
return Promise.reject(err) // Business custom handling errors
})
}
-;['get', 'delete'].forEach((method) => {
- request[method] = function (url: string, options: CustomAxiosRequestConfig =
{}) {
- options = Object.assign({}, options, {
- url,
- method,
- })
- return request(options)
- }
-})
-;['post', 'put'].forEach((method) => {
- request[method] = function (
- url: string,
- data: Record<string, any> = {},
- options: CustomAxiosRequestConfig = {},
- ) {
- options = Object.assign({}, options, {
- url,
- method,
- data,
- })
- return request(options)
- }
-})
+ ;['get', 'delete'].forEach((method) => {
+ request[method] = function (url: string, options: CustomAxiosRequestConfig
= {}) {
+ options = Object.assign({}, options, {
+ url,
+ method,
+ })
+ return request(options)
+ }
+ })
+ ;['post', 'put'].forEach((method) => {
+ request[method] = function (
+ url: string,
+ data: Record<string, any> = {},
+ options: CustomAxiosRequestConfig = {},
+ ) {
+ options = Object.assign({}, options, {
+ url,
+ method,
+ data,
+ })
+ return request(options)
+ }
+ })
/**
* file download
@@ -224,4 +224,39 @@ export function download(url: string, _blank = true) {
}
}
+
+
+/**
+ * file download with header
+ * @param url
+ * @param _blank
+ */
+export function downloadWithHeader(url: string, fileName: string = 'download',
_blank = true) {
+ fetch(url, {
+ headers: {
+ 'X-Request-Source': 'Web'
+ }
+ })
+ .then(response => {
+ if (!response.ok) {
+ throw new Error(`HTTP error! Status: ${response.status}`)
+ }
+ return response.blob()
+ })
+ .then(blob => {
+ const fileURL = window.URL.createObjectURL(blob)
+ const link = document.createElement('a')
+ link.href = fileURL
+ link.download = fileName
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ window.URL.revokeObjectURL(fileURL)
+ })
+ .catch(error => {
+ console.error('Download failed:', error)
+ })
+}
+
+
export default request as WrapperRequest
diff --git a/amoro-web/src/views/catalogs/Detail.vue
b/amoro-web/src/views/catalogs/Detail.vue
index 4f3d53042..0a2caac0e 100644
--- a/amoro-web/src/views/catalogs/Detail.vue
+++ b/amoro-web/src/views/catalogs/Detail.vue
@@ -33,6 +33,7 @@ import { checkCatalogStatus, delCatalog, getCatalogsSetting,
getCatalogsTypes, s
import type { ICatalogItem, IIOptimizeGroupItem, ILableAndValue, IMap } from
'@/types/common.type'
import { usePlaceholder } from '@/hooks/usePlaceholder'
import { getResourceGroupsListAPI } from '@/services/optimize.service'
+import { downloadWithHeader } from '@/utils/request'
interface IStorageConfigItem {
label: string
@@ -606,8 +607,8 @@ function uploadFile(info: UploadChangeParam, config: {
uploadLoading: boolean, i
message.error((error as Error).message)
}
}
-function viewFileDetail(url: string) {
- url && window.open(url)
+function viewFileDetail(url: string, fileName: string) {
+ downloadWithHeader(url, fileName)
}
onMounted(() => {
getCatalogTypeOps()
@@ -724,7 +725,7 @@ onMounted(() => {
</a-upload>
<span
v-if="config.isSuccess || config.fileName" class="config-value"
- :class="{ 'view-active': !!config.fileUrl }"
@click="viewFileDetail(config.fileUrl)"
+ :class="{ 'view-active': !!config.fileUrl }"
@click="viewFileDetail(config.fileUrl, config.fileName)"
>{{ config.fileName
}}</span>
</a-form-item>
@@ -775,7 +776,7 @@ onMounted(() => {
<span
v-if="config.isSuccess || config.fileName" class="config-value
auth-filename"
:class="{ 'view-active': !!config.fileUrl }"
:title="config.fileName"
- @click="viewFileDetail(config.fileUrl)"
+ @click="viewFileDetail(config.fileUrl, config.fileName)"
>{{ config.fileName }}</span>
</a-form-item>
</div>