xiaohaizhao 1 tháng trước cách đây
mục cha
commit
899567e1f3

+ 0 - 1
dist/assets/index-d750c661.css

@@ -1 +0,0 @@
-.header[data-v-7676a3a8]{display:flex;justify-content:space-between;align-items:center;width:100%}.picture-wall-box[data-v-7676a3a8]{display:grid;justify-content:space-between;grid-gap:10px;margin-top:20px;user-select:none}.picture-wall-box .picture-wall-item[data-v-7676a3a8]{display:flex;align-items:center;justify-content:center;border:1px solid #d9d9d9;border-radius:8px;box-sizing:border-box}.previewMaskIcon[data-v-7676a3a8]{opacity:.6}.previewMaskIcon[data-v-7676a3a8]:hover{opacity:1}.empty[data-v-7676a3a8]{width:100%;padding:50px 0;display:flex;justify-content:center}

+ 1 - 1
dist/index.html

@@ -5,7 +5,7 @@
     <link rel="icon" type="image/svg+xml" href="./vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>营销宝</title>
-    <script type="module" crossorigin src="./assets/index-fed60001.js"></script>
+    <script type="module" crossorigin src="./assets/index-07396680.js"></script>
     <link rel="modulepreload" crossorigin href="./assets/vue-8259307b.js">
     <link rel="modulepreload" crossorigin href="./assets/vue-router-55bfd43b.js">
     <link rel="stylesheet" href="./assets/index-b8e2bd64.css">

+ 2 - 0
h5preview/index.html

@@ -0,0 +1,2 @@
+<!DOCTYPE html><html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>营销工具</title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
+            document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=./static/index.2da1efab.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=./static/js/chunk-vendors.53ba089c.js></script><script src=./static/js/index.1c73a126.js></script></body></html>

+ 62 - 0
h5preview/static/iconfont/iconfont.css

@@ -0,0 +1,62 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 4527697 */
+  src: url('//at.alicdn.com/t/c/font_4527697_cha7qj3q73.woff2?t=1714380231809') format('woff2'),
+       url('//at.alicdn.com/t/c/font_4527697_cha7qj3q73.woff?t=1714380231809') format('woff'),
+       url('//at.alicdn.com/t/c/font_4527697_cha7qj3q73.ttf?t=1714380231809') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-jingyin:before {
+  content: "\e6cd";
+}
+
+.icon-mulu:before {
+  content: "\e6ca";
+}
+
+.icon-suoxiao:before {
+  content: "\e6cb";
+}
+
+.icon-bofang:before {
+  content: "\e6cc";
+}
+
+.icon-zuimoye:before {
+  content: "\e6c3";
+}
+
+.icon-shengyin:before {
+  content: "\e6c2";
+}
+
+.icon-zanting:before {
+  content: "\e6c4";
+}
+
+.icon-fangda:before {
+  content: "\e6c5";
+}
+
+.icon-diyiye:before {
+  content: "\e6c6";
+}
+
+.icon-shangyiye:before {
+  content: "\e6c7";
+}
+
+.icon-xiayiye:before {
+  content: "\e6c8";
+}
+
+.icon-quanping:before {
+  content: "\e6c9";
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
h5preview/static/index.2da1efab.css


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
h5preview/static/js/chunk-vendors.53ba089c.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
h5preview/static/js/index.1c73a126.js


+ 1 - 0
h5preview/static/js/pages-index-index.f4acab63.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["pages-index-index"],{"6c54":function(n,e,t){"use strict";t.d(e,"b",(function(){return u})),t.d(e,"c",(function(){return i})),t.d(e,"a",(function(){}));var u=function(){var n=this.$createElement,e=this._self._c||n;return e("v-uni-view",[e("v-uni-navigator",{attrs:{url:"/pages/photoGallery/index"}},[this._v("查看图集")])],1)},i=[]},e876:function(n,e,t){"use strict";t("6a54"),Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;e.default={}},ebcb:function(n,e,t){"use strict";t.r(e);var u=t("e876"),i=t.n(u);for(var r in u)["default"].indexOf(r)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(r);e["default"]=i.a},f5db:function(n,e,t){"use strict";t.r(e);var u=t("6c54"),i=t("ebcb");for(var r in i)["default"].indexOf(r)<0&&function(n){t.d(e,n,(function(){return i[n]}))}(r);var a=t("828b"),c=Object(a["a"])(i["default"],u["b"],u["c"],!1,null,"0f101360",null,!1,u["a"],void 0);e["default"]=c.exports}}]);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
h5preview/static/js/pages-photoGallery-index.684c496a.js


+ 1 - 1
src/MAR/assetsStore/detail/index.vue

@@ -93,7 +93,7 @@
           :fileType="mainData.type"
           :disabled="mainData.status == '发布'"
           ownertable="sat_sharematerial"
