|
|
@@ -1,22 +1,49 @@
|
|
|
<script setup lang="ts">
|
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
|
-import { ref } from "vue";
|
|
|
+import { ref, computed } from "vue";
|
|
|
import { getImageUrl } from "@/utils/imageUtil";
|
|
|
import Upopup from "@/components/popup/index.vue";
|
|
|
import StarRating from "@/components/start/start.vue";
|
|
|
import { storeToRefs } from "pinia";
|
|
|
import { useTokenStore } from "@/store/token";
|
|
|
import { toLoginPage } from "@/utils/toLoginPage";
|
|
|
-import { useCouponShare } from '@/hooks/useCouponShare'
|
|
|
+import { useCouponShare } from "@/hooks/useCouponShare";
|
|
|
+import { queryTemplateByIdDetails, getShareInfo } from "@/api/home";
|
|
|
+import { getEnvField } from '@/utils/envField'
|
|
|
|
|
|
const tokenStore = useTokenStore();
|
|
|
const { hasLogin } = storeToRefs(tokenStore);
|
|
|
|
|
|
-// 接收分享卡片传入的参数
|
|
|
-onLoad((options: any) => {
|
|
|
- console.log("onLoad options:", options);
|
|
|
- // 例如:options.couponId, options.from 等
|
|
|
+// 定义 templateId 存储传入的 id
|
|
|
+const templateId = ref<string>("");
|
|
|
+const shareId = ref();
|
|
|
+
|
|
|
+// 定义 couponDetail 存储接口返回数据
|
|
|
+const couponDetail = ref<any>(null);
|
|
|
+
|
|
|
+const shareType = ref(); //2来自分享
|
|
|
+onLoad(async (options: any) => {
|
|
|
+ templateId.value = options.templateId;
|
|
|
+ shareType.value = options.shareType;
|
|
|
+ // 调用接口获取优惠券详情
|
|
|
+ await fetchCouponDetail();
|
|
|
});
|
|
|
+
|
|
|
+// 获取优惠券详情
|
|
|
+async function fetchCouponDetail() {
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: "加载中..." });
|
|
|
+ const res = await queryTemplateByIdDetails({
|
|
|
+ templateId: templateId.value,
|
|
|
+ });
|
|
|
+ couponDetail.value = res;
|
|
|
+ } catch (error) {
|
|
|
+ uni.showToast({ title: "获取详情失败", icon: "none" });
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
definePage({
|
|
|
style: {
|
|
|
navigationBarTitleText: "优惠券详情",
|
|
|
@@ -24,20 +51,60 @@ definePage({
|
|
|
},
|
|
|
});
|
|
|
|
|
|
-const couponData = ref({
|
|
|
- discount: "7",
|
|
|
- unit: "折",
|
|
|
- name: "顺溜早餐折扣券",
|
|
|
- validity: "长期有效",
|
|
|
-});
|
|
|
+// 计算优惠券类型显示
|
|
|
+const couponTypeDisplay = computed(() => {
|
|
|
+ if (!couponDetail.value)
|
|
|
+ return { discount: "", unit: "", name: "", validity: "" };
|
|
|
+
|
|
|
+ const detail = couponDetail.value;
|
|
|
+ const type = detail.type;
|
|
|
+
|
|
|
+ // 有效期显示
|
|
|
+ let validity = "";
|
|
|
+ const validityType = detail.validityType;
|
|
|
+ if (validityType == 1) {
|
|
|
+ validity = `有效期至 ${detail.validEndTime}`;
|
|
|
+ } else if (validityType == 2) {
|
|
|
+ validity = `领券后 ${detail.validDays} 天有效`;
|
|
|
+ } else if (validityType == 3) {
|
|
|
+ validity = "长期有效";
|
|
|
+ } else if (validityType == 4) {
|
|
|
+ validity = "三方赠送";
|
|
|
+ }
|
|
|
|
|
|
-const couponDetails = ref({
|
|
|
- applicableProducts: "部分商品",
|
|
|
- merchantCount: "99+",
|
|
|
- usageRules: "满20元打8折,最高优惠10元",
|
|
|
- usagePeriod: "长期有效",
|
|
|
- dailyLimit: "20张",
|
|
|
- applicableArea: "山西省-太原市-小店区、山西省-太原市-迎泽区",
|
|
|
+ // 根据类型显示不同内容
|
|
|
+ if (type == 1) {
|
|
|
+ // 兑换券
|
|
|
+ return {
|
|
|
+ discount: "",
|
|
|
+ unit: "",
|
|
|
+ name: detail.name,
|
|
|
+ validity: validity,
|
|
|
+ type: 1,
|
|
|
+ };
|
|
|
+ } else if (type == 2) {
|
|
|
+ // 折扣券
|
|
|
+ return {
|
|
|
+ discount: detail.ruleDiscountRate,
|
|
|
+ unit: "折",
|
|
|
+ name: detail.name,
|
|
|
+ validity: validity,
|
|
|
+ capAmount: detail.ruleDiscountCapAmount || "0",
|
|
|
+ type: 2,
|
|
|
+ };
|
|
|
+ } else if (type == 3) {
|
|
|
+ // 满减券
|
|
|
+ return {
|
|
|
+ discount: detail.ruleReductionAmount || "0",
|
|
|
+ unit: "元",
|
|
|
+ name: detail.name,
|
|
|
+ validity: validity,
|
|
|
+ minSpend: detail.ruleMinSpendAmount || "0",
|
|
|
+ type: 3,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return { discount: "", unit: "", name: "", validity: "" };
|
|
|
});
|
|
|
|
|
|
const rules = [
|
|
|
@@ -59,20 +126,28 @@ function navigateToMiniProgram() {
|
|
|
// #ifdef MP-WEIXIN
|
|
|
uni.navigateToMiniProgram({
|
|
|
appId: "wxab9634bf98628a03", // TODO: 替换为目标小程序的 AppId
|
|
|
- path: "pages/home/home", // TODO: 替换为目标小程序的页面路径
|
|
|
- envVersion: "trial",
|
|
|
+ path: `pages/home/home?CCShareId=${shareId.value}`, // TODO: 替换为目标小程序的页面路径
|
|
|
+ envVersion: getEnvField(),
|
|
|
success: () => {
|
|
|
console.log("跳转其他小程序成功");
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
- console.error("跳转失败", JSON.stringify(err));
|
|
|
- uni.showToast({ title: err.errMsg || "跳转失败", icon: "none" });
|
|
|
+ uni.showToast({ title: "跳转失败", icon: "none" });
|
|
|
},
|
|
|
});
|
|
|
// #endif
|
|
|
}
|
|
|
|
|
|
-function receive() {
|
|
|
+//获取分享ID
|
|
|
+async function getShareId() {
|
|
|
+ const res = await getShareInfo({
|
|
|
+ shareContentId: templateId.value,
|
|
|
+ shareType: "COUPON",
|
|
|
+ });
|
|
|
+ shareId.value = res;
|
|
|
+}
|
|
|
+
|
|
|
+async function receive() {
|
|
|
if (!hasLogin.value) {
|
|
|
// 未登录 → 去登录,登录后回到当前页
|
|
|
const currentPage = getCurrentPages()[getCurrentPages().length - 1];
|
|
|
@@ -80,26 +155,18 @@ function receive() {
|
|
|
toLoginPage({
|
|
|
queryString: `?redirect=${encodeURIComponent(redirectUrl)}`,
|
|
|
});
|
|
|
+ fetchCouponDetail();
|
|
|
+ getShareId();
|
|
|
return;
|
|
|
}
|
|
|
// 已登录 → 跳转其他小程序领券
|
|
|
+ await getShareId();
|
|
|
navigateToMiniProgram();
|
|
|
}
|
|
|
|
|
|
-const { shareCoupon, ...shareHooks } = useCouponShare()
|
|
|
+const { shareCoupon, ...shareHooks } = useCouponShare();
|
|
|
function clickShare() {
|
|
|
- try {
|
|
|
- // const shareLink = await shareCoupon(couponTemplateId.value);
|
|
|
- // if (shareLink) {
|
|
|
- // couponShareLink.value = shareLink;
|
|
|
- // showShareModal.value = true;
|
|
|
- // if (props.enableCustomShare) {
|
|
|
- // emit("shareClick", couponShareLink.value, shareHooks);
|
|
|
- // }
|
|
|
- // }
|
|
|
- } finally {
|
|
|
- // uni.hideLoading()
|
|
|
- }
|
|
|
+ shareCoupon(templateId.value);
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
@@ -111,7 +178,7 @@ function clickShare() {
|
|
|
<view class="share-info-content">
|
|
|
<view class="coupon-card">
|
|
|
<!-- 折扣券 -->
|
|
|
- <!-- <view class="card-background" :style="{
|
|
|
+ <view v-if="couponTypeDisplay.type ==2" class="card-background" :style="{
|
|
|
backgroundImage: `url(${getImageUrl('@img/income/share-bg.png')})`,
|
|
|
backgroundRepeat: 'no-repeat',
|
|
|
backgroundSize: 'contain',
|
|
|
@@ -121,19 +188,22 @@ function clickShare() {
|
|
|
<view class="card-content">
|
|
|
<view class="discount-section">
|
|
|
<view class="discount-value">
|
|
|
- <text class="discount-number">{{ couponData.discount }}</text>
|
|
|
- <text class="discount-unit">{{ couponData.unit }}</text>
|
|
|
+ <text class="discount-number">{{ couponTypeDisplay.discount }}</text>
|
|
|
+ <text class="discount-unit">{{ couponTypeDisplay.unit }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="info-section">
|
|
|
- <text class="coupon-name">{{ couponData.name }}</text>
|
|
|
- <text class="validity-text">{{ couponData.validity }}</text>
|
|
|
+ <text class="coupon-name">{{ couponTypeDisplay.name }}</text>
|
|
|
+ <view>
|
|
|
+ <view class='coupon-red'>最高优惠{{ couponTypeDisplay.capAmount }}元</view>
|
|
|
+ <view class="validity-text">{{ couponTypeDisplay.validity }}</view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view> -->
|
|
|
+ </view>
|
|
|
<!-- 满减券 -->
|
|
|
- <!-- <view class="card-background" :style="{
|
|
|
+ <view v-else-if="couponTypeDisplay.type == 3" class="card-background" :style="{
|
|
|
backgroundImage: `url(${getImageUrl('@img/income/share-bg.png')})`,
|
|
|
backgroundRepeat: 'no-repeat',
|
|
|
backgroundSize: 'contain',
|
|
|
@@ -143,29 +213,29 @@ function clickShare() {
|
|
|
<view class="card-content">
|
|
|
<view class="discount-section">
|
|
|
<view class="discount-value">
|
|
|
- <text class="discount-number">{{ couponData.discount }}</text>
|
|
|
- <text class="discount-unit">元</text>
|
|
|
+ <text class="discount-number">{{ couponTypeDisplay.discount }}</text>
|
|
|
+ <text class="discount-unit">{{ couponTypeDisplay.unit }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="info-section">
|
|
|
- <text class="coupon-name">{{ couponData.name }}</text>
|
|
|
+ <text class="coupon-name">{{ couponTypeDisplay.name }}</text>
|
|
|
<view>
|
|
|
- <view class='coupon-red'>满200减8元</view>
|
|
|
- <view class="validity-text">{{ couponData.validity }}</view>
|
|
|
+ <view class='coupon-red'>满{{ couponTypeDisplay.minSpend }}减{{ couponTypeDisplay.discount }}元</view>
|
|
|
+ <view class="validity-text">{{ couponTypeDisplay.validity }}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view> -->
|
|
|
+ </view>
|
|
|
<!-- 兑换券 -->
|
|
|
- <view class="card-background">
|
|
|
+ <view v-else-if="couponTypeDisplay.type ==1" class="card-background">
|
|
|
|
|
|
<view class="card-content change-content">
|
|
|
<view class="info-section">
|
|
|
- <text class="coupon-name">{{ couponData.name }}</text>
|
|
|
+ <text class="coupon-name">{{ couponTypeDisplay.name }}</text>
|
|
|
<view>
|
|
|
<view class='coupon-red'>免费兑换</view>
|
|
|
- <view class="validity-text">{{ couponData.validity }}</view>
|
|
|
+ <view class="validity-text">{{ couponTypeDisplay.validity }}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -176,97 +246,60 @@ function clickShare() {
|
|
|
<view class="detail-item has-arrow" @click='storeShow = true'>
|
|
|
<text class="detail-label">适用分类</text>
|
|
|
<view class="detail-right">
|
|
|
- <text class="detail-value clamp">{{ couponDetails.applicableProducts }}</text>
|
|
|
+ <text class="detail-value clamp">{{ couponDetail?.relatedName }}</text>
|
|
|
<u--image class='income-right' :src="getImageUrl('@img/income/arrow-right.png')" mode="aspectFit"
|
|
|
width="32rpx" height="32rpx"></u--image>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="detail-item has-arrow" @click='shopShow = true'>
|
|
|
- <text class="detail-label">适用商品</text>
|
|
|
+ <text class="detail-label">{{ couponDetail?.relatedType == 3 ? '不适用商品' : '适用商品' }}</text>
|
|
|
<view class="detail-right">
|
|
|
- <text class="detail-value clamp">{{ couponDetails.applicableProducts }}</text>
|
|
|
+ <text class="detail-value clamp">{{ couponDetail?.productName }}</text>
|
|
|
<u--image class='income-right' :src="getImageUrl('@img/income/arrow-right.png')" mode="aspectFit"
|
|
|
width="32rpx" height="32rpx"></u--image>
|
|
|
</view>
|
|
|
</view>
|
|
|
+
|
|
|
</view>
|
|
|
|
|
|
<!-- 适用商家卡片 -->
|
|
|
<view class="merchant-card-content">
|
|
|
<view class="merchant-title">商家信息</view>
|
|
|
- <view class="merchant-card">
|
|
|
- <view class="merchant-thumb">
|
|
|
- <image class="merchant-thumb-img" src="" mode="aspectFill" />
|
|
|
- </view>
|
|
|
- <view class="merchant-info">
|
|
|
- <view class="merchant-name-row">
|
|
|
- <text class="merchant-name">雪蜜冰城</text>
|
|
|
+ <view class="merchant-box"
|
|
|
+ v-if="couponDetail?.merchantInfoVOList && couponDetail.merchantInfoVOList.length > 0">
|
|
|
+ <view class="merchant-card" v-for="(merchant, index) in couponDetail.merchantInfoVOList" :key="index">
|
|
|
+ <view class="merchant-thumb">
|
|
|
+ <image class="merchant-thumb-img" :src="merchant.logo || ''" mode="aspectFill" />
|
|
|
</view>
|
|
|
- <view class="merchant-meta-row">
|
|
|
- <view class="merchant-rating-group">
|
|
|
- <view class="merchant-stars">
|
|
|
- <StarRating :rating="2" />
|
|
|
- </view>
|
|
|
- <text class="merchant-score">4.8超赞</text>
|
|
|
- <text class="merchant-price">人均¥10</text>
|
|
|
- </view>
|
|
|
- <text class="merchant-distance">190m</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-tags">
|
|
|
- <view class="merchant-tag tag-orange">
|
|
|
- <text>消费人数500+</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-tag tag-red">
|
|
|
- <text>收藏800+</text>
|
|
|
+ <view class="merchant-info">
|
|
|
+ <view class="merchant-name-row">
|
|
|
+ <text class="merchant-name">{{ merchant.storeName }}</text>
|
|
|
</view>
|
|
|
- <view class="merchant-tag tag-blue">
|
|
|
- <text>好评率90%</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-image">
|
|
|
- <u--image :src="getImageUrl('@img/index/interests.png')" width="86rpx" height="26rpx"></u--image>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="hot">
|
|
|
- <view class="merchant-tag tag-gold">
|
|
|
- <u--image :src="getImageUrl('@img/index/rank-f.png')" width="36rpx" height="33rpx"></u--image>
|
|
|
- <text>万柏林区西餐厅热销榜第8名</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="merchant-card">
|
|
|
- <view class="merchant-thumb">
|
|
|
- <image class="merchant-thumb-img" src="" mode="aspectFill" />
|
|
|
- </view>
|
|
|
- <view class="merchant-info">
|
|
|
- <view class="merchant-name-row">
|
|
|
- <text class="merchant-name">雪蜜冰城</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-meta-row">
|
|
|
- <view class="merchant-rating-group">
|
|
|
- <view class="merchant-stars">
|
|
|
- <text class="star-icon" v-for="i in 5" :key="i">★</text>
|
|
|
+ <view class="merchant-meta-row">
|
|
|
+ <view class="merchant-rating-group">
|
|
|
+ <view class="merchant-stars">
|
|
|
+ <StarRating :rating="merchant.commentGradeAvg || 0" />
|
|
|
+ </view>
|
|
|
+ <text class="merchant-score">{{ merchant.commentGradeAvg || 0 }}超赞</text>
|
|
|
+ <text class="merchant-price">人均¥{{ merchant.shopPriceAvg || 0 }}</text>
|
|
|
</view>
|
|
|
- <text class="merchant-score">4.8超赞</text>
|
|
|
- <text class="merchant-price">人均¥10</text>
|
|
|
- </view>
|
|
|
- <text class="merchant-distance">190m</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-tags">
|
|
|
- <view class="merchant-tag tag-orange">
|
|
|
- <text>消费人数500+</text>
|
|
|
+ <text class="merchant-distance">{{ merchant.distance?merchant.distance.toFixed(2)+'km':"" }}</text>
|
|
|
</view>
|
|
|
- <view class="merchant-tag tag-red">
|
|
|
- <text>收藏800+</text>
|
|
|
- </view>
|
|
|
- <view class="merchant-tag tag-blue">
|
|
|
- <text>好评率90%</text>
|
|
|
+ <view class="merchant-tags">
|
|
|
+ <view class="merchant-tag tag-orange">
|
|
|
+ <text>消费人数{{ merchant.consumptionNumber || 0 }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="merchant-tag tag-red">
|
|
|
+ <text>收藏{{ merchant.collectNumber || 0 }}</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
-
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view v-else class="merchant-empty">
|
|
|
+ <text>暂无商家信息</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 温馨提示 -->
|
|
|
@@ -284,22 +317,24 @@ function clickShare() {
|
|
|
</view>
|
|
|
|
|
|
<view class="share-info">
|
|
|
- <view class="share-btn" @click='clickShare'>去分享</view>
|
|
|
- <!-- <view class="share-btn" @click='receive'>去领取</view> -->
|
|
|
+
|
|
|
+ <view class="share-btn" v-if='shareType==2' @click='receive'>去领取</view>
|
|
|
+ <view class="share-btn" v-else @click='clickShare'>去分享</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 适用商品 -->
|
|
|
- <Upopup :isShow="storeShow" title='适用分类' @close='storeShow = false' :isFooter='false'>
|
|
|
+ <!-- 适用分类/商品 -->
|
|
|
+ <Upopup :isShow="storeShow" title="适用分类" @close='storeShow = false' :isFooter='false'>
|
|
|
<view class="store-cont">
|
|
|
- 大同刀削面 | 水蒸蛋 | 水煮肉片 | 葱爆羊肉 | 打卤面 |葱爆羊肉 | 打卤面 |葱爆羊肉 | 打卤面
|
|
|
+ {{couponDetail?.relatedName}}
|
|
|
</view>
|
|
|
</Upopup>
|
|
|
|
|
|
- <!-- 适用商家 -->
|
|
|
- <Upopup :isShow="shopShow" title='适用商品' @close='shopShow = false' :isFooter='false'>
|
|
|
+ <!-- 适用商品 -->
|
|
|
+ <Upopup :isShow="shopShow" :title="couponDetail?.relatedType == 3 ? '不适用商品' : '适用商品'" @close='shopShow = false'
|
|
|
+ :isFooter='false'>
|
|
|
<view class="store-cont">
|
|
|
- 大同刀削面 | 水蒸蛋 | 水煮肉片 | 葱爆羊肉 | 打卤面 |葱爆羊肉 | 打卤面 |葱爆羊肉 | 打卤面
|
|
|
+ {{couponDetail?.productName}}
|
|
|
</view>
|
|
|
</Upopup>
|
|
|
</template>
|
|
|
@@ -333,10 +368,14 @@ function clickShare() {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
height: 100%;
|
|
|
- padding: 0 58rpx;
|
|
|
+ // padding: 0 58rpx;
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
.discount-section {
|
|
|
+ width: 170rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
.discount-value {
|
|
|
display: flex;
|
|
|
align-items: baseline;
|
|
|
@@ -360,7 +399,7 @@ function clickShare() {
|
|
|
}
|
|
|
|
|
|
.info-section {
|
|
|
- margin-left: 80rpx;
|
|
|
+ margin-left: 33rpx;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 24rpx;
|
|
|
@@ -374,7 +413,7 @@ function clickShare() {
|
|
|
.coupon-red {
|
|
|
color: #ff5365;
|
|
|
font-size: 24rpx;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
}
|
|
|
.validity-text {
|
|
|
font-weight: 400;
|
|
|
@@ -469,7 +508,7 @@ function clickShare() {
|
|
|
.merchant-card-content {
|
|
|
border-radius: 12rpx;
|
|
|
background: #fff;
|
|
|
- padding: 20rpx;
|
|
|
+ padding: 20rpx 20rpx 32rpx 20rpx;
|
|
|
box-sizing: border-box;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
@@ -482,6 +521,17 @@ function clickShare() {
|
|
|
border-bottom: 1rpx solid #eaeaea;
|
|
|
box-sizing: border-box;
|
|
|
}
|
|
|
+ .merchant-empty {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40rpx 0;
|
|
|
+ color: #999;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .merchant-box {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 40rpx;
|
|
|
}
|
|
|
.merchant-card {
|
|
|
display: flex;
|