Browse Source

优化图片上传与预览

YangJian0701 11 months ago
parent
commit
0df083d051
2 changed files with 115 additions and 48 deletions
  1. 111 47
      src/views/medicine/medicineManage/files.vue
  2. 4 1
      src/views/medicine/medicineManage/index.vue

+ 111 - 47
src/views/medicine/medicineManage/files.vue

@@ -1,23 +1,25 @@
 <template>
     <div class="files">
-        <el-drawer v-model="drawer" direction="rtl" append-to-body style="min-width: 500px;">
+        <el-drawer v-model="drawer" direction="rtl" append-to-body>
             <template #header>
                 <h4>上传图片</h4>
             </template>
             <template #default>
-                <div>
-                    <el-upload v-model:file-list="fileList" multiple 
-                        action="#" 
-                        list-type="picture-card"
-                        :on-change="beforeUpload"
-                        :auto-upload="false"
-                        :on-preview="handlePictureCardPreview">
-                        <el-icon>
-                            <Plus />
-                        </el-icon>
-                    </el-upload>
-
-                    <el-dialog v-model="dialogVisible">
+                <div style="display: flex;flex-wrap: wrap;grid-gap: 20px;">
+                    <div class="file-imgs" v-for="item,i in fileList" :key="i">
+                        <img class="file-imgs-item" :src="item.url">
+                        <div class="file-imgs-showDel">
+                            <div class="file-imgs-showDel-item">
+                                <el-icon class="file-imgs-showDel-item-icons" @click="handlePictureCardPreview(item)"><View /></el-icon>
+                                <el-icon class="file-imgs-showDel-item-icons" @click="delectPreview(i)"><Delete /></el-icon>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="file-mais">
+                        <el-icon class="file-mais-icons"><Plus /></el-icon>
+                        <input type="file" multiple class="file-mais-files" @change="beforeUpload">
+                    </div>
+                    <el-dialog v-model="dialogVisible" draggable>
                         <img w-full :src="dialogImageUrl" style="width: 100%;height: auto;"/>
                     </el-dialog>
                 </div>
@@ -36,18 +38,22 @@
 import { ref,reactive} from "vue";
 import * as qiniu from 'qiniu-js';
 import { upFileToken,medicineimgedit } from "@/api";
-import type { UploadProps, UploadUserFile } from 'element-plus'
 
+import type { UploadProps, UploadUserFile } from 'element-plus'
+import { Plus,View,Delete } from '@element-plus/icons-vue'
 const dialogImageUrl = ref('')
 const dialogVisible = ref(false)
 
 const fileList:any = ref<UploadUserFile[]>([])//上传的图片列表
 
