From 61032da9f6f840c9c96af090d1810bc7a0734f4b Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期三, 30 七月 2025 17:18:14 +0800 Subject: [PATCH] 商品二维码跳转 --- pages/mine/myCollect/myCollect.vue | 626 ++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 404 insertions(+), 222 deletions(-) diff --git a/pages/mine/myCollect/myCollect.vue b/pages/mine/myCollect/myCollect.vue index 4b0fd27..d198b7a 100644 --- a/pages/mine/myCollect/myCollect.vue +++ b/pages/mine/myCollect/myCollect.vue @@ -1,6 +1,5 @@ <template> - - <view class="activity-container"> + <view class="page-container"> <!-- 椤堕儴 Tab 瀵艰埅 --> <view class="tab-nav"> <view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{active: currentTab === index}" @@ -9,323 +8,502 @@ </view> </view> - <!-- 瑙嗛鍒楄〃 --> - <view class="activity-list" > - <view v-if="currentTab === 0"> - <view v-if="signedActivities.length > 0"> - <view v-for="(item, idx) in signedActivities" :key="idx" class="activity-item"> - <!-- 灏侀潰鍖哄煙 --> - <block v-if="item.coverType === '鍥剧墖' || item.coverType === '瑙嗛'"> - <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> - </block> - <block v-if="item.coverType === '鏂囧瓧'"> - <view class="activity-cover">{{ item.cover }}</view> - </block> + <!-- 瑙嗛鏀惰棌鍒楄〃 --> + <view v-if="currentTab === 0" class="list-container"> + <scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore" :lower-threshold="100"> + <view v-if="videoCollects.length > 0"> + <view v-for="(item, idx) in videoCollects" :key="item.id" class="collect-item"> + <!-- 瑙嗛灏侀潰 --> + <image v-if="tem.videoContentType === 'img'" class="cover-image" :src="item.imgs[0]" mode="aspectFill"></image> + + <view v-else class="cover-container"> + <video class="cover-image" + :src="item.videoUrl" + initial-time='0.01' + muted + :controls="false" + :show-center-play-btn="false" + object-fit="cover"></video> + <!-- <image :src="getVideoCover()" mode="aspectFill" class="cover-image" /> --> + <!-- <view v-if="item.duration" class="duration"> + {{ formatDuration(item.duration) }} + </view> --> + </view> - <!-- 娲诲姩淇℃伅 --> - <view class="activity-info"> - <view class="activity-title">{{ item.activityName }}</view> - <view class="activity-meta"> - <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> - <text class="activity-location">{{ item.activityLocation || '鏆傛棤' }}</text> + <!-- 瑙嗛淇℃伅 --> + <view class="info-container"> + <view class="title">{{ item.title || '鏃犳爣棰樿棰�' }}</view> + <view class="meta"> + <view class="meta-item"> + <u-icon name="account-fill" size="24" color="#999"></u-icon> + {{ item.authorName || '鏈煡浣滆��' }} + </view> + <view class="meta-item" v-if="item.weight > 0"> + <u-icon name="thumb-up-fill" size="24" color="#999"></u-icon> + {{ item.weight }} + </view> </view> </view> - <!-- 鎿嶄綔鍖哄煙 --> + <!-- 鍙栨秷鏀惰棌鎸夐挳 --> <view class="action-container"> - <button class="cancel-btn" @click="handleCancelCollection(item)" + <button class="cancel-btn" @click.stop="handleCancelCollection(item, 'video', idx)" hover-class="cancel-btn-hover"> 鍙栨秷鏀惰棌 </button> </view> - </view> </view> - </view> - - <view v-if="currentTab === 1"> - <!-- 宸茬粨鏉熸椿鍔ㄥ垪琛� --> - <view v-if="endedActivities.length > 0"> - <view v-for="(item, idx) in endedActivities" :key="idx" class="activity-item"> - <!-- 灏侀潰鍖哄煙 --> - <block v-if="item.coverType === '鍥剧墖' || item.coverType === '瑙嗛'"> - <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> - </block> - <block v-if="item.coverType === '鏂囧瓧'"> - <view class="activity-cover">{{ item.cover }}</view> - </block> - - <!-- 娲诲姩淇℃伅 --> - <view class="activity-info"> - <view class="activity-title">{{ item.activityName }}</view> - <view class="activity-meta"> - <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> - <text class="activity-location">{{ item.activityLocation || '鏆傛棤' }}</text> - </view> - </view> - - <!-- 鎿嶄綔鍖哄煙 --> - <view class="action-container"> - <button class="cancel-btn" @click="handleCancelCollection(item)" - hover-class="cancel-btn-hover"> - 鍙栨秷鏀惰棌 - </button> - </view> - - </view> + <view v-else class="empty-tip"> + <image src="/static/empty.png" mode="aspectFit" /> + <text>鏆傛棤鏀惰棌瑙嗛</text> </view> - </view> - - <view v-if="currentTab === 2"> - <!-- 宸插彇娑堟椿鍔ㄥ垪琛� --> - <view v-if="canceledActivities.length > 0"> - <view v-for="(item, idx) in endedActivities" :key="idx" class="activity-item"> - <!-- 灏侀潰鍖哄煙 --> - <block v-if="item.coverType === '鍥剧墖' || item.coverType === '瑙嗛'"> - <image :src="getPreviewUrl(item.cover)" mode="aspectFill" class="activity-cover" /> - </block> - <block v-if="item.coverType === '鏂囧瓧'"> - <view class="activity-cover">{{ item.cover }}</view> - </block> - <!-- 娲诲姩淇℃伅 --> - <view class="activity-info"> - <view class="activity-title">{{ item.activityName }}</view> - <view class="activity-meta"> - <text class="activity-time">{{ item.startTime }} - {{ item.endTime }}</text> - <text class="activity-location">{{ item.activityLocation || '鏆傛棤' }}</text> - </view> - </view> - <!-- 鎿嶄綔鍖哄煙 --> - <view class="action-container"> - <button class="cancel-btn" @click="handleCancelCollection(item)" - hover-class="cancel-btn-hover"> - 鍙栨秷鏀惰棌 - </button> - </view> - - </view> - - + <view class="load-more"> + <u-loadmore v-if="videoCollects.length > 0" :status="loadStatus" :load-text="{ + loadmore: '涓婃媺鍔犺浇鏇村', + loading: '姝e湪鍔犺浇', + nomore: '娌℃湁鏇村浜�' + }" /> </view> - - </view> - - - + </scroll-view> </view> + <!-- 鍟嗗搧鏀惰棌鍒楄〃 --> + <view v-if="currentTab === 1" class="list-container"> + <scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore" :lower-threshold="100"> + <view v-if="goodsCollects.length > 0"> + <view v-for="(item, idx) in goodsCollects" :key="item.id" class="collect-item"> + <!-- 鍟嗗搧灏侀潰 --> + <view class="cover-container"> + <image :src="item.original" mode="aspectFill" class="cover-image" /> + </view> + <!-- 鍟嗗搧淇℃伅 --> + <view class="info-container"> + <view class="title">{{ item.goodsName }}</view> + <view class="meta"> + <view class="meta-item"> + <u-icon name="rmb-circle-fill" size="24" color="#FF5500"></u-icon> + {{ item.price }}鍏� + </view> + <view class="meta-item"> + <u-icon name="home-fill" size="24" color="#999"></u-icon> + {{ item.storeName || '鏆傛棤' }} + </view> + </view> + </view> + + <!-- 鍙栨秷鏀惰棌鎸夐挳 --> + <view class="action-container"> + <button class="cancel-btn" @click.stop="handleCancelCollection(item, 'goods', idx)" + hover-class="cancel-btn-hover"> + 鍙栨秷鏀惰棌 + </button> + </view> + </view> + </view> + <view v-else class="empty-tip"> + <image src="/static/empty.png" mode="aspectFit" /> + <text>鏆傛棤鏀惰棌鍟嗗搧</text> + </view> + <view class="load-more"> + <u-loadmore v-if="goodsCollects.length > 0" :status="loadStatus" :load-text="{ + loadmore: '涓婃媺鍔犺浇鏇村', + loading: '姝e湪鍔犺浇', + nomore: '娌℃湁鏇村浜�' + }" /> + </view> + </scroll-view> + </view> + + <!-- 娲诲姩鏀惰棌鍒楄〃 --> + <view v-if="currentTab === 2" class="list-container"> + <scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore" :lower-threshold="100"> + <view v-if="activityCollects.length > 0"> + <view v-for="(item, idx) in activityCollects" :key="item.id" class="collect-item"> + <!-- 娲诲姩灏侀潰 --> + <view class="cover-container"> + <image v-if="item.coverType === '鍥剧墖' || item.coverType === '瑙嗛'" :src="item.cover" + mode="aspectFill" class="cover-image" /> + <view v-else-if="item.coverType === '鏂囧瓧'" class="text-cover"> + {{ item.cover }} + </view> + </view> + + <!-- 娲诲姩淇℃伅 --> + <view class="info-container"> + <view class="title">{{ item.activityName }}</view> + <view class="meta"> + <view class="meta-item"> + <u-icon name="calendar-fill" size="24" color="#999"></u-icon> + {{ item.startTime }} ~ {{ item.endTime }} + </view> + <view class="meta-item"> + <u-icon name="map-pin-fill" size="24" color="#999"></u-icon> + {{ item.activityLocation || '鏆傛棤' }} + </view> + </view> + </view> + + <!-- 鍙栨秷鏀惰棌鎸夐挳 --> + <view class="action-container"> + <button class="cancel-btn" @click.stop="handleCancelCollection(item, 'activity', idx)" + hover-class="cancel-btn-hover"> + 鍙栨秷鏀惰棌 + </button> + </view> + </view> + </view> + <view v-else class="empty-tip"> + <image src="/static/empty.png" mode="aspectFit" /> + <text>鏆傛棤鏀惰棌娲诲姩</text> + </view> + <view class="load-more"> + <u-loadmore v-if="activityCollects.length > 0" :status="loadStatus" :load-text="{ + loadmore: '涓婃媺鍔犺浇鏇村', + loading: '姝e湪鍔犺浇', + nomore: '娌℃湁鏇村浜�' + }" /> + </view> + </scroll-view> + </view> </view> - </template> <script> import { - getMyActivityList, - activityCancel - } from '@/api/activity.js' - import { - getPreviewUrl - } from '@/api/common.js' + getMyCollectList, + changeCollect + } from '@/api/collect.js' + import storage from '@/utils/storage' + export default { data() { return { - currentTab: 0, // 褰撳墠閫変腑鐨則ab绱㈠紩 + currentTab: 0, tabs: ['瑙嗛', '鍟嗗搧', '娲诲姩'], - // - videoCollects: [], // 鏀惰棌瑙嗛鍒楄〃 - storeCollects: [], // 鏀惰棌鍟嗗搧鍒楄〃 - activityCollects: [], // 鏀惰棌娲诲姩鍒楄〃 + videoCollects: [], + goodsCollects: [], + activityCollects: [], query: { - id: '', - status: '', - cancel: false, + authorId: '', + type: 'video', + pageNumber: 1, + pageSize: 5 }, + loading: false, + noMore: false, + total: 0 } }, - onLoad(){ - this.currentTab = 0; - //TODO 鏈櫥褰曢渶瑕乮d锛屾祴璇曠敤鍐欐\ - this.switchTab(this.currentTab); + computed: { + loadStatus() { + return this.loading ? 'loading' : this.noMore ? 'nomore' : 'loadmore' + } + }, + onLoad() { + this.query.authorId = storage.getUserInfo().id + this.loadData() + }, + onPullDownRefresh() { + this.query.pageNumber = 1 + this.noMore = false + this.videoCollects = [] + this.goodsCollects = [] + this.activityCollects = [] + this.loadData().finally(() => { + uni.stopPullDownRefresh() + }) }, methods: { - handleCancelCollection(id) { + async getVideoCover(videoPath) { + return null; + }, + + // 璺宠浆鍒拌棰戞挱鏀鹃〉 + // jumpToPlay(index) { + // const playInfo = { + // videoList: this.videoCollects, + // nomore: this.noMore, + // pageNumber: this.query.pageNumber, + // playIndex: index + // } + // uni.setStorageSync("playInfo", playInfo) + // uni.navigateTo({ + // url: `/pages/video/video-play?authorId=${this.query.authorId}&videoFrom=collect` + // }) + // }, + + // 鍙栨秷鏀惰棌 + handleCancelCollection(item, type, index) { + uni.showModal({ + title: '鎻愮ず', + content: '纭畾瑕佸彇娑堟敹钘忓悧锛�', + success: (res) => { + if (res.confirm) { + changeCollect({ + collectType: type, + refId: item.id + }).then(res => { + if (res.data.code === 200) { + uni.showToast({ + title: res.data.msg, + icon: 'none' + }) + if (type === 'video') { + this.videoCollects.splice(index, 1) + } else { + this.query.pageNumber = 1 + this.noMore = false + this.loadData() + } + } + }) + } + } + }) }, - getPreviewUrl(params) { - // return getPreviewUrl(params); - return ''; - }, - // 鍒囨崲tab + + // 鍒囨崲鏍囩椤� switchTab(index) { - if (this.currentTab !== index) { this.currentTab = index - // 瀹為檯椤圭洰涓彲浠ュ湪杩欓噷娣诲姞鍔犺浇鏁版嵁鐨勯�昏緫 - if (this.currentTab === 0) { - //鍔犺浇瑙嗛鍒楄〃 - this.getMyCollectionVideoList(); - } else if (this.currentTab === 1) { - //鍔犺浇鍟嗗搧鍒楄〃 - this.getMyCollectionStoreList(); - } else if (this.currentTab === 2) { - //鍔犺浇娲诲姩鍒楄〃 - this.getMyCollectActivityList(); - } - + this.query.pageNumber = 1 + this.query.type = ['video', 'goods', 'activity'][index] + this.videoCollects = [] + this.goodsCollects = [] + this.activityCollects = [] + this.loadData() } + }, + // 鍔犺浇鏇村 + loadMore() { + if (!this.loading && !this.noMore) { + this.query.pageNumber += 1 + this.loadData() + } }, - getMyCollectionStoreList() { + + // 鍔犺浇鏁版嵁 + async loadData() { + if (this.loading) return + + this.loading = true uni.showLoading({ title: '鍔犺浇涓�' - }); - - uni.hideLoading(); - }, - getMyCollectionVideoList() { - uni.showLoading({ - title: '鍔犺浇涓�' - }); - - uni.hideLoading(); - }, - getMyCollectActivityList() { - uni.showLoading({ - title: '鍔犺浇涓�' - }); - - uni.hideLoading(); - }, + }) + + try { + getMyCollectList(this.query).then(res => { + if (res.data.code === 200) { + const newData = res.data.data + this.total = res.data.total || 0 + + // 鏍规嵁褰撳墠鏍囩椤垫洿鏂板搴旀暟鎹� + if (this.currentTab === 0) { + this.videoCollects = this.query.pageNumber === 1 ? + newData : + [...this.videoCollects, ...newData] + } else if (this.currentTab === 1) { + this.goodsCollects = this.query.pageNumber === 1 ? + newData : + [...this.goodsCollects, ...newData] + } else if (this.currentTab === 2) { + this.activityCollects = this.query.pageNumber === 1 ? + newData : + [...this.activityCollects, ...newData] + } + + this.noMore = newData.length < this.query.pageSize || + (this.currentTab === 0 ? this.videoCollects : + this.currentTab === 1 ? this.goodsCollects : this.activityCollects) + .length >= this.total + } + }); + + } catch (error) { + console.error(error) + uni.showToast({ + title: '鍔犺浇澶辫触', + icon: 'none' + }) + } finally { + this.loading = false + uni.hideLoading() + } + } } } </script> <style lang="scss"> - .activity-container { + .page-container { padding: 20rpx; background-color: #f5f5f5; min-height: 100vh; } - /* Tab 瀵艰埅鏍峰紡 */ .tab-nav { display: flex; background-color: #fff; border-radius: 12rpx; margin-bottom: 20rpx; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); - } - .tab-item { - flex: 1; - text-align: center; - padding: 24rpx 0; - font-size: 28rpx; - color: #666; - position: relative; + .tab-item { + flex: 1; + text-align: center; + padding: 24rpx 0; + font-size: 28rpx; + color: #666; + position: relative; - &.active { - color: #007AFF; - font-weight: bold; + &.active { + color: #007AFF; + font-weight: bold; - &::after { - content: ''; - position: absolute; - bottom: 0; - left: 50%; - transform: translateX(-50%); - width: 80rpx; - height: 6rpx; - background-color: #007AFF; - border-radius: 3rpx; + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 80rpx; + height: 6rpx; + background-color: #007AFF; + border-radius: 3rpx; + } } } } - /* 娲诲姩鍒楄〃鏍峰紡 */ - .activity-list { + .list-container { background-color: #fff; border-radius: 12rpx; padding: 20rpx; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); + + .scroll-view { + height: calc(100vh - 200rpx); + } } - .activity-item { + .collect-item { display: flex; - padding: 20rpx 0; - border-bottom: 1rpx solid #eee; + padding: 24rpx 0; + border-bottom: 1rpx solid #f5f5f5; + align-items: center; &:last-child { border-bottom: none; } } - .activity-cover { - width: 200rpx; - height: 140rpx; - border-radius: 8rpx; - margin-right: 20rpx; - } - - .activity-info { - flex: 1; + .cover-container { position: relative; - } - - .activity-title { - font-size: 32rpx; - color: #333; - font-weight: bold; - margin-bottom: 12rpx; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; + width: 250rpx; + height: 180rpx; + border-radius: 12rpx; overflow: hidden; - } + margin-right: 24rpx; + flex-shrink: 0; - .activity-meta { - font-size: 24rpx; - color: #999; - margin-bottom: 16rpx; + .cover-image { + width: 100%; + height: 100%; + } - text { - display: block; - margin-bottom: 8rpx; + .text-cover { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); + color: #fff; + font-size: 28rpx; + padding: 16rpx; + line-height: 1.4; + } + + .play-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + opacity: 0.9; + } + + .duration { + position: absolute; + right: 8rpx; + bottom: 8rpx; + background: rgba(0, 0, 0, 0.6); + color: #fff; + font-size: 20rpx; + padding: 4rpx 12rpx; + border-radius: 20rpx; } } - .activity-status { - position: absolute; - right: 0; - top: 0; - font-size: 24rpx; - padding: 4rpx 12rpx; - border-radius: 20rpx; + .info-container { + flex: 1; + height: 160rpx; + display: flex; + flex-direction: column; + justify-content: space-between; - &.signed { - color: #007AFF; - background-color: rgba(0, 122, 255, 0.1); + .title { + font-size: 30rpx; + color: #333; + font-weight: bold; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; } - &.ended { - color: #999; - background-color: rgba(153, 153, 153, 0.1); - } + .meta { + display: flex; + flex-wrap: wrap; - &.canceled { - color: #ff3b30; - background-color: rgba(255, 59, 48, 0.1); + .meta-item { + display: flex; + align-items: center; + margin-right: 20rpx; + font-size: 24rpx; + color: #999; + } } } - /* 绌虹姸鎬佹彁绀� */ + .action-container { + margin-left: 20rpx; + flex-shrink: 0; + + .cancel-btn { + background: #f5f5f5; + color: #666; + border: none; + font-size: 24rpx; + padding: 8rpx 20rpx; + border-radius: 20rpx; + + &:active { + background: #eee; + } + } + } + .empty-tip { text-align: center; padding: 100rpx 0; image { width: 300rpx; + height: 300rpx; margin-bottom: 30rpx; opacity: 0.6; } @@ -336,4 +514,8 @@ color: #999; } } + + .load-more { + padding: 20rpx 0; + } </style> \ No newline at end of file -- Gitblit v1.8.0