绿满眶商城微信小程序-uniapp
peng
2025-07-09 c22e91296d532873b70cb51bf5510bf7738f3f1a
pages/mine/myTracks.vue
@@ -2,12 +2,61 @@
   <view class="myTracks">
      <u-navbar title="我的足迹">
         <div slot="right">
        <div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
      </div>
            <div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
         </div>
      </u-navbar>
      <u-notice-bar mode="vertical" :list="['右划删除浏览记录']"></u-notice-bar>
      <u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty>
      <div v-else>
      <!-- 顶部选项卡 -->
      <view class="tabs">
        <view
         class="tab-item"
         :class="{active: activeTab === 'video'}"
         @click="switchTab('video')"
        >
         视频
        </view>
        <view
         class="tab-item"
         :class="{active: activeTab === 'goods'}"
         @click="switchTab('goods')"
        >
         商品
        </view>
      </view>
      <!-- 视频浏览记录列表 -->
      <view v-if="activeTab === 'video'" class="video-list">
        <view
         v-for="(item, index) in videoHistory"
         :key="index"
         class="video-item"
         @click="goToVideoPlay(item, index)"
        >
           <u-swipe-action style="width: 100%;" :show="item.show" :index="index" :key="item.id"
            @click="deleteVideoView(item.id)" @open="open" :options="options">
            <view style="display: flex;" @click="goToVideoPlay(item, index)">
               <image class="video-cover" :src="item.coverUrl" mode="aspectFill"></image>
               <view class="video-info">
                 <view class="video-title">{{item.title}}</view>
                 <view class="video-author">{{item.authorName}}</view>
                 <view class="video-meta">
                  <text>播放至: {{formatPlayTime(item.playAt)}}</text>
                  <text class="separator">|</text>
                  <text>{{formatDate(item.playTime)}}</text>
                 </view>
               </view>
            </view>
           </u-swipe-action>
        </view>
        <div @click="deleteVideoView(item.id)" v-if="isEdit" class="submit">
           删除所选
        </div>
        <view v-if="videoHistory.length === 0" class="empty-tip">
         暂无视频浏览记录
        </view>
      </view>
      <view v-else-if="activeTab === 'goods'">
         <view v-for="(item, index) in trackList" :key="index">
            <view class="myTracks-title" @click="navigateToStore(item)">{{item.storeName}}</view>
            <view class="myTracks-items">
@@ -37,33 +86,34 @@
            </view>
            <view class="myTracks-divider"></view>
            <div @click="handleClickDeleteSelected(item.id)" v-if="isEdit" class="submit">
               删除所选
            </div>
         </view>
         <div @click="handleClickDeleteSelected" v-if="isEdit" class="submit">
            删除所选
         </div>
      </div>
         <view v-if="trackList.length === 0" class="empty-tip">
                  暂无商品浏览记录
         </view>
      </view>
   </view>
</template>
<script>
   import UNavbar from '@/uview-components/uview-ui/components/u-navbar/u-navbar.vue';
   import UNoticeBar from '@/uview-components/uview-ui/components/u-notice-bar/u-notice-bar.vue';
   import UEmpty from '@/uview-components/uview-ui/components/u-empty/u-empty.vue';
   import USwipeAction from '@/uview-components/uview-ui/components/u-swipe-action/u-swipe-action.vue';
   import UCheckboxGroup from '@/uview-components/uview-ui/components/u-checkbox-group/u-checkbox-group.vue';
   import UCheckbox from '@/uview-components/uview-ui/components/u-checkbox/u-checkbox.vue';
   import '@/components/uview-components/uview-ui';
   
   import {
      myTrackList,
      deleteHistoryListId
      deleteHistoryListId,
      myVideoHistory
   } from "@/api/members.js";
import storage from '@/utils/storage';
   export default {
      components: {UNavbar,UNoticeBar,UEmpty,USwipeAction,UCheckboxGroup,UCheckbox},
      data() {
         return {
            activeTab: 'video', // 当前激活的tab
            videoHistory: [], // 视频浏览列表
            isEdit:false,
            whetherEmpty: false, //是否数据为空
            params: {
@@ -79,7 +129,7 @@
                  backgroundColor: '#dd524d'
               }
            }],
            trackList: [], //足迹列表
            trackList: [], //商品浏览列表
         };
      },