-          :ownerid="mainData.sat_share_materialid"
+          :ownerid="mainData.sat_sharematerialid"
         />
       </template>
       <template #tab1>

+ 185 - 93
src/components/photoWall/index.vue

@@ -1,65 +1,27 @@
 <template>
   <div>
     <div class="header">
-      <a-upload
-        :accept="acceptType"
-        multiple
-        :beforeUpload="beforeUpload"
-        :showUploadList="false"
-        name="file"
-      >
-        <a-button
-          v-if="butText"
-          @click="addImage"
-          :disabled="props.disabled"
-          type="primary"
-          size="small"
-          class="mr-10"
-        >{{ buttonText }}</a-button
-        >
+      <a-upload :accept="acceptType" multiple :beforeUpload="beforeUpload" :showUploadList="false" name="file">
+        <a-button v-if="butText" @click="addImage" :disabled="props.disabled" type="primary" size="small"
+          class="mr-10">{{ buttonText }}</a-button>
       </a-upload>
       <div style="width: 300px" v-if="list.length">
-        <a-slider
-          :max="300"
-          :min="60"
-          id="test"
-          v-model:value="baseSize"
-          @change="changeZoom"
-        />
+        <a-slider :max="300" :min="60" id="test" v-model:value="baseSize" @change="changeZoom" />
       </div>
     </div>
-    <div
-      class="picture-wall-box"
-      :style="{
-        gridTemplateColumns: `repeat(auto-fill, ${baseSize}px)`,
-      }"
-    >
-      <div
-        class="picture-wall-item"
-        v-for="(item, index) in list"
-        :key="item.attachmentid"
-        :style="{
-          width: baseSize + 'px',
-          height: baseSize + 'px',
-        }"
-        :draggable="!props.disabled && pic && isImageFile(item)"
-        @dragstart="dragStart(index)"
-        @dragover="dragOver(index)"
-        @dragend="dragEnd"
-      >
+    <div class="picture-wall-box" :style="{
+      gridTemplateColumns: `repeat(auto-fill, ${baseSize}px)`,
+    }">
+      <div class="picture-wall-item" v-for="(item, index) in list" :key="item.attachmentid" :style="{
+        width: baseSize + 'px',
+        height: baseSize + 'px',
+      }" :draggable="!props.disabled && pic && isImageFile(item)" @dragstart="dragStart(index)"
+        @dragover="dragOver(index)" @dragend="dragEnd">
         <div v-if="item.uid">
-          <a-progress
-            type="circle"
-            :percent="item.progress"
-            :status="item.exception"
-            :size="[baseSize - 40, baseSize - 40]"
-          />
+          <a-progress type="circle" :percent="item.progress" :status="item.exception"
+            :size="[baseSize - 40, baseSize - 40]" />
         </div>
-        <a-popover
-          v-else
-          :open="hovered == index"
-          @openChange="handleHoverChange($event, index)"
-        >
+        <a-popover v-else :open="hovered == index" @openChange="handleHoverChange($event, index)">
           <template #content>
             <div style="width: 200px; padding: 8px;">
               <div style="font-weight: bold; margin-bottom: 4px;">{{ item.document || '文件' }}</div>
@@ -67,48 +29,59 @@
             </div>
           </template>
           <!-- 图片文件:使用图片预览 -->
-          <div v-if="isImageFile(item)" style="width: 100%; height: 100%; position: relative;">
-            <a-image
-              :src="item.cover"
-              :preview="{
-                src: item.url,
-              }"
-              :style="{
+          <div v-if="isImageFile(item)" style="width: 100%; height: 100%; position: relative;"
+            @click="openImagePreview(index)">
+            <a-image :src="item.cover" :style="{
+              width: '100%',
+              height: '100%',
+              objectFit: 'cover',
+            }" />
+            <!-- 删除按钮 -->
+            <div v-if="!props.disabled && isDeletable" style="position: absolute; top: 4px; right: 4px;" @click.stop>
+              <a-popconfirm :open="linksid == item.linksid" title="确定删除当前资源吗?" @confirm="confirmDeleteImage"
+                @cancel="linksid = null">
+                <DeleteOutlined class="previewMaskIcon" :style="{ fontSize: '18px', color: '#ff4d4f' }"
+                  @click.stop="linksid = item.linksid" />
+              </a-popconfirm>
+            </div>
+          </div>
+          <!-- 非图片文件:显示文件图标和点击下载 -->
+          <div v-else
+            style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; position: relative; cursor: pointer;"
+            @click.stop="handleFileClick(item)">
+            <!-- 视频且有封面图:显示封面图 -->
+            <template v-if="item.fileType && item.fileType.toLowerCase() === 'video' && hasCoverImage(item)">
+              <a-image v-if="getCoverImage(item).url" :preview="false" :src="getCoverImage(item).url" :style="{
                 width: '100%',
                 height: '100%',
                 objectFit: 'cover',
