فهرست منبع

✨ feat: 2023.11.13 - 添加视频预览

GuYun-D 1 سال پیش
والد
کامیت
a357557771
3فایلهای تغییر یافته به همراه250 افزوده شده و 263 حذف شده
  1. 19 8
      src/utils/index.js
  2. 227 251
      src/views/commodity/commoditySystem/addComponent.vue
  3. 4 4
      vue.config.js

+ 19 - 8
src/utils/index.js

@@ -84,14 +84,14 @@ export function formatTime(time, option) {
   }
   return (
     d.getMonth() +
-            1 +
-            '月' +
-            d.getDate() +
-            '日' +
-            d.getHours() +
-            '时' +
-            d.getMinutes() +
-            '分'
+    1 +
+    '月' +
+    d.getDate() +
+    '日' +
+    d.getHours() +
+    '时' +
+    d.getMinutes() +
+    '分'
   )
 }
 
@@ -133,3 +133,14 @@ export function hidden(str, frontLen, endLen) {
   // );
   return str
 }
+
+/**
+ * 判断当前资源是否是视频格式
+ * @param {string} url 
+ * @returns {boolean}
+ */
+export function isVideo(url) {
+  const videoExtensions = ['.avi', '.wmv', '.mpg', '.mpeg', '.mov', '.rm', '.ram', '.swf', '.flv', '.mp4'];
+  const lowercasedUrl = url.toLowerCase();
+  return videoExtensions.some(type => lowercasedUrl.includes(type));
+}

+ 227 - 251
src/views/commodity/commoditySystem/addComponent.vue

@@ -2,19 +2,22 @@
   <div class="style-information-component">
     <el-form-item label="商品图片" />
     <div class="upload-wrap">
-      <el-upload
-        list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
-        :headers="headers" :data="dataObj" :file-list="form.imgs" :limit="20"
-        :on-success="handleImageSuccess"
-        :action="action"
-      >
+      <el-upload list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
+        :headers="headers" :data="dataObj" :file-list="form.imgs" :limit="20" :on-success="handleImageSuccess"
+        :action="action">
         <i slot="default" class="el-icon-plus" />
         <div slot="file" slot-scope="{ file }">
-          <img class="el-upload-list__item-thumbnail" :src="file.imgPath">
+          <img v-if="!isVideo(file.imgPath)" class="el-upload-list__item-thumbnail" :src="file.imgPath">
+          <video v-else class="el-upload-list__item-thumbnail" style="width: 148px;height: 148px;" 
+            :src="file.imgPath"></video>
           <span class="el-upload-list__item-actions">
-            <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
+            <span v-if="!isVideo(file.imgPath)" class="el-upload-list__item-preview"
+              @click="handlePictureCardPreview(file)">
               <i class="el-icon-zoom-in" />
             </span>
+            <span @click="playVideo(file.imgPath)">
+              <i class="el-icon-video-play"></i>
+            </span>
             <span class="el-upload-list__item-delete" @click="handleRemove(file)">
               <i class="el-icon-delete" />
             </span>
@@ -39,60 +42,41 @@
           <el-table-column label="售价">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.price" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.price" :controls="false" :max="999999999" :min="0"
-                :precision="2"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.price" :controls="false" :max="999999999" :min="0" :precision="2"
+                :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="原价">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.originalPrice" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.originalPrice" :controls="false" :max="999999999" :min="0"
-                :precision="2" :step="0.01"
-              />
+              <el-input-number v-model="scope.row.originalPrice" :controls="false" :max="999999999" :min="0"
+                :precision="2" :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="库存">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.stockNumber" type="number" oninput="value=value.replace(/[^\d]/g,'')" /> -->
-              <el-input-number
-                v-model="scope.row.stockNumber" :controls="false" :max="999999999" :min="0"
-                :precision="0"
-              />
+              <el-input-number v-model="scope.row.stockNumber" :controls="false" :max="999999999" :min="0"
+                :precision="0" />
             </template>
           </el-table-column>
           <el-table-column label="重量(KG)">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.weight" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.weight" :controls="false" :max="999" :min="0"
-                :precision="2"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.weight" :controls="false" :max="999" :min="0" :precision="2"
+                :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="代金卷最大抵扣额度(一般设置全额抵扣)">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.weight" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.voucherPrice" :controls="false" :min="0"
-                :precision="6"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.voucherPrice" :controls="false" :min="0" :precision="6" :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="商品绑定的代金卷">
             <template slot-scope="scope">
               <el-select v-model="scope.row.voucherId" placeholder="请选择商品绑定的代金卷">
