examPointApplyList.vue 4.4 KB
<template>
  <view class="exam-point-list">
    <!-- 顶部申请按钮 -->
    <view class="apply-btn-box">
      <button :disabled="memberInfo.isPoints==0||formInfo.auditStatus==2||formInfo.auditStatus==1" class="apply-btn"
              @click="goApply">申请考点
      </button>
    </view>
    
    <!-- 列表 -->
    <view class="list-content">
      <view v-if="list.length === 0 && !loading" class="empty-tip">
        <text>暂无申请记录</text>
      </view>
      
      <view
        v-for="(item, index) in list"
        :key="index"
        :class="{ 'success-row': item.shenAuditStatus == 2 }"
        class="list-item"
      >
        <view class="item-row">
          <text class="item-label">审核协会</text>
          <text class="item-value">{{ item.auditDeptName || '-' }}</text>
        </view>
        <view class="item-row">
          <text class="item-label">审核日期</text>
          <text class="item-value">{{ formatDate(item.auditTime) }}</text>
        </view>
        <view class="item-row">
          <text class="item-label">审核状态</text>
          <text :class="getStatusClass(item.auditResult)" class="item-status">
            {{ item.auditResult == 1 ? '审核通过' : item.auditResult == 0 ? '审核拒绝' : '待审核' }}
          </text>
        </view>
        <view class="item-row">
          <text class="item-label">理由</text>
          <text class="item-value">{{ item.auditMsg ? item.auditMsg : '/' }}</text>
        </view>
      </view>
      
      <view v-if="loading" class="loading-tip">
        <text>加载中...</text>
      </view>
      
      <view v-if="noMore && list.length > 0" class="no-more-tip">
        <text>没有更多了</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import {ref} from 'vue'
import {onLoad, onShow, onReachBottom} from '@dcloudio/uni-app'
import {getMyRecentExam} from '@/common/api'

const app = getApp()
const list = ref([])
const loading = ref(false)
const noMore = ref(false)
const pageNum = ref(1)
const pageSize = ref(10)
const memberInfo = app.globalData.memberInfo
const formInfo = ref({})

onShow(() => {
  loadData()
})

onLoad(() => {
  loadData()
})

function loadData() {
  if (loading.value) return
  loading.value = true
  
  getMyRecentExam().then(res => {
    formInfo.value = res.data ?? {}
    if (res.data && res.data.auditLogs) {
      try {
        list.value = JSON.parse(res.data.auditLogs)
      } catch (e) {
        list.value = []
      }
    } else {
      list.value = []
    }
  }).finally(() => {
    loading.value = false
  })
}

onReachBottom(() => {
  if (!noMore.value) {
    pageNum.value++
    loadData()
  }
})

function goApply() {
  uni.navigateTo({
    url: '/pages/index/notice-examPointApply'
  })
}


function getStatusClass(status) {
  return {
    'status-2': status == 1,
    'status-1': status == 0,
  }
}

function formatDate(dateStr) {
  if (!dateStr) return '-'
  const date = new Date(dateStr)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}
</script>

<style lang="scss" scoped>
.exam-point-list {
  min-height: 100vh;
  background: #f5f5f5;
}

.apply-btn-box {
  padding: 20rpx 30rpx;
}

.apply-btn {
  width: 100%;
  height: 80rpx;
  line-height: 80rpx;
  background: #C4121B;
  color: #fff;
  font-size: 28rpx;
  border-radius: 44rpx;
  border: none;
  
  &::after {
    border: none;
  }
  
  &[disabled] {
    background: #f3d4d5 !important;
    color: #b7b5b5 !important;
    border: 2rpx solid #e0e0e0 !important;
    opacity: 1;
  }
}

.list-content {
  padding: 0 20rpx 20rpx;
}

.empty-tip,
.loading-tip,
.no-more-tip {
  text-align: center;
  padding: 60rpx 0;
  color: #999;
  font-size: 26rpx;
}

.list-item {
  background: #fff;
  border-radius: 16rpx;
  padding: 24rpx;
  margin-bottom: 20rpx;
}

.list-item.success-row {
  border-left: 6rpx solid #19be6b;
}

.item-row {
  display: flex;
  margin-bottom: 16rpx;
  
  &:last-child {
    margin-bottom: 0;
  }
}

.item-label {
  width: 140rpx;
  font-size: 26rpx;
  color: #999;
}

.item-value {
  flex: 1;
  font-size: 26rpx;
  color: #333;
}

.item-status {
  font-size: 26rpx;
  padding: 4rpx 16rpx;
  border-radius: 20rpx;
}

.status-1 {
  background: #fff7e6;
  color: #fa8c16;
}

.status-2 {
  background: #e6fff7;
  color: #52c41a;
}

.status-3 {
  background: #fff1f0;
  color: #ff4d4f;
}
</style>