feat: 新增优惠券功能与优化用户体验
- 新增商品券类型支持,包括商品券的领取、使用和展示 - 优化优惠券领取流程,支持兑换码兑换和自动跳转登录 - 新增优惠活动功能,支持活动商品折扣 - 重构优惠券页面布局,区分领取和使用页面 - 新增分销商信息编辑功能 - 优化小程序更新机制,改进更新提示流程 - 修复优惠券使用条件判断逻辑 - 调整UI样式,统一主题色为绿色 - 新增电话客服功能,支持动态电话号码 - 优化订单详情页,展示商品券信息
This commit is contained in:
parent
b09939848c
commit
891ee783a5
86
App.vue
86
App.vue
@ -12,56 +12,78 @@ import {
|
||||
import { APP_ID } from '@/config'
|
||||
|
||||
// 检查更新逻辑
|
||||
const checkUpdate = () => {
|
||||
// 兼容性检查(非必须,但建议)
|
||||
if (!uni.canIUse('getUpdateManager')) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '当前微信版本过低,请升级后使用',
|
||||
showCancel: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const autoUpdate = () => {
|
||||
// 获取小程序更新机制兼容
|
||||
if (uni.canIUse("getUpdateManager")) {
|
||||
// 获取更新管理器
|
||||
const updateManager = uni.getUpdateManager();
|
||||
|
||||
// 检测是否有新版本
|
||||
//1. 检查小程序是否有新版本发布,向小程序后台请求完新版本信息
|
||||
updateManager.onCheckForUpdate((res) => {
|
||||
// 请求完新版本信息的回调
|
||||
if (res.hasUpdate) {
|
||||
uni.showLoading({ title: '检测到新版本,下载中...' });
|
||||
}
|
||||
});
|
||||
|
||||
// 新版本下载完成
|
||||
updateManager.onUpdateReady(() => {
|
||||
uni.hideLoading();
|
||||
//检测到新版本,需要更新,给出提示
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已准备好,立即重启应用?',
|
||||
showCancel: false,
|
||||
title: "更新提示",
|
||||
content: "检测到新版本,是否下载新版本并重启小程序?",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 强制应用新版本并重启
|
||||
updateManager.applyUpdate();
|
||||
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
|
||||
downLoadAndUpdate(updateManager);
|
||||
} else if (res.cancel) {
|
||||
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
|
||||
uni.showModal({
|
||||
title: "温馨提示",
|
||||
content: "本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦",
|
||||
showCancel: false, //隐藏取消按钮
|
||||
confirmText: "确定更新", //只保留确定更新按钮
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
//下载新版本,并重新应用
|
||||
downLoadAndUpdate(updateManager);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载小程序新版本并重启应用
|
||||
*/
|
||||
const downLoadAndUpdate = (updateManager) => {
|
||||
uni.showLoading();
|
||||
//静默下载更新小程序新版本,更新完成后回调
|
||||
updateManager.onUpdateReady(() => {
|
||||
uni.hideLoading();
|
||||
//新的版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||
updateManager.applyUpdate();
|
||||
});
|
||||
|
||||
// 下载失败处理
|
||||
// 更新失败回调
|
||||
updateManager.onUpdateFailed(() => {
|
||||
uni.hideLoading();
|
||||
// 新的版本下载失败
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '更新失败,请删除小程序后重新搜索打开',
|
||||
showCancel: false
|
||||
title: "已经有新版本了哟~",
|
||||
content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~",
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onLaunch(() => {
|
||||
checkUpdate();
|
||||
autoUpdate();
|
||||
console.log('App Launch')
|
||||
})
|
||||
|
||||
|
16
api/activity.js
Normal file
16
api/activity.js
Normal file
@ -0,0 +1,16 @@
|
||||
import api from './api'
|
||||
|
||||
/**
|
||||
* 获取某个优惠活动
|
||||
*/
|
||||
export function getpromotionactivity(id) {
|
||||
return api.get(`/promotionactivity/get?id=${id}`, {}, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有优惠活动
|
||||
*/
|
||||
export function getPromotionactivityInfo(data) {
|
||||
return api.get(`/promotionactivity/page`, data, { login: true })
|
||||
}
|
||||
|
@ -14,6 +14,13 @@ export function couponMine(data) {
|
||||
return api.get(`/coupon/my`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* couponMine
|
||||
*/
|
||||
export function couponCanUserMine(data) {
|
||||
return api.get(`/coupon/use`, data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* couponIndex let couponCount = (params = {}) => vm.$u.get('/coupon/count', params);
|
||||
*/
|
||||
|
@ -21,3 +21,11 @@ export function getDistributorInfo(id) {
|
||||
export function getCommissionList(data) {
|
||||
return api.get(`/order/listByDistributor`, data, { login: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑分销商信息
|
||||
* @param {Object} data - 包含 id, name, phone, workUnit, recipientName, bankCardNumber, bankName
|
||||
*/
|
||||
export function editDistributor(data) {
|
||||
return api.put(`/distributor/update`, data, { login: true })
|
||||
}
|
||||
|
@ -13,3 +13,10 @@ export function menuGoods(data) {
|
||||
return api.get('/product/products', data, { login: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个商品信息
|
||||
*/
|
||||
export function getGoods(id) {
|
||||
return api.get('/product/detail/' + id, { login: false })
|
||||
}
|
||||
|
||||
|
10
pages.json
10
pages.json
@ -124,11 +124,19 @@
|
||||
"path": "pages/coupons/coupons",
|
||||
"style": {
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTitleText": "我的卡券",
|
||||
"navigationBarTitleText": "领取卡券",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/coupons/mycoupons",
|
||||
"style": {
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTitleText": "我的卡券",
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},{
|
||||
"path": "pages/mine/userinfo",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户信息",
|
||||
|
563
pages/components/pages/coupons/coupons copy.vue
Normal file
563
pages/components/pages/coupons/coupons copy.vue
Normal file
@ -0,0 +1,563 @@
|
||||
<template>
|
||||
<uv-navbar :fixed="false" :title="title" left-arrow @leftClick="$onClickLeft" />
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
<view class="exchange-box">
|
||||
<view class="input-box">
|
||||
<input type="text" v-model="exchange_code" placeholder="请输入兑换码"
|
||||
placeholder-class="text-color-assist font-size-base" />
|
||||
<button type="primary" style="background-color: #52ac41;" @click="exchange">兑换</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tabbar">
|
||||
<view class="tab" :class="{ active: activeTabIndex == index }" v-for="(item, index) in tabs" :key="index"
|
||||
@tap="handleTab(index)">
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-fill">
|
||||
<scroll-view scroll-y class="coupon-list" @scrolltolower="getCoupons(activeTabIndex)">
|
||||
<view class="wrapper" v-if="0 === activeTabIndex">
|
||||
<uv-empty v-if="myCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in myCoupons" :key="index"
|
||||
@tap="openDetailModal(item, index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill"></image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{ item.value }}</text>
|
||||
<view>
|
||||
满{{ item.least }}减{{ item.value }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd')}}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wrapper" v-if="1 === activeTabIndex">
|
||||
<uv-empty v-if="notCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in notCoupons" :key="index"
|
||||
@tap="openDetailModal(item, index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill"></image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{ item.value }}</text>
|
||||
<view>
|
||||
满{{ item.least }}减{{ item.value }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd')}}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
有效期:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd')}}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
领取时间:{{ formatDateTime(coupon.createTime) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
券价值:满{{ coupon.least }}减{{ coupon.value }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="activeTabIndex == 1">
|
||||
每人限领:{{ coupon.limit }} 张
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用范围:{{ typeInfo(coupon.type) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用店铺:{{ coupon.shopName }}
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 1">
|
||||
<button type="primary" @tap="receive(coupon, couponIndex)" class="use-coupon-btn">立即领取</button>
|
||||
</view>
|
||||
</view>
|
||||
</modal>
|
||||
|
||||
<!--轻提示-->
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad, onShow, onPullDownRefresh, onHide } from '@dcloudio/uni-app'
|
||||
import { formatDateTime, kmUnit } from '@/utils/util'
|
||||
import {
|
||||
couponReceive,
|
||||
couponMine,
|
||||
couponIndexApi
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('优惠券')
|
||||
|
||||
const tabs = ref([
|
||||
{
|
||||
title: '我的优惠券', page: 1, pagesize: 10,
|
||||
coupons: []
|
||||
},
|
||||
{
|
||||
title: '未领优惠券', page: 1, pagesize: 10,
|
||||
coupons: []
|
||||
}
|
||||
])
|
||||
const activeTabIndex = ref(0)
|
||||
const detailModalVisible = ref(false)
|
||||
const coupon = ref({})
|
||||
const couponIndex = ref(0)
|
||||
const exchange_code = ref('')
|
||||
const uToast = ref()
|
||||
const myCoupons = ref([])
|
||||
const notCoupons = ref([])
|
||||
|
||||
onShow(() => {
|
||||
getCoupons(0)
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
if (activeTabIndex.value == 0) {
|
||||
myCoupons.value = []
|
||||
}
|
||||
if (activeTabIndex.value == 1) {
|
||||
notCoupons.value = []
|
||||
}
|
||||
tabs.value[activeTabIndex.value].page = 1;
|
||||
getCoupons(activeTabIndex.value)
|
||||
})
|
||||
watch(activeTabIndex, () => {
|
||||
getCoupons(activeTabIndex.value)
|
||||
})
|
||||
|
||||
// 兑换
|
||||
const exchange = async () => {
|
||||
let data = await couponReceive({ code: exchange_code.value });
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '兑换成功',
|
||||
type: 'success'
|
||||
});
|
||||
tabs.value[0].coupons = [];
|
||||
tabs.value[0].page = 1;
|
||||
getCoupons(0)
|
||||
tabs.value[1].coupons = [];
|
||||
tabs.value[1].page = 1;
|
||||
getCoupons(1)
|
||||
}
|
||||
}
|
||||
// 使用范围
|
||||
const typeInfo = (type) => {
|
||||
if (type == 0) {
|
||||
return '通用'
|
||||
}
|
||||
if (type == 1) {
|
||||
return '自取'
|
||||
}
|
||||
if (type == 2) {
|
||||
return '外卖'
|
||||
}
|
||||
}
|
||||
const handleTab = (index) => {
|
||||
console.log('activeTabIndex2:', index)
|
||||
activeTabIndex.value = index
|
||||
}
|
||||
const getCoupons = async (type) => {
|
||||
let page = tabs.value[type].page;
|
||||
let pagesize = tabs.value[type].pagesize;
|
||||
// 我的优惠券
|
||||
let data = [];
|
||||
if (type == 0) {
|
||||
myCoupons.value = await couponMine({ page: page, pagesize: pagesize });
|
||||
}
|
||||
// 未领优惠券
|
||||
// if (type == 1) {
|
||||
// notCoupons.value = await couponIndexApi({page:page,pagesize:pagesize});
|
||||
// }
|
||||
if (type == 1) {
|
||||
notCoupons.value = await couponIndexApi({ page: page, pagesize: pagesize });
|
||||
// 过滤掉已领取的优惠券
|
||||
notCoupons.value = notCoupons.value.filter(notCoupon =>
|
||||
!myCoupons.value.some(myCoupon => myCoupon.couponId === notCoupon.id)
|
||||
);
|
||||
}
|
||||
//console.log('data:',data)
|
||||
uni.stopPullDownRefresh();
|
||||
|
||||
console.log('tabs.value:', tabs.value[type].title)
|
||||
//tabs.value[type].page++;
|
||||
}
|
||||
const openDetailModal = (couponItem, index) => {
|
||||
couponIndex.value = index;
|
||||
coupon.value = couponItem
|
||||
detailModalVisible.value = true
|
||||
}
|
||||
const useCouponWith = (coupon) => {
|
||||
//coupon.value = coupon
|
||||
useCoupon();
|
||||
}
|
||||
const closeDetailModal = () => {
|
||||
detailModalVisible.value = false
|
||||
coupon.value = {}
|
||||
}
|
||||
const useCoupon = () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
}
|
||||
const showTip1 = () => {
|
||||
uni.showToast({
|
||||
title: '您暂时还没有赠送中卡券哦~',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
const showTip2 = () => {
|
||||
uni.showToast({
|
||||
title: '您暂时还没有券码哦~',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
// 领取优惠券
|
||||
const receive = async (coupon, index) => {
|
||||
let data = await couponReceive({ id: coupon.id });
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '领取成功',
|
||||
type: 'success'
|
||||
});
|
||||
detailModalVisible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.exchange-box {
|
||||
flex-shrink: 0;
|
||||
height: 200rpx;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
width: 70%;
|
||||
flex-shrink: 0;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #eee;
|
||||
border-right: 0;
|
||||
border-radius: 8rpx 0 0 8rpx;
|
||||
// padding: 20rpx;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0 8rpx 8rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabbar {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $font-size-base;
|
||||
// color: $text-color-base;
|
||||
color: #52ac41;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
padding: 15rpx 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #52ac41;
|
||||
|
||||
.title {
|
||||
border-bottom: 5rpx solid #52ac41;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.coupon-list {
|
||||
height: calc(100vh - 120rpx - 200rpx);
|
||||
/* #ifdef H5 */
|
||||
height: calc(100vh - 120rpx - 200rpx - 44px);
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.coupon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 30rpx;
|
||||
//padding: 0 30rpx;
|
||||
border-radius: 6rpx;
|
||||
box-shadow: 0 10rpx 10rpx -10rpx rgba(15, 15, 15, 0.1);
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
left: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $bg-color;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
bottom: 65rpx;
|
||||
right: -15rpx;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1rpx dashed #c6c6c6;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.coupon-img {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.use-coupon-btn {
|
||||
width: 95%;
|
||||
border-radius: 50rem !important;
|
||||
}
|
||||
|
||||
|
||||
.taobao {
|
||||
background-color: white;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 30rpx;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.store {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.buddha {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.entrance {
|
||||
color: $uv-info;
|
||||
border: solid 2rpx $uv-info;
|
||||
line-height: 48rpx;
|
||||
padding: 0 30rpx;
|
||||
background: none;
|
||||
border-radius: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.ticket {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
width: 70%;
|
||||
padding: 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
border-right: dashed 2rpx rgb(224, 215, 211);
|
||||
display: flex;
|
||||
|
||||
.picture {
|
||||
//width: 172rpx;
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
}
|
||||
|
||||
.introduce {
|
||||
margin-left: 10rpx;
|
||||
|
||||
.top {
|
||||
color: $uv-warning;
|
||||
font-size: 28rpx;
|
||||
|
||||
.big {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.type {
|
||||
font-size: 28rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-top: 10rpx;
|
||||
font-size: 20rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 30%;
|
||||
padding: 40rpx 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.use {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
color: #ffffff !important;
|
||||
background-color: $uv-warning !important;
|
||||
line-height: 40rpx;
|
||||
color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.used {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
//color: #ffffff!important;
|
||||
//background-color: $u-type-warning!important;
|
||||
line-height: 40rpx;
|
||||
//color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right_log {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
padding: 80rpx 0rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<uv-navbar :fixed="false" :title="title" left-arrow @leftClick="$onClickLeft" />
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
|
||||
<view class="exchange-box">
|
||||
<view class="input-box">
|
||||
<input type="text" v-model="exchange_code" placeholder="请输入兑换码"
|
||||
@ -8,15 +9,15 @@
|
||||
<button type="primary" style="background-color: #52ac41;" @click="exchange">兑换</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tabbar">
|
||||
<!-- <view class="tabbar">
|
||||
<view class="tab" :class="{ active: activeTabIndex == index }" v-for="(item, index) in tabs" :key="index"
|
||||
@tap="handleTab(index)">
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="flex-fill">
|
||||
<scroll-view scroll-y class="coupon-list" @scrolltolower="getCoupons(activeTabIndex)">
|
||||
<view class="wrapper" v-if="0 === activeTabIndex">
|
||||
<view class="wrapper" v-if="1 === activeTabIndex">
|
||||
<uv-empty v-if="myCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in myCoupons" :key="index"
|
||||
@tap="openDetailModal(item, index)">
|
||||
@ -34,14 +35,18 @@
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd')}}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.isReceive === 1" class="use immediate-use"
|
||||
style="background-color: #999999;">已领取</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="receive(item, index)">
|
||||
立即领取{{ item.isReceive }}</view>
|
||||
<!-- <view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
@ -50,14 +55,17 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wrapper" v-if="1 === activeTabIndex">
|
||||
<view class="wrapper" v-if="0 === activeTabIndex">
|
||||
<uv-empty v-if="notCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in notCoupons" :key="index"
|
||||
@tap="openDetailModal(item, index)">
|
||||
<view class="taobao">
|
||||
<view class="taobao" v-if="item.couponType == 1">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill"></image>
|
||||
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">满减券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
@ -68,14 +76,51 @@
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd')}}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.isReceive === 1" class="use immediate-use"
|
||||
style="background-color: #999999 !important; padding-left: 25rpx; padding-right: 25rpx;">
|
||||
已领取</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="receive(item, index)">
|
||||
立即领取</view>
|
||||
<!-- <view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="taobao" v-if="item.couponType == 2">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">商品券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
商品名称:<text class="big" style="font-size: 32rpx;">{{ item.productName
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.isReceive === 1" class="use immediate-use"
|
||||
style="background-color: #999999 !important; padding-left: 25rpx; padding-right: 25rpx;">
|
||||
已领取</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="receive(item, index)">
|
||||
立即领取</view>
|
||||
<!-- <view class="use immediate-use" :round="true" @tap="receive(item, index)">立即领取
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 1">
|
||||
<view v-if="item.status == 0" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="used">已使用</view>
|
||||
@ -86,21 +131,26 @@
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="modal-content" v-if="coupon.couponType == 1">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
有效期:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd')}}
|
||||
领取期限:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd') }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
领取时间:{{ formatDateTime(coupon.createTime) }}
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="coupon.expiryDays != null">
|
||||
有效期:自领取后{{ coupon.expiryDays }}天内有效
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-else>
|
||||
有效期:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd') }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
券价值:满{{ coupon.least }}减{{ coupon.value }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="activeTabIndex == 1">
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="activeTabIndex == 0">
|
||||
每人限领:{{ coupon.limit }} 张
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
@ -109,11 +159,50 @@
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用店铺:{{ coupon.shopName }}
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 1">
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<button v-if="coupon.isReceive === 0" type="primary" @tap="receive(coupon, couponIndex)"
|
||||
class="use-coupon-btn">立即领取</button>
|
||||
<button v-if="coupon.isReceive === 1" style="background-color: #999999; color: white;"
|
||||
class="use-coupon-btn">已领取</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="modal-content" v-if="coupon.couponType == 2">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
领取期限:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd') }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="coupon.expiryDays != null">
|
||||
有效期:自领取后{{ coupon.expiryDays }}天内有效
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-else>
|
||||
有效期:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd') }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
券价值:使用此券免费领取 {{ coupon.productName }} 一份
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="activeTabIndex == 0">
|
||||
每人限领:{{ coupon.limit }} 张
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用范围:{{ typeInfo(coupon.type) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用店铺:{{ coupon.shopName }}
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 1">
|
||||
<button type="primary" @tap="receive(coupon, couponIndex)" class="use-coupon-btn">立即领取</button>
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
<button v-if="coupon.isReceive === 0" type="primary" @tap="receive(coupon, couponIndex)"
|
||||
class="use-coupon-btn">立即领取</button>
|
||||
<button v-if="coupon.isReceive === 1" style="background-color: #999999; color: white;"
|
||||
class="use-coupon-btn">已领取</button>
|
||||
</view>
|
||||
</view>
|
||||
</modal>
|
||||
@ -138,16 +227,16 @@ import {
|
||||
couponIndexApi
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('优惠券')
|
||||
const { member, isLogin } = storeToRefs(main);
|
||||
const title = ref('领取优惠券')
|
||||
|
||||
const tabs = ref([
|
||||
// {
|
||||
// title: '我的优惠券', page: 1, pagesize: 10,
|
||||
// coupons: []
|
||||
// },
|
||||
{
|
||||
title: '我的优惠券', page: 1, pagesize: 10,
|
||||
coupons: []
|
||||
},
|
||||
{
|
||||
title: '未领优惠券', page: 1, pagesize: 10,
|
||||
title: '领优惠券', page: 1, pagesize: 10,
|
||||
coupons: []
|
||||
}
|
||||
])
|
||||
@ -160,7 +249,50 @@ const uToast = ref()
|
||||
const myCoupons = ref([])
|
||||
const notCoupons = ref([])
|
||||
|
||||
|
||||
onLoad(async (options) => {
|
||||
|
||||
|
||||
// 如果有优惠券id参数,自动领取优惠券
|
||||
if (options.couponId) {
|
||||
console.log('111111111111111options.couponId', options.couponId);
|
||||
|
||||
if (!main.isLogin) {
|
||||
uni.navigateTo({ url: '/pages/components/pages/login/login?couponId=' + options.couponId })
|
||||
return
|
||||
}
|
||||
// 初始化优惠券
|
||||
getCoupons(0)
|
||||
let data = await couponReceive({ id: options.couponId });
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '领取成功',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/components/pages/coupons/mycoupons'
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
if (!main.isLogin) {
|
||||
uni.navigateTo({ url: '/pages/components/pages/login/login?' })
|
||||
return
|
||||
}
|
||||
// 初始化优惠券
|
||||
getCoupons(0)
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
// console.log("444444444444", member);
|
||||
// if (!main.isLogin) {
|
||||
// uni.navigateTo({ url: '/pages/components/pages/login/login' })
|
||||
// return
|
||||
// }
|
||||
|
||||
getCoupons(0)
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
@ -188,9 +320,14 @@ const exchange = async () => {
|
||||
tabs.value[0].coupons = [];
|
||||
tabs.value[0].page = 1;
|
||||
getCoupons(0)
|
||||
tabs.value[1].coupons = [];
|
||||
tabs.value[1].page = 1;
|
||||
getCoupons(1)
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/components/pages/coupons/mycoupons'
|
||||
})
|
||||
}, 1000)
|
||||
// tabs.value[1].coupons = [];
|
||||
// tabs.value[1].page = 1;
|
||||
// getCoupons(1)
|
||||
}
|
||||
}
|
||||
// 使用范围
|
||||
@ -214,14 +351,14 @@ const getCoupons = async (type) => {
|
||||
let pagesize = tabs.value[type].pagesize;
|
||||
// 我的优惠券
|
||||
let data = [];
|
||||
if (type == 0) {
|
||||
myCoupons.value = await couponMine({ page: page, pagesize: pagesize });
|
||||
}
|
||||
// if (type == 1) {
|
||||
// myCoupons.value = await couponMine({ page: page, pagesize: pagesize });
|
||||
// }
|
||||
// 未领优惠券
|
||||
// if (type == 1) {
|
||||
// notCoupons.value = await couponIndexApi({page:page,pagesize:pagesize});
|
||||
// }
|
||||
if (type == 1) {
|
||||
if (type == 0) {
|
||||
notCoupons.value = await couponIndexApi({ page: page, pagesize: pagesize });
|
||||
// 过滤掉已领取的优惠券
|
||||
notCoupons.value = notCoupons.value.filter(notCoupon =>
|
||||
@ -273,6 +410,12 @@ const receive = async (coupon, index) => {
|
||||
type: 'success'
|
||||
});
|
||||
detailModalVisible.value = false
|
||||
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/components/pages/coupons/mycoupons'
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,6 +592,7 @@ page {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.store {
|
||||
font-weight: 500;
|
||||
}
|
||||
@ -486,6 +630,21 @@ page {
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
/* 禁止图片收缩 */
|
||||
|
||||
.coupon-type {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
background-color: #f9ae3d;
|
||||
padding: 5rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 0rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.introduce {
|
||||
@ -499,6 +658,7 @@ page {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
max-width: 300rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
738
pages/components/pages/coupons/mycoupons.vue
Normal file
738
pages/components/pages/coupons/mycoupons.vue
Normal file
@ -0,0 +1,738 @@
|
||||
<template>
|
||||
<uv-navbar :fixed="false" :title="title" left-arrow @leftClick="$onClickLeft" />
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
<!-- 二级菜单 -->
|
||||
<view class="menu-container">
|
||||
<!-- 第一级菜单:通用/自取/外卖 -->
|
||||
<view class="first-level-menu">
|
||||
<view v-for="(item, index) in firstLevelMenus" :key="index"
|
||||
:class="['menu-item', { 'active': activeFirstMenu === index }]" @tap="changeFirstMenu(index)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 第二级菜单:未使用/已使用/已过期 -->
|
||||
<view class="second-level-menu">
|
||||
<view v-for="(item, index) in secondLevelMenus" :key="index"
|
||||
:class="['menu-item', { 'active': activeSecondMenu === index }]" @tap="changeSecondMenu(index)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 兑换码区域 -->
|
||||
<!-- <view class="exchange-box">
|
||||
<view class="input-box">
|
||||
<input type="text" v-model="exchange_code" placeholder="请输入兑换码"
|
||||
placeholder-class="text-color-assist font-size-base" />
|
||||
<button type="primary" style="background-color: #52ac41;" @click="exchange">兑换</button>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 优惠券列表 -->
|
||||
<view class="flex-fill">
|
||||
<scroll-view scroll-y class="coupon-list" @scrolltolower="loadMoreCoupons">
|
||||
<uv-empty v-if="filteredCoupons.length == 0" mode="list"></uv-empty>
|
||||
<view class="coupon" v-for="(item, index) in filteredCoupons" :key="index"
|
||||
@tap="openDetailModal(item, index)">
|
||||
<view class="coupon-card" v-if="item.couponType == 1">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">满减券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
<text class="big">{{ item.value }}</text>
|
||||
<view>
|
||||
满{{ item.least }}减{{ item.value }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view v-if="item.status == 0 && item.valid == 1" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else-if="item.status == 0 && item.valid == 0" class="used"
|
||||
:round="true" style="font-size: 20rpx;">未到使用期限</view>
|
||||
<view v-else-if="item.status == 1" class="used">已使用</view>
|
||||
<view v-else class="status-text expired">已过期</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="coupon-card" v-if="item.couponType == 2">
|
||||
<view class="ticket">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">商品券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
商品名称:<text class="big" style="font-size: 32rpx;">{{ item.productName }}</text>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view v-if="item.status == 0 && item.valid == 1" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else-if="item.status == 0 && item.valid == 0" class="used"
|
||||
:round="true" style="font-size: 20rpx;">未到使用期限</view>
|
||||
<view v-else-if="item.status == 1" class="used">已使用</view>
|
||||
<view v-else class="status-text expired">已过期</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 优惠券详情模态框 -->
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
有效期:{{ formatDateTime(coupon.startTime, 'yyyy-MM-dd') }}-{{ formatDateTime(coupon.endTime,
|
||||
'yyyy-MM-dd') }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
领取时间:{{ formatDateTime(coupon.createTime) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="coupon.couponType == 1">
|
||||
券价值:满{{ coupon.least }}减{{ coupon.value }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-else>
|
||||
券价值:使用此券免费领取 {{ coupon.productName }} 一份
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用范围:{{ typeInfo(coupon.type) }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">
|
||||
适用店铺:{{ coupon.shopName }}
|
||||
</view>
|
||||
<view class="d-flex align-items-center just-content-center"
|
||||
v-if="coupon.status == 0 && coupon.valid == 1">
|
||||
<button type="primary" @tap="useCoupon" class="use-coupon-btn">立即使用</button>
|
||||
</view>
|
||||
</view>
|
||||
</modal>
|
||||
|
||||
<!--轻提示-->
|
||||
<uv-toast ref="uToast"></uv-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
computed
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad, onShow, onPullDownRefresh, onHide } from '@dcloudio/uni-app'
|
||||
import { formatDateTime, kmUnit } from '@/utils/util'
|
||||
import {
|
||||
couponReceive,
|
||||
couponMine,
|
||||
couponIndexApi
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
const title = ref('我的优惠券')
|
||||
|
||||
// 一级菜单数据
|
||||
const firstLevelMenus = ref([
|
||||
{ name: '通用', type: 0, count: 0 },
|
||||
{ name: '自取', type: 1, count: 0 },
|
||||
{ name: '外卖', type: 2, count: 0 }
|
||||
])
|
||||
const activeFirstMenu = ref(0)
|
||||
|
||||
// 二级菜单数据
|
||||
const secondLevelMenus = ref([
|
||||
{ name: '未使用', status: 0 },
|
||||
{ name: '已使用', status: 1 },
|
||||
{ name: '已过期', status: 2 }
|
||||
])
|
||||
const activeSecondMenu = ref(0)
|
||||
|
||||
const detailModalVisible = ref(false)
|
||||
const coupon = ref({})
|
||||
const couponIndex = ref(0)
|
||||
const exchange_code = ref('')
|
||||
const uToast = ref()
|
||||
const myCoupons = ref([])
|
||||
const page = ref(1)
|
||||
const pagesize = ref(10)
|
||||
const loading = ref(false)
|
||||
const finished = ref(false)
|
||||
|
||||
// 根据筛选条件过滤优惠券
|
||||
const filteredCoupons = computed(() => {
|
||||
if (activeSecondMenu.value === 2) {
|
||||
return myCoupons.value.map(coupon => ({
|
||||
...coupon,
|
||||
status: 2
|
||||
}));
|
||||
}
|
||||
return myCoupons.value;
|
||||
// return myCoupons.value.filter(item => {
|
||||
// // 筛选类型(通用/自取/外卖)
|
||||
// const typeMatch = item.type === firstLevelMenus.value[activeFirstMenu.value].type;
|
||||
// // 筛选状态(未使用/已使用/已过期)
|
||||
// const statusMatch = item.status === secondLevelMenus.value[activeSecondMenu.value].status;
|
||||
// return typeMatch && statusMatch;
|
||||
// });
|
||||
});
|
||||
|
||||
// 监听一级菜单变化
|
||||
watch(activeFirstMenu, () => {
|
||||
// 重置数据并重新加载
|
||||
resetAndReload();
|
||||
});
|
||||
|
||||
// 监听二级菜单变化
|
||||
watch(activeSecondMenu, () => {
|
||||
// 重置数据并重新加载
|
||||
resetAndReload();
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
resetAndReload();
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
resetAndReload();
|
||||
})
|
||||
|
||||
// 重置数据并重新加载
|
||||
const resetAndReload = () => {
|
||||
page.value = 1;
|
||||
finished.value = false;
|
||||
myCoupons.value = [];
|
||||
loadCoupons();
|
||||
}
|
||||
|
||||
// 切换一级菜单
|
||||
const changeFirstMenu = (index) => {
|
||||
activeFirstMenu.value = index;
|
||||
}
|
||||
|
||||
// 切换二级菜单
|
||||
const changeSecondMenu = (index) => {
|
||||
activeSecondMenu.value = index;
|
||||
}
|
||||
|
||||
// 加载更多优惠券
|
||||
const loadMoreCoupons = () => {
|
||||
if (!loading.value && !finished.value) {
|
||||
page.value++;
|
||||
loadCoupons();
|
||||
}
|
||||
}
|
||||
|
||||
// 加载优惠券数据
|
||||
const loadCoupons = async () => {
|
||||
if (loading.value) return;
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const data = await couponMine({ page: page.value, pagesize: pagesize.value, type: firstLevelMenus.value[activeFirstMenu.value].type, status: secondLevelMenus.value[activeSecondMenu.value].status });
|
||||
|
||||
|
||||
if (data && data.length > 0) {
|
||||
// 将新数据添加到列表中
|
||||
myCoupons.value = page.value === 1 ? data : [...myCoupons.value, ...data];
|
||||
|
||||
// 更新各类型优惠券数量
|
||||
updateCouponCounts();
|
||||
} else {
|
||||
finished.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载优惠券失败', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
uni.stopPullDownRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新各类型优惠券数量
|
||||
const updateCouponCounts = () => {
|
||||
// 重置计数
|
||||
firstLevelMenus.value.forEach(menu => menu.count = 0);
|
||||
|
||||
// 统计各类型未使用的优惠券数量
|
||||
myCoupons.value.forEach(coupon => {
|
||||
if (coupon.status === 0) { // 只统计未使用的
|
||||
const menuIndex = firstLevelMenus.value.findIndex(menu => menu.type === coupon.type);
|
||||
if (menuIndex !== -1) {
|
||||
firstLevelMenus.value[menuIndex].count++;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 兑换优惠券
|
||||
const exchange = async () => {
|
||||
if (!exchange_code.value) {
|
||||
uToast.value.show({
|
||||
message: '请输入兑换码',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let data = await couponReceive({ code: exchange_code.value });
|
||||
if (data) {
|
||||
uToast.value.show({
|
||||
message: '兑换成功',
|
||||
type: 'success'
|
||||
});
|
||||
exchange_code.value = '';
|
||||
resetAndReload();
|
||||
}
|
||||
}
|
||||
|
||||
// 使用范围
|
||||
const typeInfo = (type) => {
|
||||
if (type == 0) {
|
||||
return '通用'
|
||||
}
|
||||
if (type == 1) {
|
||||
return '自取'
|
||||
}
|
||||
if (type == 2) {
|
||||
return '外卖'
|
||||
}
|
||||
}
|
||||
|
||||
// 打开优惠券详情
|
||||
const openDetailModal = (couponItem, index) => {
|
||||
couponIndex.value = index;
|
||||
coupon.value = couponItem;
|
||||
detailModalVisible.value = true;
|
||||
}
|
||||
|
||||
// 使用优惠券
|
||||
const useCouponWith = (coupon) => {
|
||||
useCoupon();
|
||||
}
|
||||
|
||||
// 关闭详情模态框
|
||||
const closeDetailModal = () => {
|
||||
detailModalVisible.value = false;
|
||||
coupon.value = {};
|
||||
}
|
||||
|
||||
// 使用优惠券
|
||||
const useCoupon = () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/menu/menu'
|
||||
})
|
||||
}
|
||||
|
||||
// 显示使用规则
|
||||
const showRules = (item) => {
|
||||
uni.showModal({
|
||||
title: '使用规则',
|
||||
content: `满${item.least}元可用,最高减${item.value}元`,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* #ifdef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 菜单容器样式 */
|
||||
.menu-container {
|
||||
background-color: #ffffff;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
/* 一级菜单样式 */
|
||||
.first-level-menu {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
.menu-item {
|
||||
padding: 10rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
color: #52ac41;
|
||||
font-weight: bold;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40rpx;
|
||||
height: 4rpx;
|
||||
background-color: #52ac41;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 二级菜单样式 */
|
||||
.second-level-menu {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 20rpx 0;
|
||||
|
||||
.menu-item {
|
||||
padding: 10rpx 30rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
border-radius: 30rpx;
|
||||
|
||||
&.active {
|
||||
color: #ffffff;
|
||||
background-color: #52ac41;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 兑换码区域样式 */
|
||||
.exchange-box {
|
||||
flex-shrink: 0;
|
||||
height: 120rpx;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
width: 70%;
|
||||
flex-shrink: 0;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #eee;
|
||||
border-right: 0;
|
||||
border-radius: 8rpx 0 0 8rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-base;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0 8rpx 8rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 优惠券列表样式 */
|
||||
.coupon-list {
|
||||
height: calc(100vh - 240rpx);
|
||||
/* #ifdef H5 */
|
||||
height: calc(100vh - 240rpx - 44px);
|
||||
/* #endif */
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
/* 优惠券卡片样式 */
|
||||
.coupon {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.coupon-card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
// .ticket {
|
||||
// display: flex;
|
||||
// position: relative;
|
||||
|
||||
// &::before {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// left: -10rpx;
|
||||
// top: 50%;
|
||||
// width: 20rpx;
|
||||
// height: 20rpx;
|
||||
// border-radius: 50%;
|
||||
// background-color: #f5f5f5;
|
||||
// transform: translateY(-50%);
|
||||
// }
|
||||
|
||||
// &::after {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// right: -10rpx;
|
||||
// top: 50%;
|
||||
// width: 20rpx;
|
||||
// height: 20rpx;
|
||||
// border-radius: 50%;
|
||||
// background-color: #f5f5f5;
|
||||
// transform: translateY(-50%);
|
||||
// }
|
||||
|
||||
// .left {
|
||||
// flex: 1;
|
||||
// padding: 30rpx;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// border-right: 1rpx dashed #e0e0e0;
|
||||
|
||||
// .discount {
|
||||
// display: flex;
|
||||
// align-items: baseline;
|
||||
// color: #ff5722;
|
||||
// margin-right: 20rpx;
|
||||
|
||||
// .big {
|
||||
// font-size: 80rpx;
|
||||
// font-weight: bold;
|
||||
// line-height: 1;
|
||||
// }
|
||||
|
||||
// .unit {
|
||||
// font-size: 28rpx;
|
||||
// margin-left: 4rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .introduce {
|
||||
// flex: 1;
|
||||
|
||||
// .title {
|
||||
// font-size: 28rpx;
|
||||
// color: #333;
|
||||
// font-weight: bold;
|
||||
// margin-bottom: 10rpx;
|
||||
// }
|
||||
|
||||
// .date {
|
||||
// font-size: 22rpx;
|
||||
// color: #999;
|
||||
// margin-bottom: 10rpx;
|
||||
// }
|
||||
|
||||
// .rule {
|
||||
// font-size: 22rpx;
|
||||
// color: #52ac41;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// .right {
|
||||
// width: 180rpx;
|
||||
// padding: 30rpx 20rpx;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
|
||||
// .use-btn {
|
||||
// width: 140rpx;
|
||||
// height: 60rpx;
|
||||
// line-height: 60rpx;
|
||||
// text-align: center;
|
||||
// background-color: #ff5722;
|
||||
// color: #ffffff;
|
||||
// font-size: 24rpx;
|
||||
// border-radius: 30rpx;
|
||||
// margin-bottom: 10rpx;
|
||||
// }
|
||||
|
||||
// .status-text {
|
||||
// font-size: 24rpx;
|
||||
// margin-bottom: 10rpx;
|
||||
|
||||
// &.used {
|
||||
// color: #999;
|
||||
// }
|
||||
|
||||
// &.expired {
|
||||
// color: #999;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .used-time,
|
||||
// .expired-info {
|
||||
// font-size: 20rpx;
|
||||
// color: #999;
|
||||
// text-align: center;
|
||||
// }
|
||||
|
||||
// .expired-info {
|
||||
// color: #ff5722;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
.ticket {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
width: 70%;
|
||||
padding: 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
border-right: dashed 2rpx rgb(224, 215, 211);
|
||||
display: flex;
|
||||
|
||||
.picture {
|
||||
//width: 172rpx;
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
|
||||
.coupon-type {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
background-color: #f9ae3d;
|
||||
padding: 5rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 0rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.introduce {
|
||||
margin-left: 10rpx;
|
||||
|
||||
.top {
|
||||
color: $uv-warning;
|
||||
font-size: 28rpx;
|
||||
|
||||
.big {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
max-width: 300rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.type {
|
||||
font-size: 28rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-top: 10rpx;
|
||||
font-size: 20rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 30%;
|
||||
padding: 40rpx 20rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.use {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
color: #ffffff !important;
|
||||
background-color: $uv-warning !important;
|
||||
line-height: 40rpx;
|
||||
color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 10rpx;
|
||||
padding: 0 20rpx;
|
||||
margin-left: 20rpx;
|
||||
|
||||
&.used {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&.expired {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.used {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 40rpx;
|
||||
//color: #ffffff!important;
|
||||
//background-color: $u-type-warning!important;
|
||||
line-height: 40rpx;
|
||||
//color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right_log {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
padding: 80rpx 0rpx;
|
||||
background-color: white; //rgb(255, 245, 244);
|
||||
border-radius: 20rpx;
|
||||
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* 模态框样式 */
|
||||
.modal-content {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.use-coupon-btn {
|
||||
width: 95%;
|
||||
border-radius: 50rem !important;
|
||||
background-color: #52ac41 !important;
|
||||
}
|
||||
</style>
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
|
||||
<image class="avatar" :src="userAvatar" mode="aspectFill" @tap="goToEditInfo"></image>
|
||||
<view class="user-detail">
|
||||
<view class="flex-row" style="align-items: center">
|
||||
<text class="username">Hi,{{ userName }}</text>
|
||||
@ -238,6 +238,13 @@ const goToApplyForm = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 跳转到编辑信息页面
|
||||
const goToEditInfo = () => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/components/pages/fenxiao/fenxiaorequestform?id=${userId.value}&isEdit=true`,
|
||||
});
|
||||
};
|
||||
|
||||
// 显示邀请码弹窗
|
||||
const showInviteCodePopup = () => {
|
||||
showInvitePopup.value = true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<uv-navbar :fixed="false" title="申请成为分销员" left-arrow @leftClick="$onClickLeft" />
|
||||
<uv-navbar :fixed="false" :title="isEdit ? '编辑分销员信息' : '申请成为分销员'" left-arrow @leftClick="$onClickLeft" />
|
||||
<view class="page">
|
||||
<!-- 头部导航 -->
|
||||
<!-- <view class="header">
|
||||
@ -58,8 +58,8 @@
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<view class="action-area">
|
||||
<view class="submit-btn" @tap="submitForm">提交</view>
|
||||
<view class="benefit-box">
|
||||
<view class="submit-btn" @tap="submitForm">{{ isEdit ? '保存修改' : '提交' }}</view>
|
||||
<view class="benefit-box" v-if="!isEdit">
|
||||
<view class="benefit-title" style="font-weight: bold; font-size: 36rpx;">为什么要加入我们?</view>
|
||||
<view class="benefit-item">
|
||||
<text class="benefit-text">加入我们的分销团队,不仅能共享潜力巨大的健康市场红利,更是爱的传递。</text>
|
||||
@ -81,11 +81,14 @@ import { ref, reactive } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { useMainStore } from "@/store/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { createDistributor } from "@/api/distributor";
|
||||
import { createDistributor, getDistributorInfo, editDistributor } from "@/api/distributor";
|
||||
|
||||
const main = useMainStore();
|
||||
const { isLogin, member } = storeToRefs(main);
|
||||
|
||||
// 是否是编辑模式
|
||||
const isEdit = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: "", // ID
|
||||
@ -155,28 +158,66 @@ const validateForm = () => {
|
||||
return true;
|
||||
};
|
||||
|
||||
// 加载分销商信息
|
||||
const loadDistributorInfo = async (id) => {
|
||||
try {
|
||||
const data = await getDistributorInfo({ id });
|
||||
if (data) {
|
||||
formData.id = data.id;
|
||||
formData.name = data.name;
|
||||
formData.phone = data.phone;
|
||||
formData.workUnit = data.workUnit || "";
|
||||
formData.recipientName = data.recipientName;
|
||||
formData.bankCardNumber = data.bankCardNumber;
|
||||
formData.bankName = data.bankName;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载分销商信息失败:", error);
|
||||
uni.showToast({
|
||||
title: "加载信息失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
if (!validateForm()) return;
|
||||
uni.showLoading({
|
||||
title: "提交中...",
|
||||
title: isEdit.value ? "保存中..." : "提交中...",
|
||||
});
|
||||
|
||||
// 调用分销商申请接口
|
||||
// 调用分销商申请/更新接口
|
||||
const requestData = {
|
||||
memberId: member.value.id, // ID 可选
|
||||
memberId: member.value.id,
|
||||
name: formData.name,
|
||||
phone: formData.phone,
|
||||
workUnit: formData.workUnit || "", // 工作单位可选
|
||||
recipientName: formData.recipientName, // 收款人姓名可选
|
||||
bankCardNumber: formData.bankCardNumber, // 银行卡号可选
|
||||
bankName: formData.bankName, // 开户行可选
|
||||
workUnit: formData.workUnit || "",
|
||||
recipientName: formData.recipientName,
|
||||
bankCardNumber: formData.bankCardNumber,
|
||||
bankName: formData.bankName,
|
||||
};
|
||||
|
||||
let data = await createDistributor(requestData);
|
||||
try {
|
||||
// let data = await createDistributor(requestData);
|
||||
let data = null;
|
||||
if (isEdit.value) {
|
||||
data = await editDistributor({
|
||||
id: formData.id,
|
||||
memberId: member.value.id,
|
||||
name: formData.name,
|
||||
phone: formData.phone,
|
||||
workUnit: formData.workUnit || "",
|
||||
recipientName: formData.recipientName,
|
||||
bankCardNumber: formData.bankCardNumber,
|
||||
bankName: formData.bankName,
|
||||
});
|
||||
} else {
|
||||
data = await createDistributor(requestData);
|
||||
}
|
||||
if (data) {
|
||||
uni.showToast({
|
||||
title: "申请提交成功",
|
||||
title: isEdit.value ? "保存成功" : "申请提交成功",
|
||||
icon: "success",
|
||||
});
|
||||
|
||||
@ -185,6 +226,15 @@ const submitForm = async () => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("提交失败:", error);
|
||||
uni.showToast({
|
||||
title: "提交失败",
|
||||
icon: "none",
|
||||
});
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
};
|
||||
|
||||
// 返回上一页
|
||||
@ -196,11 +246,18 @@ const goBack = () => {
|
||||
onLoad((options) => {
|
||||
if (!isLogin.value) {
|
||||
uni.navigateTo({ url: "/pages/components/pages/login/login" });
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取传入的id参数并赋值
|
||||
if (options && options.id) {
|
||||
// 判断是否是编辑模式
|
||||
if (options && options.isEdit === "true") {
|
||||
isEdit.value = true;
|
||||
}
|
||||
|
||||
// 获取传入的id参数并加载数据
|
||||
if (options && options.id && options.isEdit === "true") {
|
||||
formData.id = options.id;
|
||||
loadDistributorInfo(options.id);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -77,6 +77,7 @@ const isChecked = ref(false)
|
||||
const openid = ref(main.openid)
|
||||
const uToast = ref()
|
||||
const uCode = ref()
|
||||
const couponId = ref('');
|
||||
|
||||
const captchaStyle = computed(() => {
|
||||
let style = {};
|
||||
@ -87,6 +88,12 @@ const captchaStyle = computed(() => {
|
||||
return style;
|
||||
});
|
||||
|
||||
onLoad(async (options) => {
|
||||
if (options.couponId) {
|
||||
couponId.value = options.couponId;
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
@ -140,7 +147,13 @@ const loginForWechatMini = async (e) => {
|
||||
type: 'success'
|
||||
});
|
||||
setTimeout(function() {
|
||||
if(couponId.value != ''){
|
||||
uni.redirectTo({
|
||||
url: '/pages/components/pages/coupons/coupons?couponId=' + couponId.value
|
||||
})
|
||||
}else{
|
||||
uni.navigateBack();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
}else {
|
||||
|
@ -78,9 +78,12 @@ const questionList = ref([
|
||||
|
||||
]);
|
||||
|
||||
const phoneNumber = ref('');
|
||||
|
||||
onLoad((options) => {
|
||||
if (options && options.phone) {
|
||||
phoneNumber.value = options.phone;
|
||||
if (options && options.phoneNumber) {
|
||||
console.log("电话:==============",options.phoneNumber)
|
||||
phoneNumber.value = options.phoneNumber;
|
||||
}
|
||||
});
|
||||
|
||||
@ -121,7 +124,7 @@ const closePopup = () => {
|
||||
// 添加打电话方法
|
||||
const callService = () => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: '15251830311' // 替换为实际客服电话
|
||||
phoneNumber: phoneNumber.value // 替换为实际客服电话
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
@ -248,6 +248,14 @@
|
||||
<view>优惠金额</view>
|
||||
<view class="font-weight-bold">¥{{ order.couponPrice }}</view>
|
||||
</view>
|
||||
<view class="pay-cell" v-if="order.couponType == 2">
|
||||
<view>商品券</view>
|
||||
<view class="font-weight-bold">{{ order.title }}</view>
|
||||
</view>
|
||||
<view class="pay-cell" v-if="order.couponType == 2">
|
||||
<view>商品券规格</view>
|
||||
<view class="font-weight-bold">{{ order.couponProductSpec }}</view>
|
||||
</view>
|
||||
<view class="pay-cell">
|
||||
<view>实付金额</view>
|
||||
<view class="font-weight-bold">¥{{ order.payPrice }}</view>
|
||||
|
@ -1,20 +1,17 @@
|
||||
<template>
|
||||
<uv-navbar
|
||||
:fixed="false"
|
||||
:title="title"
|
||||
left-arrow
|
||||
@leftClick="$onClickLeft"
|
||||
/>
|
||||
<uv-navbar :fixed="false" :title="title" left-arrow @leftClick="$onClickLeft" />
|
||||
<view class="container position-relative w-100 h-100 overflow-hidden">
|
||||
<uv-empty v-if="coupons.length == 0" mode="coupon"></uv-empty>
|
||||
|
||||
<scroll-view scroll-y class="coupon-list">
|
||||
<view class="wrapper">
|
||||
<view class="coupon" v-for="(item, index) in coupons" :key="index" @tap="openDetailModal(item, index)">
|
||||
<view class="taobao">
|
||||
<view class="ticket" :style="{border: item.id == coupon_id ? '1rpx solid red':''}">
|
||||
<view class="taobao" v-if="item.couponType == 1">
|
||||
<view class="ticket" :style="{ border: item.id == coupon_id ? '1rpx solid red' : '' }">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill"></image>
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">满减券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
¥
|
||||
@ -22,12 +19,38 @@
|
||||
<view>满{{ item.least }}减{{ item.value }}</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{formatDateTime(item.startTime, 'yyyy-MM-dd')}}-{{formatDateTime(item.endTime, 'yyyy-MM-dd')}}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.id != coupon_id" class="use immediate-use" :round="true" @tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="cancelCoupon(item)">取消使用</view>
|
||||
<view v-if="item.id != coupon_id" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="cancelCoupon(item)">取消使用
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="taobao" v-if="item.couponType == 2">
|
||||
<view class="ticket" :style="{ border: item.id == coupon_id ? '1rpx solid red' : '' }">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">商品券</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
商品名称:<text class="big" style=" font-size: 32rpx;">{{ item.productName }}</text>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date u-line-1">{{ formatDateTime(item.startTime,
|
||||
'yyyy-MM-dd') }}-{{ formatDateTime(item.endTime, 'yyyy-MM-dd') }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" @click.stop="" v-if="activeTabIndex == 0">
|
||||
<view v-if="item.id != coupon_id" class="use immediate-use" :round="true"
|
||||
@tap="useCouponWith(item)">立即使用</view>
|
||||
<view v-else class="use immediate-use" :round="true" @tap="cancelCoupon(item)">取消使用
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -37,10 +60,16 @@
|
||||
|
||||
<modal custom :show="detailModalVisible" @cancel="closeDetailModal" width="90%">
|
||||
<view class="modal-content">
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">有效期:{{formatDateTime(coupon.startTime, 'yyyy-MM-dd')}}至{{formatDateTime(coupon.endTime, 'yyyy-MM-dd')}}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">领取时间:{{formatDateTime(coupon.createTime, 'yyyy-MM-dd')}}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">卷价值:满{{ coupon.least }}减{{ coupon.value }}</view>
|
||||
<view class="d-flex font-size-extra-lg text-color-base just-content-center mb-20">{{ coupon.title }}
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">有效期:{{ formatDateTime(coupon.startTime,
|
||||
'yyyy-MM-dd') }}至{{ formatDateTime(coupon.endTime, 'yyyy-MM-dd') }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">领取时间:{{ formatDateTime(coupon.createTime,
|
||||
'yyyy-MM-dd') }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-if="coupon.couponType == 1">卷价值:满{{
|
||||
coupon.least }}减{{ coupon.value }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20" v-else>券价值:使用此券免费领取 {{ coupon.productName }} 一份
|
||||
</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">适用范围:{{ typeInfo(coupon.type) }}</view>
|
||||
<view class="d-flex font-size-sm text-color-base mb-20">适用店铺:{{ coupon.shopName }}</view>
|
||||
<view class="d-flex align-items-center just-content-center" v-if="activeTabIndex == 0">
|
||||
@ -62,10 +91,10 @@ import {
|
||||
} from 'vue'
|
||||
import { useMainStore } from '@/store/store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onLoad,onShow ,onPullDownRefresh,onHide} from '@dcloudio/uni-app'
|
||||
import { formatDateTime,prePage } from '@/utils/util'
|
||||
import { onLoad, onShow, onPullDownRefresh, onHide } from '@dcloudio/uni-app'
|
||||
import { formatDateTime, prePage } from '@/utils/util'
|
||||
import {
|
||||
couponMine
|
||||
couponCanUserMine
|
||||
} from '@/api/coupon'
|
||||
const main = useMainStore()
|
||||
const { isLogin } = storeToRefs(main)
|
||||
@ -115,8 +144,8 @@ const typeInfo = (type) => {
|
||||
return '外卖';
|
||||
}
|
||||
}
|
||||
const getCoupons = async() => {
|
||||
let data = await couponMine({shopId: shop_id.value, type: type.value, page:1, pagesize:10000});
|
||||
const getCoupons = async () => {
|
||||
let data = await couponCanUserMine({ shopId: shop_id.value, type: type.value, page: 1, pagesize: 10000 });
|
||||
uni.stopPullDownRefresh();
|
||||
if (data) {
|
||||
coupons.value = data;
|
||||
@ -151,17 +180,19 @@ const useCoupon = () => {
|
||||
return;
|
||||
}
|
||||
buttonLock.value = true
|
||||
console.log('coupon:',coupon.value);
|
||||
console.log('coupon-------:', coupon.value);
|
||||
// 判断是满减券还是商品券
|
||||
if (coupon.value.couponType == 1) {
|
||||
if (parseFloat(coupon.value.least) > parseFloat(amount.value)) {
|
||||
//console.log('pages3:');
|
||||
uToast.value.show({
|
||||
message: '订单金额满'+coupon.value.least+'才能使用',
|
||||
message: '订单金额满' + coupon.value.least + '才能使用',
|
||||
type: 'error'
|
||||
});
|
||||
buttonLock.value = false
|
||||
} else {
|
||||
main.SET_COUPON(coupon)
|
||||
console.log('main.myconpon:',main.mycoupon)
|
||||
console.log('main.myconpon:', main.mycoupon)
|
||||
//prePage().coupon = coupon.value;
|
||||
//prePage().coupons = 1; // 哨兵
|
||||
|
||||
@ -170,7 +201,14 @@ const useCoupon = () => {
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
} else if (coupon.value.couponType == 2) {
|
||||
main.SET_COUPON(coupon)
|
||||
console.log('main.myconpon:', main.mycoupon)
|
||||
//prePage().coupon = coupon.value;
|
||||
//prePage().coupons = 1; // 哨兵
|
||||
uni.navigateBack({
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -182,6 +220,7 @@ const useCoupon = () => {
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.container {
|
||||
@ -192,7 +231,7 @@ page {
|
||||
|
||||
.coupon-list {
|
||||
margin-top: 30rpx;
|
||||
height:calc(100vh - 120rpx);
|
||||
height: calc(100vh - 120rpx);
|
||||
// height: calc(100vh - 120rpx - 200rpx);
|
||||
/* #ifdef H5 */
|
||||
// height: calc(100vh - 120rpx - 200rpx - 44px);
|
||||
@ -266,25 +305,30 @@ page {
|
||||
|
||||
.taobao {
|
||||
background-color: white;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 30rpx;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.store {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.buddha {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.entrance {
|
||||
color: $uv-info;
|
||||
border: solid 2rpx $uv-info;
|
||||
@ -294,8 +338,10 @@ page {
|
||||
border-radius: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.ticket {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
width: 70%;
|
||||
padding: 20rpx;
|
||||
@ -303,27 +349,48 @@ page {
|
||||
border-radius: 20rpx;
|
||||
border-right: dashed 2rpx rgb(224, 215, 211);
|
||||
display: flex;
|
||||
|
||||
.picture {
|
||||
//width: 172rpx;
|
||||
border-radius: 20rpx;
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
|
||||
.coupon-type {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
background-color: #f9ae3d;
|
||||
padding: 5rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 10rpx;
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 0rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.introduce {
|
||||
margin-left: 10rpx;
|
||||
|
||||
.top {
|
||||
color: $uv-warning;
|
||||
font-size: 28rpx;
|
||||
|
||||
.big {
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
max-width: 300rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.type {
|
||||
font-size: 28rpx;
|
||||
color: $uv-info-dark;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-top: 10rpx;
|
||||
font-size: 20rpx;
|
||||
@ -331,6 +398,7 @@ page {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 30%;
|
||||
padding: 40rpx 20rpx;
|
||||
@ -338,6 +406,7 @@ page {
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.use {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
@ -349,6 +418,7 @@ page {
|
||||
color: rgb(117, 142, 165);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.used {
|
||||
height: auto;
|
||||
padding: 0 20rpx;
|
||||
@ -361,6 +431,7 @@ page {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.right_log {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
|
@ -48,7 +48,19 @@
|
||||
</template>
|
||||
|
||||
<template>
|
||||
<list-cell arrow class="meal-time" v-if="orderType == 'takein'">
|
||||
|
||||
<list-cell v-if="applicablePromotions.length > 0">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center">
|
||||
<view class="text-color-base">优惠活动</view>
|
||||
<radio-group @change="onPromotionChange">
|
||||
<block v-for="(promotion, index) in applicablePromotions" :key="promotion.id">
|
||||
<radio :value="promotion.id" :checked="promotion.id === selectedPromotion.id" />
|
||||
<text>{{ promotion.name }}</text>
|
||||
</block>
|
||||
</radio-group>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell class="meal-time" v-if="orderType == 'takein'">
|
||||
<view class="flex-fill d-flex justify-content-between align-items-center" @click="takeinTIme = !takeinTIme">
|
||||
<view class="title">取餐时间</view>
|
||||
<view class="time">
|
||||
@ -174,19 +186,40 @@
|
||||
<!-- <view v-if="orderType == 'takeout'">餐盒费¥({{ store.canheDesc}}){{ store.canhePrice }}</view> -->
|
||||
|
||||
<view v-if="coupons == 0" class="text-color-base">暂无可用</view>
|
||||
<view v-else-if="coupon.title" class="text-color-danger">
|
||||
<view v-else-if="selectedPromotion" class="text-color-base">
|
||||
参与优惠活动无法使用优惠券
|
||||
</view>
|
||||
<view v-else-if="coupon.title && coupon.couponType == 1" class="text-color-danger">
|
||||
{{ coupon.title }}(满{{ coupon.least }}减{{ coupon.value }})
|
||||
</view>
|
||||
<view v-else-if="coupon.title && coupon.couponType == 2" class="text-color-danger">
|
||||
{{ coupon.productName }}
|
||||
</view>
|
||||
<view v-else class="text-color-primary">可用优惠券{{ coupons }}张</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell v-if="coupon.title && coupon.couponType == 2 && couponProduct != null">
|
||||
<view class="good-properties">
|
||||
<view class="property-item" v-for="(item, index) in couponProduct.productAttr" :key="index">
|
||||
<view class="property-name">
|
||||
<text class="name">{{ item.attrName }}</text>
|
||||
</view>
|
||||
<view class="property-values">
|
||||
<view class="property-value" v-for="(value, key) in item.attrValueArr" :key="key"
|
||||
:class="{ selected: value == selectedSpecs[index] }" @tap="changeSpecDefault(index, key, false)">
|
||||
{{ value }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</list-cell>
|
||||
<list-cell last>
|
||||
<view class="flex-fill d-flex justify-content-end align-items-center">
|
||||
<view>
|
||||
总计¥{{ total }}
|
||||
<!-- <text v-if="orderType == 'takeout'">,配送费¥{{ store.deliveryPrice }}</text> -->
|
||||
|
||||
<text v-if="coupon.value">,¥-{{ coupon.value }}</text>
|
||||
<text v-if="coupon.value && coupon.couponType == 1">,¥-{{ coupon.value }}</text>
|
||||
,实付
|
||||
</view>
|
||||
<view class="font-size-extra-lg font-weight-bold">¥{{ amount }}</view>
|
||||
@ -303,7 +336,57 @@ import { formatDateTime, isWeixin } from "@/utils/util";
|
||||
import debounce from "@/uni_modules/uv-ui-tools/libs/function/debounce";
|
||||
|
||||
import { orderSubmit, payUnify, getWechatConfig } from "@/api/order";
|
||||
import { getGoods } from '@/api/goods';
|
||||
import { couponCount } from "@/api/coupon";
|
||||
import { getPromotionactivityInfo } from "@/api/activity"; // 确保路径正确
|
||||
const promotionActivities = ref([]); //所有优惠活动
|
||||
const selectedPromotion = ref(null); // 用于存储用户选择的优惠活动
|
||||
const showPromotionModal = ref(false); // 控制优惠选择弹窗的显示
|
||||
const applicablePromotions = ref([]); // 存储当前购物车适用的优惠活动
|
||||
const selectedPromotionId = ref(null);
|
||||
|
||||
|
||||
// 用户选择优惠活动后的处理
|
||||
// const changeSpecDefault = (index, key) => {
|
||||
// selectedSpecs.value[index] = couponProduct.value.productAttr[index].attrValueArr[key];
|
||||
// console.log(selectedSpecs, "-------------")
|
||||
// };
|
||||
|
||||
const valueStr = ref('');
|
||||
const changeSpecDefault = (index, key, isDefault) => {
|
||||
// console.log("good:", good.value);
|
||||
if (isDefault) {
|
||||
selectedSpecs.value = [];
|
||||
for (let i = 0; i < couponProduct.value.productAttr.length; i++) {
|
||||
selectedSpecs.value[i] = couponProduct.value.productAttr[i].attrValueArr[0];
|
||||
}
|
||||
} else {
|
||||
selectedSpecs.value[index] = couponProduct.value.productAttr[index].attrValueArr[key];
|
||||
}
|
||||
valueStr.value = selectedSpecs.value.join(",");
|
||||
// 转换为数组并排序
|
||||
const sortedArray = valueStr.value.split(",").sort((a, b) => {
|
||||
return a.charCodeAt(0) - b.charCodeAt(0); // 比较Unicode码点
|
||||
});
|
||||
|
||||
// 重新组合为字符串
|
||||
valueStr.value = sortedArray.join(",");
|
||||
// console.log('valueStr:000000000000', valueStr.value);
|
||||
// console.log('selectedSpecs.value:', selectedSpecs.value);
|
||||
};
|
||||
|
||||
const onPromotionChange = (e) => {
|
||||
// 1. 获取选中项的ID
|
||||
const selectedId = e.detail.value;
|
||||
|
||||
// 2. 通过ID查找完整对象
|
||||
selectedPromotion.value = applicablePromotions.value.find(
|
||||
p => p.id == parseInt(selectedId)
|
||||
);
|
||||
selectedPromotionId.value = selectedPromotion.value.id
|
||||
// console.log("ssssssssssssssss", selectedPromotion.value);
|
||||
};
|
||||
|
||||
// #ifdef H5
|
||||
import * as jweixin from "weixin-js-sdk";
|
||||
// #endif
|
||||
@ -371,6 +454,10 @@ const subscribeMss = ref({
|
||||
}); // 微信订阅信息
|
||||
const uToast = ref();
|
||||
|
||||
//优惠券,商品券商品信息
|
||||
const couponProduct = ref(null);
|
||||
const selectedSpecs = ref([]);
|
||||
|
||||
// 在script部分添加打包费计算属性
|
||||
// const getPackingFee = computed(() => {
|
||||
// // 计算打包费(根据每个商品的boxFee计算)
|
||||
@ -380,7 +467,15 @@ const getPackingFee = computed(() => {
|
||||
if (orderType.value === 'takein' && !needPacking.value) {
|
||||
return 0;
|
||||
}
|
||||
return cart.value.reduce((acc, cur) => acc + cur.number * (cur.boxFee || 0), 0);
|
||||
let totalboxFee = cart.value.reduce((acc, cur) => acc + cur.number * (cur.boxFee || 0), 0);
|
||||
// 商品优惠券也需要配送费
|
||||
if (coupon.value && coupon.value.couponType == 2) {
|
||||
// console.log("优惠券商品打包费:", couponProduct.value?.boxFee);
|
||||
totalboxFee += parseFloat(couponProduct.value?.boxFee || 0);
|
||||
}
|
||||
|
||||
return totalboxFee;
|
||||
|
||||
});
|
||||
|
||||
// 修改total计算属性
|
||||
@ -392,12 +487,19 @@ const total = computed(() => {
|
||||
total += parseFloat(store.value.deliveryPrice);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return total.toFixed(2);
|
||||
});
|
||||
|
||||
// 修改amount计算属性
|
||||
const amount = computed(() => {
|
||||
let amount = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0) + getPackingFee.value;
|
||||
let amount;
|
||||
if (selectedPromotion.value != null) {
|
||||
amount = cart.value.reduce((acc, cur) => acc + cur.number * cur.price * selectedPromotion.value.discountRate, 0) + getPackingFee.value;
|
||||
} else {
|
||||
amount = cart.value.reduce((acc, cur) => acc + cur.number * cur.price, 0) + getPackingFee.value;
|
||||
}
|
||||
|
||||
// 加配送费
|
||||
if (store.value.distance > 0 && orderType.value == "takeout" && store.value.freeDeliveryPrice != 1) {
|
||||
@ -405,7 +507,7 @@ const amount = computed(() => {
|
||||
}
|
||||
|
||||
// 减去优惠券
|
||||
if (main.mycoupon.hasOwnProperty("id")) {
|
||||
if (main.mycoupon.hasOwnProperty("id") && main.mycoupon.couponType == 1) {
|
||||
amount -= parseFloat(main.mycoupon.value);
|
||||
}
|
||||
return amount.toFixed(2);
|
||||
@ -413,6 +515,15 @@ const amount = computed(() => {
|
||||
|
||||
onShow(() => {
|
||||
coupon.value = main.mycoupon;
|
||||
|
||||
// console.log(coupon.value,"--------------")
|
||||
if (coupon.value.couponType == 2) {
|
||||
getGoods(coupon.value.productId).then(res => {
|
||||
couponProduct.value = res;
|
||||
// console.log(couponProduct.value, "couponProduct.value==============");
|
||||
changeSpecDefault(0, 0, true);
|
||||
})
|
||||
}
|
||||
let date = new Date(new Date().getTime() + 1800000); // 一个小时后
|
||||
let hour = date.getHours();
|
||||
let minute = date.getMinutes();
|
||||
@ -451,8 +562,33 @@ onHide(() => {
|
||||
subscribeMss.value = [];
|
||||
coupons.value = 0;
|
||||
});
|
||||
onLoad((option) => {
|
||||
onLoad(async (option) => {
|
||||
|
||||
// 清空优惠券
|
||||
coupon.value = {};
|
||||
main.DEL_COUPON();
|
||||
|
||||
// 接收优惠活动ID参数
|
||||
|
||||
if (option.promotionId) {
|
||||
// 获取优惠活动id,为对象时取id属性
|
||||
// console.log(selectedPromotionId.value,"--------");
|
||||
console.log(option.promotionId, "option.promotionId11111111111")
|
||||
if (option.promotionId != null && option.promotionId != undefined && option.promotionId != 'undefined' && option.promotionId != '') {
|
||||
|
||||
selectedPromotionId.value = option.promotionId;
|
||||
}
|
||||
console.log(selectedPromotionId.value, "--------");
|
||||
}
|
||||
|
||||
cart.value = uni.getStorageSync("cart");
|
||||
// 获取活动信息
|
||||
await loadPromotionActivities();
|
||||
|
||||
//获取符合的优惠活动
|
||||
isPromotionActivity();
|
||||
|
||||
|
||||
if (option.remark) {
|
||||
form.value.remark = option.remark;
|
||||
}
|
||||
@ -460,6 +596,10 @@ onLoad((option) => {
|
||||
if (option.distributorId) {
|
||||
distributorId.value = option.distributorId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
const getSubscribeMss = async () => {
|
||||
@ -572,6 +712,13 @@ const chooseAddress = () => {
|
||||
});
|
||||
};
|
||||
const goToPackages = () => {
|
||||
if (selectedPromotion.value) {
|
||||
uToast.value.show({
|
||||
message: '参与优惠活动无法使用优惠券',
|
||||
type: 'error'
|
||||
});
|
||||
return
|
||||
}
|
||||
let newamount = amount.value;
|
||||
let coupon_id = coupon.value.id ? coupon.value.id : 0;
|
||||
let type = orderType.value == "takein" ? 1 : 2;
|
||||
@ -687,6 +834,8 @@ const pay = async () => {
|
||||
couponId: coupon.value.id ? coupon.value.id : 0, // 优惠券id
|
||||
distributorId: distributorId.value ? distributorId.value : null, // 分销商id
|
||||
needPacking: needPacking.value, // 是否需要打包费
|
||||
promotionActivityId: selectedPromotion.value ? selectedPromotion.value.id : 0, // 优惠活动id
|
||||
couponProductSpec: valueStr.value,
|
||||
};
|
||||
|
||||
cart.value.forEach((item, index) => {
|
||||
@ -883,6 +1032,88 @@ const fillMobile = () => {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const loadPromotionActivities = async () => {
|
||||
try {
|
||||
const data = { pageNo: 1, pageSize: 100, shopId: store.value.id ? store.value.id : 0 }
|
||||
const res = await getPromotionactivityInfo(data);
|
||||
// console.log("res:", res);
|
||||
if (res) {
|
||||
promotionActivities.value = res.list; // 假设接口返回的数据在 data 字段
|
||||
console.log("promotionActivities活动信息000000000:", promotionActivities.value);
|
||||
} else {
|
||||
console.error('获取优惠活动失败:', res.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取优惠活动异常:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 判断是否满足优惠活动、
|
||||
const isPromotionActivity = () => {
|
||||
// console.log("===============初始化时判断是否满足优惠活动", cart.value);
|
||||
// applicablePromotions.value = [];
|
||||
const applicablePromotionsCopy = [];
|
||||
|
||||
if (promotionActivities.value && promotionActivities.value.length > 0) {
|
||||
promotionActivities.value.forEach(promo => {
|
||||
const productIds = promo.productId ? promo.productId.split(',') : [];
|
||||
// 遍历购物车计算活动商品总额和数量
|
||||
let activityAmount = 0;
|
||||
let activityCount = 0;
|
||||
cart.value.forEach(item => {
|
||||
if (productIds.includes(String(item.id))) {
|
||||
activityAmount += item.price * item.number;
|
||||
activityCount += item.number;
|
||||
}
|
||||
});
|
||||
|
||||
if (activityAmount >= promo.minAmount && activityCount >= promo.minQuantity) {
|
||||
applicablePromotionsCopy.push(promo);
|
||||
}
|
||||
|
||||
});
|
||||
console.log(applicablePromotionsCopy.length, "applicablePromotionssssssssssssssss:", applicablePromotionsCopy);
|
||||
// 遍历判断是否有匹配的优惠活动ID
|
||||
if (selectedPromotionId.value) {
|
||||
let hasMatch = false;
|
||||
for (let i = 0; i < applicablePromotionsCopy.length; i++) {
|
||||
console.log("11111222222", selectedPromotionId.value, "=======", applicablePromotionsCopy[i].id);
|
||||
console.log(selectedPromotionId.value == applicablePromotionsCopy[i].id);
|
||||
if (selectedPromotionId.value == applicablePromotionsCopy[i].id) {
|
||||
selectedPromotion.value = applicablePromotionsCopy[i];
|
||||
hasMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("hasMatch", hasMatch);
|
||||
|
||||
// 如果没有匹配的,则使用第一个优惠活动
|
||||
if (!hasMatch && applicablePromotionsCopy.length > 0) {
|
||||
selectedPromotionId.value = applicablePromotionsCopy[0].id;
|
||||
selectedPromotion.value = applicablePromotionsCopy[0];
|
||||
} else if (applicablePromotionsCopy.length < 1) {
|
||||
selectedPromotionId.value = null;
|
||||
selectedPromotion.value = null;
|
||||
}
|
||||
} else if (applicablePromotionsCopy.length > 0) {
|
||||
selectedPromotionId.value = applicablePromotionsCopy[0].id;
|
||||
selectedPromotion.value = applicablePromotionsCopy[0];
|
||||
}
|
||||
applicablePromotions.value = applicablePromotionsCopy;
|
||||
// console.log("选择的优惠活动:", selectedPromotion.value);
|
||||
// console.log("真实的优惠活动", applicablePromotions.value);
|
||||
} else {
|
||||
selectedPromotionId.value = null;
|
||||
selectedPromotion.value = null;
|
||||
}
|
||||
|
||||
if (selectedPromotion.value) {
|
||||
coupon.value = {};
|
||||
main.DEL_COUPON();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -1016,4 +1247,37 @@ const fillMobile = () => {
|
||||
font-size: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.good-properties {
|
||||
margin: 20rpx 0;
|
||||
|
||||
.property-item {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.property-name {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.property-values {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
|
||||
.property-value {
|
||||
padding: 10rpx 25rpx;
|
||||
border: 1rpx solid #52ac41;
|
||||
border-radius: 8rpx;
|
||||
transition: all 0.3s;
|
||||
|
||||
&.selected {
|
||||
border-color: #52ac41;
|
||||
color: #52ac41;
|
||||
background: #e8f7e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -144,10 +144,6 @@ const takeout = () => {
|
||||
const coupons = () => {
|
||||
console.log("--> % orderType:\n", main.orderType)
|
||||
console.log("--> % isLogin:\n", main.isLogin)
|
||||
if (!main.isLogin) {
|
||||
uni.navigateTo({ url: '/pages/components/pages/login/login' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/pages/components/pages/coupons/coupons'
|
||||
})
|
||||
|
217
pages/menu/coupon-float.vue
Normal file
217
pages/menu/coupon-float.vue
Normal file
@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<uv-popup ref="popup" mode="center" width="90%" @change="onChange" :safe-area-inset-bottom="true" class="coupon-float-popup" :zIndex="9999">
|
||||
<view class="coupon-float-container">
|
||||
<view class="header">
|
||||
<image class="icon" src="/static/images/coupon-icon.png" />
|
||||
<text class="title">我的优惠券</text>
|
||||
<view class="close-btn" @tap="onClose">
|
||||
<uv-icon name="close" size="28" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="coupon-list">
|
||||
<uv-empty v-if="coupons.length === 0" mode="coupon" text="暂无可用优惠券"></uv-empty>
|
||||
<view v-else class="wrapper">
|
||||
<view class="coupon-card" v-for="(item, index) in coupons" :key="item.id">
|
||||
<view class="left">
|
||||
<image class="picture" :src="item.image" mode="aspectFill">
|
||||
<view class="coupon-type">{{ item.couponType === 1 ? '满减券' : '商品券' }}</view>
|
||||
</image>
|
||||
<view class="introduce">
|
||||
<view class="top">
|
||||
<view v-if="item.couponType === 1" class="price">
|
||||
<text>¥</text>
|
||||
<text class="big">{{ item.value }}</text>
|
||||
</view>
|
||||
<view v-if="item.couponType === 2" class="price">
|
||||
<text>商品:</text>
|
||||
<text class="big">{{ item.productName }}</text>
|
||||
</view>
|
||||
<view v-if="item.couponType === 1">满{{ item.least }}减{{ item.value }}</view>
|
||||
</view>
|
||||
<view class="type">{{ item.title }}</view>
|
||||
<view class="date">有效期:{{ formatDate(item.startTime) }} - {{ formatDate(item.endTime) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<uv-icon name="gift" size="32" color="#f9ae3d" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</uv-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, watch, ref, nextTick } from 'vue'
|
||||
import { formatDateTime } from '@/utils/util'
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
coupons: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const popup = ref(null)
|
||||
|
||||
// 添加调试信息
|
||||
watch(() => props.show, (newVal) => {
|
||||
// console.log('优惠券弹框显示状态变化:', newVal)
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
popup.value?.open()
|
||||
})
|
||||
} else {
|
||||
popup.value?.close()
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.coupons, (newVal) => {
|
||||
// console.log('优惠券数据变化:', newVal)
|
||||
}, { deep: true })
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
const onChange = (e) => {
|
||||
// console.log('弹框状态变化:', e)
|
||||
if (!e.show) {
|
||||
emit('close')
|
||||
}
|
||||
}
|
||||
|
||||
const formatDate = (date) => formatDateTime(date, 'yyyy-MM-dd')
|
||||
|
||||
const onClose = () => {
|
||||
popup.value?.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.coupon-float-popup {
|
||||
z-index: 3002;
|
||||
}
|
||||
.coupon-float-container {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 0 0 32rpx 0;
|
||||
min-height: 400rpx;
|
||||
max-height: 70vh;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
padding: 32rpx 0 16rpx 0;
|
||||
.icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #f9ae3d;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
right: 32rpx;
|
||||
top: 32rpx;
|
||||
z-index: 2;
|
||||
padding: 8rpx;
|
||||
}
|
||||
}
|
||||
.coupon-list {
|
||||
max-height: 60vh;
|
||||
min-height: 200rpx;
|
||||
padding: 0 32rpx 0 32rpx;
|
||||
}
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
.coupon-card {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background: linear-gradient(90deg, #fffbe6 0%, #fff 100%);
|
||||
border-radius: 18rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(249,174,61,0.08);
|
||||
padding: 24rpx 20rpx;
|
||||
position: relative;
|
||||
.left {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
.picture {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-right: 18rpx;
|
||||
position: relative;
|
||||
.coupon-type {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: #f9ae3d;
|
||||
color: #fff;
|
||||
font-size: 22rpx;
|
||||
border-radius: 0 0 0 12rpx;
|
||||
padding: 2rpx 10rpx;
|
||||
}
|
||||
}
|
||||
.introduce {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.top {
|
||||
font-size: 28rpx;
|
||||
color: #f9ae3d;
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
.big {
|
||||
font-weight: bold;
|
||||
margin: 0 8rpx;
|
||||
}
|
||||
}
|
||||
.product {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
.big {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
margin: 0 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.type {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin: 4rpx 0 0 0;
|
||||
}
|
||||
.date {
|
||||
font-size: 22rpx;
|
||||
color: #aaa;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 60rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -35,7 +35,8 @@
|
||||
<view class="iconfont iconarrow-right"></view>
|
||||
</view>
|
||||
<view class="store-location flex-row align-center">
|
||||
<text class="small" v-if="store.distance > 0 && orderType == 'takeout'">(配送距离: {{
|
||||
<text class="small" v-if="store.distance > 0 && orderType == 'takeout'">(配送距离:
|
||||
{{
|
||||
store.distance }}km)</text>
|
||||
<text class="small" v-else-if="orderType == 'takeout'">(本店不支持外卖)</text>
|
||||
</view>
|
||||
@ -62,18 +63,11 @@
|
||||
</view>
|
||||
|
||||
|
||||
<!-- #ifdef H5 -->
|
||||
|
||||
<view class="content" :style="{
|
||||
height: 'calc(100vh - ' + (headerHeight + (store.notice ? 0 : 60) + footerHeight) + 'rpx)',
|
||||
paddingBottom: '160rpx'
|
||||
}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 -->
|
||||
<view class="content" :style="{
|
||||
height: 'calc(100vh - ' + (headerHeight + (store.notice ? 0 : 60) + footerHeight) + 'rpx)',
|
||||
paddingBottom: '160rpx'
|
||||
}">
|
||||
<!-- #endif -->
|
||||
<scroll-view class="menu-sidebar" :scroll-into-view="menuScrollIntoView" scroll-with-animation
|
||||
scroll-y>
|
||||
<view class="sidebar-wrapper">
|
||||
@ -105,12 +99,19 @@
|
||||
<view class="good-card" v-for="(good, key) in item.goodsList" :key="key"
|
||||
:class="{ 'sold-out': good.stock <= 0, 'large-image': good.bigImage === 1 }">
|
||||
<template v-if="good.bigImage === 1">
|
||||
<view class="promotion-large-tags"
|
||||
v-if="getGoodPromotions(good.id).length > 0">
|
||||
<text class="promotion-large-tag"
|
||||
v-for="promo in getGoodPromotions(good.id)" :key="promo.id">{{
|
||||
promo.name }}</text>
|
||||
</view>
|
||||
<image mode="aspectFill" :src="good.image" class="good-image-large"
|
||||
@tap="showGoodDetailModal(item, good)"></image>
|
||||
<view class="good-details-large flex-row justify-between">
|
||||
<view class="good-info" style="flex: 2; padding-right: 20rpx;">
|
||||
<text class="good-name">{{ good.storeName }}</text>
|
||||
<text class="good-description">{{ good.storeInfo }}</text>
|
||||
<text class="good-description">{{ good.storeInfo
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="price-action" style="flex: 1;">
|
||||
<text class="good-price big-good-price">¥{{ good.price
|
||||
@ -149,13 +150,18 @@
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<view class="promotion-tags"
|
||||
v-if="getGoodPromotions(good.id).length > 0">
|
||||
<text class="promotion-tag"
|
||||
v-for="promo in getGoodPromotions(good.id)" :key="promo.id">{{
|
||||
promo.name }}</text>
|
||||
</view>
|
||||
<image mode="aspectFill" :src="good.image" class="good-image"
|
||||
@tap="showGoodDetailModal(item, good)"></image>
|
||||
<view class="good-details">
|
||||
<text class="good-name">{{ good.storeName }}</text>
|
||||
<text class="good-description">{{ good.storeInfo }}</text>
|
||||
<view
|
||||
class="price-action flex-row justify-between align-center">
|
||||
<view class="price-action flex-row justify-between align-center">
|
||||
<text class="good-price">¥{{ good.price }}</text>
|
||||
<!-- <view class="action-buttons" v-if="good.stock > 0">
|
||||
<button type="primary" class="spec-button"
|
||||
@ -236,7 +242,8 @@
|
||||
<!-- 购物车栏 begin -->
|
||||
<view class="cart-bar" v-if="cart.length > 0 && isCartShow">
|
||||
<view class="cart-icon-container">
|
||||
<image src="/static/images/menu/cart.png" class="cart-icon" @tap="openCartPopup"></image>
|
||||
<image src="/static/images/menu/cart.png" class="cart-icon" @tap="openCartPopup">
|
||||
</image>
|
||||
<view class="cart-badge">{{ getCartGoodsNumber }}</view>
|
||||
</view>
|
||||
<view style="display: flex; flex-direction: column;">
|
||||
@ -250,6 +257,20 @@
|
||||
预估配送费 ¥{{ store.deliveryPrice }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="promotion-selection" v-if="applicablePromotions.length > 0">
|
||||
<view class="promotion-list">
|
||||
<!-- 模板部分:无需传递参数 -->
|
||||
<radio-group @change="onPromotionChange" style="transform: scale(0.7);">
|
||||
<label v-for="promo in applicablePromotions" :key="promo.id" class="">
|
||||
<view class="promotion-content">
|
||||
<radio :value="promo.id" style="transform: scale(0.7);"
|
||||
:checked="promo.id === selectedPromotion.id" />
|
||||
<text class="promotion-name">{{ promo.name }}</text>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
<button type="primary" class="checkout-button" @tap="toPay" :disabled="disabledPay"
|
||||
:class="{ disabled: disabledPay }">
|
||||
{{ disabledPay ? `差${spread}元起送` : '去结算' }}
|
||||
@ -260,7 +281,7 @@
|
||||
|
||||
<!-- 商品详情模态框 begin -->
|
||||
<modal :show="goodDetailModalVisible" class="good-detail-modal" color="#5A5B5C" width="90%" custom
|
||||
padding="0rpx" radius="12rpx">
|
||||
padding="0rpx" radius="12rpx" @cancel="closeGoodDetailModal">
|
||||
<template #default>
|
||||
<view class="modal-header">
|
||||
<view class="close-button">
|
||||
@ -372,8 +393,23 @@
|
||||
</view>
|
||||
</template>
|
||||
</uv-popup>
|
||||
</view>
|
||||
|
||||
<!-- 优惠活动选择弹窗 -->
|
||||
<modal :show="showPromotionModal" class="promotion-select-modal" color="#5A5B5C" width="80%" custom
|
||||
padding="20rpx" radius="12rpx">
|
||||
<template #default>
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">选择优惠活动</text>
|
||||
</view>
|
||||
<scroll-view class="modal-body" scroll-y>
|
||||
<view class="promotion-item" v-for="promo in applicablePromotions" :key="promo.id">
|
||||
<text class="promo-name">{{ promo.name }}</text>
|
||||
<!-- 根据需要显示更多优惠信息 -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
</modal>
|
||||
</view>
|
||||
<!--轻提示-->
|
||||
<view class="loading" v-if="loading">
|
||||
<uv-loading-icon color="#DA5650" size=40 mode="circle"></uv-loading-icon>
|
||||
@ -391,6 +427,15 @@
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 浮窗优惠券按钮 -->
|
||||
<view class="coupon-float-btn" @tap="showCouponFlo" v-if="!loading">
|
||||
<image src="/static/images/coupon-icon.png" class="coupon-float-icon" />
|
||||
<text class="coupon-float-text">优惠券</text>
|
||||
</view>
|
||||
|
||||
<!-- 优惠券弹窗 -->
|
||||
<coupon-float :show="showCouponFloat" :coupons="allCoupons" @close="closeCouponFloat"/>
|
||||
</layout>
|
||||
</template>
|
||||
|
||||
@ -423,6 +468,26 @@ import {
|
||||
import {
|
||||
menuAds
|
||||
} from "@/api/market";
|
||||
import { getPromotionactivityInfo } from "@/api/activity"; // 确保路径正确
|
||||
import CouponFloat from './coupon-float.vue'
|
||||
import { couponMine } from '@/api/coupon'
|
||||
const promotionActivities = ref([]); //所有优惠活动
|
||||
const selectedPromotion = ref(null); // 用于存储用户选择的优惠活动
|
||||
const showPromotionModal = ref(false); // 控制优惠选择弹窗的显示
|
||||
const applicablePromotions = ref([]); // 存储当前购物车适用的优惠活动
|
||||
|
||||
// 用户选择优惠活动后的处理
|
||||
const onPromotionChange = (e) => {
|
||||
// 1. 获取选中项的ID
|
||||
const selectedId = e.detail.value;
|
||||
|
||||
// 2. 通过ID查找完整对象
|
||||
selectedPromotion.value = applicablePromotions.value.find(
|
||||
p => p.id == parseInt(selectedId)
|
||||
);
|
||||
// console.log("ssssssssssssssss", selectedPromotion.value);
|
||||
};
|
||||
|
||||
const main = useMainStore();
|
||||
const {
|
||||
orderType,
|
||||
@ -461,6 +526,10 @@ const newkmUnit = computed(() => (param) => {
|
||||
console.log("param:", param);
|
||||
return "10km";
|
||||
});
|
||||
|
||||
const showCouponFloat = ref(false)
|
||||
const allCoupons = ref([])
|
||||
|
||||
const goodCartNum = computed(() => {
|
||||
//计算单个饮品添加到购物车的数量
|
||||
return (id) =>
|
||||
@ -491,11 +560,19 @@ const getCartGoodsNumber = computed(() => {
|
||||
// });
|
||||
const getCartGoodsPrice = computed(() => {
|
||||
let total = cart.value.reduce((acc, cur) => {
|
||||
const itemPrice = cur.price * cur.number;
|
||||
let itemPrice = cur.price * cur.number;
|
||||
|
||||
// 如果有优惠活动,将商品打折后,加入总价
|
||||
if (selectedPromotion.value) {
|
||||
// console.log("动态更新总价格11111111111",selectedPromotion.value)
|
||||
itemPrice = selectedPromotion.value.discountRate * itemPrice;
|
||||
}
|
||||
const boxPrice = (cur.boxFee || 0) * cur.number;
|
||||
return acc + itemPrice + boxPrice; // 注意:你原先漏掉了 boxPrice
|
||||
}, 0);
|
||||
|
||||
|
||||
|
||||
// 返回数值类型(而非字符串)
|
||||
return parseFloat(total.toFixed(2)); // 关键修改:parseFloat 转换回数值
|
||||
});
|
||||
@ -522,8 +599,7 @@ uni.$on("refreshMenu", () => {
|
||||
onPullDownRefresh(() => {
|
||||
init();
|
||||
});
|
||||
onLoad((options) => {
|
||||
|
||||
onLoad(async (options) => {
|
||||
// 处理扫描二维码进入的情况
|
||||
if (options && options.q) {
|
||||
try {
|
||||
@ -546,6 +622,7 @@ onLoad((options) => {
|
||||
}
|
||||
init();
|
||||
refreshCart();
|
||||
|
||||
nextTick(() => {
|
||||
if (goods.value.length > 0) {
|
||||
currentCateId.value = goods.value[0].id;
|
||||
@ -561,10 +638,14 @@ onShow(() => {
|
||||
//init();
|
||||
refreshCart();
|
||||
shopAd.value = uni.getStorageSync("shopAd");
|
||||
|
||||
// 初始化页面高度计算
|
||||
nextTick(() => {
|
||||
calcLayoutHeights();
|
||||
});
|
||||
|
||||
// 获取所有优惠券
|
||||
loadAllCoupons();
|
||||
});
|
||||
|
||||
const openCartShow = () => {
|
||||
@ -681,6 +762,9 @@ const getShopList = async (res) => {
|
||||
// uni.stopPullDownRefresh();
|
||||
// 加载数据后显示弹窗
|
||||
showPopup.value = true
|
||||
|
||||
// 获取活动信息
|
||||
loadPromotionActivities();
|
||||
}
|
||||
}
|
||||
uni.stopPullDownRefresh();
|
||||
@ -703,9 +787,28 @@ const refreshCart = () => {
|
||||
}
|
||||
cart.value = tmpCart;
|
||||
cartPopupVisible.value = false;
|
||||
|
||||
// 初始化,获取购物车数据,开始计算优惠
|
||||
isPromotionActivity();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const loadPromotionActivities = async () => {
|
||||
try {
|
||||
const data = { pageNo: 1, pageSize: 100, shopId: store.value.id ? store.value.id : 0 }
|
||||
const res = await getPromotionactivityInfo(data);
|
||||
// console.log("res:", res);
|
||||
if (res) {
|
||||
promotionActivities.value = res.list; // 假设接口返回的数据在 data 字段
|
||||
console.log("promotionActivities活动信息000000000:", promotionActivities.value);
|
||||
} else {
|
||||
console.error('获取优惠活动失败:', res.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取优惠活动异常:', error);
|
||||
}
|
||||
};
|
||||
const getAds = async (shop_id) => {
|
||||
let data = await menuAds({
|
||||
shop_id: shop_id ? shop_id : 0
|
||||
@ -850,9 +953,9 @@ const calcSize = () => {
|
||||
}
|
||||
h += data.height;
|
||||
item.bottom = h;
|
||||
console.log(
|
||||
`Category ${item.id} calculated: top=${item.top}, height=${data.height}, bottom=${item.bottom}`
|
||||
);
|
||||
// console.log(
|
||||
// `Category ${item.id} calculated: top=${item.top}, height=${data.height}, bottom=${item.bottom}`
|
||||
// );
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -955,7 +1058,12 @@ const handleAddToCart = (cate, newGood, num) => {
|
||||
});
|
||||
}
|
||||
uni.setStorageSync("cart", JSON.parse(JSON.stringify(cart.value)));
|
||||
|
||||
//将商品添加到购物车后,开始计算优惠
|
||||
isPromotionActivity()
|
||||
};
|
||||
|
||||
|
||||
const handleReduceFromCart = (item, good) => {
|
||||
const index = cart.value.findIndex((item) => item.id === good.id);
|
||||
cart.value[index].number -= 1;
|
||||
@ -996,6 +1104,22 @@ const handleGoodReduce = (currentGood) => {
|
||||
cart.value.splice(cartIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 重新计算优惠
|
||||
isPromotionActivity();
|
||||
};
|
||||
|
||||
const getGoodPromotions = (productId) => {
|
||||
if (!promotionActivities.value || promotionActivities.value.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return promotionActivities.value.filter(promo => {
|
||||
if (promo.productId) {
|
||||
const productIds = promo.productId.split(',');
|
||||
return productIds.includes(String(productId));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
const showGoodDetailModal = (item, newGood) => {
|
||||
@ -1020,7 +1144,7 @@ const closeGoodDetailModal = () => {
|
||||
const changePropertyDefault = (index, key, isDefault) => {
|
||||
//改变默认属性值
|
||||
let valueStr = "";
|
||||
console.log("good:", good.value);
|
||||
// console.log("good:", good.value);
|
||||
if (isDefault) {
|
||||
newValue.value = [];
|
||||
for (let i = 0; i < good.value.productAttr.length; i++) {
|
||||
@ -1033,16 +1157,26 @@ const changePropertyDefault = (index, key, isDefault) => {
|
||||
// //valueStr = newValue.value.join(',')
|
||||
// }
|
||||
valueStr = newValue.value.join(",");
|
||||
|
||||
// 转换为数组并排序
|
||||
const sortedArray = valueStr.split(",").sort((a, b) => {
|
||||
return a.charCodeAt(0) - b.charCodeAt(0); // 比较Unicode码点
|
||||
});
|
||||
|
||||
// 重新组合为字符串
|
||||
valueStr = sortedArray.join(",");
|
||||
|
||||
// let productValue = good.value.productValue[valueStr]
|
||||
// if(!productValue) {
|
||||
// let skukey = JSON.parse(JSON.stringify(newValue.value))
|
||||
// skukey.sort((a, b) => a.localeCompare(b))
|
||||
// //console.log('skukey:',skukey)
|
||||
// valueStr = skukey.join(',')
|
||||
// valueStr = skukey.sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0)).join(',')
|
||||
// productValue = good.value.productValue[valueStr]
|
||||
}
|
||||
|
||||
// console.log('valueStr--------:', valueStr)
|
||||
let productValue = good.value.productValue[valueStr];
|
||||
// console.log('productValue--------------:', productValue)
|
||||
good.value.number = 1;
|
||||
good.value.price = parseFloat(productValue.price).toFixed(2);
|
||||
good.value.stock = productValue.stock;
|
||||
@ -1065,10 +1199,96 @@ const handleAddToCartInModal = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// // 暂存当前要添加的商品信息
|
||||
// const currentGoodToAdd = JSON.parse(JSON.stringify(good.value));
|
||||
// const currentCategory = JSON.parse(JSON.stringify(category.value));
|
||||
// const currentNum = good.value.number;
|
||||
|
||||
// // 模拟将商品加入购物车后的状态,用于计算优惠
|
||||
// let tempCart = JSON.parse(JSON.stringify(cart.value));
|
||||
// const existingCartItemIndex = tempCart.findIndex(item => item.id === currentGoodToAdd.id && item.valueStr === currentGoodToAdd.valueStr);
|
||||
// if (existingCartItemIndex > -1) {
|
||||
// tempCart[existingCartItemIndex].number += currentNum;
|
||||
// } else {
|
||||
// tempCart.push({
|
||||
// id: currentGoodToAdd.id,
|
||||
// cate_id: currentCategory.id,
|
||||
// name: currentGoodToAdd.storeName,
|
||||
// price: currentGoodToAdd.price,
|
||||
// number: currentNum,
|
||||
// image: currentGoodToAdd.image,
|
||||
// valueStr: currentGoodToAdd.valueStr,
|
||||
// boxFee: currentGoodToAdd.boxFee || 0,
|
||||
// aloneSell: currentGoodToAdd.aloneSell,
|
||||
// });
|
||||
// }
|
||||
|
||||
// let cartTotalAmount = tempCart.reduce((acc, cur) => acc + cur.number * cur.price, 0);
|
||||
|
||||
|
||||
// console.log('good:',good.value,'category:',category.value)
|
||||
handleAddToCart(category.value, good.value, good.value.number);
|
||||
closeGoodDetailModal();
|
||||
};
|
||||
|
||||
// 判断是否满足优惠活动、
|
||||
const isPromotionActivity = () => {
|
||||
// console.log("===============初始化时判断是否满足优惠活动", cart.value);
|
||||
// applicablePromotions.value = [];
|
||||
const applicablePromotionsCopy = [];
|
||||
|
||||
if (promotionActivities.value && promotionActivities.value.length > 0) {
|
||||
promotionActivities.value.forEach(promo => {
|
||||
let activityAmount = 0;
|
||||
let activityCount = 0;
|
||||
const productIds = promo.productId ? promo.productId.split(',') : [];
|
||||
// 遍历购物车计算活动商品总额和数量
|
||||
cart.value.forEach(item => {
|
||||
if (productIds.includes(String(item.id))) {
|
||||
activityAmount += item.price * item.number;
|
||||
activityCount += item.number;
|
||||
}
|
||||
});
|
||||
|
||||
if (activityAmount >= promo.minAmount && activityCount >= promo.minQuantity) {
|
||||
applicablePromotionsCopy.push(promo);
|
||||
}
|
||||
|
||||
});
|
||||
// console.log(applicablePromotionsCopy.length,"applicablePromotionssssssssssssssss:", applicablePromotionsCopy);
|
||||
if (selectedPromotion.value == null) {
|
||||
selectedPromotion.value = applicablePromotionsCopy[0];
|
||||
}
|
||||
if (applicablePromotionsCopy.length == 0) {
|
||||
selectedPromotion.value = null;
|
||||
}
|
||||
if (applicablePromotionsCopy.length == 1) {
|
||||
selectedPromotion.value = applicablePromotionsCopy[0];
|
||||
}
|
||||
|
||||
applicablePromotions.value = applicablePromotionsCopy;
|
||||
|
||||
// console.log("选择的优惠活动:", selectedPromotion.value);
|
||||
// console.log("真实的优惠活动", applicablePromotions.value);
|
||||
}
|
||||
|
||||
// console.log('applicablePromotions:', applicablePromotions.value);
|
||||
// if (applicablePromotions.value.length > 1) {
|
||||
// // 多个活动满足条件,弹窗让用户选择
|
||||
// showPromotionModal.value = true;
|
||||
// // 此处不直接添加购物车,等待用户选择活动
|
||||
// } else if (applicablePromotions.value.length === 1) {
|
||||
// // 只有一个活动满足条件,自动应用
|
||||
// selectedPromotion.value = applicablePromotions.value[0];
|
||||
// // applyPromotionAndAddToCart(currentCategory, currentGoodToAdd, currentNum);
|
||||
// closeGoodDetailModal();
|
||||
// } else {
|
||||
// // 没有活动满足条件,直接添加
|
||||
// selectedPromotion.value = null; // 清空已选优惠
|
||||
// // handleAddToCart(currentCategory, currentGoodToAdd, currentNum);
|
||||
// closeGoodDetailModal();
|
||||
// }
|
||||
};
|
||||
const openCartPopup = () => {
|
||||
//打开/关闭购物车列表popup
|
||||
popup.value.open();
|
||||
@ -1092,6 +1312,9 @@ const handleCartClear = () => {
|
||||
const handleCartItemAdd = (index) => {
|
||||
cart.value[index].number += 1;
|
||||
uni.setStorageSync("cart", JSON.parse(JSON.stringify(cart.value)));
|
||||
|
||||
// 重新计算优惠
|
||||
isPromotionActivity();
|
||||
};
|
||||
const handleCartItemReduce = (index) => {
|
||||
if (cart.value[index].number === 1) {
|
||||
@ -1103,6 +1326,9 @@ const handleCartItemReduce = (index) => {
|
||||
cartPopupVisible.value = false;
|
||||
}
|
||||
uni.setStorageSync("cart", JSON.parse(JSON.stringify(cart.value)));
|
||||
|
||||
// 重新计算优惠
|
||||
isPromotionActivity();
|
||||
};
|
||||
const toPay = () => {
|
||||
if (!isLogin.value) {
|
||||
@ -1135,7 +1361,7 @@ const toPay = () => {
|
||||
});
|
||||
uni.setStorageSync("cart", JSON.parse(JSON.stringify(cart.value)));
|
||||
uni.navigateTo({
|
||||
url: `/pages/components/pages/pay/pay?distributorId=${distributorId.value}`,
|
||||
url: `/pages/components/pages/pay/pay?distributorId=${distributorId.value}&promotionId=${selectedPromotion.value?.id}`,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1165,6 +1391,26 @@ const isSpecialPackage = (name) => {
|
||||
const closePopup = () => {
|
||||
showPopup.value = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 获取所有优惠券
|
||||
const loadAllCoupons = async () => {
|
||||
const data = await couponMine({ page: 1, pagesize: 100 });
|
||||
if (data) allCoupons.value = data;
|
||||
|
||||
console.log(data,"------------")
|
||||
console.log(allCoupons.value,"------------")
|
||||
}
|
||||
|
||||
const showCouponFlo = () => {
|
||||
console.log("我点击了优惠券按钮")
|
||||
showCouponFloat.value = true;
|
||||
}
|
||||
|
||||
const closeCouponFloat = () => {
|
||||
showCouponFloat.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -1854,6 +2100,41 @@ button[type="primary"] {
|
||||
padding-bottom: 150px;
|
||||
}
|
||||
|
||||
/* 优惠活动选择弹窗样式 */
|
||||
.promotion-select-modal .modal-header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.promotion-select-modal .modal-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.promotion-select-modal .modal-body {
|
||||
max-height: 60vh;
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
|
||||
.promotion-item {
|
||||
// padding: 20rpx;
|
||||
// border-bottom: 1px solid #f5f5f5;
|
||||
// display: flex;
|
||||
// justify-content: space-between;
|
||||
// align-items: center;
|
||||
}
|
||||
|
||||
.promotion-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.promo-name {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.new-spec-button {
|
||||
border-radius: 15rpx; // 调整按钮圆角
|
||||
margin-right: 10rpx; // 调整按钮之间的间距
|
||||
@ -1914,4 +2195,144 @@ button[type="primary"] {
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.promotion-selection {
|
||||
// padding: 20rpx;
|
||||
// background: #fff;
|
||||
}
|
||||
|
||||
.promotion-list {
|
||||
// margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.promotion-item {
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.promotion-content {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// gap: 20rpx;
|
||||
}
|
||||
|
||||
.promotion-name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.promotion-tags {
|
||||
width: 200rpx;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8rpx;
|
||||
/* 标签之间的间距 */
|
||||
margin-top: 8rpx;
|
||||
/* 标签与上方内容的间距 */
|
||||
}
|
||||
|
||||
.promotion-tag {
|
||||
display: inline-flex;
|
||||
/* 使内容居中 */
|
||||
align-items: center;
|
||||
padding: 4rpx 12rpx;
|
||||
/* 上下左右内边距 */
|
||||
background-color: #ffe0b2;
|
||||
/* 柔和的背景色,例如浅橙色 */
|
||||
color: #e65100;
|
||||
/* 标签文字颜色,与背景色搭配 */
|
||||
border: 1rpx solid #ffb74d;
|
||||
/* 边框 */
|
||||
border-radius: 8rpx;
|
||||
/* 圆角 */
|
||||
font-size: 18rpx;
|
||||
/* 字体大小 */
|
||||
font-weight: bold;
|
||||
/* 字体加粗 */
|
||||
white-space: nowrap;
|
||||
/* 防止标签文字换行 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 文字溢出时显示省略号 */
|
||||
max-width: 100%;
|
||||
/* 确保标签不会超出父容器 */
|
||||
}
|
||||
|
||||
.promotion-large-tags {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8rpx;
|
||||
/* 标签之间的间距 */
|
||||
margin-top: 8rpx;
|
||||
/* 标签与上方内容的间距 */
|
||||
}
|
||||
|
||||
.promotion-large-tag {
|
||||
display: inline-flex;
|
||||
/* 使内容居中 */
|
||||
align-items: center;
|
||||
padding: 4rpx 12rpx;
|
||||
/* 上下左右内边距 */
|
||||
background-color: #ffe0b2;
|
||||
/* 柔和的背景色,例如浅橙色 */
|
||||
color: #e65100;
|
||||
/* 标签文字颜色,与背景色搭配 */
|
||||
border: 1rpx solid #ffb74d;
|
||||
/* 边框 */
|
||||
border-radius: 8rpx;
|
||||
/* 圆角 */
|
||||
font-size: 22rpx;
|
||||
/* 字体大小 */
|
||||
font-weight: bold;
|
||||
/* 字体加粗 */
|
||||
white-space: nowrap;
|
||||
/* 防止标签文字换行 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* 文字溢出时显示省略号 */
|
||||
max-width: 100%;
|
||||
/* 确保标签不会超出父容器 */
|
||||
}
|
||||
|
||||
/* 您还可以添加一些悬停或点击效果,如果需要的话 */
|
||||
.promotion-tag:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.coupon-float-btn {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
position: fixed;
|
||||
right: 40rpx;
|
||||
top: 550rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, #fffbe6 0%, #ffe0b2 100%);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 4rpx 16rpx rgba(249, 174, 61, 0.18);
|
||||
padding: 18rpx 18rpx 10rpx 18rpx;
|
||||
cursor: pointer;
|
||||
transition: box-shadow 0.2s;
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 2rpx 8rpx rgba(249, 174, 61, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-float-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.coupon-float-text {
|
||||
font-size: 22rpx;
|
||||
color: #f9ae3d;
|
||||
font-weight: bold;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
</style>
|
@ -49,7 +49,7 @@
|
||||
<view class="block_1 flex-row justify-end" @tap="
|
||||
serv({
|
||||
type: 'pages',
|
||||
pages: '/pages/components/pages/coupons/coupons',
|
||||
pages: '/pages/components/pages/coupons/mycoupons',
|
||||
})
|
||||
">
|
||||
<text class="text_10">去使用</text>
|
||||
@ -237,7 +237,7 @@ const serv = (item) => {
|
||||
item.id +
|
||||
"&name=" +
|
||||
item.name +
|
||||
"&phone=" +
|
||||
"&phoneNumber=" +
|
||||
item.phone,
|
||||
});
|
||||
break;
|
||||
|
BIN
static/images/coupon-icon.png
Normal file
BIN
static/images/coupon-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Loading…
x
Reference in New Issue
Block a user