-                <el-option
-                  v-for="item in voucherList"
-                  :key="item.createTime"
-                  :label="item.voucherName"
-                  :value="item.id"
-                >
+                <el-option v-for="item in voucherList" :key="item.createTime" :label="item.voucherName" :value="item.id">
                 </el-option>
               </el-select>
             </template>
@@ -119,12 +103,9 @@
                 <i v-else class="el-icon-close delImg" @click="delValue(index, index1)" />
                 <div v-if="skuAttr.needImg && index === 0" class="upload-wrap diagram-upload">
                   <div class="span-wrap">
-                    <el-upload
-                      list-type="picture-card" :show-file-list="false" :on-preview="handlePictureCardPreview"
-                      :on-remove="handleRemove" :headers="headers" :data="dataObj" :file-list="[ sku ]"
-                      :multiple="false"
-                      :on-success="handleImageSuccess1" :action="action"
-                    >
+                    <el-upload list-type="picture-card" :show-file-list="false" :on-preview="handlePictureCardPreview"
+                      :on-remove="handleRemove" :headers="headers" :data="dataObj" :file-list="[sku]" :multiple="false"
+                      :on-success="handleImageSuccess1" :action="action">
                       <i v-if="!sku.image" slot="trigger" class="el-icon-plus" />
                       <div v-else class="attr-value-img">
                         <img class="attr-thumbnail" :src="sku.image">
@@ -151,68 +132,49 @@
             <template slot-scope="scope">
               {{
                 scope.row.skuAttrCodeDTOList &&
-                  scope.row.skuAttrCodeDTOList[index]
-                  | attrValueFilter(form.skuAttrList)
+                scope.row.skuAttrCodeDTOList[index]
+                | attrValueFilter(form.skuAttrList)
               }}
             </template>
           </el-table-column>
           <el-table-column label="售价">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.price" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.price" :controls="false" :max="999999999" :min="0"
-                :precision="2"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.price" :controls="false" :max="999999999" :min="0" :precision="2"
+                :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="原价">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.originalPrice" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.originalPrice" :controls="false" :max="999999999" :min="0"
-                :precision="2" :step="0.01"
-              />
+              <el-input-number v-model="scope.row.originalPrice" :controls="false" :max="999999999" :min="0"
+                :precision="2" :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="库存">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.stockNumber" type="number" oninput="value=value.replace(/[^\d]/g,'')" /> -->
-              <el-input-number
-                v-model="scope.row.stockNumber" :controls="false" :max="999999999" :min="0"
-                :precision="0"
-              />
+              <el-input-number v-model="scope.row.stockNumber" :controls="false" :max="999999999" :min="0"
+                :precision="0" />
             </template>
           </el-table-column>
           <el-table-column label="重量(KG)">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.weight" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.weight" :controls="false" :max="999" :min="0"
-                :precision="6"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.weight" :controls="false" :max="999" :min="0" :precision="6"
+                :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="代金卷最大抵扣额度(一般设置全额抵扣)">
             <template slot-scope="scope">
               <!-- <el-input v-model="scope.row.weight" type="number" oninput="value=value.replace(/-/, '')" /> -->
-              <el-input-number
-                v-model="scope.row.voucherPrice" :controls="false" :min="0"
-                :precision="6"
-                :step="0.01"
-              />
+              <el-input-number v-model="scope.row.voucherPrice" :controls="false" :min="0" :precision="6" :step="0.01" />
             </template>
           </el-table-column>
           <el-table-column label="商品绑定的代金卷">
             <template slot-scope="scope">
               <el-select v-model="scope.row.voucherId" placeholder="请选择商品绑定的代金卷">
-                <el-option
-                  v-for="item in voucherList"
-                  :key="item.createTime"
-                  :label="item.voucherName"
-                  :value="item.id"
-                >
+                <el-option v-for="item in voucherList" :key="item.createTime" :label="item.voucherName" :value="item.id">
                 </el-option>
               </el-select>
             </template>
@@ -230,18 +192,24 @@
         </el-table>
       </div>
     </div>
-    <el-dialog
-      :append-to-body="true" :visible.sync="dialogVisible" class="check-image-dialog" title="查看图片"
-      center="center"
-    >
+    <el-dialog :append-to-body="true" :visible.sync="dialogVisible" class="check-image-dialog" title="查看图片"
+      center="center">
       <img width="100%" :src="dialogImageUrl" alt>
     </el-dialog>
