orderDetail.vue 8.49 KB
<template>
  <view>
    <scroll-view scroll-y class="detail-content">
      <!-- 成员信息 -->
      <view class="card">
        <view class="card-header">
          <view class="header-left">成员信息</view>
          <view class="header-right">{{ total || 0 }}</view>
        </view>

        <!-- 加载状态 -->
        <view v-if="loading" class="state-tip">加载中...</view>
        <view v-else-if="memberList.length === 0" class="state-tip">暂无成员信息</view>

        <!-- 成员列表 - 与级位考试详情考生信息样式一致 -->
        <view class="student-list" v-else>
          <view class="student-card" v-for="n in memberList" :key="n.payId || n.perId || n.id">
            <view class="student-top">
              <view class="student-name">
                <text class="name">{{ n.perName || n.realName || '——' }}</text>
                <text class="unit">{{ n.memName || '' }}</text>
              </view>
              <view class="new-tag" :class="n.isNew == 1 ? 'is-new' : ''">
                {{ n.isNew == 1 ? '新会员' : '续费' }}
              </view>
            </view>
            <view class="student-info">
              <view class="info-col">
                <text class="info-text">{{ n.perIdcCode || n.idcCode || '——' }}</text>
              </view>
              <view class="info-col">
                <text class="info-text">{{ n.payYear || n.renewYear || '——' }}</text>
              </view>
              <view class="info-col">
                <text class="info-text">{{ getIdcTypeText(n.perIdcType || n.idcType) }}</text>
              </view>
            </view>
          </view>
        </view>

        <!-- 加载更多 -->
        <view class="load-more" v-if="memberList.length > 0 && hasMore" @click="loadMore">
          {{ loadingMore ? '加载中...' : '加载更多' }}
        </view>
      </view>

      <!-- 审核记录 -->
      <view class="h3-padding">审核记录</view>
      <view class="wBox">
        <view v-if="loadingAudit" class="state-tip">加载中...</view>
        <view v-else-if="auditList.length === 0" class="state-tip">暂无审核记录</view>
        <view class="stepItem" v-else v-for="(n, index) in auditList" :key="index">
          <view class="time">{{ parseDateTime(n.auditTime) }}</view>
          <view class="content">
            <view class="status">
             <text v-if="n.auditResult==1" class="text-success">审核通过</text>
              <text v-else-if="n.auditResult==0" class="text-danger">审核拒绝</text>
                <text v-else class="text-primary">审核中</text>
            </view>
            <view class="deptName">{{ n.auditDeptName || '--' }}</view>
            <view v-if="n.auditMsg">备注:{{ n.auditMsg }}</view>
          </view>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script setup>
import * as api from '@/common/api.js'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

const orderInfo = ref({})
const memberList = ref([])
const auditList = ref([])
const total = ref(0)
const loading = ref(false)
const loadingAudit = ref(false)
const loadingMore = ref(false)
const hasMore = ref(false)

const queryParams = ref({
  pageNum: 1,
  pageSize: 10
})

let rangeId = ''

onLoad((option) => {
  if (!option.rangeId) {
    uni.showToast({ title: '参数错误', icon: 'none' })
    setTimeout(() => uni.navigateBack(), 1500)
    return
  }
  rangeId = option.rangeId
  initData()
})

function initData() {
  uni.showLoading({ title: '加载中' })
  getMemberList()
  getAuditList()
}

function getMemberList() {
  loading.value = true
  queryParams.value.rangeId = rangeId
  api.listAPI(queryParams.value).then(res => {
    uni.hideLoading()
    if (res && res.rows) {
      if (queryParams.value.pageNum === 1) {
        memberList.value = res.rows
      } else {
        memberList.value.push(...res.rows)
      }
      total.value = res.total || memberList.value.length
      hasMore.value = memberList.value.length < (res.total || 0)
    } else {
      memberList.value = []
      total.value = 0
      hasMore.value = false
    }
  }).catch(err => {
    uni.hideLoading()
    console.error('getMemberList error:', err)
    memberList.value = []
  }).finally(() => {
    loading.value = false
  })
}

function getAuditList() {
  loadingAudit.value = true
  api.newGetLogs(rangeId).then(res => {
    if (res && res.data) {
      auditList.value = Array.isArray(res.data) ? res.data : (res.data.levelSteps || [])
    } else {
      auditList.value = []
    }
  }).catch(err => {
    console.error('getAuditList error:', err)
    auditList.value = []
  }).finally(() => {
    loadingAudit.value = false
  })
}

