Compare commits

..

1 Commits

Author SHA1 Message Date
@xiao-xiao0105 64753a3596 修改预约相关功能
10 hours ago

@ -10,7 +10,7 @@
</view> </view>
</view> </view>
<view class="oscon"> <view class="oscon">
<view class="osname"> <view class="osname">
<view class="osimg imgload"> <view class="osimg imgload">
<image v-if="item.pic" :src="getimgRemoteFile(item.pic)" mode="aspectFill"></image> <image v-if="item.pic" :src="getimgRemoteFile(item.pic)" mode="aspectFill"></image>
@ -51,8 +51,8 @@
</view> </view>
</view> </view>
<view class="rcpm"> <view class="rcpm">
<!-- <button type="primary" class="orderbtn" @click="openCardSelect(item)">预约</button>--> <button type="primary" class="orderbtn" @click="openCardSelect(item)">预约</button>
<button type="primary" class="orderbtn" @click="gotoorder">预约</button> <!-- <button type="primary" class="orderbtn" @click="gotoorder">预约</button>-->
</view> </view>
</view> </view>
</view> </view>
@ -73,46 +73,53 @@
</view> </view>
</view> </view>
<view class="course-info"> <!-- 卡片为空提示 -->
<view class="course-row"> <view v-if="!memberCards || memberCards.length === 0" class="empty-tip">
<text class="course-name">{{ currentCourse.courseName }}</text> 无对应会员卡可使用
<text class="deduct"> </view>
需扣 {{ currentCourse.deductType === 'count' <view v-else>
? currentCourse.deductCount + '次' <view class="course-info">
: '¥' + currentCourse.deductAmount }} <view class="course-row">
</text> <text class="course-name">{{ item.courseName}}</text>
<text class="deduct" v-if="selectedCard && selectedCard.memberChargeType !='days'">
需扣 {{ selectedCard.memberChargeType === 'total_fee'
? '¥' + selectedCard.chargeFee
: selectedCard.chargeCnt + '次'}}
</text>
</view>
<!-- ✅ 本次使用卡片 -->
<view class="use-card-row">
<text class="use-label">本次使用卡片:</text>
<text class="use-name" :class="{ 'is-default': !isManuallySelected }">
{{ effectiveCardName }}
</text>
<text v-if="!isManuallySelected && effectiveCard" class="default-tag">默认</text>
</view>
</view> </view>
<!-- ✅ 本次使用卡片 -->
<view class="use-card-row"> <!-- 卡片横向滑动 -->
<text class="use-label">本次使用卡片:</text> <member-card-scroll
<text class="use-name" :class="{ 'is-default': !isManuallySelected }"> v-if="memberCards && memberCards.length > 0"
{{ effectiveCardName }} ref="cardScroll"
</text> :cards="memberCards"
<text v-if="!isManuallySelected && effectiveCard" class="default-tag">默认</text> size="small"
:selectable="true"
:center="false"
:auto-select="false"
:default-card-id="defaultCardId"
@select="onCardSelect"
/>
<view v-if="memberCards && memberCards.length > 0" class="popup-footer">
<button class="confirm-btn" @click="confirmSelect">确认选择</button>
</view> </view>
</view> </view>
<!-- 卡片横向滑动 -->
<member-card-scroll
ref="cardScroll"
:cards="memberCards"
size="small"
:selectable="true"
:center="false"
:auto-select="false"
:default-card-id="defaultCardId"
:deduct-type="currentCourse.deductType"
:deduct-count="currentCourse.deductCount"
:deduct-amount="currentCourse.deductAmount"
@select="onCardSelect"
/>
<view class="popup-footer">
<button class="confirm-btn" @click="confirmSelect">确认选择</button>
</view>
</view> </view>
</uni-popup> </uni-popup>
<u-toast ref="uToast" />
<!-- 是否登录 --> <!-- 是否登录 -->
<openlogin ref="loginId" @getPhoneNumber="getPhoneNumber"></openlogin> <openlogin ref="loginId" @getPhoneNumber="getPhoneNumber"></openlogin>
</view> </view>
@ -135,31 +142,27 @@ export default {
userid: "", userid: "",
id: "", id: "",
item: { item: {
courseTimeId: 1935590320322428931, courseTimeId: null,
claName: "普拉提A班", claName: "",
courseName: "普拉提", courseName: "",
storeName: "慢瑜伽-三台子店", storeName: "",
pic: null, pic: null,
claDate: "2025-10-01", claDate: "",
weekDay: "星期二", weekDay: "",
startTime: "08:00", startTime: "",
endTime: "09:30", endTime: "",
staffName: "冉洪涛老师", staffName: "",
studentCount: 1, studentCount: null,
roomName: null, roomName: null,
claColor: "#409EFF", claColor: "",
claTimeStatus: "1", claTimeStatus: "",
bookAttendCnt: "1", bookAttendCnt: "",
atClassCnt: "5", atClassCnt: "",
lessCnt: "3" lessCnt: ""
}, },
remark: null, remark: null,
memberCards: [], memberCards: [],
currentCourse: { currentCourse: {
courseName: '普拉提A班',
deductType: 'COUNT',
deductCount: 1,
deductAmount: 0
}, },
defaultCardId: null, defaultCardId: null,
// ✅ 用户手动选中的卡(父组件持有) // ✅ 用户手动选中的卡(父组件持有)
@ -210,9 +213,9 @@ export default {
isCardUsable(card) { isCardUsable(card) {
if (!card) return false; if (!card) return false;
if (card.status && card.status !== 'ACTIVE') return false; if (card.status && card.status !== 'ACTIVE') return false;
if (card.expireDate) { if (card.expiryDate) {
const now = new Date(); const now = new Date();
const expire = new Date(card.expireDate.replace(/-/g, '/')); const expire = new Date(card.expiryDate.replace(/-/g, '/'));
if (now > expire) return false; if (now > expire) return false;
} }
const type = this.currentCourse.deductType; const type = this.currentCourse.deductType;
@ -235,15 +238,19 @@ export default {
// ✅ 打开弹窗:重置手动选择,用默认卡 // ✅ 打开弹窗:重置手动选择,用默认卡
async openCardSelect(item) { async openCardSelect(item) {
var user = myCache('userInfo'); var user = myCache('userInfo');
item.visitStore=user.visitStore;
console.log('item',item)
const { data: memberCards } = const { data: memberCards } =
await uni.$http.post("/api/memberCard/getMemberCardListByCourseTimeId", await uni.$http.post("/api/memberCard/getMemberCardListByCourseTimeId",
{visitStore:user.visitStore, item);
courseId:item.courseId
});
console.log("memberCards",memberCards)
//如果为空 则没有适合的卡片 //如果为空 则没有适合的卡片
this.memberCards = memberCards.data this.memberCards = memberCards.data
this.selectedCard = null; console.log('this.memberCards',this.memberCards)
if(this.memberCards&&this.memberCards.length > 0){
this.selectedCard = this.memberCards[0];
}else{
this.selectedCard = null;
}
this.$refs.cardPopup.open(); this.$refs.cardPopup.open();
}, },
@ -252,37 +259,53 @@ export default {
}, },
async confirmSelect() { async confirmSelect() {
// ✅ 直接从父组件 computed 拿有效卡
const card = this.effectiveCard; const card = this.effectiveCard;
if (!card) { if (!card) {
uni.showToast({ title: '无可用会员卡', icon: 'none' }); uni.showToast({ title: '无可用会员卡', icon: 'none' });
return; return;
} }
const { data: res } = await uni.$http.post('/api/course/bookCourse', { // 开启loading
courseTimeId: this.item.courseTimeId, uni.showLoading({
cardId: card.id title: '预约中...',
mask: true // 遮罩,防止重复点击
}); });
if (res && res.success) { try {
myCache('courserefresh', 1); const { data: res } = await uni.$http.post('/api/course/bookCourse', {
uni.showModal({ courseTimeId: this.item.courseTimeId,
title: '提示', memberCardId: card.memberCardId,
content: '课程已预约!', memberChargeType: this.selectedCard.memberChargeType,
cancelText: '返回', chargeCnt: this.selectedCard.chargeCnt,
confirmText: '确定', chargeFee: this.selectedCard.chargeFee
success: ress => {
uni.navigateBack({ delta: 1 });
}
}); });
} else { if (res && res.success) {
uni.showModal({ myCache('courserefresh', 1);
title: '提示', this.closeCardSelect();
content: res.message ? res.message : '课程预约失败!', this.$refs.uToast.show({
cancelText: '取消', title: '课程预约成功,请到 我的预约-预约中 查看',
confirmText: '确定' type: 'success',
duration: 2000
});
} else {
this.$refs.uToast.show({
title: res.message ? res.message : '课程预约失败!',
type: 'error',
duration: 2000
});
}
} catch (err) {
// 网络异常捕获
this.$refs.uToast.show({
title: '预约请求异常,请稍后重试',
type: 'error',
duration: 2000
}); });
} finally {
// 不管成功失败、报错,都关闭loading
uni.hideLoading();
} }
}, },
formatTime(timeStr) { formatTime(timeStr) {
return timeStr.slice(0, 5); return timeStr.slice(0, 5);
}, },
@ -819,5 +842,11 @@ export default {
border: none; border: none;
&::after { border: none; } &::after { border: none; }
} }
.empty-tip {
padding: 60rpx 20rpx;
text-align: center;
font-size: 28rpx;
color: #999;
}
</style> </style>

@ -23,19 +23,24 @@
</view> </view>
<view class="oscell"> <view class="oscell">
预约状态: 预约状态:
<view v-if="info.bookStatus==1" class="ztip">教练确认</view> <view v-if="info.bookStatus==1" class="ztip">预约中</view>
<view v-else-if="info.bookStatus==0" class="jtip">预约中</view> <view v-else-if="info.bookStatus==0" class="jtip">预约中</view>
<view v-else-if="info.bookStatus==2" class="htip">待上课</view> <view v-else-if="info.bookStatus==2" class="htip">预约成功,待上课</view>
<view v-else-if="info.bookStatus==4" class="wtip">已完成</view> <view v-else-if="info.bookStatus==4" class="wtip">已完成</view>
<view v-else-if="info.bookStatus==3" class="ctip">已取消</view> <view v-else-if="info.bookStatus==3" class="ctip">已取消</view>
</view> </view>
<view class="oscell">
签到状态:
<view v-if="info.checkIn==1" class="ztip">已签到</view>
<view v-else-if="info.checkIn==0" class="jtip">未签到</view>
</view>
<view class="oscell"> <view class="oscell">
授课教练: 授课教练:
<text class="txt">{{info.teacherName }}</text> <text class="txt">{{info.teacherName }}</text>
</view> </view>
<view class="oscell"> <view class="oscell">
上课教室: 上课教室:
<text class="txt">{{info.roomName }}</text> <text class="txt">{{info.roomName?info.roomName:'待定'}}</text>
</view> </view>
<view class="oscell"> <view class="oscell">
上课时间: 上课时间:

@ -19,11 +19,13 @@
<view class="hright"> <view class="hright">
<!-- 1:待上课,2:预约中,3:待评价 ,4:已完成 ,5:已取消 --> <!-- 1:待上课,2:预约中,3:待评价 ,4:已完成 ,5:已取消 -->
<!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; --> <!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; -->
<view v-if="item.bookStatus==1" class="ztip">教练确认</view>
<view v-if="item.bookStatus==1" class="ztip">预约中</view>
<view v-else-if="item.bookStatus==0" class="jtip">预约中</view> <view v-else-if="item.bookStatus==0" class="jtip">预约中</view>
<view v-else-if="item.bookStatus==2" class="htip">待上课</view> <view v-else-if="item.bookStatus==2" class="htip">预约成功,待上课</view>
<view v-else-if="item.bookStatus==4" class="wtip">已完成</view> <view v-else-if="item.bookStatus==4" class="wtip">已完成</view>
<view v-else-if="item.bookStatus==3" class="ctip">已取消</view> <view v-else-if="item.bookStatus==3" class="ctip">已取消</view>
<view v-else-if="item.bookStatus==5" class="ctip">预约失败</view>
</view> </view>
</view> </view>
@ -35,7 +37,8 @@
<text class="ntxt">{{item.courseName}} {{item.claName}} </text> <text class="ntxt">{{item.courseName}} {{item.claName}} </text>
<text class="txt"> 教练:{{item.teacherName || '-'}}</text> <text class="txt"> 教练:{{item.teacherName || '-'}}</text>
<text class="txt"> 上课时间:{{ item.claDate+' '+item.startTime+'-'+item.endTime}}</text> <text class="txt"> 上课时间:{{ item.claDate+' '+item.startTime+'-'+item.endTime}}</text>
<text class="txt"> 教室:{{item.roomName}}</text> <text class="txt"> 教室:{{item.roomName?item.roomName:'待定'}}</text>
<text class="txt"> 使用会员卡号:{{item.cardNo}}</text>
</view> </view>
</view> </view>
@ -49,7 +52,7 @@
<!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; --> <!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; -->
<button class="conbtn" @click="gototeacher(item)">联系教练</button> <button class="conbtn" @click="gototeacher(item)">联系教练</button>
<!-- <button v-if="item.bookStatus==2||item.bookStatus==1" type="primary" class="cancelbtn" :data-id="item.courseTimeId" @click="cancelkcdo">取消课程</button>--> <!-- <button v-if="item.bookStatus==2||item.bookStatus==1" type="primary" class="cancelbtn" :data-id="item.courseTimeId" @click="cancelkcdo">取消课程</button>-->
<button v-if="'0,1,2'.includes(item.bookStatus)" class="cancelbtn" :data-id="item.courseTimeId" @click="cancelyydo">取消预约</button> <button v-if="'0,1,2'.includes(item.bookStatus) && item.checkIn!=1" class="cancelbtn" :data-id="item.courseTimeId" @click="cancelyydo(item)">取消预约</button>
<!-- <button v-if="item.bookStatus==0" type="primary" class="paybtn" :data-id="item.courseTimeId" @click="checkdo($event,item)">确认上课</button>--> <!-- <button v-if="item.bookStatus==0" type="primary" class="paybtn" :data-id="item.courseTimeId" @click="checkdo($event,item)">确认上课</button>-->
<button v-if="item.bookStatus==4" class="viewbtn" :data-id="item.courseTimeId" @click="orderdo($event,item)">再次预约</button> <button v-if="item.bookStatus==4" class="viewbtn" :data-id="item.courseTimeId" @click="orderdo($event,item)">再次预约</button>
<!-- <button v-if="item.bookStatus==4" type="primary" class="gzbtn" :data-id="item.courseTimeId" @click="gotoevaluate($event,item)">评价</button>--> <!-- <button v-if="item.bookStatus==4" type="primary" class="gzbtn" :data-id="item.courseTimeId" @click="gotoevaluate($event,item)">评价</button>-->
@ -677,7 +680,7 @@ import { mapState, mapGetters, mapActions } from 'vuex';
// 取消预约 // 取消预约
cancelyydo(e){ cancelyydo(e){
console.log(e); console.log(e);
var id= e.currentTarget.dataset.id; // var id= e.currentTarget.dataset.id;
var that = this; var that = this;
//取消预约 //取消预约
uni.showModal({ uni.showModal({
@ -687,16 +690,14 @@ import { mapState, mapGetters, mapActions } from 'vuex';
confirmText: '确定', confirmText: '确定',
success: ress => { success: ress => {
if (ress.confirm) { if (ress.confirm) {
that.delyydo(id); that.delyydo(e);
} }
} }
}); });
}, },
// 取消预约 // 取消预约
async delyydo(id){ async delyydo(e){
var param={ var param=e;
"courseTimeId":id
};
uni.showToast({ uni.showToast({
title: '取消中...', title: '取消中...',
icon: 'success', icon: 'success',

@ -12,10 +12,12 @@
<text style="margin-left: 30rpx;">性别:{{item.sex==2?'男':(item.sex==1?'女':'未知')}}</text> <text style="margin-left: 30rpx;">性别:{{item.sex==2?'男':(item.sex==1?'女':'未知')}}</text>
</view> </view>
<text>电话:{{item.phone?item.phone:'-'}}</text> <text>电话:{{item.phone?item.phone:'-'}}</text>
<text>会员卡号:{{item.cardNo?item.cardNo:'-'}}</text>
</view> </view>
<view class="hright"> <view class="hright">
<!-- 1:待上课,2:预约中,3:待评价 ,4:已完成 ,5:已取消 --> <!-- 1:待上课,2:预约中,3:待评价 ,4:已完成 ,5:已取消 -->
<!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; --> <!-- 描述:0->预约中;1->教练确认;2->店长确认/预约成功/待上课 3->已取消;4->已完成/待评价; -->
<view v-if="item.bookStatus==1" class="ztip">教练确认</view> <view v-if="item.bookStatus==1" class="ztip">教练确认</view>
<view v-else-if="item.bookStatus==0" class="jtip">预约中</view> <view v-else-if="item.bookStatus==0" class="jtip">预约中</view>
<view v-else-if="item.bookStatus==2" class="htip">待上课</view> <view v-else-if="item.bookStatus==2" class="htip">待上课</view>
@ -139,6 +141,7 @@
// 全部 // 全部
this.loadStatus="noMore"; this.loadStatus="noMore";
this.list=res.data; this.list=res.data;
console.log('this.list',this.list)
this.$forceUpdate(); this.$forceUpdate();
} }
else{ else{

@ -8,16 +8,6 @@
<view class="uid">ID:{{ userInfo.id || userInfo.userId || '-' }}</view> <view class="uid">ID:{{ userInfo.id || userInfo.userId || '-' }}</view>
</view> </view>
<!-- 黑名单开关行 仿微信 -->
<!-- <view class="black-row">-->
<!-- <text class="black-label">加入黑名单</text>-->
<!-- <switch-->
<!-- :checked="isBlacked"-->
<!-- active-color="#00a89b"-->
<!-- @change="onBlackSwitchChange"-->
<!-- />-->
<!-- </view>-->
<view class="black-row"> <view class="black-row">
<text class="black-label">加入黑名单</text> <text class="black-label">加入黑名单</text>
<view class="custom-switch" :class="{ on: isBlacked }" @tap="handleSwitchTap"> <view class="custom-switch" :class="{ on: isBlacked }" @tap="handleSwitchTap">
@ -84,45 +74,7 @@ export default {
console.error('查询黑名单状态失败', e) console.error('查询黑名单状态失败', e)
} }
}, },
/**
* switch点击,不直接改状态,弹出确认弹窗
*/
onBlackSwitchChange(e) {
// e.detail.value 是用户想要切换到的目标状态
const targetStatus = e.detail.value
const title = targetStatus ? '加入黑名单' : '取消黑名单'
const content = targetStatus
? '加入黑名单后,对方将无法给你发送消息,确定?'
: '确定将该用户移出黑名单?'
uni.showModal({
title,
content,
success: async (res) => {
if (!res.confirm) {
// 用户点取消,不做任何操作,switch会自动回弹回旧状态,无需手动赋值
return
}
try {
const url = targetStatus ? '/api/blacklist/add?targetUid=' : '/api/blacklist/cancel?targetUid='
await uni.$http.post(`${url}${this.userId}`)
// 接口成功才更新本地状态
this.isBlacked = targetStatus
uni.showToast({
title: this.isBlacked ? '已加入黑名单' : '已取消黑名单',
icon: 'none'
})
} catch (err) {
uni.showToast({ title: '操作失败', icon: 'none' })
}
}
})
},
onSendMessage() { onSendMessage() {
// if (this.isBlacked) {
// uni.showToast({ title: '你已将对方加入黑名单', icon: 'none' })
// return
// }
let chat = { let chat = {
type: 'PRIVATE', type: 'PRIVATE',
targetId: this.userId, targetId: this.userId,
@ -190,7 +142,7 @@ export default {
onBackPress(e) { onBackPress(e) {
// 来源是左上角返回 / 安卓返回键 // 来源是左上角返回 / 安卓返回键
if(e.from === 'backbutton'){ if(e.from === 'backbutton'){
if(this.isBlacked){ if(this.isBlacked && this.chatIndex){
// 拉黑成功,自定义跳转chat // 拉黑成功,自定义跳转chat
this.goBackChat() this.goBackChat()
return true // return true 阻止原生默认返回 return true // return true 阻止原生默认返回

@ -1,7 +1,7 @@
<template> <template>
<view class="member-card-scroll"> <view class="member-card-scroll">
<scroll-view <scroll-view
class="card-scroll" class="card-scroll-wrap"
scroll-x="true" scroll-x="true"
scroll-with-animation scroll-with-animation
:show-scrollbar="false" :show-scrollbar="false"
@ -22,7 +22,7 @@
/> />
<!-- v-if="selectable && !isCardUsable(card)"--> <!-- v-if="selectable && !isCardUsable(card)"-->
<view class="unusable-tip"> <view class="unusable-tip">
<text v-if=" card.status == 'ACTIVE'" style="color:#00a89b;" >正常</text> <text v-if=" isCardUsable(card)" style="color:#00a89b;" >正常</text>
<text v-else style="color: #ff6b6b;">{{ getUnusableReason(card) }}</text> <text v-else style="color: #ff6b6b;">{{ getUnusableReason(card) }}</text>
</view> </view>
</view> </view>
@ -99,15 +99,20 @@ export default {
}, },
// 动态计算首尾 padding // 动态计算首尾 padding
innerStyle() { innerStyle() {
if (!this.center) { // ✅ 只要卡片总数=1,不管外部center参数传啥,自动触发居中计算
const isSingleCard = this.cards && this.cards.length === 1;
if (!this.center && !isSingleCard) {
// 多卡正常:保留原来的20rpx边距
return { paddingLeft: '20rpx', paddingRight: '20rpx' }; return { paddingLeft: '20rpx', paddingRight: '20rpx' };
} }
// 居中计算:左右padding = (屏幕宽度750rpx - 卡片宽度) / 2,刚好把卡片推到正中间
const padding = Math.max(0, (this.screenWidthRpx - this.cardWidthRpx) / 2); const padding = Math.max(0, (this.screenWidthRpx - this.cardWidthRpx) / 2);
return { return {
paddingLeft: padding + 'rpx', paddingLeft: padding-30 + 'rpx',
paddingRight: padding + 'rpx' paddingRight: padding + 'rpx'
}; };
} }
}, },
watch: { watch: {
cards: { cards: {
@ -183,9 +188,9 @@ export default {
if (!card) return false; if (!card) return false;
// ✅ 只有 ACTIVE 才可用 // ✅ 只有 ACTIVE 才可用
if (card.status && card.status !== 'ACTIVE') return false; if (card.status && card.status !== 'ACTIVE') return false;
if (card.expireDate) { if (card.expiryDate) {
const now = new Date(); const now = new Date();
const expire = new Date(card.expireDate.replace(/-/g, '/')); const expire = new Date(card.expiryDate.replace(/-/g, '/'));
if (now > expire) return false; if (now > expire) return false;
} }
if (card.type === 'count') { if (card.type === 'count') {
@ -214,9 +219,9 @@ export default {
if (card.status && card.status == 'DEPLETED') { if (card.status && card.status == 'DEPLETED') {
return '卡片额度已用完'; return '卡片额度已用完';
} }
if (card.expireDate) { if (card.expiryDate) {
const now = new Date(); const now = new Date();
const expire = new Date(card.expireDate.replace(/-/g, '/')); const expire = new Date(card.expiryDate.replace(/-/g, '/'));
if (now > expire) return '卡片已过期'; if (now > expire) return '卡片已过期';
} }
if (card.type === 'count') { if (card.type === 'count') {
@ -299,4 +304,17 @@ export default {
background: #00a89b; background: #00a89b;
} }
} }
.card-scroll-wrap {
width: 100%;
overflow-x: auto;
padding: 20rpx 0;
/* 多卡时默认左对齐横向滚动 */
display: flex;
gap: 20rpx;
}
</style> </style>

@ -21,22 +21,28 @@
<view class="card-middle"> <view class="card-middle">
<view class="balance-box"> <view class="balance-box">
<text class="balance-label"> <text class="balance-label">
{{ card.chargeType === 'count' ? '剩余次数' : card.chargeType ==='days'?'剩余天数':'卡内余额' }} {{ card.chargeType === 'count' ? '剩余次数' : card.chargeType ==='days'?'剩余天数':'可用余额' }}
</text> </text>
<view class="balance-value-box"> <view class="balance-value-box">
<text v-if="card.chargeType == 'total_fee'" class="unit">¥</text> <text v-if="card.chargeType == 'total_fee'" class="unit">¥</text>
<text class="balance-value"> <text class="balance-value">
{{ card.chargeType === 'count' ? (card.remainingCount || 0) : card.chargeType ==='days'?card.remainingDays: formatAmount(card.remainingTotalFee) }} {{
card.chargeType === 'count'
? Math.max((card.remainingCount || 0) - (card.freezeCount || 0), 0)
: card.chargeType === 'days'
? (card.remainingDays || 0)
: formatAmount( Math.max( (Number(card.remainingTotalFee)||0) - (Number(card.freezeAmount)||0), 0 ) )
}}
</text> </text>
<text v-if="card.chargeType === 'count'" class="unit">次</text> <text v-if="card.chargeType === 'count'" class="unit">次</text>
<text v-if="card.chargeType === 'days'" class="unit">天</text> <text v-if="card.chargeType === 'days'" class="unit">天</text>
</view> </view>
</view> </view>
<!-- 冻结信息(可选) --> <!-- 冻结信息(可选) -->
<view v-if="card.chargeType !== 'days' || card.frozenCount > 0 || card.frozenAmount > 0" class="frozen-box"> <view v-if="card.chargeType !== 'days' || card.freezeCount > 0 || card.freezeAmount > 0" class="frozen-box">
<text class="frozen-label">预约占用</text> <text class="frozen-label">预约占用</text>
<text class="frozen-value"> <text class="frozen-value">
{{ card.type === 'count' ? card.frozenCount + '次' : '¥' + formatAmount(card.frozenAmount) }} {{ card.type === 'count' ? card.freezeCount + '次' : '¥' + formatAmount(card.freezeAmount) }}
</text> </text>
</view> </view>
</view> </view>
@ -45,7 +51,7 @@
<view class="card-bottom"> <view class="card-bottom">
<text class="card-no">NO. {{ card.cardNo || '--' }}</text> <text class="card-no">NO. {{ card.cardNo || '--' }}</text>
<text class="card-expire"> <text class="card-expire">
{{ card.expireDate ? '有效期至 ' + card.expireDate : '长期有效' }} {{ card.expiryDate ? '有效期至 ' + card.expiryDate : '长期有效' }}
</text> </text>
</view> </view>
</view> </view>

@ -74,7 +74,7 @@
</view> </view>
<view class="info-row"> <view class="info-row">
<text class="info-label">有效期至</text> <text class="info-label">有效期至</text>
<text class="info-value">{{ card.expireDate || '长期有效' }}</text> <text class="info-value">{{ card.expiryDate || '长期有效' }}</text>
</view> </view>
<view class="info-row"> <view class="info-row">
<text class="info-label">状态</text> <text class="info-label">状态</text>

@ -56,11 +56,12 @@
<!-- <view v-if="item.claName=='团课'" class="txtbg">{{item.claName}}</view> <!-- <view v-if="item.claName=='团课'" class="txtbg">{{item.claName}}</view>
<view v-else class="txtbg1">{{item.claName}}</view> --> <view v-else class="txtbg1">{{item.claName}}</view> -->
<!-- <view v-if="item.claName" class="txtbg1">{{item.claName}}</view>--> <!-- <view v-if="item.claName" class="txtbg1">{{item.claName}}</view>-->
<uni-rate :size="15" :readonly="true" :value="item.star?item.star:0" :max="5"/>
</view> </view>
<view class="oscell" v-if="item.storeName"> <view class="oscell" v-if="item.storeName">
<uni-icons type="paperclip" size="18" color="#00A99A"></uni-icons> <uni-icons type="paperclip" size="18" color="#00A99A"></uni-icons>
<view class="ntip">{{item.courseName}}</view> <view class="ntip" style="margin-right: 10rpx;">{{item.courseName}}</view>
<uni-rate :size="15" :readonly="true" :value="item.star?item.star:0" :max="5"/>
</view> </view>
<view class="oscell"> <view class="oscell">
<uni-icons type="calendar" size="18" color="#00A99A"></uni-icons> <uni-icons type="calendar" size="18" color="#00A99A"></uni-icons>
@ -74,7 +75,7 @@
</view> </view>
<view class="oscell"> <view class="oscell">
<uni-icons type="map-pin-ellipse" size="18" color="#00A99A"></uni-icons> <uni-icons type="map-pin-ellipse" size="18" color="#00A99A"></uni-icons>
<view class="ntxt">{{item.roomName}}</view> <view class="ntxt">{{item.roomName?item.roomName:'教室待定'}}</view>
</view> </view>
<view class="oscell"> <view class="oscell">
<uni-icons type="checkbox" size="18" color="#00A99A"></uni-icons> <uni-icons type="checkbox" size="18" color="#00A99A"></uni-icons>

@ -13,20 +13,27 @@
</view> </view>
</view> </view>
<!-- <view class="s-list" >--> <view class="s-list" >
<!-- <view class="s-header">--> <view class="s-header">
<!-- <view class="tit-box">--> <view class="tit-box">
<!-- <text class="tit">我的会员卡</text>--> <text class="tit">我的会员卡</text>
<!-- </view>--> </view>
<!-- </view>--> </view>
<!-- &lt;!&ndash; ✅ 会员卡横向滑动(不可选,纯展示) &ndash;&gt;--> <!-- 卡片为空提示 -->
<!-- <member-card-scroll--> <view v-if="!memberCards || memberCards.length === 0" class="empty-tip">
<!-- :cards="memberCards"--> 暂无会员卡
<!-- size="small"--> </view>
<!-- :selectable="false"-->
<!-- @card-click="onCardClick"--> <view v-else>
<!-- />--> <!-- ✅ 会员卡横向滑动(不可选,纯展示) -->
<!-- </view>--> <member-card-scroll
:cards="memberCards"
size="small"
:selectable="false"
@card-click="onCardClick"
/>
</view>
</view>
<!-- 菜单1 --> <!-- 菜单1 -->
<!-- <view class="s-list"> <!-- <view class="s-list">
<view class="s-header"> <view class="s-header">
@ -115,7 +122,7 @@
<view class="title">{{servers[13].name}}</view> <view class="title">{{servers[13].name}}</view>
</view> </view>
<!-- 学员签到 教练/顾问 --> <!-- 学员签到 教练/顾问 -->
<view v-if="ifview('103,104')" class="product-item" @click="gotoServe(14)"> <view v-if="ifview('103,104,105')" class="product-item" @click="gotoServe(14)">
<view class="image-wrapper"> <view class="image-wrapper">
<image class="imgicon" :src="servers[14].img" mode="aspectFill" lazy-load></image> <image class="imgicon" :src="servers[14].img" mode="aspectFill" lazy-load></image>
</view> </view>
@ -219,77 +226,7 @@
avatar:"../../static/image/logo.png", avatar:"../../static/image/logo.png",
roleId:[], roleId:[],
memberCards: [ memberCards: [
// 1. 次卡:正常,余额充足
{
id: 1001,
cardNo: '88880001',
chargeType: 'count',//收费模式 count:课时 days:时间 total_fee:储值
cardName: '次卡',
remainingCount: 8,
frozenCount: 1,
remainingTotalFee: 0,
frozenAmount: 0,
expireDate: '2027-12-31',
status: 'ACTIVE'
},
// 2. 次卡:剩余次数不足(只剩1次)
{
id: 1002,
type: 'COUNT',
cardName: '次卡',
name: '体验次卡',
cardNo: '88880002',
remainingCount: 1,
frozenCount: 0,
remainAmount: 0,
frozenAmount: 0,
expireDate: '2026-12-31',
status: 'NORMAL'
},
// 3. 储值卡:余额充足
{
id: 1003,
type: 'AMOUNT',
cardName: '储值卡',
name: '瑜伽储值卡',
cardNo: '88880003',
remainingCount: 0,
frozenCount: 0,
remainAmount: 1280.50,
frozenAmount: 200.00,
expireDate: '2028-06-30',
status: 'NORMAL'
},
// 4. 储值卡:余额不足(只剩50元)
{
id: 1004,
type: 'AMOUNT',
cardName: '储值卡',
name: '小额储值卡',
cardNo: '88880004',
remainingCount: 0,
frozenCount: 0,
remainAmount: 50.00,
frozenAmount: 0,
expireDate: '2027-01-01',
status: 'NORMAL'
},
// 5. 已过期的次卡
{
id: 1005,
type: 'COUNT',
cardName: '次卡',
name: '过期次卡',
cardNo: '88880005',
remainingCount: 5,
frozenCount: 0,
remainAmount: 0,
frozenAmount: 0,
expireDate: '2025-01-01', // 已过期
status: 'NORMAL'
}
], ],
favoritesnum:0,//我的收藏数量 favoritesnum:0,//我的收藏数量
menus: [ menus: [
@ -425,7 +362,7 @@
this.signature = user.signature?user.signature:this.signature; this.signature = user.signature?user.signature:this.signature;
this.roleId=user.roleId?user.roleId:[]; this.roleId=user.roleId?user.roleId:[];
this.getmember(); this.getmember();
this.getMemberCards();
// if(myCache("ifuserEdit")) // if(myCache("ifuserEdit"))
// { // {
// myCache("ifuserEdit",false) // myCache("ifuserEdit",false)
@ -1238,5 +1175,10 @@
align-items: center; align-items: center;
} }
} }
.empty-tip {
padding: 60rpx 20rpx;
text-align: center;
font-size: 28rpx;
color: #999;
}
</style> </style>

Loading…
Cancel
Save