-              }"
-            >
-              <template #previewMask>
+              }" />
+              <!-- 播放图标 -->
+              <div
+                style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2; pointer-events: none;">
                 <div
-                  v-if="!props.disabled && isDeletable"
-                  style="display: flex; gap: 8px; background: rgba(0,0,0,0.5); height: 100%; align-items: center; justify-content: center;"
-                >
-                  <a-popconfirm
-                    :open="linksid == item.linksid"
-                    title="确定删除当前资源吗?"
-                    @confirm="confirmDeleteImage"
-                    @cancel="linksid = null"
-                  >
-                    <DeleteOutlined
-                      class="previewMaskIcon"
-                      :style="{ fontSize: (baseSize > 200 ? '24px' : '20px'), color: '#fff' }"
-                      @click.stop="linksid = item.linksid"
-                    />
-                  </a-popconfirm>
+                  style="width: 100%; height: 100%; background: rgba(0,0,0,0.5); border-radius: 50%; display: flex; align-items: center; justify-content: center;">
+                  <component :is="PlayCircleOutlined" :style="{ fontSize: '36px', color: '#fff' }" />
                 </div>
-              </template>
-            </a-image>
-          </div>
-          <!-- 非图片文件:显示文件图标和点击下载 -->
-          <div
-            v-else
-            style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; cursor: pointer;"
-            @click="downloadFile(item)"
-          >
-            <component :is="getFileIcon(item)" :style="{ fontSize: (baseSize > 100 ? '48px' : '36px'), color: '#1890ff' }" />
-            <div style="font-size: 12px; color: #666; margin-top: 8px; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 90%;">
-              {{ item.document || '文件' }}
+              </div>
+            </template>
+            <!-- 没有封面图:显示文件图标 -->
+            <template v-else>
+              <component :is="getFileIcon(item)"
+                :style="{ fontSize: (baseSize > 100 ? '48px' : '36px'), color: '#1890ff' }" />
+              <div
+                style="font-size: 12px; color: #666; margin-top: 8px; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 90%;">
+                {{ item.document || '文件' }}
+              </div>
+            </template>
+            <!-- 删除按钮 -->
+            <div v-if="!props.disabled && isDeletable" style="position: absolute; top: 4px; right: 4px; z-index: 10;"
+              @click.stop>
+              <a-popconfirm :open="linksid == item.linksid" title="确定删除当前资源吗?" @confirm="confirmDeleteImage"
+                @cancel="linksid = null">
+                <DeleteOutlined class="previewMaskIcon" :style="{ fontSize: '18px', color: '#ff4d4f' }"
+                  @click.stop="linksid = item.linksid" />
+              </a-popconfirm>
             </div>
           </div>
         </a-popover>
@@ -117,6 +90,44 @@
     <div class="empty" v-if="!list.length">
       <a-empty :image="simpleImage" />
     </div>
+
+    <!-- 视频播放对话框 -->
+    <a-modal v-model:open="videoVisible" :title="videoTitle" :footer="null" width="800px" centered>
+      <div style="padding: 20px 0 20px 0;">
+        <div style="display: flex; justify-content: center; background: #000; padding: 20px; border-radius: 8px;">
+          <video :src="videoUrl" controls autoplay style="max-width: 100%; max-height: 60vh;" @ended="onVideoEnded" />
+        </div>
+      </div>
+      <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
+        <a-button @click="switchVideo(-1)" :disabled="currentVideoIndex <= 0">
+          <template #icon><left-outlined /></template>
+          上一个
+        </a-button>
+        <span style="font-size: 14px; color: #666;">{{ currentVideoIndex + 1 }} / {{ videoList.length }}</span>
+        <a-button @click="switchVideo(1)" :disabled="currentVideoIndex >= videoList.length - 1">
+          下一个
+          <template #icon><right-outlined /></template>
+        </a-button>
+      </div>
+    </a-modal>
+
+    <!-- 图片预览对话框 -->
+    <a-modal v-model:open="imagePreviewVisible" :footer="null" width="90%" centered :closable="true">
+      <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
+        <a-button @click="switchImage(-1)" :disabled="currentImageIndex <= 0">
+          <template #icon><left-outlined /></template>
+          上一个
+        </a-button>
+        <span style="font-size: 14px; color: #666;">{{ currentImageIndex + 1 }} / {{ imageList.length }}</span>
+        <a-button @click="switchImage(1)" :disabled="currentImageIndex >= imageList.length - 1">
+          下一个
+          <template #icon><right-outlined /></template>
+        </a-button>
+      </div>
+      <div style="display: flex; justify-content: center;">
+        <a-image :src="currentImageUrl" style="max-width: 100%; max-height: 80vh;" />
+      </div>
+    </a-modal>
   </div>
 </template>
 
