From 9f90f0e288a2d50f1571e019a2918e7cb29ddb73 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Fri, 19 Jun 2026 15:10:55 +0800 Subject: [PATCH] 1 --- pages/index/index.vue | 288 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 264 insertions(+), 24 deletions(-) diff --git a/pages/index/index.vue b/pages/index/index.vue index fcb6a8a..a2ca615 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -10,7 +10,7 @@ :interval="interval" :duration="duration"> - + @@ -92,7 +92,7 @@ - @@ -101,7 +101,7 @@ - 团团星球 周边娱乐 @@ -109,7 +109,7 @@ - 跑腿星球 小事接力 @@ -118,7 +118,7 @@ 中奖啦 - 白嫖星球 抽点惊喜 @@ -128,7 +128,7 @@ {{ieUnreadCount > 99 ? '99+' : ieUnreadCount}} - i/e星球 思想漂流 @@ -173,7 +173,7 @@ - + 正在拼 @@ -192,7 +192,7 @@ - + 正在拼 @@ -222,7 +222,7 @@ - + 正在拼 @@ -241,7 +241,7 @@ - + 正在拼 @@ -588,10 +588,30 @@ import deLivery from "@/components/tab-bar/delivery.vue"; import postList from "@/components/tab-bar/postList.vue"; import myCenter from "@/components/tab-bar/myCenter.vue"; + + const HOME_AD_IMAGE_CACHE_KEY = 'home_ad_image_cache_v1' + const HOME_AD_IMAGE_CACHE_TTL = 30 * 24 * 60 * 60 * 1000 + const HOME_AD_IMAGE_CACHE_LIMIT = 40 + const homeAdImageDownloading = {} + const HOME_MENU_ICON_URLS = { + food: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/553230c20dea4e5c85f1e396058a7493.png', + store: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/28b5cfec79d74871b0ce67743fb7619c.png', + run: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/7690c4f897604fca804ea932bc3c1239.png', + luck: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/41cfb56caff4419b94b69d0f2303b602.png', + fish: 'https://jewel-shop.oss-cn-beijing.aliyuncs.com/a083b7d159264bbc967034088fa7eb3a.png' + } + export default { data() { return { adList:[], + homeMenuIconImages: { + food: '', + store: '', + run: '', + luck: '', + fish: '' + }, pages: [{ name: '商家账单详情111', url: '/package2/shop/shopSettlementDetail' @@ -710,6 +730,7 @@ markers: [], // 标记点,可以包括配送员位置和用户位置 polyline: [], // 路线,如果需要显示配送员路线 currentIndex: 0, + pendingTabIndex: null, width: 0, dataTabList: [{ name: '猜你喜欢', @@ -874,11 +895,23 @@ this.searchForm.pageNum++; this.getDelivery(); }, - onLoad() { - + onLoad(option) { + if (option && option.tabIndex !== undefined) { + const tabIndex = Number(option.tabIndex) + if (!isNaN(tabIndex) && tabIndex > 0) { + this.pendingTabIndex = tabIndex + } + } }, onShow() { this.indexInit() + if (this.pendingTabIndex !== null) { + const tabIndex = this.pendingTabIndex + this.pendingTabIndex = null + this.$nextTick(() => { + this.changeIndex(tabIndex) + }) + } }, onReady() { // 记录分类栏相对页面的偏移量,用于上滑检测 @@ -890,8 +923,24 @@ }, 500); }, methods: { + hasLogin() { + const token = uni.getStorageSync('hiver_token') + return !!(token && typeof token === 'string' && token.trim() && token !== 'null' && token !== 'undefined') + }, + requireLogin(tabIndex = this.currentIndex) { + if (this.hasLogin()) return true + const redirectKey = 'login_redirect_' + Date.now() + const index = Number(tabIndex) + const redirectUrl = '/pages/index/index' + (!isNaN(index) && index > 0 ? '?tabIndex=' + index : '') + uni.setStorageSync(redirectKey, redirectUrl) + uni.navigateTo({ + url: '/package2/login/login?redirect=' + redirectKey + }) + return false + }, indexInit() { let that = this + this.applyCachedHomeMenuIcons() uni.getSystemInfo({ success: function(info) { that.width = info.screenWidth * 2; @@ -987,6 +1036,7 @@ }, //滑动开始 startSwipeOrder(event, item, index) { + if (!this.requireLogin(0)) return const touch = event.touches && event.touches[0] if (!touch) return this.swipeOrder = { @@ -1018,6 +1068,10 @@ }, //滑动结束 endSwipeOrder(item, index) { + if (!this.requireLogin(0)) { + this.resetSwipeOrder() + return + } if (this.swipeOrder.id !== item.id || this.swipeOrder.index !== index) return if (this.swipeOrder.progress >= 92 && !this.swipeOrder.confirmed) { this.swipeOrder.confirmed = true @@ -1052,6 +1106,10 @@ this.$refs.pagesPopup.open() }, getOrder(item, index) { + if (!this.requireLogin(0)) { + this.resetSwipeOrder() + return + } let that = this let data = { @@ -1132,6 +1190,197 @@ uni.hideLoading(); }).catch((res) => {}); }, + normalizeAdImageUrl(url) { + if (!url) return '' + let normalized = String(url).trim() + while (normalized.endsWith(',')) { + normalized = normalized.slice(0, -1) + } + return normalized + }, + getHomeAdImageCache() { + const cache = uni.getStorageSync(HOME_AD_IMAGE_CACHE_KEY) + return cache && typeof cache === 'object' ? cache : {} + }, + saveHomeAdImageCache(cache) { + uni.setStorageSync(HOME_AD_IMAGE_CACHE_KEY, cache) + }, + isHomeAdImageCacheValid(cacheItem) { + return !!(cacheItem && cacheItem.path && Date.now() - Number(cacheItem.savedAt || 0) < HOME_AD_IMAGE_CACHE_TTL) + }, + applyCachedAdImages(mallAds) { + const cache = this.getHomeAdImageCache() + const activeUrls = Object.keys(HOME_MENU_ICON_URLS).map(key => HOME_MENU_ICON_URLS[key]) + mallAds.forEach((item) => { + const imageUrl = this.normalizeAdImageUrl(item.adImage) + item.adImage = imageUrl + item.adDisplayImage = '' + if (!/^https?:\/\//.test(imageUrl)) { + item.adDisplayImage = imageUrl + return + } + activeUrls.push(imageUrl) + const cacheItem = cache[imageUrl] + if (this.isHomeAdImageCacheValid(cacheItem)) { + item.adDisplayImage = cacheItem.path + return + } + this.cacheHomeAdImage(imageUrl) + }) + this.pruneHomeAdImageCache(cache, activeUrls) + }, + applyCachedHomeMenuIcons() { + const cache = this.getHomeAdImageCache() + Object.keys(HOME_MENU_ICON_URLS).forEach((key) => { + const imageUrl = HOME_MENU_ICON_URLS[key] + const cacheItem = cache[imageUrl] + if (this.isHomeAdImageCacheValid(cacheItem)) { + this.homeMenuIconImages[key] = cacheItem.path + return + } + this.homeMenuIconImages[key] = '' + this.cacheHomeMenuIcon(key, imageUrl) + }) + }, + cacheHomeMenuIcon(key, imageUrl) { + if (homeAdImageDownloading[imageUrl]) return + homeAdImageDownloading[imageUrl] = true + uni.downloadFile({ + url: imageUrl, + success: (downloadRes) => { + if (downloadRes.statusCode !== 200 || !downloadRes.tempFilePath) { + this.homeMenuIconImages[key] = imageUrl + delete homeAdImageDownloading[imageUrl] + return + } + this.homeMenuIconImages[key] = downloadRes.tempFilePath + uni.saveFile({ + tempFilePath: downloadRes.tempFilePath, + success: (saveRes) => { + const cache = this.getHomeAdImageCache() + const oldCacheItem = cache[imageUrl] + if (oldCacheItem && oldCacheItem.path && oldCacheItem.path !== saveRes.savedFilePath) { + uni.removeSavedFile({ + filePath: oldCacheItem.path, + fail: () => {} + }) + } + cache[imageUrl] = { + path: saveRes.savedFilePath, + savedAt: Date.now() + } + this.saveHomeAdImageCache(cache) + this.homeMenuIconImages[key] = saveRes.savedFilePath + }, + complete: () => { + delete homeAdImageDownloading[imageUrl] + } + }) + }, + fail: () => { + this.homeMenuIconImages[key] = imageUrl + delete homeAdImageDownloading[imageUrl] + }, + complete: (downloadRes) => { + if (!downloadRes || downloadRes.statusCode !== 200) { + this.homeMenuIconImages[key] = imageUrl + delete homeAdImageDownloading[imageUrl] + } + } + }) + }, + cacheHomeAdImage(imageUrl) { + if (homeAdImageDownloading[imageUrl]) return + homeAdImageDownloading[imageUrl] = true + uni.downloadFile({ + url: imageUrl, + success: (downloadRes) => { + if (downloadRes.statusCode !== 200 || !downloadRes.tempFilePath) { + this.replaceAdImageWithCache(imageUrl, imageUrl) + delete homeAdImageDownloading[imageUrl] + return + } + this.replaceAdImageWithCache(imageUrl, downloadRes.tempFilePath) + uni.saveFile({ + tempFilePath: downloadRes.tempFilePath, + success: (saveRes) => { + const cache = this.getHomeAdImageCache() + const oldCacheItem = cache[imageUrl] + if (oldCacheItem && oldCacheItem.path && oldCacheItem.path !== saveRes.savedFilePath) { + uni.removeSavedFile({ + filePath: oldCacheItem.path, + fail: () => {} + }) + } + cache[imageUrl] = { + path: saveRes.savedFilePath, + savedAt: Date.now() + } + this.saveHomeAdImageCache(cache) + this.replaceAdImageWithCache(imageUrl, saveRes.savedFilePath) + }, + complete: () => { + delete homeAdImageDownloading[imageUrl] + } + }) + }, + fail: () => { + delete homeAdImageDownloading[imageUrl] + }, + complete: (downloadRes) => { + if (!downloadRes || downloadRes.statusCode !== 200) { + this.replaceAdImageWithCache(imageUrl, imageUrl) + delete homeAdImageDownloading[imageUrl] + } + } + }) + }, + replaceAdImageWithCache(imageUrl, filePath) { + const replace = (list) => { + (list || []).forEach((item) => { + if (item.adImage === imageUrl) { + item.adDisplayImage = filePath + } + }) + } + replace(this.mallAds) + replace(this.adList) + this.$forceUpdate() + }, + pruneHomeAdImageCache(cache, activeUrls) { + const activeUrlMap = activeUrls.reduce((result, url) => { + result[url] = true + return result + }, {}) + const now = Date.now() + Object.keys(cache).forEach((url) => { + const item = cache[url] + const isExpired = !this.isHomeAdImageCacheValid(item) + if (isExpired && !activeUrlMap[url]) { + item && item.path && uni.removeSavedFile({ + filePath: item.path, + fail: () => {} + }) + delete cache[url] + } + }) + const urls = Object.keys(cache).sort((a, b) => Number(cache[a].savedAt || now) - Number(cache[b].savedAt || now)) + while (urls.length > HOME_AD_IMAGE_CACHE_LIMIT) { + const url = urls.shift() + if (activeUrlMap[url]) { + urls.push(url) + if (urls.every(itemUrl => activeUrlMap[itemUrl])) break + continue + } + const item = cache[url] + item && item.path && uni.removeSavedFile({ + filePath: item.path, + fail: () => {} + }) + delete cache[url] + } + this.saveHomeAdImageCache(cache) + }, getDelivery() { let that = this that.waimaiCount = 0 @@ -1144,21 +1393,11 @@ that.loadStatus = 'nomore'; if (res.code == 200) { that.homeReminders = res.result.homeReminders || {} - that.mallAds = res.result.mallAds + that.mallAds = res.result.mallAds || [] + that.applyCachedAdImages(that.mallAds) for(let i=0;i