vue2 多个文件模板上传图片文件 实现

40 阅读2分钟
<template>
  <el-dialog
    class="root-box"
    :visible.sync="dialogVisible"
    title="投保信息"
    :close-on-click-modal="false"
    width="50%"
    @close="closeHandle"
  >
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="120px"
    >
      <el-form-item label="承保公司:" prop="company" :rules="rules.company">
        <el-input
          v-model="ruleForm.company"
          placeholder="请输入"
          maxlength="100"
          style="width: 300px"
        />
      </el-form-item>
      <el-form-item label="保单编号:" prop="orderNo" :rules="rules.orderNo">
        <el-input
          v-model="ruleForm.orderNo"
          placeholder="请输入"
          maxlength="100"
          style="width: 300px"
        />
      </el-form-item>
      <el-form-item label="保险起期:" prop="startTime" :rules="rules.startTime">
        <el-date-picker
          style="width: 300px"
          v-model="ruleForm.startTime"
          type="datetime"
          placeholder="选择日期时间"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
        />
      </el-form-item>
      <el-form-item label="保险止期:" prop="endTime" :rules="rules.endTime">
        <el-date-picker
          style="width: 300px"
          v-model="ruleForm.endTime"
          type="datetime"
          placeholder="选择日期时间"
          format="yyyy-MM-dd"
          value-format="yyyy-MM-dd"
        />
      </el-form-item>
      <el-form-item label="承保容量:" prop="rongliang" :rules="rules.rongliang">
        <el-input
          v-model="ruleForm.rongliang"
          placeholder="请输入"
          maxlength="100"
          style="width: 300px"
        />
      </el-form-item>
      <el-form-item label="承保里程:" prop="licheng" :rules="rules.licheng">
        <el-input
          v-model="ruleForm.licheng"
          placeholder="请输入"
          maxlength="100"
          style="width: 300px"
        />
      </el-form-item>
      <el-form-item label="车辆使用性质:" prop="useCar" :rules="rules.useCar">
        <el-select v-model="ruleForm.useCar" placeholder="请选择">
          <el-option
            v-for="item in timeOption"
            :key="item.key"
            :label="item.label"
            :value="item.key"
          />
        </el-select>
      </el-form-item>
    </el-form>
    <div class="upload-file">上传附件</div>
    <div
      class="upload-content"
      v-for="(item, index) in fileTemplates"
      :key="index"
    >
      <div class="filename">{{ item.fileName }}</div>
      <el-upload
        action="/"
        list-type="picture-card"
        :on-preview="(file) => handlePictureCardPreview(file, index)"
        :on-change="
          (file, fileList) => {
            handleChange(file, fileList, index);
          }
        "
        :on-exceed="handleFileLimit"
        multiple
        :file-list="fileLists[index]"
        :auto-upload="false"
        accept="image/*"
        :limit="2"
      >
        <img
          src="~@/assets/order-certificate/upload/upload.png"
          class="album-icon"
        />
      </el-upload>
    </div>
    <el-dialog :visible.sync="picDialogVisible" :modal="false">
      <el-carousel
        ref="elCarousel"
        :autoplay="false"
        height="700px"
        :initial-index="currentFileListIndex"
      >
        <el-carousel-item v-for="(file, idx) in currentFileList" :key="idx">
          <img :src="file.url" alt="Uploaded Image" class="uploaded-image" />
        </el-carousel-item>
      </el-carousel>
    </el-dialog>

    <div class="footer">
      <el-button type="primary" @click="confirm">确定</el-button>
      <el-button style="margin-left: 50px">过期未检测</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { upload } from '@/utils/oss';
