Kaynağa Gözat

介绍信附件改为图片显示

xujie 1 yıl önce
ebeveyn
işleme
bdc0e45904

+ 214 - 0
src/components/ImageFileListPreview/index.vue

@@ -0,0 +1,214 @@
+<template>
+  <!-- <el-image
+    :src="`${realSrc}`"
+    fit="cover"
+    :style="`width:${realWidth};height:${realHeight};`"
+    :preview-src-list="realSrcList"
+  >
+    <div slot="error" class="image-slot">
+      <i class="el-icon-picture-outline"></i>
+    </div>
+  </el-image> -->
+
+  <div class="uploaders">
+    <div class="images">
+      <div v-for="(v, i) in fileList" :key="i">
+        <!-- -->
+        <slot v-if="$slots.default"
+              :v="v"
+              :i="i"></slot>
+        <!-- -->
+        <div class="image relative"
+             v-else>
+          <el-image :src="v.url"
+                    class="avatar"
+                    :preview-src-list="previewSrcList"
+                    :z-index="6000" />
+          <!-- <i v-show="!disabled"
+             class="el-icon-error"
+             @click="onRemove(i)"></i> -->
+        </div>
+      </div>
+  </div>
+   </div>
+</template>
+
+<script>
+import {imageUrl} from "@/utils/ruoyi";
+export default {
+  name: "ImageListPreview",
+  data() {
+    return {
+      fileList: [],
+      previewSrcList:[]
+    }
+  },
+  watch: {
+    value: {
+      immediate: true,
+      handler(newVal) {
+        if(newVal){
+        const list = Array.isArray(newVal) ? newVal : this.value.split(",");
+        this.fileList = list.map((data) => {
+          let item = JSON.parse(data);
+          item = {
+            name: item.name,
+            url: item.url.indexOf('http') > -1 ?   item.url : imageUrl(item.url),
+          }
+          return item;
+        });
+        this.previewSrcList = this.fileList.map((img) => img.url);
+        console.log("fileList",this.fileList,this.previewSrcList);
+      }
+        else{
+          this.fileList =[];
+          this.previewSrcList=[];
+        }
+      },
+    },
+  },
+  props: {
+    value: {
+      type: [Array,String],
+      default: [],
+    },
+    src: {
+      type: String,
+      default: ""
+    },
+    width: {
+      type: [Number, String],
+      default: ""
+    },
+    height: {
+      type: [Number, String],
+      default: ""
+    }
+  },
+  computed: {
+    realSrc() {
+      if (!this.src) {
+        return;
+      }
+      let real_src = this.src.split(",")[0];
+      return real_src;
+    },
+    realSrcList() {
+      if (!this.src) {
+        return;
+      }
+      let real_src_list = this.src.split(",");
+      let srcList = [];
+      real_src_list.forEach(item => {
+        return srcList.push(item);
+      });
+      return srcList;
+    },
+    realWidth() {
+      return typeof this.width == "string" ? this.width : `${this.width}px`;
+    },
+    realHeight() {
+      return typeof this.height == "string" ? this.height : `${this.height}px`;
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.el-image {
+  border-radius: 5px;
+  background-color: #ebeef5;
+  box-shadow: 0 0 5px 1px #ccc;
+  ::v-deep .el-image__inner {
+    transition: all 0.3s;
+    cursor: pointer;
+    &:hover {
+      transform: scale(1.2);
+    }
+  }
+  ::v-deep .image-slot {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+    color: #909399;
+    font-size: 30px;
+  }
+}
+$width: 100px;
+$height: 100px;
+
+.uploaders {
+  .red {
+    font-size: 12px;
+  }
+  //
+  .image {
+    float: left;
+    margin-right: 4px;
+    margin-bottom: 4px;
+    width: $width;
+    height: $height;
+    border: 1px solid #d9d9d9;
+    position: relative;
+
+    .avatar {
+      width: 100%;
+      height: 100%;
+    }
+
+    &:hover {
+      i.el-icon-error {
+        display: block;
+      }
+    }
+    i.el-icon-error {
+      display: none;
+      position: absolute;
+      top: 4px;
+      right: 4px;
+      font-size: 20px;
+    }
+  }
+
+  //
+  .uploader {
+    width: $width;
+    height: $height;
+    float: left;
+    position: relative;
+    margin-right: 4px;
+    margin-bottom: 4px;
+    .el-upload {
+      width: 100%;
+      height: 100%;
+      border: 1px dashed #d9d9d9;
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .el-upload:hover {
+      border-color: #20a0ff;
+    }
+    .avatar {
+      width: 100%;
+      height: 100%;
+      display: block;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+    }
+    .el-upload__input {
+      opacity: 0;
+      position: absolute;
+    }
+  }
+}
+</style>

+ 398 - 0
src/components/ImageFileUpload/index.vue

@@ -0,0 +1,398 @@
+<template>
+  <div class="component-upload-image">
+    <el-upload
+      v-if="type === 'more'"
+      multiple
+      action="#"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :limit="limit"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      ref="imageUpload"
+      :on-remove="handleDelete"
+      :show-file-list="true"
+      :headers="headers"
+      :file-list="fileList"
+      :on-preview="handlePictureCardPreview"
+      :http-request="uploadImage"
+      :class="{ hide: fileList.length >= limit }"
+    >
+      <i class="el-icon-plus"></i>
+      <!-- 上传提示 -->
+      <div class="el-upload__tip" slot="tip" v-if="showTip">
+        请上传
+        <template v-if="fileSize">
+          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
+        </template>
+        <template v-if="fileType">
+          格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
+        </template>
+        的文件
+      </div>
+    </el-upload>
+    <el-upload
+      v-if="type === 'radioIcon'"
+      action="#"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :limit="1"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      ref="imageUpload"
+      :on-remove="handleDelete"
+      :show-file-list="true"
+      :headers="headers"
+      :file-list="fileList"
+      :on-preview="handlePictureCardPreview"
+      :http-request="uploadImage"
+      :class="{ hide: fileList.length >0  }"
+    >
+      <i class="el-icon-plus"></i>
+
+      <!-- 上传提示 -->
+      <div  class="el-upload__tip" slot="tip" >
+        请上传
+        <template v-if="fileSize">
+          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
+        </template>
+        <template v-if="fileType">
+          格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
+        </template>
+        的文件
+      </div>
+    </el-upload>
+    <el-upload
+      v-if="type === 'alone'"
+      drag
+      action="#"
+      :before-upload="handleBeforeUpload"
+      :limit="2"
+      :on-error="handleUploadError"
+      ref="imageUpload"
+      :show-file-list="false"
+      :file-list="fileList"
+      :http-request="uploadImage"
+    >
+      <div v-if="fileList.length > 0" class="img-box">
+        <img style="width: 100%; height: 100%" :src="fileList[0].url" alt="" />
+        <div class="img-model" @click.stop="clickImg">
+          <span>预览</span>
+        </div>
+      </div>
+      <div v-else>
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <div class="el-upload__tip" slot="tip" v-if="showTip">
+          请上传
+          <template v-if="fileSize">
+            大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
+          </template>
+          <template v-if="fileType">
+            格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
+          </template>
+          的文件
+        </div>
+        <!--        <div class="el-upload__tip" slot="tip">只能上传jpg/png/jpeg文件,且不超过500kb</div>-->
+      </div>
+    </el-upload>
+
+    <DialogCom
+      :visible.sync="dialogVisible"
+      title="预览"
+      width="800"
+      append-to-body
+    >
+      <img
+        :src="dialogImageUrl"
+        style="display: block; max-width: 100%; margin: 0 auto"
+      />
+    </DialogCom>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { upload } from "@/api/system/public";
+import {imageUrl} from "@/utils/ruoyi";
+
+export default {
+  props: {
+    value: [String, Object, Array],
+    //两种模式:more(多选)、alone(单选)
+    type: {
+      type: String,
+      default: "more",
+    },
+    // 图片数量限制(单选模式下失效)
+    limit: {
+      type: Number,
+      default: 5,
+    },
+    // 大小限制(MB)
+    fileSize: {
+      type: Number,
+      default: 20,
+    },
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["png", "jpg", "jpeg"],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      number: 0,
+      uploadList: [],
+      dialogImageUrl: "",
+      dialogVisible: false,
+      hideUpload: false,
+      uploadImgUrl:
+        process.env.NODE_ENV === "development"
+          ? "/dev-api" + "/file/file/upload"
+          : process.env.VUE_APP_BASE_API + "/file/file/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+      },
+      fileList: [],
+      file: null,
+      baseUrl:process.env.NODE_ENV === "development"
+              ? process.env.VUE_APP_BASE_API
+              : window.origin
+    };
+  },
+  watch: {
+    value: {
+      handler(val) {
+        if (val) {
+          // 首先将值转为数组
+          const list = Array.isArray(val) ? val : this.value.split(",");
+          // 然后将数组转为对象数组
+          this.fileList = list.map((item) => {
+            // if (typeof item === "string") {
+            //   item = { name: item, url: item };
+            // }
+            let data = JSON.parse(item);
+            let res = {
+              name: data.name,
+              url: data.url.indexOf('http') > -1 ?   data.url : imageUrl(data.url),
+              imgPath: data.url.indexOf('http') > -1 ?   data.imgPath : data.url
+            }
+            return res;
+          });
+        } else {
+          this.fileList = [];
+          return [];
+        }
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+  },
+  methods: {
+    //单传模式下的预览
+    clickImg() {
+      this.dialogImageUrl = this.fileList[0].url;
+      this.dialogVisible = true;
+    },
+    //自定义上传方式(自带的成功回调及失败回调会失效)
+    uploadImage(fileObj) {
+      console.log(window.origin, "URL");
+      let formData = new FormData();
+      formData.append("file", fileObj.file);
+      upload(formData, "image")
+        .then((res) => {
+          /*上传成功*/
+          this.$modal.closeLoading();
+          let imgUrl = this.imageUrl(res.data.url); //拼接完整图片URL路径
+          let arr = [];
+          arr.push({ name: res.data.name, url: imgUrl,imgPath: res.data.url });
+          if(this.type=='more'){
+            this.fileList = this.fileList.concat(arr);
+          }
+          else{
+            this.fileList = arr;
+          }
+
+          //emit完整图片URL路径
+          this.$emit("input", this.listToTagObj(this.fileList));
+          // //非完整图片URL路径
+          // this.$emit("imgUrl", res.data.url);
+        })
+        .catch((err) => {
+          /*上传失败*/
+          this.$modal.closeLoading();
+          //this.$modal.msgError(res.msg);
+          this.$refs.imageUpload.handleRemove(fileObj.file);
+          //this.uploadedSuccessfully();
+        });
+    },
+    // 上传前loading加载
+    handleBeforeUpload(file) {
+      let isImg = false;
+      if (this.fileType.length) {
+        let fileExtension = "";
+        if (file.name.lastIndexOf(".") > -1) {
+          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+        }
+        isImg = this.fileType.some((type) => {
+          if (file.type.indexOf(type) > -1) return true;
+          if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+          return false;
+        });
+      } else {
+        isImg = file.type.indexOf("image") > -1;
+      }
+
+      if (!isImg) {
+        this.$modal.msgError(
+          `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`
+        );
+        return false;
+      }
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$modal.msgError(`上传图片大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      this.$modal.loading("正在上传图片,请稍候...");
+      this.number++;
+      this.file = file;
+    },
+    // 文件个数超出
+    handleExceed() {
+      this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
+    },
+    // 上传成功回调
+    handleUploadSuccess(res, file,fileList) {
+      console.log("handleUploadSuccess",res,file,fileList);
+      if (res.code === 200) {
+        let imgUrl = process.env.VUE_APP_BASE_API + res.data.url;
+        this.uploadList.push({ name: res.data.name, url: imgUrl });
+        this.uploadedSuccessfully();
+
+        // let str = res.data.code;
+        // let blob = new Blob([str],{type:'image/jpeg'});
+        // let imgUrl = window.URL.createObjectURL(blob);
+        // debugger
+      } else {
+        this.number--;
+        this.$modal.closeLoading();
+        this.$modal.msgError(res.msg);
+        this.$refs.imageUpload.handleRemove(file);
+        this.uploadedSuccessfully();
+      }
+    },
+    // 删除图片
+    handleDelete(file) {
+      const findex = this.fileList.map((f) => f.name).indexOf(file.name);
+      if (findex > -1) {
+        this.fileList.splice(findex, 1);
+        this.$emit("input", this.listToTagObj(this.fileList));
+      }
+      console.log(this.listToTagObj(this.fileList), "删除图片");
+    },
+    // 上传失败
+    handleUploadError() {
+      this.$modal.msgError("上传图片失败,请重试");
+      this.$modal.closeLoading();
+    },
+    // 上传结束处理
+    uploadedSuccessfully() {
+      if (this.number > 0 && this.uploadList.length === this.number) {
+        this.fileList = this.fileList.concat(this.uploadList);
+        this.uploadList = [];
+        this.number = 0;
+        this.$emit("input", this.listToTagObj(this.fileList));
+        this.$modal.closeLoading();
+      }
+    },
+    // 预览
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    // 对象转成指定字符串分隔
+    listToString(list, separator) {
+      let strs = "";
+      separator = separator || ",";
+      for (let i in list) {
+        if (list[i].url) {
+          strs += list[i].url.replace(this.baseUrl, "") + separator;
+        }
+      }
+      return strs != "" ? strs.substr(0, strs.length - 1) : "";
+    },
+    listToTagObj(list) {
+      let tempArry = [];
+      for (let i in list) {
+        tempArry.push(JSON.stringify({url: list[i].url, name: list[i].name, imgPath: list[i].imgPath}));
+      }
+      console.log("listToString2", tempArry);
+      return tempArry;
+    },
+    clearFiles(){
+        this.$refs["imageUpload"].clearFiles();
+        // this.fileList = [];
+        // this.fileValueList = [];
+      },
+  },
+};
+</script>
+<style scoped lang="scss">
+// .el-upload--picture-card 控制加号部分
+::v-deep .hide .el-upload--picture-card {
+  display: none !important;
+}
+// 去掉动画效果
+::v-deep .el-list-enter-active,
+::v-deep .el-list-leave-active {
+  transition: all 0s;
+}
+
+::v-deep .el-list-enter,
+.el-list-leave-active {
+  opacity: 0;
+  transform: translateY(0);
+}
+.img-box {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .img-model {
+    width: 100%;
+    display: none;
+    position: absolute;
+    left: 0;
+    top: 0;
+    align-items: center;
+    > span {
+      background-color: rgba(30, 30, 30, 0.3);
+      display: block;
+      padding: 5px;
+      color: #fff;
+      text-shadow: 0 0 2px #1e1e1e;
+    }
+  }
+  &:hover {
+    .img-model {
+      display: block;
+    }
+  }
+}
+</style>

+ 19 - 6
src/views/core/outIn/letter/dialog.addletter.vue

@@ -70,14 +70,17 @@
             </el-col>
             <el-col :span="12">
               <el-form-item label="上传介绍信附件" ref="letterFile" prop="letterFile">
-                <K-file-upload
+<!--                <K-file-upload
                   ref="uploadFile"
                   :limit=2
                   :defaultValue="formFileListDefualtValue"
                   :fileType="letterFileType"
                   @input="fileListChanged"
                   v-model="formData.letterFile"
-                />
+                />-->
+                  <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
+                  <img-file-upload ref="uploadimage" type="more" :value="formData.letterFile"
+                             @input="imageLetterListChanged"></img-file-upload>
               </el-form-item>
             </el-col>
             <el-col :span="12">
@@ -158,7 +161,7 @@
           ref="formUser"
           :model="userInfo"
           :rules="userInfoRules"
-          label-width="120px"
+          label-width="140px"
         >
           <el-form-item label="来访单位" prop="companyName">
             <el-input v-model="userInfo.companyName" maxlength="20" placeholder="请输入来访单位" />
@@ -179,11 +182,16 @@
           <el-form-item label="证件号码" prop="idCard">
             <el-input v-model="userInfo.idCard" maxlength="20" placeholder="请输入证件号码" />
           </el-form-item>
-          <el-form-item prop="imgFile" ref="userImgFile" label="上传证件图片">
+          <el-form-item prop="imgFile" v-if="parseInt(userInfo.idType) === 0" ref="userImgFile" label="上传证件正反面">
             <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
             <imgUpload ref="uploadimage" type="more" :value="userInfo.imgFile" :limit=2
                            @input="imageListChanged"></imgUpload>
           </el-form-item>
+          <el-form-item prop="imgFile" v-else ref="userImgFile" label="上传证件图片">
+            <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
+            <imgUpload ref="uploadimage" type="more" :value="userInfo.imgFile" :limit=2
+                       @input="imageListChanged"></imgUpload>
+          </el-form-item>
         </el-form>
         <div slot="footer" class="dialog-footer">
           <el-button type="primary" @click="submitUser">确 定</el-button>
@@ -211,10 +219,11 @@ import OrgTreeSelect from "@/components/orgTreeSelect";
 import KFileUpload from "@/components/K-FileUpload/index.vue";
 import dayjs from "dayjs";
 import imgUpload from "@/components/ImageUpload";
+import imgFileUpload from "@/components/ImageFileUpload";
 import DataRangePicker from "@/components/dateTime/daterange.picker.vue";
 import orgSelect from "@/components/orgSelect/zl.orgSelect.vue";
 export default {
-  components: {orgSelect, OrgTreeSelect, KFileUpload, imgUpload,DataRangePicker },
+  components: {orgSelect, OrgTreeSelect, KFileUpload, imgUpload,DataRangePicker,imgFileUpload },
   data() {
     const params = this.$route.params;
     return {
@@ -318,6 +327,10 @@ export default {
       this.userInfo.imgFile = list;
       this.$refs.userImgFile.clearValidate();
     },
+    imageLetterListChanged(list) {
+      this.formData.letterFile = list;
+      this.$refs.letterFile.clearValidate();
+    },
     fileListChanged(list)
     {
       this.$refs.letterFile.clearValidate();
@@ -351,7 +364,7 @@ export default {
     onHide() {
       this.isShow = false;
       this.formData = this.reset();
-      this.$refs["uploadFile"].clearFiles();
+      //this.$refs["uploadFile"].clearFiles();
     },
     onHideUser() {
       this.open = false;

+ 4 - 7
src/views/core/outIn/letter/dialog.letter.detail.vue

@@ -40,12 +40,8 @@
           <el-descriptions-item label="来访事由">{{formData.reasons}}</el-descriptions-item>
           <el-descriptions-item label="开具日期">{{formData.startTimeStr}}</el-descriptions-item>
           <el-descriptions-item label="有效天数">{{formData.effectiveDays}}</el-descriptions-item>
-          <el-descriptions-item label="介绍信附件">
-            <K-file-upload
-              ref="upload"
-              :isShowUploadBtn="false"
-              :defaultValue="formData.letterFile"
-            />
+          <el-descriptions-item label="介绍信附件" span="2">
+            <image-file-list-preview v-model="formData.letterFile"></image-file-list-preview>
           </el-descriptions-item>
           <el-descriptions-item label="备注">{{formData.description}}</el-descriptions-item>
 
@@ -172,9 +168,10 @@ import OrgTreeSelect from "@/components/orgTreeSelect";
 import KFileUpload from "@/components/K-FileUpload/index.vue";
 import dayjs from "dayjs";
 import imgUpload from "@/components/ImageUpload";
+import imageFileListPreview from "@/components/ImageFileListPreview";
 import DataRangePicker from "@/components/dateTime/daterange.picker.vue";
 export default {
-  components: { OrgTreeSelect, KFileUpload, imgUpload,DataRangePicker },
+  components: { OrgTreeSelect, KFileUpload, imgUpload,DataRangePicker,imageFileListPreview },
   data() {
     const params = this.$route.params;
     return {