Procházet zdrojové kódy

优惠券详情明细

zhengnaiwen_citu před 7 měsíci
rodič
revize
3d10f62816

+ 37 - 5
api/sign.js

@@ -21,7 +21,7 @@ export const getRewardSignInRecordSummary = () => {
     method: 'GET',
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
@@ -33,7 +33,7 @@ export const getRewardSignInRecordPage = (pageNo, pageSize) => {
     method: 'GET',
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
@@ -57,7 +57,7 @@ export const getAccountBalance = () => {
     method: 'GET',
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
@@ -69,7 +69,7 @@ export const getUserAccount = () => {
     method: 'GET',
     custom: {
       showLoading: false,
-      auth: false
+      auth: true
     }
   })
 }
@@ -98,6 +98,7 @@ export const getDiyTemplate = (ids) => {
       ids
     },
     custom: {
+      auth: true,
       showError: false,
       showLoading: false,
     }
@@ -109,8 +110,39 @@ export const getDiyTemplateUsed = () => {
     url: '/app-api/promotion/diy-template/used',
     method: 'GET',
     custom: {
+      auth: true,
       showError: false,
       showLoading: false,
     }
   })
-}
+}
+
+
+
+// 获取优惠券模板分页
+export const getCouponTemplatePage = (params) => {
+  return request({
+    url: '/app-api/promotion/coupon-template/page',
+    method: 'GET',
+    params,
+    custom: {
+      auth: true,
+      showError: false,
+      showLoading: false,
+    }
+  })
+}
+
+// 我的优惠劵列表
+export const getCouponPage = (params) => {
+  return request({
+    url: '/app-api/promotion/coupon/page',
+    method: 'GET',
+    params,
+    custom: {
+      auth: true,
+      showError: false,
+      showLoading: false,
+    }
+  })
+}

+ 0 - 1
custom-tab-bar/index.js

@@ -51,7 +51,6 @@ Component({
       this.setData({  
         selected: data.index  
       })
-      console.log('select', this.data)
     }
   }
 })

+ 6 - 0
pages.json

@@ -83,6 +83,12 @@
 					"style": {
 						"navigationBarTitleText": "我的聊天"
 					}
+				},
+				{
+					"path": "coupon/index",
+					"style": {
+						"navigationBarTitleText": "我的优惠券"
+					}
 				}
 			]
 		},

+ 186 - 19
pages/index/welfare.vue

@@ -9,17 +9,27 @@
               <view class="wallet-content-member">
                 <view class="iconBox">
                   <view class="iconBox-line">
-                    <uni-icons type="vip-filled" size="40" color="#ffbc00"></uni-icons>
+                    <uni-icons type="vip-filled" size="20" color="#ffbc00"></uni-icons>
                   </view>
                 </view>
-              </view>
-              <view class="wallet-content-integral wallet-content-item">
+                <view class="name">
+                  <text v-if="useUserStore.isLogin" @tap="toInfo" class="active">
+                    {{ useUserStore?.baseInfo?.name || useUserStore?.userInfo?.phone }}
+                  </text>
+                  <text v-else @tap="handleLogin">点击登录</text>
+                </view>
+                </view>
+              <view class="wallet-content-integral wallet-content-item" @tap="handleTo('integral')">
                 <text>{{ balance.point || 0 }}</text>
-                <text>积分</text>
+                <text class="title">积分</text>
               </view>
-              <view class="wallet-content-cash wallet-content-item">
+              <view class="wallet-content-cash wallet-content-item" @tap="handleTo('balance')">
                 <text>{{ balance.balance > 0 ? (balance?.balance / 100.0).toFixed(2) : 0 }}</text>
-                <text>余额</text>
+                <text class="title">余额</text>
+              </view>
+              <view class="wallet-content-coupon wallet-content-item" @tap="handleTo('coupon')">
+                <text>{{ myCoupon }}</text>
+                <text class="title">优惠券</text>
               </view>
             </view>
           </view>
@@ -54,6 +64,8 @@
               v-for="item in items"
               :key="item.id"
               class="item"