export default {
  name: "EditOrderInfoDialog",
  props: {},
  data() {
    return {
      dialogVisible: false,
      picDialogVisible: false,
      fileList: [],
      ruleForm: {
         uploadedFileList: [], 
      },
      rules: {
        company: [{ required: true, message: "请输入", trigger: "blur" }],
        rightTime: [
          { required: true, message: "请输入", trigger: "blur" },
          { pattern: /^\d{1,3}$/, message: "1-3位数字", trigger: "blur" },
        ],
        mount: [
          { required: true, message: "请输入", trigger: "blur" },
          { pattern: /^\d{1,6}$/, message: "1-6位数字", trigger: "blur" },
        ],
        channelCompany: [
          { required: true, message: "请输入", trigger: "change" },
        ],
        quanyi1: [{ required: true, message: "请输入", trigger: "blur" }],
        quanyiName: [{ required: true, message: "请选择", trigger: "change" }],
        rangeTime: [{ required: true, message: "请选择", trigger: "change" }],
        number: [
          { required: true, message: "请输入数量", trigger: "blur" },
          { pattern: /^\d{1,6}$/, message: "1-6位数字", trigger: "blur" },
        ],
        time: [
          { required: true, message: "请输入有效期", trigger: "blur" },
          { pattern: /^\d{1,6}$/, message: "1-6位数字", trigger: "blur" },
        ],
      },
      timeOption: [{ key: "私家车", label: "私家车" }],
      fileTemplates: [{ fileName: "检测报告" }, { fileName: "保单" }],
      fileLists: [], // 存储每个 el-upload 的文件列表
      currentFileList: [], // 存储当前点击的 el-upload 的文件列表
      currentFileListIndex: 0, //用于存储被点击图片的索引
    };
  },
  methods: {
    showDialog() {
      this.dialogVisible = true;
    },
    closeHandle() {
      this.$emit("close");
    },

    handleFileLimit(files,fileList){
        console.log("handleFileLimit:", files, fileList);
        this.$message.error("每个附件最多只能上传2张图片!!");
    },

    handleChange(file, fileList, index) {
      console.log("handleChange:", file, fileList, index);
      // if (fileList.length > 2) {
      //   // 如果超过5个,移除最新添加的文件
      //   this.$message.error("每个附件最多只能上传2张图片。");
      //   fileList.splice(2); // 保留前2个文件,移除多余的
      // } else {
      //   // 如果没有超过,更新文件列表
      //   this.fileLists[index] = fileList.slice(0, 2); // 防止用户一次选择多个文件导致超过限制个
      // }
      this.fileLists[index] = fileList
      //选中后文件上传
      this.fileUpload(file,index)
    },

    handlePictureCardPreview(file, uploadIndex) {
      // 查找点击的图片在当前文件列表中的索引
      const clickedImageIndex = this.fileLists[uploadIndex].findIndex(
        (f) => f.name === file.name
      );
      console.log(
        "handlePictureCardPreview:",
        file,
        uploadIndex,
        clickedImageIndex
      );
      // 更新当前文件列表和被点击图片的索引
      this.currentFileList = this.fileLists[uploadIndex];
      this.currentFileListIndex = clickedImageIndex;
      this.setActiveItem(clickedImageIndex);
      // 当点击图片时,显示模态框
      this.picDialogVisible = true;
    },
    setActiveItem(index) {
      // 使用 $nextTick 确保 DOM 更新完成后再调用 setActiveItem 方法
      this.$nextTick(() => {
        if (this.$refs.elCarousel) {
          this.$refs.elCarousel.setActiveItem(index);
        }
      });
    },

    async fileUpload(file,index) {
      const fileName = file.name;
      const res = await upload(file.raw);
      console.log('22handleFileUpload', res);
      if (!(String(res.data.code) === '0')) {
        this.$message.error(res.data.message);
        return;
      }
      const data = res.data.data;

      const fileItem = {
        fileId: data.picId,
        fileName: fileName
      };
      // 确保 uploadedFileList 的相应索引已经初始化为数组
    if (!Array.isArray(this.ruleForm.uploadedFileList[index])) {
      this.$set(this.ruleForm.uploadedFileList, index, []); // 为 uploadedFileList 在 index 处创建一个空数组
    }
      this.ruleForm.uploadedFileList[index].push(fileItem);
       console.log('this.ruleForm', this.ruleForm);
    },


    async confirm() {
      const valid = await new Promise((resolve, reject) => {
        this.$refs.ruleForm.validate((valid) => {
          if (valid) {
            resolve(true);
          } else {
            resolve(false);
          }
        });
      });
      console.log("valid", valid);
    },
  },
};
</script>

<style lang="scss" scoped>
.root-box {
  ::v-deep .el-form-item__label {
    color: #646464;

    font-weight: 400;
  }

  .upload-file {
    font-family: PingFangSC-Medium;
    font-size: 16px;
    color: #383838;
    letter-spacing: 0;
    font-weight: bold;
  }
  .upload-content {
    margin: 10px 20px 10px 20px;
    .filename {
      margin-bottom: 10px;
      font-weight: bold;
    }
  }
  .uploaded-image {
    max-width: 100%; /* 限定图片的最大宽度为容器宽度 */
    max-height: 100%; /* 限定图片的最大高度为容器高度 */
    display: block; /* 防止图片下方出现空隙 */
    margin: auto; /* 水平和垂直居中 */
  }
  .footer {
    width: 100%;
    display: flex;
    justify-items: center;
    justify-content: center;
  }
}
</style>