fix(file): 解决OSS图片处理参数导致的文件访问问题

- 在SelectFile组件中为文件链接添加stripOssImageProcess处理
- 从common工具库导入并使用stripOssImageProcess函数
- 在creditMpCustomer编辑页面对文件URL进行图片处理参数清理
- 在creditMpCustomer列表页面添加sanitizeFileUrl函数处理文件URL
- 修改文件规范化逻辑以确保非图片文件移除OSS处理参数
This commit is contained in:
2026-03-19 17:30:21 +08:00
parent a0a4cc7a8d
commit 54827a9876
4 changed files with 55 additions and 22 deletions

View File

@@ -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<{

View File

@@ -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 = [
'星期日', '星期日',

View File

@@ -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;

View File

@@ -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[];
} }