road-detail-list.vue 8.83 KB
<template>
  <view class="page-container">
    <!-- 顶部吸顶区域 -->
    <up-sticky>
      <view class="sticky-header">
        <!-- 状态Tabs -->
        <up-tabs
            v-model="activeStatus"
            :list="statusTabs"
            line-width="40rpx"
            active-color="#1989fa"
            inactive-color="#666"
            :scrollable="true"
            class="status-tabs"
            @click="handleStatusChange"
        ></up-tabs>

        <!-- 搜索框 -->
        <up-search
            v-model="searchValue"
            :placeholder="searchPlaceholder"
            bg-color="#f5f5f5"
            shape="round"
            :show-action="true"
            actionText="搜索"
            :animation="true"
            @search="handleSearch"
            @custom="handleSearch"
            :clearabled="false"
            maxlength="50"
            class="search-input"
        ></up-search>
      </view>
    </up-sticky>

    <!-- 分页列表区域 -->
    <z-paging
        ref="pagingRef"
        v-model="planList"
        @query="queryList"
        :top="140"
    >
      <!-- 空数据插槽 -->
      <template #empty>
        <view class="empty-container">
          <up-empty mode="list" text="暂无相关计划数据"></up-empty>
        </view>
      </template>

      <!-- 列表内容 -->
      <view class="card-list">
        <view
            class="plan-card"
            v-for="(item, index) in planList"
            :key="index"
        >
          <view class="card-header">
            <text class="plan-name">{{ item.planName || '未命名计划' }}</text>
<!--            <text class="plan-status" :class="getStatusClass(item.status)">{{ getStatusText(item.status) }}</text>-->
          </view>
          <view class="card-body">
            <view class="info-item">
              <text class="label">计划编码:</text>
              <text class="value">{{ item.planNo || '-' }}</text>
            </view>
            <view class="info-item">
              <text class="label">养护周期:</text>
              <text class="value">{{ item.rate || '-' }} {{ uni.$dict.getDictLabel('cycle_id_type', item.cycleId) }}</text>
            </view>
            <view class="info-item">
              <text class="label">计划完成次数:</text>
              <text class="value">{{ item.planNum || 0 }}</text>
            </view>
            <view class="info-item">
              <text class="label">已完成比例:</text>
              <text class="value">{{ item.finishPercent || 0 }}%</text>
            </view>
            <view class="info-item">
              <text class="label">计划有效期:</text>
              <text class="value">{{ timeFormat(item.beginTime,'yyyy-mm-dd') || '-'}} 至 {{ timeFormat(item.endTime,'yyyy-mm-dd') || '-'}}</text>
            </view>
          </view>
          <view class="card-footer">
            <up-button
                type="primary"
                size="mini"
                @click="handleDetail(item)"
            >
              查看详情
            </up-button>
          </view>
        </view>
      </view>
    </z-paging>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { timeFormat } from '@/uni_modules/uview-plus'
import { getRoadDetails } from "@/api/maintain-manage/maintain-manage";

// ========== 基础数据定义 ==========
// 状态Tabs数据
const statusTabs = ref([
  { name: '待完成', id: '1' },
  { name: '已失效', id: '3' },
  { name: '已完成', id: '2' }
])

// 响应式数据
const activeStatus = ref('1')       // 当前选中的状态
const searchValue = ref('')         // 搜索框值
const planList = ref([])            // 计划列表(绑定z-paging)
const pagingRef = ref(null)         // z-paging实例
const loading = ref(false)          // 加载状态

// URL参数存储
const roadId = ref('')              // 从URL获取的roadId
const finishState = ref('')         // 从URL获取的finish_state

// 搜索占位符
const searchPlaceholder = computed(() => {
  return '请输入计划名称'
})

// ========== 方法定义 ==========
// 从URL获取参数
const getUrlParams = (options) => {
  // 1. 修复:URL中是roadId(驼峰),不是road_id
  if (options?.roadId) {
    roadId.value = options.roadId
    console.log('从URL获取的roadId:', roadId.value) // 打印验证
  }

  if (options?.finish_state) {
    finishState.value = options.finish_state
    // 同步更新Tabs选中状态
    activeStatus.value = options.finish_state
    console.log('从URL获取的finish_state:', finishState.value)
  }
}

