upload.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { defineStore } from 'pinia'
  2. import { ref, computed } from 'vue'
  3. import config from '../config'
  4. export const useUploadStore = defineStore('upload', () => {
  5. // 状态
  6. const selectedFiles = ref([])
  7. const textContent = ref('')
  8. const textType = ref('plain')
  9. const expirationHours = ref(3)
  10. const maxDownloadCount = ref(-1)
  11. const password = ref('')
  12. const uploadResult = ref(null)
  13. const uploading = ref(false)
  14. // 上传进度状态
  15. const uploadProgress = ref(0) // 0-100
  16. const uploadSpeed = ref(0) // 字节/秒
  17. const uploadedBytes = ref(0) // 已上传字节数
  18. const totalBytes = ref(0) // 总字节数
  19. // 计算属性
  20. const hasFiles = computed(() => selectedFiles.value.length > 0)
  21. const hasText = computed(() => textContent.value.trim().length > 0)
  22. const canUpload = computed(() => hasFiles.value || hasText.value)
  23. const totalFileSize = computed(() => {
  24. return selectedFiles.value.reduce((sum, file) => sum + file.size, 0)
  25. })
  26. // 计算剩余时间(秒)
  27. const remainingTime = computed(() => {
  28. if (uploadSpeed.value === 0 || uploadProgress.value >= 100) {
  29. return 0
  30. }
  31. const remainingBytes = totalBytes.value - uploadedBytes.value
  32. return Math.ceil(remainingBytes / uploadSpeed.value)
  33. })
  34. // 方法
  35. function addFiles(files) {
  36. const remainingSlots = config.maxFiles - selectedFiles.value.length
  37. const filesToAdd = []
  38. const rejectedFiles = []
  39. // 文件大小预检
  40. for (const file of files.slice(0, remainingSlots)) {
  41. // 检查文件大小
  42. if (file.size > config.uploadLimit) {
  43. rejectedFiles.push({
  44. file,
  45. reason: 'size',
  46. maxSize: config.uploadLimit
  47. })
  48. continue
  49. }
  50. // 检查是否重复
  51. if (!selectedFiles.value.some(f => f.name === file.name && f.size === file.size)) {
  52. filesToAdd.push(file)
  53. }
  54. }
  55. // 添加有效的文件
  56. filesToAdd.forEach(file => {
  57. selectedFiles.value.push({
  58. id: Date.now() + Math.random(),
  59. file,
  60. name: file.name,
  61. size: file.size,
  62. type: file.type,
  63. progress: 0
  64. })
  65. })
  66. return {
  67. added: filesToAdd.length,
  68. rejected: rejectedFiles
  69. }
  70. }
  71. function removeFile(id) {
  72. const index = selectedFiles.value.findIndex(f => f.id === id)
  73. if (index > -1) {
  74. selectedFiles.value.splice(index, 1)
  75. }
  76. }
  77. function clearFiles() {
  78. selectedFiles.value = []
  79. }
  80. function reset() {
  81. selectedFiles.value = []
  82. textContent.value = ''
  83. textType.value = 'plain'
  84. expirationHours.value = 3
  85. maxDownloadCount.value = -1
  86. password.value = ''
  87. uploadResult.value = null
  88. uploading.value = false
  89. resetUploadProgress() // 重置进度
  90. }
  91. function setUploadResult(result) {
  92. uploadResult.value = result
  93. }
  94. function setUploading(status) {
  95. uploading.value = status
  96. }
  97. function updateFileProgress(id, progress) {
  98. const file = selectedFiles.value.find(f => f.id === id)
  99. if (file) {
  100. file.progress = progress
  101. }
  102. }
  103. // 更新上传进度
  104. function setUploadProgress(percent, speed, loaded, total) {
  105. uploadProgress.value = percent
  106. uploadSpeed.value = speed
  107. uploadedBytes.value = loaded
  108. totalBytes.value = total
  109. }
  110. // 重置上传进度
  111. function resetUploadProgress() {
  112. uploadProgress.value = 0
  113. uploadSpeed.value = 0
  114. uploadedBytes.value = 0
  115. totalBytes.value = 0
  116. }
  117. return {
  118. // 状态
  119. selectedFiles,
  120. textContent,
  121. textType,
  122. expirationHours,
  123. maxDownloadCount,
  124. password,
  125. uploadResult,
  126. uploading,
  127. // 计算属性
  128. hasFiles,
  129. hasText,
  130. canUpload,
  131. totalFileSize,
  132. // 方法
  133. addFiles,
  134. removeFile,
  135. clearFiles,
  136. reset,
  137. setUploadResult,
  138. setUploading,
  139. updateFileProgress,
  140. setUploadProgress,
  141. resetUploadProgress
  142. }
  143. })