Files
h5-meike/pages/ticket/scenic.vue
T
jacobxu666andClaude Opus 4.8 77e5cb9510 feat: 全站 UI 按 Minimalist Modern 重设计,新增返回悬浮钮
- 设计令牌层:mm-* CSS 变量与工具类、uView 换肤、优设标题黑字体
- 九个页面全部重写为新风格(列表/详情/下单/出行人/订单/支付成功/登录)
- 补齐 H5 运行时缺失的基础样式(uni-view/scroll-view/toast/swiper 等,App.vue 全局)
- 修复:详情头图轮播、预订须知弹层滚动、出行人数量按购买数限制、订单详情去箭头
- 新增 gmy-back-touch 返回悬浮钮,除首页外全页接入,点击返回上一页

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 12:48:45 +08:00

257 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page mm-page">
<!-- xuchao: 景区卡片列表 —— 整卡可点进详情,入场逐个渐显 -->
<view class="list mm-stagger">
<view class="card mm-card mm-fade-up" v-for="(item,index) in lookList" :key="index"
@click="toDetail(item.id)">
<image class="card__img" mode="aspectFill"
:src="item.mainPic||'https://aliyunoss.hn12301.net/sd/all_moren.png'"></image>
<view class="card__body">
<view class="card__name">{{item.name||''}}</view>
<view class="card__desc" v-if="item.subTypeId">{{item.subTypeId}}</view>
<view class="card__foot">
<view class="card__price">
<view class="card__origin">原价 <text
class="card__origin-num">¥{{(item.price/100).toFixed(0)}}</text></view>
<view class="card__now">
<text class="card__cur">¥</text>
<text class="card__num mm-display mm-grad-text">{{(item.unitPrice/100).toFixed(0)}}</text>
<text class="card__unit">元</text>
</view>
</view>
<view class="card__cta mm-grad">
<text>预订</text>
<u-icon name="arrow-right" color="#ffffff" size="22"></u-icon>
</view>
</view>
</view>
</view>
</view>
<!-- xuchao: 空态(首次请求返回空列表才显示,避免加载中闪烁) -->
<view class="empty mm-fade-up" v-if="showEmpty">
<u-icon name="empty-coupon" color="#CBD5E1" size="120"></u-icon>
<view class="empty__text">暂无在售门票产品</view>
</view>
<!-- xuchao: 列表底部:仅分页加载时显示"正在加载…" -->
<view class="foot" v-if="lookList.length > 0 && !isLoad">
<text>正在加载…</text>
</view>
<!-- xuchao: 订单悬浮按钮 -->
<gmy-float-touch @menuClick="floatTouchClick"></gmy-float-touch>
</view>
</template>
<script>
// xuchao: 门票列表页(启动页/入口页)
import auth from '@/common/auth.js'
import gmyFloatTouch from "@/components/gmy-float-touch/gmy-float-touch.vue"
var that = ''
export default {
components: { gmyFloatTouch },
data() {
return {
pageAll: 2,
isLoad: true,
lookList: [],
// xuchao: 首次请求是否已返回,用于区分"加载中"与"真没数据"
firstLoaded: false,
obj: {
"name": "",
"typeId": "",
"cityId": "",
"pageSize": 10,
"pageNum": 1,
"todayAvailable": false
}
}
},
computed: {
showEmpty() {
return this.firstLoaded && this.lookList.length === 0
}
},
onLoad() {
that = this
// xuchao: 未登录则(正式)跳登录页 / (开发)静默假登录
if (!auth.requireLogin('/pages/ticket/scenic')) return
this.queryTicketsPageMethod()
},
onReachBottom() {
this.queryTicketsPageMethod()
},
methods: {
queryTicketsPageMethod() {
if (this.obj.pageNum <= this.pageAll && this.isLoad) {
this.isLoad = false
this.$u.api.queryTicketsPage(this.obj).then(res => {
this.isLoad = true
this.firstLoaded = true
this.obj.pageNum = this.obj.pageNum * 1 + 1
this.pageAll = Math.ceil(res.data.total / 10)
this.total = res.data.total
this.lookList = this.lookList.concat(res.data.list)
})
}
},
toDetail(e) {
uni.navigateTo({
url: 'scenicdetail?id=' + e
})
},
// xuchao: 悬浮按钮 —— 跳门票订单列表
floatTouchClick(e) {
if (e == 4) {
uni.navigateTo({
url: '/pages/ticket/orderlist'
})
}
}
}
}
</script>
<style scoped lang="less">
.page {
padding: 32rpx 32rpx 40rpx;
}
/* ---------- 卡片列表 ---------- */
.list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.card {
display: flex;
padding: 20rpx;
box-sizing: border-box;
transition: transform 0.2s ease-out, box-shadow 0.3s ease-out;
}
.card:active {
transform: scale(0.985);
box-shadow: var(--mm-shadow-sm);
}
.card__img {
width: 208rpx;
height: 208rpx;
flex: none;
border-radius: 18rpx;
background: var(--mm-muted);
}
.card__body {
flex: 1;
min-width: 0;
margin-left: 24rpx;
display: flex;
flex-direction: column;
}
.card__name {
font-size: 30rpx;
font-weight: 600;
letter-spacing: -0.01em;
color: var(--mm-fg);
overflow: hidden !important;
text-overflow: ellipsis !important;
display: -webkit-box !important;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.card__desc {
margin-top: 8rpx;
font-size: 22rpx;
line-height: 1.45;
color: var(--mm-muted-fg);
overflow: hidden !important;
text-overflow: ellipsis !important;
display: -webkit-box !important;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.card__foot {
margin-top: auto;
padding-top: 12rpx;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
.card__origin {
font-size: 20rpx;
color: var(--mm-muted-fg);
}
.card__origin-num {
text-decoration: line-through;
}
.card__now {
display: flex;
align-items: baseline;
}
.card__cur {
font-size: 24rpx;
font-weight: 600;
color: var(--mm-accent);
margin-right: 2rpx;
}
.card__num {
font-size: 46rpx;
line-height: 1;
}
.card__unit {
font-size: 20rpx;
color: var(--mm-muted-fg);
margin-left: 6rpx;
}
/* xuchao: 预订按钮 —— 渐变胶囊 + 箭头,承担整卡的行动号召 */
.card__cta {
flex: none;
display: flex;
align-items: center;
gap: 6rpx;
height: 60rpx;
padding: 0 26rpx;
border-radius: 999rpx;
color: #fff;
font-size: 24rpx;
box-shadow: 0 6rpx 16rpx rgba(0, 82, 255, 0.25);
}
/* ---------- 空态与底部 ---------- */
.empty {
margin-top: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 24rpx;
}
.empty__text {
font-size: 26rpx;
color: var(--mm-muted-fg);
}
.foot {
padding: 44rpx 0 20rpx;
text-align: center;
font-size: 22rpx;
letter-spacing: 0.1em;
color: var(--mm-muted-fg);
}
</style>