wuhb 2 недель назад
Родитель
Сommit
e78f4f512b
2 измененных файлов с 91 добавлено и 5 удалено
  1. 3 4
      components/upload-image/upload-image.uvue
  2. 88 1
      pages/apply/applyNew.uvue

+ 3 - 4
components/upload-image/upload-image.uvue

@@ -64,6 +64,8 @@
     const emit = defineEmits<{
         (e: 'update:modelValue', images: UploadResponse[]): void
         (e: 'change', images: UploadResponse[]): void
+        (e: 'delete', index: number, list: UploadResponse[]): void
+        (e: 'preview', index: number, urls: string[]): void
     }>()
 
     // 图片列表
@@ -169,10 +171,7 @@
 
     // 预览图片
     const handlePreview = (index: number): void => {
-        uni.previewImage({
-            urls: imageUrls.value,
-            current: index
-        })
+        emit('preview', index, imageUrls.value)
     }
 
     // 删除图片

+ 88 - 1
pages/apply/applyNew.uvue

@@ -179,6 +179,7 @@
 				            businessType="material"
 				            @update:modelValue="handleImageUpdate"
 				            @delete="handleImageDelete"
+				            @preview="handleImagePreview"
 				        />
 				    </view>
 				</view>
@@ -225,11 +226,26 @@
 		                <text class="delete-confirm-cancel-text">取消</text>
 		            </view>
 		            <view class="delete-confirm-ok" @click="confirmDeleteImage">
-		                <text class="delete-confirm-ok-text">确定</text>
+		        <text class="delete-confirm-ok-text">确定</text>
 		            </view>
 		        </view>
 		    </view>
 		</view>
+		
+		<!-- 图片预览弹窗 -->
+		<view v-if="showImagePreview" class="image-preview-modal" @click="showImagePreview = false">
+		    <swiper class="preview-swiper" :current="previewIndex" @change="handlePreviewChange">
+		        <swiper-item v-for="(url, idx) in previewUrls" :key="idx">
+		            <image class="preview-image" :src="url" mode="aspectFit" @click.stop></image>
+		        </swiper-item>
+		    </swiper>
+		    <view class="preview-close" @click="showImagePreview = false">
+		        <text class="preview-close-text">×</text>
+		    </view>
+		    <view class="preview-indicator">
+		        <text class="preview-indicator-text">{{ previewIndex + 1 }} / {{ previewUrls.length }}</text>
+		    </view>
+		</view>
 	</view>
 </template>
 
@@ -284,6 +300,9 @@ const showMeasurePicker = ref<boolean>(false)
 const measureList = ref<UTSJSONObject[]>([])
 const showDeleteConfirm = ref<boolean>(false)
 const deleteImageIndex = ref<number>(0)
+const showImagePreview = ref<boolean>(false)
+const previewUrls = ref<string[]>([])
+const previewIndex = ref<number>(0)
 
 type NewMaterial = {
 	itemName: string
@@ -692,6 +711,17 @@ const confirmDeleteImage = (): void => {
     showDeleteConfirm.value = false
 }
 
+// 处理图片预览
+const handleImagePreview = (index: number, urls: string[]): void => {
+    previewUrls.value = urls
+    previewIndex.value = index
+    showImagePreview.value = true
+}
+
+const handlePreviewChange = (e: any): void => {
+    previewIndex.value = e.detail.current
+}
+
 // 处理新增物料
 const handleAddMaterial = async (): Promise<void> => {
 	// 验证输入
@@ -1501,4 +1531,61 @@ onMounted(() => {
 					font-size: 28rpx;
 					color: #ffffff;
 				}
+				
+				/* 图片预览弹窗样式 */
+				.image-preview-modal {
+					position: fixed;
+					top: 0;
+					left: 0;
+					right: 0;
+					bottom: 0;
+					background-color: #000000;
+					z-index: 10000;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+				
+				.preview-swiper {
+					width: 100%;
+					height: 80%;
+				}
+				
+				.preview-image {
+					width: 100%;
+					height: 100%;
+				}
+				
+				.preview-close {
+					position: absolute;
+					top: 80rpx;
+					right: 30rpx;
+					width: 60rpx;
+					height: 60rpx;
+					border-radius: 30rpx;
+					background-color: rgba(255, 255, 255, 0.3);
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+				
+				.preview-close-text {
+					font-size: 40rpx;
+					color: #ffffff;
+				}
+				
+				.preview-indicator {
+					position: absolute;
+					bottom: 100rpx;
+					left: 50%;
+					transform: translateX(-50%);
+					padding: 10rpx 30rpx;
+					background-color: rgba(0, 0, 0, 0.5);
+					border-radius: 20rpx;
+				}
+				
+				.preview-indicator-text {
+					font-size: 28rpx;
+					color: #ffffff;
+				}
  </style>