+
+    <el-dialog width="30%" :append-to-body="true" :visible.sync="previewVideoVisible" class="check-image-dialog"
+      title="预览视频" center="center">
+      <div style="display: flex; align-items: center; justify-content: center;">
+        <video controls autoplay muted style="width: 400px; height: 400px;" :src="dialogVideoUrl"></video>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { uploadUrl } from '@/utils/request'
 import { getToken } from '@/utils/auth'
+import { isVideo } from '@/utils/index'
 export default {
   filters: {
     attrValueFilter(map, list) {
@@ -285,7 +253,9 @@ export default {
   data() {
     return {
       dialogImageUrl: '',
+      dialogVideoUrl: '',
       dialogVisible: false,
+      previewVideoVisible: false,
       newform: this.form,
       headers: {
         'Authorization-business': getToken()
@@ -321,7 +291,8 @@ export default {
         return this.form.skuList.slice(0, 1)
       }
       return this.form.skuList
-    }
+    },
+
   },
   watch: {
     'form.skuAttrList': {
@@ -354,6 +325,7 @@ export default {
     this.headers.tenant = 'MDAwMA=='
   },
   methods: {
+    isVideo,
     // proving1(e) {
     //   var keynum = window.event ? e.keyCode : e.which // 获取键盘码
     //   // var keychar = String.fromCharCode(keynum) // 获取键盘码对应的字符
@@ -377,6 +349,10 @@ export default {
     //     e.target.value = ' '
     //   }
     // },
+    playVideo(url) {
+      this.dialogVideoUrl = url
+      this.previewVideoVisible = true
+    },
     handleImageSuccess(response) {
       const url = response.data.url
       this.form.imgs.push({
@@ -561,177 +537,177 @@ export default {
 @import url("../../../styles/elDialog.scss");
 
 .style-information-component {
-	width: 100%;
-	min-height: 300px;
-	padding: 24px;
-	background-color: rgb(255, 255, 255);
-
-	.el-form-item {
-		margin-bottom: 10px;
-	}
-
-	.attr-value-list {
-		display: flex;
-		flex-wrap: wrap;
-
-		.main-diagram {
-			width: 180px;
-
-			.span-wrap {
-				position: relative;
-				display: inline-block;
-				margin-top: 10px;
-
-				.attr-actions {
-					line-height: 100px;
-					position: absolute;
-					width: 100%;
-					height: 100%;
-					left: 0;
-					top: 0;
-					cursor: default;
-					text-align: center;
-					color: #fff;
-					opacity: 0;
-					font-size: 20px;
-					background-color: rgba(0, 0, 0, 0.5);
-					-webkit-transition: opacity 0.3s;
-					transition: opacity 0.3s;
-					z-index: 1;
-
-					&:hover {
-						opacity: 1;
-
-						.attr-preview {
-							display: inline-block;
-						}
-
-						i {
-							color: #fff;
-							font-size: 20px;
-						}
-					}
-				}
-
-				.attr-preview {
-					display: none;
-					cursor: pointer;
-					font-size: 20px;
-					color: #fff;
-				}
-
-				.attr-delete {
-					margin-left: 15px;
-					color: #fff;
-				}
-			}
-
-			.attr-value-img {
-				width: 100%;
-				height: 100%;
-
-				img {
-					width: 100%;
-					height: 100%;
-					object-fit: contain;
-				}
-			}
-		}
-	}
-
-	.m-8 {
-		margin-right: 8px;
-	}
-
-	.upload-btn {
-		box-sizing: border-box;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		width: 100%;
-		height: 110px;
-		cursor: pointer;
-		border: 2px dashed #2e60f8;
-		border-radius: 2px;
-		background-color: #f8f9fb;
-		text-align: center;
-		font-size: 20px;
-		color: #2e60f8;
-
-		i {
-			color: #2e60f8;
-			font-size: 20px;
-		}
-
-		.upload-title {
-			margin-left: 10px;
-			font-size: 14px;
-		}
-	}
-
-	.upload-wrap {
-		margin-bottom: 25px;
-
-		.el-upload-list__item {
-			transition: none !important;
-		}
-
-		.el-upload,
-		.el-upload-list__item {
-			width: 100px;
-			height: 100px;
-			line-height: 100px;
-		}
-
-		.el-progress,
-		.el-progress-circle {
-			width: 80px !important;
-			height: 80px !important;
-		}
-	}
-
-	.sku-attr-list {
-		.el-input {
-			width: 180px;
-		}
-	}
-
-	.single-style {
-		.el-input {
-			max-width: 180px;
-		}
-	}
-
-	.add-attr-btn {
-		margin-bottom: 25px;
-	}
-
-	.check-image-dialog {
-		.el-dialog {
-			margin-top: 25px;
-
-			.el-dialog__body {
-				img {
-					max-width: 100%;
-					max-height: 100%;
-					height: 500px;
-					object-fit: contain;
-				}
-			}
-		}
-	}
-
-	.delImg {
-		position: absolute;
-		top: 12px;
-		margin-left: -24px
-	}
-
-	.delImg:hover {
-		border-radius: 50%;
-		color: #ffffff;
-		background: #2e60f8;
-		cursor: pointer;
-	}
+  width: 100%;
+  min-height: 300px;
+  padding: 24px;
+  background-color: rgb(255, 255, 255);
+
+  .el-form-item {
+    margin-bottom: 10px;
+  }
+
+  .attr-value-list {
+    display: flex;
+    flex-wrap: wrap;
+
+    .main-diagram {
+      width: 180px;
+
+      .span-wrap {
+        position: relative;
+        display: inline-block;
+        margin-top: 10px;
+
+        .attr-actions {
+          line-height: 100px;
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          left: 0;
+          top: 0;
+          cursor: default;
+          text-align: center;
+          color: #fff;
+          opacity: 0;
+          font-size: 20px;
+          background-color: rgba(0, 0, 0, 0.5);
+          -webkit-transition: opacity 0.3s;
+          transition: opacity 0.3s;
+          z-index: 1;
+
+          &:hover {
+            opacity: 1;
+
+            .attr-preview {
+              display: inline-block;
+            }
+
+            i {
+              color: #fff;
+              font-size: 20px;
+            }
+          }
+        }
+
+        .attr-preview {
+          display: none;
+          cursor: pointer;
+          font-size: 20px;
+          color: #fff;
+        }
+
+        .attr-delete {
+          margin-left: 15px;
+          color: #fff;
+        }
+      }
+
+      .attr-value-img {
+        width: 100%;
+        height: 100%;
+
+        img {
+          width: 100%;
+          height: 100%;
+          object-fit: contain;
+        }
+      }
+    }
+  }
+
+  .m-8 {
+    margin-right: 8px;
+  }
+
+  .upload-btn {
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 110px;
+    cursor: pointer;
+    border: 2px dashed #2e60f8;
+    border-radius: 2px;
+    background-color: #f8f9fb;
+    text-align: center;
+    font-size: 20px;
+    color: #2e60f8;
+
+    i {
+      color: #2e60f8;
+      font-size: 20px;
+    }
+
+    .upload-title {
+      margin-left: 10px;
+      font-size: 14px;
+    }
+  }
+
+  .upload-wrap {
+    margin-bottom: 25px;
+
+    .el-upload-list__item {
+      transition: none !important;
+    }
+
+    .el-upload,
+    .el-upload-list__item {
+      width: 100px;
+      height: 100px;
+      line-height: 100px;
+    }
+
+    .el-progress,
+    .el-progress-circle {
+      width: 80px !important;
+      height: 80px !important;
+    }
+  }
+
+  .sku-attr-list {
+    .el-input {
+      width: 180px;
+    }
+  }
+
+  .single-style {
+    .el-input {
+      max-width: 180px;
+    }
+  }
+
+  .add-attr-btn {
+    margin-bottom: 25px;
+  }
+
+  .check-image-dialog {
+    .el-dialog {
+      margin-top: 25px;
+
+      .el-dialog__body {
+        img {
+          max-width: 100%;
+          max-height: 100%;
+          height: 500px;
+          object-fit: contain;
+        }
+      }
+    }
+  }
+
+  .delImg {
+    position: absolute;
+    top: 12px;
+    margin-left: -24px
+  }
+
+  .delImg:hover {
+    border-radius: 50%;
+    color: #ffffff;
+    background: #2e60f8;
+    cursor: pointer;
+  }
 }
 </style>

+ 4 - 4
vue.config.js

@@ -40,16 +40,16 @@ module.exports = {
     },
     proxy: {
       '/businessapi': {
-        target: 'http://192.168.0.91:9104',
-        // target: 'https://nsbusinessapi.tuanfengkeji.cn',
+        // target: 'http://192.168.0.91:9104',
+        target: 'https://nsbusinessapi.tuanfengkeji.cn',
         changeOrigin: true,
         pathRewrite: {
           '^/businessapi': ''
         }
       },
       '/canvasApi': {
-        target: 'http://192.168.0.91:9104', // 测试
-        // target: 'https://nsbusinessapi.tuanfengkeji.cn',
+        // target: 'http://192.168.0.91:9104', // 测试
+        target: 'https://nsbusinessapi.tuanfengkeji.cn',
         changeOrigin: true,
         pathRewrite: {
           '^/canvasApi': ''