function loadMore() {
  if (hasMore.value && !loadingMore.value) {
    loadingMore.value = true
    queryParams.value.pageNum++
    getMemberList()
    loadingMore.value = false
  }
}

function getAuditResultText(result) {
  const map = { 0: '审核拒绝', 1: '审核通过' }
  return map[result] || '审核中'
}

function getIdcTypeText(type) {
  const map = { 1: '身份证', 2: '护照', 3: '其他' }
  return map[type] || '其他'
}

function parseDate(dateStr) {
  if (!dateStr) return '——'
  if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
    return dateStr.slice(0, 10)
  }
  return dateStr
}

function parseDateTime(dateStr) {
  if (!dateStr) return '——'
  if (typeof dateStr === 'string' && dateStr.indexOf('T') > -1) {
    const [date, time] = dateStr.split('T')
    return `${date} ${time?.slice(0, 5) || ''}`
  }
  return dateStr
}
</script>

<style scoped lang="scss">
$primary-color: #e8341d;
$success-color: #52c41a;
$danger-color: #e8341c;
$bg-color: #f5f7fa;
$card-bg: #ffffff;
$text-primary: #333;
$text-secondary: #666;
$text-placeholder: #999;
$border-color: #eee;
$content-gap: 24rpx;

.detail-content {
  padding: 20rpx;
  background: $bg-color;
  min-height: 100vh;
  box-sizing: border-box;
}

.h3-padding {
  padding: 30rpx 30rpx 0;
  font-size: 30rpx;
  font-weight: 600;
  color: #333;
}

.wBox {
  width: 700rpx;
  padding: 30rpx;
  margin: 20rpx auto 0;
  background: #FFFFFF;
  box-shadow: 0rpx 12rpx 116rpx 0rpx rgba(196, 203, 214, 0.1);
  border-radius: 15rpx;
}

.stepItem {
  // display: flex;
  padding: 16rpx;
  border-bottom: 1rpx dashed #eee;

  &:last-child {
    border-bottom: none;
  }

  .time {
    width: 80%;
    font-size: 22rpx;
    color: #999;
    flex-shrink: 0;
    padding-top: 4rpx;
  }

  .content {
    flex: 1;

    .status {
      font-size: 28rpx;
      font-weight: 600;
      margin-bottom: 6rpx;
    }

    .deptName {
      font-size: 26rpx;
      color: #666;
    }

    view {
      font-size: 24rpx;
      color: #999;
      margin-top: 4rpx;
    }
  }
}

.card {
  background: $card-bg;
  border-radius: 16rpx;
  margin-bottom: 20rpx;
  overflow: hidden;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24rpx $content-gap 20rpx;
  border-bottom: 1rpx solid $border-color;

  .header-left {
    font-size: 30rpx;
    font-weight: 600;
    color: $text-primary;
  }

  .header-right {
    font-size: 26rpx;
    color: $primary-color;
    font-weight: 500;
  }
}

.state-tip {
  text-align: center;
  padding: 60rpx 0;
  font-size: 26rpx;
  color: $text-placeholder;
}

.student-list {
  padding: 0 $content-gap 24rpx;
}

.student-card {
  border-radius: 12rpx;
  padding: 24rpx;
  margin-top: 16rpx;
  border: 1rpx solid $border-color;

  .student-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20rpx;

    .student-name {
      .name {
        font-size: 32rpx;
        font-weight: 600;
        color: $text-primary;
      }

      .unit {
        font-size: 24rpx;
        color: $text-placeholder;
        margin-left: 16rpx;
      }
    }

    .new-tag {
      font-size: 22rpx;
      padding: 6rpx 16rpx;
      border-radius: 20rpx;
      background: rgba($text-placeholder, 0.1);
      color: $text-placeholder;
      flex-shrink: 0;

      &.is-new {
        background: rgba($primary-color, 0.1);
        color: $primary-color;
      }
    }
  }

  .student-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12rpx;

    .info-col {
      flex: 1;
      text-align: center;

      .info-text {
        font-size: 28rpx;
        color: $text-primary;
        font-weight: 500;
        line-height: 1.4;
      }
    }
  }
}

.load-more {
  text-align: center;
  padding: 24rpx 0;
  font-size: 26rpx;
  color: $primary-color;
}

</style>