@@ -100,8 +150,75 @@
         this.getList();
      },
      methods: {
         // 切换tab
         switchTab(tab) {
           this.activeTab = tab
         },
         // 跳转到视频详情页
         goToVideoPlay(item, index) {
            const playInfo = {
               videoList: this.videoHistory,
               nomore: true,
               pageNumber: this.params.pageNumber,
               playIndex: index
            }
            uni.setStorageSync("playInfo", playInfo)
             uni.navigateTo({
              url: `/pages/video/video-play?authorId=${storage.getUserInfo().id}&videoFrom=history`
             })
         },
         // 格式化播放时间 (秒 -> 分:秒)
         formatPlayTime(seconds) {
            const secsInt = Math.floor(seconds); // 去掉小数部分
             const mins = Math.floor(secsInt / 60)
             const secs = secsInt % 60
             return `${mins}:${secs < 10 ? '0' + secs : secs}`
         },
         // 格式化日期
         formatDate(timestamp) {
           const now = new Date()
           const date = new Date(timestamp)
           // 如果是今天
           if (date.toDateString() === now.toDateString()) {
            const hours = date.getHours().toString().padStart(2, '0')
            const minutes = date.getMinutes().toString().padStart(2, '0')
            return `${hours}:${minutes}`
           }
           // 如果是昨天
           const yesterday = new Date(now)
           yesterday.setDate(now.getDate() - 1)
           if (date.toDateString() === yesterday.toDateString()) {
            return '昨天'
           }
           // 其他情况显示日期
           const month = date.getMonth() + 1
           const day = date.getDate()
           return `${month}月${day}日`
         },
         checkboxChangeDP(val){
            console.log(val)
         },
         // 删除视频浏览记录
         deleteVideoView(id) {
            deleteHistoryListId([id], 'video').then((res) => {
               if (res.data.code == 200) {
                  this.videoHistory = [];
                  this.params.pageNumber = 1
                  this.getList();
               } else {
                  uni.showToast({
                     title: res.data.message,
                     duration: 2000,
                     icon: "none",
                  });
               }
            });
         },
         // 删除所选的数据
         handleClickDeleteSelected(val){
@@ -147,32 +264,53 @@
            uni.showLoading({
               title: "加载中",
            });
            myTrackList(this.params).then((res) => {
               uni.stopPullDownRefresh();
               uni.hideLoading();
               if (res.statusCode == 200) {
                  res.data.result.records.length &&
                     res.data.result.records.forEach((item) => {
            if (this.activeTab === 'goods') {
               myTrackList(this.params).then((res) => {
                  uni.stopPullDownRefresh();
                  uni.hideLoading();
                  if (res.statusCode == 200) {
                     res.data.result.records.length &&
                        res.data.result.records.forEach((item) => {
                           item.show = false;
                           item.checked = false
                        });
                     let data = res.data.result.records;
                     if (data.total == 0) {
                        this.whetherEmpty = true;
                     } else {
                        this.trackList.push(...data);
                     }
                  }
               });
            } else if (this.activeTab === 'video') {
               myVideoHistory(this.params).then(res => {
                  res.data.data.length &&
                     res.data.data.forEach((item) => {
                        item.show = false;
                        item.checked = false
                     });
                  let data = res.data.result.records;
                  let data = res.data.data;
                  if (data.total == 0) {
                     this.whetherEmpty = true;
                  } else {
                     this.trackList.push(...data);
                     this.videoHistory = [
                       ...this.videoHistory,
                       ...res.data.data.filter(
                         (newItem) => !this.videoHistory.some((oldItem) => oldItem.id === newItem.id)
                       ),
                     ];
                  }
               }
            });
               })
            }
         },
         /**
          * 删除足迹
          */
         delTracks(index,ids) {
            deleteHistoryListId(ids || this.trackList[index].goodsId).then((res) => {
            deleteHistoryListId(ids || this.trackList[index].goodsId, 'goods').then((res) => {
               if (res.data.code == 200) {
                  this.trackList = [];
                  this.params.pageNumber = 1
@@ -309,4 +447,95 @@
   .edit{
     padding-right: 32rpx;
   }
   .container {
     padding: 20rpx;
   }
   /* 选项卡样式 */
   .tabs {
     display: flex;
     margin-bottom: 20rpx;
     border-bottom: 1rpx solid #eee;
   }
   .tab-item {
     flex: 1;
     text-align: center;
     padding: 20rpx 0;
     font-size: 32rpx;
     color: #666;
   }
   .tab-item.active {
     color: #007AFF;
     position: relative;
   }
   .tab-item.active::after {
     content: '';
     position: absolute;
     bottom: 0;
     left: 50%;
     transform: translateX(-50%);
     width: 80rpx;
     height: 4rpx;
     background-color: #007AFF;
   }
   /* 视频列表样式 */
   .video-list {
     padding: 10rpx 0;
   }
   .video-item {
     display: flex;
     padding-bottom: 10rpx;
     padding-left: 20rpx;
     border-bottom: 1rpx solid #f5f5f5;
   }
   .video-cover {
     width: 220rpx;
     height: 160rpx;
     border-radius: 8rpx;
     margin-right: 20rpx;
   }
   .video-info {
     flex: 1;
     display: flex;
     flex-direction: column;
     justify-content: space-between;
   }
   .video-title {
     font-size: 30rpx;
     color: #333;
     display: -webkit-box;
     -webkit-box-orient: vertical;
     -webkit-line-clamp: 2;
     overflow: hidden;
     line-height: 1.4;
   }
   .video-author {
     font-size: 26rpx;
     color: #999;
   }
   .video-meta {
     font-size: 24rpx;
     color: #999;
   }
   .separator {
     margin: 0 10rpx;
   }
   .empty-tip {
     text-align: center;
     padding: 100rpx 0;
     color: #999;
     font-size: 28rpx;
   }
</style>