7月29号

This commit is contained in:
lcj
2026-07-29 13:53:24 +08:00
parent ee0825c1e6
commit cdb23eea01
13 changed files with 102 additions and 55 deletions
+23 -13
View File
@@ -306,19 +306,29 @@ async function onBookClick(card: CardBenefit) {
url: `/packages/user/pages/reserve/index?cardNumber=${res.cardNumber}&resourceId=${res.resourceId}&cardModelId=${card.cardModelId}`, url: `/packages/user/pages/reserve/index?cardNumber=${res.cardNumber}&resourceId=${res.resourceId}&cardModelId=${card.cardModelId}`,
}) })
} else { } else {
uni.showModal({ if (String(card.cardModelId) === '820093340659013') {
title: '提示', uni.showModal({
content: '暂无可用年卡,请先购买', title: '提示',
confirmText: '去购买', content: '暂无可用年卡',
cancelText: '取消', showCancel: true,
success: (modalRes) => { cancelText: '取消',
if (modalRes.confirm) { confirmText: '确定'
uni.navigateTo({ })
url: `/packages/user/pages/buy?goodsId=${card.goodsId}`, } else {
}) uni.showModal({
} title: '提示',
}, content: '暂无可用年卡,请先购买',
}) confirmText: '去购买',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
uni.navigateTo({
url: `/packages/user/pages/buy?goodsId=${card.goodsId}`,
})
}
},
})
}
} }
} catch (err: any) { } catch (err: any) {
uni.showToast({ title: err?.msg || err?.message || '检查失败', icon: 'none' }) uni.showToast({ title: err?.msg || err?.message || '检查失败', icon: 'none' })
+1
View File
@@ -658,6 +658,7 @@ function handleCancel() {
display: flex; display: flex;
gap: 24rpx; gap: 24rpx;
padding: 0 24rpx; padding: 0 24rpx;
margin-top: 48rpx;
} }
.btn-confirm { .btn-confirm {
+3 -2
View File
@@ -39,7 +39,8 @@
{ {
"path": "pages/profile/index", "path": "pages/profile/index",
"style": { "style": {
"navigationBarTitleText": "个人中心" // "navigationBarTitleText": "个人中心"
"navigationStyle": "custom"
} }
} }
], ],
@@ -184,7 +185,7 @@
}, },
"tabBar": { "tabBar": {
"color": "#7A7E83", "color": "#7A7E83",
"selectedColor": "#3c9cff", "selectedColor": "#019FFF",
"borderStyle": "white", "borderStyle": "white",
"backgroundColor": "#ffffff", "backgroundColor": "#ffffff",
"list": [ "list": [
+5 -5
View File
@@ -70,17 +70,17 @@
</view> </view>
<view class="promo-value-block"> <view class="promo-value-block">
<text class="promo-value">¥3800+</text> <text class="promo-value">¥3800+</text>
<text class="promo-save">立省3600+</text> <text class="promo-save">立省1万+</text>
</view> </view>
</view> </view>
<text class="promo-desc">42家景区全年免首道门票</text> <text class="promo-desc">一卡畅玩赣湘边核心景区</text>
<text class="promo-desc-sub">含武功山/君澜温泉/方特/韶山,法定节假日通用</text> <text class="promo-desc-sub">含武功山/君澜温泉/方特/橘子洲小火车/湘江游轮等</text>
<text class="promo-highlight">单次最高可省228元 | 单景区全年可免6次</text> <text class="promo-highlight">单次最高可省299 | 单景区全年最高可免6次</text>
<view class="promo-cta"> <view class="promo-cta">
<text class="cta-label">立即抢购|专属特惠</text> <text class="cta-label">立即抢购|专属特惠</text>
<view class="cta-arrow" /> <view class="cta-arrow" />
</view> </view>
<text class="promo-trust">已售1.2万+ | 萍乡文旅官方联名卡</text> <text class="promo-trust">萍乡市文旅集团监制发行</text>
</view> </view>
</view> </view>
</view> </view>
+23 -20
View File
@@ -1,12 +1,13 @@
<template> <template>
<view class="page"> <view class="page">
<!-- 头部:风景图 + 用户信息 --> <!-- 头部:风景图 + 用户信息 -->
<image
class="hero-bg"
src="https://aliyunoss.hn12301.net/sd/pingxiang_wo_bj.png"
mode="widthFix"
/>
<view class="profile-hero"> <view class="profile-hero">
<image
class="hero-bg"
src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?fm=jpg&q=80&w=750&h=400&fit=crop"
mode="aspectFill"
/>
<view class="hero-overlay" /> <view class="hero-overlay" />
<view class="hero-content"> <view class="hero-content">
<view class="avatar-wrap"> <view class="avatar-wrap">
@@ -19,7 +20,7 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 功能菜单 --> <!-- 功能菜单 -->
<view class="menu-section"> <view class="menu-section">
<view class="menu-card"> <view class="menu-card">
@@ -53,7 +54,7 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 退出登录 --> <!-- 退出登录 -->
<view class="btn-area" v-if="userStore.isLogin"> <view class="btn-area" v-if="userStore.isLogin">
<view class="btn-logout" @click="handleLogout"> <view class="btn-logout" @click="handleLogout">
@@ -111,23 +112,29 @@ function formatPhone(phone?: string) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
} }
</script> </script>
<style>
page{
background: #fff;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.page { .page {
min-height: 100vh; min-height: 100vh;
background: $uv-bg-color;
} }
/* Hero header */ /* Hero header */
.profile-hero { .profile-hero {
position: relative; position: relative;
height: 280rpx; height: 380rpx;
overflow: hidden; overflow: hidden;
padding-top: 120rpx;
} }
.hero-bg { .hero-bg {
position: absolute; position: absolute;
top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -139,11 +146,7 @@ function formatPhone(phone?: string) {
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(
180deg,
rgba(48, 49, 51, 0.5) 0%,
rgba(48, 49, 51, 0.7) 100%
);
} }
.hero-content { .hero-content {
@@ -176,14 +179,14 @@ function formatPhone(phone?: string) {
font-family: $font-family-display; font-family: $font-family-display;
font-size: $font-size-title; font-size: $font-size-title;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
color: #fff; color: #1B1613;
margin-bottom: $spacing-1; margin-bottom: $spacing-1;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3); text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
} }
.user-desc { .user-desc {
font-size: $font-size-sm; font-size: $font-size-sm;
color: rgba(255, 255, 255, 0.7); color: #403D3A;
&--link { &--link {
color: $uv-warning; color: $uv-warning;
@@ -193,7 +196,7 @@ function formatPhone(phone?: string) {
/* Menu section */ /* Menu section */
.menu-section { .menu-section {
padding: $spacing-3; padding: $spacing-3;
margin-top: -60rpx; margin-top: -25rpx;
position: relative; position: relative;
z-index: 3; z-index: 3;
} }
@@ -201,7 +204,7 @@ function formatPhone(phone?: string) {
.menu-card { .menu-card {
background: $color-card; background: $color-card;
border-radius: $radius-lg; border-radius: $radius-lg;
box-shadow: $shadow-base; box-shadow: 0 4rpx 16rpx rgba(15, 23, 42, 0.15);
overflow: hidden; overflow: hidden;
} }
+46 -14
View File
@@ -85,17 +85,19 @@
<!-- 入园码二维码 --> <!-- 入园码二维码 -->
<view class="qrcode-section" v-if="!showFaceModal && !isLeaving"> <view class="qrcode-section" v-if="!showFaceModal && !isLeaving">
<text class="qrcode-title">入园码</text> <text class="qrcode-title">入园码</text>
<view class="qrcode-box"> <view>为确保信息安全,现入园核销只能使用人脸核销。</view>
<image <!-- <view class="qrcode-box"> -->
<!-- 为确保信息安全,现入园核销只能使用人脸核销。 -->
<!-- <image
class="qrcode-img" class="qrcode-img"
:src="userInfoData?.qrCode || '/static/qr-demo.png'" :src="userInfoData?.qrCode || '/static/qr-demo.png'"
mode="aspectFit" mode="aspectFit"
/> /> -->
</view> <!-- </view> -->
<view class="qrcode-countdown"> <!-- <view class="qrcode-countdown">
<view class="countdown-icon" /> <view class="countdown-icon" />
<text class="countdown-text">{{ countdown }}秒后自动刷新</text> <text class="countdown-text">{{ countdown }}秒后自动刷新</text>
</view> </view> -->
</view> </view>
<!-- 持卡人信息(页面底部) --> <!-- 持卡人信息(页面底部) -->
@@ -152,8 +154,8 @@
<!-- 人脸绑定提醒弹窗 --> <!-- 人脸绑定提醒弹窗 -->
<ConfirmModal <ConfirmModal
v-model="showFaceModal" v-model="showFaceModal"
title="系统安全升级提醒" :title="faceModalTitle"
:content="'为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。'" :content="faceModalContent"
confirmText="前往人脸绑定" confirmText="前往人脸绑定"
@confirm="onFaceModalConfirm" @confirm="onFaceModalConfirm"
/> />
@@ -167,15 +169,18 @@ import { useUserStore } from '../../store/user'
import { getUserCardList, getQrAndUserInfo } from '../../api/card' import { getUserCardList, getQrAndUserInfo } from '../../api/card'
import type { UserCardListItem, QrAndUserInfoResult } from '../../api/types' import type { UserCardListItem, QrAndUserInfoResult } from '../../api/types'
import ConfirmModal from '../../components/confirm-modal.vue' import ConfirmModal from '../../components/confirm-modal.vue'
import { post } from '../../api/request'
const userStore = useUserStore() const userStore = useUserStore()
const notLoggedIn = ref(false) const notLoggedIn = ref(false)
const loading = ref(false) const loading = ref(true)
const loaded = ref(false) const loaded = ref(false)
const userCards = ref<UserCardListItem[]>([]) const userCards = ref<UserCardListItem[]>([])
const userInfoData = ref<QrAndUserInfoResult | null>(null) const userInfoData = ref<QrAndUserInfoResult | null>(null)
const showFaceModal = ref(false) const showFaceModal = ref(false)
const faceModalTitle = ref('系统安全升级提醒')
const faceModalContent = ref('为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。')
const isLeaving = ref(false) const isLeaving = ref(false)
const hasCard = computed(() => userCards.value.length > 0) const hasCard = computed(() => userCards.value.length > 0)
@@ -189,6 +194,7 @@ async function fetchCards() {
const mobile = uni.getStorageSync('phone') as string const mobile = uni.getStorageSync('phone') as string
if (!mobile) { if (!mobile) {
loaded.value = true loaded.value = true
loading.value = false
return return
} }
loading.value = true loading.value = true
@@ -199,6 +205,8 @@ async function fetchCards() {
const firstCard = userCards.value[0] const firstCard = userCards.value[0]
if (firstCard?.needFaceImgFlag) { if (firstCard?.needFaceImgFlag) {
faceModalTitle.value = '系统安全升级提醒'
faceModalContent.value = '为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。'
showFaceModal.value = true showFaceModal.value = true
} }
@@ -226,6 +234,8 @@ async function refreshNeedFace() {
if (current) { if (current) {
fetchUserInfo(current) fetchUserInfo(current)
if (current.needFaceImgFlag) { if (current.needFaceImgFlag) {
faceModalTitle.value = '系统安全升级提醒'
faceModalContent.value = '为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。'
showFaceModal.value = true showFaceModal.value = true
} }
} }
@@ -259,6 +269,8 @@ function onCardChange(e: any) {
if (card) { if (card) {
fetchUserInfo(card) fetchUserInfo(card)
if (card.needFaceImgFlag) { if (card.needFaceImgFlag) {
faceModalTitle.value = '系统安全升级提醒'
faceModalContent.value = '为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。'
showFaceModal.value = true showFaceModal.value = true
} }
} }
@@ -344,17 +356,37 @@ function onFeatureClick(item: { label: string }) {
return return
} }
if (item.label === '我要预约') { if (item.label === '我要预约') {
const url = currentCard.value?.thirdId const card = currentCard.value
? `/packages/content/pages/scenic-list?cardModelId=${currentCard.value.thirdId}` if (!card) {
: '/packages/content/pages/scenic-list' uni.showToast({ title: '请先选择一张旅游卡', icon: 'none' })
uni.navigateTo({ url }) return
}
post<any>('/mp-api/mpCard/checkFaceBind', { cardModelId: card.cardModelId, cardNumber: card.cardNo })
.then((res) => {
if (res?.needBindFace) {
faceModalTitle.value = '系统安全升级提醒'
faceModalContent.value = '为保障您的旅游卡信息安全、规范入园使用,平台已启动人脸核验升级。\n根据规则要求,使用旅游卡前需完成人脸绑定,核验仅用于身份核实,人脸信息严格保密,不会挪作他用。\n请立即完成人脸绑定,方可继续使用全部功能。'
showFaceModal.value = true
} else {
const url = card.thirdId
? `/packages/content/pages/scenic-list?cardModelId=${card.thirdId}`
: '/packages/content/pages/scenic-list'
uni.navigateTo({ url })
}
})
.catch(() => {
const url = card.thirdId
? `/packages/content/pages/scenic-list?cardModelId=${card.thirdId}`
: '/packages/content/pages/scenic-list'
uni.navigateTo({ url })
})
return return
} }
if (item.label === '使用说明') { if (item.label === '使用说明') {
uni.navigateTo({ url: '/packages/content/pages/usage-guide' }) uni.navigateTo({ url: '/packages/content/pages/usage-guide' })
return return
} }
if (item.label === '使用记录') { if (item.label === '预约/使用记录') {
uni.navigateTo({ url: '/packages/user/pages/reserve/list' }) uni.navigateTo({ url: '/packages/user/pages/reserve/list' })
return return
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

+1 -1
View File
@@ -127,7 +127,7 @@ $radius-full: 9999rpx;
// === SHADOWS === // === SHADOWS ===
$shadow-sm: 0 2rpx 8rpx rgba(15, 23, 42, 0.04); $shadow-sm: 0 2rpx 8rpx rgba(15, 23, 42, 0.04);
$shadow-base: 0 4rpx 16rpx rgba(15, 23, 42, 0.08); $shadow-base: 0 4rpx 16rpx rgba(15, 23, 42, 0.04);
$shadow-lg: 0 8rpx 32rpx rgba(15, 23, 42, 0.12); $shadow-lg: 0 8rpx 32rpx rgba(15, 23, 42, 0.12);
$shadow-xl: 0 16rpx 48rpx rgba(15, 23, 42, 0.16); $shadow-xl: 0 16rpx 48rpx rgba(15, 23, 42, 0.16);
$shadow-accent: 0 8rpx 24rpx rgba(60, 156, 255, 0.25); $shadow-accent: 0 8rpx 24rpx rgba(60, 156, 255, 0.25);