chooseExaminer.vue 6.67 KB
<template>
  <view class="container">
    <!-- 搜索区域:固定在顶部 -->
    <view class="search-area">
      <view class="search-item">
        <text>考官姓名:</text>
        <input v-model="queryParams.name" placeholder="请输入考官姓名" class="search-input" />
      </view>
      <view class="search-item">
        <text>考官编号:</text>
        <input v-model="queryParams.certCode" placeholder="请输入考官编号" class="search-input" />
      </view>
      <view class="search-buttons">
        <button class="search-btn" @click="handleQuery">查询</button>
        <button class="reset-btn" @click="resetQuery">重置</button>
      </view>
    </view>

    <view class="list-item" v-for="(item, index) in infoList" :key="item.perId">
      <view class="info">
        <view class="name">{{ item.name }} {{ item.perCode }}</view>
        <view class="idc">证件号码:{{ item.idcCode }}</view>
        <view class="reg">注册地:{{ item.memName }}</view>
      </view>
      <button
        class="choose-btn"
        :class="{ disabled: checkChosen(item) }"
        @click="handleChoose(item)"
        :disabled="checkChosen(item)"
      >
        {{ checkChosen(item) ? '已选择' : '选择' }}
      </button>
    </view>

    <uni-popup ref="expirePopup" type="center" background-color="rgba(0,0,0,0.5)">
      <view class="custom-modal">
        <view class="modal-title">提示</view>
        <view class="modal-content">该考官资质已过期,是否继续添加?</view>
        <view class="modal-btns">
          <button class="btn-cancel" @click="closeExpirePopup()">取消</button>
          <button class="btn-confirm" @click="confirmAddExpireExaminer()">确定</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

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

const props = defineProps({
  isValidity: {
    type: String,
    default: '0'
  }
})

const isValidity = ref('0')
const memId = ref('')
const chosen = ref([])
const expirePopup = ref(null)
const currentExpireItem = ref(null)

onLoad((option) => {
  isValidity.value = option.isValidity
  memId.value = option.memId
  chosen.value = JSON.parse(option.chosen)
})

const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    name: null,
    certCode: null,
    type: 1,
    shenMemId: ''
  }
})
const { queryParams } = toRefs(data)

const infoList = ref([])
const loading = ref(false)
const total = ref(0)

// 获取考官列表
async function getList() {
  if (!queryParams.value.name) 
    return uni.showToast({ title: '请输入考官姓名', icon: 'none' })
  if (queryParams.value.type == 1 && !queryParams.value.certCode) 
    return uni.showToast({ title: '请输入考官编号', icon: 'none' })
  
  loading.value = true
  const res = await api.getCoachList(queryParams.value)
  infoList.value = res.rows
  total.value = res.total
  loading.value = false
  
  if (infoList.value.length === 0) {
    uni.showToast({ title: '请核实考官编号、有效期及归属地!', icon: 'none' })
  }
}

// 检查是否已选择
function checkChosen(row) {
  return _.some(chosen.value, (c) => {
    return c.perId == row.perId
  })
}

// 查询
function handleQuery() {
  queryParams.value.pageNum = 1
  getList()
}

// 重置
function resetQuery() {
  queryParams.value.name = null
  queryParams.value.certCode = null
  infoList.value = []
  total.value = 0
}

async function handleChoose(row) {
  if (checkChosen(row)) {
    return uni.showToast({ title: '已选择该考官', icon: 'none' })
  }
  
  // 资质过期逻辑
  if (row.canChoose != 1) {
    // 暂存当前考官数据
    currentExpireItem.value = row
    // 打开自定义过期确认弹窗
    expirePopup.value.open()
    return
  }
}

// 关闭过期确认弹窗
function closeExpirePopup() {
  expirePopup.value.close()
}

// 确认添加过期考官
async function confirmAddExpireExaminer() {
  if (!currentExpireItem.value) return
  
  try {
    await api.otherAdd(memId.value, currentExpireItem.value.perId)
    uni.showToast({ title: '添加成功', icon: 'success' })
    uni.navigateBack({ delta: 1 })
  } catch (err) {
    uni.showToast({ title: '添加失败', icon: 'none' })
  } finally {
    expirePopup.value.close()
    currentExpireItem.value = null
  }
}
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  background: #f7f7f7;
  min-height: 100vh;
  padding: 0;
}

.search-area {
  background: #ffffff;
  border-radius: 16rpx;
  padding: 30rpx;
  margin: 30rpx;
  flex-shrink: 0;
}

.search-item {
  display: flex;
  align-items: center;
  margin-bottom: 20rpx;
}
.search-input {
  flex: 1;
  border: 1rpx solid #ddd;
  border-radius: 8rpx;
  padding: 20rpx;
  font-size: 28rpx;
}

.search-buttons {
  display: flex;
  justify-content: space-between;
  margin-top: 30rpx;
  margin-left: 80px;
}
.search-btn, .reset-btn {
  width: 220rpx;
  height: 70rpx;
  line-height: 70rpx;
  border-radius: 8rpx;
  text-align: center;
  font-size: 28rpx;
}
.search-btn {
  background: #C4121B;
  color: #fff;
}
.reset-btn {
  background: #f7f7f7;
  color: #333;
}

/* 列表区域:滚动 */
.list-area {
  flex: 1;
  background: #ffffff;
  border-radius: 16rpx;
  margin: 0 30rpx 30rpx;
  padding: 0 30rpx;
}

.list-item {
  padding: 30rpx;
  margin: 0 30rpx;
  border-bottom: 1rpx solid #eee;
  background-color: #fff;
}
.info {
  flex: 1;
}
.name {
  font-size: 30rpx;
  font-weight: bold;
  color: #333;
}
.idc, .reg {
  font-size: 26rpx;
  color: #666;
  margin: 20rpx 0;
}
.choose-btn {
  color: #C4121B;
  font-size: 26rpx;
  border: 1rpx solid #C4121B;
  border-radius: 8rpx;
  padding: 10rpx 20rpx;
  background-color: #fff;
  margin: 10rpx auto;
}
.choose-btn.disabled {
  color: #ccc;
  border-color: #ccc;
}

/* 自定义弹窗样式(和之前保持统一) */
.custom-modal {
  width: 600rpx;
  background: #fff;
  border-radius: 20rpx;
  padding: 40rpx 30rpx;
  box-sizing: border-box;
  text-align: center;
}
.modal-title {
  font-size: 36rpx;
  font-weight: 600;
  color: #333;
  margin-bottom: 30rpx;
}
.modal-content {
  font-size: 30rpx;
  color: #666;
  line-height: 1.6;
  margin-bottom: 30rpx;
}
.modal-btns {
  display: flex;
  justify-content: space-between;
  gap: 20rpx;
}
.btn-cancel {
  flex: 1;
  height: 80rpx;
  line-height: 80rpx;
  background: #f5f5f5;
  color: #999;
  border-radius: 40rpx;
  font-size: 32rpx;
  border: none;
}
.btn-confirm {
  flex: 1;
  height: 80rpx;
  line-height: 80rpx;
  background: #C4121B;
  color: #fff;
  border-radius: 40rpx;
  font-size: 32rpx;
  border: none;
}
/* 去除button默认边框 */
.btn-cancel::after, .btn-confirm::after {
  border: none;
}
</style>