文件上传 ,显示文件列

javascript 复制代码
 <Dialog
      :visible.sync="registerProblemPieceShow"
      @close="registerProblemPieceClose"
      title="登记问题件"
      width="900px"
      v-dialogDrag
      append-to-body
      destroy-on-close
    >
      <div class="registerProblemPiece_content">
        <RegisterProblemPiece ref="RegisterProblemPieceRef"></RegisterProblemPiece>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="registerProblemPieceClose()">关闭</el-button>
        <el-button type="primary" @click="registerProblemPieceSubmit()">确定</el-button>
      </span>
    </Dialog>



    // 登记问题件
    registerProblemPiece () {
      this.registerProblemPieceShow = true
    },
    registerProblemPieceClose () {
      this.$refs.RegisterProblemPieceRef.resetForm()
      this.registerProblemPieceShow = false
    },

    async registerProblemPieceSubmit () {
      try {
        const res = await this.$refs.RegisterProblemPieceRef.handleSubmit()
        console.log('res:', res)
        this.registerProblemPieceClose()
      } catch (error) {
        console.log('error:', error)
        this.$message.error(error.message)
      }
    },
javascript 复制代码
<template>
  <div class="registerProblemPiece_content">
    <el-form
      :model="registerProblemPieceForm"
      :rules="registerProblemPieceRules"
      :label-width="'100px'"
      size="medium"
      ref="registerProblemPieceFormRef"
    >
      <el-form-item label="问题件类型" prop="problemType">
        <el-select v-model="registerProblemPieceForm.problemType" placeholder="请选择问题件类型" style="width: 260px">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="registerProblemPieceForm.remark"
          placeholder="请输入备注"
          type="textarea"
          :rows="4"
          :maxlength="200"
          show-word-limit
          style="width: 700px"
        ></el-input>
      </el-form-item>

      <div class="upload-section">
        <el-form-item label="附件" prop="attachment" class="upload-container">
          <el-upload
            ref="upload"
            class="upload-component"
            action="#"
            drag
            :file-list="fileList"
            :multiple="true"
            :auto-upload="false"
            accept=".pdf,.jpg,.png,.jpeg"
            :limit="5"
            :on-change="handleChange"
            :on-remove="handleRemove"
            :on-exceed="handleExceed"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          </el-upload>
        </el-form-item>

        <div class="upload-tips">
          <div><i class="el-icon-warning-outline"></i> 温馨提示:</div>
          <div>1. 最多上传5个文件</div>
          <div>2. 格式:只允许上传 <span style="color: red">png、jpg、pdf</span></div>
          <div>3. 文件大小:单个文件最大5M</div>
        </div>
      </div>
    </el-form>
  </div>
</template>

<script>
export default {
  data () {
    return {
      registerProblemPieceForm: {
        problemType: '',
        remark: '',
        attachment: []
      },
      registerProblemPieceRules: {
        problemType: [{ required: true, message: '请选择问题件类型', trigger: 'change' }],
        remark: [{ required: true, message: '请输入备注', trigger: 'blur' }]
      },
      options: [
        { value: '1', label: '问题件类型1' },
        { value: '2', label: '问题件类型2' }
      ],
      fileList: []
    }
  },

  methods: {
    // 文件状态改变时的钩子
    async handleChange (file, fileList) {
      // 只处理新添加的文件
      if (file.status !== 'ready') return

      // 检查文件有效性并上传
      if (!this.isValidFile(file)) {
        this.$nextTick(() => this.$refs.upload.handleRemove(file))
        return
      }

      await this.uploadFile(file)
      this.fileList = fileList
    },

    // 验证文件是否有效
    isValidFile (file) {
      if (!file || !file.name) {
        this.$message.error('无效的文件')
        return false
      }

      const fileName = file.name
      const fileExt = fileName.substring(fileName.lastIndexOf('.')).toLowerCase()
      const validExtensions = ['.pdf', '.jpg', '.png', '.jpeg']
      const isValidType = validExtensions.includes(fileExt)
      const isValidSize = file.size / 1024 / 1024 < 5

      if (!isValidType) {
        this.$message.error(`文件 ${fileName} 格式不支持,只能上传 pdf、jpg、png、jpeg 格式!`)
        return false
      }

      if (!isValidSize) {
        this.$message.error(`文件 ${fileName} 过大,文件大小不能超过 5MB!`)
        return false
      }

      return true
    },

    // 处理文件上传
    async uploadFile (file) {
      try {
        const formData = new FormData()
        formData.append('file', file.raw)

        const res = await this.$request({
          url: `/file2`,
          method: 'post',
          data: formData
        })

        // 添加新上传的文件到 attachment 数组
        this.registerProblemPieceForm.attachment.push({
          ...res.data,
          uid: file.uid || Date.now()
        })
      } catch (error) {
        console.error('文件上传失败:', error)
        this.$message.error('文件上传失败,请重试')
        this.$nextTick(() => this.$refs.upload.handleRemove(file))
      }
    },

    handleRemove (file) {
      this.registerProblemPieceForm.attachment = this.registerProblemPieceForm.attachment.filter(
        (item) => item.uid !== file.uid
      )
      this.fileList = this.fileList.filter((item) => item.uid !== file.uid)
    },

    // 返回表单验证Promise
    async handleSubmit () {
      return new Promise((resolve, reject) => {
        this.$refs.registerProblemPieceFormRef.validate((valid) => {
          if (!valid) reject(new Error('提交失败,检查内容完整'))
          resolve(this.registerProblemPieceForm)
        })
      })
    },

    handleExceed () {
      this.$message.warning('只能上传5个文件')
    },

    // 重置表单
    resetForm () {
      this.$refs.registerProblemPieceFormRef.resetFields()
      this.registerProblemPieceForm = {
        problemType: '',
        remark: '',
        attachment: []
      }
      this.fileList = []
      this.$refs.upload.clearFiles()
      this.$refs.upload.handleRemove()
    },

    // 获取表单数据
    getFormData () {
      return this.registerProblemPieceForm
    }
  }
}
</script>
<style lang="scss" scoped>
.registerProblemPiece_content {
  padding-top: 30px;
}
.upload-section {
  display: flex;
  width: 100%;
  margin-top: 10px;

  .upload-container {
    width: 350px;
    margin-right: 20px;

    .upload-component {
      width: 100%;
    }
  }

  .upload-tips {
    color: #606266;
    font-size: 13px;
    line-height: 1.5;
    padding-top: 16px;

    i {
      color: #e6a23c;
      margin-right: 4px;
    }
  }
}
::v-deep .el-upload-dragger {
  width: 100%;
  height: 100px !important;
  line-height: 0;
}

::v-deep .el-icon-upload {
  margin: 0;
  margin-bottom: 4px;
  line-height: normal;
}

::v-deep .el-upload-list__item {
  transition: none !important;
}
</style>
相关推荐
福兮说14 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理14 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
专业程序开发源15 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
专业程序开发源15 小时前
springboot社区养老系统44071-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
小呆呆66615 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)15 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan16 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_17 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒17 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技17 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端