From 21118ce6f947ac458b7a3ffe544b8db8482d8f5e Mon Sep 17 00:00:00 2001 From: tsui110 Date: Tue, 30 Dec 2025 10:03:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E5=8F=91=E8=B4=A7?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E9=BB=98=E8=AE=A4=E5=9C=B0=E5=9D=80=E4=B8=8D?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E4=BA=86=E5=95=86=E5=9F=8E=E9=A1=B5=E9=9D=A2=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=80=BB=E8=BE=91=EF=BC=8C=E4=B8=8D=E5=86=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=A7=A6=E5=BA=95=E5=8A=A0=E8=BD=BD=E6=96=B0=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=EF=BC=8C=E8=80=8C=E6=98=AF=E4=B8=80=E6=AC=A1=E6=80=A7?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=89=80=E6=9C=89=E5=95=86=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/cabinet/index.vue | 34 ++++++- pages/shop/index.vue | 208 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 222 insertions(+), 20 deletions(-) diff --git a/pages/cabinet/index.vue b/pages/cabinet/index.vue index 5757d7c..1503d24 100644 --- a/pages/cabinet/index.vue +++ b/pages/cabinet/index.vue @@ -606,10 +606,10 @@ async function onShip() { vibrateShort() const user_id = uni.getStorageSync('user_id') if (!user_id) return - + const selectedItems = aggregatedList.value.filter(item => item.selected) if (selectedItems.length === 0) return - + // 收集所有需要发货的 inventory id let allIds = [] selectedItems.forEach(item => { @@ -618,13 +618,39 @@ async function onShip() { allIds.push(...idsToShip) } }) - + if (allIds.length === 0) { uni.showToast({ title: '选择无效', icon: 'none' }) return } - // 2. 确认发货 + // 1. 先检查是否有默认地址 + try { + const addresses = await listAddresses(user_id) + const addressList = addresses.list || addresses.data || addresses || [] + + if (!addressList || addressList.length === 0) { + // 没有默认地址,提示用户跳转到新建地址页面 + uni.showModal({ + title: '提示', + content: '申请发货需要设置默认地址,是否前往新建地址?', + confirmText: '前往', + cancelText: '取消', + success: (res) => { + if (res.confirm) { + uni.navigateTo({ url: '/pages-user/address/edit' }) + } + } + }) + return + } + } catch (e) { + console.error('获取地址列表失败:', e) + uni.showToast({ title: '获取地址失败', icon: 'none' }) + return + } + + // 2. 有默认地址,确认发货 uni.showModal({ title: '确认发货', content: `共 ${allIds.length} 件物品,确认申请发货?`, diff --git a/pages/shop/index.vue b/pages/shop/index.vue index 0bdde1a..6495e29 100644 --- a/pages/shop/index.vue +++ b/pages/shop/index.vue @@ -11,12 +11,49 @@ + + + + 价格区间: + + + - + + + 筛选 + 重置 + + + + {{ range.label }} + + + + - @@ -122,6 +159,19 @@ const page = ref(1) const pageSize = 20 const hasMore = ref(true) +// 价格筛选相关 +const priceMin = ref('') +const priceMax = ref('') +const priceRanges = [ + { key: 'all', label: '全部', min: null, max: null }, + { key: '0-100', label: '0-100', min: 0, max: 100 }, + { key: '100-500', label: '100-500', min: 100, max: 500 }, + { key: '500-1000', label: '500-1K', min: 500, max: 1000 }, + { key: '1000-5000', label: '1K-5K', min: 1000, max: 5000 }, + { key: '5000+', label: '5K+', min: 5000, max: null } +] +const activePriceRange = ref('all') + const tabs = [ { id: 'product', name: '商品' }, { id: 'coupon', name: '优惠券' }, @@ -163,25 +213,34 @@ function switchTab(id) { } async function loadItems(append = false) { - if (loading.value && append) return + if (loading.value) return loading.value = true try { const res = await getStoreItems(currentTab.value, page.value, pageSize) const list = res.list || res || [] + const total = res.total || 0 const newItems = normalizeItems(list, currentTab.value) - + if (append) { allItems.value = [...allItems.value, ...newItems] } else { allItems.value = newItems } - - if (newItems.length < pageSize) { - hasMore.value = false - } else { + + // 根据返回的total计算总页数 + const totalPages = Math.ceil(total / pageSize) + + // 如果当前页小于总页数,继续加载下一页 + if (page.value < totalPages) { page.value++ + // 递归加载下一页 + loading.value = false // 临时释放loading状态,允许递归调用 + await loadItems(true) + } else { + // 所有数据加载完成 + hasMore.value = false } - + applyFilters() } catch (e) { console.error(e) @@ -193,12 +252,59 @@ async function loadItems(append = false) { function applyFilters() { const k = String(keyword.value || '').trim().toLowerCase() + const minPrice = priceMin.value !== '' ? parseFloat(priceMin.value) : null + const maxPrice = priceMax.value !== '' ? parseFloat(priceMax.value) : null + items.value = allItems.value.filter(item => { + // 关键词筛选 const title = String(item.title || '').toLowerCase() - return !k || title.includes(k) + const matchKeyword = !k || title.includes(k) + + // 价格筛选 + const itemPrice = item.points || 0 + let matchPrice = true + if (minPrice !== null) { + matchPrice = matchPrice && itemPrice >= minPrice + } + if (maxPrice !== null) { + matchPrice = matchPrice && itemPrice <= maxPrice + } + + return matchKeyword && matchPrice }) } +function applyPriceFilter() { + activePriceRange.value = 'custom' + applyFilters() +} + +function resetPriceFilter() { + priceMin.value = '' + priceMax.value = '' + activePriceRange.value = 'all' + applyFilters() +} + +function selectQuickPrice(range) { + activePriceRange.value = range.key + if (range.min !== null) { + priceMin.value = range.min.toString() + } else { + priceMin.value = '' + } + if (range.max !== null) { + priceMax.value = range.max.toString() + } else { + priceMax.value = '' + } + applyFilters() +} + +function isRangeActive(range) { + return activePriceRange.value === range.key +} + function onSearchConfirm() { applyFilters() } function onProductTap(p) { @@ -269,9 +375,7 @@ onShow(() => { }) onReachBottom(() => { - if (!loading.value && hasMore.value) { - loadItems(true) - } + // 所有数据已在页面加载时一次性请求完成,无需触底加载 }) watch(keyword, () => applyFilters()) @@ -297,7 +401,7 @@ watch(keyword, () => applyFilters()) padding: 20rpx 24rpx 0; box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.05); } -.header-placeholder { height: 180rpx; } +.header-placeholder { height: 340rpx; } .search-box { margin-bottom: 20rpx; } .search-input-wrap { @@ -310,6 +414,78 @@ watch(keyword, () => applyFilters()) .search-input { flex: 1; font-size: 26rpx; color: $text-main; } .placeholder-style { color: $text-tertiary; } +/* 价格筛选 */ +.filter-section { + margin-bottom: 16rpx; + padding: 16rpx; + background: rgba(255, 255, 255, 0.6); + border-radius: $radius-md; +} +.filter-row { + display: flex; + align-items: center; + margin-bottom: 12rpx; +} +.filter-label { + font-size: 24rpx; + color: $text-secondary; + white-space: nowrap; + margin-right: 12rpx; +} +.price-inputs { + flex: 1; + display: flex; + align-items: center; + gap: 8rpx; +} +.price-input { + flex: 1; + height: 56rpx; + background: rgba(0, 0, 0, 0.04); + border-radius: $radius-sm; + padding: 0 16rpx; + font-size: 24rpx; + color: $text-main; + text-align: center; +} +.input-placeholder { color: $text-tertiary; } +.price-separator { + font-size: 24rpx; + color: $text-tertiary; + padding: 0 4rpx; +} +.filter-btn { + padding: 12rpx 20rpx; + background: $gradient-brand; + color: #fff; + font-size: 24rpx; + border-radius: $radius-round; + margin-left: 12rpx; + white-space: nowrap; + &.reset { + background: rgba(0, 0, 0, 0.06); + color: $text-secondary; + } +} +.quick-prices { + display: flex; + flex-wrap: wrap; + gap: 12rpx; +} +.quick-price-tag { + padding: 8rpx 20rpx; + background: rgba(0, 0, 0, 0.04); + border-radius: $radius-round; + font-size: 22rpx; + color: $text-secondary; + transition: all 0.2s; + &.active { + background: $gradient-brand; + color: #fff; + font-weight: 600; + } +} + /* Tabs */ .tab-row { display: flex;