You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

800 lines
17 KiB

3 months ago
<template>
<view class="page">
<view class="oinfo" v-if="info">
<!-- 信息 -->
<view class="yycon">
<view class="oscon">
<view class="osrcon">
3 weeks ago
<view class="ostop">
<view class="osname">门店{{info.storeName?info.storeName:''}}</view>
<view class="qrimg" v-if="info.qrCode" @click="openQR(info.qrCode)">
<image class="qrimg" :src="'data:image/png;base64,'+info.qrCode" mode="aspectFill"></image>
</view>
3 months ago
</view>
<view class="oscell">
3 weeks ago
上课课程
3 months ago
<text class="txt">{{info.courseName }}</text>
</view>
3 weeks ago
<view v-if="info.claName" class="oscell">
上课班级
<text class="txt">{{info.claName }}</text>
</view>
<view class="oscell">
预约状态
<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==2" class="htip">待上课</view>
<view v-else-if="info.bookStatus==4" class="wtip">已完成</view>
<view v-else-if="info.bookStatus==3" class="ctip">已取消</view>
</view>
3 months ago
<view class="oscell">
授课教练
<text class="txt">{{info.teacherName }}</text>
</view>
<view class="oscell">
3 weeks ago
上课教室
3 months ago
<text class="txt">{{info.roomName }}</text>
</view>
<view class="oscell">
上课时间
3 weeks ago
<text class="txt">{{ (info.claDate?info.claDate:'')+' '+ (info.startTime?info.startTime:'') + (info.endTime?'-'+info.endTime:'') }}</text>
</view>
<view class="oscell" v-if="info.claTimeStatus">
课程状态
<text class="txt">{{info.claTimeStatus=='1'?'待上课':(info.claTimeStatus=='2'?'已上课':'') }}</text>
</view>
<view class="oscell">
创建日期
<text class="txt">{{info.createTime }}</text>
</view>
<view class="oscellqr">
<view class="ordtip">预约二维码(扫码签到)</view>
<view class="ordqr">
<image class="imgqr" :src="'data:image/png;base64,'+info.qrCode" mode="aspectFill"></image>
</view>
<view class="ordno">
<view class="txt"> 预约号 {{ info.code }}</view>
<view class="copy" @click="copydo(info.code)">.</view> </view>
3 months ago
</view>
</view>
</view>
</view>
<!-- 进度信息 -->
<view class="yycon">
3 weeks ago
<uni-steps v-if="ifshow" :options="steps" direction="column" :active="cur"></uni-steps>
3 months ago
</view>
</view>
3 weeks ago
<!-- 二维码 -->
<uni-popup ref="pfDialog" :mask-click="false">
<view class="pcon">
<view class="phtxt">预约二维码</view>
<view class="ptxt">
<image class="qrimg" :src="qr" mode="aspectFill"></image>
</view>
<view class="btn" @click="closeDialog">
关闭
</view>
</view>
</uni-popup>
3 months ago
<!-- 是否登录 -->
<openlogin ref="loginId" @getPhoneNumber="getPhoneNumber"></openlogin>
3 weeks ago
<view v-if="ifscan" class="bottom"></view>
<view v-if="ifscan" class="submitcon">
<button type="primary" class="bbtn" @tap="goSign()"></button>
</view>
3 months ago
</view>
</template>
<script>
import { myCache } from '../../utils/utils.js';
import openlogin from "../components/openlogin.vue";
export default {
components: {
openlogin
},
data() {
return {
openId:"",
phone:"",
userid:"",
id:"",
3 weeks ago
qr:'',
info: {
"claName": "",
"storeName": "",
3 months ago
"pic": null,
3 weeks ago
"claDate": "",
3 months ago
"weekDay": null,
3 weeks ago
"startTime": "",
"endTime": "",
3 months ago
"roomName": null,
"claColor": null,
"claTimeStatus": null,
3 weeks ago
"bookStatus": null,
"createTime": "",
3 months ago
"code": null,
"courseName": null,
"teacherId": null,
3 weeks ago
"teacherName": "",
3 months ago
"checkIn": 1,
"statusTime": [
{
"time": "2025-09-02 17:26:18",
"status": 0
},
{
"time": "2025-09-02 17:26:18",
"status": 1
},
{
"time": "2025-09-02 17:26:18",
"status": 2
},
{
"time": "2025-09-02 17:26:18",
"status": 3
}
]
},
3 weeks ago
cur:0,
3 months ago
steps:
[
3 weeks ago
// {title:'已付款',desc:'2025-02-05 13:30'},
// {title:'已预约',desc:'2025-02-05 13:30'},
// {title:'教练已确认',desc:''},
// {title:'店长确认,准备上课',desc:''},
// {title:'课程结束',desc:''},
3 months ago
],
3 weeks ago
ifshow:false,
ifscan:false,
3 months ago
};
},
onLoad(options) {
3 weeks ago
if(options.type&&options.type=='qd')
{
this.ifscan=true;
this.$forceUpdate();
}
3 months ago
if(options.id)
{
3 weeks ago
this.id=options.id;
3 months ago
this.getinfo();
}
},
onShow(){
this.openId = myCache('openId');
var user = myCache('user');
this.userid = user.userid? user.userid:'';
this.phone = user.userphone;
if(this.userid==""||this.userid=="0"){
uni.navigateTo({
url: `/pages/login/login`
});
}
},
methods: {
3 weeks ago
copydo(text){
if (!text) {
uni.showToast({
title: '复制内容为空!',
icon: 'none'
})
return;
}
uni.setClipboardData({
data: text,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
})
}
})
},
openQR(qr){
console.log("openQR")
this.qr='data:image/png;base64,'+qr;
this.$forceUpdate();
this.openDialog();
},
closeDialog(){
this.$refs.pfDialog.close();
},
openDialog(){
this.$refs.pfDialog.open();
3 months ago
},
getPhoneNumber(e){
if(e.phone){
this.phone = e.phone
}
if(e.userid){
this.userid = e.userid
}
},
iflogin(){
this.openId = myCache('openId');
var user = myCache('user');
this.userid = user.userid? user.userid:'';
this.phone = user.userphone;
if(this.userid==""||this.userid=="0"||this.phone==""){
uni.navigateTo({
url: `/pages/login/login`
});
return false;
}
else{
return true;
}
},
goback(){
uni.navigateBack({
delta: 1
});
},
async getinfo() {
uni.showLoading({
title: '数据加载中...'
});
3 weeks ago
const {data: res} = await uni.$http.post('/api/course/bookCourseDetail', {"bookId":this.id});//"2037434363846811650"
if(res&&res.data){
3 months ago
// 预约信息
3 weeks ago
this.info=res.data;
this.steps=[
// {title:'已预约',desc:''},
// {title:'教练已确认',desc:''},
// {title:'店长已确认',desc:''},
// {title:'预约已取消',desc:''},
// {title:'课程已结束',desc:''},
];
3 months ago
// 描述预约进度0->预约中1->教练确认2->店长确认/预约成功/待上课 3->已取消;4- >已完成/待评价;
// {title:'已付款',desc:'2025-02-05 13:30'},
// {title:'已预约',desc:'2025-02-05 13:30'},
// {title:'教练已确认',desc:'2025-02-05 13:30'},
// {title:'店长确认,准备上课',desc:''},
// {title:'课程结束',desc:''},
3 weeks ago
var statusTime=res.data.statusTime?res.data.statusTime:[];
if(statusTime&&statusTime.length>0){
statusTime.forEach(cell=>{
3 months ago
var ii={
title: cell.status==0?'已预约':(cell.status==1?'教练已确认':(cell.status==2?'店长已确认':(cell.status==3?'预约已取消':cell.status==4?'课程已结束':''))),
desc: cell.time
}
this.steps.push(ii);
});
3 weeks ago
var lastStatus=statusTime[statusTime.length-1].status;
3 months ago
if(lastStatus==0){
this.steps.push({
title:'教练待确认',desc:''
});
this.steps.push({
title:'店长确认,准备上课',desc:''
});
this.steps.push({
title:'课程结束',desc:''
});
}
else if(lastStatus==1){
this.steps.push({
title:'店长确认,准备上课',desc:''
});
this.steps.push({
title:'课程结束',desc:''
});
}
if(lastStatus==2){
this.steps.push({
title:'课程结束',desc:''
});
}
}
else{
this.steps.push({
title:'预约中',desc:''
});
this.steps.push({
title:'教练待确认',desc:''
});
this.steps.push({
title:'店长确认,准备上课',desc:''
});
this.steps.push({
title:'课程结束',desc:''
});
}
this.$forceUpdate();
3 weeks ago
this.cur=-1;
this.steps.forEach(cell=>{
if(cell.desc){
this.cur++;
this.$forceUpdate();
}
});
this.ifshow=true;
this.$forceUpdate();
}
else{
uni.showModal({
title: '提示',
content: res.message? res.message:'预约详情获取失败!请重试!',
cancelText: '取消',
confirmText: '确定',
success: ress => {
if (ress.confirm) {
// 返回
uni.navigateBack({
delta: 1
});
}
else{
// 返回
uni.navigateBack({
delta: 1
});
}
}
});
}
},
async goSign(){
uni.showLoading({
title: '学员签到中...'
});
const {data: res} = await uni.$http.post('/api/my/checkIn', {"code":this.info.code,"bookId":this.info.bookId});
if(res&&res.success){
uni.showModal({
title: '提示',
content: '学员签到成功!',
cancelText: '取消',
confirmText: '确定',
success: ress => {
//返回
uni.navigateBack({
delta: 1,
});
}
});
}
else{
uni.showModal({
title: '提示',
content: res.message? res.message:'学员签到失败!',
cancelText: '取消',
confirmText: '确定',
success: ress => {
if (ress.confirm) {
}
}
});
3 months ago
}
},
}
}
</script>
<style lang="scss" scoped>
::v-deep .uni-collapse-item__title-box{
padding: 0 !important;
}
::v-deep .uni-collapse-item__title-text{
font-weight: 600;
}
.page{
padding: 0;
position: relative;
background-image: url('@/static/image/bg.jpg');
background-attachment: fixed;
background-size: cover;
background-position: center center;
min-height: calc(100vh - var(--window-top) - var(--window-bottom));
}
.ret{
position: fixed;
top:20rpx;
left:20rpx;
background: rgba(0, 0, 0, .3);
height: 60rpx;
width: 60rpx;
border-radius: 50% 50%;
text-align: center;
line-height: 60rpx;
z-index: 9999;
}
.oscon{
margin:0;
background-color: #f3fafa;
padding: 16rpx;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.osimg{
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
}
.osrcon{
display: flex;
flex-direction: column;
flex: 1;
justify-content: flex-start;
margin-left: 20rpx;
}
3 weeks ago
.ostop{
display: flex;
flex-direction: row;
3 months ago
border-bottom: 1rpx dotted #74defb;
3 weeks ago
padding-bottom: 15rpx;
.osname{
line-height: 48rpx;
font-size:32rpx;
font-weight: 600;
color:#009999;
display: flex;
flex:1;
}
.qrimg{
width: 50rpx;
height: 50rpx;
}
3 months ago
}
.oscell{
display: flex;
flex-direction: row;
font-size: 28rpx;
color:#333;
padding: 15rpx 0;
border-bottom: 1rpx dotted #74defb;
.txt{
display: flex; flex: 1;
3 weeks ago
}
}
.oscellqr{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 20rpx 20rpx 10rpx 20rpx;
.ordtip{
font-size: 28rpx;
color:#000;
margin-bottom: 10rpx;
}
.ordqr{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 200rpx;
margin-bottom: 10rpx;
.imgqr{
width: 200rpx;
height: 200rpx;
}
}
.ordno{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.txt{
font-size: 28rpx;
color:#000;
}
.copy{
font-size: 28rpx;
color:#1296db;
margin-left: 6rpx;
}
3 months ago
}
}
3 weeks ago
.ztip{
color:#1296db;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.jtip{
color:#feb467;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.htip{
border-radius: 12rpx;
color:#fc6900;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.hwtip{
color:#FF0000;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.wtip{
color:#43cca4;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.gtip{
color:#0036D6;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.ftip{
color:#6A81F1;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
.ctip{
color:#888;
font-size: 26rpx;
padding: 0;
height: 40rpx;
line-height: 40rpx;
}
3 months ago
}
3 weeks ago
3 months ago
.oinfo{
padding:20rpx;
position: relative;
3 weeks ago
margin-bottom: 20rpx;
3 months ago
.ozc{
display: flex;
flex-direction: column;
background-color: #becba0 ;
padding: 20rpx;
border-radius: 16rpx;
.ozstate{
font-size: 28rpx;
color: #333;
width: 100%;
margin: 10rpx 0;
}
.oztip{
font-size: 26rpx;
color: #333;
width: 100%;
margin: 0 0 20rpx;
}
}
.owc{
display: flex;
flex-direction: column;
3 months ago
background-color: #00a89b ;
3 months ago
padding: 20rpx;
border-radius: 16rpx;
.ozstate{
font-size: 28rpx;
color: #FFF;
width: 100%;
margin: 6rpx 0 0;
}
.oztip{
font-size: 26rpx;
color: #FFF;
width: 100%;
margin: 0 0 6rpx;
}
}
.oztgray{
display: flex;
flex-direction: column;
background-color: #ddd;
padding: 20rpx;
border-radius: 16rpx;
.ozstate{
font-size: 28rpx;
color: #333;
width: 100%;
margin: 6rpx 0;
}
.oztip{
font-size: 26rpx;
color: #747474;
width: 100%;
margin: 0 0 20rpx;
}
}
.oztorange{
display: flex;
flex-direction: column;
background-color: #faa755;
padding: 20rpx;
border-radius: 16rpx;
.ozstate{
font-size: 28rpx;
color: #FFF;
width: 100%;
margin: 6rpx 0;
}
.oztip{
font-size: 26rpx;
color: #FFF;
width: 100%;
margin: 0 0 20rpx;
}
}
.yycon{
display: flex;
flex-direction: column;
justify-content: center;
background-color: #FFFFFF;
margin-top: 20rpx;
padding: 20rpx 20rpx;
.atitle{
padding: 10rpx 0 10rpx;
color:#303133;
font-size: 30rpx;
font-weight: 600;
display: flex;
flex-direction: row;
justify-content: space-between;
.price{
font-size: 36rpx;
}
}
.olist{
display: flex;
flex-direction: column;
padding: 0;
width: 100%;
.ocell{
font-size: 26rpx;
color:#747474;
padding: 10rpx 0 10rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.ocell1{
font-size: 26rpx;
color:#747474;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}
.sqcon{
padding: 20rpx;
margin: 20rpx 0;
background-color: #f5f5f5;
display: flex;
flex-direction: column;
border-radius: 10rpx;
.sqlist{
display: flex;
flex-direction: row;
justify-content: space-between;
color: #333333;
font-size: 26rpx;
line-height: 50rpx;
}
}
}
}
3 weeks ago
3 months ago
::v-deep.uni-radio-input-checked{
3 months ago
background-color: #00a89b !important;
border-color: #00a89b !important;
3 months ago
background-clip: content-box!important;
box-sizing: border-box;
}
::v-deep.uni-radio-input-checked::before{
display: none!important;
}
3 weeks ago
.pcon{
width: 690rpx;
padding-top:30rpx;
padding-bottom:50rpx;
background: #FCFCFD;
box-shadow: 0rpx 128rpx 128rpx 2rpx rgba(31,47,70,0.12);
border-radius: 16rpx 16rpx 16rpx 16rpx;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.phtxt{
width: 600rpx;
margin: 20rpx auto 10rpx;
font-size: 36rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 600;
color: #23262F;
}
.ptxt
{
width: 620rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 30rpx auto;
border-radius: 16rpx 16rpx 16rpx 16rpx;
opacity: 1;
border: 2rpx solid #F7F8FA;
padding: 30rpx;
.qrimg{
width: 400rpx;
height: 400rpx;
}
}
.btn{
width: 520rpx;
height: 80rpx;
line-height: 80rpx;
background: #00A99A;
box-shadow: 0rpx 12rpx 64rpx 2rpx rgba(0,169,154,0.4);
border-radius: 254rpx 254rpx 254rpx 254rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #FCFCFD;
}
}
.bottom{
width: 100%;
margin-bottom: 148rpx;
}
.submitcon{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 148rpx;
background: #FFFFFF;
box-shadow: 0rpx -4rpx 60rpx 2rpx rgba(1,31,63,0.1);
opacity: 1;
display: flex;
flex-direction: row;
}
.bbtn{
margin: 20rpx 50rpx 50rpx;
font-size: 32rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #FCFCFD;
width: 650rpx;
height: 76rpx;
line-height: 76rpx;
background: #00a89b;
box-shadow: 0rpx 12rpx 64rpx 2rpx rgba(137,150,95,0.4);
border-radius: 10rpx;
opacity: 1;
&::after{
border:none;
}
}
3 months ago
</style>