吉安感知网项目-前端
chenyao
2026-06-30 4b3c357f2fa24a27eac3fe59cbf64e34255ab212
applications/mobile-web-view/src/appPages/work/workDetail/index.vue
@@ -2,12 +2,20 @@
   <div class="workDetailContainer">
      <div class="detailTop">
         <div class="image-container">
            <van-swipe :autoplay="3000" indicator-color="#4C85FF">
            <van-swipe-item v-for="(img, index) in getImageList" :key="index">
               <van-image class="detailImage" :src="img" fit="cover" width="100%" height="235px"
                  @click="openPreview(index)" preview-visible="false" />
            </van-swipe-item>
         </van-swipe>
            <video
               v-if="isVideoAttachment && mediaSrc"
               ref="videoRef"
               class="video-js vjs-default-skin vjs-big-play-centered detailVideo"
               controls
               preload="auto"
               playsinline
            ></video>
            <van-swipe v-else :autoplay="3000" indicator-color="#4C85FF">
               <van-swipe-item v-for="(img, index) in [mediaSrc]" :key="index">
                  <van-image class="detailImage" :src="img" fit="cover" width="100%" height="235px"
                     @click="openPreview(index)" preview-visible="false" />
               </van-swipe-item>
            </van-swipe>
         </div>
      </div>
   <!-- 工单内容 -->
@@ -15,6 +23,10 @@
      <div class="workOrderContent">
        <div class="workOrderTitle">工单内容</div>
        <div class="workOrderContainer">
               <div class="orderRow">
                  <div class="rowTitle">工单名称</div>
                  <div>{{ workDetailData.eventName }}</div>
               </div>
          <div class="orderRow">
            <div class="rowTitle">工单编号</div>
            <div>{{ workDetailData.eventNum }}</div>
@@ -59,11 +71,18 @@
import { showToast, showNotify, showImagePreview } from 'vant'
import { getShowImg, getSmallImg } from '@/utils/util'
import { useRoute,useRouter } from 'vue-router'
import { getAiImg } from '@ztzf/utils'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
const keyword = ref('')
const route = useRoute()
const router = useRouter()
const workDetailData = ref({})
const videoRef = ref(null)
let player = null
const isVideoAttachment = computed(() => Number(workDetailData.value.attachmentType) === 3)
// 预览图片
const getImageList = computed(() => {
@@ -75,11 +94,10 @@
   }
   return imageArr
})
const openPreview = index => {
   const detail = workDetailData.value
   const showUrl = detail.eventImageUrl
const openPreview = () => {
   if (isVideoAttachment.value || !mediaSrc.value) return
   showImagePreview({
      images: [showUrl],
      images: [mediaSrc.value],
      startPosition: 0,
   })
}
@@ -88,21 +106,94 @@
router.push({
      path: '/webViewWrapper/mapWork',
      query: {
         currentItem: JSON.stringify(item)
         currentItem: JSON.stringify(item)
      }
   })
}
function replaceWithProxy(url) {
   if (!url) return ''
   return url.replace(
      /^https?:\/\/[^/]+/,
      'https://wrj.shuixiongit.com/ja-proxy'
   )
}
function getVideoType(url) {
   const path = (url || '').split('?')[0].toLowerCase()
   if (path.endsWith('.m3u8')) return 'application/x-mpegURL'
   if (path.endsWith('.mp4')) return 'video/mp4'
   if (path.endsWith('.webm')) return 'video/webm'
   if (path.endsWith('.ogg') || path.endsWith('.ogv')) return 'video/ogg'
   if (path.endsWith('.mov')) return 'video/quicktime'
   return ''
}
function getVideoSource() {
   const type = getVideoType(mediaSrc.value)
   return {
      src: mediaSrc.value,
      ...(type ? { type } : {}),
   }
}
function destroyPlayer() {
   if (!player) return
   player.dispose()
   player = null
}
async function initPlayer() {
   if (!isVideoAttachment.value || !mediaSrc.value) return
   await nextTick()
   if (!videoRef.value) return
   if (player) {
      player.src(getVideoSource())
      player.load()
      return
   }
   player = videojs(videoRef.value, {
      controls: true,
      preload: 'auto',
      autoplay: false,
      fluid: false,
      sources: [getVideoSource()],
   })
   player.on('error', () => {
      console.error('视频播放失败:', player?.error(), mediaSrc.value)
   })
}
const mediaSrc = ref('')
watch([isVideoAttachment, mediaSrc], () => {
   if (isVideoAttachment.value) {
      initPlayer()
   } else {
      destroyPlayer()
   }
})
onMounted(async () => {
   keyword.value = JSON.parse(route.query.workDetailData)
   try {
      const res = await getSharingDetailsApi({ cacheKey: keyword.value })
      workDetailData.value = res.data.data
      let {eventImageUrl,geojson} = workDetailData.value
      // http://220.177.172.27:8100 改为 https://wrj.shuixiongit.com/ja-proxy
      eventImageUrl = replaceWithProxy(eventImageUrl)
      if (eventImageUrl){
         mediaSrc.value = !isVideoAttachment.value && geojson ? await getAiImg(eventImageUrl,geojson) : eventImageUrl
      }
   } catch (error) {
      showToast('分享链接失效')
   }
})
onBeforeUnmount(destroyPlayer)
</script>
<style lang="scss" scoped>
.workDetailContainer {
@@ -110,12 +201,23 @@
      .image-container {
         position: relative;
         width: 100%;
         height: 235px;
         .detailImage {
            width: 100%;
            height: 100%;
            display: block;
            object-fit: cover;
         }
         .detailVideo {
            width: 100%;
            height: 235px;
         }
         :deep(.video-js .vjs-tech) {
            width: 100%;
            height: 100%;
         }
      }
   }