|
@@ -1,385 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="test-container">
|
|
|
- <h2>文件上传测试页面</h2>
|
|
|
- <p>这个页面用于测试文件上传功能,可以在浏览器中直接访问</p>
|
|
|
-
|
|
|
- <div class="test-info">
|
|
|
- <h3>测试说明:</h3>
|
|
|
- <ul>
|
|
|
- <li>此页面可以在任何浏览器中访问</li>
|
|
|
- <li>文件选择功能会正常工作</li>
|
|
|
- <li>提交功能会模拟发送数据</li>
|
|
|
- <li>实际使用时需要在微信小程序中打开</li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="upload-area" @click="triggerFileInput">
|
|
|
- <div class="upload-icon">
|
|
|
- <i class="el-icon-upload"></i>
|
|
|
- </div>
|
|
|
- <div class="upload-text">
|
|
|
- <p>点击选择文件</p>
|
|
|
- <p class="upload-hint">支持图片、文档、视频等格式</p>
|
|
|
- </div>
|
|
|
- <input
|
|
|
- ref="fileInput"
|
|
|
- type="file"
|
|
|
- multiple
|
|
|
- accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.mp4,.mp3"
|
|
|
- @change="handleFileSelect"
|
|
|
- style="display: none"
|
|
|
- />
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="selectedFiles.length > 0" class="file-list">
|
|
|
- <h3>已选择的文件</h3>
|
|
|
- <div class="file-item" v-for="(file, index) in selectedFiles" :key="index">
|
|
|
- <div class="file-info">
|
|
|
- <div class="file-icon">
|
|
|
- <i :class="getFileIcon(file.type)"></i>
|
|
|
- </div>
|
|
|
- <div class="file-details">
|
|
|
- <div class="file-name">{{ file.name }}</div>
|
|
|
- <div class="file-size">{{ formatFileSize(file.size) }}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="file-actions">
|
|
|
- <el-button
|
|
|
- type="danger"
|
|
|
- size="mini"
|
|
|
- @click="removeFile(index)"
|
|
|
- icon="el-icon-delete"
|
|
|
- >
|
|
|
- 删除
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="submit-area">
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- size="large"
|
|
|
- @click="testSubmit"
|
|
|
- :disabled="selectedFiles.length === 0"
|
|
|
- :loading="submitting"
|
|
|
- >
|
|
|
- {{ submitting ? '提交中...' : '测试提交' }}
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="testResult" class="test-result">
|
|
|
- <h3>测试结果:</h3>
|
|
|
- <pre>{{ testResult }}</pre>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-export default {
|
|
|
- name: 'FileUploadTest',
|
|
|
- data() {
|
|
|
- return {
|
|
|
- selectedFiles: [],
|
|
|
- submitting: false,
|
|
|
- testResult: ''
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- triggerFileInput() {
|
|
|
- this.$refs.fileInput.click()
|
|
|
- },
|
|
|
-
|
|
|
- handleFileSelect(event) {
|
|
|
- const files = Array.from(event.target.files)
|
|
|
-
|
|
|
- files.forEach(file => {
|
|
|
- if (file.size > 50 * 1024 * 1024) {
|
|
|
- this.$message.error(`文件 ${file.name} 超过50MB限制`)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- const exists = this.selectedFiles.find(f => f.name === file.name)
|
|
|
- if (exists) {
|
|
|
- this.$message.warning(`文件 ${file.name} 已存在`)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- this.selectedFiles.push(file)
|
|
|
- })
|
|
|
-
|
|
|
- event.target.value = ''
|
|
|
- },
|
|
|
-
|
|
|
- removeFile(index) {
|
|
|
- this.selectedFiles.splice(index, 1)
|
|
|
- },
|
|
|
-
|
|
|
- getFileIcon(type) {
|
|
|
- if (type.startsWith('image/')) {
|
|
|
- return 'el-icon-picture'
|
|
|
- } else if (type.includes('pdf')) {
|
|
|
- return 'el-icon-document'
|
|
|
- } else if (type.includes('word') || type.includes('document')) {
|
|
|
- return 'el-icon-document'
|
|
|
- } else if (type.includes('excel') || type.includes('spreadsheet')) {
|
|
|
- return 'el-icon-document'
|
|
|
- } else if (type.includes('video')) {
|
|
|
- return 'el-icon-video-camera'
|
|
|
- } else if (type.includes('audio')) {
|
|
|
- return 'el-icon-headset'
|
|
|
- } else {
|
|
|
- return 'el-icon-document'
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- formatFileSize(bytes) {
|
|
|
- if (bytes === 0) return '0 B'
|
|
|
- const k = 1024
|
|
|
- const sizes = ['B', 'KB', 'MB', 'GB']
|
|
|
- const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
|
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
|
|
- },
|
|
|
-
|
|
|
- async testSubmit() {
|
|
|
- if (this.selectedFiles.length === 0) {
|
|
|
- this.$message.warning('请先选择文件')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- this.submitting = true
|
|
|
- this.testResult = ''
|
|
|
-
|
|
|
- try {
|
|
|
- const filesData = await this.prepareFilesData()
|
|
|
-
|
|
|
- // 模拟提交数据
|
|
|
- const mockResult = {
|
|
|
- success: true,
|
|
|
- message: '测试提交成功',
|
|
|
- timestamp: new Date().toISOString(),
|
|
|
- filesCount: filesData.length,
|
|
|
- files: filesData.map(file => ({
|
|
|
- name: file.name,
|
|
|
- type: file.type,
|
|
|
- size: file.size,
|
|
|
- dataLength: file.data.length
|
|
|
- }))
|
|
|
- }
|
|
|
-
|
|
|
- this.testResult = JSON.stringify(mockResult, null, 2)
|
|
|
- this.$message.success('测试提交成功')
|
|
|
-
|
|
|
- // 清空文件列表
|
|
|
- this.selectedFiles = []
|
|
|
-
|
|
|
- } catch (error) {
|
|
|
- console.error('测试提交失败:', error)
|
|
|
- this.$message.error('测试提交失败')
|
|
|
- this.testResult = JSON.stringify({ error: error.message }, null, 2)
|
|
|
- } finally {
|
|
|
- this.submitting = false
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- async prepareFilesData() {
|
|
|
- const filesData = []
|
|
|
-
|
|
|
- for (const file of this.selectedFiles) {
|
|
|
- try {
|
|
|
- const base64 = await this.fileToBase64(file)
|
|
|
- filesData.push({
|
|
|
- name: file.name,
|
|
|
- type: file.type,
|
|
|
- size: file.size,
|
|
|
- data: base64
|
|
|
- })
|
|
|
- } catch (error) {
|
|
|
- console.error('转换文件失败:', error)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return filesData
|
|
|
- },
|
|
|
-
|
|
|
- fileToBase64(file) {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const reader = new FileReader()
|
|
|
- reader.onload = () => resolve(reader.result)
|
|
|
- reader.onerror = reject
|
|
|
- reader.readAsDataURL(file)
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped>
|
|
|
-.test-container {
|
|
|
- max-width: 800px;
|
|
|
- margin: 0 auto;
|
|
|
- padding: 20px;
|
|
|
- background: #fff;
|
|
|
- min-height: 100vh;
|
|
|
-}
|
|
|
-
|
|
|
-.test-info {
|
|
|
- background: #f0f9ff;
|
|
|
- border: 1px solid #b3d8ff;
|
|
|
- border-radius: 6px;
|
|
|
- padding: 15px;
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.test-info h3 {
|
|
|
- margin-top: 0;
|
|
|
- color: #409eff;
|
|
|
-}
|
|
|
-
|
|
|
-.test-info ul {
|
|
|
- margin: 10px 0;
|
|
|
- padding-left: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.test-info li {
|
|
|
- margin: 5px 0;
|
|
|
- color: #606266;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-area {
|
|
|
- border: 2px dashed #d9d9d9;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 40px;
|
|
|
- text-align: center;
|
|
|
- cursor: pointer;
|
|
|
- transition: all 0.3s;
|
|
|
- background: #fafafa;
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-area:hover {
|
|
|
- border-color: #409eff;
|
|
|
- background: #f0f9ff;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-icon {
|
|
|
- font-size: 48px;
|
|
|
- color: #c0c4cc;
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-text p {
|
|
|
- margin: 5px 0;
|
|
|
- color: #606266;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-hint {
|
|
|
- font-size: 12px;
|
|
|
- color: #c0c4cc;
|
|
|
-}
|
|
|
-
|
|
|
-.file-list {
|
|
|
- margin: 20px 0;
|
|
|
-}
|
|
|
-
|
|
|
-.file-list h3 {
|
|
|
- margin-bottom: 15px;
|
|
|
- color: #303133;
|
|
|
-}
|
|
|
-
|
|
|
-.file-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- padding: 15px;
|
|
|
- border: 1px solid #ebeef5;
|
|
|
- border-radius: 6px;
|
|
|
- margin-bottom: 10px;
|
|
|
- background: #fff;
|
|
|
- transition: all 0.3s;
|
|
|
-}
|
|
|
-
|
|
|
-.file-item:hover {
|
|
|
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
-}
|
|
|
-
|
|
|
-.file-info {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- flex: 1;
|
|
|
-}
|
|
|
-
|
|
|
-.file-icon {
|
|
|
- font-size: 24px;
|
|
|
- color: #409eff;
|
|
|
- margin-right: 15px;
|
|
|
-}
|
|
|
-
|
|
|
-.file-details {
|
|
|
- flex: 1;
|
|
|
-}
|
|
|
-
|
|
|
-.file-name {
|
|
|
- font-weight: 500;
|
|
|
- color: #303133;
|
|
|
- margin-bottom: 5px;
|
|
|
- word-break: break-all;
|
|
|
-}
|
|
|
-
|
|
|
-.file-size {
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
-}
|
|
|
-
|
|
|
-.file-actions {
|
|
|
- margin-left: 15px;
|
|
|
-}
|
|
|
-
|
|
|
-.submit-area {
|
|
|
- margin: 20px 0;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.test-result {
|
|
|
- margin-top: 20px;
|
|
|
- background: #f5f5f5;
|
|
|
- border-radius: 6px;
|
|
|
- padding: 15px;
|
|
|
-}
|
|
|
-
|
|
|
-.test-result h3 {
|
|
|
- margin-top: 0;
|
|
|
- color: #303133;
|
|
|
-}
|
|
|
-
|
|
|
-.test-result pre {
|
|
|
- background: #fff;
|
|
|
- border: 1px solid #ddd;
|
|
|
- border-radius: 4px;
|
|
|
- padding: 10px;
|
|
|
- overflow-x: auto;
|
|
|
- font-size: 12px;
|
|
|
- line-height: 1.4;
|
|
|
-}
|
|
|
-
|
|
|
-@media (max-width: 768px) {
|
|
|
- .test-container {
|
|
|
- padding: 15px;
|
|
|
- }
|
|
|
-
|
|
|
- .upload-area {
|
|
|
- padding: 30px 20px;
|
|
|
- }
|
|
|
-
|
|
|
- .file-item {
|
|
|
- flex-direction: column;
|
|
|
- align-items: flex-start;
|
|
|
- }
|
|
|
-
|
|
|
- .file-actions {
|
|
|
- margin-left: 0;
|
|
|
- margin-top: 10px;
|
|
|
- align-self: flex-end;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|