rkljw пре 19 часа
родитељ
комит
9449dbfc59
4 измењених фајлова са 506 додато и 3 уклоњено
  1. 1 0
      package.json
  2. 5 0
      src/router/index.js
  3. 4 3
      src/views/complaint/complaintList.vue
  4. 496 0
      src/views/file/index.vue

+ 1 - 0
package.json

@@ -47,6 +47,7 @@
     "vue-splitpane": "1.0.4",
     "vuedraggable": "2.20.0",
     "vuex": "3.1.0",
+    "weixin-js-sdk": "^1.6.5",
     "xlsx": "0.14.1"
   },
   "devDependencies": {

+ 5 - 0
src/router/index.js

@@ -50,6 +50,11 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/file',
+    component: () => import('@/views/file/index'),
+    hidden: true
+  },
   {
     path: '/login',
     component: () => import('@/views/login/index'),

+ 4 - 3
src/views/complaint/complaintList.vue

@@ -624,6 +624,7 @@ export default {
     //4.编辑 start ------------------------------------------------------------>
     downloadFile(data,name){  
       let files = [];
+      let names = [];
       let fileName = name;
       if (!Array.isArray(data)) {
         data = [data];
@@ -632,14 +633,14 @@ export default {
       for(let item of data){
         if(item.imgUrl){
           files.push(item.imgUrl);
-        }else{
-          files.push(item)
+          names.push(item.oldFileName);
         }
       }
       //console.log(files)
       let getData = {
         files:files,
-        fileName:fileName
+        fileName:fileName,
+        names:names
       }
 
       this.$store.dispatch('complaint/downloadFile',getData).then(res=> {

+ 496 - 0
src/views/file/index.vue

@@ -0,0 +1,496 @@
+<template>
+  <div class="file-upload-container">
+    <div class="header">
+      <h2>文件上传</h2>
+      <!-- <p>选择文件后提交给小程序</p>
+      <p v-if="type" class="type-info">当前类型: {{ type }}</p>
+      <p v-else class="type-info">未设置类型参数</p> -->
+    </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 class="file-status">
+               <span v-if="uploadedFiles[index]" class="status-success">
+                 <i class="el-icon-check"></i> 已上传
+               </span>
+               <span v-else class="status-uploading">
+                 <i class="el-icon-loading"></i> 上传中...
+               </span>
+             </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="submitToMiniProgram"
+        :disabled="uploadedFiles.length === 0"
+        :loading="submitting"
+      >
+        {{ submitting ? '提交中...' : '提交文件' }} ({{ uploadedFiles.length }}个文件)
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import wx from 'weixin-js-sdk' 
+export default {
+  name: 'FileUpload',
+  data() {
+    return {
+      selectedFiles: [],
+      uploadedFiles: [], // 存储上传后的文件URL
+      submitting: false,
+      type: '' // 从URL接收的type参数
+    }
+  },
+  mounted() {
+    this.checkWechatEnvironment()
+    this.getTypeFromUrl()
+  },
+  methods: {
+    // 从URL获取type参数
+    getTypeFromUrl() {
+      try {
+        // 方法1: 使用URLSearchParams
+        const urlParams = new URLSearchParams(window.location.search)
+        this.type = urlParams.get('type') || ''
+        
+        // 如果URLSearchParams获取不到,尝试其他方法
+        if (!this.type) {
+          // 方法2: 使用正则表达式
+          const match = window.location.search.match(/[?&]type=([^&]*)/)
+          if (match) {
+            this.type = decodeURIComponent(match[1])
+          }
+        }
+        
+        // 方法3: 使用Vue Router的query参数
+        if (!this.type && this.$route && this.$route.query) {
+          this.type = this.$route.query.type || ''
+        }
+        
+        console.log('当前URL:', window.location.href)
+        console.log('URL查询参数:', window.location.search)
+        console.log('从URL接收的type参数:', this.type)
+        console.log('Vue Router query:', this.$route ? this.$route.query : '无路由信息')
+        
+        // 如果还是没有获取到,显示提示
+        if (!this.type) {
+          console.warn('未找到type参数,请检查URL格式,例如: ?type=image')
+        }
+      } catch (error) {
+        console.error('获取type参数时出错:', error)
+      }
+    },
+
+    // 检查微信环境
+    checkWechatEnvironment() {
+      const isWechat = /micromessenger/i.test(navigator.userAgent)
+      if (!isWechat) {
+        this.$message.warning('请在微信中打开此页面')
+      }
+    },
+
+    // 触发文件选择
+    triggerFileInput() {
+      this.$refs.fileInput.click()
+    },
+
+    // 处理文件选择
+    async handleFileSelect(event) {
+      const files = Array.from(event.target.files)
+      
+      for (const file of files) {
+        // 检查文件大小限制 (50MB)
+        if (file.size > 50 * 1024 * 1024) {
+          this.$message.error(`文件 ${file.name} 超过50MB限制`)
+          continue
+        }
+        
+        // 检查是否已存在同名文件
+        const exists = this.selectedFiles.find(f => f.name === file.name)
+        if (exists) {
+          this.$message.warning(`文件 ${file.name} 已存在`)
+          continue
+        }
+        
+        // 添加到选中文件列表
+        this.selectedFiles.push(file)
+        
+        // 上传文件并获取URL
+        try {
+          await this.uploadFile(file)
+        } catch (error) {
+          console.error(`上传文件 ${file.name} 失败:`, error)
+          this.$message.error(`上传文件 ${file.name} 失败`)
+        }
+      }
+      
+      // 清空input值,允许重复选择同一文件
+      event.target.value = ''
+    },
+
+    // 删除文件
+    removeFile(index) {
+      this.selectedFiles.splice(index, 1)
+      // 同时删除对应的上传文件信息
+      if (this.uploadedFiles[index]) {
+        this.uploadedFiles.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 submitToMiniProgram() {
+      if (this.uploadedFiles.length === 0) {
+        this.$message.warning('请先选择并上传文件')
+        return
+      }
+
+      this.submitting = true
+
+      try {
+        // 检查微信环境
+        if (typeof WeixinJSBridge === 'undefined') {
+          this.$message.error('请在微信中打开此页面')
+          return
+        }
+
+        // 通过微信JS-SDK发送消息给小程序
+        if (wx && wx.miniProgram) {
+          // 在微信小程序web-view中
+          wx.miniProgram.postMessage({
+            data: {
+              type: 'file_upload',
+              files: this.uploadedFiles
+            }
+          })
+          
+          this.$message.success('文件已提交给小程序')
+          this.selectedFiles = []
+          this.uploadedFiles = []
+          
+          // 延迟关闭web-view,让用户看到成功提示
+          setTimeout(() => {
+            wx.miniProgram.navigateBack({
+              delta: 1
+            })
+          }, 1500)
+        } else {
+          // 如果不在小程序web-view中,提示用户
+          this.$message.error('请在微信小程序中打开此页面')
+        }
+
+      } catch (error) {
+        console.error('提交文件失败:', error)
+        this.$message.error('提交失败,请重试')
+      } finally {
+        this.submitting = false
+      }
+    },
+    uploadFile(file) {
+        return new Promise((resolve, reject) => {
+            const formData = new FormData();
+            formData.append('file', file);
+            
+            this.$store.dispatch('pool/uploadFile', formData).then(res => {
+              if(res.code == 200){
+                const fileInfo = {
+                  imgUrl:res.data.imgUrl,
+                  id:res.data.id,
+                  src:res.data.src,
+                  fileName:res.data.fileName,
+                  fileType:res.data.fileType,
+                  oldFileName:res.data.oldFileName,
+                  oldName:res.data.oldName,
+                  type: this.type, // 添加从URL接收的type参数
+                };
+                
+                // 添加到已上传文件列表
+                this.uploadedFiles.push(fileInfo);
+                console.log('文件上传成功:', fileInfo);
+                resolve(fileInfo);
+              }else{
+                this.$message({
+                  type: 'info',
+                  message: res.message
+                });
+                
+                // 从selectedFiles中删除上传失败的文件
+                const fileIndex = this.selectedFiles.findIndex(f => f.name === file.name);
+                if (fileIndex !== -1) {
+                    this.selectedFiles.splice(fileIndex, 1);
+                }
+                
+                reject(res.message);
+              }
+            }).catch((error) => {
+                console.error('文件上传失败:', error);
+                this.$message({
+                    type: 'error',
+                    message: `上传文件 ${file.name} 失败,请重试!`
+                });
+                
+                // 从selectedFiles中删除上传失败的文件
+                const fileIndex = this.selectedFiles.findIndex(f => f.name === file.name);
+                if (fileIndex !== -1) {
+                    this.selectedFiles.splice(fileIndex, 1);
+                }
+                
+                reject(error);
+            });
+        });
+    },
+  }
+}
+</script>
+
+<style scoped>
+.file-upload-container {
+  max-width: 800px;
+  margin: 0 auto;
+  padding: 20px;
+  background: #fff;
+  min-height: 100vh;
+}
+
+.header {
+  text-align: center;
+  margin-bottom: 30px;
+}
+
+.header h2 {
+  color: #303133;
+  margin-bottom: 10px;
+}
+
+.header p {
+  color: #909399;
+  font-size: 14px;
+}
+
+.type-info {
+  background: #f0f9ff;
+  border: 1px solid #409eff;
+  border-radius: 4px;
+  padding: 8px 12px;
+  margin-top: 10px;
+  font-size: 12px;
+  color: #409eff;
+}
+
+.upload-area {
+  border: 2px dashed #d9d9d9;
+  border-radius: 8px;
+  padding: 40px;
+  text-align: center;
+  cursor: pointer;
+  transition: all 0.3s;
+  background: #fafafa;
+}
+
+.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-top: 30px;
+}
+
+.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-status {
+  margin-top: 5px;
+}
+
+.status-success {
+  color: #67c23a;
+  font-size: 12px;
+}
+
+.status-success i {
+  margin-right: 3px;
+}
+
+.status-uploading {
+  color: #e6a23c;
+  font-size: 12px;
+}
+
+.status-uploading i {
+  margin-right: 3px;
+  animation: rotating 2s linear infinite;
+}
+
+@keyframes rotating {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+.file-actions {
+  margin-left: 15px;
+}
+
+.submit-area {
+  margin-top: 30px;
+  text-align: center;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .file-upload-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>