dc453c5f by 华明祺

feat: 优化会员认证和支付流程

- App.vue: 添加 globalData 初始化,修复选择证件照后跳转登录页的问题
- common/api.js: certifiedNew 接口改为 URL 参数传参
- myCenter/goPay.vue: 使用 await-to-js 重构支付逻辑,添加 loading 状态
- myCenter/sucPay.vue: 接收 orderId 参数,通过接口获取订单信息并展示
- personal/sucPay.vue: 调整订单信息字段绑定
- config.js: 更新 API 基础地址
1 parent 87d7b854
<script>
import {
getInfo
} from '@/common/login.js';
import * as api from '@/common/api.js';
import config from '@/config.js';
import {
getInfo
} from '@/common/login.js';
import * as api from '@/common/api.js';
import config from '@/config.js';
let loginUrl=['login/login', 'login/register']
let firstload = false
export default {
onLaunch: function(options) {
console.log('App Launch', options);
let loginUrl = ['login/login', 'login/register', 'personal/addVip_per']
let firstload = false
export default {
globalData: {
isLogin: false,
baseUrl_api: '',
user: null,
userType: '',
userInfo: null,
deptType: '',
genFlag: '',
authenticationStatus: '',
memberInfo: null,
isExam: false
},
onLaunch: function(options) {
console.log('App Launch', options);
this.globalData.baseUrl_api = config.baseUrl_api;
if(loginUrl.indexOf(options.path)==-1){
let userName = uni.getStorageSync('userName')
if (userName) {
getInfo().then(() => {
this.globalData.isLogin = true;
firstload = true
let firstLoadCallback = getApp().firstLoadCallback;
if (firstLoadCallback) {
firstLoadCallback();
}
}).catch(() => {
firstload = true
uni.redirectTo({
url: '/login/login'
})
})
} else {
this.globalData.isLogin = false;
firstload = true
uni.redirectTo({
url: '/login/login'
})
}
}
},
onShow: function() {
console.log('App Show',firstload,this.globalData.isLogin);
if(firstload&&!this.globalData.isLogin){
uni.redirectTo({
url: '/login/login'
})
}
},
onHide: function() {
console.log('App Hide');
}
};
this.globalData.baseUrl_api = config.baseUrl_api;
if (loginUrl.indexOf(options.path) == -1) {
let userName = uni.getStorageSync('userName')
if (userName) {
getInfo().then(() => {
this.globalData.isLogin = true;
firstload = true
let firstLoadCallback = getApp().firstLoadCallback;
if (firstLoadCallback) {
firstLoadCallback();
}
}).catch(() => {
firstload = true
uni.redirectTo({
url: '/login/login'
})
})
} else {
this.globalData.isLogin = false;
firstload = true
uni.redirectTo({
url: '/login/login'
})
}
}
},
onShow: function() {
console.log('App Show', firstload, this.globalData.isLogin);
// if (firstload && !this.globalData.isLogin) {
// uni.redirectTo({
// url: '/login/login'
// })
// }
},
onHide: function() {
console.log('App Hide');
}
};
</script>
<style lang="scss">
......
......@@ -1306,11 +1306,10 @@ export function checkBusinessLicense(data) {
}
// 生成团体订单renewYear
export function certifiedNew(params) {
export function certifiedNew(renewYear) {
return request({
url: `/system/certifiedNew/commit`,
method: 'post',
params
url: `/system/certifiedNew/commit?renewYear=${renewYear}`,
method: 'post'
})
}
......
......@@ -5,11 +5,11 @@
// staging 会员系统
// const baseUrl_api = "http://22yidpjzjifv.ngrok.xiaomiqiu123.top/stage-api/";
// const baseUrl_api = "https://ztx.itechtop.cn:8443/stage-api";
const baseUrl_api = 'http://192.168.1.189:8788'
const baseUrl_api = 'http://192.168.1.189:8787'
// const baseUrl_api = 'https://tkcn.19wk.cn:8443/stage-api'
// const baseUrl_api = 'http://tk004.wxjylt.com/stage-api'
// const baseUrl_api = 'https://system.taekwondo.org.cn/stage-api'
export default {
baseUrl_api
}
baseUrl_api
}
\ No newline at end of file
......
<template>
<view :class="{ 'lock-scroll': popupShow }">
<view v-if="showDirectly&&directUnderFlag==0">
<view class="flexbox">
<view>
有效日期至 <text class="text-primary">{{form?.validityDate?.slice(0,10) }}</text>
</view>
<view>
<text v-if="activeStatus==0&&authenticationStatusa" class="text-danger">未激活</text>
<text v-else>
<text v-if="authenticationStatusa == 0 ||!authenticationStatusa" class="text-danger">未认证</text>
<text v-if="authenticationStatusa == 1" class="text-success">认证中</text>
<text v-if="authenticationStatusa == 2" class="text-success">已认证</text>
<text v-if="authenticationStatusa == 3" class="text-danger">认证未通过</text>
<text v-if="authenticationStatusa == 4" class="text-danger">即将过期</text>
<text v-if="authenticationStatusa == 5" class="text-danger">已过期</text>
</text>
</view>
</view>
<view class="flexbox" style="justify-content: flex-end;padding: 0 30rpx 40rpx;">
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini"
v-if="activeStatus==0&&authenticationStatusa" @click="payTheFees">激活</button>
<view v-else >
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="auditStatus==1||auditStatus==2||form.isPoints==0"
@click="showApplyDialog">考点申请</button>
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="btn"
@click="payTheFees">去缴费</button>
<button class="btn-red-kx" style="margin: 0 20rpx 0 0;" size="mini" v-if="form.deptType!=1"
@click="auditEditFN">审核详情</button>
</view>
</view>
</view>
<view class="mainbox">
<uni-list>
<uni-list-item v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3"
title="所属协会" :rightText="form.aname">
</uni-list-item>
<uni-list-item title="会员编号" v-if="form.menCode" :rightText="form.menCode" />
<uni-list-item title="机构名称" :rightText="form.name" />
<uni-list-item title="所属省份">
<template v-slot:footer>
<view class="frrr">
<uni-data-picker readonly :clear-icon="false"
v-model="form.belongProvinceId" :localdata="options">
</uni-data-picker>
</view>
</template>
</uni-list-item>
<uni-list-item title="社会信用代码"
v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3&&newResult||form.associateId&&form.associateId>0||activeStatus==1"
:rightText="form.creditCode" />
<uni-list-item v-if="form.certSiteContact" title="联系人" :rightText="form.certSiteContact" />
<uni-list-item v-else title="联系人" :rightText="form.contact" />
<uni-list-item v-if="form.certSiteTel" title="联系方式" :rightText="form.certSiteTel" />
<uni-list-item v-else title="联系方式" :rightText="form.phone" />
<uni-list-item title="认证地址">
<template v-slot:footer>
<view class="frrr">
<uni-data-picker readonly :clear-icon="false" v-if="form.certRegionId"
v-model="form.certRegionId" :localdata="options">
</uni-data-picker>
<uni-data-picker readonly :clear-icon="false" v-else-if="form.certCityId"
v-model="form.certCityId" :localdata="options">
</uni-data-picker>
<uni-data-picker readonly :clear-icon="false" v-else-if="form.certProvinceId"
v-model="form.certProvinceId" :localdata="options">
</uni-data-picker>
</view>
</template>
</uni-list-item>
<uni-list-item title="认证详细地址" :rightText="form.certAddress" />
<uni-list-item title="法人姓名" :rightText="form.certLegal||'--'" />
<uni-list-item v-if="form.deptType==6" title="是否为考点" :rightText="form.isPoints==0?'是':'否'" />
<uni-list-item title="法人身份证" clickable>
<template v-slot:footer>
<view v-if="form.legalIdcPhotoArr&&form.legalIdcPhotoArr?.length>0" class="frrr">
<image class="ylImage" mode="aspectFit" @click="showImage(form.legalIdcPhotoArr,index)"
v-for="(item,index) in form.legalIdcPhotoArr" :key="item" :src="item">
</image>
</view>
</template>
</uni-list-item>
<uni-list-item title="营业执照" clickable>
<template v-slot:footer>
<view class="frrr" @click="download(form.businessLicenseArr[0]?.url)"
v-if="form.businessLicenseArr&&form.businessLicenseArr?.length>0">
<text class="text-primary">{{form.businessLicenseArr[0]?.name}}</text>
</view>
</template>
</uni-list-item>
<uni-list-item title="机构照片" clickable>
<template v-slot:footer >
<view class="frrr">
<view v-if="form.picturesArr&&form.picturesArr?.length>0" class="photoBook"
@click="showImage(form.picturesArr,0)">
<image mode="aspectFit" class="ylImage" :src="form.picturesArr[0]">
</image>
<text>{{form.picturesArr?.length}}</text>
</view>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
<!-- 弹窗添加触摸事件拦截 -->
<uni-popup ref="applyPopup" type="center"
@touchmove.stop.prevent="() => {}"
@open="onPopupOpen"
@close="onPopupClose">
<view class="apply-dialog" @touchmove.stop.prevent="() => {}">
<view class="dialog-title">考点申请</view>
<view class="dialog-content">
<text class="remind">友情提示:非考点无法申请级位考试</text>
</view>
<view class="dialog-buttons">
<button class="btn-cancel" @click="closeApplyDialog">暂不申请</button>
<button class="btn-confirm" @click="goToApplyPage">立即申请</button>
</view>
</view>
</uni-popup>
<view class="height1"></view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import * as loginServer from '@/common/login.js';
import _ from 'underscore'
import {
ref, onUnmounted
} from 'vue'
import {
onLoad,onShow
} from '@dcloudio/uni-app'
const app = getApp()
const form = ref({
type: 1
})
const userType = ref()
const activeStatus = ref(0)
const directUnderFlag = ref(0)
const showDirectly = ref(true)
const authenticationStatusa = ref()
const result = ref(false)
const newResult = ref(false)
const btn = ref(false)
const type = ref(true)
const flag = ref(false)
const pr = ref({})
const applicationForMembership1 = ref({})
const options = ref([])
const applyPopup = ref(null)
// 新增:控制弹窗显示状态(用于锁定滚动)
const popupShow = ref(false)
// 考点审核状态 0 未提交 1 审核中 2 审核成功 3 审核失败
const auditStatus = ref(0)
onShow(() => {
init()
if (form.value.deptType != 1) { // 修复:原代码deptType未定义,改为form.value.deptType
getMyStatusAPI()
}
})
// 页面卸载时恢复滚动(防止异常锁死)
onUnmounted(() => {
uni.setPageScrollEnabled({ enabled: true })
popupShow.value = false
})
function init() {
api.regionsList().then(res => {
options.value = res.data
})
api.getMyOwnMemberInfo().then(res => {
console.log(res)
userType.value = app.globalData.userType
newResult.value = res.data.newResult
result.value = res.data.result
authenticationStatusa.value = res.data.authenticationStatus
showDirectly.value = !res.data.memberInfo.associateId
activeStatus.value = res.data.memberInfo.activeStatus
pr.value = res.data.pr
directUnderFlag.value = res.data.memberInfo.directUnderFlag
if (authenticationStatusa.value == 0) {
btn.value = false
} else if (authenticationStatusa.value == 1) {
btn.value = true
} else {
btn.value = !result.value
}
// 认证信息
if (authenticationStatusa.value == 0 || authenticationStatusa.value == 3) {
type.value = false
}
// 至少审核通过一次
if (authenticationStatusa.value != 0) {
if (newResult.value) {
// 至少认证过一次
flag.value = true
}
}
if (!res.data.memberInfo) {
res.data.memberInfo = {}
}
if (!res.data.dept) {
res.data.dept = {}
}
form.value = {
...res.data.dept,
...res.data.memberInfo
}
// 入会材料
if (form.value.materials) {
form.value.materials1 = JSON.parse(form.value.materials)
}
// 入会申请书
if (form.value.applicationForMembership) {
form.value.applicationForMembership1 = JSON.parse(form.value.applicationForMembership)
}
applicationForMembership1.value = form.value.applicationForMembership || []
form.value.deptType = res.data.dept.deptType
if (form.value.businessLicense) {
form.value.businessLicenseArr = []
try{
form.value.businessLicenseArr = JSON.parse(form.value.businessLicense) || []
}catch(e){
form.value.businessLicenseArr=[{url:form.value.businessLicense,name:'营业执照'}]
}
console.log('营业执照',form.value.businessLicenseArr)
}
if (form.value.certLegalIdcPhoto && form.value.certLegalIdcPhoto!=null) {
form.value.legalIdcPhotoArr = []
var arr = form.value.certLegalIdcPhoto?.split(',') || []
if (arr.length > 0) {
arr = _.map(arr, (p) => {
if(p.indexOf('http')==-1){
console.log(p)
p = config.baseUrl_api + p
}
return p
})
form.value.legalIdcPhotoArr = arr
}
console.log('法人身份证',form.value.legalIdcPhotoArr)
}
if (form.value.certPictures) {
form.value.picturesArr = []
var arr = form.value.certPictures.split(',') || []
if (arr.length > 0) {
arr = _.map(arr, (p) => {
if(p.indexOf('http')==-1){
p = config.baseUrl_api + p
}
return p
})
form.value.picturesArr = arr
}
console.log(form.value.picturesArr)
}
})
}
async function getMyStatusAPI() {
const { data } = await api.getMyStatus()
if (data && data.auditStatus) {
auditStatus.value = data.auditStatus
} else {
auditStatus.value = 0
}
}
// 新增:弹窗打开时锁定滚动
function onPopupOpen() {
popupShow.value = true
// 1. 小程序API锁定页面滚动
uni.setPageScrollEnabled({ enabled: false })
// 延时兜底(防止API生效延迟)
setTimeout(() => {
uni.setPageScrollEnabled({ enabled: false })
}, 100)
}
// 新增:弹窗关闭时恢复滚动
function onPopupClose() {
popupShow.value = false
// 恢复页面滚动
uni.setPageScrollEnabled({ enabled: true })
setTimeout(() => {
uni.setPageScrollEnabled({ enabled: true })
}, 100)
}
function showApplyDialog() {
applyPopup.value.open()
}
// 关闭申请弹窗
function closeApplyDialog() {
applyPopup.value.close()
}
// 跳转到考点申请页面
function goToApplyPage() {
closeApplyDialog()
uni.navigateTo({
url: `/myCenter/examPointApply?memId=${form.value.memId}`
})
}
function auditEditFN() {
uni.navigateTo({
url: `/myCenter/reviewList`
})
}
function showImage(arr, index) {
uni.previewImage({
urls: arr,
current: index,
success: function(res) {}
})
}
function download(url) {
console.log(url)
if (url.indexOf('.png') > -1 || url.indexOf('.jpg') > -1) {
if(url.indexOf('http')>-1){
uni.previewImage({
urls: [url],
success: function(res) {}
})
} else {
uni.previewImage({
urls: [config.baseUrl_api + url],
success: function(res) {}
})
}
} else {
if(url.indexOf('http')>-1){
goWebView(url)
} else {
goWebView(config.baseUrl_api + url)
}
}
}
function goWebView(url) {
url = url.replace("http://", "https://")
uni.showLoading({
title: '下载中'
});
uni.downloadFile({
url: url,
success: function(res) {
uni.hideLoading();
var filePath = res.tempFilePath;
uni.showLoading({
title: '正在打开'
});
uni.openDocument({
filePath: filePath,
showMenu: true,
success: function(res) {
uni.hideLoading();
},
fail: function(err) {
uni.hideLoading();
uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
}
});
},
fail: function(error) {
uni.hideLoading();
uni.showToast({
title: `下载失败`,
icon: 'none',
duration: 2000
});
}
});
}
function payTheFees(){
if (!form.value.name) {
uni.showToast({
title: `请先完善团体信息`,
icon: 'none'
});
return; // 新增:防止无名称时跳转
}
uni.navigateTo({
url:`/myCenter/perfect`
})
}
</script>
<style scoped lang="scss">
// 新增:锁定滚动的核心样式
.lock-scroll {
position: fixed !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden !important;
height: 100vh !important;
}
.height1{height: 100rpx;}
.photobox {
position: relative;
margin: 30rpx auto;
.photo {
width: 210rpx;
height: 280rpx;
background-color: #f4f4f4;
display: block;
margin: auto;
}
}
.ylImage {
width: 300rpx;
height: 200rpx;
display: block;
box-shadow: 0 0 10rpx #ddd;
border-radius: 8rpx;
}
.photoBook{position: relative;border-radius: 10rpx; overflow: hidden;
&::after{content: '';position: absolute;width: 100%;height: 100%;top: 0;left: 0;
background: linear-gradient(180deg,rgba(0, 0, 0, 0),rgba(0, 0, 0, 0.7));
}
text{ position: absolute;z-index: 1;
font-size: 24rpx;
color: #fff;
bottom: 4rpx;
right: 8rpx;}
}
.frrr{width: 100%;text-align: right;
text-align: right;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;}
:deep(.selected-list){font-size: 32rpx;padding: 0;}
:deep(.input-value){padding: 0;}
:deep(.uni-list-item__extra-text) {
font-size: 32rpx;color: #000;
}
:deep(.uni-list-item__extra) {
flex: 1 1 auto;
}
:deep(.uni-list-item__content) {
flex: 0 0 auto;
}
:deep(.uni-list-item__content-title) {
color: #999;
}
.flexbox {
padding: 30rpx;
background-color: #fff;
justify-content: space-between;
}
.mainbox {
margin: 30rpx;
}
.apply-dialog {
width: 530rpx;
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
// 新增:禁止弹窗内部滚动
touch-action: none;
}
.dialog-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.dialog-content {
margin: 40rpx;
}
.remind {
color: #FF8124;
font-size: 26rpx;
margin-top: 40rpx;
}
.dialog-buttons {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
}
.btn-cancel {
width: 225rpx;
height: 80rpx;
line-height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 40rpx;
background: #fff;
color: #333;
text-align: center;
font-size: 14px;
}
.btn-confirm {
width: 225rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
background: #C4121B;
font-size: 14px;
color: #fff;
text-align: center;
}
// 新增:给uni-popup蒙版添加禁止滚动样式
:deep(.uni-popup__mask) {
touch-action: none !important;
}
<template>
<view :class="{ 'lock-scroll': popupShow }">
<view v-if="showDirectly&&directUnderFlag==0">
<view class="flexbox">
<view>
有效日期至 <text class="text-primary">{{form?.validityDate?.slice(0,10) }}</text>
</view>
<view>
<text v-if="activeStatus==0&&authenticationStatusa" class="text-danger">未激活</text>
<text v-else>
<text v-if="authenticationStatusa == 0 ||!authenticationStatusa" class="text-danger">未认证</text>
<text v-if="authenticationStatusa == 1" class="text-success">认证中</text>
<text v-if="authenticationStatusa == 2" class="text-success">已认证</text>
<text v-if="authenticationStatusa == 3" class="text-danger">认证未通过</text>
<text v-if="authenticationStatusa == 4" class="text-danger">即将过期</text>
<text v-if="authenticationStatusa == 5" class="text-danger">已过期</text>
</text>
</view>
</view>
<view class="flexbox" style="justify-content: flex-end;padding: 0 30rpx 40rpx;">
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini"
v-if="activeStatus==0&&authenticationStatusa" @click="payTheFees">激活</button>
<view v-else>
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini"
:disabled="auditStatus==1||auditStatus==2||form.isPoints==0"
@click="showApplyDialog">考点申请</button>
<button class="btn-red" style="margin: 0 20rpx 0 0;" size="mini" :disabled="btn"
@click="payTheFees">去缴费</button>
<button class="btn-red-kx" style="margin: 0 20rpx 0 0;" size="mini" v-if="form.deptType!=1"
@click="auditEditFN">审核详情</button>
</view>
</view>
</view>
<view class="mainbox">
<uni-list>
<uni-list-item v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3"
title="所属协会" :rightText="form.aname">
</uni-list-item>
<uni-list-item title="会员编号" v-if="form.menCode" :rightText="form.menCode" />
<uni-list-item title="机构名称" :rightText="form.name" />
<uni-list-item title="所属省份">
<template v-slot:footer>
<view class="frrr">
<uni-data-picker readonly :clear-icon="false" v-model="form.belongProvinceId"
:localdata="options">
</uni-data-picker>
</view>
</template>
</uni-list-item>
<uni-list-item title="社会信用代码"
v-if="authenticationStatusa != 1&&authenticationStatusa != 0&&authenticationStatusa != 3&&newResult||form.associateId&&form.associateId>0||activeStatus==1"
:rightText="form.creditCode" />
<uni-list-item v-if="form.certSiteContact" title="联系人" :rightText="form.certSiteContact" />
<uni-list-item v-else title="联系人" :rightText="form.contact" />
<uni-list-item v-if="form.certSiteTel" title="联系方式" :rightText="form.certSiteTel" />
<uni-list-item v-else title="联系方式" :rightText="form.phone" />
<uni-list-item title="认证地址">
<template v-slot:footer>
<view class="frrr">
<uni-data-picker readonly :clear-icon="false" v-if="form.certRegionId"
v-model="form.certRegionId" :localdata="options">
</uni-data-picker>
<uni-data-picker readonly :clear-icon="false" v-else-if="form.certCityId"
v-model="form.certCityId" :localdata="options">
</uni-data-picker>
<uni-data-picker readonly :clear-icon="false" v-else-if="form.certProvinceId"
v-model="form.certProvinceId" :localdata="options">
</uni-data-picker>
</view>
</template>
</uni-list-item>
<uni-list-item title="认证详细地址" :rightText="form.certAddress" />
<uni-list-item title="法人姓名" :rightText="form.certLegal||'--'" />
<uni-list-item v-if="form.deptType==6" title="是否为考点" :rightText="form.isPoints==0?'是':'否'" />
<uni-list-item title="法人身份证" clickable>
<template v-slot:footer>
<view v-if="form.legalIdcPhotoArr&&form.legalIdcPhotoArr?.length>0" class="frrr">
<image class="ylImage" mode="aspectFit" @click="showImage(form.legalIdcPhotoArr,index)"
v-for="(item,index) in form.legalIdcPhotoArr" :key="item" :src="item">
</image>
</view>
</template>
</uni-list-item>
<uni-list-item title="营业执照" clickable>
<template v-slot:footer>
<view class="frrr" @click="download(form.businessLicenseArr[0]?.url)"
v-if="form.businessLicenseArr&&form.businessLicenseArr?.length>0">
<text class="text-primary">{{form.businessLicenseArr[0]?.name}}</text>
</view>
</template>
</uni-list-item>
<uni-list-item title="机构照片" clickable>
<template v-slot:footer>
<view class="frrr">
<view v-if="form.picturesArr&&form.picturesArr?.length>0" class="photoBook"
@click="showImage(form.picturesArr,0)">
<image mode="aspectFit" class="ylImage" :src="form.picturesArr[0]">
</image>
<text>{{form.picturesArr?.length}}</text>
</view>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
<!-- 弹窗添加触摸事件拦截 -->
<uni-popup ref="applyPopup" type="center" @touchmove.stop.prevent="() => {}" @open="onPopupOpen"
@close="onPopupClose">
<view class="apply-dialog" @touchmove.stop.prevent="() => {}">
<view class="dialog-title">考点申请</view>
<view class="dialog-content">
<text class="remind">友情提示:非考点无法申请级位考试</text>
</view>
<view class="dialog-buttons">
<button class="btn-cancel" @click="closeApplyDialog">暂不申请</button>
<button class="btn-confirm" @click="goToApplyPage">立即申请</button>
</view>
</view>
</uni-popup>
<view class="height1"></view>
</view>
</template>
<script setup>
import * as api from '@/common/api.js'
import config from '@/config.js'
import * as loginServer from '@/common/login.js';
import _ from 'underscore'
import {
ref,
onUnmounted
} from 'vue'
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const app = getApp()
const form = ref({
type: 1
})
const userType = ref()
const activeStatus = ref(0)
const directUnderFlag = ref(0)
const showDirectly = ref(true)
const authenticationStatusa = ref()
const result = ref(false)
const newResult = ref(false)
const btn = ref(false)
const type = ref(true)
const flag = ref(false)
const pr = ref({})
const applicationForMembership1 = ref({})
const options = ref([])
const applyPopup = ref(null)
// 新增:控制弹窗显示状态(用于锁定滚动)
const popupShow = ref(false)
// 考点审核状态 0 未提交 1 审核中 2 审核成功 3 审核失败
const auditStatus = ref(0)
onShow(() => {
init()
if (form.value.deptType != 1) { // 修复:原代码deptType未定义,改为form.value.deptType
getMyStatusAPI()
}
})
// 页面卸载时恢复滚动(防止异常锁死)
onUnmounted(() => {
uni.setPageScrollEnabled({
enabled: true
})
popupShow.value = false
})
function init() {
api.regionsList().then(res => {
options.value = res.data
})
api.getMyOwnMemberInfo().then(res => {
console.log(res)
userType.value = app.globalData.userType
newResult.value = res.data.newResult
result.value = res.data.result
authenticationStatusa.value = res.data.authenticationStatus
showDirectly.value = !res.data.memberInfo.associateId
activeStatus.value = res.data.memberInfo.activeStatus
pr.value = res.data.pr
directUnderFlag.value = res.data.memberInfo.directUnderFlag
if (authenticationStatusa.value == 0) {
btn.value = false
} else if (authenticationStatusa.value == 1) {
btn.value = true
} else {
btn.value = !result.value
}
// 认证信息
if (authenticationStatusa.value == 0 || authenticationStatusa.value == 3) {
type.value = false
}
// 至少审核通过一次
if (authenticationStatusa.value != 0) {
if (newResult.value) {
// 至少认证过一次
flag.value = true
}
}
if (!res.data.memberInfo) {
res.data.memberInfo = {}
}
if (!res.data.dept) {
res.data.dept = {}
}
form.value = {
...res.data.dept,
...res.data.memberInfo
}
// 入会材料
if (form.value.materials) {
form.value.materials1 = JSON.parse(form.value.materials)
}
// 入会申请书
if (form.value.applicationForMembership) {
form.value.applicationForMembership1 = JSON.parse(form.value.applicationForMembership)
}
applicationForMembership1.value = form.value.applicationForMembership || []
form.value.deptType = res.data.dept.deptType
if (form.value.businessLicense) {
form.value.businessLicenseArr = []
try {
form.value.businessLicenseArr = JSON.parse(form.value.businessLicense) || []
} catch (e) {
form.value.businessLicenseArr = [{
url: form.value.businessLicense,
name: '营业执照'
}]
}
console.log('营业执照', form.value.businessLicenseArr)
}
if (form.value.certLegalIdcPhoto && form.value.certLegalIdcPhoto != null) {
form.value.legalIdcPhotoArr = []
var arr = form.value.certLegalIdcPhoto?.split(',') || []
if (arr.length > 0) {
arr = _.map(arr, (p) => {
if (p.indexOf('http') == -1) {
console.log(p)
p = config.baseUrl_api + p
}
return p
})
form.value.legalIdcPhotoArr = arr
}
console.log('法人身份证', form.value.legalIdcPhotoArr)
}
if (form.value.certPictures) {
form.value.picturesArr = []
var arr = form.value.certPictures.split(',') || []
if (arr.length > 0) {
arr = _.map(arr, (p) => {
if (p.indexOf('http') == -1) {
p = config.baseUrl_api + p
}
return p
})
form.value.picturesArr = arr
}
console.log(form.value.picturesArr)
}
})
}
async function getMyStatusAPI() {
const {
data
} = await api.getMyStatus()
if (data && data.auditStatus) {
auditStatus.value = data.auditStatus
} else {
auditStatus.value = 0
}
}
// 新增:弹窗打开时锁定滚动
function onPopupOpen() {
popupShow.value = true
// 1. 小程序API锁定页面滚动
uni.setPageScrollEnabled({
enabled: false
})
// 延时兜底(防止API生效延迟)
setTimeout(() => {
uni.setPageScrollEnabled({
enabled: false
})
}, 100)
}
// 新增:弹窗关闭时恢复滚动
function onPopupClose() {
popupShow.value = false
// 恢复页面滚动
uni.setPageScrollEnabled({
enabled: true
})
setTimeout(() => {
uni.setPageScrollEnabled({
enabled: true
})
}, 100)
}
function showApplyDialog() {
applyPopup.value.open()
}
// 关闭申请弹窗
function closeApplyDialog() {
applyPopup.value.close()
}
// 跳转到考点申请页面
function goToApplyPage() {
closeApplyDialog()
uni.navigateTo({
url: `/myCenter/examPointApply?memId=${form.value.memId}`
})
}
function auditEditFN() {
uni.navigateTo({
url: `/myCenter/reviewList`
})
}
function showImage(arr, index) {
uni.previewImage({
urls: arr,
current: index,
success: function(res) {}
})
}
function download(url) {
console.log(url)
if (url.indexOf('.png') > -1 || url.indexOf('.jpg') > -1) {
if (url.indexOf('http') > -1) {
uni.previewImage({
urls: [url],
success: function(res) {}
})
} else {
uni.previewImage({
urls: [config.baseUrl_api + url],
success: function(res) {}
})
}
} else {
if (url.indexOf('http') > -1) {
goWebView(url)
} else {
goWebView(config.baseUrl_api + url)
}
}
}
function goWebView(url) {
url = url.replace("http://", "https://")
uni.showLoading({
title: '下载中'
});
uni.downloadFile({
url: url,
success: function(res) {
uni.hideLoading();
var filePath = res.tempFilePath;
uni.showLoading({
title: '正在打开'
});
uni.openDocument({
filePath: filePath,
showMenu: true,
success: function(res) {
uni.hideLoading();
},
fail: function(err) {
uni.hideLoading();
uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
}
});
},
fail: function(error) {
uni.hideLoading();
uni.showToast({
title: `下载失败`,
icon: 'none',
duration: 2000
});
}
});
}
function payTheFees() {
if (!form.value.name) {
uni.showToast({
title: `请先完善团体信息`,
icon: 'none'
});
return; // 新增:防止无名称时跳转
}
uni.navigateTo({
url: `/myCenter/perfect`
})
}
</script>
<style scoped lang="scss">
// 新增:锁定滚动的核心样式
.lock-scroll {
position: fixed !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden !important;
height: 100vh !important;
}
.height1 {
height: 100rpx;
}
.photobox {
position: relative;
margin: 30rpx auto;
.photo {
width: 210rpx;
height: 280rpx;
background-color: #f4f4f4;
display: block;
margin: auto;
}
}
.ylImage {
width: 300rpx;
height: 200rpx;
display: block;
box-shadow: 0 0 10rpx #ddd;
border-radius: 8rpx;
}
.photoBook {
position: relative;
border-radius: 10rpx;
overflow: hidden;
&::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.7));
}
text {
position: absolute;
z-index: 1;
font-size: 24rpx;
color: #fff;
bottom: 4rpx;
right: 8rpx;
}
}
.frrr {
width: 100%;
text-align: right;
text-align: right;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
}
:deep(.selected-list) {
font-size: 32rpx;
padding: 0;
}
:deep(.input-value) {
padding: 0;
}
:deep(.uni-list-item__extra-text) {
font-size: 32rpx;
color: #000;
}
:deep(.uni-list-item__extra) {
flex: 1 1 auto;
}
:deep(.uni-list-item__content) {
flex: 0 0 auto;
}
:deep(.uni-list-item__content-title) {
color: #999;
}
.flexbox {
padding: 30rpx;
background-color: #fff;
justify-content: space-between;
}
.mainbox {
margin: 30rpx;
}
.apply-dialog {
width: 530rpx;
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
// 新增:禁止弹窗内部滚动
touch-action: none;
}
.dialog-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.dialog-content {
margin: 40rpx;
}
.remind {
color: #FF8124;
font-size: 26rpx;
margin-top: 40rpx;
}
.dialog-buttons {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
}
.btn-cancel {
width: 225rpx;
height: 80rpx;
line-height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 40rpx;
background: #fff;
color: #333;
text-align: center;
font-size: 14px;
}
.btn-confirm {
width: 225rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
background: #C4121B;
font-size: 14px;
color: #fff;
text-align: center;
}
// 新增:给uni-popup蒙版添加禁止滚动样式
:deep(.uni-popup__mask) {
touch-action: none !important;
}
</style>
\ No newline at end of file
......
<template>
<view class="container">
<view class="content">
<view class="card">
<view class="yearRow">
<view class="label">缴费年限</view>
<view class="control">
<image class="icon" @click="minusYear" src="/static/dd_02.png" mode="widthFix" v-if="form.renewYear > 1" ></image>
<image class="icon" src="/static/dd_02_g.png" mode="widthFix" v-else ></image>
<text class="num">{{ form.renewYear }}</text>
<image class="icon" src="/static/btn_03.png" mode="widthFix" @click="plusYear" v-if="form.renewYear < 5" ></image>
<image class="icon" src="/static/btn_03_g.png" mode="widthFix" v-else ></image>
</view>
</view>
</view>
<view class="card ">
<!-- 费用合计 -->
<view class="row ">
<text class="label">费用合计</text>
<text class="value red">{{ form.renewYear * memberFee }}</text>
</view>
<view class="hintRow" v-if="preferentialPolicy">
<text class="hintText">温馨提示:根据中国跆协{{ preferentialData.name || '优惠' }}政策减免一年费用,每个单位在政策有效期内只享受一次</text>
</view>
</view>
<view class="payRow ">
<radio-group @change="onPayTypeChange">
<label class="radioItem">
<radio value="1" :checked="payType === '1'" class="custom-radio" />
<view class="payInfo">
<image class="icon" src="/static/min.png" mode="widthFix"></image>
<text>民生付</text>
</view>
</label>
</radio-group>
</view>
<view class="totalRow ">
<text class="label">支付费用合计</text>
<text class="value redBig">{{ memberTotalFee }}</text>
</view>
</view>
<view class="bottomBtn">
<view class="deductRow">
<text class="label">减免费用</text>
<text class="value red">-{{ memberFee }}</text>
</view>
<button class="payBtn" @click="handelPay" :loading="isPaying">立即支付 ¥{{ memberTotalFee }}</button>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import * as api from '@/common/api.js'
const form = ref({
renewYear: 1
})
const memberFee = ref(0)
const preferentialPolicy = ref(false)
const preferentialData = ref({ name: '优惠' })
const payType = ref('1')
const isPaying = ref(false)
const memberTotalFee = computed(() => {
if (preferentialPolicy.value) {
return memberFee.value * form.value.renewYear - memberFee.value * 1
} else {
return memberFee.value * form.value.renewYear
}
})
// 年限减
const minusYear = () => {
if (form.value.renewYear > 1) {
form.value.renewYear--
}
}
// 年限加
const plusYear = () => {
if (form.value.renewYear < 6) {
form.value.renewYear++
}
}
// 支付方式切换
const onPayTypeChange = (e) => {
payType.value = e.detail.value
}
// 支付操作
const handelPay = async () => {
// if (memberTotalFee.value <= 0) return
isPaying.value = true
const { data } = await api.certifiedNew({ renewYear: form.value.renewYear })
isPaying.value = false
if (data.payFlag == 0) {
uni.navigateTo({
url: `/myCenter/sucPay`
})
} else {
if (data.orderId) {
api.callBack2(data.orderId)
uni.navigateTo({
url: `/myCenter/sucPay`
})
}
}
}
onLoad((option) => {
// 接收年限
form.value.renewYear = Number(option.renewYear || 1)
// 初始化获取费用和优惠
init()
})
// 初始化接口
async function init() {
try {
await getMyMemberCertUnitFeeApi()
await canUseDiscountApi()
await getZtxDiscountPolicyApi()
} catch (err) {
console.error('初始化失败:', err)
}
}
// 获取会员单价
async function getMyMemberCertUnitFeeApi() {
const res = await api.getMyMemberCertUnitFee()
memberFee.value = Number(res.data || 1500)
}
// 是否可用优惠
async function canUseDiscountApi() {
const res = await api.canUseDiscount()
preferentialPolicy.value = res.data || true
}
// 获取优惠政策详情
async function getZtxDiscountPolicyApi() {
const res = await api.getZtxDiscountPolicy()
preferentialData.value = res.data || { name: '优惠' }
}
</script>
<style scoped>
/* 整体容器 */
.container {
min-height: 100vh;
background-color: #f7f7f7;
}
/* 内容区域 */
.content {
padding: 20rpx 20rpx 120rpx;
}
/* 卡片 */
.card {
background: #fff;
border-radius: 8rpx;
padding: 25rpx 20rpx;
margin-bottom: 20rpx;
}
/* 缴费年限行 */
.yearRow {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.yearRow .label {
font-size: 28rpx;
color: #333;
}
.yearRow .control {
display: flex;
align-items: center;
}
.control image {
width: 50rpx;
height: 50rpx;
}
/* 加减按钮样式 */
.num-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
border: 1rpx solid #C4121B;
}
.num-btn.disabled {
border-color: #ccc;
}
.num-btn.disabled .btn-icon {
color: #ccc;
}
.btn-icon {
font-size: 24rpx;
color: #C4121B;
font-weight: bold;
}
.yearRow .num {
font-size: 28rpx;
color: #333;
min-width: 80rpx;
text-align: center;
margin: 0 10rpx;
}
/* 通用行 */
.row {
display: flex;
justify-content: space-between;
align-items: center;
}
.row .label {
font-size: 28rpx;
color: #333;
}
.row .value {
font-size: 30rpx;
color: #C4121B;
font-weight: 500;
}
/* 优惠提示 */
.hintRow {
display: flex;
align-items: flex-start;
font-size: 24rpx;
line-height: 1.4;
}
.hint-icon {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
background-color: #C4121B;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10rpx;
flex-shrink: 0;
margin-top: 2rpx;
}
.icon{
width:30px;
}
.icon-check {
color: #fff;
font-size: 16rpx;
}
.hintRow .hintText {
color: #FF8124;
flex: 1;
margin-top: 10rpx;
}
/* 减免费用 */
.deductRow {
background: #fff;
padding: 20rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
border-radius: 8rpx;
}
.deductRow .label {
font-size: 28rpx;
color: #333;
}
.deductRow .value {
font-size: 30rpx;
color: #C4121B;
}
/* 支付方式行 */
.payRow {
background: #fff;
border-radius: 8rpx;
padding: 20rpx 20rpx;
margin-bottom: 20rpx;
}
.radioItem {
display: flex;
align-items: center;
}
/* 自定义红色单选框 */
::v-deep .custom-radio .wx-radio-input {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
border: 2rpx solid #ccc;
}
::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked {
border-color: #C4121B !important;
background: #C4121B !important;
}
.payInfo {
display: flex;
align-items: center;
margin-left: 15rpx;
}
.payInfo .icon {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.payInfo text {
font-size: 28rpx;
color: #333;
}
/* 总费用行(突出显示) */
.totalRow {
background: #fff;
border-radius: 8rpx;
padding: 20rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10rpx;
}
.totalRow .label {
font-size: 28rpx;
color: #333;
}
.redBig {
font-size: 32rpx;
color: #C4121B;
font-weight: bold;
}
/* 底部按钮 */
.bottomBtn {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 20rpx;
background: #fff;
border-top: 1rpx solid #eee;
}
.payBtn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background-color: #C4121B;
color: #fff;
border-radius: 8rpx;
font-size: 32rpx;
text-align: center;
border: none;
}
.payBtn[disabled] {
background-color: #ccc;
color: #999;
}
/* 通用红色文字 */
.red {
color: #C4121B;
}
<template>
<view class="container">
<view class="content">
<view class="card">
<view class="yearRow">
<view class="label">缴费年限</view>
<view class="control">
<image class="icon" @click="minusYear" src="/static/dd_02.png" mode="widthFix"
v-if="form.renewYear > 1"></image>
<image class="icon" src="/static/dd_02_g.png" mode="widthFix" v-else></image>
<text class="num">{{ form.renewYear }}</text>
<image class="icon" src="/static/btn_03.png" mode="widthFix" @click="plusYear"
v-if="form.renewYear < 5"></image>
<image class="icon" src="/static/btn_03_g.png" mode="widthFix" v-else></image>
</view>
</view>
</view>
<view class="card ">
<!-- 费用合计 -->
<view class="row ">
<text class="label">费用合计</text>
<text class="value red">{{ (form.renewYear * memberFee).toFixed(2) }}</text>
</view>
<view class="hintRow" v-if="preferentialPolicy">
<text
class="hintText">温馨提示:根据中国跆协{{ preferentialData.name || '优惠' }}政策减免一年费用,每个单位在政策有效期内只享受一次</text>
</view>
</view>
<view class="payRow ">
<radio-group @change="onPayTypeChange">
<label class="radioItem">
<radio value="1" :checked="payType === '1'" class="custom-radio" />
<view class="payInfo">
<image class="icon" src="/static/min.png" mode="widthFix"></image>
<text>民生付</text>
</view>
</label>
</radio-group>
</view>
<view class="totalRow ">
<text class="label">支付费用合计</text>
<text class="value redBig">{{ memberTotalFee }}</text>
</view>
</view>
<view class="bottomBtn">
<view class="deductRow">
<text class="label">减免费用</text>
<text class="value red">-{{ memberFee.toFixed(2) }}</text>
</view>
<button class="payBtn" @click="handelPay" :loading="isPaying">立即支付 ¥{{ memberTotalFee }}</button>
</view>
</view>
</template>
<script setup>
import {
ref,
computed
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app';
import to from 'await-to-js'
import * as api from '@/common/api.js'
const form = ref({
renewYear: 1
})
const memberFee = ref(0)
const preferentialPolicy = ref(false)
const preferentialData = ref({
name: '优惠'
})
const payType = ref('1')
const isPaying = ref(false)
const memberTotalFee = computed(() => {
if (preferentialPolicy.value) {
return (memberFee.value * form.value.renewYear - memberFee.value * 1).toFixed(2)
} else {
return (memberFee.value * form.value.renewYear).toFixed(2)
}
})
// 年限减
const minusYear = () => {
if (form.value.renewYear > 1) {
form.value.renewYear--
}
}
// 年限加
const plusYear = () => {
if (form.value.renewYear < 6) {
form.value.renewYear++
}
}
// 支付方式切换
const onPayTypeChange = (e) => {
payType.value = e.detail.value
}
// 支付操作
const handelPay = async () => {
if (memberTotalFee.value < 0) {
uni.showToast({
title: '支付金额异常',
icon: 'none'
})
return
}
// 显示 loading
uni.showLoading({
title: '支付中...',
mask: true
})
isPaying.value = true
// 创建订单
const [orderErr, orderRes] = await to(api.certifiedNew(form.value.renewYear))
if (orderErr) {
uni.hideLoading()
isPaying.value = false
uni.showToast({
title: '创建订单失败',
icon: 'none'
})
return
}
const data = orderRes.data
// 无需支付,直接成功
if (data.payFlag == 0) {
uni.hideLoading()
isPaying.value = false
uni.navigateTo({
url: `/myCenter/sucPay?orderId=${data.orderId}`
})
return
}
// 需要支付回调
if (data.orderId) {
await to(api.callBack2(data.orderId))
uni.hideLoading()
isPaying.value = false
uni.navigateTo({
url: `/myCenter/sucPay?orderId=${data.orderId}`
})
}
}
onLoad((option) => {
// 接收年限
form.value.renewYear = Number(option.renewYear || 1)
// 初始化获取费用和优惠
init()
})
// 初始化接口
async function init() {
uni.showLoading({
title: '加载中...'
})
const [err] = await to(Promise.all([
getMyMemberCertUnitFeeApi(),
canUseDiscountApi(),
getZtxDiscountPolicyApi()
]))
uni.hideLoading()
if (err) {
console.error('初始化失败:', err)
}
}
// 获取会员单价
async function getMyMemberCertUnitFeeApi() {
const [err, res] = await to(api.getMyMemberCertUnitFee())
if (!err && res.data) {
memberFee.value = Number(res.data || 1500)
}
}
// 是否可用优惠
async function canUseDiscountApi() {
const [err, res] = await to(api.canUseDiscount())
if (!err && res.data !== undefined) {
preferentialPolicy.value = res.data
}
}
// 获取优惠政策详情
async function getZtxDiscountPolicyApi() {
const [err, res] = await to(api.getZtxDiscountPolicy())
if (!err && res.data) {
preferentialData.value = res.data
}
}
</script>
<style scoped>
/* 整体容器 */
.container {
min-height: 100vh;
background-color: #f7f7f7;
}
/* 内容区域 */
.content {
padding: 20rpx 20rpx 120rpx;
}
/* 卡片 */
.card {
background: #fff;
border-radius: 8rpx;
padding: 25rpx 20rpx;
margin-bottom: 20rpx;
}
/* 缴费年限行 */
.yearRow {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.yearRow .label {
font-size: 28rpx;
color: #333;
}
.yearRow .control {
display: flex;
align-items: center;
}
.control image {
width: 50rpx;
height: 50rpx;
}
/* 加减按钮样式 */
.num-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
border: 1rpx solid #C4121B;
}
.num-btn.disabled {
border-color: #ccc;
}
.num-btn.disabled .btn-icon {
color: #ccc;
}
.btn-icon {
font-size: 24rpx;
color: #C4121B;
font-weight: bold;
}
.yearRow .num {
font-size: 28rpx;
color: #333;
min-width: 80rpx;
text-align: center;
margin: 0 10rpx;
}
/* 通用行 */
.row {
display: flex;
justify-content: space-between;
align-items: center;
}
.row .label {
font-size: 28rpx;
color: #333;
}
.row .value {
font-size: 30rpx;
color: #C4121B;
font-weight: 500;
}
/* 优惠提示 */
.hintRow {
display: flex;
align-items: flex-start;
font-size: 24rpx;
line-height: 1.4;
}
.hint-icon {
width: 24rpx;
height: 24rpx;
border-radius: 50%;
background-color: #C4121B;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10rpx;
flex-shrink: 0;
margin-top: 2rpx;
}
.icon {
width: 30px;
}
.icon-check {
color: #fff;
font-size: 16rpx;
}
.hintRow .hintText {
color: #FF8124;
flex: 1;
margin-top: 10rpx;
}
/* 减免费用 */
.deductRow {
background: #fff;
padding: 20rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
border-radius: 8rpx;
}
.deductRow .label {
font-size: 28rpx;
color: #333;
}
.deductRow .value {
font-size: 30rpx;
color: #C4121B;
}
/* 支付方式行 */
.payRow {
background: #fff;
border-radius: 8rpx;
padding: 20rpx 20rpx;
margin-bottom: 20rpx;
}
.radioItem {
display: flex;
align-items: center;
}
/* 自定义红色单选框 */
::v-deep .custom-radio .wx-radio-input {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
border: 2rpx solid #ccc;
}
::v-deep .custom-radio .wx-radio-input.wx-radio-input-checked {
border-color: #C4121B !important;
background: #C4121B !important;
}
.payInfo {
display: flex;
align-items: center;
margin-left: 15rpx;
}
.payInfo .icon {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.payInfo text {
font-size: 28rpx;
color: #333;
}
/* 总费用行(突出显示) */
.totalRow {
background: #fff;
border-radius: 8rpx;
padding: 20rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10rpx;
}
.totalRow .label {
font-size: 28rpx;
color: #333;
}
.redBig {
font-size: 32rpx;
color: #C4121B;
font-weight: bold;
}
/* 底部按钮 */
.bottomBtn {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 20rpx;
background: #fff;
border-top: 1rpx solid #eee;
}
.payBtn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background-color: #C4121B;
color: #fff;
border-radius: 8rpx;
font-size: 32rpx;
text-align: center;
border: none;
}
.payBtn[disabled] {
background-color: #ccc;
color: #999;
}
/* 通用红色文字 */
.red {
color: #C4121B;
}
</style>
\ No newline at end of file
......
<template>
<view class="success-container">
<!-- 成功图标(渐变圆形+动效) -->
<view class="success-icon">
<view class="icon-circle">
<text class="check-icon"></text>
</view>
</view>
<!-- 支付成功标题(动画) -->
<view class="success-title">支付成功</view>
<view class="success-subtitle">支付成功,请等待审核</view>
<!-- 订单信息卡片(带阴影) -->
<view class="info-card">
<view class="info-item">
<text class="label">付款账户</text>
<text class="value">(5437)</text>
</view>
<view class="info-item">
<text class="label">交易流水号</text>
<text class="value">2205051351076117833</text>
</view>
<view class="info-item">
<text class="label">商户名称</text>
<text class="value">中国跆拳道协会</text>
</view>
<view class="info-item">
<text class="label">订单金额</text>
<text class="value amount">1500.00元</text>
</view>
<view class="info-item">
<text class="label">会员编号</text>
<text class="value">CTA00004</text>
</view>
<view class="info-item">
<text class="label">会员有效期</text>
<text class="value">2028年1月25日</text>
</view>
</view>
<!-- 确定按钮(渐变+动效) -->
<view class="confirm-btn-area">
<button class="confirm-btn" @click="goBack">确定</button>
</view>
</view>
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app'
const goBack = () => {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const { from } = currentPage.options || {}
let delta = 1
if (from === 'payOrder') {
delta = 2 // 来自添加会员 / 订单页 → 返回 2 级
}else{
delta = 3
}
uni.navigateBack({ delta })
}
onLoad((option) => {
})
</script>
<style scoped>
/* 全局容器 */
.success-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 40rpx 60rpx;
min-height: 100vh;
background-color: #f8f9fa;
box-sizing: border-box;
}
/* 成功图标容器 */
.success-icon {
margin-bottom: 40rpx;
animation: fadeIn 0.6s ease-out;
}
/* 渐变圆形背景 */
.icon-circle {
width: 180rpx;
height: 180rpx;
border-radius: 50%;
/* 青绿色渐变 */
background: linear-gradient(135deg, #06c1ae, #04a896);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 30rpx rgba(6, 193, 174, 0.3);
/* 轻微上浮动效 */
animation: scaleIn 0.8s ease-out;
}
/* 对勾图标 */
.check-icon {
font-size: 90rpx;
color: #ffffff;
font-weight: bold;
}
/* 支付成功标题 */
.success-title {
font-size: 48rpx;
font-weight: 700;
color: #333333;
margin-bottom: 12rpx;
animation: slideUp 0.6s ease-out;
}
/* 副标题 */
.success-subtitle {
font-size: 28rpx;
color: #666666;
margin-bottom: 60rpx;
animation: slideUp 0.8s ease-out;
}
/* 订单信息卡片 */
.info-card {
width: 100%;
background: #ffffff;
border-radius: 20rpx;
padding: 40rpx 30rpx;
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
margin-bottom: 80rpx;
animation: fadeIn 1s ease-out;
}
/* 单个信息项 */
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
/* 最后一项去掉下划线 */
.info-item:last-child {
border-bottom: none;
}
/* 标签样式 */
.label {
font-size: 32rpx;
color: #666666;
}
/* 值样式 */
.value {
font-size: 32rpx;
color: #333333;
text-align: right;
}
/* 金额特殊样式 */
.amount {
color: #cd1e27;
font-weight: 600;
}
/* 确定按钮区域 */
.confirm-btn-area {
width: 100%;
padding: 0 20rpx;
box-sizing: border-box;
}
/* 确定按钮(渐变+动效) */
.confirm-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
/* 按钮渐变背景 */
background: #fff;
color: #C4121B;
font-size: 36rpx;
font-weight: 600;
border-radius: 45rpx;
border: 1px solid #C4121B;
animation: slideUp 1s ease-out;
/* 禁止默认样式 */
position: relative;
overflow: hidden;
}
/* 按钮点击反馈 */
.confirm-btn::after {
border: none;
}
.confirm-btn:active {
transform: scale(0.98);
box-shadow: 0 4rpx 10rpx rgba(6, 193, 174, 0.2);
}
/* 动画定义 */
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes scaleIn {
0% { transform: scale(0); }
70% { transform: scale(1.1); }
100% { transform: scale(1); }
}
@keyframes slideUp {
0% { opacity: 0; transform: translateY(30rpx); }
100% { opacity: 1; transform: translateY(0); }
}
<template>
<view class="success-container">
<!-- 成功图标(渐变圆形+动效) -->
<view class="success-icon">
<view class="icon-circle">
<text class="check-icon"></text>
</view>
</view>
<!-- 支付成功标题(动画) -->
<view class="success-title">支付成功</view>
<view class="success-subtitle">支付成功,请等待审核</view>
<!-- 订单信息卡片(带阴影) -->
<view class="info-card">
<view class="info-item">
<text class="label">交易流水号</text>
<text class="value">{{ orderInfo.tradeNo || '--' }}</text>
</view>
<view class="info-item">
<text class="label">商户名称</text>
<text class="value">{{ orderInfo.merchantName|| '中国跆拳道协会' }}</text>
</view>
<view class="info-item">
<text class="label">订单金额</text>
<text class="value amount">{{ orderInfo.price ? orderInfo.price + '元' : '--' }}</text>
</view>
</view>
<!-- 确定按钮(渐变+动效) -->
<view class="confirm-btn-area">
<button class="confirm-btn" @click="goBack">确定</button>
</view>
</view>
</template>
<script setup>
import {
ref
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
import to from 'await-to-js'
import * as api from '@/common/api.js'
const orderInfo = ref({
orderId: '',
tradeNo: '',
merchantName: '中国跆拳道协会',
price: ''
})
const goBack = () => {
uni.reLaunch({
url: '/myCenter/auth'
})
}
onLoad(async (option) => {
if (option.orderId) {
const [err, res] = await to(api.getOrderInfo(option.orderId))
if (!err && res.data) {
orderInfo.value = res.data
} else {
orderInfo.value.orderId = option.orderId
}
}
})
</script>
<style scoped>
/* 全局容器 */
.success-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 40rpx 60rpx;
min-height: 100vh;
background-color: #f8f9fa;
box-sizing: border-box;
}
/* 成功图标容器 */
.success-icon {
margin-bottom: 40rpx;
animation: fadeIn 0.6s ease-out;
}
/* 渐变圆形背景 */
.icon-circle {
width: 180rpx;
height: 180rpx;
border-radius: 50%;
/* 青绿色渐变 */
background: linear-gradient(135deg, #06c1ae, #04a896);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 30rpx rgba(6, 193, 174, 0.3);
/* 轻微上浮动效 */
animation: scaleIn 0.8s ease-out;
}
/* 对勾图标 */
.check-icon {
font-size: 90rpx;
color: #ffffff;
font-weight: bold;
}
/* 支付成功标题 */
.success-title {
font-size: 48rpx;
font-weight: 700;
color: #333333;
margin-bottom: 12rpx;
animation: slideUp 0.6s ease-out;
}
/* 副标题 */
.success-subtitle {
font-size: 28rpx;
color: #666666;
margin-bottom: 60rpx;
animation: slideUp 0.8s ease-out;
}
/* 订单信息卡片 */
.info-card {
width: 100%;
background: #ffffff;
border-radius: 20rpx;
padding: 40rpx 30rpx;
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.05);
margin-bottom: 80rpx;
animation: fadeIn 1s ease-out;
}
/* 单个信息项 */
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
/* 最后一项去掉下划线 */
.info-item:last-child {
border-bottom: none;
}
/* 标签样式 */
.label {
font-size: 32rpx;
color: #666666;
white-space: nowrap;
margin-right: 20rpx;
flex-shrink: 0;
}
/* 值样式 */
.value {
font-size: 32rpx;
color: #333333;
text-align: right;
word-break: break-all;
word-wrap: break-word;
}
/* 金额特殊样式 */
.amount {
color: #cd1e27;
font-weight: 600;
}
/* 确定按钮区域 */
.confirm-btn-area {
width: 100%;
padding: 0 20rpx;
box-sizing: border-box;
}
/* 确定按钮(渐变+动效) */
.confirm-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
/* 按钮渐变背景 */
background: #fff;
color: #C4121B;
font-size: 36rpx;
font-weight: 600;
border-radius: 45rpx;
border: 1px solid #C4121B;
animation: slideUp 1s ease-out;
/* 禁止默认样式 */
position: relative;
overflow: hidden;
}
/* 按钮点击反馈 */
.confirm-btn::after {
border: none;
}
.confirm-btn:active {
transform: scale(0.98);
box-shadow: 0 4rpx 10rpx rgba(6, 193, 174, 0.2);
}
/* 动画定义 */
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes scaleIn {
0% {
transform: scale(0);
}
70% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
@keyframes slideUp {
0% {
opacity: 0;
transform: translateY(30rpx);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
</style>
\ No newline at end of file
......
......@@ -15,7 +15,7 @@
<view class="info-card">
<view class="info-item">
<text class="label">交易流水号</text>
<text class="value">{{ orderInfo.tradeNo }}</text>
<text class="value">{{ orderInfo.tradeNo||'--' }}</text>
</view>
<view class="info-item">
<text class="label">商户名称</text>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!