+              :class="{ disabled: !item.canTake }"
+              @tap="onGetCoupon(item.id, item.canTake)"
             >
               <view class="img">
                 <image
@@ -72,7 +84,7 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, watch } from 'vue'
 import layoutPage from '@/layout'
 import {
 	getRewardSignInConfigList,
@@ -81,11 +93,17 @@ import {
   getAccountBalance,
   getUserAccount,
   getDiyTemplateUsed,
-  getDiyTemplate
+  getDiyTemplate,
+  getCouponTemplatePage,
+  takeCoupon,
+  getCouponPage
 } from '@/api/sign'
 import { onShow, onLoad } from '@dcloudio/uni-app'
-// 设置自定义tabBar选中值
+import { userStore } from '@/store/user'
+import { showAuthModal } from '@/hooks/useModal'
 
+const useUserStore = userStore()
+// 设置自定义tabBar选中值
 
 const SignItems = ref([])
 
@@ -101,25 +119,48 @@ const signLoading = ref(false)
 
 const balance = ref({})
 
+const pageInfo = ref({
+  pageNo: 1,
+  pageSize: 20
+})
+const total = ref(0)
 const items = ref([])
-const more = ref('noMore')
+const more = ref('more')
+
+const myCoupon = ref(0)
+
+watch(() => useUserStore.isLogin, () => {
+  if (useUserStore.isLogin) {
+    init()
+  }
+})
+
+watch(() => useUserStore.refreshToken, () => {
+  init()
+})
 
 onShow(() => {
   const currentPage = getCurrentPages()[0];  // 获取当前页面实例
   const currentTabBar = currentPage?.getTabBar?.();
   // 设置当前tab页的下标index
   currentTabBar?.setData({ selected: 2 });
+  init()
 })
-onLoad(() => {
+
+function init () {
   // 获取签到列表
   getSignIn()
   // 获取签到信息
   getSummary()
   // 获取余额积分
   getBalance()
+  pageInfo.value.pageNo = 1
+  items.value = []
   // 获取模板
-  handleGetTmpUsed()
-})
+  getAllCouponPage()
+  getMyCoupon()
+
+}
 
 // 获取积分余额
 async function getBalance() {
@@ -176,6 +217,41 @@ async function handleSignIn () {
 }
 
 
+// 获取优惠券分页
+async function getAllCouponPage () {
+  try {
+    const { data } = await getCouponTemplatePage({ ...pageInfo.value })
+    console.log(data)
+    if (!data || !data.list || !data.list.length) {
+      if (pageInfo.value.pageNo === 1) {
+        more.value = 'more'
+        return
+      }
+      pageInfo.value.pageNo--
+      more.value = 'more'
+      return
+    }
+    items.value.push(...data.list)
+    total.value = +data.total
+    more.value = total.value === items.value.length ? 'noMore' : 'more'
+  } catch (error) {
+    if (pageInfo.value.pageNo === 1) {
+      more.value = 'more'
+      return
+    }
+    pageInfo.value.pageNo--
+    more.value = 'more'
+  }
+}
+
+async function getMyCoupon () {
+  const { data } = await getCouponPage({ pageNo:1, pageSize: 1, status: 1 })
+  if (data) {
+    myCoupon.value = +data.total
+  }
+}
+
+// 优惠券列表
 async function handleGetTmpUsed () {
   try {
     const { data } = await getDiyTemplateUsed()
@@ -206,15 +282,70 @@ async function handleGetTmpUsed () {
       return
     }
     const { data: _data } = await getDiyTemplate(ids.join(','))
-    items.value.push(..._data)
+    items.value = _data
     more.value = 'noMore'
   } catch (error) {
     
   }
 }
 
-async function loadingMore () {}
+async function loadingMore () {
+  pageInfo.value.pageNo++
+  getAllCouponPage()
+}
+
+function handleLogin () {
+  if (!useUserStore.isLogin) {
+		showAuthModal()
+		return
+	}
+}
+
+function toInfo () {
+  uni.navigateTo({
+		url: '/pagesA/info/index'
+	})
+}
+
+async function onGetCoupon(id, canTake) {
+  if (!canTake) {
+    return
+  }
+  uni.showLoading({
+    title: '领取中'
+  })
+  try {
+    const {
+			code,
+			msg
+		} = await takeCoupon(id)
+    if (code !== 0) {
+      uni.showToast({
+        title: msg,
+        icon: 'none'
+      })
+      return
+    }
+    uni.showToast({
+      title: '领取成功',
+      icon: 'success'
+    })
+    getMyCoupon()
+    pageInfo.value.pageNo = 1
+    items.value = []
+    await getAllCouponPage()
+  } catch (error) {
+    
+  } finally {
+    uni.hideLoading()
+  }
+}
 
+function handleTo (page) {
+  uni.navigateTo({
+    url: `/pagesA/${page}/index`
+  })
+}
 </script>
 
 <style scoped lang="scss">
@@ -248,25 +379,47 @@ $px: 20rpx;
       
       &-member {
         width: 50%;
+        display: flex;
+        align-items: center;
+        position: relative;
+        &:after {
+          content: '';
+          position: absolute;
+          width: 4rpx;
+          height: 30%;
+          right: 0;
+          top: 35%;
+          background: #00897B;
+        }
         .iconBox {
-          width: 100%;
+          width: 100rpx;
           height: 100%;
           display: flex;
           align-items: center;
           justify-content: center;
           &-line {
-            border: 10rpx solid #ffbc00;
+            border: 4rpx solid #ffbc00;
             border-radius: 180rpx;
             padding: 10rpx;
           }
         }
+        .name {
+          flex: 1;
+          .actvie {
+            color: #ffbc00;
+          }
+          
+        }
       }
       &-item {
-        width: 25%;
+        width: 16.6%;
         display: flex;
         flex-direction: column;
         align-items: center;
         justify-content: center;
+        .title {
+          font-size: .85em;
+        }
       }
       &-integral {
       }
@@ -352,6 +505,21 @@ $px: 20rpx;
       background: #FFF;
       padding: $px;
       font-size: .85em;
+      &.disabled {
+        position: relative;
+        &::after {
+          content: '已领取';
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 100%;
+          height: 100%;
+          background: rgba(255,255,255,.75);
+        }
+      }
       .img {
         image {
           width: 128rpx;
@@ -359,7 +527,6 @@ $px: 20rpx;
         }
       }
     }
-    
   }
 }
 </style>

