diff --git a/pages/index/index.vue b/pages/index/index.vue index ba20c73..5cebd48 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -39,6 +39,7 @@ :list="item.waresList" :title="item.specialAreaName" size="small" + :showSales="item.specialArea" > + + + + 库存剩余 + + + {{ getInventoryPercentage(goodDetail.inventory) }}% + + + + + + + + + @@ -75,7 +108,9 @@ >BV:{{ goodDetail.goodsAssAchive | numberToCurrency }} - 销量:{{ goodDetail.sales | seles }} + 销量:{{ goodDetail.sales | seles }} @@ -85,6 +120,39 @@ {{ goodDetail.waresName }} + + + + + + 库存剩余 + + + {{ getInventoryPercentage(goodDetail.inventory) }}% + + + + + + + + + {{ '急速下单即享优先发货' }} @@ -573,6 +641,45 @@ export default { // 作为返回值返回 return d + '天' + h + ':' + m + ':' + s }, + // 处理库存百分比,移除百分号并转换为数字 + getInventoryPercentage(inventory) { + if (typeof inventory === 'string') { + // 移除百分号并转换为数字 + const numStr = inventory.replace('%', '').trim() + const num = parseFloat(numStr) + return isNaN(num) ? 0 : Math.min(100, Math.max(0, num)) + } else if (typeof inventory === 'number') { + // 如果是数字,确保在0-100范围内 + return Math.min(100, Math.max(0, inventory)) + } + return 0 + }, + // 根据库存百分比返回对应的进度条样式类 + getProgressClass(inventory) { + const percentage = this.getInventoryPercentage(inventory) + if (percentage >= 80) { + return 'progress-high' + } else if (percentage >= 60) { + return 'progress-medium-high' + } else if (percentage >= 40) { + return 'progress-medium' + } else if (percentage >= 20) { + return 'progress-low' + } else { + return 'progress-critical' + } + }, + // 根据库存百分比返回百分比数字的样式类 + getPercentageClass(inventory) { + const percentage = this.getInventoryPercentage(inventory) + if (percentage <= 20) { + return 'percentage-critical' + } else if (percentage <= 30) { + return 'percentage-urgent' + } else { + return 'percentage-normal' + } + }, }, } @@ -970,4 +1077,194 @@ export default { justify-content: flex-end; margin-bottom: 10rpx; } + +/* 库存进度条样式 */ +.inventory-progress-container { + margin-top: 20rpx; + + .inventory-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12rpx; + + .inventory-label { + display: flex; + align-items: center; + font-size: 24rpx; + + .inventory-status { + color: #333; + } + } + + .inventory-percentage { + font-size: 24rpx; + font-weight: 700; + font-family: + DIN Alternate, + Arial, + sans-serif; + + &.percentage-critical { + color: #ff3742; + animation: percentageBlink 1s ease-in-out infinite; + text-shadow: 0 0 10rpx rgba(255, 55, 66, 0.3); + } + + &.percentage-urgent { + color: #ff5252; + animation: percentageGlow 2s ease-in-out infinite; + } + + &.percentage-normal { + color: #005bac; + } + } + } + + .inventory-progress-bar { + width: 100%; + height: 16rpx; + background: rgba(0, 0, 0, 0.08); + border-radius: 8rpx; + overflow: hidden; + position: relative; + box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.1); + + .inventory-progress-fill { + height: 100%; + border-radius: 8rpx; + transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; + + /* 进度条渐变色彩 */ + &.progress-critical { + background: linear-gradient( + 90deg, + #ff1744 0%, + #d50000 50%, + #ff1744 100% + ); + box-shadow: 0 0 20rpx rgba(255, 23, 68, 0.4); + animation: criticalPulse 1.5s ease-in-out infinite; + } + + &.progress-low { + background: linear-gradient( + 90deg, + #ff5722 0%, + #e64a19 50%, + #ff5722 100% + ); + box-shadow: 0 0 15rpx rgba(255, 87, 34, 0.3); + } + + &.progress-medium { + background: linear-gradient( + 90deg, + #ff9800 0%, + #f57c00 50%, + #ff9800 100% + ); + box-shadow: 0 0 10rpx rgba(255, 152, 0, 0.2); + } + + &.progress-medium-high { + background: linear-gradient( + 90deg, + #2196f3 0%, + #1976d2 50%, + #2196f3 100% + ); + box-shadow: 0 0 8rpx rgba(33, 150, 243, 0.2); + } + + &.progress-high { + background: linear-gradient( + 90deg, + #4caf50 0%, + #388e3c 25%, + #005bac 75%, + #003d82 100% + ); + box-shadow: 0 0 8rpx rgba(0, 91, 172, 0.2); + } + + /* 流动光效 */ + .progress-shine { + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + transparent 0%, + rgba(255, 255, 255, 0.8) 50%, + transparent 100% + ); + animation: shineFlow 2s ease-in-out infinite; + } + + /* 高光效果 */ + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 60%; + background: linear-gradient( + to bottom, + rgba(255, 255, 255, 0.4) 0%, + rgba(255, 255, 255, 0.1) 50%, + transparent 100% + ); + border-radius: 8rpx 8rpx 0 0; + } + } + } +} + +/* 动画定义 */ +@keyframes percentageBlink { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.7; + } +} + +@keyframes percentageGlow { + 0%, + 100% { + text-shadow: 0 0 5rpx rgba(255, 82, 82, 0.3); + } + 50% { + text-shadow: 0 0 15rpx rgba(255, 82, 82, 0.6); + } +} + +@keyframes criticalPulse { + 0%, + 100% { + box-shadow: 0 0 20rpx rgba(255, 23, 68, 0.4); + } + 50% { + box-shadow: 0 0 30rpx rgba(255, 23, 68, 0.7); + } +} + +@keyframes shineFlow { + 0% { + left: -100%; + } + 100% { + left: 100%; + } +} diff --git a/pages/specialArea/list.vue b/pages/specialArea/list.vue index 392fd8b..7f572f3 100644 --- a/pages/specialArea/list.vue +++ b/pages/specialArea/list.vue @@ -103,8 +103,42 @@ {{ item.prefixLabelTarget.label }} - {{ item.waresName }} + {{ item.waresName }} + + + + + + 库存剩余 + + + {{ getInventoryPercentage(item.inventory) }}% + + + + + + + + + +