diff --git a/manifest.json b/manifest.json index dc76de1..2f63bb3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name" : "瀚海回收", - "appid" : "", + "appid" : "__UNI__197A38F", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", diff --git a/pages/component/recycle copy.vue b/pages/component/recycle copy.vue new file mode 100644 index 0000000..134e98e --- /dev/null +++ b/pages/component/recycle copy.vue @@ -0,0 +1,1927 @@ + + + + + \ No newline at end of file diff --git a/pages/component/recycle.vue b/pages/component/recycle.vue index 60504b6..a3dd7bc 100644 --- a/pages/component/recycle.vue +++ b/pages/component/recycle.vue @@ -52,8 +52,8 @@ {{item.name}} - - + + 查看品牌 @@ -74,7 +74,7 @@ - {{item.quantity || 0}} + {{getItemTotalQuantity(item)}} @@ -133,11 +133,12 @@ 已选商品明细 - + {{item.name}} - {{2222}} + 品牌:{{item.brandName}} + {{item.service}} ¥{{item.price}}/件 @@ -290,6 +291,22 @@ + + + + + + 关闭 + 选择要减少的品牌 + + + + + {{brand.name}} + + + + @@ -330,6 +347,10 @@ export default { pendingBrandIndex: null, // 记录待加一的品牌商品index showPriceInfoPopup: false, isWaitingForBrandSelection: false, // 等待品牌选择的标志 + showBrandReducePopup: false, // 显示减少数量时的品牌选择弹窗 + reduceItem: null, // 待减少数量的商品 + reduceBrandList: [], // 可减少的品牌列表 + viewedRuleItems: new Set(), // 已查看过规则的商品ID集合 } }, computed: { @@ -341,13 +362,29 @@ export default { // 计算总数量 totalCount() { return Object.values(this.allProducts).reduce((total, categoryItems) => { - return total + categoryItems.reduce((sum, item) => sum + (item.quantity || 0), 0) + return total + categoryItems.reduce((sum, item) => { + // 如果商品有品牌数量,汇总所有品牌的数量 + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 0) { + return sum + Object.values(item.brandQuantities).reduce((brandSum, qty) => brandSum + qty, 0) + } + // 否则使用原来的quantity字段 + return sum + (item.quantity || 0) + }, 0) }, 0) }, // 计算总价格 totalPrice() { const total = Object.values(this.allProducts).reduce((categoryTotal, categoryItems) => { - return categoryTotal + categoryItems.reduce((sum, item) => sum + (item.quantity || 0) * Number(item.price), 0) + return categoryTotal + categoryItems.reduce((sum, item) => { + let itemQuantity = 0 + // 如果商品有品牌数量,汇总所有品牌的数量 + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 0) { + itemQuantity = Object.values(item.brandQuantities).reduce((brandSum, qty) => brandSum + qty, 0) + } else { + itemQuantity = item.quantity || 0 + } + return sum + itemQuantity * Number(item.price) + }, 0) }, 0) return total.toFixed(1) }, @@ -365,8 +402,33 @@ export default { return { min, max } }, selectedProducts() { - // 返回所有分类下所有已选商品 - return Object.values(this.allProducts).flat().filter(item => item.quantity > 0) + // 返回所有分类下所有已选商品,按品牌分组 + const products = [] + Object.values(this.allProducts).flat().forEach(item => { + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 0) { + // 按品牌分别添加 + Object.entries(item.brandQuantities).forEach(([brandId, quantity]) => { + if (quantity > 0) { + const brandInfo = this.getBrandInfo(brandId) + products.push({ + ...item, + quantity: quantity, + brandId: brandId, + brandName: brandInfo ? brandInfo.name : '未知品牌', + brandImage: brandInfo ? brandInfo.image : '', + uniqueKey: `${item.id}_${brandId}` // 用于区分同商品不同品牌 + }) + } + }) + } else if (item.quantity > 0) { + // 没有品牌的商品 + products.push({ + ...item, + uniqueKey: item.id + }) + } + }) + return products }, filteredBrandList() { if (!this.brandSearch) return this.brandList @@ -428,7 +490,12 @@ export default { getCategoryItemCount(index) { const categoryId = this.categories[index]?.id const categoryItems = this.allProducts[categoryId] || [] - return categoryItems.reduce((sum, item) => sum + (item.quantity || 0), 0) + return categoryItems.reduce((sum, item) => { + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 0) { + return sum + Object.values(item.brandQuantities).reduce((brandSum, qty) => brandSum + qty, 0) + } + return sum + (item.quantity || 0) + }, 0) }, // 切换分类 switchCategory(index) { @@ -446,19 +513,100 @@ export default { const categoryId = this.categories[this.currentCategory]?.id const item = this.allProducts[categoryId]?.[index] if (!item) return + + // 如果是减少数量且delta为负数 + if (delta < 0) { + // 检查是否有多个品牌 + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 1) { + // 有多个品牌,显示选择弹窗 + this.reduceItem = { item, index, delta } + this.reduceBrandList = Object.entries(item.brandQuantities) + .filter(([brandId, quantity]) => quantity > 0) + .map(([brandId, quantity]) => { + const brandInfo = this.getBrandInfo(brandId) + return { + brandId, + quantity, + name: brandInfo ? brandInfo.name : '未知品牌', + image: brandInfo ? brandInfo.image : '' + } + }) + this.showBrandReducePopup = true + return + } else if (item.brandQuantities && Object.keys(item.brandQuantities).length === 1) { + // 只有一个品牌,直接减少 + const brandId = Object.keys(item.brandQuantities)[0] + const currentQty = item.brandQuantities[brandId] || 0 + const newQty = Math.max(0, currentQty + delta) + this.$set(item.brandQuantities, brandId, newQty) + + // 如果数量为0,删除该品牌 + if (newQty === 0) { + this.$delete(item.brandQuantities, brandId) + } + return + } else { + // 没有品牌数量,使用原来的逻辑 + let newQuantity = (item.quantity || 0) + delta + if (newQuantity < 0) newQuantity = 0 + this.$set(item, 'quantity', newQuantity) + return + } + } + // 品牌商品且数量为0且加一时 - if (item.isPin === 'Y' && (item.quantity || 0) === 0 && delta > 0) { + if ((item.quantity || 0) === 0 && delta > 0) { this.pendingBrandIndex = index this.isWaitingForBrandSelection = true; this.showRules(item); // 先显示回收规则 return } - let newQuantity = (item.quantity || 0) + delta - if (newQuantity < 0) newQuantity = 0 - this.$set(item, 'quantity', newQuantity) + + }, + // 选择要减少的品牌 + selectReduceBrand(brandInfo) { + const { item, index, delta } = this.reduceItem + const currentQty = item.brandQuantities[brandInfo.brandId] || 0 + const newQty = Math.max(0, currentQty + delta) + + this.$set(item.brandQuantities, brandInfo.brandId, newQty) + + // 如果数量为0,删除该品牌 + if (newQty === 0) { + this.$delete(item.brandQuantities, brandInfo.brandId) + } + + this.closeBrandReducePopup() + }, + + // 关闭减少品牌选择弹窗 + closeBrandReducePopup() { + this.showBrandReducePopup = false + this.reduceItem = null + this.reduceBrandList = [] + }, + // 获取品牌信息 + getBrandInfo(brandId) { + return this.brandList.find(brand => brand.id === brandId) + }, + // 获取商品的总数量(所有品牌) + getItemTotalQuantity(item) { + if (item.brandQuantities && Object.keys(item.brandQuantities).length > 0) { + return Object.values(item.brandQuantities).reduce((sum, qty) => sum + qty, 0) + } + return item.quantity || 0 }, // 显示回收规则 showRules(item) { + // 检查该商品是否已经查看过规则 + if (this.viewedRuleItems.has(item.id)) { + // 如果已经查看过,直接跳过规则弹窗,进入品牌选择 + this.isWaitingForBrandSelection = false; + this.getGoodsBrandList(item.id); + this.showBrandPopup = true; + return; + } + // 获取回收规则富文本 this.$api('getGoodsRecycleRule', { goodsId: item.id }, res => { if (res.code === 200 && res.result) { @@ -466,7 +614,7 @@ export default { } else { this.ruleHtml = '

暂无回收规则

' } - this.showRulePopup = true + this.showRulePopup = true }) }, showMore() { @@ -511,14 +659,25 @@ export default { }, goToPickup() { // 获取所有选中的衣物(所有分类) - const selectedItems = this.selectedProducts.map(item => ({ - id: item.id, - name: item.name, - icon: item.image, - quantity: item.quantity, - unitPrice: item.price, - desc: '允许脏破烂,160码以上' - })) + const selectedItems = this.selectedProducts.map(item => { + const baseItem = { + id: item.id, + name: item.name, + icon: item.image, + quantity: item.quantity, + unitPrice: item.price, + desc: item.brandName ? `品牌:${item.brandName}` : '允许脏破烂,160码以上' + } + + // 如果有品牌信息,添加品牌相关字段 + if (item.brandId) { + baseItem.brandId = item.brandId + baseItem.brandName = item.brandName + baseItem.brandImage = item.brandImage + } + + return baseItem + }) const itemsStr = encodeURIComponent(JSON.stringify(selectedItems)) uni.navigateTo({ url: `/pages/subcomponent/pickup?fromRecycle=true&items=${itemsStr}` @@ -527,10 +686,10 @@ export default { checkBrand(index) { const categoryId = this.categories[this.currentCategory]?.id const item = this.allProducts[categoryId]?.[index] - if (item?.shopCion) { + if (item?.id) { this.pendingBrandIndex = index - this.getGoodsBrandList(item.shopCion) - this.showBrandPopup = true + this.getGoodsBrandList(item.id) + this.showBrandPopup = true } }, closeBrandPopup() { @@ -552,8 +711,13 @@ export default { Object.values(this.allProducts).forEach(categoryItems => { categoryItems.forEach(item => { item.quantity = 0 + if (item.brandQuantities) { + item.brandQuantities = {} + } }) }) + // 清空已查看规则的记录 + this.viewedRuleItems.clear() // 模拟网络请求延迟 await new Promise(resolve => setTimeout(resolve, 1000)) @@ -576,10 +740,44 @@ export default { this.showDetailPanel = !this.showDetailPanel }, updateQuantityByProduct(item, delta) { - if (!item.quantity) item.quantity = 0 - item.quantity += delta - if (item.quantity < 0) item.quantity = 0 - this.updateTotal() + // 在明细弹窗中更新数量 + if (item.brandId) { + // 有品牌ID的商品 + const originalItem = this.findOriginalItem(item.id) + if (originalItem && originalItem.brandQuantities) { + const currentQty = originalItem.brandQuantities[item.brandId] || 0 + const newQty = Math.max(0, currentQty + delta) + this.$set(originalItem.brandQuantities, item.brandId, newQty) + + // 如果数量为0,删除该品牌 + if (newQty === 0) { + this.$delete(originalItem.brandQuantities, item.brandId) + } + + // 同步更新显示的数量 + item.quantity = newQty + } + } else { + // 没有品牌的商品 + if (!item.quantity) item.quantity = 0 + item.quantity += delta + if (item.quantity < 0) item.quantity = 0 + + // 同步到原商品 + const originalItem = this.findOriginalItem(item.id) + if (originalItem) { + this.$set(originalItem, 'quantity', item.quantity) + } + } + }, + + // 查找原始商品对象 + findOriginalItem(itemId) { + for (const categoryItems of Object.values(this.allProducts)) { + const item = categoryItems.find(i => i.id === itemId) + if (item) return item + } + return null }, openRulePopup() { this.showRulePopup = true @@ -591,13 +789,12 @@ export default { this.isWaitingForBrandSelection = false; // 清除等待状态 const categoryId = this.categories[this.currentCategory]?.id; const item = this.allProducts[categoryId]?.[this.pendingBrandIndex]; - if (item?.isPin === 'Y') { - this.getGoodsBrandList(item.shopCion); - this.showBrandPopup = true; // 打开品牌索引弹窗 - } else { - // 如果商品不是品牌商品,或者出现意外情况,重置状态 - this.pendingBrandIndex = null; - } + + // 记录该商品的规则已被查看 + this.viewedRuleItems.add(item.id); + + this.getGoodsBrandList(item.id); + this.showBrandPopup = true; // 打开品牌索引弹窗 } }, loadMoreGoods() { @@ -639,14 +836,25 @@ export default { const categoryId = this.categories[this.currentCategory]?.id const item = this.allProducts[categoryId]?.[this.pendingBrandIndex] if (item) { - this.$set(item, 'quantity', 1) - this.$set(item, 'pinId', this.brandConfirmInfo.id); + // 初始化品牌数量对象 + if (!item.brandQuantities) { + this.$set(item, 'brandQuantities', {}) + } + + // 增加该品牌的数量 + const currentQty = item.brandQuantities[this.brandConfirmInfo.id] || 0 + this.$set(item.brandQuantities, this.brandConfirmInfo.id, currentQty + 1) + + // 清除原来的quantity(如果存在) + if (item.quantity) { + this.$set(item, 'quantity', 0) + } } this.pendingBrandIndex = null } }, - getGoodsBrandList(iconId) { - this.$api('getGoodsBrandList', { iconId }, res => { + getGoodsBrandList(productId) { + this.$api('getGoodsBrandList', { productId }, res => { // console.log(res,'res') if (res && res.success && res.result && res.result.records) { this.brandList = res.result.records.map(item => { @@ -725,8 +933,13 @@ export default { Object.values(this.allProducts).forEach(categoryItems => { categoryItems.forEach(item => { this.$set(item, 'quantity', 0) + if (item.brandQuantities) { + this.$set(item, 'brandQuantities', {}) + } }) }) + // 清空已查看规则的记录 + this.viewedRuleItems.clear() this.showDetailPanel = false this.$forceUpdate() getApp().globalData.shouldClearRecycle = false @@ -764,8 +977,13 @@ export default { Object.values(this.allProducts).forEach(categoryItems => { categoryItems.forEach(item => { this.$set(item, 'quantity', 0) + if (item.brandQuantities) { + this.$set(item, 'brandQuantities', {}) + } }) }) + // 清空已查看规则的记录 + this.viewedRuleItems.clear() this.showDetailPanel = false this.$forceUpdate() getApp().globalData.shouldClearRecycle = false @@ -776,8 +994,13 @@ export default { Object.values(this.allProducts).forEach(categoryItems => { categoryItems.forEach(item => { this.$set(item, 'quantity', 0) + if (item.brandQuantities) { + this.$set(item, 'brandQuantities', {}) + } }) }) + // 清空已查看规则的记录 + this.viewedRuleItems.clear() // 重置其他相关数据 this.showDetailPanel = false this.$forceUpdate() @@ -1923,4 +2146,79 @@ export default { } } } + +/* 减少数量时的品牌选择弹窗 */ +.brand-reduce-popup-mask { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: rgba(0,0,0,0.35); + z-index: 5001; + display: flex; + align-items: center; + justify-content: center; +} +.brand-reduce-popup { + width: 70vw; + max-width: 270px; + background: #fff; + border-radius: 32rpx; + box-shadow: 0 8rpx 32rpx rgba(0,0,0,0.12); + display: flex; + flex-direction: column; + align-items: center; + padding: 48rpx 20rpx 36rpx 20rpx; + position: relative; +} +.brand-reduce-popup-header { + display: flex; + align-items: center; + justify-content: center; + padding: 32rpx 24rpx 0 24rpx; + font-size: 32rpx; + font-weight: bold; + position: relative; +} +.brand-reduce-popup-close { + position: absolute; + left: 24rpx; + font-size: 28rpx; + color: #888; +} +.brand-reduce-popup-title { + font-size: 32rpx; + color: #222; + font-weight: bold; +} +.brand-reduce-popup-list { + flex: 1; + overflow-y: auto; + max-height: 60vh; + padding: 0 24rpx; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + &::-webkit-scrollbar { + width: 0 !important; + display: none; /* Chrome, Safari, Opera */ + } +} +.brand-item { + display: flex; + align-items: center; + padding: 16rpx 0; + border-bottom: 1px solid #f0f0f0; +} +.brand-logo { + width: 60rpx; + height: 60rpx; + margin-right: 20rpx; + border-radius: 8rpx; + background: #f8f8f8; +} +.brand-name { + font-size: 28rpx; + color: #222; +} \ No newline at end of file diff --git a/pages/subcomponent/pickup.vue b/pages/subcomponent/pickup.vue index a800e1d..f7e8b5d 100644 --- a/pages/subcomponent/pickup.vue +++ b/pages/subcomponent/pickup.vue @@ -55,9 +55,15 @@ 订单详情 - + + + + - {{ item.name }} + + {{ item.name }} + {{ item.brandName }} + {{ item.desc }} ¥{{ item.unitPrice }}/件 @@ -324,7 +330,10 @@ export default { shopId: item.id, num: item.quantity }; - if (item.pinId) { + // 如果有品牌ID,添加到订单项中 + if (item.brandId) { + orderItem.pinId = item.brandId; + } else if (item.pinId) { orderItem.pinId = item.pinId; } return orderItem; @@ -604,14 +613,51 @@ export default { padding: 0 30rpx; .order-item { display: flex; - align-items: center; + align-items: flex-start; padding: 30rpx 0; border-bottom: 1rpx solid #f5f5f5; &:last-child { border-bottom: none; } - image { width: 80rpx; height: 80rpx; margin-right: 20rpx; } + .item-left { + position: relative; + margin-right: 20rpx; + image { + width: 80rpx; + height: 80rpx; + border-radius: 8rpx; + } + .brand-logo { + position: absolute; + bottom: -8rpx; + right: -8rpx; + width: 32rpx; + height: 32rpx; + border-radius: 50%; + border: 2rpx solid #fff; + background: #fff; + } + } .item-info { flex: 1; - .name { font-size: 30rpx; color: #333; font-weight: 500; } + .name-brand-row { + display: flex; + align-items: center; + flex-wrap: wrap; + margin-bottom: 4rpx; + .name { + font-size: 30rpx; + color: #333; + font-weight: 500; + margin-right: 12rpx; + } + .brand-tag { + background: #FFE8CC; + color: #FF9500; + font-size: 20rpx; + padding: 4rpx 8rpx; + border-radius: 8rpx; + border: 1rpx solid #FFD4A0; + } + } .desc { font-size: 24rpx; color: #999; margin: 4rpx 0 8rpx 0; } .price-row { display: flex;