+ 13 - 0
pagesA/balance/index.vue

@@ -0,0 +1,13 @@
+<template>
+  <view>
+    <view>余额</view>
+  </view>
+</template>
+<!-- balance 余额 -->
+<script setup>
+
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 189 - 0
pagesA/coupon/index.vue

@@ -0,0 +1,189 @@
+<template>
+  <layout-page>
+    <scroll-view class="scrollBox" scroll-y="true" @scrolltolower="loadingMore">
+      <view class="defaultBgc content">
+        <view
+          v-for="item in items"
+          :key="item.id"
+          class="content-item"
+          :class="{ used: item.status === 2, disabled: item.status === 3 }"
+        >
+          <view class="msg">
+            <view class="item">
+              <view class="name">{{ item.name }}</view>
+              <view class="price">
+                <uni-icons color="#f30" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>
+                {{ item.price }}
+              </view>
+            </view>
+            <view class="item">
+              <view class="desc">有效期:{{ item.legalTime }}</view>
+              <view class="desc">满 {{ item.used }} 可用</view>
+            </view>
+          </view>
+          <view class="use">
+            <button
+            class="btn"
+            :class="{ disabled: item.status !== 1 }"
+            @tap="handleTo(item.status)"
+            >{{ item.status === 1 ? '立即使用' : item.status === 2 ? '已使用' : '已过期'}}</button>
+          </view>
+        </view>
+        <uni-load-more :status="more" />
+      </view>
+    </scroll-view>
+  </layout-page>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import {
+  getCouponPage
+} from '@/api/sign'
+import { timesTampChange } from '@/utils/date'
+
+
+const pageInfo = ref({
+  pageNo:1,
+  pageSize: 20
+})
+const total = ref(0)
+const items = ref([])
+const more = ref('more')
+
+getMyCoupon()
+
+async function getMyCoupon () {
+  try {
+    const { data } = await getCouponPage({ ...pageInfo.value })
+    if (!data || !data.list || !data.list.length) {
+      if (pageInfo.value.pageNo === 1) {
+        more.value = 'more'
+        return
+      }
+      pageInfo.value.pageNo--
+      more.value = 'more'
+      return
+    }
+    items.value.push(...data.list.map(e => {
+      return {
+        ...e,
+        price: (e.discountPrice / 100).toFixed(2),
+        legalTime: timesTampChange(e.validStartTime, 'Y-M-D') + ' 至 ' + timesTampChange(e.validEndTime, 'Y-M-D'),
+        used: (e.usePrice / 100).toFixed(2)
+      }
+    }))
+    total.value = +data.total
+    more.value = items.value.length >= total.value ? 'noMore' : 'more'
+  } catch (error) {
+    if (pageInfo.value.pageNo === 1) {
+      more.value = 'more'
+      return
+    }
+    pageInfo.value.pageNo--
+    more.value = 'more'
+  }
+}
+
+function handleTo (status) {
+  if (status !== 1) {
+    return
+  }
+  wx.navigateToMiniProgram({  
+    appId: 'wx6decdf12f9e7a061', // 目标小程序的 appId
+    envVersion: 'develop',
+    success(res) {  
+        // 打开成功  
+        console.log('成功跳转至小程序:', res);  
+    },  
+    fail(err) {  
+        // 打开失败
+        uni.showToast({
+          title: '打开商城失败',
+          icon: 'none'
+        })
+    }  
+});  
+}
+</script>
+
+<style lang="scss" scoped>
+.content {
+  // height: 100vh;
+  width: 100vw;
+  padding: 20rpx;
+  box-sizing: border-box;
+  &-item {
+    margin-bottom: 20rpx;
+    .msg {
+      background: #FFF;
+      padding: 40rpx;
+      box-sizing: border-box;
+      -webkit-mask: radial-gradient(circle at 0.375rem 100%, #00000000 0.375rem, red 0) -0.375rem;
+      position: relative;
+      &::after {
+        content: '';
+        position: absolute;
+        bottom: 0;
+        right: 0.375rem;
+        width: calc( 100% - 0.75rem);
+        height: 0;
+        border-top: 2rpx dashed #eee;
+      }
+    }
+    .use {
+      background: #FFF;
+      padding: 20rpx;
+      box-sizing: border-box;
+      display: flex;
+      justify-content: flex-end;
+      font-size: .85em ;
+      -webkit-mask: radial-gradient(circle at 0.375rem 0%, #0000 0.375rem, red 0) -0.375rem;
+      .btn {
+        margin: 0;
+        position: relative;
+        border: 0;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        box-sizing: border-box;
+        text-align: center;
+        text-decoration: none;
+        white-space: nowrap;
+        vertical-align: baseline;
+        transform: translate(0, 0);
+        padding: 0 0.5rem;
+        height: 1.5625rem;
+        width: 200rpx;
+        border-radius: 1.25rem;
+        background: linear-gradient(90deg, #ff3000, rgba(255, 48, 0, 0.6));
+        color: #ffffff;
+        font-size: 0.75rem;
+        font-weight: 400;
+        &.disabled {
+          background: rgba(255, 48, 0, 0.6);
+        }
+      }
+    }
+    .item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      margin-bottom: 20rpx;
+      .name {
+        font-weight: bolder;
+        font-size: 36rpx;
+      }
+      .price {
+        color: #f30;
+        font-size: 54rpx;
+      }
+      .desc {
+        color: #999;
+        font-size: 24rpx;
+      }
+      
+    }
+  }
+}
+</style>

+ 13 - 0
pagesA/integral/index.vue

@@ -0,0 +1,13 @@
+<template>
+  <div>
+
+  </div>
+</template>
+<!-- integral 积分 -->
+<script setup>
+
+</script>
+
+<style lang="scss" scoped>
+
+</style>