finish-plan-detail.vue 6.1 KB
<template>
  <view class="page-container" style="padding-bottom: 20px;">
    <!-- 页面级加载组件 -->
    <up-loading-page
        v-if="loading"
        :loading="true"
        title="加载中..."
        color="#3c9cff"
    ></up-loading-page>

    <!-- 内容容器 -->
    <template v-else>
      <view class="content-wrap" v-for="(i, index) in orderDetail" :key="index">
        <!-- 工单详情内容 -->
        <up-cell-group :border="false" inset>
          <!-- 1. 工单计划名称 -->
          <up-cell align="middle">
            <template #title>
              <view class="up-line-1">{{i.planName || '--'}}</view>
            </template>
          </up-cell>

          <!-- 2. 工单位置 -->
          <up-cell
              title="计划编码"
              :value="i.planNo || '--'"
              align="middle"
          ></up-cell>

          <!-- 3. 工单名称 -->
          <up-cell
              title="养护周期"
              :value="`${i.rate}${uni.$dict.getDictLabel('cycle_id_type', i.cycleId)}`"
              align="middle"
          ></up-cell>

          <!-- 4. 情况描述 -->
          <up-cell
              title="计划有效期"
              :value="`${timeFormat(i.beginTime,'yyyy-mm-dd')} 至 ${timeFormat(i.endTime,'yyyy-mm-dd')}`"
              align="middle"
          ></up-cell>

          <!-- 5. 问题照片(核心修复:兼容WebP + 强制尺寸) -->
          <up-cell title="照片">
            <template #value>
              <view class="cell-content-wrap">
                <!-- 修复1:手动渲染图片,兼容WebP + 强制尺寸 -->
                <view v-if="!!i.beginImgList?.length" class="album-container">
                  <view
                      class="album-item"
                      v-for="(imgUrl, imgIndex) in formatImageUrls(i.beginImgList)"
                      :key="imgIndex"
                      @click="previewImage(imgUrl, formatImageUrls(i.beginImgList))"
                  >
                    <image
                        :src="imgUrl"
                        mode="widthFix"
                        class="album-image"
                        :style="{width: '70px', height: '70px', objectFit: 'cover'}"
                    ></image>
                  </view>
                </view>
                <text v-else class="empty-text">暂无问题照片</text>
              </view>
            </template>
          </up-cell>

          <!-- 7. 处理结果 -->
          <up-cell align="middle">
            <template #title>
              <view style="min-width: 200rpx">养护描述</view>
            </template>
            <template #value>
              <view class="up-line-1 common-text-color">{{i.remark || '--'}}</view>
            </template>
          </up-cell>

          <up-cell
              title="提交时间"
              :value="i.finishTime==null?'--':timeFormat(i.finishTime,'yyyy-mm-dd hh:MM:ss')"
              align="middle"
          ></up-cell>

          <up-cell
              title="提交人"
              :value="i.userName || '--'"
              align="middle"
              :border="false"
          ></up-cell>
        </up-cell-group>
      </view>
    </template>
  </view>
</template>

<script setup lang="ts">
import {ref} from 'vue';
import {detailList} from "@/api/maintain-manage/maintain-manage";
import {onLoad} from '@dcloudio/uni-app';
import {timeFormat} from '@/uni_modules/uview-plus';

// 状态管理
const loading = ref(true);
const orderDetail = ref([]);

/**
 * 格式化图片URL(兼容WebP + 清理非法字符)
 * @param urls 原始图片列表
 */
const formatImageUrls = (urls) => {
  if (!Array.isArray(urls) || urls.length === 0) return [];

  return urls.map(url => {
    if (typeof url !== 'string') return '';
    // 1. 清理URL开头的非法字符(如数字、空格)
    const validStart = url.indexOf('http');
    const cleanUrl = validStart > 0 ? url.substring(validStart) : url;
    // 2. 小程序兼容:WebP转JPEG(可选,后端无转换则注释)
    // return cleanUrl.replace('.webp', '.jpeg');
    return cleanUrl;
  }).filter(url => !!url);
};

/**
 * 预览图片
 * @param currentUrl 当前点击的图片
 * @param allUrls 所有图片列表
 */
const previewImage = (currentUrl, allUrls) => {
  uni.previewImage({
    current: currentUrl,
    urls: allUrls,
    fail: (err) => {
      console.error('预览图片失败:', err);
      uni.showToast({title: '预览图片失败', icon: 'none'});
    }
  });
};

/**
 * 获取工单详情
 */
const getOrderDetail = async (planNo: string) => {
  try {
    loading.value = true;
    let queryData = {
      planNo: planNo,
      pageSize: 100,
      pageNo: 1,
    };
    const res = await detailList(queryData);
    console.log('接口返回:', res);

    // 修复2:正确解析接口数据(res.data.list 而非 res.list)
    orderDetail.value = res.data?.list || res.list || [];

    // 调试:打印格式化后的图片URL
    console.log('格式化后图片URL:', formatImageUrls(orderDetail.value[0]?.beginImgList || []));
  } catch (error) {
    console.error('获取工单详情失败:', error);
    uni.showToast({title: '加载失败,请重试', icon: 'none'});
  } finally {
    loading.value = false;
  }
};

// 页面加载
onLoad((options) => {
  const {planNo} = options;
  if (planNo) {
    getOrderDetail(planNo);
  } else {
    loading.value = false;
    uni.showToast({title: '缺少工单ID', icon: 'none'});
  }
});
</script>

<style scoped lang="scss">
// 内容容器
.content-wrap {
  background: #fff;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 30rpx;
}

// 图片容器样式
.cell-content-wrap {
  padding: 10rpx 0;
}

// 自定义相册容器
.album-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10rpx; // 图片间距
}

// 单张图片样式
.album-item {
  width: 70px;
  height: 70px;
  border-radius: 4rpx;
  overflow: hidden;
}

// 图片样式(强制尺寸 + 覆盖)
.album-image {
  width: 100%;
  height: 100%;
  object-fit: cover; // 保持比例裁剪,避免拉伸
}

// 空文本样式
.empty-text {
  color: #999;
  font-size: 14px;
  line-height: 70px; // 和图片高度对齐
}
</style>