3a51a1cd by 张猛

团体支付考点

1 parent dbdf4c4c
......@@ -50,6 +50,7 @@ export function submitCert(data) {
params: data
})
}
/**
* 段位考试成绩列表
* @param params
......@@ -165,6 +166,19 @@ export function ztxAudit(params) {
}
/**
* 考点审核
* @param params
* @returns {*}
*/
export function shenAuditExamPointApply(params) {
return request({
url: `/member/examPointApply/shenAudit/${params.ids}`,
method: 'post',
params
})
}
/**
* 获取机构资料
* @param memId
* @returns {*}
......
......@@ -10,6 +10,7 @@ function pcLogin(data) {
params: data
}).then((res) => {
uni.setStorageSync('token', 'Bearer ' + res.data.token)
pcLoginOpenId()
}).then(getInfo)
}
......@@ -150,6 +151,7 @@ function groupMemberRegister(data) {
params: data
})
}
// 获取道馆信息
function getMyOwnMemberInfo() {
return request({
......@@ -163,6 +165,23 @@ function getMyOwnMemberInfo() {
})
}
function pcLoginOpenId() {
uni.login({
provider: 'weixin',
success: (res) => {
if (res.code) {
pcBindOpenId(res.code)
}
},
fail: (res) => {
uni.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
}
})
}
function wxLogin() {
const openId = uni.getStorageSync('openId')
......@@ -209,6 +228,15 @@ function pcLoginByOpenId(openId) {
})
}
function pcBindOpenId(code) {
return request({
url: `/bindOpenId?jsCode=${code}`,
method: "POST",
}).then((res) => {
uni.setStorageSync('openId', res.data.openId);
})
}
export {
pcLogin,
getCodeImg,
......
......@@ -66,6 +66,7 @@ async function minShengPay(orderId, encryptedData) {
}))
if (decryptErr || !decryptResult?.data) {
handlePaymentError(new Error(ERROR_MESSAGES.DECRYPT_FAILED), orderId)
}
......@@ -85,14 +86,14 @@ async function minShengPay(orderId, encryptedData) {
uni.hideLoading()
// 8. 调起微信支付
const [payErr, paySuccess] = await to(invokeWechatPayment(payParams, orderId))
const [payErr] = await to(invokeWechatPayment(payParams, orderId))
if (payErr) {
handlePaymentError(payErr, orderId)
}
if (paySuccess) {
return paySuccess
}
// if (paySuccess) {
// return paySuccess
// }
}
/**
......@@ -194,7 +195,6 @@ function parsePayInfo(payInfoStr) {
* @returns {Promise<Object>} 支付结果
*/
function invokeWechatPayment(payParams, orderId) {
debugger
return new Promise((resolve, reject) => {
// 参数校验
const requiredFields = ['appId', 'nonceStr', 'prepayId', 'timeStamp', 'signType', 'paySign']
......
......@@ -30,7 +30,7 @@ function getHeaders() {
return header
}
const request = function(req) {
const request = function (req) {
req.method = req.method.toUpperCase()
if (!['GET', 'POST', 'PUT', 'DELETE'].includes(req.method)) {
uni.showToast({
......
// dev
// const baseUrl_api = 'http://192.168.1.137:8787'
const baseUrl_api = 'http://tk001.wxjylt.com/stage-api'
const baseUrl_api = 'http://192.168.1.137:8787'
// const baseUrl_api = 'http://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'
// prod
......@@ -9,5 +10,7 @@ const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do'
export default {
baseUrl_api,
payUrl
payUrl,
loginImage_api
}
......
......@@ -2,15 +2,15 @@
<view class="audit-page">
<!-- 提示信息 -->
<view class="tips-box">
<uni-icons type="info" size="18" color="#13B5B1"></uni-icons>
<text class="tips-text" v-if="type === 'batch'">批量审核 {{ ids.split(',').length }} 条记录</text>
<text class="tips-text" v-else>单个审核</text>
<uni-icons color="#13B5B1" size="18" type="info"></uni-icons>
<text v-if="type === 'batch'" class="tips-text">批量审核 {{ ids.split(',').length }} 条记录</text>
<text v-else class="tips-text">单个审核</text>
</view>
<!-- 审核表单 -->
<view class="form-section">
<view class="section-header">
<uni-icons type="edit" size="18" color="#AD181F"></uni-icons>
<uni-icons color="#AD181F" size="18" type="edit"></uni-icons>
<text class="section-title">审核信息</text>
</view>
......@@ -19,22 +19,22 @@
<text class="form-label">审批结果</text>
<view class="radio-group">
<view
class="radio-item"
:class="{ selected: form.flag === '1' }"
class="radio-item"
@click="form.flag = '1'"
>
<view class="radio-circle">
<uni-icons v-if="form.flag === '1'" type="checkmark" size="10" color="#fff"></uni-icons>
<uni-icons v-if="form.flag === '1'" color="#fff" size="10" type="checkmark"></uni-icons>
</view>
<text>审批通过</text>
</view>
<view
class="radio-item"
:class="{ selected: form.flag === '0' }"
class="radio-item"
@click="form.flag = '0'"
>
<view class="radio-circle">
<uni-icons v-if="form.flag === '0'" type="checkmark" size="10" color="#fff"></uni-icons>
<uni-icons v-if="form.flag === '0'" color="#fff" size="10" type="checkmark"></uni-icons>
</view>
<text>审批拒绝</text>
</view>
......@@ -45,18 +45,37 @@
<text class="form-label">备注</text>
<textarea
v-model="form.reason"
:maxlength="500"
class="textarea"
placeholder="请输入备注信息(拒绝时必填)"
:maxlength="500"
/>
</view>
</view>
</view>
<view v-if="userType==2&&selfSelect==0" class="section">
<view class="section examiner-section">
<button class="add-btn" @click="handelAddExamine">+ 添加考官</button>
</view>
<view class="examiner-list">
<view v-for="(item, index) in list" :key="item.id" class="examiner-item">
<view class="info">
<text class="name">{{ item.perName }} {{ item.perCode }}</text>
<text class="idc">证件号码:{{ item.perIdcCode }}</text>
<text class="reg">注册地:{{ item.memName }}</text>
</view>
<button class="del-btn" @click="handleDel(item)">删除</button>
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-wrap">
<button class="btn-cancel" @click="goBack">取消</button>
<button class="btn-submit" @click="doSubmit" :disabled="submitting">
<button :disabled="submitting" class="btn-submit" @click="doSubmit">
<text v-if="!submitting">确认提交</text>
<text v-else>提交中...</text>
</button>
......@@ -66,32 +85,63 @@
<script setup>
import * as api from '@/common/api_exam.js'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import {ref} from 'vue'
import {onLoad} from '@dcloudio/uni-app'
import {listApi} from "@/common/api.js";
const type = ref('single') // single 或 batch
const ids = ref('')
const submitting = ref(false)
const selfSelect = ref('1')
const userType = ref('')
const list = ref([])
const memId = ref('')
const app = getApp();
const form = ref({
flag: '1',
reason: ''
reason: '',
selfSelect: "1"
})
onLoad((options) => {
console.log(options)
if (options.type) {
type.value = options.type
}
if (options.ids) {
ids.value = options.ids
}
if (options.selfSelect) {
selfSelect.value = options.selfSelect
}
if (options.memId) {
memId.value = options.memId
getExaminer()
}
userType.value = app.globalData.userType
console.log(userType.value)
})
function goBack() {
uni.navigateBack()
}
function handelAddExamine() {
const chosenStr = JSON.stringify(list.value)
uni.navigateTo({
url: `/myCenter/chooseExaminer?memId=${memId.value}&isValidity=0&chosen=${chosenStr}&selfSelect=0`
})
}
async function getExaminer() {
const res = await listApi({memId: memId.value})
list.value = res.rows
}
function doSubmit() {
if (form.value.flag === '0' && !form.value.reason) {
uni.showToast({
......@@ -107,9 +157,10 @@ function doSubmit() {
const params = {
ids: ids.value,
flag: form.value.flag,
reason: form.value.reason || ''
reason: form.value.reason || '',
selfSelect: selfSelect.value
}
if (userType.value == '1') {
api.ztxAudit(params).then(res => {
uni.showToast({
title: '操作成功',
......@@ -126,6 +177,24 @@ function doSubmit() {
})
submitting.value = false
})
} else {
api.shenAuditExamPointApply(params).then(res => {
uni.showToast({
title: '操作成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
}).catch(err => {
console.error('审核失败', err)
uni.showToast({
title: '操作失败',
icon: 'none'
})
submitting.value = false
})
}
}
</script>
......@@ -269,4 +338,161 @@ function doSubmit() {
}
}
}
.section {
padding: 15rpx 20rpx;
}
/* 考官区域 */
.examiner-section {
background: #fff;
padding: 15rpx;
margin-bottom: 20rpx;
border: none;
border-radius: 0;
}
.add-btn {
background: #fff;
color: #C4121B;
border: 1rpx solid #C4121B;
border-radius: 10rpx;
padding: 10rpx 0;
width: 100%;
font-size: 14px;
}
.examiner-list {
padding: 0 10rpx;
background-color: #fff;
margin-bottom: 20rpx;
overflow-y: auto;
margin-bottom: 70px;
}
examiner-item {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 20rpx;
border-bottom: 1rpx solid #eee;
align-items: center;
}
.info {
flex: 1;
}
.name {
font-size: 14px;
font-weight: 500;
color: #333;
display: block;
margin-bottom: 5rpx;
}
.idc, .reg {
font-size: 12px;
color: #666;
display: block;
margin: 10rpx 0;
}
.del-btn {
color: #C4121B;
font-size: 12px;
border: 1rpx solid #C4121B;
border-radius: 50rpx;
padding: 10rpx 25rpx;
line-height: 1.2;
background: #fff;
}
/* 提交按钮 */
.submit-area {
padding: 20rpx 0;
background-color: #fff;
width: 100%;
position: fixed;
bottom: 0;
}
.submit-btn {
width: 80%;
height: 88rpx;
border-radius: 44rpx;
margin: 0 auto;
line-height: 88rpx;
background: #C4121B;
color: #fff;
text-align: center;
font-size: 16px;
border: none;
}
/* 自定义弹窗样式(核心) */
.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-tip {
font-size: 28rpx;
color: #FF7A00;
margin-top: 20rpx;
}
.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;
}
.single-btn {
flex: 1;
}
.btn-cancel::after, .btn-confirm::after {
border: none;
}
</style>
......
......@@ -3,7 +3,7 @@
<!-- 基本信息 -->
<view class="section">
<view class="section-header">
<uni-icons type="paperclip" size="18" color="#AD181F"></uni-icons>
<uni-icons color="#AD181F" size="18" type="paperclip"></uni-icons>
<text class="section-title">基本信息</text>
</view>
<view class="info-card">
......@@ -17,7 +17,7 @@
</view>
<view class="info-row">
<text class="label">审核状态</text>
<text class="value" :class="getStatusClass(form.auditStatus)">
<text :class="getStatusClass(form.auditStatus)" class="value">
{{ getStatusText(form.auditStatus) }}
</text>
</view>
......@@ -45,14 +45,14 @@
</view>
<!-- 审核记录 -->
<view class="section" v-if="auditList.length > 0">
<view v-if="auditList.length > 0" class="section">
<view class="section-header">
<uni-icons type="checkmark-circle" size="18" color="#AD181F"></uni-icons>
<uni-icons color="#AD181F" size="18" type="checkmark-circle"></uni-icons>
<text class="section-title">审核记录</text>
</view>
<view class="audit-list">
<view class="audit-item" v-for="(item, index) in auditList" :key="index">
<view class="audit-dot" :class="item.auditResult == 2 ? 'pass' : 'fail'"></view>
<view v-for="(item, index) in auditList" :key="index" class="audit-item">
<view :class="item.auditResult == 2 ? 'pass' : 'fail'" class="audit-dot"></view>
<view class="audit-content">
<view class="audit-row">
<text class="audit-label">审核协会</text>
......@@ -64,11 +64,11 @@
</view>
<view class="audit-row">
<text class="audit-label">审核状态</text>
<text class="audit-value" :class="item.auditResult == 2 ? 'text-success' : 'text-danger'">
<text :class="item.auditResult == 2 ? 'text-success' : 'text-danger'" class="audit-value">
{{ item.auditResult == 2 ? '通过' : '拒绝' }}
</text>
</view>
<view class="audit-row" v-if="item.auditMsg">
<view v-if="item.auditMsg" class="audit-row">
<text class="audit-label">备注</text>
<text class="audit-value">{{ item.auditMsg }}</text>
</view>
......@@ -77,43 +77,43 @@
</view>
</view>
<!-- 考官信息 -->
<view class="section" v-if="examinerList.length > 0">
<view class="section-header">
<uni-icons type="person" size="18" color="#AD181F"></uni-icons>
<text class="section-title">考官信息</text>
</view>
<view class="examiner-table" v-if="examinerList.length > 0">
<view class="table-header">
<view class="th th-name">姓名</view>
<view class="th th-code">会员号</view>
<view class="th th-idcard">证件号码</view>
</view>
<view class="table-body">
<view class="table-row" v-for="(item, index) in examinerList" :key="index">
<view class="td td-name">{{ item.perName }}</view>
<view class="td td-code">{{ item.perCode || '-' }}</view>
<view class="td td-idcard">{{ item.perIdcCode || '-' }}</view>
</view>
</view>
</view>
<view class="no-data" v-else>
<text>暂无考官信息</text>
</view>
</view>
<!-- &lt;!&ndash; 考官信息 &ndash;&gt;-->
<!-- <view class="section" v-if="examinerList.length > 0">-->
<!-- <view class="section-header">-->
<!-- <uni-icons type="person" size="18" color="#AD181F"></uni-icons>-->
<!-- <text class="section-title">考官信息</text>-->
<!-- </view>-->
<!-- <view class="examiner-table" v-if="examinerList.length > 0">-->
<!-- <view class="table-header">-->
<!-- <view class="th th-name">姓名</view>-->
<!-- <view class="th th-code">会员号</view>-->
<!-- <view class="th th-idcard">证件号码</view>-->
<!-- </view>-->
<!-- <view class="table-body">-->
<!-- <view class="table-row" v-for="(item, index) in examinerList" :key="index">-->
<!-- <view class="td td-name">{{ item.perName }}</view>-->
<!-- <view class="td td-code">{{ item.perCode || '-' }}</view>-->
<!-- <view class="td td-idcard">{{ item.perIdcCode || '-' }}</view>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- <view class="no-data" v-else>-->
<!-- <text>暂无考官信息</text>-->
<!-- </view>-->
<!-- </view>-->
</view>
</template>
<script setup>
import * as api from '@/common/api_exam.js'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import {ref} from 'vue'
import {onLoad} from '@dcloudio/uni-app'
const form = ref({})
const auditList = ref([])
const examinerList = ref([])
const auditStatusMap = { 1: '审核中', 2: '审核通过', 3: '审核拒绝' }
const auditStatusMap = {1: '审核中', 2: '审核通过', 3: '审核拒绝'}
onLoad((options) => {
if (options.item) {
......@@ -133,7 +133,7 @@ onLoad((options) => {
})
function getExaminerList(memId) {
api.listInfo({ memId: memId }).then(res => {
api.listInfo({memId: memId}).then(res => {
if (res.rows) {
examinerList.value = res.rows
}
......@@ -319,9 +319,17 @@ function formatDateTime(dateStr) {
}
}
.th-name { width: 25%; }
.th-code { width: 30%; }
.th-idcard { width: 45%; }
.th-name {
width: 25%;
}
.th-code {
width: 30%;
}
.th-idcard {
width: 45%;
}
.table-body {
.table-row {
......@@ -343,9 +351,17 @@ function formatDateTime(dateStr) {
}
}
.td-name { width: 25%; }
.td-code { width: 30%; }
.td-idcard { width: 45%; }
.td-name {
width: 25%;
}
.td-code {
width: 30%;
}
.td-idcard {
width: 45%;
}
}
}
......
......@@ -38,10 +38,10 @@
<!-- 顶部Tab栏(截图风格) -->
<view class="tab-bar">
<view
class="tab-item"
v-for="(tab, index) in tabList"
:key="index"
:class="{ active: currentTab === index }"
class="tab-item"
@click="switchTab(index)"
>
{{ tab.name }}
......@@ -49,26 +49,26 @@
</view>
<!-- 批量审核按钮(保留原逻辑,仅优化样式) -->
<view class="batch-btn-wrap" v-if="selectedList.length > 0 && currentTab === 0">
<button class="btn-batch" :disabled="selectedList.length === 0" @click="goBatchAudit">
<uni-icons type="checkmark-circle" size="16" color="#fff"></uni-icons>
<view v-if="selectedList.length > 0 && currentTab === 0" class="batch-btn-wrap">
<button :disabled="selectedList.length === 0" class="btn-batch" @click="goBatchAudit">
<uni-icons color="#fff" size="16" type="checkmark-circle"></uni-icons>
批量审核 ({{ selectedList.length }})
</button>
</view>
<!-- 列表区域(保留原字段+截图样式+所有按钮) -->
<scroll-view
:lower-threshold="100"
class="scroll-list"
scroll-y
@scrolltolower="loadMore"
:lower-threshold="100"
>
<view class="appList">
<view
class="appItem"
v-for="(item, index) in infoList"
:key="index"
:class="{ 'item-checked': isSelected(item) }"
class="appItem"
>
<!-- 选择框(保留原逻辑+适配截图样式) -->
<!-- <view class="checkbox-wrap" v-if="item.auditStatus == 1" @click="toggleSelect(item)">
......@@ -78,12 +78,12 @@
</view> -->
<!-- 主内容区(点击跳详情,保留原所有字段) -->
<view @click="goDetail(item)" class="item-content">
<view class="item-content" @click="goDetail(item)">
<!-- 状态标签+提交时间(截图风格顶部) -->
<view class="item-top">
<text class="submit-time">{{ formatDate(item.commitTime) }} 提交</text>
<text class="status-tag" :class="getStatusClass(item.auditStatus)">
<text :class="getStatusClass(item.auditStatus)" class="status-tag">
{{ getStatusText(item.auditStatus) }}
</text>
</view>
......@@ -127,21 +127,22 @@
v-if="item.auditStatus == 1"
class="btn-info"
@click.stop="goAudit(item)"
>审核</button>
>审核
</button>
<button class="btn-info" @click.stop="goInstitution(item)">机构资料</button>
</view>
</view>
</view>
<!-- 加载更多(保留原逻辑) -->
<view class="loading-more" v-if="infoList.length > 0">
<uni-load-more :status="loadMoreStatus" :contentText="loadMoreText"></uni-load-more>
<view v-if="infoList.length > 0" class="loading-more">
<uni-load-more :contentText="loadMoreText" :status="loadMoreStatus"></uni-load-more>
</view>
</scroll-view>
<!-- 空数据(保留原逻辑+适配截图样式) -->
<view class="nodata" v-if="infoList.length == 0 && !loading">
<image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image>
<view v-if="infoList.length == 0 && !loading" class="nodata">
<image :src="config.baseUrl_api + '/fs/static/nodata.png'" mode="aspectFit"></image>
<text>暂无数据</text>
</view>
</view>
......@@ -151,8 +152,8 @@
// 完全保留你原代码的所有JS逻辑、方法、字段,未做任何修改
import * as api from '@/common/api_exam.js'
import config from '@/config.js'
import { ref } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import {ref} from 'vue'
import {onLoad, onShow} from '@dcloudio/uni-app'
const app = getApp()
const loading = ref(false)
......@@ -179,12 +180,14 @@ const selectedList = ref([])
// 新增Tab配置(匹配截图,关联原审核状态)
const tabList = ref([
{ name: '全部', auditStatus: '' },
{ name: '审核中', auditStatus: '1' },
{ name: '审核通过', auditStatus: '2' },
{ name: '审核拒绝', auditStatus: '3' }
{name: '全部', auditStatus: ''},
{name: '审核中', auditStatus: '1'},
{name: '审核通过', auditStatus: '2'},
{name: '审核拒绝', auditStatus: '3'}
])
const currentTab = ref(0)
const userType = ref('')
onLoad(() => {
init()
......@@ -198,6 +201,9 @@ onShow(() => {
// init()
}
}
userType.value = app.globalData.userType
init()
})
function init() {
......@@ -208,12 +214,20 @@ function init() {
function switchTab(index) {
if (currentTab.value === index) return
currentTab.value = index
// 同步原审核状态查询参数
queryParams.value.auditStatus = Number(tabList.value[index].auditStatus)
// 重置列表和选择状态
queryParams.value.pageNum = 1
loadMoreStatus.value = 'more'
selectedList.value = []
if (userType.value == 1) {
// 同步原审核状态查询参数
queryParams.value.auditStatus = Number(tabList.value[index].auditStatus)
}
if (userType.value == 2) {
// 同步原审核状态查询参数
queryParams.value.shenAuditStatus = tabList.value[index].auditStatus
}
getList()
}
......@@ -229,9 +243,9 @@ function getList(isLoadMore = false) {
loadMoreStatus.value = 'loading'
}
uni.showLoading({ title: '加载中' })
uni.showLoading({title: '加载中'})
const params = { ...queryParams.value }
const params = {...queryParams.value}
if (commitTimeStart.value) {
params.commitTimeStart = commitTimeStart.value + ' 00:00:00'
}
......@@ -327,15 +341,17 @@ function goDetail(item) {
}
function goAudit(item) {
const itemStr = encodeURIComponent(JSON.stringify(item))
// const itemStr = encodeURIComponent(JSON.stringify(item))
uni.navigateTo({
url: `/level/ztx/examinationAudit?item=${itemStr}&type=single`
url: `/level/ztx/examinationAudit?ids=${item.id}&type=single&selfSelect=${item.selfSelect}&memId=${item.memId}`
})
}
function goBatchAudit() {
if (selectedList.value.length === 0) return
const ids = selectedList.value.map(s => s.id).join(',')
const arr = selectedList.value.filter(s => s.selfSelect == 1)
const ids = arr.map(s => s.id).join(',')
uni.navigateTo({
url: `/level/ztx/examinationAudit?ids=${ids}&type=batch`
})
......@@ -348,7 +364,7 @@ function goInstitution(item) {
}
function getStatusText(status) {
const statusMap = { 1: '审核中', 2: '审核通过', 3: '审核拒绝' }
const statusMap = {1: '审核中', 2: '审核通过', 3: '审核拒绝'}
return statusMap[status] || '-'
}
......@@ -656,14 +672,16 @@ function formatDate(dateStr) {
padding: 30rpx;
margin: 20rpx;
border-radius: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}
.search-form {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 24rpx;
}
.form-item {
width: 48%;
display: flex;
......@@ -678,6 +696,7 @@ function formatDate(dateStr) {
font-size: 26rpx;
color: #666;
}
input {
width: 100%;
height: 70rpx;
......@@ -688,6 +707,7 @@ function formatDate(dateStr) {
background-color: #fafafa;
box-sizing: border-box;
}
.picker-value {
width: 100%;
height: 70rpx;
......@@ -702,6 +722,7 @@ function formatDate(dateStr) {
line-height: 70rpx;
box-sizing: border-box;
}
.date-range {
display: flex;
align-items: center;
......@@ -711,11 +732,13 @@ function formatDate(dateStr) {
.picker-value {
flex: 1;
}
.date-separator {
color: #999;
}
}
}
.search-btns {
display: flex;
justify-content: center;
......@@ -730,10 +753,12 @@ function formatDate(dateStr) {
border-radius: 35rpx;
border: none;
}
.btn-search {
background: linear-gradient(135deg, #13B5B1, #15c5c1);
color: #fff;
}
.btn-reset {
background-color: #f5f5f5;
color: #666;
......
<template>
<view class="role-entry-page">
<!-- 全屏背景图 -->
<image class="page-bg" :src="config.baseUrl_api + '/fs/static/bg.png'" mode="aspectFill"></image>
<image :src="config.loginImage_api + '/fs/static/bg.png'" class="page-bg" mode="aspectFill"></image>
<!-- 顶部 Logo 区域 -->
<view class="header-wrapper">
<view class="logo-box">
<image class="logo" :src="config.baseUrl_api + '/fs/static/wx_logo.png'" mode="aspectFit"></image>
<image :src="config.loginImage_api + '/fs/static/wx_logo.png'" class="logo" mode="aspectFit"></image>
</view>
</view>
<!-- 功能按钮区域 -->
<view class="btn-container">
<view @click="goToPage('/personal/addVip_per')">
<image :src="config.baseUrl_api + '/fs/static/btn01.png'" class="btn-item"></image>
<image :src="config.loginImage_api + '/fs/static/btn01.png'" class="btn-item"></image>
</view>
<view @click="goToPage('/personal/home')">
<image :src="config.baseUrl_api + '/fs/static/btn02.png'" class="btn-item"></image>
<image :src="config.loginImage_api + '/fs/static/btn02.png'" class="btn-item"></image>
</view>
<view @click="goToPage('/login/loginC')">
<image :src="config.baseUrl_api + '/fs/static/btn03.png'" class="btn-item"></image>
<image :src="config.loginImage_api + '/fs/static/btn03.png'" class="btn-item"></image>
</view>
</view>
......@@ -29,9 +27,10 @@
</view>
</template>
<script setup>
import { ref } from 'vue'
import {ref} from 'vue'
import {onShow} from '@dcloudio/uni-app'
import config from '@/config.js'
onShow(() => {
uni.hideLoading();
})
......@@ -71,6 +70,7 @@ const goToPage = (url) => {
display: flex;
justify-content: space-between;
padding: 0 40rpx;
img, image {
width: 90px;
}
......
This diff could not be displayed because it is too large.
......@@ -23,15 +23,23 @@
style="margin: 0 20rpx 0 0;" @click="payTheFees">激活
</button>
<view v-else>
<button :disabled="auditStatus==1||auditStatus==2||form.isPoints==0" class="btn-red" size="mini"
<button v-if="form.deptType==6"
:disabled="auditStatus==1||auditStatus==2||form.isPoints==0" class="btn-red"
size="mini"
style="margin: 0 20rpx 0 0;"
@click="showApplyDialog">考点申请
</button>
<button v-if="form.deptType==6"
class="btn-red-kx"
size="mini"
style="margin: 0 20rpx 0 0;"
@click="auditEditFN(2)">考点详情
</button>
<button :disabled="btn" class="btn-red" size="mini" style="margin: 0 20rpx 0 0;"
@click="payTheFees">去缴费
</button>
<button v-if="form.deptType!=1" class="btn-red-kx" size="mini" style="margin: 0 20rpx 0 0;"
@click="auditEditFN">审核详情
@click="auditEditFN(1)">审核详情
</button>
</view>
</view>
......@@ -167,12 +175,15 @@ const applyPopup = ref(null)
const popupShow = ref(false)
// 考点审核状态 0 未提交 1 审核中 2 审核成功 3 审核失败
const auditStatus = ref(0)
const openId = uni.getStorageSync('openId')
onShow(() => {
console.log(openId)
init()
if (form.value.deptType != 1) { // 修复:原代码deptType未定义,改为form.value.deptType
getMyStatusAPI()
}
console.log()
})
// 页面卸载时恢复滚动(防止异常锁死)
......@@ -339,9 +350,9 @@ function goToApplyPage() {
})
}
function auditEditFN() {
function auditEditFN(type) {
uni.navigateTo({
url: `/myCenter/reviewList`
url: `/myCenter/reviewList?type=${type}`
})
}
......@@ -599,4 +610,9 @@ function payTheFees() {
:deep(.uni-popup__mask) {
touch-action: none !important;
}
.btn-red, .btn-red-kx {
padding: 0 !important;
width: 140rpx;
}
</style>
......
......@@ -4,11 +4,11 @@
<view class="search-area">
<view class="search-item">
<text>考官姓名:</text>
<input v-model="queryParams.name" placeholder="请输入考官姓名" class="search-input" />
<input v-model="queryParams.name" class="search-input" placeholder="请输入考官姓名"/>
</view>
<view class="search-item">
<text>考官编号:</text>
<input v-model="queryParams.certCode" placeholder="请输入考官编号" class="search-input" />
<input v-model="queryParams.certCode" class="search-input" placeholder="请输入考官编号"/>
</view>
<view class="search-buttons">
<button class="search-btn" @click="handleQuery">查询</button>
......@@ -16,23 +16,23 @@
</view>
</view>
<view class="list-item" v-for="(item, index) in infoList" :key="item.perId">
<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="choose-btn"
:class="{ disabled: checkChosen(item) }"
@click="handleChoose(item)"
:disabled="checkChosen(item)"
class="choose-btn"
@click="handleChoose(item)"
>
{{ checkChosen(item) ? '已选择' : '选择' }}
</button>
</view>
<uni-popup ref="expirePopup" type="center" background-color="rgba(0,0,0,0.5)">
<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>
......@@ -46,8 +46,8 @@
</template>
<script setup>
import { ref, reactive, toRefs } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import {ref, reactive, toRefs} from 'vue'
import {onLoad} from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
import _ from 'lodash'
......@@ -63,13 +63,10 @@ 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 infoList = ref([])
const loading = ref(false)
const total = ref(0)
const selfSelect = ref('0')
const data = reactive({
queryParams: {
pageNum: 1,
......@@ -80,18 +77,23 @@ const data = reactive({
shenMemId: ''
}
})
const { queryParams } = toRefs(data)
const {queryParams} = toRefs(data)
onLoad((option) => {
console.log(option)
isValidity.value = option.isValidity
memId.value = option.memId
chosen.value = JSON.parse(option.chosen)
selfSelect.value = option.selfSelect ?? '1'
})
const infoList = ref([])
const loading = ref(false)
const total = ref(0)
// 获取考官列表
async function getList() {
if (!queryParams.value.name)
return uni.showToast({ title: '请输入考官姓名', icon: 'none' })
return uni.showToast({title: '请输入考官姓名', icon: 'none'})
if (queryParams.value.type == 1 && !queryParams.value.certCode)
return uni.showToast({ title: '请输入考官编号', icon: 'none' })
return uni.showToast({title: '请输入考官编号', icon: 'none'})
loading.value = true
const res = await api.getCoachList(queryParams.value)
......@@ -100,7 +102,7 @@ async function getList() {
loading.value = false
if (infoList.value.length === 0) {
uni.showToast({ title: '请核实考官编号、有效期及归属地!', icon: 'none' })
uni.showToast({title: '请核实考官编号、有效期及归属地!', icon: 'none'})
}
}
......@@ -126,8 +128,9 @@ function resetQuery() {
}
async function handleChoose(row) {
debugger
if (checkChosen(row)) {
return uni.showToast({ title: '已选择该考官', icon: 'none' })
return uni.showToast({title: '已选择该考官', icon: 'none'})
}
// 资质过期逻辑
......@@ -150,11 +153,19 @@ 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)
}
await api.otherAdd(memId.value, currentExpireItem.value.perId)
uni.showToast({ title: '添加成功', icon: 'success' })
uni.navigateBack({ delta: 1 })
uni.showToast({title: '添加成功', icon: 'success'})
uni.navigateBack({delta: 1})
} catch (err) {
uni.showToast({ title: '添加失败', icon: 'none' })
uni.showToast({title: '添加失败', icon: 'none'})
} finally {
expirePopup.value.close()
currentExpireItem.value = null
......@@ -184,6 +195,7 @@ async function confirmAddExpireExaminer() {
align-items: center;
margin-bottom: 20rpx;
}
.search-input {
flex: 1;
border: 1rpx solid #ddd;
......@@ -198,6 +210,7 @@ async function confirmAddExpireExaminer() {
margin-top: 30rpx;
margin-left: 80px;
}
.search-btn, .reset-btn {
width: 220rpx;
height: 70rpx;
......@@ -206,10 +219,12 @@ async function confirmAddExpireExaminer() {
text-align: center;
font-size: 28rpx;
}
.search-btn {
background: #C4121B;
color: #fff;
}
.reset-btn {
background: #f7f7f7;
color: #333;
......@@ -230,19 +245,23 @@ async function confirmAddExpireExaminer() {
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;
......@@ -252,6 +271,7 @@ async function confirmAddExpireExaminer() {
background-color: #fff;
margin: 10rpx auto;
}
.choose-btn.disabled {
color: #ccc;
border-color: #ccc;
......@@ -266,23 +286,27 @@ async function confirmAddExpireExaminer() {
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;
......@@ -293,6 +317,7 @@ async function confirmAddExpireExaminer() {
font-size: 32rpx;
border: none;
}
.btn-confirm {
flex: 1;
height: 80rpx;
......@@ -303,6 +328,7 @@ async function confirmAddExpireExaminer() {
font-size: 32rpx;
border: none;
}
/* 去除button默认边框 */
.btn-cancel::after, .btn-confirm::after {
border: none;
......
......@@ -2,25 +2,32 @@
<view class="container">
<!-- 考官选择类型 -->
<view class="radio-section">
<radio-group @change="onSelfSelectChange" class="radio-group">
<radio-group class="radio-group" @change="onSelfSelectChange">
<label class="radio-item">
<radio value="1" :checked="form.selfSelect == '1'" class="custom-radio" />
<radio :checked="form.selfSelect == '1'" class="custom-radio" value="1"/>
<text class="radio-text">自行录入考官(级位考官)</text>
</label>
<label class="radio-item">
<radio value="0" :checked="form.selfSelect == '0'" class="custom-radio" />
<label v-if="shenForm.memberEpAudit==1" class="radio-item">
<radio :checked="form.selfSelect == '0'" class="custom-radio" value="0"/>
<text class="radio-text">省跆协指派考官</text>
</label>
</radio-group>
</view>
<view class="section">
<!-- 自行录入考官区域 -->
<view class="section examiner-section" v-if="showExamine">
<view v-if="form.selfSelect==0" class="section examiner-section">
<view class="modal-title">温馨提示</view>
<view class="modal-content"> 关于考官指派,请联系{{ shenForm.baseName }},联系电话:{{ shenForm.phone }}
</view>
</view>
<!-- 温馨提示 -->
<view v-if="showExamine" class="section examiner-section">
<button class="add-btn" @click="handelAddExamine">+ 添加考官</button>
</view>
<view class="examiner-list" v-if="showExamine">
<view class="examiner-item" v-for="(item, index) in list" :key="item.id">
<view v-if="showExamine" class="examiner-list">
<view v-for="(item, index) in list" :key="item.id" class="examiner-item">
<view class="info">
<text class="name">{{ item.perName }} {{ item.perCode }}</text>
<text class="idc">证件号码:{{ item.perIdcCode }}</text>
......@@ -36,7 +43,7 @@
</view>
<!-- 自定义考点申请弹窗(替换原uni.showModal) -->
<uni-popup ref="applyPopup" type="center" background-color="rgba(0,0,0,0.5)">
<uni-popup ref="applyPopup" background-color="rgba(0,0,0,0.5)" type="center">
<view class="custom-modal">
<view class="modal-title">考点申请</view>
<view class="modal-btns">
......@@ -48,7 +55,7 @@
</uni-popup>
<!-- 自定义删除确认弹窗 -->
<uni-popup ref="delPopup" type="center" background-color="rgba(0,0,0,0.5)">
<uni-popup ref="delPopup" background-color="rgba(0,0,0,0.5)" type="center">
<view class="custom-modal">
<view class="modal-title">提示</view>
<view class="modal-content">确定删除该考官吗?</view>
......@@ -60,10 +67,11 @@
</uni-popup>
<!-- 自定义省跆协指派提示弹窗 -->
<uni-popup ref="assignPopup" type="center" background-color="rgba(0,0,0,0.5)">
<uni-popup ref="assignPopup" background-color="rgba(0,0,0,0.5)" type="center">
<view class="custom-modal">
<view class="modal-title">温馨提示</view>
<view class="modal-content">关于考官指派,请联系河北省跆协,联系电话:XXXX</view>
<view class="modal-content"> 关于考官指派,请联系{{ shenForm.baseName }},联系电话:{{ shenForm.phone }}
</view>
<view class="modal-btns">
<button class="btn-confirm single-btn" @click="closeAssignPopup()">我知道了</button>
</view>
......@@ -71,7 +79,7 @@
</uni-popup>
<!-- 自定义提交成功弹窗 -->
<uni-popup ref="successPopup" type="center" background-color="rgba(0,0,0,0.5)">
<uni-popup ref="successPopup" background-color="rgba(0,0,0,0.5)" type="center">
<view class="custom-modal">
<view class="modal-title">成功</view>
<view class="modal-content">提交成功,请等待审核</view>
......@@ -84,9 +92,10 @@
</template>
<script setup>
import { ref, } from 'vue'
import { onLoad,onShow } from '@dcloudio/uni-app'
import {ref,} from 'vue'
import {onLoad, onShow} from '@dcloudio/uni-app'
import * as api from '@/common/api.js'
import {getShenMemberInfo} from "@/common/api.js";
const form = ref({
selfSelect: '1' // 1:自行录入 0:省跆协指派
......@@ -95,6 +104,7 @@ const showExamine = ref(true)
const loading = ref(false)
const list = ref([])
const memId = ref(null)
const shenForm = ref({})
// 弹窗引用
const applyPopup = ref(null)
......@@ -112,27 +122,35 @@ onShow(() => {
if (memId.value) {
getExaminer()
}
getShenMemberInfoFn()
})
async function getExaminer() {
loading.value = true
const res = await api.listApi({ memId: memId.value })
const res = await api.listApi({memId: memId.value})
list.value = res.rows
loading.value = false
}
async function getShenMemberInfoFn() {
const res = await api.getShenMemberInfo()
shenForm.value = res.data ?? {}
}
// 删除考官:打开自定义弹窗
function handleDel(row) {
currentDelItem.value = row
delPopup.value.open()
}
// 确认删除
async function confirmDel() {
await api.examinerDel(currentDelItem.value.id)
uni.showToast({ title: '删除成功', icon: 'success' })
getExaminer()
uni.showToast({title: '删除成功', icon: 'success'})
await getExaminer()
closeDelPopup()
}
function closeDelPopup() {
delPopup.value.close()
}
......@@ -141,10 +159,11 @@ function closeDelPopup() {
function onSelfSelectChange(e) {
form.value.selfSelect = e.detail.value
showExamine.value = e.detail.value == '1'
if (e.detail.value == '2') {
if (e.detail.value == '0') {
assignPopup.value.open()
}
}
function closeAssignPopup() {
assignPopup.value.close()
}
......@@ -159,19 +178,20 @@ function handelAddExamine() {
// 提交申请:打开自定义成功弹窗
async function handelSubmit() {
if (!form.value.selfSelect) {
return uni.showToast({ title: '请选择考官类型', icon: 'none' })
return uni.showToast({title: '请选择考官类型', icon: 'none'})
}
if (form.value.selfSelect == '1' && list.value.length == 0) {
return uni.showToast({ title: '请添加考官', icon: 'none' })
return uni.showToast({title: '请添加考官', icon: 'none'})
}
try {
await api.commitExamPointApply(form.value)
successPopup.value.open()
} catch (err) {
uni.showToast({ title: err.data.msg, icon: 'none' })
uni.showToast({title: err.data.msg, icon: 'none'})
}
}
function confirmSuccess() {
successPopup.value.close()
uni.navigateBack()
......@@ -181,9 +201,11 @@ function confirmSuccess() {
function openApplyPopup() {
applyPopup.value.open()
}
function closeApplyPopup() {
applyPopup.value.close()
}
function confirmApply() {
applyPopup.value.close()
// 此处添加考点申请逻辑
......@@ -195,9 +217,11 @@ function confirmApply() {
.container {
min-height: 100vh;
}
.section{
padding:15rpx 20rpx;
.section {
padding: 15rpx 20rpx;
}
/* 单选框区域 */
.radio-section {
background: #fff;
......@@ -332,28 +356,33 @@ function confirmApply() {
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-tip {
font-size: 28rpx;
color: #FF7A00;
margin-top: 20rpx;
}
.modal-btns {
display: flex;
justify-content: space-between;
gap: 20rpx;
}
.btn-cancel {
flex: 1;
height: 80rpx;
......@@ -364,6 +393,7 @@ function confirmApply() {
font-size: 32rpx;
border: none;
}
.btn-confirm {
flex: 1;
height: 80rpx;
......@@ -374,9 +404,11 @@ function confirmApply() {
font-size: 32rpx;
border: none;
}
.single-btn {
flex: 1;
}
.btn-cancel::after, .btn-confirm::after {
border: none;
}
......
......@@ -5,17 +5,17 @@
审核信息
</view>
<view>
<view class="stepItem" v-for="(n,index) in recordList" :key="index">
<view class="time">{{n.auditTime||'待审批'}}</view>
<view v-for="(n,index) in recordList" :key="index" class="stepItem">
<view class="time">{{ n.auditTime || '待审批' }}</view>
<view class="content">
<view class="status">
<text v-if="n.auditResult==1" class="text-success">审核通过</text>
<text v-if="n.auditResult==0" class="text-danger"> 审核拒绝</text>
</view>
<!-- <view class="name">{{index+1}}</view> -->
<view class="deptName">{{n.auditDeptName}}</view>
<view class="deptName">{{ n.auditDeptName }}</view>
<view v-if="n.auditResult==0">
备注:{{n.auditMsg||'/' }}
备注:{{ n.auditMsg || '/' }}
</view>
</view>
</view>
......@@ -26,35 +26,46 @@
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'underscore'
import to from 'await-to-js'
import {
import * as api from '@/common/api.js'
import config from '@/config.js'
import _ from 'underscore'
import to from 'await-to-js'
import {
onMounted,
ref
} from 'vue'
import {
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const app = getApp();
const userType = ref('')
const recordList = ref([])
onLoad(async (option) => {
await getMyRecentFN()
})
} from '@dcloudio/uni-app'
async function getMyRecentFN() {
const app = getApp();
const userType = ref('')
const recordList = ref([])
onLoad(async (option) => {
console.log(option)
if (option.type == 1) await getMyRecentFN()
if (option.type == 2) await getMyRecentExamFn()
})
async function getMyRecentFN() {
const [err, res] = await to(api.getMyRecent())
if (!err && res.data && res.data.auditLogs) {
recordList.value = JSON.parse(res.data.auditLogs)
}
}
async function getMyRecentExamFn() {
const [err, res] = await to(api.getMyRecentExam())
if (!err && res.data && res.data.auditLogs) {
recordList.value = JSON.parse(res.data.auditLogs)
}
}
</script>
<style scoped lang="scss">
.wBox {
<style lang="scss" scoped>
.wBox {
width: 700rpx;
padding: 30rpx;
margin: 20rpx auto;
......@@ -79,5 +90,5 @@
text-align: justify;
}
}
}
}
</style>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!