刘光辉
119 分钟以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import type { TmsAttachmentFile } from './types';
 
import { getAuthMediaUrl } from '#/utils/jnpf';
 
const IMAGE_EXT = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg']);
const VIDEO_EXT = new Set(['mp4', 'webm', 'ogg', 'mov', 'm4v']);
const AUDIO_EXT = new Set(['mp3', 'wav', 'aac', 'm4a', 'flac']);
const OFFICE_EXT = new Set([
  'doc',
  'docx',
  'docm',
  'dot',
  'dotx',
  'xls',
  'xlsx',
  'xlsm',
  'xlt',
  'xltx',
  'ppt',
  'pptx',
  'pptm',
  'pps',
  'ppsx',
  'pot',
  'potx',
  'csv',
  'rtf',
  'odt',
  'ods',
  'odp',
  'ott',
  'ots',
  'otp',
]);
 
export function resolvePreviewType(ext?: string): string {
  if (!ext) return 'other';
  const e = ext.toLowerCase().replace(/^\./, '');
  if (IMAGE_EXT.has(e)) return 'image';
  if (VIDEO_EXT.has(e)) return 'video';
  if (AUDIO_EXT.has(e)) return 'audio';
  if (e === 'pdf') return 'pdf';
  if (OFFICE_EXT.has(e)) return 'office';
  return 'other';
}
 
export function guessExt(file?: Pick<TmsAttachmentFile, 'fileExt' | 'name' | 'url'>): string {
  if (file?.fileExt) return file.fileExt.replace(/^\./, '').toLowerCase();
  const fromName = file?.name?.match(/\.([^.\\/]+)$/);
  if (fromName?.[1]) return fromName[1].toLowerCase();
  const fromUrl = file?.url?.match(/\.([^.\\/?#]+)(?:[?#]|$)/);
  if (fromUrl?.[1]) return fromUrl[1].toLowerCase();
  return '';
}
 
/** 补齐 previewType / fileExt,便于仅有 name+url 的附件也能页内预览 */
export function normalizeAttachment(file: TmsAttachmentFile): TmsAttachmentFile {
  const fileExt = guessExt(file);
  return {
    ...file,
    fileExt: file.fileExt || fileExt || undefined,
    previewType: file.previewType || resolvePreviewType(fileExt),
  };
}
 
/** 认证媒体地址;t=t 让文件服务直接输出内容,避免 img/video 302 */
export function toAuthMediaUrl(url?: string): string {
  if (!url) return '';
  const apiIndex = url.indexOf('/api/');
  const path = /^https?:\/\//i.test(url) && apiIndex >= 0 ? url.slice(apiIndex) : url;
  return getAuthMediaUrl(path, false);
}