// 状态切换
const handleStatusChange = (item) => {
  console.log('切换状态:', item)
  activeStatus.value = item.id
  // 更新finishState值
  finishState.value = item.id
  // 重置分页并刷新
  pagingRef.value?.reload()
}

// 搜索处理
const handleSearch = () => {
  console.log('搜索关键词:', searchValue.value)
  // 重置分页并刷新
  pagingRef.value?.reload()
}

// 获取状态文本
const getStatusText = (status) => {
  const statusMap = {
    '1': '待完成',
    '2': '已完成',
    '3': '已失效'
  }
  return statusMap[status] || '未知状态'
}

// 获取状态样式类
const getStatusClass = (status) => {
  const classMap = {
    '1': 'status-pending',
    '2': 'status-completed',
    '3': 'status-invalid'
  }
  return classMap[status] || ''
}

// 查看详情
const handleDetail = (item) => {
  uni.navigateTo({
    url: `/pages/planDetail/planDetail?planId=${item.id || ''}`
  })
}

// 分页请求数据(z-paging回调)
const queryList = async (pageNo, pageSize) => {
  try {
    loading.value = true

    // 构造请求参数:优先使用URL参数
    const paramsData = {
      pageNo: pageNo,
      pageSize: pageSize,
      road_id: roadId.value, // 现在能拿到正确的roadId了
      finish_state: finishState.value || activeStatus.value,
      planName: searchValue.value.trim()
    }

    console.log('请求参数:', paramsData) // 验证road_id是否有值
    const res = await getRoadDetails(paramsData)
    console.log(res)
    // 兼容不同的接口返回格式
    const listData = res?.list || res || []

    // 告知z-paging数据加载完成
    pagingRef.value?.complete(listData)
    loading.value = false
  } catch (error) {
    console.error('请求失败:', error)
    uni.showToast({ title: '加载失败,请重试', icon: 'none' })
    pagingRef.value?.complete(false)
    loading.value = false
  }
}

// ========== 生命周期修复 ==========
// 2. 修复:只有onLoad才会接收页面跳转的options参数
onLoad((options) => {
  // 页面首次加载时获取URL参数
  getUrlParams(options)
  // 初始化数据
  pagingRef.value?.reload()
})

onShow(() => {
  // 可选:页面再次显示时刷新(比如从详情页返回)
  // if (roadId.value) { // 有roadId才刷新
  //   pagingRef.value?.reload()
  // }
})

onMounted(() => {
  // 可选:初始化其他逻辑
})
</script>

<style scoped lang="scss">
.page-container {
  min-height: 100vh;
  background-color: #f8f8f8;
}

// 顶部吸顶区域样式
.sticky-header {
  background-color: #ffffff;
  padding-bottom: 10rpx;
  border-bottom: 1px solid #eee;

  // 状态Tabs样式
  .status-tabs {
    margin: 10rpx 0 0 0;
  }

  // 搜索框样式
  .search-input {
    margin: 20rpx 20rpx 10rpx !important;
  }
}

// 卡片列表样式
.card-list {
  padding: 0 20rpx;
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

// 计划卡片样式
.plan-card {
  background-color: #ffffff;
  border-radius: 12rpx;
  padding: 24rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);

  // 卡片头部
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20rpx;
    padding-bottom: 12rpx;
    border-bottom: 1px solid #f5f5f5;

    .plan-name {
      font-size: 30rpx;
      font-weight: 600;
      color: #333;
    }

    .plan-status {
      font-size: 24rpx;
      padding: 4rpx 12rpx;
      border-radius: 20rpx;

      // 状态样式
      &.status-pending {
        background-color: #fff7e6;
        color: #ff9f1c;
      }

      &.status-completed {
        background-color: #e8f8f5;
        color: #00b42a;
      }

      &.status-invalid {
        background-color: #f5f5f5;
        color: #999;
      }
    }
  }

  // 卡片内容
  .card-body {
    display: flex;
    flex-direction: column;
    gap: 16rpx;
    margin-bottom: 20rpx;

    .info-item {
      display: flex;
      align-items: center;
      font-size: 28rpx;

      .label {
        color: #999;
        flex-shrink: 0;
      }

      .value {
        color: #333;
        flex: 1;
      }
    }
  }

  // 卡片底部
  .card-footer {
    display: flex;
    justify-content: flex-end;
  }
}

// 空数据样式
.empty-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400rpx;
}
</style>