23436998 by lttnew

道馆

1 parent 843f28df
......@@ -2,7 +2,8 @@
"permissions": {
"allow": [
"Bash(ls D:/ltt/ztx_wx_gzt/views/*/index.vue)",
"WebFetch(domain:minimax-algeng-chat-tts.oss-cn-wulanchabu.aliyuncs.com)"
"WebFetch(domain:minimax-algeng-chat-tts.oss-cn-wulanchabu.aliyuncs.com)",
"Bash(node -c pages/index/perfect.vue)"
]
}
}
......
......@@ -1537,6 +1537,16 @@ export function checkBusinessLicense(data) {
})
}
// 校验社会信用代码是否已存在
export function creditCodeExist(code) {
return request({
url: `/member/info/creditCodeExist`,
params: {
creditCode: code
}
})
}
// 生成单位订单renewYear
export function certifiedNew(renewYear) {
return request({
......@@ -1689,6 +1699,15 @@ export function getMyRecentExam() {
})
}
// 考点申请列表
export function examPointApplyList(params) {
return request({
url: '/member/examPointApply/list',
method: 'get',
params
})
}
// 获取订单详情
export function getOrderInfo(orderId) {
......@@ -2078,3 +2097,12 @@ export function settlementDetailList(params) {
params: params
})
}
// 会员审核记录列表
export function memberAuditList(params) {
return request({
url: '/system/input/list',
method: 'get',
params: params
})
}
......
<template>
<view class="custom-modal" v-if="show">
<view class="modal-mask" @click="onMaskClick"></view>
<view class="modal-content">
<view class="modal-header" v-if="title">
<text class="modal-title">{{ title }}</text>
</view>
<view class="modal-body">
<rich-text v-if="isHtml" :nodes="content"></rich-text>
<text v-else class="modal-text">{{ content }}</text>
</view>
<view class="modal-footer">
<button class="btn-cancel" @click="onCancel" v-if="showCancel">{{ cancelText }}</button>
<button class="btn-confirm" @click="onConfirm" v-if="showConfirm">{{ confirmText }}</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
isHtml: {
type: Boolean,
default: false
},
showCancel: {
type: Boolean,
default: true
},
showConfirm: {
type: Boolean,
default: true
},
cancelText: {
type: String,
default: '取消'
},
confirmText: {
type: String,
default: '确定'
},
maskCloseable: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['cancel', 'confirm'])
const show = ref(false)
function onCancel() {
show.value = false
emit('cancel')
}
function onConfirm() {
show.value = false
emit('confirm')
}
function onMaskClick() {
if (props.maskCloseable) {
show.value = false
}
}
// 对外暴露的方法
function open() {
show.value = true
}
function close() {
show.value = false
}
defineExpose({ open, close })
</script>
<style lang="scss" scoped>
.custom-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.modal-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: relative;
width: 600rpx;
max-width: 85%;
background: #fff;
border-radius: 24rpx;
overflow: hidden;
animation: modalIn 0.2s ease;
}
@keyframes modalIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
.modal-header {
padding: 32rpx 30rpx 0;
text-align: center;
}
.modal-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.modal-body {
padding: 30rpx;
max-height: 60vh;
overflow-y: auto;
}
.modal-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
text-align: center;
white-space: pre-wrap;
word-break: break-word;
}
.modal-footer {
display: flex;
padding: 0 30rpx 30rpx;
gap: 24rpx;
justify-content: center;
}
.btn-cancel,
.btn-confirm {
flex: 1;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
border-radius: 40rpx;
margin: 0;
padding: 0;
border: none;
}
.btn-cancel {
background: #fff;
color: #AD181F;
border: 2rpx solid #AD181F;
}
.btn-confirm {
background: #AD181F;
color: #fff;
}
</style>
<template>
<view>
<!-- 自定义弹窗 -->
<custom-modal ref="customModalRef" :title="modalConfig.title" :content="modalConfig.content" :showCancel="modalConfig.showCancel" :cancelText="modalConfig.cancelText" :confirmText="modalConfig.confirmText" @confirm="onModalConfirm" />
<!-- 顶部添加考官按钮 -->
<view class="add-btn-box">
<button class="btn-red-kx mini" @click="openAddExaminer">
......@@ -13,20 +16,22 @@
<view class="item" v-for="(n,index) in list" :key="index">
<view class="item-content">
<view class="name-row">
<view class="name">{{n.perName}}</view>
<view class="expired-tag" v-if="n.canChoose != 1">
<text class="expired-text">已过期</text>
</view>
<view class="name">{{n.perName}} <text class="expired-text" v-if="n.canChoose != 1">已过期</text></view>
<!-- <view class="expired-tag" v-if="n.canChoose != 1">
<text class="text">已过期</text>
</view> -->
</view>
<view class="date">会员号:{{n.perCode||'-'}}</view>
<view class="date">有效日期:{{ formatDate(n.roleInfo && n.roleInfo.validTime ? n.roleInfo.validTime : '-') }}</view>
<view class="date">注册地:{{n.memName||'-'}}</view>
</view>
<view class="status">
<text v-if="isChosen(n)" class="text-chosen">已选</text>
<!-- <text v-else-if="n.canChoose != 1" class="text-gray">不可选</text> -->
<text v-else-if="n.canChoose == 1" class="text-primary" @click="handleChoose(n)">选择</text>
<text v-else class="text-gray">不可选</text>
<text v-if="pageType == 1" class="text-danger" @click="handleDelete(n)">删除</text>
<template v-else>
<text v-if="isChosen(n)" class="text-chosen">已选</text>
<text v-else-if="n.canChoose == 1" class="text-primary" @click="handleChoose(n)">选择</text>
<text v-else class="text-gray">不可选</text>
</template>
</view>
</view>
</view>
......@@ -79,12 +84,10 @@
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import {
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import customModal from '@/components/custom-modal.vue'
const app = getApp();
const list = ref([])
const loading = ref(false)
......@@ -92,6 +95,8 @@
let ec = null
const addPopup = ref(null)
const customModalRef = ref(null)
const modalConfig = ref({})
const addForm = ref({
type: 1,
name: '',
......@@ -99,10 +104,16 @@
})
const searchResult = ref(null)
const searchNoData = ref(false)
const pageType = ref('')
onLoad((option) => {
chosen = JSON.parse(decodeURIComponent(option.chosen || '[]'))
ec = option.ec
if(option.pageType ){
pageType.value = option.pageType || ''
}else{
chosen = JSON.parse(decodeURIComponent(option.chosen || '[]'))
ec = option.ec
}
console.log('pageType.value',pageType.value)
getList()
})
......@@ -176,6 +187,52 @@
uni.navigateBack({ delta: 1 })
}
// 删除考官
let pendingDeleteRow = null
let modalAction = '' // 'delete' or 'add'
function handleDelete(row) {
pendingDeleteRow = row
modalAction = 'delete'
modalConfig.value = {
title: '提示',
content: `确定删除 "${row.perName}" 吗?`,
showCancel: true,
cancelText: '取消',
confirmText: '确定'
}
customModalRef.value.open()
}
function onModalConfirm() {
if (modalAction === 'delete' && pendingDeleteRow) {
uni.showLoading({ title: '删除中' })
api.examinerDel(pendingDeleteRow.id).then(() => {
uni.hideLoading()
uni.showToast({ title: '删除成功', icon: 'success' })
getList()
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '删除失败', icon: 'error' })
})
pendingDeleteRow = null
modalAction = ''
} else if (modalAction === 'add' && pendingAddRow) {
uni.showLoading({ title: '添加中' })
api.selfAdd(pendingAddRow.perId).then(() => {
uni.hideLoading()
uni.showToast({ title: '添加成功', icon: 'success' })
addPopup.value.close()
getList()
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '添加失败', icon: 'error' })
})
pendingAddRow = null
modalAction = ''
}
}
// 打开添加考官弹窗
function openAddExaminer() {
addForm.value.name = ''
......@@ -218,26 +275,18 @@
}
// 执行添加考官
let pendingAddRow = null
function doAddExaminer(row) {
uni.showModal({
pendingAddRow = row
modalAction = 'add'
modalConfig.value = {
title: '提示',
content: `确定添加 "${row.name}" 为考官吗?`,
success: (res) => {
if (res.confirm) {
uni.showLoading({ title: '添加中' })
api.selfAdd(row.perId).then(() => {
uni.hideLoading()
uni.showToast({ title: '添加成功', icon: 'success' })
addPopup.value.close()
// 刷新列表
getList()
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '添加失败', icon: 'error' })
})
}
}
})
content: `确定添加 "${row.perName}" 为考官吗?`,
showCancel: true,
cancelText: '取消',
confirmText: '确定'
}
customModalRef.value.open()
}
</script>
......@@ -333,7 +382,11 @@
}
.text-danger {
color: #dd524d;
border-radius: 30rpx;
background: linear-gradient(135deg, #fff1f0, #ffe5e5);
color: #e8341d;
font-size: 22rpx;
border: 1rpx solid rgba(232, 52, 29, 0.3);
}
.popBody {
......
......@@ -88,14 +88,18 @@
<!-- 注册提示弹框 -->
<uni-popup ref="registerPopup" type="center" :mask-click="false">
<view class="register-popup">
<view class="popup-title">注册提示</view>
<view class="popup-title">系统提示</view>
<view class="popup-content">
<view class="popup-text">请准备以下材料,以便顺利完成注册</view>
<view class="popup-list">
<text>1. 单位营业执照(清晰照片)</text>
<text>2. 法人身份证正反面照片(清晰照片)</text>
<text>3. 单位营业执照(清晰照片)</text>
</view>
<view class="popup-text">尊敬的用户,您好!</view>
<view class="popup-text">在开始注册团体会员前,请您提前准备好以下材料,以便顺利完成申请:</view>
<view class="popup-item">1. 单位营业执照</view>
<view class="popup-desc">请提供清晰的营业执照原件照片或扫描件(加盖公章更佳)</view>
<view class="popup-item">2. 法人身份证正反面照片</view>
<view class="popup-desc">请分别上传身份证正面及反面清晰照片</view>
<view class="popup-desc">确保信息完整、无遮挡、无模糊</view>
<view class="popup-item">3. 机构照片</view>
<view class="popup-desc">请提供体现单位实际经营或办公环境的照片1-2张</view>
<view class="popup-desc">如门头、办公场所、活动场地等(能展示机构真实存在即可)</view>
</view>
<view class="popup-btns">
<view class="popup-btn cancel" @click="closeRegisterPopup">取消</view>
......@@ -108,10 +112,12 @@
<script setup>
import {
onLoad
onLoad,
onReady
} from '@dcloudio/uni-app';
import {
ref
ref,
nextTick
} from 'vue'
import config from '@/config.js'
import {
......@@ -152,7 +158,7 @@ const app = getApp()
onLoad(() => {
getCode()
if (uni.showShareMenu) {
uni.showShareMenu({
withShareTicket: true,
......@@ -161,6 +167,10 @@ onLoad(() => {
}
})
onReady(() => {
console.log('registerPopup ready:', registerPopup.value)
})
function goBack() {
uni.navigateBack()
}
......@@ -246,7 +256,11 @@ function login() {
}
function goRegister() {
registerPopup.value.open()
nextTick(() => {
if (registerPopup.value) {
registerPopup.value.open()
}
})
}
function closeRegisterPopup() {
......@@ -560,28 +574,47 @@ function call(num) {
/* 注册提示弹框 */
.register-popup {
width: 600rpx;
width: 700rpx;
background: #ffffff;
border-radius: 24rpx;
overflow: hidden;
}
.popup-title {
font-size: 32rpx;
font-weight: 500;
// display: inline-block;
// background: #AD181F;
color: #333;
font-size: 28rpx;
font-weight: 600;
margin: 30rpx auto 20rpx;
text-align: center;
padding: 40rpx 30rpx 20rpx;
}
.popup-content {
padding: 20rpx 30rpx 40rpx;
padding: 0 30rpx 30rpx;
}
.popup-text {
font-size: 26rpx;
color: #666;
margin-bottom: 16rpx;
line-height: 1.6;
}
.popup-item {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
font-weight: 600;
margin-top: 24rpx;
margin-bottom: 10rpx;
}
.popup-desc {
font-size: 24rpx;
color: #888;
padding-left: 16rpx;
line-height: 1.5;
margin-bottom: 8rpx;
}
.popup-list {
......@@ -599,24 +632,27 @@ function call(num) {
.popup-btns {
display: flex;
border-top: 1rpx solid #eee;
padding: 0 30rpx 30rpx;
gap: 24rpx;
}
.popup-btn {
flex: 1;
height: 100rpx;
line-height: 100rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 30rpx;
border-radius: 40rpx;
}
.popup-btn.cancel {
color: #666;
border-right: 1rpx solid #eee;
background: #fff;
color: #AD181F;
border: 2rpx solid #AD181F;
}
.popup-btn.confirm {
color: #AD181F;
font-weight: 500;
background: #AD181F;
color: #fff;
}
</style>
......
......@@ -59,6 +59,20 @@
</view>
</view>
</view>
<!-- 自定义弹框 -->
<customModal
ref="customModalRef"
:title="modalConfig.title"
:content="modalConfig.content"
:isHtml="modalConfig.isHtml"
:showCancel="modalConfig.showCancel"
:showConfirm="modalConfig.showConfirm"
:cancelText="modalConfig.cancelText"
:confirmText="modalConfig.confirmText"
@confirm="onModalConfirm"
@cancel="onModalCancel"
></customModal>
</template>
<script setup>
......@@ -72,6 +86,7 @@ import {
groupMemberRegister
} from '@/common/login.js'
import config from '@/config.js'
import customModal from '@/components/custom-modal.vue'
const agree = ref(false)
const codeUrl = ref(null)
const registerForm = ref({
......@@ -86,6 +101,46 @@ const countDown = ref({
start: false,
second: 60
})
// 自定义弹框
const customModalRef = ref(null)
const modalConfig = ref({
title: '',
content: '',
isHtml: false,
showCancel: true,
showConfirm: true,
cancelText: '取消',
confirmText: '确定'
})
function onModalConfirm() {
if (modalConfig.value.onConfirm) {
modalConfig.value.onConfirm()
}
}
function onModalCancel() {
if (modalConfig.value.onCancel) {
modalConfig.value.onCancel()
}
}
function showModal(options) {
modalConfig.value = {
title: options.title || '',
content: options.content || '',
isHtml: options.isHtml || false,
showCancel: options.showCancel !== false,
showConfirm: options.showConfirm !== false,
cancelText: options.cancelText || '取消',
confirmText: options.confirmText || '确定',
onConfirm: options.onConfirm,
onCancel: options.onCancel
}
customModalRef.value?.open()
}
const inputstyle = ref({
borderColor: 'transparent',
fontSize: '30rpx'
......@@ -138,18 +193,14 @@ function register() {
groupMemberRegister(registerForm.value)
.then((res) => {
uni.showModal({
showModal({
title: '提示',
content: `恭喜你,您的账号 ${registerForm.value.telNo} 注册成功!`,
confirmText: '去登录',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
registerForm.value = {}
goLogin()
} else {
// 取消,保持当前页面
}
confirmText: '去登录',
onConfirm: () => {
registerForm.value = {}
goLogin()
}
})
})
......
......@@ -23,18 +23,19 @@
style="margin: 0 20rpx 0 0;" @click="payTheFees">激活
</button>
<view v-else>
<button v-if="form.deptType==6"
:disabled="auditStatus==1||auditStatus==2||form.isPoints==0" class="btn-red"
<!-- :disabled="auditStatus==1||auditStatus==2||form.isPoints==0" class="btn-red" -->
<!-- <button v-if="form.deptType==6"
size="mini"
style="margin: 0 20rpx 0 0;"
@click="showApplyDialog">考点申请
</button>
<button v-if="form.deptType==6"
</button> -->
<!-- <button v-if="form.deptType==6"
class="btn-red-kx"
size="mini"
style="margin: 0 20rpx 0 0;"
@click="auditEditFN(2)">考点详情
</button>
</button> -->
<button :disabled="btn" class="btn-red" size="mini" style="margin: 0 20rpx 0 0;"
@click="payTheFees">去缴费
</button>
......
<template>
<view class="container">
<!-- 自定义弹窗 -->
<custom-modal ref="customModalRef" :title="modalConfig.title" :content="modalConfig.content" :showCancel="modalConfig.showCancel" :cancelText="modalConfig.cancelText" :confirmText="modalConfig.confirmText" @confirm="onModalConfirm" />
<!-- 考官选择类型 -->
<view class="radio-section">
<radio-group class="radio-group" @change="onSelfSelectChange">
......@@ -13,20 +16,24 @@
</label>
</radio-group>
</view>
<!-- 温馨提示 -->
<view v-if="form.selfSelect == '1'" class="tip-box">
<text class="tip-text">温馨提示: 您可以自行录入考官信息,如果暂时没有合适的考官,也可以选择由省跆协指派(支持多选)进行考点申报,同时请尽快完成考点考官的认证。</text>
</view>
<!-- 省跆协指派提示 -->
<view v-if="form.selfSelect == '0'" class="tip-box">
<text class="tip-text">温馨提示:关于考官指派,请联系{{ shenForm.baseName || '' }},联系电话:{{ shenForm.phone || '' }}</text>
</view>
<view class="section">
<!-- 自行录入考官区域 -->
<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">
<view v-if="form.selfSelect == '1'" class="section examiner-section">
<button class="add-btn" @click="handelAddExamine">+ 添加考官</button>
</view>
<view v-if="showExamine" class="examiner-list">
<view v-if="form.selfSelect == '1'" 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>
......@@ -41,62 +48,15 @@
<view class="submit-area">
<button class="submit-btn" @click="handelSubmit">确定提交</button>
</view>
<!-- 自定义考点申请弹窗(替换原uni.showModal) -->
<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">
<button class="btn-cancel" @click="closeApplyPopup()">暂不申请</button>
<button class="btn-confirm" @click="confirmApply()">立即申请</button>
</view>
<view class="modal-tip">友情提示:非考点无法申请级位考试</view>
</view>
</uni-popup>
<!-- 自定义删除确认弹窗 -->
<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>
<view class="modal-btns">
<button class="btn-cancel" @click="closeDelPopup()">取消</button>
<button class="btn-confirm" @click="confirmDel()">确定</button>
</view>
</view>
</uni-popup>
<!-- 自定义省跆协指派提示弹窗 -->
<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"> 关于考官指派,请联系{{ shenForm.baseName }},联系电话:{{ shenForm.phone }}
</view>
<view class="modal-btns">
<button class="btn-confirm single-btn" @click="closeAssignPopup()">我知道了</button>
</view>
</view>
</uni-popup>
<!-- 自定义提交成功弹窗 -->
<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>
<view class="modal-btns">
<button class="btn-confirm single-btn" @click="confirmSuccess()">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {ref,} from 'vue'
import {ref} from 'vue'
import {onLoad, onShow} from '@dcloudio/uni-app'
import * as api from '@/common/api.js'
import {getShenMemberInfo} from "@/common/api.js";
import customModal from '@/components/custom-modal.vue'
const app = getApp();
const form = ref({
selfSelect: '1' // 1:自行录入 0:省跆协指派
})
......@@ -106,28 +66,33 @@ const list = ref([])
const memId = ref(null)
const shenForm = ref({})
// 弹窗引用
const applyPopup = ref(null)
const delPopup = ref(null)
const assignPopup = ref(null)
const successPopup = ref(null)
let currentDelItem = ref(null)
// 自定义弹窗
const customModalRef = ref(null)
const modalConfig = ref({
title: '',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确定'
})
let modalAction = '' // 'del', 'success', 'assign', 'apply'
let pendingDelItem = null
onLoad((option) => {
memId.value = option.memId
// memId.value = app.globalData.memberInfo.memId
getExaminer()
})
onShow(() => {
if (memId.value) {
// 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: app.globalData.memberInfo.memId})
list.value = res.rows
loading.value = false
}
......@@ -139,20 +104,16 @@ async function getShenMemberInfoFn() {
// 删除考官:打开自定义弹窗
function handleDel(row) {
currentDelItem.value = row
delPopup.value.open()
}
// 确认删除
async function confirmDel() {
await api.examinerDel(currentDelItem.value.id)
uni.showToast({title: '删除成功', icon: 'success'})
await getExaminer()
closeDelPopup()
}
function closeDelPopup() {
delPopup.value.close()
pendingDelItem = row
modalAction = 'del'
modalConfig.value = {
title: '提示',
content: '确定删除该考官吗?',
showCancel: true,
cancelText: '取消',
confirmText: '确定'
}
customModalRef.value.open()
}
// 切换考官类型:打开自定义提示弹窗
......@@ -160,14 +121,17 @@ function onSelfSelectChange(e) {
form.value.selfSelect = e.detail.value
showExamine.value = e.detail.value == '1'
if (e.detail.value == '0') {
assignPopup.value.open()
modalAction = 'assign'
modalConfig.value = {
title: '温馨提示',
content: `关于考官指派,请联系${shenForm.value.baseName || ''},联系电话:${shenForm.value.phone || ''}`,
showCancel: false,
confirmText: '我知道了'
}
customModalRef.value.open()
}
}
function closeAssignPopup() {
assignPopup.value.close()
}
function handelAddExamine() {
const chosenStr = JSON.stringify(list.value)
uni.navigateTo({
......@@ -175,7 +139,7 @@ function handelAddExamine() {
})
}
// 提交申请:打开自定义成功弹窗
// 提交申请
async function handelSubmit() {
if (!form.value.selfSelect) {
return uni.showToast({title: '请选择考官类型', icon: 'none'})
......@@ -183,27 +147,47 @@ async function handelSubmit() {
if (form.value.selfSelect == '1' && list.value.length == 0) {
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'})
}
}
function confirmSuccess() {
successPopup.value.close()
uni.navigateBack()
}
// 考点申请弹窗(如需调用可在合适位置打开)
function openApplyPopup() {
applyPopup.value.open()
}
function closeApplyPopup() {
applyPopup.value.close()
modalAction = 'success'
modalConfig.value = {
title: '提示',
content: '友情提示:非考点无法申请级位考试,是否确认提交申请?',
showCancel: true,
cancelText: '暂不申请',
confirmText: '确认提交'
}
customModalRef.value.open()
}
// 弹窗确认回调
async function onModalConfirm() {
if (modalAction === 'del' && pendingDelItem) {
try {
await api.examinerDel(pendingDelItem.id)
uni.showToast({title: '删除成功', icon: 'success'})
await getExaminer()
} catch (e) {
uni.showToast({title: '删除失败', icon: 'error'})
}
pendingDelItem = null
} else if (modalAction === 'success') {
try {
await api.commitExamPointApply(form.value)
modalAction = 'submitSuccess'
modalConfig.value = {
title: '成功',
content: '提交成功,请等待审核',
showCancel: false,
confirmText: '确定'
}
customModalRef.value.open()
} catch (err) {
uni.showToast({title: err.data?.msg || '提交失败', icon: 'none'})
}
} else if (modalAction === 'submitSuccess') {
uni.navigateBack()
}
modalAction = ''
}
function confirmApply() {
......@@ -231,6 +215,19 @@ function confirmApply() {
border-radius: 0;
}
/* 提示框 */
.tip-box {
background: #fff7e6;
padding: 20rpx 30rpx;
margin-bottom: 10rpx;
}
.tip-text {
font-size: 24rpx;
color: #fa8c16;
line-height: 1.6;
}
.radio-group {
display: flex;
align-items: center;
......
<template>
<view class="exam-point-list">
<!-- 顶部申请按钮 -->
<view class="apply-btn-box">
<button class="apply-btn" :disabled="memberInfo.isPoints==0||memberInfo.auditStatus==2" @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="list-item"
:class="{ 'success-row': item.shenAuditStatus == 2 }"
>
<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="item-status" :class="getStatusClass(item.auditResult)">
{{ 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, onReachBottom } from '@dcloudio/uni-app'
import { getMyRecent } 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
onLoad(() => {
loadData()
})
function loadData() {
if (loading.value) return
loading.value = true
getMyRecent().then(res => {
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-1': status == 0,
'status-2': status == 1,
'status-3': status == 3
}
}
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>
......@@ -237,16 +237,13 @@ const cancelModalContent = ref('');
const currentOrder = ref(null);
// 页面挂载初始化
onMounted(() => {
onLoad((option) => {
// 获取app实例和deptType
const app = getApp();
console.log('onMounted - app:', app);
console.log('onMounted - app.globalData:', app.globalData);
deptType.value = Number(app.globalData?.deptType || 0);
console.log('onMounted - deptType.value:', deptType.value, typeof deptType.value);
const firstType = tabs.value[0]?.type ?? '0';
currentTab.value = firstType;
queryParams.type = firstType;
currentTab.value = option.type || firstType;
queryParams.type = option.type ||firstType;
initData();
});
......@@ -290,7 +287,7 @@ const getStatusText = (status) => {
1: '缴费成功',
2: '订单取消'
};
return map[status] || '未知状态';
return map[status] || '';
};
// 审核状态文本映射
......@@ -301,7 +298,7 @@ const getAuditStatusText = (status) => {
2: '审核通过',
3: '审核拒绝'
};
return map[status] || '未知状态';
return map[status] || '';
};
// 数据请求核心方法
......
......@@ -6,8 +6,8 @@
<uni-forms-item label="所属协会" required>
<view style="width: 60vw;overflow:auto;">
<uni-data-picker v-model="form.parentId" :localdata="tree"
:readonly="type&&parentId!=-1&&parentId!=0" :clear-icon="false"
:map="{text:'label',value:'id'}" popup-title="请选择" @change="changCase">
:readonly="type&&parentId!=-1&&parentId!=0" :clear-icon="false" placeholder="请选择协会"
:map="{text:'label',value:'id'}" popup-title="" @change="changCase">
</uni-data-picker>
</view>
</uni-forms-item>
......@@ -32,7 +32,7 @@
<uni-easyinput v-model="form.siteTel" />
</uni-forms-item>
<uni-forms-item label="认证地址" required>
<uni-data-picker v-model="form.coordinates1" @change="changeCoordinates1"
<uni-data-picker v-model="form.coordinates1" @change="changeCoordinates1" placeholder="请选择认证地址"
:localdata="regionsList"></uni-data-picker>
</uni-forms-item>
<uni-forms-item label="详细地址" required>
......@@ -792,7 +792,7 @@
}
:deep(.input-value) {
padding: 0 5px;
padding: 0 5rpx;
}
.picker-view {
......
......@@ -45,21 +45,29 @@ const recordList = ref([])
onLoad(async (option) => {
console.log(option)
if (option.type == 1) await getMyRecentFN()
if (!option.type || 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)
try {
recordList.value = JSON.parse(res.data.auditLogs) || []
} catch (e) {
recordList.value = []
}
}
}
async function getMyRecentExamFn() {
const [err, res] = await to(api.getMyRecentExam())
if (!err && res.data && res.data.auditLogs) {
recordList.value = JSON.parse(res.data.auditLogs)
try {
recordList.value = JSON.parse(res.data.auditLogs) || []
} catch (e) {
recordList.value = []
}
}
}
</script>
......
......@@ -47,6 +47,7 @@
</view>
<!-- 道馆 -->
<view v-if="userType=='4'" class="girdBox">
<view @click="goPath('/personalVip/mobilize')">
<uni-badge :text="numData.personTransferCount" class="potag"/>
......@@ -63,6 +64,87 @@
级位变更
</view>
</view>
<view v-if="userType=='4'" class="girdFather">
<view class="ttt">个人会员</view>
<view class="girdBox">
<view @click="goPath('/personalVip/addVip')">
<uni-badge :text="numData.personTransferCount" class="potag"/>
<image :src="config.baseUrl_api+'/fs/static/icon/2.png'"/>
添加会员
</view>
<view @click="goPath('/personalVip/list')">
<image :src="config.baseUrl_api+'/fs/static/icon/25.png'"/>
会员列表
</view>
<view @click="goPath('/personalVip/mobilize')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'"/>
会员调动
</view>
<view @click="goPath('/personalVip/payment')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'"/>
会员缴费
</view>
<view @click="goPath('/personal/memberAuditRecord')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'"/>
会员审核记录
</view>
<view @click="goPath('/myCenter/order?type=0')">
<image :src="config.baseUrl_api+'/fs/static/icon/28.png'"/>
订单列表
</view>
</view>
<view class="ttt">单位会员</view>
<view class="girdBox">
<view @click="goPath('/myCenter/auth')">
<uni-badge :text="numData.memberJiaofeiCount" class="potag"/>
<image :src="config.baseUrl_api+'/fs/static/icon/4.png'"/>
会员认证
</view>
<view @click="goPath('/myCenter/reviewList')">
<image :src="config.baseUrl_api+'/fs/static/icon/27.png'"/>
认证详情
</view>
<view @click="goPath('/myCenter/examPointApplyList')">
<image :src="config.baseUrl_api+'/fs/static/icon/17.png'"/>
考点申请
</view>
<view @click="goPath('/myCenter/order?type=1')">
<image :src="config.baseUrl_api+'/fs/static/icon/9.png'"/>
订单列表
</view>
</view>
<view class="ttt">级位管理</view>
<view class="girdBox">
<view @click="goPath('/level/apply')">
<image :src="config.baseUrl_api+'/fs/static/icon/3.png'"/>
考试申请
</view>
<view @click="goPath('/level/ztx/mail')">
<image :src="config.baseUrl_api+'/fs/static/icon/25.png'"/>
证书邮寄
</view>
<view @click="goPath('/level/ztx/costSettlement')">
<image :src="config.baseUrl_api+'/fs/static/icon/10.png'"/>
证书下载
</view>
<view @click="goPath('/personalVip/changeLevel')">
<image :src="config.baseUrl_api+'/fs/static/icon/26.png'"/>
级位变更
</view>
<view @click="goPath('/level/chooseExaminer?pageType=1')">
<image :src="config.baseUrl_api+'/fs/static/icon/10.png'"/>
考官库
</view>
<view @click="goPath('/myCenter/order?type=2')">
<image :src="config.baseUrl_api+'/fs/static/icon/10.png'"/>
订单列表
</view>
</view>
</view>
<view v-if="userType=='3'" class="girdBox">
<view @click="goPath('/group/apply/applyList')">
<uni-badge :text="numData.memberJiaofeiCount" class="potag"/>
......
<template>
<view class="notice-page">
<view class="notice-content">
<view class="notice-body">
<view class="section">中国跆拳道协会团体会员入会申请免责声明</view>
<view class="section ">
<view class="section-text">尊敬的申请单位:</view>
<view class="section-text mt20">为确保中国跆拳道协会(以下简称"中国跆协")会员管理工作的规范性与严肃性,保障贵单位合法权益,请在提交入会申请材料并缴纳会费前,仔细阅读本声明。贵单位一旦勾选"同意",即视为已理解并自愿接受以下条款的约束。</view>
</view>
<view class="section">
<view class="section-title">一、信息真实性承诺</view>
<view class="section-item">1. 贵单位保证在入会申请过程中提交的全部材料(包括但不限于营业执照、法人身份证明、场所证明及从业人员资质证明等)均真实、准确、完整、有效。</view>
<view class="section-item">2. 若贵单位提交虚假、伪造、变造或失效的材料,由此产生的一切法律责任及后果由贵单位自行承担;中国跆协有权无条件取消会员资格,且已缴纳会费不予退还。</view>
</view>
<view class="section">
<view class="section-title">二、主体合法性承诺</view>
<view class="section-item">1. 贵单位保证系依法登记注册并合法存续的法人或非法人组织,具备申请成为中国跆协团体会员的法定资格。</view>
<view class="section-item">2. 贵单位的经营活动及业务范围符合国家法律法规及跆拳道行业管理规范,不存在被吊销、注销、列入经营异常名录或严重违法失信名单等情形。</view>
</view>
<view class="section">
<view class="section-title">三、授权与程序合规性承诺</view>
<view class="section-item">1. 贵单位确认本次入会申请已经通过内部合法决策程序(如股东会、理事会决议或法定代表人决定),系单位真实意愿。</view>
<view class="section-item">2. 贵单位指定办理入会手续的人员已获得充分授权,其在线勾选同意本声明的行为具有法律效力。</view>
</view>
<view class="section">
<view class="section-title">四、遵守协会规章承诺</view>
<view class="section-item">1. 贵单位承诺入会后严格遵守《中国跆拳道协会章程》《中国跆拳道协会会员管理办法》及中国跆协发布的其他规章制度。</view>
<view class="section-item">2. 贵单位知晓并接受:违反上述规章的,中国跆协有权依据规定给予警告、限期整改、暂停会员资格直至取消会员资格的处罚。</view>
</view>
<view class="section">
<view class="section-title">五、信息变更告知义务</view>
<view class="section-item">1. 贵单位承诺在会员资格存续期间,如单位名称、法定代表人、联系方式、经营状态等信息发生变更,将在变更之日起15个工作日内通过会员系统更新信息或书面告知中国跆协。</view>
<view class="section-item">2. 因未及时告知导致无法接收协会通知、证书发放错误或其他损失的,由贵单位自行承担责任。</view>
</view>
<view class="section">
<view class="section-title">六、免责条款</view>
<view class="section-item">1. 因贵单位提供信息不实、不完整或未及时更新信息,导致中国跆协或第三方遭受损失的,贵单位应承担全部赔偿责任。</view>
<view class="section-item">2. 因不可抗力(包括但不限于自然灾害、政府行为、政策法律法规变更、网络攻击或系统故障)导致贵单位申请信息丢失、泄露或申请流程中断的,中国跆协不承担责任,但应在条件允许时提供必要协助。</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
function goBack() {
uni.navigateBack()
}
</script>
<style lang="scss" scoped>
.notice-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
}
.notice-content {
flex: 1;
padding: 30rpx;
overflow-y: auto;
}
.notice-header {
padding: 40rpx 0;
text-align: center;
}
.notice-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.notice-body {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
}
.section {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
line-height: 1.5;
}
.section-text {
font-size: 28rpx;
color: #666;
line-height: 1.8;
text-align: justify;
&.mt20 {
margin-top: 20rpx;
}
}
.section-item {
font-size: 28rpx;
color: #666;
line-height: 1.8;
margin-bottom: 12rpx;
text-align: justify;
&:last-child {
margin-bottom: 0;
}
}
.notice-footer {
padding: 30rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
</style>
<template>
<view class="notice-page">
<view class="notice-content">
<view class="notice-body">
<!-- <view class="title">考点申请须知</view> -->
<view class="subtitle">中国跆拳道协会考点申请须知</view>
<view class="paragraph">
欢迎贵单位申请成为中国跆拳道协会(以下简称中国跆协)考点。请确保本次申请系自愿行为,且已充分了解并愿意遵守本须知的全部内容。
</view>
<view class="section">
<view class="section-title">一、基本要求</view>
<view class="section-item">1. 申请单位须为中国跆协有效团体会员。</view>
<view class="section-item">2. 具体申请条件(人员资质、场地设施等)请以中国跆协官网公布的最新要求为准。</view>
</view>
<view class="section">
<view class="section-title">二、考点主要职责</view>
<view class="section-item">1. 按规定组织考试,接受协会统一安排。</view>
<view class="section-item">2. 严格执行收费标准,不得违规收费。</view>
<view class="section-item">3. 按时完成成绩上传及证书办理。</view>
</view>
<view class="section">
<view class="section-title">三、禁止事项</view>
<view class="section-item">- 严禁跨区域组织考试</view>
<view class="section-item">- 严禁为非会员单位办理证书</view>
<view class="section-item">- 严禁买卖或伪造证书</view>
<view class="section-item">- 严禁擅自颁发证书</view>
</view>
<view class="section">
<view class="section-title">四、违规处理</view>
<view class="section-item">视情节给予警告、暂停考点资格、取消考点资格、取消会员资格等处理;情节严重者列入行业黑名单。</view>
</view>
<view class="section">
<view class="section-title">五、其他</view>
<view class="section-item">本须知依据中国跆协相关规定制定,解释权归中国跆拳道协会所有。具体申请条件及材料清单,请登录中国跆拳道协会官网查询。</view>
</view>
</view>
</view>
<view class="notice-footer">
<button class="back-btn" @click="goBack">上一步</button>
<button class="agree-btn" @click="goApply">下一步</button>
</view>
</view>
</template>
<script setup>
function goApply() {
uni.navigateTo({
url: '/myCenter/examPointApply'
})
}
function goBack() {
uni.navigateBack({
delta: 1
})
}
</script>
<style lang="scss" scoped>
.notice-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
}
.notice-content {
flex: 1;
padding: 30rpx;
overflow-y: auto;
}
.notice-body {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
}
.title {
font-size: 36rpx;
font-weight: 600;
color: #333;
text-align: center;
margin-bottom: 30rpx;
}
.subtitle {
font-size: 28rpx;
color: #666;
margin-bottom: 30rpx;
}
.paragraph {
font-size: 28rpx;
color: #666;
line-height: 1.8;
margin-bottom: 30rpx;
}
.section {
margin-bottom: 30rpx;
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.section-item {
font-size: 26rpx;
color: #666;
line-height: 1.8;
margin-bottom: 8rpx;
text-align: justify;
}
.notice-footer {
padding: 30rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
}
.back-btn{
width: 48%;
height: 88rpx;
line-height: 88rpx;
background: #fff;
color: #C4121B;
font-size: 32rpx;
border-radius: 44rpx;
border: 1rpx solid #C4121B;
}
.agree-btn {
width: 48%;
height: 88rpx;
line-height: 88rpx;
background: #C4121B;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
border: none;
&::after {
border: none;
}
}
</style>
<template>
<view class="notice-page">
<view class="notice-content">
<view class="notice-body">
<view class="section">中国跆拳道协会团体会员入会须知</view>
<view class="section ">
<view class="section-text">欢迎您申请成为中国跆拳道协会(以下简称中国跆协)团体会员。贵单位的入会申请应经过内部决策程序(如理事会决议或法定代表人决定),确认为自愿行为。请您在提交申请前,务必仔细阅读本入会须知,并确保申请材料真实、完整。</view>
</view>
<view class="section">
<view class="section-title">一、团体会员分类</view>
<view class="section-text">根据中国跆协相关规定,团体会员共分三类:区域性一级团体会员、区域性二级团体会员、专业性团体会员。</view>
</view>
<view class="section">
<view class="section-title">二、入会条件</view>
<view class="section-text">申请成为中国跆协团体会员,须具备以下条件:</view>
<view class="section-item">1. 承认章程:承认并拥护《中国跆拳道协会章程》及协会各项规章制度、决议。</view>
<view class="section-item">2. 合法资质:必须是经当地工商、民政或教育/体育行政部门登记注册,具有独立法人资格或能够独立承担民事责任的合法机构。</view>
<view class="section-item">3. 组织健全:具有比较完善的章程、组织管理机构、固定的活动场所及相应的从业人员。</view>
<view class="section-item">4. 运营规范:在区域内具有一定影响力,能够行使会员权利,履行会员义务,支持中国跆拳道事业的发展。</view>
</view>
<view class="section">
<view class="section-title">三、入会程序</view>
<view class="section-text">团体会员入会实行"逐级审批、属地管理"原则:</view>
<view class="section-item">1. 提交申请:向所属行政区域的上一级中国跆协团体会员提交入会申请书及相关资质材料。</view>
<view class="section-item sub">专业性团体会员(如道馆、俱乐部):通常向所在地的"区域性二级团体会员"(市级协会)提交申请。</view>
<view class="section-item sub">区域性二级团体会员:向所在地的"区域性一级团体会员"(省级协会)提交申请。</view>
<view class="section-item sub">无上级协会的:如当地暂无相应级别团体会员,可直接向中国跆拳道协会或上一级协会提交申请。</view>
<view class="section-item">2. 审核批准:由受理申请的团体会员进行资格审查和实地考察,并报中国跆协备案。</view>
<view class="section-item">3. 缴纳会费:审核通过后,按年度标准缴纳会费。</view>
<view class="section-item">4. 颁发证书:由中国跆协或授权的团体会员颁发统一制作的"团体会员证书"。</view>
</view>
<view class="section">
<view class="section-title">四、会费标准</view>
<view class="section-text">团体会员须按年度缴纳会费。具体标准依据《中国跆拳道协会会员会费标准》执行(注:具体金额请以中国跆协官方最新文件为准)。</view>
</view>
<view class="section">
<view class="section-title">五、会员权利</view>
<view class="section-text">团体会员享有《中国跆拳道协会会员管理办法》规定的以下主要权利:</view>
<view class="section-item">1. 本团体的选举权、被选举权和表决权。</view>
<view class="section-item">2. 组织辖区内跆拳道活动的管理权(仅限区域性团体会员)。</view>
<view class="section-item">3. 参加中国跆协举办的赛事、培训、交流活动的优先权。</view>
<view class="section-item">4. 获得中国跆协在业务指导、教练员裁判员委派、级段位考试等方面的服务优先权。</view>
<view class="section-item">5. 对协会工作的批评建议权和监督权。</view>
</view>
<view class="section">
<view class="section-title">六、会员义务</view>
<view class="section-text">团体会员应履行以下主要义务:</view>
<view class="section-item">1. 遵守章程,执行协会决议,维护协会合法权益。</view>
<view class="section-item">2. 完成协会交办的工作,如组织参赛、数据统计、行业调研等。</view>
<view class="section-item">3. 按时足额缴纳会费。</view>
<view class="section-item">4. 定期向上级协会上报年度工作计划和总结。</view>
<view class="section-item">5. 积极宣传和推广跆拳道运动。</view>
</view>
<view class="section">
<view class="section-title">七、退会与违规处理</view>
<view class="section-item">1. 自动退会:团体会员如果一年不交纳会费或不参加本团体活动的,视为自动退会。退会后须交回会员证书。</view>
<view class="section-item">2. 违规处罚:会员行为若违反《会员管理办法》,如出现严重违规经营、损害协会声誉、拖欠应缴款项等行为,协会视情节轻重给予警告、限期整改、暂停会员资格直至取消会员资格的处罚。</view>
</view>
<view class="section">
<view class="section-title">八、其他</view>
<view class="section-item">1. 本须知内容依据《中国跆拳道协会章程》及《中国跆拳道协会会员管理办法(暂行)》制定。</view>
<view class="section-item">2. 团体会员在开展活动时,须严格遵守国家安全生产法律法规,落实赛事活动安全责任。</view>
<view class="section-item">3. 如有疑问,请咨询所在地的中国跆协区域性团体会员(省/市跆拳道协会)或登录中国跆拳道协会官网查询。</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
function goBack() {
uni.navigateBack()
}
</script>
<style lang="scss" scoped>
.notice-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
}
.notice-content {
flex: 1;
padding: 30rpx;
overflow-y: auto;
}
.notice-header {
padding: 40rpx 0;
text-align: center;
}
.notice-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.notice-body {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
}
.section {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
line-height: 1.5;
}
.section-text {
font-size: 28rpx;
color: #666;
line-height: 1.8;
text-align: justify;
margin-bottom: 16rpx;
}
.section-item {
font-size: 28rpx;
color: #666;
line-height: 1.8;
margin-bottom: 12rpx;
text-align: justify;
padding-left: 0;
&.sub {
padding-left: 40rpx;
color: #888;
font-size: 26rpx;
}
&:last-child {
margin-bottom: 0;
}
}
.notice-footer {
padding: 30rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
</style>
<template>
<view class="notice-page">
<view class="notice-content">
<view class="notice-body">
<view class="section">
<view class="section-title">尊敬的用户:</view>
<view class="section-text">欢迎您注册中国跆拳道协会会员管理系统。</view>
</view>
<view class="section">
<view class="section-title">一、注册信息</view>
<view class="section-text">根据系统要求及提示,在网上填写必要的个人用户或单位用户相关有效信息即可注册成功。</view>
</view>
<view class="section">
<view class="section-title">二、用户权限</view>
<view class="section-item">1)信息注册成功仅代表您同意将本人或本单位信息纳入到本系统内,并非中国跆拳道协会会员。</view>
<view class="section-item">2)注册用户如需办理相关业务需向所属单位或向上级协会提交缴费及入会申请,会员信息在有效期内方可使用相关功能。</view>
</view>
<view class="section">
<view class="section-title">三、责任</view>
<view class="section-item">1)用户须遵守国家法律法规。</view>
<view class="section-item">2)用户须按要求填写准确的个人及单位资料,如用户提供的资料包含有不正确的信息,本系统保留结束用户使用相关服务的权利。</view>
<view class="section-item">3)中国跆拳道协会承诺保守用户信息等秘密。</view>
</view>
<view class="section">
<view class="section-title">四、解释权说明</view>
<view class="section-text">以上内容最终解释权归中国跆拳道协会所有。</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
function goBack() {
uni.navigateBack()
}
</script>
<style lang="scss" scoped>
.notice-page {
min-height: 100vh;
background: #f5f5f5;
display: flex;
flex-direction: column;
}
.notice-content {
flex: 1;
padding: 30rpx;
overflow-y: auto;
}
.notice-header {
padding: 40rpx 0;
text-align: center;
}
.notice-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.notice-body {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
}
.section {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
line-height: 1.5;
}
.section-text {
font-size: 28rpx;
color: #666;
line-height: 1.8;
text-align: justify;
}
.section-item {
font-size: 28rpx;
color: #666;
line-height: 1.8;
margin-bottom: 12rpx;
text-align: justify;
padding-left: 0;
&:last-child {
margin-bottom: 0;
}
}
.notice-footer {
padding: 30rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
</style>
<template>
<view class="member-audit-record">
<!-- Tab切换 -->
<view class="tab-bar">
<view
v-for="tab in tabs"
:key="tab.value"
class="tab-item"
:class="{ active: currentTab === tab.value }"
@click="onTabChange(tab.value)"
>
{{ tab.label }}
</view>
</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="list-item"
:class="{ 'success-row': item.approveStatus == 2 }"
>
<view class="item-header">
<text class="item-name">{{ item.name }}</text>
<text class="item-status" :class="getStatusClass(item.approveStatus)">
{{ getStatusText(item.approveStatus) }}
</text>
</view>
<view class="item-row">
<text class="item-label">证件类型</text>
<text class="item-value">{{ getIdcTypeText(item.idcType) }}</text>
</view>
<view class="item-row">
<text class="item-label">证件号</text>
<text class="item-value">{{ item.idcCode || '-' }}</text>
</view>
<view class="item-row">
<text class="item-label">提交单位</text>
<text class="item-value">{{ item.memName || '-' }}</text>
</view>
<view class="item-row">
<text class="item-label">提交时间</text>
<text class="item-value">{{ formatDate(item.commitTime) }}</text>
</view>
<view class="item-row">
<text class="item-label">审核时间</text>
<text class="item-value">{{ formatDate(item.approveTime) }}</text>
</view>
<view v-if="item.msg" class="item-row">
<text class="item-label">备注</text>
<text class="item-value">{{ item.msg }}</text>
</view>
<view v-if="item.fileUrl" class="item-row">
<text class="item-label">附件</text>
<image
class="item-image"
:src="fillImgUrl(item.fileUrl)"
mode="aspectFill"
@click="previewImage(item.fileUrl)"
></image>
</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, onReachBottom } from '@dcloudio/uni-app'
import { memberAuditList } from '@/common/api'
import config from '@/config'
const tabs = [
{ label: '全部', value: '' },
{ label: '审核中', value: '1' },
{ label: '审核通过', value: '2' },
{ label: '审核拒绝', value: '3' }
]
const currentTab = ref('')
const list = ref([])
const loading = ref(false)
const noMore = ref(false)
const pageNum = ref(1)
const pageSize = ref(10)
function onTabChange(value) {
currentTab.value = value
list.value = []
pageNum.value = 1
noMore.value = false
loadData()
}
function loadData() {
if (loading.value) return
loading.value = true
memberAuditList({
pageNum: pageNum.value,
pageSize: pageSize.value,
approveStatus: currentTab.value
}).then(res => {
if (res.rows) {
if (pageNum.value === 1) {
list.value = res.rows
} else {
list.value = [...list.value, ...res.rows]
}
if (res.rows.length < pageSize.value) {
noMore.value = true
}
} else {
if (pageNum.value === 1) {
list.value = []
}
noMore.value = true
}
}).finally(() => {
loading.value = false
})
}
// 上划加载
onReachBottom(() => {
if (!noMore.value) {
pageNum.value++
loadData()
}
})
onLoad(() => {
loadData()
})
function getStatusText(status) {
const map = { 1: '审核中', 2: '审核通过', 3: '审核拒绝' }
return map[status] || '-'
}
function getStatusClass(status) {
return {
'status-1': status == 1,
'status-2': status == 2,
'status-3': status == 3
}
}
function getIdcTypeText(type) {
const map = {
1: '身份证',
2: '护照',
3: '军官证',
4: '港澳通行证',
5: '台湾通行证'
}
return map[type] || '-'
}
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}`
}
function fillImgUrl(url) {
if (!url) return ''
if (url.startsWith('http')) return url
return config.baseUrl + url
}
function previewImage(url) {
uni.previewImage({
urls: [fillImgUrl(url)],
current: fillImgUrl(url)
})
}
</script>
<style lang="scss" scoped>
.member-audit-record {
min-height: 100vh;
background: #f5f5f5;
}
.tab-bar {
display: flex;
background: #fff;
padding: 0 20rpx;
border-bottom: 1rpx solid #eee;
}
.tab-item {
flex: 1;
height: 88rpx;
line-height: 88rpx;
text-align: center;
font-size: 28rpx;
color: #666;
position: relative;
}
.tab-item.active {
color: #e64329;
font-weight: 600;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 4rpx;
background: #e64329;
border-radius: 2rpx;
}
.list-content {
padding: 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-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.item-name {
font-size: 32rpx;
font-weight: 600;
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;
}
.item-row {
display: flex;
margin-bottom: 16rpx;
}
.item-label {
width: 140rpx;
font-size: 26rpx;
color: #999;
}
.item-value {
flex: 1;
font-size: 26rpx;
color: #333;
word-break: break-all;
}
.item-image {
width: 120rpx;
height: 120rpx;
border-radius: 8rpx;
margin-top: 8rpx;
}
</style>
......@@ -186,7 +186,7 @@ const getStatusText = (status) => {
1: '缴费成功',
2: '订单取消'
};
return map[status] || '未知状态';
return map[status] || '';
};
// 数据请求核心方法
......
......@@ -291,7 +291,7 @@ function getStatusText(status) {
3: '审核拒绝',
9: '缴费中'
}
return statusMap[status] || '未知状态'
return statusMap[status] || ''
}
function getStatusClass(status) {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!