吉安感知网项目-前端
张含笑
2026-01-27 dd57e0e9a989e7ee8b3e3473a7ee6a1dff06a4ae
uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -1,68 +1,523 @@
<!-- 工单详情 - 包含待审核、待处理、处理中、已完成 -->
<!-- 工单详情 -->
<template>
  <div class="workDetailContainer">
    <WebViewPlus
      ref="sWebViewRef"
      :src="`${viewUrl}`"
      @webMessage="onPostMessage"
    />
   <div class="workDetailContainer">
      <!-- 自定义导航栏 -->
      <u-navbar title="工单详情" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick">
         <template #right>
            <div class="share-btn" @click="onShareClick"></div>
         </template>
      </u-navbar>
      <div class="detailTop">
         <div class="image-container">
            <u-swiper
               class="detailImage"
               :list="getImageList"
               mode="round"
               indicator
               indicatorMode="dot"
               indicatorActiveColor="#4C85FF"
               indicatorInactiveColor="#fff"
               indicatorPosition="center"
               height="410rpx"
               @click="previewImage"
            ></u-swiper>
         </div>
      </div>
    <!-- 工单内容 -->
    <div class="worderContainer">
      <div class="workOrderContent">
        <div class="workOrderTitle">工单内容</div>
        <div class="workOrderContainer">
          <div class="orderRow">
            <div class="rowTitle">工单编号</div>
            <div>{{ workDetailData.eventCode }}</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="actionButton">
      <div class="btngroups">
        <up-button type="primary"  color="#AEAEAE" text="退回" @click="rejectTicket"></up-button>
        <up-button type="primary" color="#1D6FE9" text="确认" @click="confirmTheTicket"></up-button>
      </div>
    </div>
    <!-- 分享弹出层 -->
    <div v-if="showShareModal" class="share-modal-overlay" @click="onShareModalClose">
      <div class="share-modal-content" @click.stop>
        <div class="share-modal-header">
          <div class="share-modal-title">分享到</div>
          <div class="share-modal-close" @click="onShareModalClose">×</div>
        </div>
        <div class="share-modal-body">
          <div class="share-item" @click="shareToWechat">
            <div class="share-icon wechat"></div>
            <div class="share-name">微信好友</div>
          </div>
          <div class="share-item" @click="shareToMoments">
            <div class="share-icon moments"></div>
            <div class="share-name">朋友圈</div>
          </div>
          <div class="share-item" @click="copyLink">
            <div class="share-icon link"></div>
            <div class="share-name">复制链接</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { getWebViewUrl } from "@/utils/index.js";
import { onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "@/store/index.js";
const userStore = useUserStore();
const userInfo = userStore.userInfo;
const sWebViewRef = ref(null);
const viewUrl = ref("");
onLoad((options) => {
  const eventNum = options.eventNum;
  viewUrl.value = getWebViewUrl("/workDetail", {
    eventNum: eventNum,
    totalNum: options.totalNum,
    keyword: options.keyword,
    aiType: options.aiType,
    wLJobInfoId: options.wLJobInfoId,
    status: options.status,
    current: options.current,
  });
});
// import { getShowImg, getSmallImg } from '@/utils/util'
import { ref, computed } from 'vue'
import {getGddetailedData,backGdApi} from '/src/api/work/index.js'
import dayjs from 'dayjs'
const formatDate = dateString => {
  return dayjs(dateString).format('MM/DD HH:mm')
}
const eventNum = ref('')
// 工单内容
const workDetailData = ref({})
onLoad(async options => {
  eventNum.value = options.id
  await getDataList(options.id)
})
const getDataList = async val => {
  const params = {
    id: val,
  }
  const res = await getGddetailedData(params)
  const response = res.data.data
  workDetailData.value = response
  console.log('详情', workDetailData.value)
function onPostMessage(data) {
  if (data.type === "workback") {
    // #ifdef MP-WEIXIN
    if ("fun" in data && data.fun === "add") {
      uni.setStorageSync("joinParams", {
        type: "add",
      });
    }
    // #endif
}
// 图片预览
const previewImage = index => {
  if (getImageList.value.length === 0) return
  const currentIndex = typeof index === 'number' ? index : 0
  uni.previewImage({
    urls: getImageList.value,
    current: currentIndex,
  })
}
const getImageList = computed(() => {
  const imageArr = []
  const detail = workDetailData.value
  if (detail.eventImageUrl) {
    const smallUrl = detail.eventImageUrl
    imageArr.push(smallUrl)
  }
  if (detail.update_photo_url) {
    const smallUrl = detail.update_photo_url
    imageArr.push(smallUrl)
  }
  return imageArr
})
// 跳转地图
const jumpMap = item => {
  const contactStr = encodeURIComponent(JSON.stringify(item))
  uni.navigateTo({
    url: `/subPackages/workDetail/mapWork/index?eventNum=${contactStr}`,
  })
}
// 退回
const rejectTicket = () => {
  const id = workDetailData.value.id
  backGdApi({eventId : id,eventStatus:'0'}).then(res => {
    uni.showToast({
      title: '退回成功',
      icon: 'success',
      duration: 1500
    })
    setTimeout(() => {
      uni.navigateBack()
    }, 1500)
  })
    // #ifndef MP-WEIXIN
    uni.setStorageSync("joinParams", {
      type: "add",
    });
    uni.switchTab({
      url: `/pages/work/index?addLog=111`,
      // url: '/pages/work/index'
    });
    // #endif
  } else if (data.type === "jumpMapNav") {
    // #ifndef MP-WEIXIN
    uni.navigateTo({
      url: `/subPackages/workDetail/mapWork/index?currentItem=${data.eventNum}`,
    });
    // #endif
}
// 确认工单
const confirmTheTicket = () => {
  const id = workDetailData.value.id
  backGdApi({eventId : id,eventStatus:'1'}).then(res => {
    uni.showToast({
      title: '确认成功',
      icon: 'success',
      duration: 1500
    })
    setTimeout(() => {
      uni.navigateBack()
    }, 1500)
  })
}
// 分享模态框状态
const showShareModal = ref(false)
// 分享按钮点击事件 - 显示分享模态框
const onShareClick = () => {
   showShareModal.value = true
}
// 关闭分享模态框
const onShareModalClose = () => {
   showShareModal.value = false
}
// 微信好友分享
const shareToWechat = () => {
   shareToPlatform('weixin', 'WXSceneSession')
}
// 朋友圈分享
const shareToMoments = () => {
   shareToPlatform('weixin', 'WXSceneTimeline')
}
// 复制链接
const copyLink = async () => {
   const shareUrl = 'https://example.com/workDetail?eventNum=' + workDetailData.value.event_num
   try {
      await uni.setClipboardData({
         data: shareUrl,
      })
      uni.showToast({
         title: '链接已复制',
         icon: 'success',
      })
   } catch (error) {
      console.error('复制失败:', error)
      uni.showToast({
         title: '复制失败,请重试',
         icon: 'none',
      })
   }
   onShareModalClose()
}
// 通用分享平台函数
const shareToPlatform = (provider, scene = '') => {
   // 检查当前平台是否支持分享功能
   const platform = uni.getSystemInfoSync().platform
   // H5平台不支持uni.share API
   if (platform === 'web') {
      uni.showToast({
         title: 'H5平台暂不支持分享功能',
         icon: 'none',
      })
      onShareModalClose()
      return
   }
   // 检查uni.share是否存在
   if (typeof uni.share !== 'function') {
      uni.showToast({
         title: '当前环境不支持分享功能',
         icon: 'none',
      })
      onShareModalClose()
      return
   }
   try {
      const shareConfig = {
         provider,
         type: 0,
         title: workDetailData.value.event_name || '工单详情',
         summary: '查看工单详情',
         href: 'https://example.com/workDetail?eventNum=' + workDetailData.value.event_num,
         imageUrl: workDetailData.value.photo_url,
         success: () => {
            uni.showToast({ title: '分享成功', icon: 'success' })
            onShareModalClose()
         },
         fail: err => {
            console.log('分享失败', err)
            uni.showToast({
               title: '分享失败,请重试',
               icon: 'none',
            })
            onShareModalClose()
         },
      }
      // 添加场景参数(如果有)
      if (scene) {
         shareConfig.scene = scene
      }
      uni.share(shareConfig)
   } catch (error) {
      console.error('分享出错:', error)
      uni.showToast({
         title: '分享功能异常',
         icon: 'none',
      })
      onShareModalClose()
   }
}
// 返回按钮点击事件
const onBackClick = () => {
  uni.navigateBack()
}
// 监听导航栏右侧按钮点击事件(兼容原来的配置)
const onNavigationBarButtonTap = e => {
  if (e.index === 0) {
    onShareClick()
  }
}
</script>
<style lang="scss" scoped>
.workDetailContainer {
  width: 100%;
  height: 100%;
  background-size: cover;
  // 添加导航栏高度的padding-top,避免内容被遮挡
  padding-top: 88rpx;
  :deep(){
  .u-navbar__content{
    background: url("https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png")  no-repeat !important;
    background-size: 100%!important;
    height: 88rpx !important;
  }
}  // 分享按钮样式
  .share-btn {
    width: 40rpx;
    height: 40rpx;
    background-image: url('/static/images/work/share.svg');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
  }
  .detailTop {
  // #ifdef APP-PLUS
  padding-top: 60rpx;
  // #endif
    .image-container {
      position: relative;
      width: 100%;
      height: 410rpx;
      .detailImage {
        width: 100%;
        height: 100%;
        display: block;
        object-fit: cover;
      }
      // 轮播图容器
      :deep(.u-swiper) {
        // 指示器容器 - 修改为居中对齐
        .u-swiper__indicator {
          position: absolute;
          left: 50%;
          transform: translateX(-50%);
          bottom: 20rpx;
          display: flex;
          justify-content: center;
          align-items: center;
          z-index: 10;
        }
        .u-swiper-indicator__wrapper__dot--active {
          width: 5px !important;
        }
      }
    }
  }
  .worderContainer {
    padding: 0 24rpx;
    padding-bottom: 4rpx;
    background: #f6f6f6;
    margin-top: 20rpx;
  }
  .workOrderContent {
    margin-top: 30epx;
    background-color: #fff;
    border-radius: 12rpx;
    padding: 20rpx;
    margin-bottom: 34rpx;
    .workOrderTitle {
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: bold;
      font-size: 32rpx;
      color: #222324;
    }
    .workOrderContainer {
      .orderRow {
        display: flex;
        justify-content: space-between;
        align-items: center;
        min-height: 96rpx;
        border-bottom: 1px solid #f5f5f5;
        color: #7b7b7b;
        .rowTitle {
          font-family: Source Han Sans CN, Source Han Sans CN;
          font-weight: 400;
          font-size: 30rpx;
          color: #222324;
          white-space: nowrap;
        }
        .rowAddress {
          font-family: Source Han Sans CN, Source Han Sans CN;
          font-weight: 400;
          font-size: 28rpx;
          color: #1d6fe9;
          text-decoration: underline;
          text-align: right;
          padding-top: 1px;
          padding-left: 5px;
          padding-right: 2px;
        }
      }
    }
  }
  .actionButton {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 61px;
    border-radius: 6px 6px 6px 6px;
    .btngroups {
      display: flex;
      justify-content: space-between;
      align-items: center;
      :deep(.u-button) {
        width: 276rpx !important;
        height: 76rpx !important;
        &:last-child {
          margin-left: 30rpx;
        }
      }
    }
  }
}
/* 分享弹出层样式 */
.share-modal-overlay {
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   background-color: rgba(0, 0, 0, 0.6);
   display: flex;
   justify-content: flex-end;
   align-items: flex-end;
   z-index: 9999;
}
.share-modal-content {
   background-color: #fff;
   border-radius: 20rpx 20rpx 0 0;
   padding: 30rpx;
   width: 100%;
   max-height: 80vh;
   overflow-y: auto;
}
.share-modal-header {
   display: flex;
   justify-content: space-between;
   align-items: center;
   margin-bottom: 30rpx;
}
.share-modal-title {
   font-size: 36rpx;
   font-weight: bold;
   color: #222324;
   text-align: center;
   flex: 1;
}
.share-modal-close {
   font-size: 60rpx;
   color: #999;
   line-height: 40rpx;
}
.share-modal-body {
   display: flex;
   flex-wrap: wrap;
   justify-content: space-around;
   padding-bottom: 30rpx;
}
.share-modal-footer {
   display: flex;
   justify-content: space-around;
   padding-top: 30rpx;
   border-top: 1px solid #f0f0f0;
}
.share-item {
   display: flex;
   flex-direction: column;
   align-items: center;
   margin: 20rpx;
   width: 120rpx;
}
.share-icon {
   width: 90rpx;
   height: 90rpx;
   border-radius: 50%;
   margin-bottom: 15rpx;
   background-size: contain;
   background-repeat: no-repeat;
   background-position: center;
}
.share-icon.wechat {
   background-image: url('@/static/images/work/wechat.svg');
}
.share-icon.moments {
   background-image: url('@/static/images/work/moments.svg');
}
.share-icon.link {
   background-image: url('@/static/images/work/link.svg');
}
.share-name {
   font-size: 24rpx;
   color: #666;
   margin-top: 10rpx;
}
</style>