chooseExaminer.vue 8.74 KB
<template>
	<view>
    <!-- 顶部添加考官按钮 -->
    <view class="add-btn-box">
      <button class="btn-red-kx mini" @click="openAddExaminer">
        <uni-icons type="personadd" size="14" color="#AD181F"></uni-icons>
        添加考官
      </button>
    </view>

    <view class="indexboxre">
			<view class="userlist">
				<view class="item" v-for="(n,index) in list" :key="index">
					<view>
						<view class="name">{{n.perName}}</view>
						<view class="date">会员号:{{n.perCode||'-'}}</view>
						<view class="date">有效日期:{{n.roleInfo && n.roleInfo.validTime ? n.roleInfo.validTime : '-'}}</view>
						<view class="date">注册地:{{n.memName||'-'}}</view>
            <view class="date" :class="{'text-danger': n.canChoose != 1}">
              状态:{{ n.canChoose == 1 ? '正常' : '资质已过期' }}
            </view>
					</view>
					<view class="status">
						<text v-if="isChosen(n)" class="text-gray">已选</text>
						<text v-else class="text-primary" @click="handleChoose(n)">选择</text>
					</view>
				</view>
			</view>
			<view class="nodata" v-if="list.length==0 && !loading">
				<image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image>
				<text>暂无考官数据</text>
			</view>
		</view>

    <!-- 添加考官弹窗 -->
    <uni-popup ref="addPopup" type="bottom" background-color="#fff" animation>
      <view class="popBody">
        <view class="h3 text-center">添加考官</view>
        <view class="form-item">
          <text class="label">考官姓名</text>
          <uni-easyinput v-model="addForm.name" placeholder="请输入考官姓名" />
        </view>
        <view class="form-item" v-if="addForm.type == 1">
          <text class="label">考官编号</text>
          <uni-easyinput v-model="addForm.certCode" placeholder="请输入考官编号" />
        </view>
        <view class="btn-group">
          <button class="btn-cancel" @click="addPopup.close()">取消</button>
          <button class="btn-confirm" @click="searchAndAdd">查询</button>
        </view>

        <!-- 搜索结果 -->
        <view v-if="searchResult" class="search-result">
          <view class="result-item">
            <view class="info">
              <view class="name">{{searchResult.perName}}</view>
              <view class="date">会员号:{{searchResult.perCode||'-'}}</view>
              <view class="date">证件号码:{{searchResult.idcCode||'-'}}</view>
              <view class="date">注册地:{{searchResult.memName||'-'}}</view>
            </view>
            <view class="action">
              <text v-if="searchResult.added" class="text-gray">已添加</text>
              <text v-else class="text-primary" @click="doAddExaminer(searchResult)">添加</text>
            </view>
          </view>
        </view>
        <view v-if="searchNoData" class="no-data">
          <text>未查询到考官信息</text>
        </view>
      </view>
    </uni-popup>
	</view>
</template>

