123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- <template>
- <view class="reservation_layout">
- <view class="header_title">
- <view class="left">
- <view class="title">{{course_name}}</view>
- <view class="subtitle">{{teacher_desc}}</view>
- </view>
- <view class="right">
- <image :src="course_image" class="image" mode=""></image>
- </view>
- </view>
- <view class="teacher_list">
- <view class="teacher_item" v-for="(item,index) in data" :key="index" @click="selectTeacher(index,item)" :class="index === teacherActive? 'active':''">
- <text>{{item.teacher_name}}</text>
- </view>
- </view>
- <view class="course">
- <scroll-view scroll-x >
- <view class="days">
- <view class="day" v-for="(item, index) in dateArr" :key="index" @click="selectDateEvent(index,item)" :class="{ borderb: index==dateActive}" :style="{color:index==dateActive?selectedTabColor:'#333'}">
- <text>{{ item.week }}</text>
- <view>{{item.date}}</view>
- </view>
- </view>
- </scroll-view>
- <view class="times">
- <scroll-view scroll-y="true" >
- <view class="time_list">
- <view class="day" v-for="(item,_index) in timeArr" :key="_index" :class="{'disable':item.disable,
- 'active':isMultiple?item.isActive:_index==timeActive}" :style="{color:isMultiple?item.isActive? '#fff':'#333'
- :_index==timeActive?'#fff':'#333',backgroundColor:isMultiple?item.isActive? selectedItemColor:''
- :_index==timeActive?selectedItemColor:''}" @click="selectTimeEvent(_index,item)">
- <view class="disableText">{{item.disable?disableText:undisableText}}</view>
- <view class="time">{{item.begin}}~{{item.end}}</view>
- <view class="num" >{{item.reservationSum}}</view>
- </view>
- </view>
- </scroll-view>
- </view>
- </view>
- <!-- <view class="">
- 预约时间:{{orderDateTime.begin}}
- </view> -->
- <button @click="reservationPopup()" class="confirm_button" >确认预约</button>
- <uni-popup ref="outcomePopup" :is-mask-click="false" >
- <view class="outcome_popup_layout">
- <view class="outcome_title">
- 预约成功
- </view>
- <view class="outcome_text" >
- 你已经预约:{{orderDateTime.begin}}直播主持课程
- </view>
- <button class="outcome_button" @click="outcomeButton()" >确认</button>
- </view>
- </uni-popup>
- <uni-popup ref="outcomeNoPay" :is-mask-click="false" >
- <view class="outcome_popup_layout">
- <view class="outcome_title">
- 未购物课程
- </view>
- <view class="outcome_text" >
- 你还未购买该课程,不可预约
- </view>
- <view class="outcome_but">
- <button class="outcome_button_pay" @click="outcomeNoPay()" >取消</button>
- <button class="outcome_button_pay" @click="outcomePay()" >立即购买</button>
- </view>
- </view>
- </uni-popup>
- </view>
- </template>
- <script>
- export default {
- props: {
- isQuantum: {
- type: Boolean,
- default: true
- },
- isMultiple: { //是否多选
- type: Boolean,
- default: false
- },
- isSection: { //预约时间段
- type: Boolean,
- default: false
- },
- disableText:{ //禁用显示的文本
- type: String,
- default: "已预约"
- },
- disableSumText:{
- type:String,
- default:"已约满"
- },
- undisableText: { //未禁用显示的文本
- type: String,
- default: "可预约"
- },
- timeInterval: { // 时间间隔,小时为单位
- type: Number,
- default: 1
- },
- selectedTabColor: { // 日期栏选中的颜色
- type: String,
- default: "#51bf81"
- },
- selectedItemColor: { // 时间选中的颜色
- type: String,
- default: "#51bf81"
- },
- beginTime: {
- type: String,
- default: "08:30"
- },
- endTime: {
- type: String,
- default: "19:30"
- },
- appointTime: { // 预约的时间
- type: Array,
- default () {
- return []
- }
- },
- disableTimeSlot: { // 预约开始和结束时间,来禁用时间段
- type: Array,
- default () {
- return []
- }
- }
- },
- watch: {
- appointTime: {
- handler(val) {
- if (val && val.length) {
- this.initOnload()
- }
- }
- },
- // disableTimeSlot: {
- // handler(val) {
- // if (val && val.length) {
- // this.initOnload()
- // }
- // }
- // },
- shcedule_list:{
- handler(val) {
- if(val && val.length){
- this.initOnload()
- }
- }
- }
- },
- data() {
- return {
- data:[
- ],
- shcedule_list:[],//排课列表
- teacher_desc: "",//当前老师的一个介绍
- course_name: "",//当前老师的名字
- course_image: "",//当前老师的图片
- orders_product_id:0,//商品id
- course_id:0,//课程id
- schedule_id:0,//排课id
- teacherActive:-1,
-
- orderDateTime: '暂无选择', // 选中时间
- orderTimeArr: {}, //多选的时间
- dateArr: [], //日期数据
- timeArr: [], //时间数据
- nowDate: "", // 当前日期
- dateActive: 0, //选中的日期索引
- timeActive: 0, //选中的时间索引
- timeQuanBeginIndex: 0, //时间段开始的下标
- selectDate: "", //选择的日期
- timeQuanBegin: "", //时间段开始时间
- timeQuanEnd: "", //时间段结束时间
- // isTime:[],
-
- }
- },
- onLoad(e) {
- //接受url参数
- let {orders_product_id,course_id} = e
- this.orders_product_id = orders_product_id
- this.course_id = course_id
- },
- onShow() {
- if(this.course_id > 0){
-
- this.$http.request('api/course/get_schedule_list',{course_id:this.course_id},'post').then((res)=>{
- if(res.code === "success"){
- this.data = res.data
- this.selectDate = this.currentTime().date
- this.defaultTeacherDesc()
- this.initOnload()
- }
- })
- }
-
- },
- methods: {
- //老师选择事件
- selectTeacher(index,item){
-
- if(this.teacherActive == index)return
-
- this.teacherActive = index;
-
- if(this.data.length >0){
- if(this.teacherActive == index){
- this.shcedule_list = this.data[index]["list"]
- this.teacher_id = this.data[index].teacher_id
- this.course_name = this.shcedule_list[0].course_name
- this.teacher_desc = this.shcedule_list[0].teacher_desc
- this.course_image = this.shcedule_list[0].course_image
- this.initOnload()
- }
- }
-
- },
-
- //默认选项
- defaultTeacherDesc(){
- this.teacherActive = 0
- if(this.data.length>0){
- this.teacher_id = this.data[0].teacher_id
- this.shcedule_list = this.data[0]["list"]
- this.course_name = this.shcedule_list[0].course_name
- this.teacher_desc = this.shcedule_list[0].teacher_desc
- this.course_image = this.shcedule_list[0].course_image
- console.log(this.shcedule_list);
- }
- },
- //预约课程事件
- reservationPopup(){
- //如果没有选择老师
- if(this.teacher_id === 0){
- uni.showToast({
- title:"请选择老师",
- icon:"none"
- })
- return
- }
- //没有选择预约日期
- if(this.dateActive < 0){
- uni.showToast({
- title:"请选择预约日期",
- icon:"none"
- })
- return
- }
- //没有选择预约时间
- if(this.timeActive < 0){
- uni.showToast({
- title:"请选择预约时间",
- icon:"none"
- })
- return
- }
- console.log(66,this.shcedule_id)
- this.$http.request("api/course/reservation/",{course_id:this.course_id,schedule_id:this.shcedule_id},'post').then((res)=>{
- if(res.code === 'success'){
- if (this.shcedule_id){
- this.shcedule_list.forEach((item, index) => {
- // 时间段
- if(item.id === this.shcedule_id){
- this.shcedule_list[index].disable = true
- this.shcedule_list[index].reservation_status = 1
- }
- })
- }
- this.handleSubmit();
- this.initOnload();
- this.$refs.outcomePopup.open("center")
- }else{
- uni.showToast({
- title: res.msg,
- icon:"none"
- })
- }
- })
-
- },
-
- outcomeButton(){
- this.$refs.outcomePopup.close();
- this.initOnload()
- },
- outcomeNoPay(){
- this.$refs.outcomeNoPay.close();
- },
- outcomePay(){
- uni.setStorageSync('shcedule_id', this.shcedule_id);
- uni.switchTab({
- url:"/pages/index/index?schedule_id",
- })
- },
- initOnload() {
- this.dateArr = this.initData() // 日期栏初始化
- console.log(this.isQuantum)
- this.timeArr = this.initTime(this.isQuantum) //时间选项初始化
- console.log(3,this.timeArr);
- this.timeQuanBegin = this.timeQuanEnd = ""
- console.log(4,this.orderTimeArr)
- let isFullTime = true
- this.timeArr.forEach((item, index) => {
- // 时间段
- if (this.isQuantum) {
- console.log(33,item)
- if(item.reservation_status === 1){
- console.log(222)
- item.disable = true
- }
- // 将预约的时间禁用
- /*this.appointTime.forEach(t => {
- let [date, time] = t.split(' ')
- if (date == this.selectDate && item.begin == time) {
- console.log(66,item)
- item.disable = true
- }
- })*/
- }
- })
- this.timeActive = -1
- },
-
- // 日期选择事件
- selectDateEvent(index, item) {
- if(this.dateActive == index)return
- this.dateActive = index
- this.selectDate = item.date
- console.log(1,this.selectDate)
- console.log(2,this.dateActive)
- this.initOnload()
- },
-
- // 时间选择事件
- selectTimeEvent(index, item) {
- if (item.disable) return
- if(item.disableSum) return
- console.log(item.shcedule_id)
- this.shcedule_id = item.shcedule_id
- if (this.isQuantum) {
- return this.handleSelectQuantum(index, item)
-
- }
-
- // if (this.isMultiple) {
- // item.isActive = !item.isActive
- // this.timeArr = this.timeArr.slice()
- // this.orderTimeArr[this.selectDate] = this.timeArr.reduce((prev, cur) => {
- // cur.isActive && prev.push(cur.time)
- // return prev
- // }, [])
- // } else {
-
- // this.timeActive = index
- // this.orderDateTime = `${this.selectDate} ${item.time}`
- // }
- },
-
- handleSelectQuantum(index, item) {
- if (item.disable) return
- this.timeActive = index
- this.orderDateTime = {
- begin: `${this.selectDate} ${item.begin}`,
- end: `${this.selectDate} ${item.end}`,
- }
-
- },
-
- handleSubmit() {
- this.appointTime.push(this.orderDateTime.begin)
- console.log(this.appointTime);
- },
-
-
- //字符串拼接
- strFormat(str) {
- return str < 10 ? `0${str}` : str
- },
- // 获取当前时间
- currentTime() {
- const myDate = new Date();
- const y = myDate.getFullYear()
- const m = myDate.getMonth() + 1;
- const d = myDate.getDate();
- const date = y + '-' + this.strFormat(m) + '-' + this.strFormat(d);
-
- const hour = myDate.getHours()
- const min = myDate.getMinutes()
- const secon = myDate.getSeconds()
- const time = this.strFormat(hour) + ':' + this.strFormat(min) + ':' + this.strFormat(secon);
- return {
- date,
- time
- }
- },
-
- //时间戳转日期
- timeStamp(time, isQuantum) {
- const dates = new Date(time)
- const year = dates.getFullYear()
- const month = dates.getMonth() + 1
- const date = dates.getDate()
- const day = dates.getDay()
- const hour = dates.getHours()
- const min = dates.getMinutes()
- const days = [ '日', '一', '二', '三', '四', '五', '六']
- return {
- allDate: `${year}/${this.strFormat(month)}/${this.strFormat(date)}`,
- date: `${this.strFormat(year)}-${this.strFormat(month)}-${this.strFormat(date)}`, //返回的日期 07-01
- day: `周${days[day]}`, //返回的礼拜天数 星期一
- hour: this.strFormat(hour) + ':' + this.strFormat(min) + (isQuantum ? "" : '') //返回的时钟 08:00
- }
- },
-
- //获取最近7天的日期和礼拜天数
- initData() {
- const time = []
- const date = new Date()
- const now = date.getTime() //获取当前日期的时间戳
- // const now = this.start_time *1000
- let timeStr = 3600 * 24 * 1000 //一天的时间戳
- let obj = {
- 0: "今天",
- // 1: "明天",
- // 2: "后天"
- }
- for (let i = 0; i < 7; i++) {
- time.push({
- date: this.timeStamp(now + timeStr * i).date, //保存日期
- timeStamp: now + timeStr * i, //保存时间戳
- week: obj[i]?? this.timeStamp(now + timeStr * i).day
- })
- }
- return time
- },
-
- //时间数组
- // this.shcedule_list[{"start_time":1732060800,"end_time":1732063500}];
- initTime( isQuantum) {
- const time = []
- let disable = false
- this.shcedule_list.forEach((cruTiem)=>{
- let selectDateStr = new Date(this.selectDate + ' 00:00:00').getTime()
- let starTimeStamp = cruTiem.start_time * 1000
- let endTimeStamp = cruTiem.end_time * 1000
- if (starTimeStamp > Date.now()){
- disable = true
- }
- if (starTimeStamp >= selectDateStr && (selectDateStr + 24*60*60*1000) >= endTimeStamp) {
- let timeStr = 60 * 1000 * cruTiem.duration
- console.log(starTimeStamp,endTimeStamp);
- // timeStr = 60 * 1000 * i.duration
- if (isQuantum) {
- time.push({
- begin: this.timeStamp(starTimeStamp , isQuantum).hour,
- end: this.timeStamp(endTimeStamp , isQuantum).hour,
- reservationSum:`${cruTiem.reservation_number}/${cruTiem.course_number}`,
- reservation_status:cruTiem.reservation_status,
- shcedule_id:cruTiem.id,
- disable: false
- })
- }
- }
- })
- return time
- },
- }
- }
- </script>
- <style lang="less">
- .reservation_layout{
- width: 750rpx;
- // margin: 30rpx auto;
- .header_title{
- width: 690rpx;
- margin: 30rpx auto;
- display: flex;
- justify-content: space-between;
- .left{
- display: inline-flex;
- flex-direction: column;
- justify-content: center;
- .title {
- font-size: 50rpx;
- font-weight: bold;
- margin-bottom: 10rpx;
- }
- .subtitle{
- font-size: 26rpx;
- color: #868686;
- }
- }
- .right{
- width: 154rpx;
- height: 154rpx;
- .image{
- width: 154rpx;
- height: 154rpx;
- border-radius: 50%;
- }
- }
- }
- .teacher_list{
- width: 690rpx;
- margin: 30rpx auto;
- display: flex;
- flex-wrap: wrap;
- .teacher_item{
- background-color: #ffffff;
- width: 280rpx;
- padding: 10rpx;
- margin: 20rpx;
- border-radius: 20rpx;
- text-align: center;
- }
- .teacher_item.active{
- color: #51bf81;
- border: 2rpx solid #51bf81;
- }
- }
- .course{
- width: 690rpx;
- margin: 0rpx auto;
- // border: 2rpx solid;
- scroll-view{
- width: 100%;
- white-space: nowrap;
- height: 75px;
- background-color: #fff;
- position: relative;
- padding-top: 10rpx;
- }
- .days{
- display: flex;
- background-color: #ffffff;
- .day{
- display: inline-flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin: 0rpx 20rpx;
- height: 115rpx;
- text{
- margin: 10rpx 0rpx;
- }
- }
- .day.borderb {
- border-bottom: 2px solid #51bf81;
- }
- }
- .times{
- // border: 2rpx solid;
- scroll-view{
- width: 100%;
- // white-space: nowrap;
- height: 300px;
- background-color: #fff;
- // position: relative;
- padding-top: 10rpx;
- }
- .time_list{
- display: flex;
- flex-wrap: wrap;
- background-color: #ffffff;
- .day{
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- width: 200rpx;
- height: 200rpx;
- background-color: #f3f3f3;
- margin: 10rpx;
- border-radius: 20rpx;
- .time{
- margin: 20rpx;
-
- }
- }
- }
- }
- }
- .confirm_button {
- font-size: 40rpx;
- font-weight: 600;
- width: 690rpx;
- left: 30rpx;
- position: fixed;
- bottom: 100rpx;
- background-color:#51bf81;
- color: #fff;
- padding: 5px;
- border-radius: 60rpx;
- }
-
-
- .popup_layout{
- background-color: #ffffff;
- width: 750rpx;
- height: 60vh;
- border-radius: 40rpx;
- padding-top: 1px;
- .title{
- font-size: 40rpx;
- font-weight: bold;
- margin: 30rpx;
- }
- .time_list{
- display: flex;
- justify-content: space-between;
- flex-wrap: wrap;
- margin: 30rpx;
- .time_item{
- display: inline-flex;
- justify-content: center;
- align-items: center;
- padding: 10rpx;
- width: 200rpx;
- margin: 10rpx 0rpx;
- border: 2rpx solid;
- }
- }
- }
- .outcome_popup_layout{
- width: 690rpx;
- background-color: #ffffff;
- display: flex;
- flex-direction: column;
- border-radius: 40rpx;
- overflow: hidden;
- .outcome_title{
- display: inline-flex;
- justify-content: center;
- align-items: center;
- padding: 10rpx;
- margin: 30rpx;
- font-size: 40rpx;
- font-weight: bold;
- color: #000000;
- }
- .outcome_text{
- display: inline-flex;
- justify-content: center;
- align-items: center;
- margin: 30rpx auto;
- width: 576rpx;
- height: 50rpx;
- padding:20rpx;
- }
- .outcome_button{
- width: 100%;
- height: 100%;
- // height: 100%;
- }
- .outcome_button_pay{
- float: left;
- width: 50%;
- height: 100%;
- // height: 100%;
- }
- }
- }
- </style>
|