vr-shopxo-uniapp/pages/plugins/vr-ticket-wallet/ticket-wallet.vue

790 lines
28 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view :class="theme_view" class="ticket-wallet-page">
<!-- 顶部返回 + 标题导航 -->
<!-- <view class="top-nav-bar">
<view class="nav-back" @click="goBack">
<text class="back-arrow"></text>
</view>
<view class="nav-title">
<text class="title-text">我的票夹</text>
<text class="ticket-count" v-if="totalActiveCount > 0">{{ totalActiveCount }}张待使用</text>
</view>
<view class="nav-placeholder"></view>
</view> -->
<!-- 主内容区域 -->
<scroll-view
class="wallet-scroll"
scroll-y
:refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onPullDownRefresh"
>
<!-- 顶部潮流 Banner -->
<view class="brand-banner">
<!-- 氛围模糊渐变光晕 -->
<view class="ambiance-light-1"></view>
<view class="ambiance-light-2"></view>
<!-- 等高线矢量线条背景 -->
<svg class="contour-bg" viewBox="0 0 400 300" fill="none" stroke="currentColor">
<path d="M-50,60 C80,30 180,120 450,40" stroke-width="1" stroke-dasharray="3 3" />
<path d="M-50,110 C90,70 190,170 450,90" stroke-width="1" />
<path d="M-50,160 C100,120 200,210 450,140" stroke-width="0.8" />
<path d="M-50,210 C110,170 210,250 450,190" stroke-width="1.2" />
<path d="M-50,260 C120,220 220,290 450,240" stroke-width="0.8" stroke-dasharray="4 2" />
</svg>
<!-- 旋转黑胶唱片左侧(背景大黑胶) -->
<view class="record-disc-large">
<view class="record-body">
<view class="record-circle-1"></view>
<view class="record-circle-2"></view>
<view class="record-center">
<view class="record-dot"></view>
</view>
</view>
</view>
<!-- 旋转黑胶唱片右侧(背景小黑胶) -->
<view class="record-disc-small">
<view class="record-body">
<view class="record-circle-1"></view>
<view class="record-circle-2"></view>
<view class="record-center">
<view class="record-dot"></view>
</view>
</view>
</view>
<!-- 涂鸦笑脸 -->
<view class="graffiti-face">
<svg class="graffiti-svg" viewBox="0 0 40 40" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<circle cx="20" cy="20" r="16" />
<path d="M14,16 L14.01,16 M26,16 L26.01,16" stroke-width="3.5" />
<path d="M13,22 Q20,29 27,22" />
</svg>
</view>
<!-- Live Music 竖排小文字 -->
<view class="live-music-tag">
<text>l</text><text>i</text><text>v</text><text>e</text>
<text class="live-music-dot">•</text>
<text>m</text><text>u</text><text>s</text><text>i</text><text>c</text>
<text class="live-music-dot">•</text>
<text>i</text><text>n</text>
</view>
<view class="live-music-subtag">
<text>v</text><text>r</text><text>t</text><text>i</text><text>c</text><text>k</text><text>e</text><text>t</text>
</view>
<!-- 品牌旋转星标 Hub -->
<view class="brand-star-hub">
<!-- 品牌旋转星标文字环 (使用 xlink:href 兼容小程序) -->
<svg class="rotating-text-svg svg-compat" viewBox="0 0 120 120">
<path id="vrTicketPath" d="M 60 16 A 44 44 0 1 1 59.9 16" fill="none" />
<text fill="black" style="font-size: 7.2px; font-weight: 900; letter-spacing: 0.26em;">
<textPath xlink:href="#vrTicketPath" startOffset="0%">
VRTICKET • VRTICKET • VRTICKET • VRTICKET •
</textPath>
</text>
</svg>
<!-- 四角星中心 -->
<svg class="star-core-svg" viewBox="0 0 100 100" fill="none">
<path d="M 50 2 C 50 38 38 50 2 50 C 38 50 50 62 50 98 C 50 62 62 50 98 50 C 62 50 50 38 50 2 Z" fill="black" />
</svg>
<!-- 斜横幅标 -->
<view class="brand-label-plate">
VRTicket
</view>
</view>
</view>
<!-- 票券主面板容器 -->
<view class="ticket-panel-container">
<!-- 待使用演出列表 -->
<view class="section-header-row" v-if="activeGroups.length > 0">
<text class="section-main-title">待核销票据</text>
<view class="section-count-badge">
<text>共</text>
<text class="section-count-number">{{ totalActiveCount }}</text>
<text>张票</text>
</view>
</view>
<view class="section-block" v-if="activeGroups.length > 0">
<view
class="ticket-group-card"
v-for="(group, gIdx) in activeGroups"
:key="'active-' + gIdx"
@click="openQrPopup(group)"
>
<!-- 左右侧切打孔 notch -->
<view class="ticket-punch-hole-left"></view>
<view class="ticket-punch-hole-right"></view>
<!-- 卡券主要内容区 -->
<view class="card-inner-box">
<!-- 影院/场馆行 + 动作按钮 -->
<view class="card-header-row">
<view class="cinema-title-wrap">
<iconfont name="icon-store" size="32rpx" color="#000000" propClass="lh-il va-m"></iconfont>
<text class="cinema-title-text">{{ group.venue_name || '测试场馆' }}</text>
</view>
<!-- 快捷联系 actions -->
<view class="action-buttons">
<!-- 电话呼叫 -->
<view class="action-circle-btn" @click.stop="callService(group.venue_name)">
<iconfont name="icon-phone" size="28rpx" color="#444444" propClass="lh-il va-m"></iconfont>
</view>
<!-- 地图导航 -->
<view class="action-circle-btn" @click.stop="openNavigation(group.venue_name)">
<iconfont name="icon-map-location" size="28rpx" color="#444444" propClass="lh-il va-m"></iconfont>
</view>
</view>
</view>
<!-- 详细内容主体 (左栏文本 + 右栏电影海报小卡) -->
<view class="card-content-body">
<!-- 左边栏:名称、时间、座位 -->
<view class="card-left-info">
<text class="movie-title-text">{{ group.goods_title }}</text>
<!-- <text class="movie-format-tag">{{ group.tickets[0] && group.tickets[0].goods_type === 1 ? '国语 3D' : '国语 2D' }}</text> -->
<!-- 时间点Montserrat 重磅粗体) -->
<view class="session-time-text">{{ formatSessionTime(group.session_time) }}</view>
<!-- 座位信息块 -->
<view class="seat-badge-block">
<!-- 场馆厅信息 -->
<view class="seat-hall-text" v-if="group.tickets[0] && getHallFromSeatInfo(group.tickets[0].seat_info)">
<iconfont name="icon-map-position" size="24rpx" color="#e1251b" propClass="lh-il va-m mr-xs"></iconfont> {{ getHallFromSeatInfo(group.tickets[0].seat_info) }}
</view>
<!-- 座位号列表 -->
<view class="seat-detail-wrap">
<view class="seat-numbers-list">
<text v-for="(t, tIdx) in group.tickets" :key="t.id" class="seat-item">
{{ t.seat_number }}
</text>
</view>
</view>
</view>
</view>
<!-- 右边栏:高颜值海报小卡 -->
<view class="card-right-poster">
<!-- 红光氛围灯效 overlay -->
<view class="poster-spotlight"></view>
<image
class="poster-image-item"
:src="resolveImageUrl(group.goods_image) || defaultPoster"
mode="aspectFill"
/>
<!-- 海报底部的水印文字 -->
<view class="poster-text-overlay" v-if="!group.goods_image">
<text class="poster-abbr-title">{{ getShortTitle(group.goods_title) }}</text>
<text class="poster-en-title">{{ getEnTitle(group.goods_title) }}</text>
</view>
<!-- <view class="poster-format-badge">EVE</view> -->
</view>
</view>
<!-- 底部查看票码分割栏 -->
<view class="ticket-card-footer">
<text class="footer-tip-text">使用时请点击展示二维码/条形码</text>
<text class="view-code-text">查看票码 </text>
</view>
</view>
</view>
</view>
<!-- 空状态:没有待使用票据 -->
<view class="empty-section" v-else-if="!isLoading && loadStatus === 3">
<image class="empty-icon" src="/static/images/common/no-data.png" mode="aspectFit" />
<text class="empty-text">暂无待使用的电子票</text>
<view class="empty-tip">
<text>购买演出票后,在这里查看</text>
</view>
</view>
<!-- 加载中骨架 -->
<view class="loading-section" v-if="isLoading">
<view class="skeleton-card" v-for="i in 2" :key="i">
<view class="skeleton-header">
<view class="skeleton-thumb"></view>
<view class="skeleton-meta">
<view class="skeleton-line short"></view>
<view class="skeleton-line"></view>
<view class="skeleton-line"></view>
</view>
</view>
<view class="skeleton-divider"></view>
<view class="skeleton-footer"></view>
</view>
</view>
<!-- 历史票根 -->
<view v-if="historyGroups.length > 0">
<view class="history-section-title-wrap">
<text class="history-section-title">历史票根 ({{ historyGroups.length }})</text>
</view>
<view
class="ticket-group-card history-card"
v-for="(group, gIdx) in historyGroups"
:key="'history-' + gIdx"
>
<!-- 左右侧切打孔 notch -->
<!-- 左右侧切打孔 notch -->
<view class="ticket-punch-hole-left"></view>
<view class="ticket-punch-hole-right"></view>
<!-- 核销水印盖章 -->
<view class="stamp-container">
<view class="verified-stamp" :class="{ 'refunded': group.tickets[0] && group.tickets[0].verify_status !== 1 }">
{{ group.tickets[0] && group.tickets[0].verify_status === 1 ? '已核销 PASSED' : '已退款 REFUND' }}
</view>
</view>
<!-- 卡券内容区 -->
<view class="card-inner-box">
<!-- 影院/场馆行 -->
<view class="card-header-row">
<view class="cinema-title-wrap">
<iconfont name="icon-store" size="32rpx" color="#888888" propClass="lh-il va-m"></iconfont>
<text class="cinema-title-text">{{ group.venue_name || '测试场馆' }}</text>
</view>
</view>
<!-- 详细内容主体 -->
<view class="card-content-body">
<view class="card-left-info">
<text class="movie-title-text">{{ group.goods_title }}</text>
<!-- <text class="movie-format-tag">{{ group.tickets[0] && group.tickets[0].goods_type === 1 ? '国语 3D' : '国语 2D' }}</text> -->
<view class="session-time-text">{{ formatSessionTime(group.session_time) }}</view>
<!-- 座位信息块 -->
<view class="seat-badge-block">
<!-- 场馆厅信息 -->
<view class="seat-hall-text" v-if="group.tickets[0] && getHallFromSeatInfo(group.tickets[0].seat_info)">
<iconfont name="icon-map-position" size="24rpx" color="#888888" propClass="lh-il va-m mr-xs"></iconfont> {{ getHallFromSeatInfo(group.tickets[0].seat_info) }}
</view>
<!-- 座位号列表 -->
<view class="seat-detail-wrap">
<view class="seat-numbers-list">
<text v-for="(t, tIdx) in group.tickets" :key="t.id" class="seat-item">
{{ t.seat_number }}
</text>
</view>
</view>
</view>
</view>
<!-- 海报小卡 -->
<view class="card-right-poster">
<image
class="poster-image-item"
:src="resolveImageUrl(group.goods_image) || defaultPoster"
mode="aspectFill"
/>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 底部安全区占位 -->
<view class="safe-area-bottom"></view>
</scroll-view>
<!-- QR 弹窗 -->
<u-popup
ref="qrPopupRef"
propType="center"
:propIsMaskClick="true"
:propRound="24"
:propBackgroundColor="qrPopupBg"
@change="onPopupChange"
@close="onPopupClose"
>
<ticket-qr-popup
:tickets="currentQrTickets"
:current-index="currentQrIndex"
:show-info="currentShowInfo"
@change="onQrSlideChange"
@refresh="onQrRefresh"
/>
</u-popup>
<!-- 提示弹窗 (Mock 效果) -->
<view v-if="showInfoModal" class="info-modal-mask" @click="showInfoModal = false">
<view class="info-modal-content" @click.stop>
<view class="info-modal-icon"></view>
<view class="info-modal-title">系统模拟提示</view>
<scroll-view scroll-y class="info-modal-scroll">
<text class="info-modal-text">{{ infoModalText }}</text>
</scroll-view>
<button class="info-modal-btn" @click="showInfoModal = false">关闭</button>
</view>
</view>
<!-- 快捷导航 -->
<component-quick-nav :propIsNav="true" :propIsBar="true" :propIsGrayscale="plugins_mourning_data_is_app"></component-quick-nav>
<!-- 公共 -->
<component-common ref="common" :propIsGrayscale="plugins_mourning_data_is_app"></component-common>
</view>
</template>
<script>
import uPopup from '@/components/u-popup/u-popup.vue';
import TicketQrPopup from './components/ticket-qr-popup/index.vue';
import componentCommon from '@/components/common/common';
import componentQuickNav from '@/components/quick-nav/quick-nav';
const app = getApp();
export default {
name: 'TicketWallet',
components: {
uPopup,
TicketQrPopup,
componentCommon,
componentQuickNav,
},
data() {
return {
// 主题样式
theme_view: '',
// 哀悼灰度插件
plugins_mourning_data_is_app: app.globalData.is_app_mourning(),
// 加载状态 1=加载中 2=加载失败 3=加载成功
loadStatus: 1,
isRefreshing: false,
// 原始票据列表API 返回扁平数组)
rawTickets: [],
// 默认海报兜底图
defaultPoster: '/static/images/common/empty.png',
// QR 弹窗控制(使用 ref.open()/close() 模式)
qrPopupBg: '#ffffff',
// 当前弹窗内展示的票(带 qr_payload
currentQrTickets: [],
currentQrIndex: 0,
currentShowInfo: {},
// 内部定时器
refreshTimer: null,
// 屏幕亮度
screenBrightnessValue: 0.5,
// 当前展示票的剩余秒数
currentExpiresIn: 0,
// 快捷互动遮罩
showInfoModal: false,
infoModalText: '',
};
},
computed: {
isLoading() {
return this.loadStatus === 1;
},
// 按演出 + 场次分组verify_status == 0
activeGroups() {
const active = this.rawTickets.filter(t => t.verify_status === 0);
return this.groupByShow(active);
},
// 历史票根分组verify_status == 1 已核销 或 2 已退款)
historyGroups() {
const history = this.rawTickets.filter(t => t.verify_status === 1 || t.verify_status === 2);
return this.groupByShow(history);
},
// 待使用票据总张数
totalActiveCount() {
return this.activeGroups.reduce((sum, g) => sum + g.tickets.length, 0);
},
},
onLoad(params) {
// 调用公共事件方法
app.globalData.page_event_onload_handle(params);
// 记录来源页面
if (params && params.from) {
this.sourceFrom = params.from;
}
// 获取初始屏幕亮度
// #ifndef H5
uni.getScreenBrightness({
success: (res) => {
this.screenBrightnessValue = res.value;
},
});
// #endif
},
onShow() {
// 调用公共事件方法
app.globalData.page_event_onshow_handle();
// 加载票据列表
this.init();
// 初始化配置
if (app.globalData.get_config('status') == 1) {
app.globalData.init_config(0, this, 'init_config', true);
} else {
app.globalData.is_config(this, 'init_config');
}
// 公共onshow事件
if ((this.$refs.common || null) != null) {
this.$refs.common.on_show({object: this, method: 'init'});
}
},
onUnload() {
this.clearRefreshTimer();
this.restoreScreenBrightness();
},
methods: {
// 初始化配置
init_config(status) {
if ((status || false) == true) {
var theme_view = app.globalData.get_theme_value_view();
var mourning = parseInt(app.globalData.get_config('plugins_mourning_data') || 0) == 1;
this.setData({
theme_view: theme_view,
plugins_mourning_data_is_app: mourning,
});
}
},
// 返回上一页
goBack() {
const pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.reLaunch({ url: '/pages/index/index' });
}
},
// 格式化日期与时间
formatSessionDate(timeStr) {
if (!timeStr) return '';
const parts = timeStr.split(' ');
return parts[0] || '';
},
formatSessionTime(timeStr) {
if (!timeStr) return '';
// session_time is already in "08:00-23:59" format
return timeStr;
},
getShortTitle(title) {
if (!title) return '潮流演艺';
return title.slice(0, 4);
},
// 从 seat_info 中提取场馆厅信息
// seat_info 格式: "08:00-23:59|测试场馆|老展厅 1|A|2排1座"
getHallFromSeatInfo(seatInfo) {
if (!seatInfo) return '';
const parts = seatInfo.split('|');
// parts[2] 是厅信息,如 "老展厅 1"
return parts[2] || '';
},
getEnTitle(title) {
if (!title) return 'LIVE MUSIC SHOW';
return 'CREATIVE EXPERIENCE';
},
// 将相对路径拼接为完整静态资源 URL兼容非 H5 环境)
resolveImageUrl(path) {
if (!path) return '';
// 已经是完整 URL 则直接返回
if (path.indexOf('http') === 0) return path;
// 相对路径补上 static_url
var base = (app.globalData.data.static_url || '').replace(/\/+$/, '');
return base + '/' + path.replace(/^\/+/, '');
},
callService(venueName) {
this.infoModalText = `正在虚拟呼叫 「${venueName}」 客服热线:\n\n📞 400-880-9911\n\n[提示]:由于在安全沙箱中运行,呼叫将在本地虚拟完成,为您解答关于演出的任何问题。`;
this.showInfoModal = true;
},
openNavigation(venueName) {
this.infoModalText = `📌 正在智能检索并规划前往「${venueName}」的最佳通行路线:\n\n- 驾车:预计 12 分钟 (3.5公里)\n- 步行:预计 25 分钟 (1.8公里)\n- 地铁2号线直达\n\n路线规划成功已无线映射至您的智能HUD导航`;
this.showInfoModal = true;
},
// 初始化加载
init() {
var self = this;
var user = app.globalData.get_user_info(this, 'init');
if (user == false) {
this.loadStatus = 2;
return;
}
this.loadStatus = 1;
uni.request({
url: app.globalData.get_request_url('list', 'ticket', 'vr_ticket'),
method: 'GET',
dataType: 'json',
success: function(res) {
if (res.data.code == 0) {
var tickets = res.data.data.tickets || [];
self.rawTickets = tickets;
self.loadStatus = 3;
} else {
self.loadStatus = 2;
if (app.globalData.is_login_check(res.data, self, 'init')) {
app.globalData.showToast(res.data.msg);
}
}
},
fail: function() {
self.loadStatus = 2;
app.globalData.showToast(self.$t('common.internet_error_tips'));
},
});
},
// 按演出 + 场馆 + 下单时间issued_at进行分组组织
groupByShow(tickets) {
var map = {};
tickets.forEach(function(t) {
var key = t.goods_id + '|' + (t.venue_name || '') + '|' + (t.issued_at || '');
if (!map[key]) {
map[key] = {
goods_id: t.goods_id,
goods_title: t.goods_title,
goods_image: t.goods_image,
session_time: t.session_time,
venue_name: t.venue_name,
issued_at: t.issued_at,
tickets: [],
};
}
map[key].tickets.push(t);
});
// 按下单时间或场次时间倒序(最近的在前)
return Object.values(map).sort(function(a, b) {
if (a.issued_at && b.issued_at) {
return b.issued_at - a.issued_at;
}
return (b.session_time || '').localeCompare(a.session_time || '');
});
},
// 下拉刷新
onPullDownRefresh() {
this.isRefreshing = true;
var self = this;
uni.request({
url: app.globalData.get_request_url('list', 'ticket', 'vr_ticket'),
method: 'GET',
dataType: 'json',
success: function(res) {
uni.stopPullDownRefresh();
self.isRefreshing = false;
if (res.data.code == 0) {
self.rawTickets = res.data.data.tickets || [];
self.loadStatus = 3;
} else {
app.globalData.showToast(res.data.msg || '刷新失败');
}
},
fail: function() {
uni.stopPullDownRefresh();
self.isRefreshing = false;
app.globalData.showToast(self.$t('common.internet_error_tips'));
},
});
},
// 打开 QR 弹窗(点击演出卡)
openQrPopup(group) {
var self = this;
var ticketIds = group.tickets.map(function(t) { return t.id; });
uni.showLoading({ title: '加载中...' });
// 并行请求每张票的 detail含 qr_payload
var promises = ticketIds.map(function(id) {
return self.fetchTicketDetail(id);
});
Promise.all(promises).then(function(results) {
uni.hideLoading();
// results 中可能有 undefined请求失败的票过滤掉
var validTickets = results.filter(function(r) { return r != null; });
if (validTickets.length === 0) {
app.globalData.showToast('加载票据失败,请重试');
return;
}
self.currentQrTickets = validTickets;
self.currentQrIndex = 0;
self.currentShowInfo = {
title: group.goods_title,
session_time: group.session_time,
venue_name: group.venue_name,
};
// 匹配暗黑 iOS Wallet 风格的背景
self.qrPopupBg = '#111111';
self.boostScreenBrightness();
self.startQrCountdown();
// 打开弹窗(通过 ref.open() 方式)
self.$nextTick(function() {
if (self.$refs.qrPopupRef) {
self.$refs.qrPopupRef.open();
}
});
}).catch(function() {
uni.hideLoading();
app.globalData.showToast('加载票据失败,请重试');
});
},
// QR 弹窗关闭回调(来自 u-popup @change show=false 或 @close
onPopupChange: function(e) {
if (e && e.show === false) {
this.clearRefreshTimer();
this.restoreScreenBrightness();
}
},
// QR 弹窗关闭事件
onPopupClose: function() {
this.clearRefreshTimer();
this.restoreScreenBrightness();
},
// 获取单张票详情(含 qr_payload
fetchTicketDetail(ticketId) {
return new Promise(function(resolve) {
uni.request({
url: app.globalData.get_request_url('detail', 'ticket', 'vr_ticket', 'id=' + ticketId),
method: 'GET',
dataType: 'json',
success: function(res) {
if (res.data.code == 0 && res.data.data.ticket) {
resolve(res.data.data.ticket);
} else {
resolve(null);
}
},
fail: function() {
resolve(null);
},
});
});
},
// Swiper 滑动切换
onQrSlideChange(index) {
this.currentQrIndex = index;
// 重启倒计时(针对新票)
this.startQrCountdown();
},
// 启动内部倒计时(无 UI
startQrCountdown() {
var self = this;
this.clearRefreshTimer();
var currentTicket = this.currentQrTickets[this.currentQrIndex];
if (!currentTicket) return;
this.currentExpiresIn = currentTicket.qr_expires_in || 0;
this.refreshTimer = setInterval(function() {
self.currentExpiresIn--;
// 剩余 ≤ 30 秒时静默刷新
if (self.currentExpiresIn <= 30 && self.currentExpiresIn > 0) {
self.silentRefreshQr(self.currentQrIndex);
}
if (self.currentExpiresIn <= 0) {
self.clearRefreshTimer();
}
}, 1000);
},
// 静默刷新某张票 of QR
silentRefreshQr(ticketIndex) {
var self = this;
var ticket = this.currentQrTickets[ticketIndex];
if (!ticket) return;
uni.request({
url: app.globalData.get_request_url('refreshQr', 'ticket', 'vr_ticket', 'id=' + ticket.id),
method: 'GET',
dataType: 'json',
success: function(res) {
if (res.data.code == 0 && res.data.data.ticket) {
self.$set(self.currentQrTickets, ticketIndex, res.data.data.ticket);
self.currentExpiresIn = res.data.data.ticket.qr_expires_in || 0;
}
},
fail: function() {
// 静默失败,不提示
},
});
},
// 用户点击过期遮罩触发刷新(来自 popup 组件事件)
onQrRefresh() {
var self = this;
var ticketIndex = this.currentQrIndex;
var ticket = this.currentQrTickets[ticketIndex];
if (!ticket) return;
uni.showLoading({ title: '刷新中...' });
uni.request({
url: app.globalData.get_request_url('refreshQr', 'ticket', 'vr_ticket', 'id=' + ticket.id),
method: 'GET',
dataType: 'json',
success: function(res) {
uni.hideLoading();
if (res.data.code == 0 && res.data.data.ticket) {
self.$set(self.currentQrTickets, ticketIndex, res.data.data.ticket);
self.currentExpiresIn = res.data.data.ticket.qr_expires_in || 0;
} else {
app.globalData.showToast(res.data.msg || '刷新失败');
}
},
fail: function() {
uni.hideLoading();
app.globalData.showToast('网络错误,刷新失败');
},
});
},
// 清理定时器
clearRefreshTimer() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
},
// 提亮屏幕(检票场景)
boostScreenBrightness() {
// #ifndef H5
uni.setScreenBrightness({ value: 1.0 });
// #endif
},
// 恢复屏幕原始亮度
restoreScreenBrightness() {
// #ifndef H5
if (this.screenBrightnessValue > 0) {
uni.setScreenBrightness({ value: this.screenBrightnessValue });
}
// #endif
},
},
};
</script>
<style>
@import './ticket-wallet.css';
</style>