c9bf47f3 by lttnew

6.5 认证重新排版

1 parent e28234aa
......@@ -1575,6 +1575,7 @@ export function certifiedNew(data) {
const params = []
if (data.renewYear) params.push(`renewYear=${data.renewYear}`)
params.push(`type=${data.type}`)
if (data.payType) params.push(`payType=${data.payType}`)
if (data.contactPerson) params.push(`contactPerson=${data.contactPerson}`)
if (data.contactTel) params.push(`contactTel=${data.contactTel}`)
if (params.length > 0) {
......
......@@ -51,12 +51,12 @@
<form v-if="isActive==0">
<view class="round-input-item">
<image :src="config.baseUrl_api+'/fs/static/lg/tag01.png'" class="icon"></image>
<uni-easyinput v-model="form.username" :styles="inputstyle" placeholder="账号"/>
<uni-easyinput v-model="form.username" :styles="inputstyle" placeholder="新用户请注册后进行登陆"/>
</view>
<view class="round-input-item">
<image :src="config.baseUrl_api+'/fs/static/lg/tag02.png'" class="icon"></image>
<uni-easyinput v-model="form.password" :styles="inputstyle"
placeholder="初次登录请联系省级协会获取初始密码"
placeholder="新用户请注册后进行登陆"
type="password"/>
</view>
<view class="round-input-item">
......@@ -104,6 +104,10 @@
</view>
<view class="fixedagree">
<!-- <text>仅供中国跆拳道协会会员单位登录使用</text> -->
<view class="">
中国跆拳道协会
<text @click="call('010-87188971')">010-87188971</text>
</view>
<view class="wNumber">
技术服务热线:
<text @click="call('15606190026')">15606190026</text>
......
......@@ -21,8 +21,11 @@
<!-- 温馨提示 -->
<view class="tip-box">
<text class="tip-text">温馨提示:
您可以自行录入考官信息,如果暂时没有考官,可以选择由省跆协指派进行考点申报,请尽快完成考点考官的认证。
<text class="tip-text">温馨提示:
根据中国跆拳道协会考点管理办法请添加考点考官
如若已有考官:点击【录入考官信息】,根据相关信息填写考官资料进行录入。
如若没有考官:点击【申请省跆协指派考官】,选择省内相关考官并及时参加考官培训
完成考官设置后,才能继续提交考点申报。请您尽快操作,以免影响后续考试安排。
</text>
</view>
......
......@@ -34,13 +34,15 @@
<!-- 费用合计 -->
<view class="row ">
<text class="label">费用合计</text>
<text class="value red">{{ (form.renewYear * memberFee).toFixed(2) }}</text>
<text class="value red">{{ originalTotalFee }}</text>
</view>
<view v-if="preferentialPolicy" class="hintRow">
<text
class="hintText">温馨提示:根据中国跆协{{ preferentialData.name || '优惠' }}政策减免一年费用,每个单位在政策有效期内只享受一次
</text>
<view v-if="preferentialPolicy" class="discountPolicy">
<!-- <view class="discountPolicyTitle">减免政策</view> -->
<view class="discountPolicyRow">
<text class="discountLabel">{{ preferentialData.name || '减免费用' }}</text>
<text class="discountValue">-{{ discountAmount }}</text>
</view>
</view>
</view>
......@@ -83,14 +85,18 @@
</view>
<view class="bottomBtn">
<view v-if="preferentialPolicy" class="deductRow">
<text class="label">减免费用</text>
<text class="value red">-{{ memberFee.toFixed(2) }}</text>
</view>
<button :loading="isPaying" class="payBtn" @click="handelPay">立即支付 ¥{{ memberTotalFee }}</button>
</view>
</view>
<custom-modal
ref="preferentialModalRef"
title="优惠政策"
:content="preferentialModalContent"
:showCancel="false"
confirmText="我知道了"
/>
</template>
<script setup>
......@@ -105,6 +111,7 @@ import to from 'await-to-js'
import * as api from '@/common/api.js'
import {minShengPay} from '@/common/pay.js'
import config from '@/config.js'
import customModal from '@/components/custom-modal.vue'
// 订单信息(再次支付时传入)
const payForm = ref({})
......@@ -125,6 +132,8 @@ const assoName = ref('')
const app = getApp()
const sourcePage = ref('')
const PERFECT_PAY_REFRESH_KEY = 'perfectNeedRefreshAfterPay'
const preferentialModalRef = ref(null)
const hasShownPreferentialModal = ref(false)
const pickFirst = (...values) => {
const value = values.find(item => item !== undefined && item !== null && String(item).trim() !== '')
......@@ -144,25 +153,20 @@ const getOrderContent = (content) => {
const fillPayDisplayInfo = (data = {}, content = {}, option = {}) => {
const memberInfo = app.globalData?.memberInfo || {}
const deptInfo = app.globalData?.dept || app.globalData?.userInfo?.dept || {}
payName.value = pickFirst(
memberInfo.name,
const optionPayName = option.payName ? decodeURIComponent(option.payName) : ''
const optionAssoName = option.assoName ? decodeURIComponent(option.assoName) : ''
const hasOrderId = !!option.orderId
const orderPayNames = [
data.orderName,
content.orderName,
content.memberName,
data.memberName,
data.payDeptName,
content.payDeptName,
data.payMemName,
content.payMemName,
option.payName ? decodeURIComponent(option.payName) : '',
data.orderName,
content.orderName,
deptInfo.deptName
)
assoName.value = pickFirst(
memberInfo.aname,
memberInfo.associateName,
memberInfo.assoName,
deptInfo.aname,
deptInfo.associateName,
content.payMemName
]
const orderAssoNames = [
data.assoName,
data.associateName,
data.associationName,
......@@ -172,17 +176,53 @@ const fillPayDisplayInfo = (data = {}, content = {}, option = {}) => {
content.associateName,
content.associationName,
content.aname,
content.parentName,
option.assoName ? decodeURIComponent(option.assoName) : ''
)
content.parentName
]
const cachePayNames = [
memberInfo.name,
deptInfo.deptName
]
const cacheAssoNames = [
memberInfo.aname,
memberInfo.associateName,
memberInfo.assoName,
deptInfo.aname,
deptInfo.associateName
]
// 再次支付以订单详情为准;新认证缴费没有订单详情,以入口页面最新传参为准。
payName.value = hasOrderId
? pickFirst(...orderPayNames, optionPayName, ...cachePayNames)
: pickFirst(optionPayName, ...orderPayNames, ...cachePayNames)
assoName.value = hasOrderId
? pickFirst(...orderAssoNames, optionAssoName, ...cacheAssoNames)
: pickFirst(optionAssoName, ...orderAssoNames, ...cacheAssoNames)
}
const originalTotal = computed(() => {
return Number(memberFee.value || 0) * Number(form.value.renewYear || 0)
})
const originalTotalFee = computed(() => {
return originalTotal.value.toFixed(2)
})
const discountValue = computed(() => {
if (!preferentialPolicy.value) return 0
return Math.min(Number(memberFee.value || 0), originalTotal.value)
})
const discountAmount = computed(() => {
return discountValue.value.toFixed(2)
})
const memberTotalFee = computed(() => {
const total = memberFee.value * form.value.renewYear
if (preferentialPolicy.value) {
return (total - memberFee.value).toFixed(2)
}
return total.toFixed(2)
return Math.max(originalTotal.value - discountValue.value, 0).toFixed(2)
})
const preferentialModalContent = computed(() => {
return `根据中国跆协${preferentialData.value.name || '优惠'}政策减免一年费用,每个单位在政策有效期内只享受一次。`
})
// 年限减
......@@ -205,7 +245,7 @@ const onPayTypeChange = (e) => {
// 支付操作
const handelPay = async () => {
if (memberTotalFee.value < 0) {
if (Number(memberTotalFee.value || 0) < 0) {
uni.showToast({
title: '支付金额异常',
icon: 'none'
......@@ -270,6 +310,7 @@ const handelPay = async () => {
// 第一次下单
const [err, res] = await to(api.certifiedNew({
renewYear: form.value.renewYear,
payType: payType.value,
type: payType.value,
contactPerson: form.value.contactPerson,
contactTel: form.value.contactTel
......@@ -306,7 +347,6 @@ const handelPay = async () => {
})
return
}
// 民生支付
if (data.payResult && data.payResult.encryptedData) {
uni.hideLoading()
......@@ -372,7 +412,18 @@ async function init() {
uni.hideLoading()
if (err) {
console.error('初始化失败:', err)
return
}
showPreferentialPolicyModal()
}
function showPreferentialPolicyModal() {
// 已享受过优惠时 canUseDiscount 返回 false,不再提示。
if (!preferentialPolicy.value || hasShownPreferentialModal.value) return
hasShownPreferentialModal.value = true
setTimeout(() => {
preferentialModalRef.value?.open()
}, 100)
}
// 获取会员单价
......@@ -524,12 +575,33 @@ async function getZtxDiscountPolicyApi() {
font-weight: 500;
}
/* 优惠提示 */
.hintRow {
display: flex;
align-items: flex-start;
.discountPolicy {
margin-top: 18rpx;
padding-top: 18rpx;
border-top: 1rpx solid #f1f1f1;
}
.discountPolicyTitle {
font-size: 24rpx;
line-height: 1.4;
color: #999;
margin-bottom: 12rpx;
}
.discountPolicyRow {
display: flex;
justify-content: space-between;
align-items: center;
}
.discountLabel {
font-size: 26rpx;
color: #666;
}
.discountValue {
font-size: 30rpx;
color: #C4121B;
font-weight: 600;
}
/* 对公转账表单 */
......@@ -584,33 +656,6 @@ async function getZtxDiscountPolicyApi() {
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;
......
......@@ -19,12 +19,11 @@
<view class="member-left">
<view class="hello">您好!</view>
<view class="member-name">{{ memberName }}</view>
<view class="member-desc">您已经是中国跆拳道协会的金牌会员了</view>
<view class="name-line"></view>
<!-- <view class="member-desc">您已经是中国跆拳道协会的金牌会员了</view> -->
</view>
<view class="level-box" @click="goPath('/myCenter/reviewList')">
<image class="star" :src="config.baseUrl_api + '/fs/static/img/star.png'" mode="aspectFit"></image>
<view class="level-title">晋级考点</view>
<image class="star" :src="examPointIcon" mode="aspectFit"></image>
<view class="level-title" :class="{ disabled: !isExamPoint }">晋级考点</view>
<view class="detail-btn">查看详情</view>
</view>
</view>
......@@ -154,6 +153,13 @@ const validityDate = computed(() => {
return value ? String(value).slice(0, 10) : '--'
})
const isExamPoint = computed(() => String(memberInfo.value?.isPoints) === '0')
const examPointIcon = computed(() => {
const fileName = isExamPoint.value ? 'star.png' : 'star_g.png'
return `${config.baseUrl_api}/fs/static/img/${fileName}`
})
onLoad((option) => {
const userName = uni.getStorageSync('userName')
if (!userName) {
......@@ -412,7 +418,7 @@ function closeExamPointDialog() {
function goExamPointApply() {
closeExamPointDialog()
uni.navigateTo({ url: '/myCenter/examPointApplyList' })
uni.navigateTo({ url: '/pages/index/notice-examPointApply' })
}
async function handleNoDisplay() {
......@@ -509,10 +515,23 @@ function handelCancelOrder() {
function handelGetMyRecent() {
return new Promise(async (resolve) => {
const res = await to(api.getMyRecent())
if (res[0] || !res[1]?.data) return resolve(false)
payForm.value = res[1].data?.comOrder || {}
if (payForm.value.content) payForm.value.content = JSON.parse(payForm.value.content)
const [err, res] = await to(api.getMyRecent())
if (err) {
uni.showToast({ title: '获取缴费状态失败,请稍后重试', icon: 'none' })
return resolve(false)
}
const recentData = res?.data
if (!recentData) {
payForm.value = {}
return resolve(true)
}
payForm.value = recentData?.comOrder || {}
if (!payForm.value.id) return resolve(true)
if (payForm.value.content && typeof payForm.value.content === 'string') {
try {
payForm.value.content = JSON.parse(payForm.value.content)
} catch (e) {}
}
if (payForm.value.payStatus === '0') {
unpaidPopup.value?.open()
return resolve(false)
......@@ -609,6 +628,7 @@ function handelGetMyRecent() {
color: #181818;
font-size: 34rpx;
font-weight: 700;
// border-bottom:6rpx solid #111;
}
.member-desc {
......@@ -617,13 +637,7 @@ function handelGetMyRecent() {
font-size: 22rpx;
}
.name-line {
width: 112rpx;
height: 6rpx;
margin-top: 14rpx;
background: #111;
border-radius: 8rpx;
}
.level-box {
display: flex;
......@@ -644,6 +658,10 @@ function handelGetMyRecent() {
font-weight: 700;
}
.level-title.disabled {
color: #9a9a9a;
}
.detail-btn {
margin-top: 8rpx;
padding: 4rpx 14rpx;
......
......@@ -12,32 +12,19 @@
<view class="personitem" v-for="(n,index) in list" :key="index">
<uni-swipe-action>
<uni-swipe-action-item>
<view class="content-box" @click="handleInfo(n)">
<view class="content-box" :class="{ normal: isNormalMember(n) }" @click="handleInfo(n)">
<view v-if="isNormalMember(n)" class="normal-corner">正常会员</view>
<view class="flexbox" style="flex: 1 1 auto;">
<view class="photobox">
<image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image>
<view class="colorful" v-else>{{n.name.slice(0,1)}}</view>
</view>
<view>
{{n.name}} <text class="date">({{n.perCode}})</text>
<view class="member-info">
<view class="member-name">
{{n.name}} <text class="date">({{n.perCode || '--'}})</text>
</view>
<view class="validity-line">有效期:{{ formatValidityDate(n.validityDate) }}</view>
</view>
<view class="flexbox" style="flex:0 0 auto">
<text v-if="n.certStage==0" class="text-primary">
新会员
</text>
<text v-if="n.certStage==1" class="text-warning">
待提交
</text>
<text v-if="n.certStage==2" class="text-red">
缴费中
</text>
<text v-if="n.certStage==3" class="text-success">
正常
</text>
<text v-if="n.certStage==4" class="text-gray">
过期
</text>
</view>
</view>
......@@ -166,6 +153,14 @@
})
}
function isNormalMember(item) {
return String(item.certStage) === '3'
}
function formatValidityDate(value) {
return value ? String(value).slice(0, 10) : '--'
}
function goVipList() {
let path = '/personalVip/addVip';
uni.navigateTo({
......@@ -203,9 +198,43 @@
}
.content-box {
position: relative;
background: #fff;
overflow: hidden;
.photobox{margin-right: 20rpx;
}
}
.content-box.normal {
background: linear-gradient(135deg, #fff3f4 0%, #ffffff 58%, #fff0f1 100%);
border: 1rpx solid rgba(196, 18, 27, 0.22);
box-shadow: 0 10rpx 26rpx rgba(196, 18, 27, 0.12);
}
.normal-corner {
position: absolute;
top: 0;
right: 0;
padding: 8rpx 18rpx;
border-radius: 0 0 0 20rpx;
background: linear-gradient(135deg, #C4121B 0%, #e24a52 100%);
color: #fff;
font-size: 22rpx;
font-weight: 600;
}
.member-info {
min-width: 0;
padding-right: 120rpx;
}
.member-name {
color: #222;
font-size: 30rpx;
font-weight: 600;
line-height: 1.4;
}
.validity-line {
margin-top: 8rpx;
color: #777;
font-size: 24rpx;
line-height: 1.4;
}
.pdbox{padding: 0 20rpx;}
</style>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!