陕西昭德型煤:
1.现场巡检上传附件查看附件修改联调
| | |
| | | // Props 定义 |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | action: { type: String, default: "/common/minioUploads" }, |
| | | action: { type: String, default: "/common/commonUploads" }, |
| | | data: { type: Object }, |
| | | limit: { type: Number, default: 5 }, |
| | | fileSize: { type: Number, default: 10 }, // 默认10MB,适合视频 |
| | |
| | | isShowTip: { type: Boolean, default: true }, |
| | | disabled: { type: Boolean, default: false }, |
| | | drag: { type: Boolean, default: false }, // 拍照不需要拖拽 |
| | | statusType: { type: Number, default: "" }, // 用于区分不同状态的上传 |
| | | type: { type: Number, default: "" }, // 用于区分不同状态的上传 |
| | | maxVideoDuration: { type: Number, default: 30 }, // 最大视频时长(秒) |
| | | }); |
| | | |
| | |
| | | const testServerConnection = () => { |
| | | return new Promise((resolve) => { |
| | | uni.request({ |
| | | url: uploadFileUrl.value.replace('/common/minioUploads', '/common/test'), |
| | | url: uploadFileUrl.value.replace('/common/commonUploads', '/common/commonUploads'), |
| | | method: 'GET', |
| | | timeout: 5000, |
| | | success: (res) => { |
| | |
| | | filePath: filePath, |
| | | name: 'files', |
| | | formData: { |
| | | type: props.statusType || 0, |
| | | type: props.type || 0, |
| | | ...(props.data || {}) |
| | | }, |
| | | header: { |
| | |
| | | v-for="(videoUrl, index) in beforeProductionVideos" |
| | | :key="index" |
| | | class="video-item" |
| | | @click="previewVideo(videoUrl)" |
| | | @click="playVideo(videoUrl, index)" |
| | | > |
| | | <view class="video-preview"> |
| | | <video |
| | | :src="videoUrl" |
| | | class="video-thumbnail" |
| | | :poster="videoUrl" |
| | | :controls="false" |
| | | :show-center-play-btn="true" |
| | | @play="onVideoPlay" |
| | | ></video> |
| | | <view class="video-overlay"> |
| | | <u-icon name="play-circle-fill" size="40" color="#fff"></u-icon> |
| | | </view> |
| | | <view class="video-tip">点击播放</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 视频播放弹窗 --> |
| | | <u-popup |
| | | :show="showVideoPlayer" |
| | | mode="center" |
| | | width="100%" |
| | | height="100%" |
| | | :closeable="true" |
| | | @close="closeVideoPlayer" |
| | | :safeAreaInsetBottom="false" |
| | | > |
| | | <view class="video-player-container"> |
| | | <video |
| | | v-if="currentVideoUrl" |
| | | :src="currentVideoUrl" |
| | | class="video-player" |
| | | :controls="true" |
| | | :show-center-play-btn="true" |
| | | :enable-play-gesture="true" |
| | | :show-fullscreen-btn="true" |
| | | :enable-progress-gesture="true" |
| | | :object-fit="'contain'" |
| | | @fullscreenchange="onFullscreenChange" |
| | | ></video> |
| | | </view> |
| | | </u-popup> |
| | | |
| | | <!-- 空状态 --> |
| | | <view v-if="beforeProductionImgs.length === 0 && beforeProductionVideos.length === 0" class="empty-state"> |
| | |
| | | const beforeProductionImgs = ref([]) |
| | | // 视频数组 |
| | | const beforeProductionVideos = ref([]) |
| | | // 视频播放器 |
| | | const showVideoPlayer = ref(false) |
| | | const currentVideoUrl = ref('') |
| | | |
| | | // 打开弹窗并加载数据 |
| | | const openDialog = async (row) => { |
| | |
| | | }) |
| | | } |
| | | |
| | | // 预览视频 |
| | | const previewVideo = (url) => { |
| | | uni.previewVideo({ |
| | | sources: [{ |
| | | src: url |
| | | }], |
| | | fail: (err) => { |
| | | console.error('视频预览失败:', err) |
| | | uni.showToast({ |
| | | title: '视频预览失败', |
| | | icon: 'error' |
| | | }) |
| | | // 播放视频 |
| | | const playVideo = (url, index) => { |
| | | currentVideoUrl.value = url |
| | | showVideoPlayer.value = true |
| | | } |
| | | }) |
| | | |
| | | // 关闭视频播放器 |
| | | const closeVideoPlayer = () => { |
| | | showVideoPlayer.value = false |
| | | currentVideoUrl.value = '' |
| | | } |
| | | |
| | | // 视频播放事件 |
| | | const onVideoPlay = () => { |
| | | // 可以在这里处理播放事件 |
| | | } |
| | | |
| | | // 全屏变化事件 |
| | | const onFullscreenChange = (e) => { |
| | | console.log('全屏状态变化:', e) |
| | | // 如果退出全屏,可以选择关闭弹窗 |
| | | if (e.detail && e.detail.fullScreen === false) { |
| | | // 可以选择保持弹窗打开或关闭 |
| | | } |
| | | } |
| | | |
| | | // 表单关闭方法 |
| | |
| | | // 重置数据 |
| | | beforeProductionImgs.value = [] |
| | | beforeProductionVideos.value = [] |
| | | } |
| | | |
| | | // 处理URL,添加基础域名 |
| | | function formatUrl(url) { |
| | | if (!url) return '' |
| | | // 如果已经是完整URL,直接返回 |
| | | if (url.startsWith('http://') || url.startsWith('https://')) { |
| | | return url |
| | | } |
| | | // 否则添加基础域名 |
| | | return `https://nj477vg8876.vicp.fun${url.startsWith('/') ? '' : '/'}${url}` |
| | | } |
| | | |
| | | // 处理每一类数据:分离图片和视频 |
| | |
| | | const videos = [] |
| | | |
| | | items.forEach(item => { |
| | | const fileUrl = item.url || item.downloadUrl || item.fileUrl |
| | | if (!fileUrl) return |
| | | |
| | | const fullUrl = formatUrl(fileUrl) |
| | | |
| | | if (item.contentType?.startsWith('image/')) { |
| | | images.push(item.url) |
| | | images.push(fullUrl) |
| | | } else if (item.contentType?.startsWith('video/')) { |
| | | videos.push(item.url) |
| | | videos.push(fullUrl) |
| | | } |
| | | }) |
| | | |
| | |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .video-preview { |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: #333; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | position: relative; |
| | | } |
| | | |
| | | .video-tip { |
| | | .video-thumbnail { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | } |
| | | |
| | | .video-overlay { |
| | | position: absolute; |
| | | bottom: 5px; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | font-size: 12px; |
| | | color: #fff; |
| | | background-color: rgba(0, 0, 0, 0.6); |
| | | padding: 2px 8px; |
| | | border-radius: 4px; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.3); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .video-player-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background-color: #000; |
| | | position: relative; |
| | | } |
| | | |
| | | .video-player { |
| | | width: 100%; |
| | | height: 100%; |
| | | max-width: 100vw; |
| | | max-height: 100vh; |
| | | } |
| | | |
| | | .empty-state { |
| | |
| | | "delay" : 0 |
| | | }, |
| | | /* 模块配置 */ |
| | | "modules" : {}, |
| | | "modules" : { |
| | | "Camera" : {}, |
| | | "VideoPlayer" : {} |
| | | }, |
| | | /* 应用发布信息 */ |
| | | "distribute" : { |
| | | /* android打包配置 */ |
| | |
| | | try { |
| | | let arr = [] |
| | | if (beforeModelValue.value.length > 0) { |
| | | arr.push(...beforeModelValue.value.map(item => ({ ...item, statusType: 0 }))) |
| | | arr.push(...beforeModelValue.value.map(item => ({ ...item, type: 0 }))) |
| | | } |
| | | if (afterModelValue.value.length > 0) { |
| | | arr.push(...afterModelValue.value.map(item => ({ ...item, statusType: 1 }))) |
| | | arr.push(...afterModelValue.value.map(item => ({ ...item, type: 1 }))) |
| | | } |
| | | if (issueModelValue.value.length > 0) { |
| | | arr.push(...issueModelValue.value.map(item => ({ ...item, statusType: 2 }))) |
| | | arr.push(...issueModelValue.value.map(item => ({ ...item, type: 2 }))) |
| | | } |
| | | |
| | | // 提交数据 |
| | |
| | | :fileSize="50" |
| | | :fileType="['jpg', 'jpeg', 'png', 'mp4', 'mov']" |
| | | :maxVideoDuration="60" |
| | | :statusType="0" |
| | | :type="0" |
| | | @update:modelValue="handleStorageBlobUpdate" |
| | | /> |
| | | </view> |