55b06f5f by lttnew

考点申请

1 parent 51313627
// dev
// const baseUrl_api = 'http://192.168.1.137:8787'
// const baseUrl_api = 'http://192.168.1.125:8787'
const baseUrl_api = 'https://tk001.wxjylt.com/stage-api/'
const loginImage_api = 'http://tk001.wxjylt.com/stage-api'
const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do'
......
<template>
<view class="container">
<!-- 搜索区域:固定在顶部 -->
<view class="search-area">
<view class="search-item">
<text>考官姓名:</text>
<input v-model="queryParams.name" class="search-input" placeholder="请输入考官姓名"/>
</view>
<view class="search-item">
<text>考官编号:</text>
<input v-model="queryParams.certCode" class="search-input" placeholder="请输入考官编号"/>
</view>
<view class="search-buttons">
<button class="search-btn" @click="handleQuery">查询</button>
<button class="reset-btn" @click="resetQuery">重置</button>
</view>
</view>
<view v-for="(item, index) in infoList" :key="item.perId" class="list-item">
<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="{ disabled: checkChosen(item) }"
:disabled="checkChosen(item)"
class="choose-btn"
@click="handleChoose(item)"
>
{{ checkChosen(item) ? '已选择' : '选择' }}
</button>
</view>
<uni-popup ref="expirePopup" background-color="rgba(0,0,0,0.5)" type="center">
<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 class="loading-tip" v-if="loading">加载中...</view>
<view class="empty-tip" v-else-if="infoList.length === 0">暂无可添加的考官</view>
<checkbox-group class="examiner-list" @change="onCheckboxChange">
<label v-for="item in infoList" :key="item.perId" class="examiner-item">
<view class="item-left">
<checkbox :value="item.perId.toString()" :checked="selectedIds.includes(item.perId.toString())" :disabled="checkChosen(item)" color="#C4121B" />
</view>
<view class="item-info">
<view class="name">{{ item.perName }} </view>
<view class="idc">会员号:{{ item.perCode }}</view>
<view class="idc">证件号码:{{ item.perIdcCode }}</view>
<view class="reg">注册地:{{ item.memName }}</view>
</view>
</view>
</uni-popup>
<view v-if="checkChosen(item)" class="chosen-tag">已添加</view>
</label>
</checkbox-group>
<view class="bottom-area">
<view class="selected-tip" v-if="selectedIds.length > 0">已选择 {{ selectedIds.length }} 位考官</view>
<view> <button class="add-btn" :disabled="selectedIds.length === 0" @click="handleAdd">添加</button></view>
</view>
</view>
</template>
<script setup>
import {ref, reactive, toRefs} from 'vue'
import {onLoad} from '@dcloudio/uni-app';
import {ref} 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)
const loading = ref(true)
const infoList = ref([])
const loading = ref(false)
const total = ref(0)
const selfSelect = ref('0')
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
certCode: null,
type: 1,
shenMemId: ''
}
})
const {queryParams} = toRefs(data)
const chosen = ref([])
const selectedIds = ref([])
const memId = ref('')
onLoad((option) => {
console.log(option)
isValidity.value = option.isValidity
memId.value = option.memId
chosen.value = JSON.parse(option.chosen)
selfSelect.value = option.selfSelect ?? '1'
memId.value = option.memId || ''
chosen.value = option.chosen ? JSON.parse(option.chosen) : []
getList()
})
// 获取考官列表
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
try {
const res = await api.getCoachList(queryParams.value)
const res = await api.listApi({chooseFlag: 1})
infoList.value = res.rows || []
total.value = res.total || 0
} catch (err) {
console.error('获取考官列表失败:', err)
infoList.value = []
total.value = 0
} finally {
loading.value = false
}
// 空数组提示
if (infoList.value.length === 0) {
uni.showToast({title: '请核实考官编号、有效期及归属地', icon: 'none', duration: 2000})
}
}
// 检查是否已选择
function checkChosen(row) {
return _.some(chosen.value, (c) => {
return c.perId == row.perId
})
}
// 查询
function handleQuery() {
queryParams.value.pageNum = 1
getList()
function checkChosen(item) {
return chosen.value.some(c => c.perId == item.perId)
}
// 重置
function resetQuery() {
queryParams.value.name = null
queryParams.value.certCode = null
infoList.value = []
total.value = 0
function onCheckboxChange(e) {
selectedIds.value = e.detail.value
}
function handleChoose(row) {
if (checkChosen(row)) {
return uni.showToast({title: '已选择该考官', icon: 'none'})
}
// 暂存当前考官数据
currentExpireItem.value = row
// 资质过期逻辑
if (row.canChoose != 1) {
// 打开自定义过期确认弹窗
expirePopup.value.open()
function handleAdd() {
if (selectedIds.value.length === 0) {
uni.showToast({title: '请先选择考官', icon: 'none'})
return
}
confirmAddExpireExaminer()
}
// 关闭过期确认弹窗
function closeExpirePopup() {
expirePopup.value.close()
}
const ids = selectedIds.value.join(',')
// 确认添加过期考官
async function confirmAddExpireExaminer() {
if (!currentExpireItem.value) return
try {
if (selfSelect.value == 1) {
// 自己添
await api.selfAdd(currentExpireItem.value.perId)
} else {
// 省级添加
await api.otherAdd(memId.value, currentExpireItem.value.perId)
}
uni.showLoading({title: '添加中...'})
api.selfAdd(ids).then(() => {
uni.hideLoading()
uni.showToast({title: '添加成功', icon: 'success'})
uni.navigateBack({delta: 1})
} catch (err) {
console.log(err)
const errMsg = err?.data?.msg || err?.msg || '添加失败'
uni.showToast({title: errMsg, icon: 'none', duration: 3000})
} finally {
expirePopup.value.close()
currentExpireItem.value = null
await getList()
}
uni.navigateBack()
}).catch(err => {
uni.hideLoading()
uni.showToast({title: err?.data?.msg || '添加失败', icon: 'none'})
})
}
</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;
.container {
min-height: 100vh;
background: #f7f7f7;
padding-bottom: 140rpx;
}
.search-btn, .reset-btn {
width: 220rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 8rpx;
.loading-tip,
.empty-tip {
text-align: center;
padding: 100rpx 0;
font-size: 28rpx;
color: #666;
}
.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;
.examiner-list {
background: #fff;
}
.list-item {
.examiner-item {
display: flex;
align-items: center;
padding: 30rpx;
margin: 0 30rpx;
border-bottom: 1rpx solid #eee;
background-color: #fff;
}
.info {
.item-left {
margin-right: 20rpx;
}
.item-info {
flex: 1;
}
......@@ -262,83 +124,60 @@ async function confirmAddExpireExaminer() {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.idc, .reg {
font-size: 26rpx;
font-size: 24rpx;
color: #666;
margin: 20rpx 0;
margin-bottom: 6rpx;
}
.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;
.chosen-tag {
font-size: 24rpx;
color: #999;
background: #f5f5f5;
padding: 6rpx 16rpx;
border-radius: 4rpx;
}
/* 自定义弹窗样式(和之前保持统一) */
.custom-modal {
width: 600rpx;
.bottom-area {
position: fixed;
bottom: 0;
left: 0;
right: 0;
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 {
padding: 20rpx 30rpx;
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
border-top: 1rpx solid #eee;
display: flex;
align-items: center;
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;
.selected-tip {
font-size: 26rpx;
color: #666;
}
.btn-confirm {
flex: 1;
height: 80rpx;
line-height: 80rpx;
.add-btn {
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
background: #C4121B;
color: #fff;
border-radius: 40rpx;
font-size: 32rpx;
font-size: 28rpx;
border-radius: 35rpx;
border: none;
}
/* 去除button默认边框 */
.btn-cancel::after, .btn-confirm::after {
.add-btn[disabled] {
background: #ccc;
color: #fff;
}
.add-btn::after {
border: none;
}
</style>
......
......@@ -135,7 +135,7 @@ function onSelfSelectChange(e) {
function handelAddExamine() {
const chosenStr = JSON.stringify(list.value)
uni.navigateTo({
url: `/myCenter/chooseExaminer?memId=${memId.value}&isValidity=0&chosen=${chosenStr}`
url: `/myCenter/chooseExaminer?memId=${memId.value}&chosen=${chosenStr}`
})
}
......
......@@ -2,7 +2,7 @@
<view class="exam-point-list">
<!-- 顶部申请按钮 -->
<view class="apply-btn-box">
<button class="apply-btn" :disabled="memberInfo.isPoints==0&&memberInfo.auditStatus==2" @click="goApply">申请考点</button>
<button class="apply-btn" :disabled="memberInfo.isPoints==0&&formInfo.auditStatus==2" @click="goApply">申请考点</button>
</view>
<!-- 列表 -->
......@@ -59,6 +59,7 @@ const noMore = ref(false)
const pageNum = ref(1)
const pageSize = ref(10)
const memberInfo = app.globalData.memberInfo
const formInfo = ref({})
onLoad(() => {
loadData()
})
......@@ -68,6 +69,7 @@ function loadData() {
loading.value = true
getMyRecent().then(res => {
formInfo.value = res.data
if (res.data && res.data.auditLogs) {
try {
list.value = JSON.parse(res.data.auditLogs)
......
......@@ -126,10 +126,10 @@
<image :src="config.baseUrl_api+'/fs/static/icon/25.png'"/>
证书邮寄
</view>
<view @click="goPath('/level/ztx/costSettlement')">
<!-- <view @click="goPath('/level/ztx/costSettlement')">
<image :src="config.baseUrl_api+'/fs/static/icon/10.png'"/>
证书下载
</view>
</view> -->
<view @click="goPath('/personalVip/changeLevel')">
<image :src="config.baseUrl_api+'/fs/static/icon/26.png'"/>
级位变更
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!