Просмотр исходного кода

feat:积分商城首页 - 代码优化整理

xyh 5 месяцев назад
Родитель
Сommit
9df3d9f858
3 измененных файлов с 328 добавлено и 173 удалено
  1. 19 7
      src/pages/index/index.vue
  2. 96 31
      src/points/components/task-list/task-list.vue
  3. 213 135
      src/points/home/index.vue

+ 19 - 7
src/pages/index/index.vue

@@ -175,16 +175,16 @@ export default {
     }
   },
   onShow() {
+    // 获取坐标
+    this.getLocaltion()
     // 获取城市
-    this.getCity()
+    //this.getCity()
     // 获取banner
     this.getBanner()
     // 获取商品
     this.getProject()
     // 获取商品分类
     this.getCatetory()
-    // 获取坐标
-    this.getLocaltion()
     // 获取优惠劵
     this.getCoupon()
     // 获取推荐数据
@@ -216,9 +216,10 @@ export default {
       uni.request({
         url: 'https://restapi.amap.com/v3/ip?parameters',
         data: {
-          key: '5457092e6c62b83c1b2e45dbe973d858',
+          key: 'a4c460548bff03534a39e0985d210674',
         },
         success: res => {
+          console.log(res,'定位')
           uni.setStorageSync('selectCity', res.data.city.slice(0, 2))
           uni.setStorageSync('selectCitycode', res.data.adcode)
         },
@@ -238,14 +239,27 @@ export default {
     },
     // 获取坐标
     getLocaltion() {
+      var _this = this;
       uni.getLocation({
         type: 'wgs84',
         success: function (res) {
           uni.setStorageSync('latitude', res.latitude)
           uni.setStorageSync('longitude', res.longitude)
+          _this.getCityInfo(res.latitude,res.longitude)
         },
       })
     },
+    async getCityInfo(latitude, longitude) {
+      const amapKey = '5457092e6c62b83c1b2e45dbe973d858';
+      const url = `https://restapi.amap.com/v3/geocode/regeo?key=${amapKey}&location=${longitude},${latitude}`;
+      const res = await uni.request({
+        url: url,
+        method: 'GET'
+      });
+      uni.setStorageSync('selectCity', res.data.regeocode.addressComponent.city)
+      uni.setStorageSync('selectCitycode', '140110')
+        console.log('高德API返回:', res.data.regeocode.addressComponent.city);
+    },
     // 获取商品分类
     getCatetory() {
       this.selectList = [{ cdescribe: '热门' }]
@@ -339,9 +353,7 @@ export default {
     },
     // 静默登录
     onLogin(wxCode) {
-      console.log('绕过微信登录,直接添加token')
-      //TODO
-      let res = {"code":200,"msg":"操作成功","data":{"token":"eyJhbGciOiJIUzUxMiJ9.eyJ0ZjoiOiIxMmU1NmQzZS0zYzk3LTQ2MzItOTczZC02NDA2ZmY0MWUxZDgifQ.2rJluXVPEBORNDLflsXnlcH59R77Jo7W8vG8XIHoVjJzJIGtEiQQE3ebYjDa5mk4IzzfkI4NdQsUjmWqWBcalA","id":"2033845259451543553","loginTime":1773900425855,"expireTime":1774505225855,"ipaddr":"172.17.0.1","loginLocation":"内网IP","browser":"Mobile Safari","os":"Mac OS X (iPhone)","nickName":null,"code":null,"role":1,"password":null,"enabled":false,"authorities":null,"copenid":"o7Txd6o8yxUPo6o00Q4fum4JjPJE","cicon":"https://thirdwx.qlogo.cn/mmopen/vi_32/hBiaibicQOu5sF8AicvXyOmVWDKiayct5TcYFTic94NBIa76SMTrHF4icRPDibdG4pxXCNJWtYc4iag7zX2Eia0UadENPzuRh8A7PZAibyXibEZpvpYiabIY/132","cphone":null,"cnickName":"名字","username":null,"cunionid":null,"dmoney":0.00,"nnum":0,"caddressList":null,"dbalance":0.00,"dallMoney":0.00,"cscanImg":null,"cupUser":null,"cmrAddressId":null,"csessionKey":"102_Qj1zgSWBZAaA5gi9Joa8sRQxo334WTeEuD8SfgIwKFsLnz9gyyOjrjpNPqMa7mWcQUljz_ABcaXLsSCIDkWlKlOUEfAoqBeGuW7Wejnjsoc","accountNonExpired":false,"accountNonLocked":false,"credentialsNonExpired":false}}
+      let res = {"code":200,"msg":"操作成功","data":{"token":"eyJhbGciOiJIUzUxMiJ9.eyJ0ZjoiOiI3NzdkMzczMC03NWQ4LTQ1OGYtYmE3Yy1hMTJhM2RiMGI5MGYifQ.6fjnNOgNwSllGJ1wllF5xYojFqwMDQ8yRoJ2BnMGlJDeAlePB6KjKSmJ-E5KxS7qoDgXPFOMQQDDSZcsF3GAPQ","id":"2033845259451543553","loginTime":1775114559991,"expireTime":1775719359991,"ipaddr":"172.24.144.218","loginLocation":"内网IP","browser":"Mobile Safari","os":"Mac OS X (iPhone)","nickName":null,"code":null,"role":1,"enabled":false,"password":null,"authorities":null,"username":null,"cphone":null,"cnickName":"名字","copenid":"o7Txd6o8yxUPo6o00Q4fum4JjPJE","cicon":"https://thirdwx.qlogo.cn/mmopen/vi_32/hBiaibicQOu5sF8AicvXyOmVWDKiayct5TcYFTic94NBIa76SMTrHF4icRPDibdG4pxXCNJWtYc4iag7zX2Eia0UadENPzuRh8A7PZAibyXibEZpvpYiabIY/132","accountNonExpired":false,"accountNonLocked":false,"credentialsNonExpired":false,"csessionKey":"102_Qj1zgSWBZAaA5gi9Joa8sRQxo334WTeEuD8SfgIwKFsLnz9gyyOjrjpNPqMa7mWcQUljz_ABcaXLsSCIDkWlKlOUEfAoqBeGuW7Wejnjsoc","cunionid":null,"dmoney":0.30,"nnum":1,"caddressList":null,"dbalance":0.00,"dallMoney":0.00,"cscanImg":null,"cupUser":null,"cmrAddressId":null}};
       uni.setStorageSync('wx_copenid', res.data.copenid)
       uni.setStorageSync('access-token', res.data.token)
       return false;

+ 96 - 31
src/points/components/task-list/task-list.vue

@@ -5,16 +5,12 @@
     </view>
     <view class="task-list">
       <view 
-        v-for="(task, index) in taskData"
-        :key="index"
+        v-for="task in taskData"
+        :key="task.activityId"
         class="task-item">
         <view class="task-item-left">
           <view class="task-icon">
-            <ImageItem src="/static/points/task_order.png" v-if="task.taskName.includes('订单')"/>
-            <ImageItem src="/static/points/task_shop.png" v-if="task.taskName.includes('商户')"/>
-            <ImageItem src="/static/points/task_trend.png" v-if="task.taskName.includes('动态')"/>
-            <ImageItem src="/static/points/task_wx.png" v-if="task.taskName.includes('服务号')"/>
-            <ImageItem src="/static/points/task_account.png" v-if="task.taskName.includes('账号充值')"/>
+            <ImageItem :src="getTaskIcon(task.taskName)" />
           </view>
 
           <view class="task-info">
@@ -26,7 +22,10 @@
           </view>
         </view>
         <view class="task-item-right">
-          <button :class="task.completedStatus == 1 ? 'task-btn' : 'no-task-btn'" @click.stop="handleTask(task, index)">
+          <button 
+            :class="task.completedStatus == 1 ? 'task-btn' : 'no-task-btn'" 
+            @click.stop="handleTask(task)"
+            :disabled="task.completedStatus == 1">
             {{ task.completedStatus == 1 ? '已完成' : '去完成' }}
           </button>
         </view>
@@ -42,7 +41,7 @@
 import ImageItem from "@/components/swiper/components/image.vue";
 
 export default {
-  components: {ImageItem},
+  components: { ImageItem },
   props: {
     taskData: {
       type: Array,
@@ -51,30 +50,91 @@ export default {
   },
   data() {
     return {
+      // 任务类型配置
+      taskConfig: {
+        order: {
+          icon: '/static/points/task_order.png',
+          action: this.handleOrderTask
+        },
+        merchant: {
+          icon: '/static/points/task_shop.png',
+          action: this.handleMerchantTask
+        },
+        dynamic: {
+          icon: '/static/points/task_trend.png',
+          action: this.handleDynamicTask
+        },
+        service: {
+          icon: '/static/points/task_wx.png',
+          action: this.handleServiceTask
+        },
+        recharge: {
+          icon: '/static/points/task_account.png',
+          action: this.handleRechargeTask
+        }
+      }
     }
   },
   methods: {
-    handleTask(task, index) {
-      if (task.completedStatus != 1) {
-        if(task.taskName.includes('订单')){
-          this.$emit('scrollToSearch');
-        }else if(task.taskName.includes('商户')){
-          uni.switchTab({
-            url: '/pages/identify/identify',
-          })
-        }else if(task.taskName.includes('动态')){
-          uni.switchTab({
-            url: '/pages/discover/discover',
-          })
-        }else if(task.taskName.includes('服务号')){
+    // 获取任务图标
+    getTaskIcon(taskName) {
+      if (taskName.includes('订单')) return this.taskConfig.order.icon;
+      if (taskName.includes('商户')) return this.taskConfig.merchant.icon;
+      if (taskName.includes('动态')) return this.taskConfig.dynamic.icon;
+      if (taskName.includes('服务号')) return this.taskConfig.service.icon;
+      if (taskName.includes('账号充值')) return this.taskConfig.recharge.icon;
+      return '';
+    },
 
-        }else if(task.taskName.includes('账号充值')){
-          uni.navigateTo({
-            url: '/pages/my/pay'
-          });
-        }
+    // 处理任务点击
+    handleTask(task) {
+      if (task.completedStatus === 1) return;
+
+      if (task.taskName.includes('订单')) {
+        this.taskConfig.order.action();
+      } else if (task.taskName.includes('商户')) {
+        this.taskConfig.merchant.action();
+      } else if (task.taskName.includes('动态')) {
+        this.taskConfig.dynamic.action();
+      } else if (task.taskName.includes('服务号')) {
+        this.taskConfig.service.action();
+      } else if (task.taskName.includes('账号充值')) {
+        this.taskConfig.recharge.action();
       }
     },
+
+    // 处理订单任务
+    handleOrderTask() {
+      this.$emit('scrollToSearch');
+    },
+
+    // 处理商户任务
+    handleMerchantTask() {
+      uni.switchTab({
+        url: '/pages/identify/identify'
+      });
+    },
+
+    // 处理动态任务
+    handleDynamicTask() {
+      uni.switchTab({
+        url: '/pages/discover/discover'
+      });
+    },
+
+    // 处理服务号任务
+    handleServiceTask() {
+      // 服务号任务处理逻辑
+    },
+
+    // 处理账号充值任务
+    handleRechargeTask() {
+      uni.navigateTo({
+        url: '/pages/my/pay'
+      });
+    },
+
+    // 处理查看更多任务
     handleMoreTasks() {
       uni.navigateTo({
         url: '/points/pointInfo/taskList'
@@ -107,6 +167,7 @@ export default {
       justify-content: space-between;
       align-items: center;
       margin-bottom: 32rpx;
+      
       .task-item-left {
         display: flex;
         align-items: center;
@@ -115,7 +176,8 @@ export default {
           width: 72rpx;
           height: 72rpx;
           margin-right: 18rpx;
-          image{
+          
+          image {
             width: 72rpx;
             height: 72rpx;
           }
@@ -137,12 +199,14 @@ export default {
             background: #FBF2E1;
             border-radius: 22rpx;
             padding-right: 12rpx;
-            image{
+            
+            image {
               width: 32rpx;
               height: 32rpx;
               margin-right: 4rpx;
             }
-            text{
+            
+            text {
               font-family: PingFang SC, PingFang SC;
               font-weight: 500;
               font-size: 24rpx;
@@ -165,7 +229,8 @@ export default {
           line-height: 48rpx;
           border: 1px solid #EEEEEE;
         }
-        .no-task-btn{
+        
+        .no-task-btn {
           height: 48rpx;
           background: #03C1B8;
           border-radius: 98rpx;

+ 213 - 135
src/points/home/index.vue

@@ -4,8 +4,10 @@ import TaskList from '../components/task-list/task-list.vue'
 import ProductList from '../components/product-list/product-list.vue'
 import ImageItem from "@/components/swiper/components/image.vue";
 import { mapState, mapActions } from 'vuex';
-import {getSignPoint,signPoint,getHomeTask} from '@/api/points'
+import { getSignPoint, signPoint, getHomeTask } from '@/api/points'
+
 export default {
+  name: 'PointsHome',
   components: {
     ImageItem,
     SignIn,
@@ -16,9 +18,11 @@ export default {
     ...mapState({
       myPoint: state => state.points.myPoint
     }),
+    // 总积分
     totalPoints() {
       return this.myPoint.totalPoints || 0;
     },
+    // 本月新获取积分
     monthlyPoints() {
       return this.myPoint.earnedPoints || 0;
     }
@@ -27,177 +31,251 @@ export default {
     return {
       // 滚动距离
       scrollTop: 0,
-      signData:[],
-      taskData:[]
+      // 签到数据
+      signData: [],
+      // 任务数据
+      taskData: [],
+      // 加载状态
+      loading: {
+        points: false,
+        sign: false,
+        task: false
+      }
     }
   },
   mounted() {
-    // 获取积分信息
-    this.getPointsInfo();
-    this.getSignList();
-    this.getTaskList();
-    // 在H5端添加滚动事件监听器
-    if (process.env.UNI_PLATFORM === 'h5') {
-      // 使用this.$el获取当前组件的根元素
-      const homeEl = this.$el
-      if (homeEl) {
-        homeEl.addEventListener('scroll', this.handleScroll)
-      }
-    } else {
-      // 在非H5端监听页面滚动事件
-      uni.onPageScroll(this.handlePageScroll)
-    }
+    // 初始化数据
+    this.initData();
+    // 绑定滚动事件
+    this.bindScrollEvent();
   },
   beforeUnmount() {
-    // 移除滚动事件监听器
-    if (process.env.UNI_PLATFORM === 'h5') {
-      const homeEl = this.$el
-      if (homeEl) {
-        homeEl.removeEventListener('scroll', this.handleScroll)
-      }
-    } else {
-      // 移除页面滚动事件监听
-      uni.offPageScroll(this.handlePageScroll)
-    }
+    // 解绑滚动事件
+    this.unbindScrollEvent();
   },
   methods: {
     ...mapActions([
       'getPointsInfo'
     ]),
+    // 初始化数据
+    async initData() {
+      try {
+        // 并行获取数据,提高加载速度
+        await Promise.all([
+          this.fetchPointsInfo(),
+          this.fetchSignList(),
+          this.fetchTaskList()
+        ]);
+      } catch (error) {
+        console.error('初始化数据失败:', error);
+      }
+    },
+    // 获取积分信息
+    async fetchPointsInfo() {
+      this.loading.points = true;
+      try {
+        await this.getPointsInfo();
+      } catch (error) {
+        console.error('获取积分信息失败:', error);
+      } finally {
+        this.loading.points = false;
+      }
+    },
+    // 获取签到数据
+    async fetchSignList() {
+      this.loading.sign = true;
+      try {
+        // 实际项目中使用真实API
+        // const res = await getSignPoint({
+        //   cityName: uni.getStorageSync('selectCity'),
+        //   cityCode: uni.getStorageSync('selectCitycode'),
+        // });
+        
+        // 模拟数据
+        const res = {
+          data: [
+            {
+              "date": "01-30",
+              "points": 1,
+              "status": 1
+            },
+            {
+              "date": "02-01",
+              "points": 0,
+              "status": 0
+            },
+            {
+              "date": "02-02",
+              "points": 1,
+              "status": 1
+            },
+            {
+              "date": "02-03",
+              "points": 1,
+              "status": 0
+            },
+            {
+              "date": "02-04",
+              "points": 1,
+              "status": 0
+            },
+            {
+              "date": "02-05",
+              "points": 1,
+              "status": 0
+            },
+            {
+              "date": "02-06",
+              "points": 3,
+              "status": 0
+            }
+          ],
+          code: 200,
+          msg: "查询成功"
+        };
+        
+        if (res.code === 200) {
+          this.signData = res.data;
+        }
+      } catch (error) {
+        console.error('获取签到数据失败:', error);
+      } finally {
+        this.loading.sign = false;
+      }
+    },
+    // 获取任务数据
+    async fetchTaskList() {
+      this.loading.task = true;
+      try {
+        // 实际项目中使用真实API
+        // const res = await getHomeTask({
+        //   cityName: uni.getStorageSync('selectCity'),
+        //   cityCode: uni.getStorageSync('selectCitycode'),
+        // });
+        
+        // 模拟数据
+        const res = {
+          data: [
+            {
+              "activityId": 21,
+              "taskName": "浏览动态",
+              "rewardPoints": 10,
+              "completedCount": 1,
+              "triggerValue": 2,
+              "completedStatus": 0
+            },
+            {
+              "activityId": 22,
+              "taskName": "完成一次订单",
+              "rewardPoints": 20,
+              "completedCount": 3,
+              "triggerValue": 2,
+              "completedStatus": 1
+            }
+          ],
+          code: 200,
+          msg: "查询成功"
+        };
+        
+        if (res.code === 200) {
+          this.taskData = res.data;
+        }
+      } catch (error) {
+        console.error('获取任务数据失败:', error);
+      } finally {
+        this.loading.task = false;
+      }
+    },
+    // 绑定滚动事件
+    bindScrollEvent() {
+      if (process.env.UNI_PLATFORM === 'h5') {
+        // 在H5端添加滚动事件监听器
+        const homeEl = this.$el;
+        if (homeEl && typeof homeEl.addEventListener === 'function') {
+          homeEl.addEventListener('scroll', this.handleScroll);
+        }
+      } else {
+        // 在非H5端监听页面滚动事件
+        uni.onPageScroll(this.handlePageScroll);
+      }
+    },
+    // 解绑滚动事件
+    unbindScrollEvent() {
+      if (process.env.UNI_PLATFORM === 'h5') {
+        const homeEl = this.$el;
+        if (homeEl && typeof homeEl.removeEventListener === 'function') {
+          homeEl.removeEventListener('scroll', this.handleScroll);
+        }
+      } else {
+        // 移除页面滚动事件监听
+        uni.offPageScroll(this.handlePageScroll);
+      }
+    },
+    // 处理滚动事件(H5端)
     handleScroll() {
-      const homeEl = this.$el
+      const homeEl = this.$el;
       if (homeEl) {
-        const scrollTop = homeEl.scrollTop
+        const scrollTop = homeEl.scrollTop;
         // 更新滚动距离
-        this.scrollTop = scrollTop
-        const scrollHeight = homeEl.scrollHeight
-        const clientHeight = homeEl.clientHeight
-        // 当滚动到距离底部50px以内时,触发加载更多
-        if (scrollTop + clientHeight >= scrollHeight - 50) {
-          this.reachBottom()
-        }
+        this.updateScrollTop(scrollTop);
+        // 检查是否触底
+        this.checkReachBottom(homeEl, scrollTop);
       }
     },
     // 处理页面滚动事件(非H5端)
     handlePageScroll(e) {
-      const scrollTop = e.scrollTop
+      const scrollTop = e.scrollTop;
       // 更新滚动距离
-      this.scrollTop = scrollTop
-      // 当滚动到距离底部50px以内时,触发加载更多
-      const homeEl = this.$el
+      this.updateScrollTop(scrollTop);
+      // 检查是否触底
+      const homeEl = this.$el;
       if (homeEl) {
-        const scrollHeight = homeEl.scrollHeight
-        const clientHeight = homeEl.clientHeight
-        if (scrollTop + clientHeight >= scrollHeight - 50) {
-          this.reachBottom()
-        }
+        this.checkReachBottom(homeEl, scrollTop);
       }
     },
-    reachBottom() {
-      if (this.$refs.productRef) {
-        this.$refs.productRef.loadMore()
+    // 更新滚动距离
+    updateScrollTop(scrollTop) {
+      this.scrollTop = scrollTop;
+    },
+    // 检查是否触底
+    checkReachBottom(element, scrollTop) {
+      const scrollHeight = element.scrollHeight;
+      const clientHeight = element.clientHeight;
+      // 当滚动到距离底部50px以内时,触发加载更多
+      if (scrollTop + clientHeight >= scrollHeight - 50) {
+        this.reachBottom();
       }
     },
-    /** 签到领积分 */
-    async getSignList() {
-      // const res = await getSignPoint({
-      //   cityName: uni.getStorageSync('selectCity'),
-      //   cityCode:uni.getStorageSync('selectCitycode'),
-      // });
-      const res = {
-        data: [
-          {
-            "date": "01-30",
-            "points": 1,
-            "status": 1
-          },
-          {
-            "date": "02-01",
-            "points": 0,
-            "status": 0
-          },
-          {
-            "date": "02-02",
-            "points": 1,
-            "status": 1
-          },
-          {
-            "date": "02-03",
-            "points": 1,
-            "status": 0
-          },
-          {
-            "date": "02-04",
-            "points": 1,
-            "status": 0
-          },
-          {
-            "date": "02-05",
-            "points": 1,
-            "status": 0
-          },
-          {
-            "date": "02-06",
-            "points": 3,
-            "status": 0
-          }
-        ],
-        code: 200,
-        msg: "查询成功"
+    // 触底加载更多
+    reachBottom() {
+      if (this.$refs.productRef) {
+        this.$refs.productRef.loadMore();
       }
-      this.signData = res.data;
     },
+    // 处理签到
     handleSign(index) {
       signPoint().then(res => {
-        if(res.code == 200){
+        if (res.code === 200) {
           this.signData[index].status = 1;
         }
-      })
-    },
-
-    /** 任务逻辑 */
-    async getTaskList() {
-      // const res = await getHomeTask({
-      //   cityName: uni.getStorageSync('selectCity'),
-      //   cityCode:uni.getStorageSync('selectCitycode'),
-      // });
-      const res = {
-        data: [
-          {
-            "activityId": 21,
-            "taskName": "浏览动态",
-            "rewardPoints": 10,
-            "completedCount": 1,
-            "triggerValue": 2,
-            "completedStatus": 0
-          },
-          {
-            "activityId": 22,
-            "taskName": "完成一次订单",
-            "rewardPoints": 20,
-            "completedCount": 3,
-            "triggerValue": 2,
-            "completedStatus": 1
-          }
-        ],
-        code: 200,
-        msg: "查询成功"
-      }
-      this.taskData = res.data;
+      }).catch(error => {
+        console.error('签到失败:', error);
+      });
     },
-    goBillPage(){
+    // 跳转到积分明细页面
+    goBillPage() {
       uni.navigateTo({
         url: '/points/pointInfo/billPage'
       });
     },
-    orderGo(){
+    // 跳转到订单列表页面
+    orderGo() {
       uni.navigateTo({
         url: '/points/order/orderList'
       });
     },
     // 滚动到搜索框
     scrollToSearch() {
-      // 计算滚动距离,使搜索框触底顶
       const homeEl = this.$el;
       if (homeEl) {
         // 滚动到商品列表的位置,使搜索框显示在顶部
@@ -212,7 +290,7 @@ export default {
 </script>
 
 <template>
-  <view class="points-home">
+  <view class="points-home" ref="homeRef">
     <view class="points-task">
       <!-- 积分头部 -->
       <view class="points-header" @click="goBillPage">
@@ -232,9 +310,9 @@ export default {
     <!-- 商品列表组件 -->
     <ProductList ref="productRef" :scrollTop="scrollTop" />
     <!-- 积分订单跳转 -->
-   <view @click="orderGo" class="orderIcons">
+    <view @click="orderGo" class="orderIcons">
       <ImageItem src="/static/points/orderGo.png"/>
-   </view>
+    </view>
   </view>
 </template>