<template> <view class="pages"> <view class="navbar-box"> <u-navbar title="订单详情" :safeAreaInsetTop="true" @leftClick="leftClick" :titleStyle="{color:'#fff'}" leftIconColor="#fff" bgColor="transparent"></u-navbar> </view> <view class="banner"> <!-- <image class="img" :src="staticUrl+'/img/bookticket-banner.png'" alt=""> --> <image class="img" :src="theatre.showImg" alt=""> <view class="content"> <view class="share" @click="openShare(item)"> <image class="icon" :src="staticUrl+'/img/share-ico.png'" ></image> </view> <view class="name">{{theatre.name}}</view> <view class="addr u-flex u-row-between"> <view class="text">{{theatre.address}}</view> <u-icon name="arrow-right" color="#ffffff" size="36rpx" @click="goMap"></u-icon> </view> </view> </view> <view class="tabs-wrap"> <view class="inner"> <u-tabs :list="tabsArr" @click="tabsClick" lineColor="#ED0000" lineWidth="82rpx" :activeStyle="{color: '#2D2D2D',fontWeight: 'bold'}" itemStyle="width:33%; height: 46px;box-sizing:border-box" > </u-tabs> </view> </view> <view class="page-wrap"> <view class="ticket" v-if="tabsIndex==0"> <view class="date-block auditorium"> <view class="title">演出厅</view> <view class="date-list u-flex u-flex-wrap"> <view class="date-item" :class="{active:auditoriumIndex==index}" @click="auditoriumClick(index)" v-for="(date,index) in auditoriumList" :key="index"> <view class="name">{{ date.name }}</view> </view> </view> </view> <view class="date-block"> <view class="title">演出日期</view> <view class="date-list u-flex"> <view class="date-item" :class="{active:dateIndex==index}" @click="dateClick(index)" v-for="(date,index) in dateList" :key="index"> <view class="name">{{ date.name || ' ' }}</view> <view class="date">{{ date.month }} - {{ date.day }}</view> </view> <view class="date-item more-date u-flex u-row-center" @click="calendarShow = true"> <view class="text"> <view class="">更多</view> <view class="">日期</view> </view> <u-icon name="arrow-right" color="#7F7F7F" size="24rpx"></u-icon> </view> </view> </view> <view class="date-block session-wrap"> <view class="title">演出场次</view> <view class="session"> <view class="session-item" :class="{active:sessionIndex==index}" @click="sessionClick(index)" v-for="(date,index) in sessionList" :key="index"> {{ date.performTimeStart}} - {{date.performTimeEnd}} </view> </view> <view class="empty" v-if="auditoriumList.length>=1&&sessionList.length<1"> 当前日期暂无演出场次,请重新选择 </view> </view> <view class="date-block ticket-type"> <view class="title">门票</view> <view class="type-item" :class="{active:sessionIndex==index}" v-for="(item,index) in ticketTypeList" :key="index"> <view class="name-price u-flex u-row-between"> <view class="name">{{item.goodsName}}</view> <view class="prices">¥ {{item.salePrice}}</view> </view> <!-- <view class="ishave"> <text class="text">{{(item.quantity>0&&sessionList.length>=1)?'有票':'无票'}}</text> </view> --> <view class="bottom u-flex u-row-between"> <view class="left u-flex"> <!-- 购票须知 <u-icon name="arrow-right" color="#7F7F7F" size="24rpx"></u-icon> --> {{item.goodsSnapshot}} </view> <view class="btn" @click="book(item)" v-if="item.quantity>0&&sessionList.length>=1">预定</view> <view class="btn disabled" v-else>无票</view> </view> </view> </view> </view> <!-- ticket end --> <view class="details" v-if="tabsIndex==1"> <view class="details-block"> <view class="title">剧情简介</view> <view class="intro"> <u-parse :content="performInfo.performSnapshot"></u-parse> </view> </view> <view class="details-block actors"> <view class="title u-flex u-row-between"> 演职人员 <view class="right u-flex" @click="$u.route('pages/actors',{performId:performId})"> <text>更多</text> <u-icon name="arrow-right" color="#7F7F7F" size="24rpx"></u-icon> </view> </view> <view class="actor-list"> <u-scroll-list :indicator="false"> <view class="item" v-for="(item, index) in actorsArr" :key="index"> <image class="img" :src="item.performerHead||staticUrl+'/img/actors.png'"></image> <view class="text"> <view class="name">{{item.performerName}}</view> <view class="role u-line-1">{{item.performerRole}}</view> </view> </view> </u-scroll-list> <u-empty text="暂无" v-if="actorsArr.length<1"></u-empty> </view> </view> </view> <view class="viewingTips" v-if="tabsIndex==2"> <u-parse :content="formerNotice"></u-parse> </view> </view> <u-calendar ref="calendar" :formatter="formatter" :maxDate="maxDate" :show="calendarShow" color="#EF1010" :closeOnClickOverlay="true" @close="closeCalendar" @confirm="confirmCalendar"> </u-calendar> <!-- 分享选择弹出内容 --> <view class="share-option" :class="{shareShow:shareShow}"> <view class="overlay" v-if="shareShow" @click="shareShow=false"></view> <button class="share-option-item wx-share" data-name="shareBtn" open-type="share"> 发送给朋友 </button> <view class="share-option-item" @click="getPoster">生成海报</view> <view class="share-option-item" @click="shareShow=false">取消</view> </view> <u-popup :show="posterShow" @close="posterShow=false" ref="uni-popup"> <view class="poster-wrap u-flex u-col-center"> <view class="poster-inner"> <view class="close-wrap" @click="posterShow=false"> <u-icon name="close-circle" color="#fff" size="56rpx"></u-icon> </view> <view class="poster" id="poster" ref="poster" > <u--image :showLoading="true" :src="posterSrc" width="100%" height="65vh" mode="aspectFit"></u--image> </view> <!-- savePoster --> <view class="poster-btn" @click="saveImage">保存图片</view> </view> </view> </u-popup> <canvas canvas-id="canvas" class="canvas" style="width: 670px; height: 900px;"></canvas> </view> </template> <script> import { systemInfo } from "@/mixin.js"; // 日历 const d = new Date() const year = d.getFullYear() let month = d.getMonth() + 1 month = month < 10 ? `0${month}` : month const date = d.getDate() // 日历 let parentThis= null; export default { mixins:[systemInfo], data() { return { performId:'', staticUrl:this.$commonConfig.staticUrl, tabsArr:[ {name:'票务购买'}, {name:'演出详情'}, {name:'观影须知'} ], theatre:{}, tabsIndex:0, dateList:[], dateIndex:0, calendarShow:false,//日历 maxDate:`${year}-${month}-${date + 30}`, auditoriumList:[],//演艺厅 auditoriumIndex:0, sessionList:[],//演出场次 sessionIndex:0, ticketTypeList:[],//门票 actorsArr:[], shareShow:false, posterShow:false, posterSrc:'', performInfo:{},//节目详情 formerNotice:{},//节目观影须知 performDateList:[],//有票的日期 } }, onShow() { }, onLoad(page) { parentThis = this; console.log('page',page); this.performId = page.id; this.getPerformData(); // this.getSystemInfo(); let today = new Date(); this.setDate(today); this.getPerformInfo(); this.getPerformerNotice(); }, onReady() { // 如果需要兼容微信小程序的话,需要用此写法 this.$refs.calendar.setFormatter(this.formatter); }, methods: { leftClick(e){ let pages = getCurrentPages(); if(pages.length==1){ uni.$u.route('/pages/index/index') }else{ uni.navigateBack() }; }, getPerformData(){ this.$u.api.performSell({performId:this.performId}).then(res=>{ // console.log('getPerformData',res.data); this.theatre = res.data.theatreList[0]; this.auditoriumList = res.data.theatreList[0].auditoriumList; this.ticketTypeList = res.data.goodsList; this.performDateList = this.auditoriumList[this.auditoriumIndex].performDateList; this.getTimes() // console.log('auditoriumList',this.auditoriumList); }).catch(err=>{ console.log('getPoster',err); }) }, getPerformInfo(){ this.$u.api.performInfo({id:this.performId}).then(res=>{ // console.log('getPerformInfo',res.data); this.performInfo = res.data; this.actorsArr = res.data.performerList; }).catch(err=>{ console.log('getPerformInfo',err); }) }, getPerformerNotice(){ this.$u.api.performerNotice({performId:this.performId}).then(res=>{ // console.log('getPerformerNotice',res.data); this.formerNotice = res.data.performNotice; }).catch(err=>{ console.log('getPerformerNotice',err); }) }, getTimes(){ let auditoriumId= this.auditoriumList[this.auditoriumIndex]?.id; if(!auditoriumId){return} let dateOBJ = this.dateList[this.dateIndex]; let param = { auditoriumId:auditoriumId,//演艺厅ID(演艺厅列表) performId:this.performId, date:`${dateOBJ.year}-${dateOBJ.month}-${dateOBJ.day}` }; // console.log('param',param); this.$u.api.getAuditoriumTimes(param).then(res=>{ // console.log('getTimes',res.data); this.sessionList = res.data.list.map(item=>{ item.performTimeStart = item.performTimeStart; item.performTimeEnd = item.performTimeEnd; return item }); }).catch(err=>{ console.log('getPoster',err); }) }, formatter: (day) => { // console.log('day',day); // console.log('thisthisthisthisthisthisthisthisthis',parentThis); // console.log('==================================',day.date.toISOString().split('T')[0]); let ticket = parentThis.performDateList.find(item => item.performDate === day.date.toISOString().split('T')[0]); if(ticket){ day.dot = true } // if(ticket&&ticket.ishave){ // day.bottomInfo = '有票' // day.dot = true // }else if(ticket){ // day.dot = true // } return day }, setDate(firstDay,isSelect){ if(this.performDateList[0]&&!isSelect){ firstDay = new Date(this.performDateList[0].day); } // console.log('this.dateListthis.dateListthis.dateListthis.dateList',this.dateList); // 前端写演出日期(今天,明天,后天) let today = firstDay; let tomorrow = new Date(); tomorrow.setDate(today.getDate() + 1); let afterTomorrow = new Date(); afterTomorrow.setDate(today.getDate() + 2); this.dateList = [ { year: today.getFullYear(), month: today.getMonth() + 1, day: today.getDate(),name:'日期' }, { year: tomorrow.getFullYear(), month: tomorrow.getMonth() + 1, day: tomorrow.getDate() ,name:'日期'}, { year: afterTomorrow.getFullYear(), month: afterTomorrow.getMonth() + 1, day: afterTomorrow.getDate(),name:'日期' } ]; this.getTimes() }, dateClick(index){ this.dateIndex = index; this.getTimes() }, auditoriumClick(index){ this.auditoriumIndex = index; }, confirmCalendar(e){ // console.log('confirmCalendar',e); this.setDate( new Date(e),true ); this.dateIndex = 0; // console.log('maxDate',this.maxDate); // console.log('dateList',this.dateList); this.calendarShow = false; }, closeCalendar(){ this.calendarShow = false; }, tabsClick(e){ // console.log('tabsClick',e); this.tabsIndex = e.index; }, sessionClick(index){ this.sessionIndex = index; }, book(item){ // console.log('book',item); // console.log('performInfo',this.performInfo); let session = this.sessionList[this.sessionIndex]; // console.log('session',session); let performTimeStart = session.performTimeStart; let performTimeEnd = session.performTimeEnd; let dateOBJ = this.dateList[this.dateIndex]; uni.$u.route('pages/chosenposition',{ goodsId:item.id, performId:this.performId, performName:this.performInfo.name, day:`${dateOBJ.year}-${dateOBJ.month}-${dateOBJ.day}`, performTimeStart:session.performTimeStart, performTimeEnd:session.performTimeEnd, performTimeId:session.id, auditoriumId:this.auditoriumList[this.auditoriumIndex].id }) }, openShare(){ this.shareShow = true; // 前端生成海报开始 let that = this; const ctx = uni.createCanvasContext('canvas', this); // 加载海报背景图 uni.getImageInfo({ src: this.performInfo.posterImg, success: res1 => { const img1 = res1.path; // 加载海报二维码 uni.getImageInfo({ src: this.performInfo.appletQrcode, success: res2 => { const img2 = res2.path; // 绘制海报背景图 ctx.drawImage(img1, 0, 0, 670, 900); // 绘制海报二维码 ctx.drawImage(img2, 468, 724, 188, 166); // 绘制完成后导出图片并显示 ctx.draw(false, () => { uni.canvasToTempFilePath({ canvasId: 'canvas', success: res3 => { this.posterSrc = res3.tempFilePath; }, fail: err => { console.error(err); }, }, this); }); }, fail: err2 => { console.error(err2); }, }); }, fail: err1 => { console.error(err1); }, }); // 前端生成海报结束 }, // 海报相关开始 getPoster(item){ this.posterShow = true; this.shareShow = false; // 后端生成海报 // this.$u.api.performQrcode({performId:this.performId}).then(res=>{ // this.posterSrc = res.data.imageUrl; // // console.log('getPoster',res.data); // }).catch(err=>{ // console.log('getPoster',err); // }) }, saveImage() { let that = this; uni.showLoading({ title: '保存中' }); uni.downloadFile({ url: this.posterSrc, success(res) { if (res.statusCode === 200) { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success() { uni.showToast({ title: '保存到相册成功', icon: 'success' }); }, fail(err) { console.log('保存图片失败',err); if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') { uni.getSetting({ success(res) { if (!res.authSetting['scope.writePhotosAlbum']) { uni.showModal({ title: '提示', content: '您还没有授权访问相册,请前往设置页面打开权限。', confirmText: '去设置', success(res) { if (res.confirm) { uni.openSetting(); } } }); } else { uni.showToast({ title: '保存图片失败', icon: 'none' }); } } }); } else { uni.showToast({ title: '保存图片失败', icon: 'none' }); } }, complete() { uni.hideLoading(); that.posterShow = false; } }); } else { uni.showToast({ title: '下载图片失败', icon: 'none' }); } }, fail() { uni.showToast({ title: '下载图片失败', icon: 'none' }); } }); }, // 海报相关结束 goMap(){ uni.openLocation({ latitude:Number(this.theatre.latitude), //维度 longitude: Number(this.theatre.longitude), //经度 name: this.theatre.name, //目的地定位名称 scale: 15, //缩放比例 address: this.theatre.address //导航详细地址 }) }, } } </script> <style lang="scss" scoped> .banner{ position: relative; .img{ width: 750rpx; height: 554rpx; display: block; } .content{ position: absolute; width: 100%; box-sizing: border-box; padding: 0 32rpx; left: 0; bottom: 100rpx; } .share{ overflow: hidden; margin-bottom: 100rpx; .icon{ float: right; display: block; width: 32rpx; height: 32rpx; padding: 10rpx; border-radius: 50%; background-color: rgba(0,0,0,0.4); } } .name{ font-size: 44rpx; font-weight: 800; color: #FFFFFF; line-height: 66rpx; margin-bottom: 38rpx; } .addr{ font-size: 24rpx; font-weight: 400; color: #FFFFFF; line-height: 36rpx; } } .tabs-wrap{ position: relative; margin-bottom: 54rpx; &::after{ content: ''; width: 100%; height: 1px; background-color: #eee; position: absolute; left: 0; right: 0; bottom: -46rpx; } .inner{ position: relative; padding-top: 50rpx; background-color: #FFFFFF; border-radius: 32rpx 32rpx 0rpx 0rpx; height: 46rpx; margin-top: -30px; } } .date-block{ margin-bottom: 64rpx; } .title{ font-size: 32rpx; font-weight: bold; color: #2D2D2D; line-height: 48rpx; margin-bottom: 38rpx; } .session-wrap{ .empty{ background-color: #636363; color: #979797; border-radius: 8rpx; padding: 24rpx; text-align: center; } } .session{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 20rpx; .session-item{ height: 80rpx; line-height: 80rpx; border-radius: 12rpx; border: 2rpx solid #636363; text-align: center; font-size: 24rpx; font-weight: 400; color: #636363; &.active{ color: #ED0000; border-color: #ED0000; } } } .ticket-type{ .type-item{ background: #FFFFFF; box-shadow: 0rpx 2rpx 12rpx 0rpx rgba(180,180,180,0.5); border-radius: 20rpx; margin-bottom: 20rpx; padding: 38rpx 40rpx; .name-price{ margin-bottom: 26rpx; } .name{ font-size: 28rpx; font-weight: 500; color: #363636; } .prices{ font-size: 36rpx; font-weight: bold; color: #ED0000; } .ishave{ margin-bottom: 26rpx; .text{ height: 30rpx; line-height: 30rpx; padding: 0 22rpx; background: #FFC8C8; border-radius: 20rpx; font-size: 20rpx; font-weight: 400; color: #ED0000; } } .bottom{ font-size: 22rpx; font-weight: 400; color: #7F7F7F; .btn{ height: 60rpx; line-height: 60rpx; background: linear-gradient(90deg, #FF7979 0%, #ED0000 100%); border-radius: 30rpx; padding: 0 36rpx; font-size: 28rpx; font-weight: 500; color: #FFFFFF; &.disabled{ background: #979797; } } } } } .details{ .title{} .details-block{ background: #FFFFFF; box-shadow: 0rpx 2rpx 12rpx 2rpx rgba(221,221,221,0.5); border-radius: 20rpx; margin-bottom: 24rpx; padding: 36rpx; &.actors{ .title{ .right{ font-size: 24rpx; font-weight: 400; color: #7F7F7F; } } } } .intro{ font-size: 26rpx; font-weight: 400; color: #4E4E4E; line-height: 40rpx; } .actor-list{ .item{ flex-shrink: 0; width: 160rpx; text-align: center; margin-right: 24rpx; } .img{ display: block; width: 100%; height: 200rpx; margin-bottom: 16rpx; } .name{ font-size: 28rpx; font-weight: 500; color: #2D2D2D; line-height: 42rpx; margin-bottom: 4rpx; } .role{ font-size: 24rpx; font-weight: 400; color: #7F7F7F; line-height: 36rpx; } } } .canvas{ position: absolute; left: -99999px; } </style>