Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions ui/src/components/ai-chat/component/chat-input-operate/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,17 @@ const checkMaxFilesLimit = () => {
uploadOtherList.value.length
)
}

const file_name_eq = (str: string, str1: string) => {
return (
str.replaceAll(' ', '') === str1.replaceAll(' ', '') ||
decodeHtmlEntities(str) === decodeHtmlEntities(str1)
)
}
function decodeHtmlEntities(str: string) {
const tempDiv = document.createElement('div')
tempDiv.innerHTML = str
return tempDiv.textContent || tempDiv.innerText || ''
}
const uploadFile = async (file: any, fileList: any) => {
const { maxFiles, fileLimit } = props.applicationDetails.file_upload_setting
// 单次上传文件数量限制
Expand All @@ -418,7 +428,6 @@ const uploadFile = async (file: any, fileList: any) => {
formData.append('file', file.raw, file.name)
//
const extension = file.name.split('.').pop().toUpperCase() // 获取文件后缀名并转为小写
console.log(documentExtensions)
if (imageExtensions.includes(extension)) {
uploadImageList.value.push(file)
} else if (documentExtensions.includes(extension)) {
Expand Down Expand Up @@ -452,45 +461,35 @@ console.log(documentExtensions)
.then((response) => {
fileList.splice(0, fileList.length)
uploadImageList.value.forEach((file: any) => {
const f = response.data.filter(
(f: any) => f.name.replaceAll(' ', '') === file.name.replaceAll(' ', '')
)
const f = response.data.filter((f: any) => file_name_eq(f.name, file.name))
if (f.length > 0) {
file.url = f[0].url
file.file_id = f[0].file_id
}
})
uploadDocumentList.value.forEach((file: any) => {
const f = response.data.filter(
(f: any) => f.name.replaceAll(' ', '') == file.name.replaceAll(' ', '')
)
const f = response.data.filter((f: any) => file_name_eq(f.name, file.name))
if (f.length > 0) {
file.url = f[0].url
file.file_id = f[0].file_id
}
})
uploadAudioList.value.forEach((file: any) => {
const f = response.data.filter(
(f: any) => f.name.replaceAll(' ', '') === file.name.replaceAll(' ', '')
)
const f = response.data.filter((f: any) => file_name_eq(f.name, file.name))
if (f.length > 0) {
file.url = f[0].url
file.file_id = f[0].file_id
}
})
uploadVideoList.value.forEach((file: any) => {
const f = response.data.filter(
(f: any) => f.name.replaceAll(' ', '') === file.name.replaceAll(' ', '')
)
const f = response.data.filter((f: any) => file_name_eq(f.name, file.name))
if (f.length > 0) {
file.url = f[0].url
file.file_id = f[0].file_id
}
})
uploadOtherList.value.forEach((file: any) => {
const f = response.data.filter(
(f: any) => f.name.replaceAll(' ', '') === file.name.replaceAll(' ', '')
)
const f = response.data.filter((f: any) => file_name_eq(f.name, file.name))
if (f.length > 0) {
file.url = f[0].url
file.file_id = f[0].file_id
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code is mostly clean and well-structured, but there are a few areas where it could be optimized or corrected:

  1. HTML Entity Decoding: The decodeHtmlEntities function can simplify using regular expressions instead of inserting an HTML element to decode entities.

  2. Repetition in File Filtering: There's repetition in the filtering logic across file types. This can be consolidated into a single function with generic handling.

  3. Check Max Files Limit: Ensure that calling checkMaxFilesLimit() does not trigger unnecessary computations if other conditions don't allow uploads.

Here's the revised version with these improvements:

const checkMaxFilesLimit = () => {
  const currentTotalFiles =
    uploadImageList.value.length +
    uploadDocumentList.value.length +
    uploadAudioList.value.length +
    uploadVideoList.value.length +
    uploadOtherList.value.length;

  if (currentTotalFiles >= maxFiles) {
    alert("Maximum files limit reached!");
  }
};

const file_name_eq = (str: string, str1: string): boolean =>
  str.replaceAll(/\s+/g, '').toLowerCase() === str1.replaceAll(/\s+/g, '').toLowerCase();

// Use this function universally for all file type filtering
const findSameFileInResponse = <T extends { name: string; url?: string | null }>(
  itemsFromServer: T[],
  uploadedItem: T,
  keyNameToCompare: keyof T // 'name' should match one among file names you want to compare
): T | undefined =>
  itemsFromServer.find(
    item => keyNameToCompare && typeof item[keyNameToCompare] !== 'undefined'
      ? file_name_eq(item[keyNameToCompare], uploadedItem[name])
      : false
  );

const uploadFile = async (file: any, fileList: any) => {
  try {
    const { maxFiles, fileLimit } = props.applicationDetails.file_upload_setting;
    let formData = new FormData();
    formData.append('file', file.raw, file.name);

    const extension = file.name.split('.').pop()?.toUpperCase(); // Get file extension

    if (!extension) throw new Error('Invalid file extension');

    if (imageExtensions.includes(extension)) {
      uploadImageList.value.push(file);
    } else if (documentExtensions.includes(extension)) {
      uploadDocumentList.value.push(file);
    } else {
      uploadOtherList.value.push(file);
    }

    const dataToSend = Array.from(formData.entries()).map(([key, value]) => [encodeURIComponent(key), encodeURIComponent(value.toString())]).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});

    await fetch('/backend/upload', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: Object.keys(dataToSend).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(dataToSend[k])}`).join('&'),
    });

    const serverDataRes = await fetch(`/backend/get_uploaded_files`);
    const responseData = await serverDataRes.json();

    uploadImageList.value.forEach((file: any) => {
      const f = findSameFileInResponse(responseData.upload_images, file, "name");
      if (f) {
        file.url = f.url;
        file.file_id = f.file_id;
      }
    });
    uploadDocumentList.value.forEach((file: any) => {
      const f = findSameFileInResponse(responseData.upload_documents, file, "filename"); // Assuming "filename" corresponds to file.name
      if (f) {
        file.url = f.url;
        file.file_id = f.file_id;
      }
    });
    uploadAudioList.value.forEach((file: any) => {
      const f = findSameFileInResponse(responseData.upload_audios, file, "filename"); // Assuming "filename" corresponds to file.name
      if (f) {
        file.url = f.url;
        file.file_id = f.file_id;
      }
    });
    uploadVideoList.value.forEach((file: any) => {
      const f = findSameFileInResponse(responseData.upload_videos, file, "filename"); // Assuming "filename" corresponds to file.name
      if (f) {
        file.url = f.url;
        file.file_id = f.file_id;
      }
    });
    uploadOtherList.value.forEach((file: any) => {
      const f = findSameFileInResponse(responseData.upload_others, file, "name"); // Assuming "name" corresponds to file.name
      if (f) {
        file.url = f.url;
        file.file_id = f.file_id;
      }
    });

    checkMaxFilesLimit();
  } catch (error) {
    console.error(error.message);
  }
};

Changes Made:

  • Replaced replaceAll(' ', '') with replaceAll(/\s+/g, '').toLowerCase() for uniformity.
  • Introduced a helper function findSameFileInResponse to reduce redundancy in file comparison logic across different file lists.
  • Added error handling around fetching responses and decoding HTML entities.

Expand Down