huangye-parking/miniapp/pages/coupon/my-coupons.vue
2026-03-09 17:40:07 +08:00

190 lines
4.2 KiB
Vue

<template>
<view class="coupons-page">
<NavBar title="我的优惠券" />
<!-- 状态标签页 -->
<view class="tabs">
<view
class="tab-item"
:class="{ active: currentStatus === 'unused' }"
@click="switchStatus('unused')"
>未使用</view>
<view
class="tab-item"
:class="{ active: currentStatus === 'used' }"
@click="switchStatus('used')"
>已使用</view>
<view
class="tab-item"
:class="{ active: currentStatus === 'expired' }"
@click="switchStatus('expired')"
>已过期</view>
</view>
<!-- 筛选栏 -->
<FilterBar :filters="filters" @change="onFilterChange" />
<!-- 优惠券列表 -->
<view class="coupon-list">
<CouponCard
v-for="coupon in coupons"
:key="coupon.id"
:coupon="coupon"
@showQrcode="openQrcode"
@gotoYgl="gotoYgl"
/>
<view v-if="!coupons.length && !loading" class="empty-tip">暂无优惠券</view>
</view>
<!-- 二维码弹窗 -->
<QrcodePopup
:visible="qrcodeVisible"
:code="currentCoupon.code || ''"
@close="qrcodeVisible = false"
/>
</view>
</template>
<script>
import { getMyCoupons } from '@/api/coupon'
import { getStores } from '@/api/store'
import CouponCard from '@/components/CouponCard.vue'
import QrcodePopup from '@/components/QrcodePopup.vue'
import FilterBar from '@/components/FilterBar.vue'
import NavBar from '@/components/NavBar.vue'
export default {
components: { CouponCard, QrcodePopup, FilterBar, NavBar },
data() {
return {
loading: false,
currentStatus: 'unused',
currentStoreId: '',
currentType: '',
coupons: [],
qrcodeVisible: false,
currentCoupon: {},
filters: [
{
label: '门店',
key: 'storeId',
options: [{ label: '全部门店', value: '' }],
selectedIndex: 0
},
{
label: '类型',
key: 'type',
options: [
{ label: '全部类型', value: '' },
{ label: '免费券', value: 'free' },
{ label: '抵扣券', value: 'discount' }
],
selectedIndex: 0
}
]
}
},
onShow() {
this.loadStores()
this.loadCoupons()
},
methods: {
/** 加载门店列表用于筛选 */
async loadStores() {
try {
const res = await getStores()
const stores = res.data || res || []
this.filters[0].options = [
{ label: '全部门店', value: '' },
...stores.map(s => ({ label: s.name, value: s.id }))
]
} catch (err) {
console.error('加载门店列表失败:', err)
}
},
/** 加载优惠券列表 */
async loadCoupons() {
this.loading = true
try {
const params = { status: this.currentStatus }
if (this.currentStoreId) params.storeId = this.currentStoreId
if (this.currentType) params.type = this.currentType
const res = await getMyCoupons(params)
this.coupons = res.data || res || []
} catch (err) {
console.error('加载优惠券失败:', err)
} finally {
this.loading = false
}
},
/** 切换状态标签 */
switchStatus(status) {
this.currentStatus = status
this.loadCoupons()
},
/** 筛选变更 */
onFilterChange({ key, value, filterIndex, selectedIndex }) {
if (key === 'storeId') {
this.currentStoreId = value
} else if (key === 'type') {
this.currentType = value
}
this.filters[filterIndex].selectedIndex = selectedIndex
this.loadCoupons()
},
/** 打开二维码弹窗 */
openQrcode(coupon) {
this.currentCoupon = coupon
this.qrcodeVisible = true
},
/** 跳转驿公里小程序 */
gotoYgl() {
uni.navigateToMiniProgram({
appId: 'wx8c943e2e64e04284',
fail: () => {
uni.showToast({ title: '跳转驿公里失败', icon: 'none' })
}
})
}
}
}
</script>
<style scoped>
.coupons-page {
padding: 20rpx;
}
.tabs {
display: flex;
background: #fff;
border-radius: 12rpx;
margin-bottom: 16rpx;
overflow: hidden;
}
.tab-item {
flex: 1;
text-align: center;
padding: 20rpx 0;
font-size: 28rpx;
color: #666;
}
.tab-item.active {
color: #007aff;
font-weight: bold;
border-bottom: 4rpx solid #007aff;
}
.coupon-list {
padding-bottom: 20rpx;
}
.empty-tip {
text-align: center;
padding: 60rpx 0;
color: #999;
font-size: 28rpx;
}
</style>