wujingjing
2025-03-04 92d2ea48d343fc00d81905167d033c40200ea716
src/components/chat/components/playBar/hook/useUploadFile.ts
@@ -1,29 +1,44 @@
import { useEventListener, useFileDialog } from '@vueuse/core';
import { ref, type Ref } from 'vue';
import { type Ref } from 'vue';
import type { Attach } from './useAttach';
import { convertFileSize } from '/@/utils/file';
export type UseUploadFileOptions = {
   pastTarget: Ref<HTMLElement | null>;
   attachFileList: Ref<Attach<UploadFile>[]>;
};
export type FileType = 'doc' | 'docx' | 'pdf' | 'md' | 'xls' | 'xlsx' | 'png' | 'jpg' | 'jpeg' | 'gif' | 'json';
export type FileGroupType = 'word' | 'pdf' | 'excel' | 'image' | 'json' | 'md';
const compareFiles = (file1: File, file2: File) => {
   if (file1.type !== file2.type) return false;
   if (file1.name !== file2.name) return false;
   if (file1.size !== file2.size) return false;
   if (file1.lastModified !== file2.lastModified) return false;
   return true;
};
export type FileType = 'doc' | 'docx' | 'pdf' | 'md' | 'xls' | 'xlsx' | 'png' | 'jpg' | 'jpeg' | 'gif' | 'json' | 'txt' | 'csv';
export type FileGroupType = 'word' | 'pdf' | 'excel' | 'image' | 'json' | 'md' | 'csv' | 'txt';
export type UploadFile = {
   name: string;
   type: FileType;
   groupType: FileGroupType;
   size: string;
   file: File;
   icon?: string;
   iconClass?: string;
   previewUrl?: string;
};
const getGroupType = (type: FileType): FileGroupType => {
export const getFileGroupType = (type: FileType): FileGroupType => {
   switch (type) {
      case 'doc':
      case 'docx':
         return 'word';
      case 'csv':
         return 'csv';
      case 'txt':
         return 'txt';
      case 'md':
         return 'md';
@@ -44,7 +59,7 @@
   }
};
const getIconByGroupType = (groupType: FileGroupType) => {
export const getIconByGroupType = (groupType: FileGroupType) => {
   switch (groupType) {
      case 'word':
         return 'word';
@@ -52,6 +67,10 @@
         return 'pdf';
      case 'excel':
         return 'excel';
      case 'csv':
         return 'csv';
      case 'txt':
         return 'txt';
      case 'json':
         return 'json';
@@ -62,7 +81,7 @@
   }
};
const getIconClassByGroupType = (groupType: FileGroupType) => {
export const getIconClassByGroupType = (groupType: FileGroupType) => {
   switch (groupType) {
      case 'word':
         return 'text-blue-400';
@@ -70,6 +89,10 @@
         return 'text-red-400';
      case 'excel':
         return 'text-green-400';
      case 'csv':
         return 'text-green-500';
      case 'txt':
         return 'text-cyan-400';
      case 'json':
         return 'text-yellow-400';
@@ -79,17 +102,25 @@
         return '';
   }
};
// const supportFileType = ['doc', 'docx', 'md', 'xls', 'xlsx', 'png', 'jpg', 'jpeg', 'gif', 'json', 'pdf'];
const supportFileType = ['csv', 'txt'];
export const getFileSuffix = (name: string): FileType => {
   if (!name) return 'txt';
   const suffix = name.split('.').pop() as FileType;
   return suffix;
};
export const useUploadFile = (options: UseUploadFileOptions) => {
   const supportFileType = ['doc', 'docx', 'md', 'xls', 'xlsx', 'png', 'jpg', 'jpeg', 'gif', 'json', 'pdf'];
   const attachFileList = ref<UploadFile[]>([]);
   const parseFiles = (files:FileList) => {
   const { attachFileList } = options;
   const parseFiles = (files: FileList) => {
      const filterFiles: UploadFile[] = [];
      for (const file of files) {
         const suffix = file.name.split('.').pop() as FileType;
         if (attachFileList.value.find((item) => compareFiles(item.model.file, file))) {
            continue;
         }
         const suffix = getFileSuffix(file.name);
         if (supportFileType.includes(suffix)) {
            const groupType = getGroupType(suffix);
            const groupType = getFileGroupType(suffix);
            const uploadFile: UploadFile = {
               type: suffix,
               groupType: groupType,
@@ -113,8 +144,25 @@
            filterFiles.push(uploadFile);
         }
      }
      attachFileList.value.push(...filterFiles);
   }
      attachFileList.value.push(
         ...filterFiles.map(
            (item) =>
               ({
                  get title() {
                     return item.name;
                  },
                  type: 'file',
                  model: item,
                  get icon() {
                     return item.icon;
                  },
                  get iconClass() {
                     return item.iconClass;
                  },
               } as Attach<UploadFile>)
         )
      );
   };
   /**
    * 解析粘贴板文件
@@ -124,46 +172,37 @@
      event.stopPropagation();
      const data = event.clipboardData || window.clipboardData;
      const files = data.files as FileList;
      parseFiles(files)
      parseFiles(files);
   };
   const clearFileList = () => {
      attachFileList.value = [];
   };
   const {
      files,
      open:openFileDialog,
      reset:resetOpenFileDialog,
      open: openFileDialog,
      reset: resetOpenFileDialog,
      onChange: onPickFileChange,
   } = useFileDialog({
      accept:
         'application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/markdown,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,image/png,image/jpeg,image/gif,application/json,application/pdf', // Set to accept only image files
         reset:true
      accept: 'text/csv,text/plain', // Only accept csv and txt files
      reset: true,
   });
   const openFileClick = () =>{
   const openFileClick = () => {
      openFileDialog();
   }
   };
   onPickFileChange((files) => {
      if(!files) return;
      parseFiles(files)
      if (!files) return;
      parseFiles(files);
   });
   const deleteIndexFile = (index) => {
      const file = attachFileList.value[index];
      // Revoke object URL for image files
   const deleteUploadFile = (file: UploadFile) => {
      if (file.previewUrl) {
         URL.revokeObjectURL(file.previewUrl);
      }
      attachFileList.value.splice(index, 1);
   };
   useEventListener(options.pastTarget, 'paste', pasteUpload);
   return {
      attachFileList,
      clearFileList,
      deleteIndexFile,
      openFileClick
      deleteUploadFile,
      openFileClick,
   };
};