From 2eb21bfe2f40630a46e675211f23b5f240e395a4 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期五, 12 九月 2025 15:01:42 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/user_action' into send_coupon --- pages.json | 19 ++ pages/order/claim-coupon/claim-coupon.vue | 350 +++++++++++++++++++++++++++++++++++++++++++ api/coupon.js | 74 +++++++++ pages/commodity-square/commoditySquare.vue | 2 4 files changed, 442 insertions(+), 3 deletions(-) diff --git a/api/coupon.js b/api/coupon.js new file mode 100644 index 0000000..6721566 --- /dev/null +++ b/api/coupon.js @@ -0,0 +1,74 @@ + + +import { http, Method } from "@/utils/request.js"; + +/** + * 鑾峰彇铏氭嫙鍟嗗搧浼樻儬鍒稿垪琛� + * @param {Object} params - 鏌ヨ鍙傛暟 + * @param {number} params.pageNumber - 椤电爜 + * @param {number} params.pageSize - 姣忛〉鏁伴噺 + * @param {string} params.claimStatus - 棰嗗彇鐘舵�� (NOT_CLAIM: 鏈鍙�, CLAIM: 宸查鍙�) + * @param {string} params.userId - 鐢ㄦ埛ID + * @param {string} params.orderId - 璁㈠崟ID + * @returns {Promise} 杩斿洖浼樻儬鍒稿垪琛� + */ +export function getVirtualCoupons(params) { + return http.request({ + url: "/lmk/coupon/virtual", + method: Method.GET, + needToken: true, + params, + }); +} + +/** + * 棰嗗彇铏氭嫙鍟嗗搧浼樻儬鍒� + * @param {string|number} id - 浼樻儬鍒窱D + * @returns {Promise} 杩斿洖棰嗗彇缁撴灉 + */ +export function claimVirtualCoupon(id) { + return http.request({ + url: `/lmk/coupon/card/${id}`, + method: Method.POST, + needToken: true, + }); +} + +/** + * 鏍规嵁璁㈠崟ID鑾峰彇铏氭嫙鍟嗗搧浼樻儬鍒� + * @param {string} orderId - 璁㈠崟ID + * @returns {Promise} 杩斿洖浼樻儬鍒稿垪琛� + */ +export function getVirtualCouponsByOrderId(orderId) { + return http.request({ + url: `/lmk/coupon/virtual/order/${orderId}`, + method: Method.GET, + needToken: true, + }); +} + +/** + * 鏍规嵁浼樻儬鍗烽鍙朓D鑾峰彇铏氭嫙鍟嗗搧浼樻儬鍒� + * @param {string} userId - 鐢ㄦ埛ID + * @returns {Promise} 杩斿洖浼樻儬鍒稿垪琛� + */ +export function getVirtualCouponsByUserId(userId) { + return http.request({ + url: `/lmk/coupon/card/couponCardInfo/${userId}`, + method: Method.GET, + needToken: true, + }); +} + +/** + * 鑾峰彇浼樻儬鍒歌鎯� + * @param {string|number} id - 浼樻儬鍒窱D + * @returns {Promise} 杩斿洖浼樻儬鍒歌鎯� + */ +export function getVirtualCouponDetail(id) { + return http.request({ + url: `/lmk/coupon/card/couponCardInfo/${id}`, + method: Method.POST, + needToken: true, + }); +} \ No newline at end of file diff --git a/pages.json b/pages.json index 861b104..4a7378d 100644 --- a/pages.json +++ b/pages.json @@ -1779,8 +1779,23 @@ } }, { + "path" : "claim-coupon/claim-coupon", + "style" : + { + "navigationBarTitleText" : "浼樻儬鍒搁鍙�", + "enablePullDownRefresh" : true, + "componentPlaceholder": { + "u-image": "view", + "u-tag": "view", + "u-loading": "view", + "u-empty": "view", + "u-modal":"view" + } + } + }, + { "path" : "editOrderAddress/editOrderAddress", - "style" : + "style" : { "navigationBarTitleText" : "淇敼璁㈠崟", "componentPlaceholder": { @@ -1796,7 +1811,7 @@ }, { "path" : "cardPack", - "style" : + "style" : { "navigationBarTitleText" : "浼樻儬鍔靛崱鍖�", "componentPlaceholder": { diff --git a/pages/commodity-square/commoditySquare.vue b/pages/commodity-square/commoditySquare.vue index 85e0b28..ec242c5 100644 --- a/pages/commodity-square/commoditySquare.vue +++ b/pages/commodity-square/commoditySquare.vue @@ -51,7 +51,7 @@ <view class="goodsContent" style="font-size: 24rpx;"> {{item.sellingPoint}} </view> - <view + <view v-if="item.goodsType !=='VIRTUAL_GOODS'" style="display: flex; justify-content: space-between;align-items:center; 100%;width: 100%;"> <view class="goodsPrice">锟{item.price}}</view> <view class="addCard" style="display: flex; align-items: center;"> diff --git a/pages/order/claim-coupon/claim-coupon.vue b/pages/order/claim-coupon/claim-coupon.vue new file mode 100644 index 0000000..2acfa09 --- /dev/null +++ b/pages/order/claim-coupon/claim-coupon.vue @@ -0,0 +1,350 @@ +<template> + <view class="container"> + <!-- 椤堕儴鏍囬 --> + <view class="header"> + <text class="title">浼樻儬鍒搁鍙�</text> + <text class="subtitle">棰嗗彇鎮ㄧ殑涓撳睘浼樻儬鍒�</text> + </view> + + <!-- 鍗曚釜浼樻儬鍒稿睍绀� --> + <view class="coupon-container" v-if="couponInfo"> + <view class="coupon-card"> + <!-- 鍟嗗搧鍥剧墖 --> + <view class="goods-image-container"> + <u-image + :src="couponInfo.goodsImage || '/static/default_goods.png'" + width="100%" + height="300rpx" + mode="aspectFit" + border-radius="16" + @click="previewImage(couponInfo.goodsImage)" + ></u-image> + </view> + + <!-- 浼樻儬鍒镐俊鎭� --> + <view class="coupon-info"> + <view class="coupon-name">{{ couponInfo.couponName || couponInfo.name }}</view> + <view class="goods-name">{{ couponInfo.skuName }}</view> + <view class="coupon-no">缂栧彿锛歿{ couponInfo.couponNo }}</view> + <view class="time-info"> + <text class="create-time">鍒涘缓鏃堕棿锛歿{ formatDate(couponInfo.createTime) }}</text> + </view> + <view class="status"> + <u-tag + :text="couponInfo.claimStatus === 'CLAIM' ? '宸查鍙�' : '鏈鍙�'" + :type="couponInfo.claimStatus === 'CLAIM' ? 'success' : 'warning'" + size="mini" + /> + </view> + </view> + + <!-- 棰嗗彇鎸夐挳 --> + <view class="claim-btn-container"> + <button + class="claim-btn" + :class="{ 'claimed': couponInfo.claimStatus === 'CLAIM' }" + :disabled="couponInfo.claimStatus === 'CLAIM'" + @click="claimCoupon" + > + {{ couponInfo.claimStatus === 'CLAIM' ? '宸查鍙�' : '绔嬪嵆棰嗗彇' }} + </button> + </view> + </view> + </view> + + <!-- 鍔犺浇涓姸鎬� --> + <view class="loading-container" v-else-if="loading"> + <u-loading mode="circle" size="40"></u-loading> + <text class="loading-text">鍔犺浇涓�...</text> + </view> + + <!-- 绌虹姸鎬� --> + <u-empty + v-else + text="鏆傛棤浼樻儬鍒�" + mode="coupon" + icon-size="120" + margin-top="200" + ></u-empty> + + <!-- 鍘昏喘鐗╁脊绐� --> + <u-modal + v-model="showShoppingModal" + :content="'鎭枩鎮ㄩ鍙栨垚鍔燂紝鏄惁绔嬪嵆浣跨敤浼樻儬鍒稿幓璐墿锛�'" + :show-cancel-button="true" + confirm-text="鍘昏喘鐗�" + cancel-text="绋嶅悗鍐嶈" + @confirm="goShopping" + @cancel="closeModal" + ></u-modal> + </view> +</template> + +<script> + import { getVirtualCouponDetail, claimVirtualCoupon } from '@/api/coupon.js'; + + export default { + data() { + return { + couponInfo: null, // 鍗曚釜浼樻儬鍒镐俊鎭� + loading: false, + showShoppingModal: false ,// 鎺у埗鍘昏喘鐗╁脊绐楁樉绀� + couponId:'' + } + }, + onLoad(options) { + // 閫氳繃鍙傛暟浼犻�掍紭鎯犲埜ID + // 渚嬪: /pages/order/claim-coupon/claim-coupon?id=123 + options.id = '1966390012058017794' + + this.couponId = '' + if (options.id) { + this.loadCouponInfo(options.id); + } else { + // 濡傛灉娌℃湁浼犻�扞D锛屾樉绀虹┖鐘舵�� + uni.showToast({ + title: '缂哄皯浼樻儬鍒窱D鍙傛暟', + icon: 'none' + }); + } + }, + methods: { + // 鍔犺浇鎸囧畾ID鐨勪紭鎯犲埜淇℃伅 + async loadCouponInfo(id) { + if (this.loading) return; + this.loading = true; + + try { + // 璋冪敤鑾峰彇鍗曚釜浼樻儬鍒歌鎯呯殑鎺ュ彛 + const res = await getVirtualCouponDetail(id); + + if (res.data.code===200) { + this.couponInfo = res.data.data; + } else { + throw new Error(res.message || '鑾峰彇浼樻儬鍒稿け璐�'); + } + } catch (err) { + console.error('鑾峰彇浼樻儬鍒镐俊鎭け璐�:', err); + uni.showToast({ + title: err.message || '鑾峰彇浼樻儬鍒稿け璐�', + icon: 'none' + }); + } finally { + this.loading = false; + } + }, + + // 棰嗗彇浼樻儬鍒� + async claimCoupon() { + if (!this.couponInfo || this.couponInfo.claimStatus === 'CLAIM') { + uni.showToast({ + title: '璇ヤ紭鎯犲埜宸查鍙�', + icon: 'none' + }); + return; + } + + try { + uni.showLoading({ + title: '棰嗗彇涓�...' + }); + + // 璋冪敤棰嗗彇浼樻儬鍒告帴鍙� + const res = await claimVirtualCoupon(this.couponInfo.id); + + if (res.data.code===200) { + // 鏇存柊鏈湴鐘舵�� + this.couponId = res.data.data + this.$set(this.couponInfo, 'claimStatus', 'CLAIM'); + this.$set(this.couponInfo, 'claimTime', new Date()); + uni.hideLoading(); + uni.showToast({ + title: '棰嗗彇鎴愬姛', + icon: 'success' + }); + + // 鏄剧ず鍘昏喘鐗╁脊绐� + this.showShoppingModal = true; + } else { + throw new Error(res.message || '棰嗗彇澶辫触'); + } + } catch (err) { + uni.hideLoading(); + console.error('棰嗗彇浼樻儬鍒稿け璐�:', err); + uni.showToast({ + title: err.message || '棰嗗彇澶辫触', + icon: 'none' + }); + } + }, + + // 鍘昏喘鐗� + goShopping() { + // 鍏抽棴寮圭獥 + this.showShoppingModal = false; + + // 杩欓噷鍙互娣诲姞璺宠浆鍒拌喘鐗╅〉闈㈢殑閫昏緫 + // 渚嬪璺宠浆鍒板晢鍝佽鎯呴〉鎴栬喘鐗╄溅椤甸潰 + // 鏍规嵁瀹為檯闇�姹傝皟鏁磋烦杞矾寰� + if (this.couponInfo && this.couponInfo.skuId) { + // 濡傛灉鏈夊晢鍝両D锛岃烦杞埌鍟嗗搧璇︽儏椤� + uni.navigateTo({ + url: `/pages/commodity-square/coups-goods-list?promotionsId=${this.couponId}&promotionType=COUPON` + }); + } else { + // 鍚﹀垯璺宠浆鍒伴椤垫垨鍏朵粬椤甸潰 + uni.switchTab({ + url: '/pages/tabbar/index/home' + }); + } + }, + + // 鍏抽棴寮圭獥 + closeModal() { + this.showShoppingModal = false; + // 鍏抽棴寮圭獥鍚庤繑鍥炰笂涓�椤� + uni.navigateBack(); + }, + + // 鏍煎紡鍖栨棩鏈� + formatDate(date) { + if (!date) return ''; + const d = new Date(date); + return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`; + }, + + // 棰勮鍥剧墖 + previewImage(url) { + if (url) { + uni.previewImage({ + urls: [url] + }); + } + } + } + } +</script> + +<style lang="scss" scoped> +.container { + padding: 20rpx; + background-color: #f5f5f5; + min-height: 100vh; +} + +.header { + background-color: #fff; + padding: 30rpx; + border-radius: 16rpx; + margin-bottom: 20rpx; + text-align: center; + + .title { + font-size: 36rpx; + font-weight: bold; + color: #333; + display: block; + margin-bottom: 10rpx; + } + + .subtitle { + font-size: 28rpx; + color: #999; + } +} + +.coupon-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 60vh; +} + +.coupon-card { + background-color: #fff; + border-radius: 16rpx; + padding: 30rpx; + width: 90%; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); + text-align: center; + + .goods-image-container { + margin-bottom: 30rpx; + border-radius: 16rpx; + overflow: hidden; + } + + .coupon-info { + margin-bottom: 30rpx; + + .coupon-name { + font-size: 36rpx; + font-weight: bold; + color: #333; + margin-bottom: 20rpx; + } + + .goods-name { + font-size: 30rpx; + color: #666; + margin-bottom: 20rpx; + line-height: 1.5; + } + + .coupon-no { + font-size: 26rpx; + color: #999; + margin-bottom: 20rpx; + } + + .time-info { + font-size: 26rpx; + color: #999; + margin-bottom: 20rpx; + } + + .status { + margin-bottom: 20rpx; + } + } + + .claim-btn-container { + .claim-btn { + width: 80%; + height: 80rpx; + background-color: #ff6b6b; + color: #fff; + border-radius: 40rpx; + font-size: 32rpx; + border: none; + margin: 0 auto; + + &:active { + background-color: #ff5252; + } + + &.claimed { + background-color: #ccc; + } + + &[disabled] { + background-color: #ccc; + } + } + } +} + +.loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 60vh; + + .loading-text { + margin-top: 20rpx; + color: #999; + font-size: 28rpx; + } +} +</style> \ No newline at end of file -- Gitblit v1.8.0