utils.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import mime from 'mime'
  2. import { FileAppearanceTypeEnum } from './types'
  3. import type { FileEntity } from './types'
  4. import { upload } from '@/service/base'
  5. import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
  6. import { SupportUploadFileTypes } from '@/app/components/workflow/types'
  7. import type { FileResponse } from '@/types/workflow'
  8. import { TransferMethod } from '@/types/app'
  9. type FileUploadParams = {
  10. file: File
  11. onProgressCallback: (progress: number) => void
  12. onSuccessCallback: (res: { id: string }) => void
  13. onErrorCallback: () => void
  14. }
  15. type FileUpload = (v: FileUploadParams, isPublic?: boolean, url?: string) => void
  16. export const fileUpload: FileUpload = ({
  17. file,
  18. onProgressCallback,
  19. onSuccessCallback,
  20. onErrorCallback,
  21. }, isPublic, url) => {
  22. const formData = new FormData()
  23. formData.append('file', file)
  24. const onProgress = (e: ProgressEvent) => {
  25. if (e.lengthComputable) {
  26. const percent = Math.floor(e.loaded / e.total * 100)
  27. onProgressCallback(percent)
  28. }
  29. }
  30. upload({
  31. xhr: new XMLHttpRequest(),
  32. data: formData,
  33. onprogress: onProgress,
  34. }, isPublic, url)
  35. .then((res: { id: string }) => {
  36. onSuccessCallback(res)
  37. })
  38. .catch(() => {
  39. onErrorCallback()
  40. })
  41. }
  42. export const getFileExtension = (fileName: string, fileMimetype: string, isRemote?: boolean) => {
  43. let extension = ''
  44. if (fileMimetype)
  45. extension = mime.getExtension(fileMimetype) || ''
  46. if (fileName && !extension) {
  47. const fileNamePair = fileName.split('.')
  48. const fileNamePairLength = fileNamePair.length
  49. if (fileNamePairLength > 1)
  50. extension = fileNamePair[fileNamePairLength - 1]
  51. else
  52. extension = ''
  53. }
  54. if (isRemote)
  55. extension = ''
  56. return extension
  57. }
  58. export const getFileAppearanceType = (fileName: string, fileMimetype: string) => {
  59. const extension = getFileExtension(fileName, fileMimetype)
  60. if (extension === 'gif')
  61. return FileAppearanceTypeEnum.gif
  62. if (FILE_EXTS.image.includes(extension.toUpperCase()))
  63. return FileAppearanceTypeEnum.image
  64. if (FILE_EXTS.video.includes(extension.toUpperCase()))
  65. return FileAppearanceTypeEnum.video
  66. if (FILE_EXTS.audio.includes(extension.toUpperCase()))
  67. return FileAppearanceTypeEnum.audio
  68. if (extension === 'html')
  69. return FileAppearanceTypeEnum.code
  70. if (extension === 'pdf')
  71. return FileAppearanceTypeEnum.pdf
  72. if (extension === 'md' || extension === 'markdown')
  73. return FileAppearanceTypeEnum.markdown
  74. if (extension === 'xlsx' || extension === 'xls')
  75. return FileAppearanceTypeEnum.excel
  76. if (extension === 'docx' || extension === 'doc')
  77. return FileAppearanceTypeEnum.word
  78. if (extension === 'pptx' || extension === 'ppt')
  79. return FileAppearanceTypeEnum.ppt
  80. if (FILE_EXTS.document.includes(extension.toUpperCase()))
  81. return FileAppearanceTypeEnum.document
  82. return FileAppearanceTypeEnum.custom
  83. }
  84. export const getSupportFileType = (fileName: string, fileMimetype: string, isCustom?: boolean) => {
  85. if (isCustom)
  86. return SupportUploadFileTypes.custom
  87. const extension = getFileExtension(fileName, fileMimetype)
  88. for (const key in FILE_EXTS) {
  89. if ((FILE_EXTS[key]).includes(extension.toUpperCase()))
  90. return key
  91. }
  92. return ''
  93. }
  94. export const getProcessedFiles = (files: FileEntity[]) => {
  95. return files.filter(file => file.progress !== -1).map(fileItem => ({
  96. type: fileItem.supportFileType,
  97. transfer_method: fileItem.transferMethod,
  98. url: fileItem.url || '',
  99. upload_file_id: fileItem.uploadedId || '',
  100. }))
  101. }
  102. export const getProcessedFilesFromResponse = (files: FileResponse[]) => {
  103. return files.map((fileItem) => {
  104. return {
  105. id: fileItem.related_id,
  106. name: fileItem.filename,
  107. size: fileItem.size || 0,
  108. type: fileItem.mime_type,
  109. progress: 100,
  110. transferMethod: fileItem.transfer_method,
  111. supportFileType: fileItem.type,
  112. uploadedId: fileItem.related_id,
  113. url: fileItem.url,
  114. }
  115. })
  116. }
  117. export const getFileNameFromUrl = (url: string) => {
  118. const urlParts = url.split('/')
  119. return urlParts[urlParts.length - 1] || ''
  120. }
  121. export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileExtensions: string[]) => {
  122. if (allowFileTypes.includes(SupportUploadFileTypes.custom))
  123. return allowFileExtensions.map(item => item.slice(1).toUpperCase())
  124. return allowFileTypes.map(type => FILE_EXTS[type]).flat()
  125. }
  126. export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => {
  127. return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase())
  128. }
  129. export const getFilesInLogs = (rawData: any) => {
  130. const result = Object.keys(rawData || {}).map((key) => {
  131. if (typeof rawData[key] === 'object' && rawData[key]?.dify_model_identity === '__dify__file__') {
  132. return {
  133. varName: key,
  134. list: getProcessedFilesFromResponse([rawData[key]]),
  135. }
  136. }
  137. if (Array.isArray(rawData[key]) && rawData[key].some(item => item?.dify_model_identity === '__dify__file__')) {
  138. return {
  139. varName: key,
  140. list: getProcessedFilesFromResponse(rawData[key]),
  141. }
  142. }
  143. return undefined
  144. }).filter(Boolean)
  145. return result
  146. }
  147. export const fileIsUploaded = (file: FileEntity) => {
  148. if (file.uploadedId)
  149. return true
  150. if (file.transferMethod === TransferMethod.remote_url && file.progress === 100)
  151. return true
  152. }
  153. export const downloadFile = (url: string, filename: string) => {
  154. const anchor = document.createElement('a')
  155. anchor.href = url
  156. anchor.download = filename
  157. anchor.style.display = 'none'
  158. anchor.target = '_blank'
  159. anchor.title = filename
  160. document.body.appendChild(anchor)
  161. anchor.click()
  162. document.body.removeChild(anchor)
  163. }