-const beforeUpload = async(file:any) => {  
-    console.log('上传',file)
-    var strtype:any = file.name.substring(file.name.lastIndexOf('.') + 1); //获取后缀 png jpg
-    const token:any = await upFileTokenApi(strtype)
-    handleUpload(file,token.data);
+const beforeUpload = async(data:any) => {  
+    let arr = data.target.files
+    for (let i = 0; i < arr.length; i++) {
+        const file = arr[i];
+        var strtype:any = file.name.substring(file.name.lastIndexOf('.') + 1); //获取后缀 png jpg
+        const token:any = await upFileTokenApi(strtype)
+        handleUpload(file,token.data);
+    }
 }
 //获取token
 const upFileTokenApi = async (strtype:any)=>{
@@ -57,7 +63,6 @@ const upFileTokenApi = async (strtype:any)=>{
  * 上传七牛云
  */
 const handleUpload = (file:any,qiniuToken:any)=> {  
-    
     var config = {
         useCdnDomain: false, //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
         region: qiniu.region.z2,
@@ -70,7 +75,7 @@ const handleUpload = (file:any,qiniuToken:any)=> {
         mimeType: [] || null
     };
     var key = file.name || null
-    const observable = qiniu.upload(objectToBinary(file), key, qiniuToken);  
+    const observable = qiniu.upload(file, key, qiniuToken);  
 
     // const observable = qiniu.upload(file, key, qiniuToken, putExtra, config);  
     observable.subscribe({  
@@ -84,34 +89,12 @@ const handleUpload = (file:any,qiniuToken:any)=> {
       },  
       complete(res:any) {  
         // 上传完成信息  
-        const j = fileList.value.findIndex((item:any)=>{return item.name == file.name})
-        fileList.value[j] = { name: file.name, url: res.key }
-        // 更新你的文件列表或进行其他操作  
+        fileList.value.push({ name: file.name, url: res.key })
+        console.log(fileList.value); 
       },  
     });  
   }
 
-  
-const objectToBinary = (obj:any)=> {
-    // 将对象转换为JSON字符串
-    const jsonStr = JSON.stringify(obj);
-    // 将字符串转换为二进制数据
-    const binaryStr = unescape(encodeURIComponent(jsonStr));
-    // 创建Blob对象
-    const blob = new Blob([binaryStr], { type: 'application/octet-stream' });
-    // 创建File对象
-    const file = new File([blob], "filename.bin", {
-        type: 'application/octet-stream',
-    });
-    return file;
-}
- 
-// 示例用法
-const obj = { key: "value" };
-const file = objectToBinary(obj);
-console.log(file);
-
-
 
 /**
  * 查看图片
@@ -120,6 +103,12 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
   dialogImageUrl.value = uploadFile.url!
   dialogVisible.value = true
 }
+/**
+ * 删除图片
+ */
+ const delectPreview = (index:any) => {
+  fileList.value?.splice(index, 1)
+}
 
 const drawer = ref(false)
 
@@ -149,6 +138,7 @@ const setMedicineeditApi = async()=>{
 }
 const showDrawer = () => {
     drawer.value = true
+    fileList.value =[]
 }
 
 
@@ -158,5 +148,79 @@ defineExpose({
 })
 </script>
 <style lang="scss">
-/* @import url(); 引入css类 */
+.files{
+    user-select: none;
+}
+.file-imgs{
+    width: 178px;
+    height: 178px; 
+    border-radius: 6px;
+    overflow: hidden;
+    border: 1px dashed var(--el-border-color);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    &-item{
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+        border-radius: 6px;
+        overflow: hidden;
+    }
+    &-showDel{
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100%;
+        width: 100%;
+        background: rgba($color: #000000, $alpha: .6);
+        display: none;
+        &-item{
+            width: 100%;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            grid-gap: 40px;
+            color: #fff;
+            font-size: 20px;
+            &-icons:hover{
+                color: red;
+            }
+        }
+    }
+}
+.file-imgs:hover{
+    .file-imgs-showDel{
+        display: block;
+        cursor: pointer;
+    }
+}
+.file-mais{
+    border: 1px dashed var(--el-border-color);
+    border-radius: 6px;
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    text-align: center;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    &-files{
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100%;
+        width: 100%;
+        border: 1px solid red;
+        opacity: 0;
+        cursor: pointer;
+    }
+}
+.file-mais:hover{
+    border: 1px dashed #337ecc;
+}
 </style>

+ 4 - 1
src/views/medicine/medicineManage/index.vue

@@ -40,6 +40,9 @@
                       :min-scale="0.2"
                       :preview-src-list="row.crcList"
                       :initial-index="4"
+                      preview-teleported
+                      :infinite="false"
+                      v-if="row.img"
                       fit="cover">
                   </el-image>
                 </template>
@@ -159,7 +162,7 @@ const columns: any = [
   { prop: 'unit', label: '单位', width: 120},
   { prop: 'dosageForm', label: '剂型', width: 120},
   { prop: 'qualificationNumber', label: '批签发合格编号', width: 150},
-  { prop: 'imgurl', label: '预览', width: 150, name: 'imgUrl' },
+  { prop: 'imgUrl', label: '预览', width: 150, name: 'imgUrl' },
   { prop: 'operation', label: '操作', fixed: 'right', 'min-width': 150 }
 ]