fix(file): 解决OSS图片处理参数导致的文件访问问题
- 在SelectFile组件中为文件链接添加stripOssImageProcess处理 - 从common工具库导入并使用stripOssImageProcess函数 - 在creditMpCustomer编辑页面对文件URL进行图片处理参数清理 - 在creditMpCustomer列表页面添加sanitizeFileUrl函数处理文件URL - 修改文件规范化逻辑以确保非图片文件移除OSS处理参数
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
<div v-else class="image-upload-item">
|
<div v-else class="image-upload-item">
|
||||||
<a
|
<a
|
||||||
class="file-item"
|
class="file-item"
|
||||||
:href="item.url"
|
:href="stripOssImageProcess(item.url)"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
:style="{ width: width + 'px', height: height + 'px' }"
|
:style="{ width: width + 'px', height: height + 'px' }"
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import SelectData from './components/select-data.vue';
|
import SelectData from './components/select-data.vue';
|
||||||
import { FileRecord } from '@/api/system/file/model';
|
import { FileRecord } from '@/api/system/file/model';
|
||||||
import { isImage } from '@/utils/common';
|
import { isImage, stripOssImageProcess } from '@/utils/common';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
|||||||
@@ -444,6 +444,24 @@ export const isImage = (fileName) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 移除 OSS 图片处理参数(非图片文件拼接该参数会导致访问失败)
|
||||||
|
export const stripOssImageProcess = (url?: string) => {
|
||||||
|
if (!url) return url;
|
||||||
|
const hashIndex = url.indexOf('#');
|
||||||
|
const withNoHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
||||||
|
const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';
|
||||||
|
const queryIndex = withNoHash.indexOf('?');
|
||||||
|
if (queryIndex < 0) return url;
|
||||||
|
const base = withNoHash.slice(0, queryIndex);
|
||||||
|
const query = withNoHash.slice(queryIndex + 1);
|
||||||
|
const kept = query
|
||||||
|
.split('&')
|
||||||
|
.filter(Boolean)
|
||||||
|
.filter((p) => p !== 'x-oss-process' && !p.startsWith('x-oss-process='));
|
||||||
|
const rebuilt = kept.length ? `${base}?${kept.join('&')}` : base;
|
||||||
|
return `${rebuilt}${hash}`;
|
||||||
|
};
|
||||||
|
|
||||||
export const getWeek = (text) => {
|
export const getWeek = (text) => {
|
||||||
const week = [
|
const week = [
|
||||||
'星期日',
|
'星期日',
|
||||||
|
|||||||
@@ -149,7 +149,7 @@
|
|||||||
import { FileRecord } from '@/api/system/file/model';
|
import { FileRecord } from '@/api/system/file/model';
|
||||||
import RegionsSelect from '@/components/RegionsSelect/index.vue';
|
import RegionsSelect from '@/components/RegionsSelect/index.vue';
|
||||||
import SelectFile from '@/components/SelectFile/index.vue';
|
import SelectFile from '@/components/SelectFile/index.vue';
|
||||||
import { isImage } from '@/utils/common';
|
import { isImage, stripOssImageProcess } from '@/utils/common';
|
||||||
|
|
||||||
// 是否是修改
|
// 是否是修改
|
||||||
const isUpdate = ref(false);
|
const isUpdate = ref(false);
|
||||||
@@ -248,15 +248,22 @@
|
|||||||
.map((item: any) => {
|
.map((item: any) => {
|
||||||
if (!item) return null;
|
if (!item) return null;
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
|
const url = isImage(item) ? item : stripOssImageProcess(item);
|
||||||
return {
|
return {
|
||||||
url: item,
|
url,
|
||||||
name: guessNameFromUrl(item),
|
name: guessNameFromUrl(url),
|
||||||
thumbnail: item,
|
thumbnail: url,
|
||||||
isImage: isImage(item)
|
isImage: isImage(url)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const url = item.url || item.path || item.href;
|
const rawUrl = item.url || item.path || item.href;
|
||||||
if (!url || typeof url !== 'string') return null;
|
const url =
|
||||||
|
rawUrl && typeof rawUrl === 'string'
|
||||||
|
? isImage(rawUrl)
|
||||||
|
? rawUrl
|
||||||
|
: stripOssImageProcess(rawUrl)
|
||||||
|
: undefined;
|
||||||
|
if (!url) return null;
|
||||||
return {
|
return {
|
||||||
url,
|
url,
|
||||||
name: typeof item.name === 'string' ? item.name : guessNameFromUrl(url),
|
name: typeof item.name === 'string' ? item.name : guessNameFromUrl(url),
|
||||||
@@ -298,7 +305,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onFileChoose = (data: FileRecord) => {
|
const onFileChoose = (data: FileRecord) => {
|
||||||
const url = data.url || data.downloadUrl || data.path;
|
const rawUrl = data.url || data.downloadUrl || data.path;
|
||||||
|
const url = rawUrl ? (isImage(rawUrl) ? rawUrl : stripOssImageProcess(rawUrl)) : undefined;
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const exists = fileList.value.some((d: any) => d?.url === url);
|
const exists = fileList.value.some((d: any) => d?.url === url);
|
||||||
if (exists) return;
|
if (exists) return;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
/>
|
/>
|
||||||
<a
|
<a
|
||||||
v-else
|
v-else
|
||||||
:href="file.url"
|
:href="sanitizeFileUrl(file.url, file.isImage)"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
@@ -108,6 +108,7 @@ import {
|
|||||||
} from '@/api/credit/creditMpCustomer';
|
} from '@/api/credit/creditMpCustomer';
|
||||||
import type {CreditMpCustomer, CreditMpCustomerParam} from '@/api/credit/creditMpCustomer/model';
|
import type {CreditMpCustomer, CreditMpCustomerParam} from '@/api/credit/creditMpCustomer/model';
|
||||||
import {exportCreditData} from '../utils/export';
|
import {exportCreditData} from '../utils/export';
|
||||||
|
import { stripOssImageProcess } from '@/utils/common';
|
||||||
|
|
||||||
type NormalizedFile = {
|
type NormalizedFile = {
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -213,6 +214,10 @@ const tryParseJson = (value: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sanitizeFileUrl = (url: string, isImage: boolean) => {
|
||||||
|
return isImage ? url : (stripOssImageProcess(url) as string);
|
||||||
|
};
|
||||||
|
|
||||||
const filesCache = new Map<string, NormalizedFile[]>();
|
const filesCache = new Map<string, NormalizedFile[]>();
|
||||||
|
|
||||||
const normalizeFiles = (raw: unknown): NormalizedFile[] => {
|
const normalizeFiles = (raw: unknown): NormalizedFile[] => {
|
||||||
@@ -223,19 +228,21 @@ const normalizeFiles = (raw: unknown): NormalizedFile[] => {
|
|||||||
.map((item: any) => {
|
.map((item: any) => {
|
||||||
if (!item) return null;
|
if (!item) return null;
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
|
const url = sanitizeFileUrl(item, isImageUrl(item));
|
||||||
return {
|
return {
|
||||||
url: item,
|
url,
|
||||||
thumbnail: item,
|
thumbnail: url,
|
||||||
name: guessNameFromUrl(item),
|
name: guessNameFromUrl(url),
|
||||||
isImage: isImageUrl(item)
|
isImage: isImageUrl(url)
|
||||||
} satisfies NormalizedFile;
|
} satisfies NormalizedFile;
|
||||||
}
|
}
|
||||||
const url = item.url || item.path || item.href;
|
const rawUrl = item.url || item.path || item.href;
|
||||||
if (!url || typeof url !== 'string') return null;
|
const url = typeof rawUrl === 'string' ? rawUrl : undefined;
|
||||||
|
if (!url) return null;
|
||||||
const thumbnail = typeof item.thumbnail === 'string' ? item.thumbnail : undefined;
|
const thumbnail = typeof item.thumbnail === 'string' ? item.thumbnail : undefined;
|
||||||
const name = typeof item.name === 'string' ? item.name : guessNameFromUrl(url);
|
const name = typeof item.name === 'string' ? item.name : guessNameFromUrl(url);
|
||||||
const isImage = typeof item.isImage === 'boolean' ? item.isImage : isImageUrl(url);
|
const isImage = typeof item.isImage === 'boolean' ? item.isImage : isImageUrl(url);
|
||||||
return {url, thumbnail, name, isImage} satisfies NormalizedFile;
|
return {url: sanitizeFileUrl(url, isImage), thumbnail, name, isImage} satisfies NormalizedFile;
|
||||||
})
|
})
|
||||||
.filter(Boolean) as NormalizedFile[];
|
.filter(Boolean) as NormalizedFile[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user