| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import { defineStore } from 'pinia'
- import { ref, computed } from 'vue'
- import config from '../config'
- export const useUploadStore = defineStore('upload', () => {
- // 状态
- const selectedFiles = ref([])
- const textContent = ref('')
- const textType = ref('plain')
- const expirationHours = ref(3)
- const maxDownloadCount = ref(-1)
- const password = ref('')
- const uploadResult = ref(null)
- const uploading = ref(false)
- // 上传进度状态
- const uploadProgress = ref(0) // 0-100
- const uploadSpeed = ref(0) // 字节/秒
- const uploadedBytes = ref(0) // 已上传字节数
- const totalBytes = ref(0) // 总字节数
- // 计算属性
- const hasFiles = computed(() => selectedFiles.value.length > 0)
- const hasText = computed(() => textContent.value.trim().length > 0)
- const canUpload = computed(() => hasFiles.value || hasText.value)
- const totalFileSize = computed(() => {
- return selectedFiles.value.reduce((sum, file) => sum + file.size, 0)
- })
- // 计算剩余时间(秒)
- const remainingTime = computed(() => {
- if (uploadSpeed.value === 0 || uploadProgress.value >= 100) {
- return 0
- }
- const remainingBytes = totalBytes.value - uploadedBytes.value
- return Math.ceil(remainingBytes / uploadSpeed.value)
- })
- // 方法
- function addFiles(files) {
- const remainingSlots = config.maxFiles - selectedFiles.value.length
- const filesToAdd = []
- const rejectedFiles = []
- // 文件大小预检
- for (const file of files.slice(0, remainingSlots)) {
- // 检查文件大小
- if (file.size > config.uploadLimit) {
- rejectedFiles.push({
- file,
- reason: 'size',
- maxSize: config.uploadLimit
- })
- continue
- }
- // 检查是否重复
- if (!selectedFiles.value.some(f => f.name === file.name && f.size === file.size)) {
- filesToAdd.push(file)
- }
- }
- // 添加有效的文件
- filesToAdd.forEach(file => {
- selectedFiles.value.push({
- id: Date.now() + Math.random(),
- file,
- name: file.name,
- size: file.size,
- type: file.type,
- progress: 0
- })
- })
- return {
- added: filesToAdd.length,
- rejected: rejectedFiles
- }
- }
- function removeFile(id) {
- const index = selectedFiles.value.findIndex(f => f.id === id)
- if (index > -1) {
- selectedFiles.value.splice(index, 1)
- }
- }
- function clearFiles() {
- selectedFiles.value = []
- }
- function reset() {
- selectedFiles.value = []
- textContent.value = ''
- textType.value = 'plain'
- expirationHours.value = 3
- maxDownloadCount.value = -1
- password.value = ''
- uploadResult.value = null
- uploading.value = false
- resetUploadProgress() // 重置进度
- }
- function setUploadResult(result) {
- uploadResult.value = result
- }
- function setUploading(status) {
- uploading.value = status
- }
- function updateFileProgress(id, progress) {
- const file = selectedFiles.value.find(f => f.id === id)
- if (file) {
- file.progress = progress
- }
- }
- // 更新上传进度
- function setUploadProgress(percent, speed, loaded, total) {
- uploadProgress.value = percent
- uploadSpeed.value = speed
- uploadedBytes.value = loaded
- totalBytes.value = total
- }
- // 重置上传进度
- function resetUploadProgress() {
- uploadProgress.value = 0
- uploadSpeed.value = 0
- uploadedBytes.value = 0
- totalBytes.value = 0
- }
- return {
- // 状态
- selectedFiles,
- textContent,
- textType,
- expirationHours,
- maxDownloadCount,
- password,
- uploadResult,
- uploading,
- // 计算属性
- hasFiles,
- hasText,
- canUpload,
- totalFileSize,
- // 方法
- addFiles,
- removeFile,
- clearFiles,
- reset,
- setUploadResult,
- setUploading,
- updateFileProgress,
- setUploadProgress,
- resetUploadProgress
- }
- })
|