hookehuyr

feat(UploadMedia): 替换点击事件为tap并优化预览组件

使用nut-image-preview组件替换自定义图片预览模态框
将click事件统一改为更适合移动端的tap事件
添加播放图标资源并替换文本播放按钮
优化保存后的页面跳转逻辑
1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1756374388710" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1502" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M852.727563 392.447107C956.997809 458.473635 956.941389 565.559517 852.727563 631.55032L281.888889 993.019655C177.618644 1059.046186 93.090909 1016.054114 93.090909 897.137364L93.090909 126.860063C93.090909 7.879206 177.675064-35.013033 281.888889 30.977769L852.727563 392.447107 852.727563 392.447107Z" fill="#FFFFFF" p-id="1503"></path></svg>
...\ No newline at end of file ...\ No newline at end of file
...@@ -136,45 +136,3 @@ ...@@ -136,45 +136,3 @@
136 left: 0; 136 left: 0;
137 } 137 }
138 } 138 }
...\ No newline at end of file ...\ No newline at end of file
139 -
140 -.preview-modal {
141 - position: fixed;
142 - top: 0;
143 - left: 0;
144 - width: 100%;
145 - height: 100%;
146 - background: rgba(0, 0, 0, 1);
147 - z-index: 9999;
148 - display: flex;
149 - align-items: center;
150 - justify-content: center;
151 -
152 - .preview-container {
153 - position: relative;
154 - width: 100%;
155 - height: 100%;
156 - display: flex;
157 - align-items: center;
158 - justify-content: center;
159 - }
160 -
161 - .preview-image {
162 - max-width: 100%;
163 - max-height: 100%;
164 - object-fit: contain;
165 - }
166 -
167 - .close-btn {
168 - position: absolute;
169 - top: 20rpx;
170 - right: 20rpx;
171 - width: 60rpx;
172 - height: 60rpx;
173 - background: rgba(0, 0, 0, 0.5);
174 - border-radius: 50%;
175 - display: flex;
176 - align-items: center;
177 - justify-content: center;
178 - z-index: 10000;
179 - }
180 -}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <view 7 <view
8 v-if="!uploadedFile" 8 v-if="!uploadedFile"
9 class="border border-dashed border-gray-300 rounded-lg p-8 flex flex-col items-center justify-center mb-4 bg-white" 9 class="border border-dashed border-gray-300 rounded-lg p-8 flex flex-col items-center justify-center mb-4 bg-white"
10 - @click="chooseMedia" 10 + @tap="chooseMedia"
11 > 11 >
12 <view class="text-gray-400 mb-4"> 12 <view class="text-gray-400 mb-4">
13 <Photograph size="48" /> 13 <Photograph size="48" />
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
26 :src="uploadedFile.url" 26 :src="uploadedFile.url"
27 class="w-full h-64 object-cover cursor-pointer" 27 class="w-full h-64 object-cover cursor-pointer"
28 mode="aspectFit" 28 mode="aspectFit"
29 - @click="previewImage" 29 + @tap="previewImage"
30 /> 30 />
31 <view 31 <view
32 - @click="removeFile" 32 + @tap="removeFile"
33 class="absolute top-2 right-2 w-8 h-8 bg-black bg-opacity-50 rounded-full flex items-center justify-center" 33 class="absolute top-2 right-2 w-8 h-8 bg-black bg-opacity-50 rounded-full flex items-center justify-center"
34 > 34 >
35 <Close size="16" class="text-white" /> 35 <Close size="16" class="text-white" />
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
40 <view v-if="uploadedFile.type === 'video'" class="relative rounded-lg overflow-hidden bg-white shadow-sm"> 40 <view v-if="uploadedFile.type === 'video'" class="relative rounded-lg overflow-hidden bg-white shadow-sm">
41 <view 41 <view
42 class="relative w-full h-64 bg-black rounded-lg flex items-center justify-center" 42 class="relative w-full h-64 bg-black rounded-lg flex items-center justify-center"
43 - @click="playVideo" 43 + @tap="playVideo"
44 > 44 >
45 <image 45 <image
46 v-if="uploadedFile.thumbnail" 46 v-if="uploadedFile.thumbnail"
...@@ -50,12 +50,12 @@ ...@@ -50,12 +50,12 @@
50 /> 50 />
51 <view class="absolute inset-0 flex items-center justify-center"> 51 <view class="absolute inset-0 flex items-center justify-center">
52 <view class="w-16 h-16 bg-black bg-opacity-60 rounded-full flex items-center justify-center"> 52 <view class="w-16 h-16 bg-black bg-opacity-60 rounded-full flex items-center justify-center">
53 - <text class="text-white text-2xl">▶</text> 53 + <image :src="playIcon" class="w-6 h-6" />
54 </view> 54 </view>
55 </view> 55 </view>
56 </view> 56 </view>
57 <view 57 <view
58 - @click="removeFile" 58 + @tap="removeFile"
59 class="absolute top-2 right-2 w-8 h-8 bg-black bg-opacity-50 rounded-full flex items-center justify-center" 59 class="absolute top-2 right-2 w-8 h-8 bg-black bg-opacity-50 rounded-full flex items-center justify-center"
60 > 60 >
61 <Close size="16" class="text-white" /> 61 <Close size="16" class="text-white" />
...@@ -74,14 +74,14 @@ ...@@ -74,14 +74,14 @@
74 <!-- Action Buttons --> 74 <!-- Action Buttons -->
75 <view class="flex gap-3"> 75 <view class="flex gap-3">
76 <view 76 <view
77 - @click="chooseMedia" 77 + @tap="chooseMedia"
78 class="flex-1 bg-gray-100 text-gray-700 py-3 rounded-lg text-center" 78 class="flex-1 bg-gray-100 text-gray-700 py-3 rounded-lg text-center"
79 > 79 >
80 {{ uploadedFile ? '重新选择' : '选择文件' }} 80 {{ uploadedFile ? '重新选择' : '选择文件' }}
81 </view> 81 </view>
82 <view 82 <view
83 v-if="uploadedFile" 83 v-if="uploadedFile"
84 - @click="saveMedia" 84 + @tap="saveMedia"
85 class="flex-1 bg-blue-500 text-white py-3 rounded-lg text-center" 85 class="flex-1 bg-blue-500 text-white py-3 rounded-lg text-center"
86 > 86 >
87 保存 87 保存
...@@ -94,11 +94,11 @@ ...@@ -94,11 +94,11 @@
94 v-if="videoVisible" 94 v-if="videoVisible"
95 class="fixed inset-0 bg-black" 95 class="fixed inset-0 bg-black"
96 style="z-index: 9999;" 96 style="z-index: 9999;"
97 - @click="closeVideo" 97 + @tap="closeVideo"
98 > 98 >
99 <!-- Close Button --> 99 <!-- Close Button -->
100 <view 100 <view
101 - @click.stop="closeVideo" 101 + @tap.stop="closeVideo"
102 class="absolute top-4 right-4 w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center" 102 class="absolute top-4 right-4 w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center"
103 style="z-index: 10000;" 103 style="z-index: 10000;"
104 > 104 >
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
118 :object-fit="'contain'" 118 :object-fit="'contain'"
119 :show-fullscreen-btn="true" 119 :show-fullscreen-btn="true"
120 style="width: 100vw; height: 100vh; position: absolute; top: 0; left: 0;" 120 style="width: 100vw; height: 100vh; position: absolute; top: 0; left: 0;"
121 - @click.stop 121 + @tap.stop
122 @play="handleVideoPlay" 122 @play="handleVideoPlay"
123 @pause="handleVideoPause" 123 @pause="handleVideoPause"
124 @error="handleVideoError" 124 @error="handleVideoError"
...@@ -126,31 +126,14 @@ ...@@ -126,31 +126,14 @@
126 /> 126 />
127 </view> 127 </view>
128 128
129 - <!-- Image Preview Modal --> 129 + <!-- 图片预览 -->
130 - <view 130 + <nut-image-preview
131 - v-if="previewVisible" 131 + v-model:show="previewVisible"
132 - class="fixed inset-0 bg-black" 132 + :images="previewImages"
133 - style="z-index: 9999;" 133 + :init-no="previewIndex"
134 - @click="closePreview" 134 + @close="closePreview"
135 - >
136 - <!-- Close Button -->
137 - <view
138 - @click.stop="closePreview"
139 - class="absolute top-4 right-4 w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center"
140 - style="z-index: 10000;"
141 - >
142 - <Close size="24" class="text-white" />
143 - </view>
144 -
145 - <!-- Image Preview -->
146 - <image
147 - :src="previewImages[previewIndex]?.src"
148 - class="w-full h-full object-contain"
149 - mode="aspectFit"
150 - @click.stop
151 /> 135 />
152 </view> 136 </view>
153 - </view>
154 </template> 137 </template>
155 138
156 <script setup> 139 <script setup>
...@@ -158,6 +141,7 @@ import { ref, onMounted } from 'vue'; ...@@ -158,6 +141,7 @@ import { ref, onMounted } from 'vue';
158 import Taro from '@tarojs/taro'; 141 import Taro from '@tarojs/taro';
159 import { Left, Photograph, Close } from '@nutui/icons-vue-taro'; 142 import { Left, Photograph, Close } from '@nutui/icons-vue-taro';
160 import BASE_URL from '@/utils/config'; 143 import BASE_URL from '@/utils/config';
144 +import playIcon from '@/assets/images/icon/play.svg';
161 145
162 // 响应式数据 146 // 响应式数据
163 const uploadedFile = ref(null); 147 const uploadedFile = ref(null);
...@@ -404,7 +388,9 @@ const saveMedia = async () => { ...@@ -404,7 +388,9 @@ const saveMedia = async () => {
404 388
405 // 延迟返回Dashboard页面 389 // 延迟返回Dashboard页面
406 setTimeout(() => { 390 setTimeout(() => {
407 - Taro.navigateBack(); 391 + Taro.reLaunch({
392 + url: '/pages/Dashboard/index'
393 + });
408 }, 2000); 394 }, 2000);
409 } catch (error) { 395 } catch (error) {
410 console.error('上传失败:', error); 396 console.error('上传失败:', error);
......