吉安感知网项目-前端
罗广辉
11 hours ago 7320bc8910fbfe1488a236aa1588e4d388c3f36c
feat: 预览
6 files modified
251 ■■■■■ changed files
applications/mobile-web-view/src/appPages/work/workDetail/index.vue 124 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/App.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue 31 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue 31 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/orderManage/outcomeData.vue 35 ●●●●● patch | view | raw | blame | history
packages/utils/common/index.js 28 ●●●●● patch | view | raw | blame | history
applications/mobile-web-view/src/appPages/work/workDetail/index.vue
@@ -12,66 +12,73 @@
                ></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-image
                            class="detailImage"
                            :src="img"
                            fit="cover"
                            width="100%"
                            height="235px"
                            @click="openPreview(index)"
                            preview-visible="false"
                        />
                    </van-swipe-item>
                </van-swipe>
            </div>
        </div>
    <!-- 工单内容 -->
    <div class="worderContainer">
      <div class="workOrderContent">
        <div class="workOrderTitle">工单内容</div>
        <div class="workOrderContainer">
        <!-- 工单内容 -->
        <div class="worderContainer">
            <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>
          </div>
          <div class="orderRow">
            <div class="rowTitle">工单处置人</div>
            <div>{{ workDetailData.disposeUserName }}</div>
          </div>
          <div class="orderRow">
            <div class="rowTitle">处置部门</div>
            <div>{{ workDetailData.disposeDeptName }}</div>
          </div>
          <div class="orderRow">
            <div class="rowTitle">拍摄时间</div>
            <div>{{ workDetailData.shootTime }}</div>
          </div>
          <div class="orderRow">
            <div class="rowTitle">分发人员</div>
            <div>{{ workDetailData.distributeUserName }}</div>
          </div>
          <div class="orderRow">
            <div class="rowTitle">分发部门</div>
            <div>{{ workDetailData.distributeDeptName }}</div>
          </div>
                    <div class="orderRow">
                        <div class="rowTitle">工单编号</div>
                        <div>{{ workDetailData.eventNum }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">工单处置人</div>
                        <div>{{ workDetailData.disposeUserName }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">处置部门</div>
                        <div>{{ workDetailData.disposeDeptName }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">拍摄时间</div>
                        <div>{{ workDetailData.shootTime }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">分发人员</div>
                        <div>{{ workDetailData.distributeUserName }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">分发部门</div>
                        <div>{{ workDetailData.distributeDeptName }}</div>
                    </div>
          <div class="orderRow">
            <div class="rowTitle">分发时间</div>
            <div>{{ workDetailData.distributeTime }}</div>
          </div>
          <div class="orderRow">
            <div class="rowTitle">工单位置</div>
            <div class="rowAddress" @click="jumpMap(workDetailData)">{{ workDetailData.eventLocation }}</div>
          </div>
        </div>
      </div>
    </div>
                    <div class="orderRow">
                        <div class="rowTitle">分发时间</div>
                        <div>{{ workDetailData.distributeTime }}</div>
                    </div>
                    <div class="orderRow">
                        <div class="rowTitle">工单位置</div>
                        <div class="rowAddress" @click="jumpMap(workDetailData)">{{ workDetailData.eventLocation }}</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import {getSharingDetailsApi} from '@/api/work/index'
import { getSharingDetailsApi } from '@/api/work/index'
import { showToast, showNotify, showImagePreview } from 'vant'
import { getShowImg, getSmallImg } from '@/utils/util'
import { useRoute,useRouter } from 'vue-router'
import { getAiImg } from '@ztzf/utils'
import { useRoute, useRouter } from 'vue-router'
import { getAiImg, replaceWithProxy } from '@ztzf/utils'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
const keyword = ref('')
@@ -103,20 +110,12 @@
}
// 跳转地图
const jumpMap = item => {
router.push({
    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) {
@@ -181,16 +180,15 @@
    try {
        const res = await getSharingDetailsApi({ cacheKey: keyword.value })
        workDetailData.value = res.data.data
        let {eventImageUrl,geojson} = workDetailData.value
        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
        if (eventImageUrl) {
            mediaSrc.value = !isVideoAttachment.value && geojson ? await getAiImg(eventImageUrl, geojson) : eventImageUrl
        }
    } catch (error) {
        showToast('分享链接失效')
    }
})
onBeforeUnmount(destroyPlayer)
@@ -285,8 +283,8 @@
            }
            .rowAddress {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
                font-size: 14px;
                color: #1d6fe9;
                text-decoration: underline;
@@ -303,9 +301,7 @@
            :deep(.custom-field .van-field__control) {
                padding: 0 !important;
            }
        }
    }
}
</style>
applications/task-work-order/src/App.vue
@@ -16,7 +16,7 @@
    function getXTToken() {
        loginApi({
            "belongSystem": "basic",
            "username": "dkzx01",
            "username": "admin",
            "password": "geovis@123"
        })
            .then(res => {
applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
@@ -5,12 +5,14 @@
                <el-table-column label="线索缩略图" width="120">
                    <template v-slot="{ row }">
                        <el-image
                            :key="row.thumbnail"
                            v-if="row.attachmentType === 1 || row.attachmentType === 2"
                            :src="row.attachmentType === 1 ? row.resultUrl : row.aiImg"
                            :preview-src-list="[row.attachmentType === 1 ? row.resultUrl : row.aiImg]"
                            :src="row.thumbnail"
                            :preview-src-list="[row.resultUrl]"
                            fit="cover"
                            style="width: 80px; height: 80px"
                            preview-teleported
                            @error="handleThumbnailError(row)"
                        />
                        <div class="video-btn" v-if="row.attachmentType === 3" @click="videoClick(row)">
                            <el-icon :size="30" color="#fff">
@@ -67,7 +69,7 @@
import { ref } from 'vue'
import { gdTaskResultListApi } from './achievementApi'
import DistributeDiaLog from './DistributeDiaLog.vue'
import { getAiImg } from '@ztzf/utils'
import { appendAiImages } from '@ztzf/utils'
import { VideoPlay } from '@element-plus/icons-vue'
import VideoPlayDialog from '@/components/VideoPlayDialog.vue'
@@ -110,19 +112,28 @@
    return row.areaCode || '-'
}
// 缩略图加载失败时展示原图
function handleThumbnailError(item) {
    if (item.thumbnail !== item.resultUrl) {
        item.thumbnail = item.resultUrl
    }
}
// 获取成果列表
async function getList() {
    if (!currentRow.value?.id) return
    loading.value = true
    try {
        const res = await gdTaskResultListApi({ patrolTaskId: currentRow.value.id })
        list.value = await Promise.all(
            (res?.data?.data ?? []).map(async item => {
                if (item.attachmentType !== 2) return item
                const aiImg = await getAiImg(item.resultUrl, item.geojson)
                return { ...item, aiImg }
            })
        )
        list.value = (res?.data?.data ?? []).map(item => ({
            ...item,
            thumbnail: item.resultUrl.replace(/(\.[^./?]+)(\?.*)?$/, '_thumbnail$1$2'),
        }))
        list.value.forEach(item => {
            if (item.attachmentType === 2 && item.geojson !== '[]' && item.geojson?.length) {
                appendAiImages(item)
            }
        })
    } finally {
        loading.value = false
    }
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -88,11 +88,13 @@
                                )"
                            >
                                <el-image
                                    :key="item.thumbnail"
                                    v-if="item.attachmentType === 1 || item.attachmentType === 2"
                                    :src="item.attachmentType === 1 ? item.resultUrl : item.aiImg"
                                    :preview-src-list="[item.attachmentType === 1 ? item.resultUrl : item.aiImg]"
                                    :src="item.thumbnail"
                                    :preview-src-list="[item.resultUrl]"
                                    fit="cover"
                                    preview-teleported
                                    @error="handleThumbnailError(item)"
                                />
                                <div class="video-btn" v-if="item.attachmentType === 3" @click="videoClick(item)">
                                    <el-icon :size="30" color="#fff">
@@ -285,7 +287,7 @@
<script setup>
import { computed, ref, onMounted, inject } from 'vue'
import { ElMessage } from 'element-plus'
import { fieldRules, flyVisual, geomAnalysis, getAiImg } from '@ztzf/utils'
import { fieldRules, flyVisual, geomAnalysis, appendAiImages } from '@ztzf/utils'
import {
    gdPatrolTaskRepublish,
    gdFlyerPageApi,
@@ -509,18 +511,27 @@
}
let taskResultList = ref([])
// 缩略图加载失败时展示原图
function handleThumbnailError(item) {
    if (item.thumbnail !== item.resultUrl) {
        item.thumbnail = item.resultUrl
    }
}
// 获取成果列表
async function getTaskResultList() {
    if (!formData.value?.id) return
    try {
        const res = await gdTaskResultListApi({ patrolTaskId: formData.value.id })
        taskResultList.value = await Promise.all(
            (res?.data?.data ?? []).map(async item => {
                if (item.attachmentType !== 2) return item
                const aiImg = await getAiImg(item.resultUrl, item.geojson)
                return { ...item, aiImg }
            })
        )
        taskResultList.value = (res?.data?.data ?? []).map(item => ({
            ...item,
            thumbnail: item.resultUrl.replace(/(\.[^./?]+)(\?.*)?$/, '_thumbnail$1$2'),
        }))
        taskResultList.value.forEach(item => {
            if (item.attachmentType === 2 && item.geojson !== '[]' && item.geojson?.length) {
                appendAiImages(item)
            }
        })
    } finally {
    }
}
applications/task-work-order/src/views/orderView/orderManage/orderManage/outcomeData.vue
@@ -57,12 +57,14 @@
          <el-table-column label="图片/视频" >
            <template v-slot="{ row }">
                            <el-image
                                :key="row.thumbnail"
                                v-if="row.attachmentType === 1 || row.attachmentType === 2"
                                :src="row.attachmentType === 1 ? row.resultUrl : row.aiImg"
                                :preview-src-list="[row.attachmentType === 1 ? row.resultUrl : row.aiImg]"
                                :src="row.thumbnail"
                                :preview-src-list="[row.resultUrl]"
                                fit="cover"
                    style="width: 80px; height: 80px"
                    preview-teleported
                        style="width: 80px; height: 80px"
                        preview-teleported
                                @error="handleThumbnailError(row)"
                            />
                            <div class="video-btn" v-if="row.attachmentType === 3 && row.resultUrl" @click="videoClick(row)">
                                <el-icon :size="30" color="#fff">
@@ -113,7 +115,7 @@
import {gdTaskResultPageApi, gdTaskResultDownloadApi, gdTaskResultRemoveApi,listByWorkOrderId}from './orderManageApi'
import { Search, RefreshRight, Download } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getAiImg, getDictLabel } from '@ztzf/utils'
import { getDictLabel, appendAiImages } from '@ztzf/utils'
import dayjs from 'dayjs'
import VideoPlayDialog from '@/components/VideoPlayDialog.vue'
@@ -164,6 +166,13 @@
  }
}
// 缩略图加载失败时展示原图
function handleThumbnailError(item) {
  if (item.thumbnail !== item.resultUrl) {
    item.thumbnail = item.resultUrl
  }
}
// 获取成果数据列表
async function getList() {
  loading.value = true
@@ -175,13 +184,15 @@
        ? searchParams.value.patrolTaskIds.join(',')
        : ''
    })
        list.value = await Promise.all(
            (res?.data?.data?.records ?? []).map(async item => {
                if (item.attachmentType !== 2) return item
                const aiImg = await getAiImg(item.resultUrl,item.geojson)
                return { ...item, aiImg }
            })
        )
    list.value = (res?.data?.data?.records ?? []).map(item => ({
      ...item,
      thumbnail: item.resultUrl.replace(/(\.[^./?]+)(\?.*)?$/, '_thumbnail$1$2'),
    }))
    list.value.forEach(item => {
      if (item.attachmentType === 2 && item.geojson !== '[]' && item.geojson?.length) {
        appendAiImages(item)
      }
    })
    total.value = res?.data?.data?.total || 0
  } finally {
    loading.value = false
packages/utils/common/index.js
@@ -74,6 +74,34 @@
        })
}
// 替换图片请求代理地址
export function replaceWithProxy(url) {
    if (!url) return ''
    return url.replace(
        /^https?:\/\/[^/]+/,
        'https://wrj.shuixiongit.com/ja-proxy'
    )
}
// 异步生成算法成果图片
export async function appendAiImages(item) {
    try {
        const [resultUrl, thumbnail] = await Promise.all([
            getAiImg(replaceWithProxy(item.resultUrl), item.geojson),
            getAiImg(replaceWithProxy(item.thumbnail), item.geojson),
        ])
        console.log()
        if (item.id === '2019312870354416746'){
            console.log(resultUrl)
            console.log(thumbnail)
        }
        item.resultUrl = resultUrl
        item.thumbnail = thumbnail
    } catch {
        item.thumbnail = item.resultUrl
    }
}
// 图片转带ai框的图片
export function getAiImg(url, aiFrameSource) {
    if (!url) return url