<script setup>
	import * as api from '@/common/api.js'
	import config from '@/config.js'
	import {
		ref
	} from 'vue'
	import {
		onLoad
	} from '@dcloudio/uni-app'
	const app = getApp();
	const list = ref([])
	const loading = ref(false)
	let chosen = []
	let ec = null

  const addPopup = ref(null)
  const addForm = ref({
    type: 1,
    name: '',
    certCode: ''
  })
  const searchResult = ref(null)
  const searchNoData = ref(false)

	onLoad((option) => {
		chosen = JSON.parse(decodeURIComponent(option.chosen || '[]'))
		ec = option.ec
		getList()
	})

	function getList() {
		loading.value = true
		uni.showLoading({ title: '加载中' })
		api.listApi({ memId: app.globalData.memberInfo.memId }).then(res => {
			list.value = res.rows || []
			for (let l of list.value) {
				if (l.roleInfo) {
					try {
						l.roleInfo = typeof l.roleInfo === 'string' ? JSON.parse(l.roleInfo) : l.roleInfo
					} catch (e) {}
				}
				// 检查是否已选
				for (let t of chosen) {
					if (t.perId == l.perId) {
						l.disabled = true
					}
				}
			}
			uni.hideLoading()
			loading.value = false
		}).catch(() => {
			uni.hideLoading()
			loading.value = false
		})
	}

	function isChosen(n) {
		return chosen.some(c => c.perId == n.perId)
	}

	function handleChoose(row) {
		if (row.canChoose != 1) {
			uni.showToast({
				title: '该考官资质已过期!',
				icon: 'error'
			})
			return
		}

		var obj = {
			perId: row.perId,
			name: row.perName,
		}

		uni.$emit('chosen', {
			obj: obj,
			ec
		})
		uni.navigateBack({ delta: 1 })
	}

  // 打开添加考官弹窗
  function openAddExaminer() {
    addForm.value.name = ''
    addForm.value.certCode = ''
    searchResult.value = null
    searchNoData.value = false
    addPopup.value.open()
  }

  // 搜索并添加考官
  function searchAndAdd() {
    if (!addForm.value.name) {
      uni.showToast({ title: '请输入考官姓名', icon: 'none' })
      return
    }
    if (addForm.value.type == 1 && !addForm.value.certCode) {
      uni.showToast({ title: '请输入考官编号', icon: 'none' })
      return
    }

    uni.showLoading({ title: '查询中' })
    api.getCoachList(addForm.value).then(res => {
      uni.hideLoading()
      if (res.rows && res.rows.length > 0) {
        searchResult.value = res.rows[0]
        // 检查是否已添加
        const isAdded = list.value.some(l => l.perId === searchResult.value.perId)
        if (isAdded) {
          searchResult.value.added = true
        }
      } else {
        searchResult.value = null
        searchNoData.value = true
      }
    }).catch(() => {
      uni.hideLoading()
      searchResult.value = null
      searchNoData.value = true
    })
  }

  // 执行添加考官
  function doAddExaminer(row) {
    uni.showModal({
      title: '提示',
      content: `确定添加 "${row.name}" 为考官吗?`,
      success: (res) => {
        if (res.confirm) {
          uni.showLoading({ title: '添加中' })
          api.selfAdd(app.globalData.memberInfo.memId, row.perId).then(() => {
            uni.hideLoading()
            uni.showToast({ title: '添加成功', icon: 'success' })
            addPopup.value.close()
            // 刷新列表
            getList()
          }).catch(() => {
            uni.hideLoading()
            uni.showToast({ title: '添加失败', icon: 'error' })
          })
        }
      }
    })
  }
</script>

<style scoped lang="scss">
	.indexboxre {
		padding: 0 30rpx;
	}

  .add-btn-box {
    padding: 20rpx 30rpx;

    .btn-red-kx {
      width: 100%;
      display: inline-flex;
      align-items: center;
      background: #fff;
      border: 1px solid #AD181F;
      color: #AD181F;
      text-align: center;
      font-size: 26rpx;
      padding: 10rpx 20rpx;
      height: 60rpx;
      line-height: 60rpx;
      justify-content: center;
    }
  }

	.userlist {
		.item {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 30rpx;
			margin-bottom: 20rpx;
			background: #fff;
			border-radius: 10rpx;

			.name {
				font-size: 32rpx;
				font-weight: bold;
				margin-bottom: 10rpx;
			}

			.date {
				font-size: 26rpx;
				color: #666;
				margin-top: 6rpx;
			}

			.status {
				text {
					padding: 10rpx 20rpx;
					font-size: 28rpx;
				}
			}
		}
	}

	.text-primary {
		color: #007aff;
	}

	.text-gray {
		color: #999;
	}

	.text-danger {
		color: #dd524d;
	}

  .popBody {
    padding: 40rpx 30rpx;

    .h3 {
      font-size: 32rpx;
      font-weight: bold;
      margin-bottom: 30rpx;
    }

    .form-item {
      margin-bottom: 20rpx;

      .label {
        display: block;
        font-size: 28rpx;
        color: #333;
        margin-bottom: 10rpx;
      }
    }

    .btn-group {
      display: flex;
      justify-content: center;
      gap: 40rpx;
      margin-top: 30rpx;

      .btn-cancel,
      .btn-confirm {
        width: 200rpx;
        height: 70rpx;
        line-height: 70rpx;
        font-size: 28rpx;
        border-radius: 35rpx;
      }

      .btn-cancel {
        background: #fff;
        color: #AD181F;
        border: 1px solid #AD181F;
      }

      .btn-confirm {
        background: #AD181F;
        color: #fff;
      }
    }
  }

  .search-result {
    margin-top: 30rpx;
    border-top: 1px solid #eee;
    padding-top: 20rpx;

    .result-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20rpx;
      background: #f9f9f9;
      border-radius: 8rpx;

      .name {
        font-size: 30rpx;
        font-weight: bold;
        margin-bottom: 8rpx;
      }

      .date {
        font-size: 24rpx;
        color: #666;
        margin-top: 4rpx;
      }

      .action {
        text {
          padding: 10rpx 20rpx;
          font-size: 28rpx;
        }
      }
    }
  }

  .no-data {
    text-align: center;
    padding: 40rpx;
    color: #999;
    font-size: 28rpx;
  }
</style>