@@ -125,7 +136,7 @@ import { ref, reactive, defineProps, watch, computed } from "vue";
 import Api from "@/api/api";
 import Up from "@/api/upload";
 import utils from "@/utils/utils";
-import { DeleteOutlined, FileOutlined, FileTextOutlined, PlayCircleOutlined } from "@ant-design/icons-vue";
+import { DeleteOutlined, FileOutlined, FileTextOutlined, PlayCircleOutlined, LeftOutlined, RightOutlined } from "@ant-design/icons-vue";
 import { Empty } from "ant-design-vue";
 
 const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
@@ -237,6 +248,20 @@ function getFileIcon(item) {
   return FileTextOutlined;
 }
 
+// 判断是否有封面图
+function hasCoverImage(item) {
+  if (!item || !item.subfiles || !item.subfiles.length) return false;
+  const hasCover = item.subfiles.some(s => s.type === 'cover');
+  return hasCover;
+}
+
+// 获取封面图
+function getCoverImage(item) {
+  if (!item || !item.subfiles || !item.subfiles.length) return null;
+  const cover = item.subfiles.find(s => s.type === 'cover');
+  return cover;
+}
+
 // 格式化文件大小
 function getFileSize(size) {
   if (!size) return '未知大小';
@@ -250,6 +275,16 @@ function getFileSize(size) {
   return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
 }
 
+// 处理文件点击:视频播放,其他下载
+function handleFileClick(item) {
+  const type = (item.fileType || '').toLowerCase();
+  if (type === 'video') {
+    playVideo(item);
+  } else {
+    downloadFile(item);
+  }
+}
+
 // 下载文件
 function downloadFile(item) {
   const link = document.createElement('a');
@@ -261,6 +296,59 @@ function downloadFile(item) {
   document.body.removeChild(link);
 }
 
+// 视频播放相关
+let videoVisible = ref(false);
+let videoUrl = ref('');
+let videoTitle = ref('');
+let currentVideoIndex = ref(0);
+let videoList = ref([]);
+
+function playVideo(item) {
+  // 获取所有视频列表
+  videoList.value = list.value.filter(v => (v.fileType || '').toLowerCase() === 'video');
+  currentVideoIndex.value = videoList.value.findIndex(v => v.linksid === item.linksid);
+  videoUrl.value = item.url;
+  videoTitle.value = item.document;
+  videoVisible.value = true;
+}
+
+function switchVideo(direction) {
+  const newIndex = currentVideoIndex.value + direction;
+  console.log("videoList.value[newIndex]", videoList.value[newIndex])
+  if (newIndex >= 0 && newIndex < videoList.value.length) {
+    currentVideoIndex.value = newIndex;
+    videoUrl.value = videoList.value[newIndex].url;
+    videoTitle.value = videoList.value[newIndex].document || '视频';
+  }
+}
+
+function onVideoEnded() {
+  // 播放结束自动切换到下一个
+  switchVideo(1);
+}
+
+// 图片预览相关
+let imagePreviewVisible = ref(false);
+let currentImageUrl = ref('');
+let currentImageIndex = ref(0);
+let imageList = ref([]);
+
+function openImagePreview(index) {
+  // 获取所有图片列表
+  imageList.value = list.value.filter(v => isImageFile(v));
+  currentImageIndex.value = index;
+  currentImageUrl.value = imageList.value[index].url;
+  imagePreviewVisible.value = true;
+}
+
+function switchImage(direction) {
+  const newIndex = currentImageIndex.value + direction;
+  if (newIndex >= 0 && newIndex < imageList.value.length) {
+    currentImageIndex.value = newIndex;
+    currentImageUrl.value = imageList.value[newIndex].url;
+  }
+}
+
 function beforeUpload(file) {
   file.document = file.name;
   const filetype = file.document.substr(file.document.lastIndexOf(".") + 1);
@@ -359,7 +447,7 @@ watch(
   }
 );
 function init(attinfos, pic = props.pic) {
-  if(!attinfos.length) return;
+  if (!attinfos.length) return;
   const fileType = Number(props.fileType);
   if (pic) {
     list.value = attinfos;
@@ -382,7 +470,7 @@ function init(attinfos, pic = props.pic) {
   if (
     pic &&
     list.value[list.value.length - 1].sequence !=
-      props.startSequence + list.value.length
+    props.startSequence + list.value.length
   ) {
     setSequenceAll();
   }
@@ -503,6 +591,10 @@ function handleHoverChange(visible, index) {
   opacity: 1;
 }
 
+.picture-wall-box .picture-wall-item :deep(.ant-popconfirm) {
+  z-index: 10;
+}
+
 .empty {
   width: 100%;
   padding: 50px 0;

+ 0 - 0
部署时要将h5preview文件复制到根目录一起打包.txt


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác