web-base-h5/pages/specialArea/list.vue

1584 lines
38 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<backIcon :diff="diff"></backIcon>
<view class="index_header">
<view>{{ titLabel }}</view>
</view>
<!-- 分类抽屉按钮 -->
<view class="category-drawer-btn" @click="openCategoryDrawer">
<u-icon name="list" size="20" color="#005BAC"></u-icon>
<text>分类</text>
</view>
<view class="index_btm">
<view class="index_r full-width">
<view class="search">
<u--input
placeholder="请输入商品名称"
placeholderStyle="font-size:14px;"
prefixIcon="search"
shape="circle"
v-model="waresName"
border="none"
@confirm="getAllGoods1()"
prefixIconStyle="font-size: 22px;color: #909399"
></u--input>
</view>
<view class="goodList">
<!-- 空状态提示 -->
<view v-if="goodList.length === 0" class="empty-state">
<view class="empty-icon">
<u-icon :name="getEmptyIcon()" size="80" color="#d0d0d0"></u-icon>
</view>
<view class="empty-title">{{ getEmptyTitle() }}</view>
<view class="empty-desc">{{ getEmptyDesc() }}</view>
<view class="empty-tips">
<text v-for="(tip, index) in getEmptyTips()" :key="index">
{{ tip }}
</text>
</view>
<view class="empty-actions">
<view class="empty-action primary" @click="openCategoryDrawer">
<u-icon name="list" size="16" color="#ffffff"></u-icon>
<text>浏览分类</text>
</view>
<view
class="empty-action secondary"
@click="clearSearch"
v-if="waresName"
>
<u-icon name="close-circle" size="16" color="#005bac"></u-icon>
<text>清除搜索</text>
</view>
</view>
</view>
<!-- 商品列表 -->
<view
v-for="item in goodList"
:key="item.waresCode"
class="goodList_i"
@tap="goDetails(item)"
v-else
>
<view style="display: flex; flex: 1">
<view
class="fly"
v-show="
item.preSaleStatus == 3 ||
item.isSale == 1 ||
(item.specialArea === 14 && !Number(item.inventory))
"
></view>
<view class="image-container">
<img :src="item.cover || item.cover1" class="cover" alt="" />
<!-- 三角形角标 -->
<view class="triangle-badge" v-if="item.warnMessage">
<view
class="triangle-badge-text"
:class="{
'text-2': item.warnMessage.length === 2,
'text-3': item.warnMessage.length === 3,
'text-4': item.warnMessage.length === 4,
}"
>
{{ item.warnMessage }}
</view>
</view>
</view>
<view class="goodList_ir">
<view>
<view>
<span
class="qzbq"
v-if="item.prefixLabelTarget != undefined"
>{{ item.prefixLabelTarget.label }}</span
>
<span style="font-weight: 500">{{ item.waresName }}</span>
</view>
</view>
<view>
<view
class="inventory-progress-container"
v-if="
item.useRatio &&
item.inventory !== undefined &&
item.specialArea == 14
"
>
<view class="inventory-progress-bar">
<view
class="inventory-progress-fill"
:style="{
width: getInventoryPercentage(item.inventory) + '%',
}"
:class="getProgressClass(item.inventory)"
>
<!-- 添加流动光效 -->
<view
class="progress-shine"
v-if="getInventoryPercentage(item.inventory) <= 30"
></view>
</view>
</view>
<view
class="inventory-percentage"
:class="getPercentageClass(item.inventory)"
>
剩余{{ getInventoryPercentage(item.inventory) }}%
</view>
</view>
<view class="goodList_ib">
<view>
<view
class="pv"
v-if="
specialArea != 18 &&
specialArea != 13 &&
specialArea != 31 &&
specialArea != 10
"
>
业绩:{{ item.waresAchieve | numberToCurrency }}
</view>
<view class="pv" v-if="specialArea == 10">
积分可抵扣:{{ item.deductMoney | numberToCurrency }}
</view>
<view
class="pv"
v-if="specialArea == 31 && userInfo.isMakerSpace == 0"
>
业绩:{{ item.waresAchieve | numberToCurrency }}
</view>
<view class="pv" v-if="specialArea == 13">
BV:{{ item.assAchieve | numberToCurrency }}
</view>
<view
v-if="specialArea == 31 && userInfo.isMakerSpace == 1"
>
{{ item.vipPrice | numberToCurrency }}
</view>
<view
v-if="
(specialArea == 31 && userInfo.isMakerSpace == 0) ||
specialArea != 31
"
>
{{ item.waresPrice | numberToCurrency }}
</view>
</view>
<template v-if="item.specialArea !== 14">
<img
@click.stop="addCar(item)"
v-show="
item.preSaleStatus != 3 &&
item.isSale != 1 &&
specialArea != 31
"
src="@/static/images/cart.png"
alt=""
/>
</template>
<template v-else>
<img
@click.stop="addCar(item)"
v-show="
item.preSaleStatus != 3 &&
item.isSale != 1 &&
Number(item.inventory)
"
src="@/static/images/cart.png"
alt=""
/>
</template>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<u-picker
:show="isCountry"
@cancel="isCountry = false"
@confirm="sureCountry"
:columns="countryList"
keyName="label"
></u-picker>
<selSpaceGoods ref="selSpaceGoods" @getCar="getCatLength"></selSpaceGoods>
<cartBall
ref="cart"
:carLength="shopCarLength"
:specialArea="specialArea"
></cartBall>
<!-- 分类抽屉遮罩 -->
<view
class="drawer-mask"
:class="{ show: showCategoryDrawer }"
@click="closeCategoryDrawer"
v-if="showCategoryDrawer"
></view>
<!-- 分类抽屉 -->
<view class="category-drawer" :class="{ show: showCategoryDrawer }">
<view class="drawer-header">
<text class="drawer-title">商品分类</text>
<u-icon
name="close"
size="20"
color="#666"
@click="closeCategoryDrawer"
></u-icon>
</view>
<view class="drawer-content">
<view
v-for="item in oneList"
:key="item.pkId"
class="drawer-menu-group"
>
<!-- 一级分类 -->
<view
class="drawer-first-level"
:class="{ active: oneId == item.pkId }"
>
<view class="drawer-menu-text" @click="selectFirstLevel(item)">{{
truncateText(item.classifyName, 12)
}}</view>
<!-- <view
v-if="item.children && item.children.length > 0"
class="drawer-expand-icon"
:class="{ expanded: expandedMenus.includes(item.pkId) }"
@click="toggleExpand(item.pkId)"
>
<u-icon
name="arrow-right"
size="16"
:color="oneId == item.pkId ? '#fff' : '#666'"
></u-icon>
</view> -->
</view>
<view
class="drawer-second-level-container"
:class="{ expanded: expandedMenus.includes(item.pkId) }"
v-if="item.children && item.children.length > 0"
>
<view
v-for="subItem in item.children"
:key="subItem.pkId"
class="drawer-second-level"
:class="{ active: twoId == subItem.pkId }"
@click="selectSecondLevel(subItem)"
>
<view class="drawer-sub-menu-text">{{
truncateText(subItem.classifyName, 12)
}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import backIcon from '@/components/backIcon.vue'
import cartBall from '@/components/cartBall.vue'
import { mapGetters, mapActions } from 'vuex'
import * as api from '@/config/goods'
import clTabbar from '@/components/cl-tabbar.vue'
import selSpaceGoods from '@/components/selSpaceGoods.vue'
export default {
components: {
'cl-tabbar': clTabbar,
backIcon,
cartBall,
selSpaceGoods,
},
props: {
specialAreaProp: {
type: Number,
},
},
computed: {},
filters: {
seles(value) {
if (value > 999) {
return 999 + '+'
} else {
return value
}
},
},
data() {
return {
newShareMember: false,
specialArea: 1,
oneList: [],
oneId: '',
twoList: [],
twoId: '',
goodList: [],
titLabel: '',
itemChildren: [],
diff: 1,
shopCarLength: false,
userInfo: {},
pkCountry: 1,
pkCountryLabel: '',
pkCountryImg: '',
countryList: [],
isCountry: false,
waresName: '',
expandedMenus: [], // 存储展开的一级菜单ID
showCategoryDrawer: false, // 控制分类抽屉显示
}
},
onLoad(options) {
console.log(
'%c [ options ]-25',
'font-size:13px; background:#cb38d2; color:#ff7cff;',
options
)
if (JSON.parse(options.children).length > 0) {
let arr = []
if (options.childArea) {
this.specialArea = this.specialAreaProp || options.childArea
// this.diff = 1
} else {
JSON.parse(options.children).forEach(item => {
if (item.isShow) {
arr.push(item.value)
}
})
this.specialArea = arr[0]
// this.diff = 0
}
if (options.diff) {
this.diff = options.diff
}
} else {
this.specialArea = this.specialAreaProp || options.specialArea
}
this.titLabel = options.label
let tempArr = JSON.parse(options.children)
if (this.specialArea != 18) {
api.menuList().then(res => {
tempArr = tempArr.filter(item =>
res.data.find(ctem => ctem.menuKey == item.name)
)
this.itemChildren = tempArr
})
}
// 修改标题
uni.setNavigationBarTitle({
title: this.titLabel,
success: () => {},
})
// 获取一级分类并获取商品列表
// this.getClassIfy()
this.userInfo = uni.getStorageSync('User')
console.log(
'%c [ this.userInfo ]-242',
'font-size:13px; background:#cb38d2; color:#ff7cff;',
this.userInfo
)
if (this.specialArea == 1) {
if (uni.getStorageSync('pkCountry')) {
this.pkCountry = uni.getStorageSync('pkCountry')
} else {
this.pkCountry = this.userInfo.pkSettleCountry
uni.setStorageSync('pkCountry', this.pkCountry + '')
}
} else {
this.pkCountry = this.userInfo.pkSettleCountry
}
this.setSpecial({
value: this.specialArea,
})
},
onShow() {
this.newShareMember = uni.getStorageSync('User')?.loginType !== 0
// 确保抽屉是关闭的
this.showCategoryDrawer = false
let that = this
uni.$on('returnData', function (data) {
that.specialArea = data.value
that.setSpecial({
value: data.value,
})
})
// 获取国家
// this.getJScountry()
this.$nextTick(() => {
this.$refs.cart.getCar()
})
},
onHide() {
this.$refs.cart.close()
this.setSmallCarLength(0)
},
beforeDestroy() {
this.setSmallCarLength(0)
},
methods: {
...mapActions(['setSmallCarLength', 'setShopCarLength']),
getAllCategory() {
api
.getAllCategory({
specialArea: this.specialArea,
pkCountry: this.pkCountry,
})
.then(res => {
if (res.code === 200) {
const tempList = res.data || []
this.oneList = tempList.map(item => {
const children = item.children
if (children && children.length > 0) {
item.children = [
{ classifyName: '全部', pkId: item.pkId },
...children,
]
}
return {
...item,
}
})
// 默认全部展开
this.expandedMenus = this.oneList.map(item => item.pkId)
// 选择第一个分类
if (this.oneList[0]) {
this.oneId = this.oneList[0].pkId
this.twoId = this.oneList[0].pkId
this.getAllGoods(this.oneList[0].pkId)
}
}
})
},
truncateText(text, maxLength) {
if (!text) return ''
if (text.length <= maxLength) return text
return text.substring(0, maxLength) + '...'
},
// 选择一级分类(不影响展开状态)
selectFirstLevel(item) {
this.oneId = item.pkId
this.twoId = item.pkId
this.getAllGoods(item.pkId)
},
// 切换展开状态(不影响选择状态)
toggleExpand(pkId) {
const index = this.expandedMenus.indexOf(pkId)
if (index === -1) {
this.expandedMenus.push(pkId)
} else {
this.expandedMenus.splice(index, 1)
}
},
// 保留原方法以兼容其他地方的调用
toggleFirstLevel(item) {
this.selectFirstLevel(item)
},
// 选择二级分类
selectSecondLevel(item) {
this.twoId = item.pkId
this.getAllGoods1(item.pkId)
// 不自动关闭抽屉,让用户手动关闭
},
// 打开分类抽屉
openCategoryDrawer() {
this.showCategoryDrawer = true
},
// 关闭分类抽屉
closeCategoryDrawer() {
this.showCategoryDrawer = false
},
// 获取空状态图标
getEmptyIcon() {
if (this.waresName) {
return 'search'
}
return 'shopping-cart'
},
// 获取空状态标题
getEmptyTitle() {
if (this.waresName) {
return '未找到相关商品'
}
return '暂无商品'
},
// 获取空状态描述
getEmptyDesc() {
if (this.waresName) {
return `没有找到包含"${this.waresName}"的商品`
}
// 如果二级分类ID不等于一级分类ID说明选择了具体的二级分类
if (this.twoId !== this.oneId) {
const currentCategory = this.oneList.find(
item => item.pkId === this.oneId
)
if (currentCategory && currentCategory.children) {
const subCategory = currentCategory.children.find(
sub => sub.pkId === this.twoId
)
if (subCategory) {
return `"${subCategory.classifyName}"分类下还没有商品哦`
}
}
}
// 显示一级分类名称
const currentCategory = this.oneList.find(
item => item.pkId === this.oneId
)
if (currentCategory) {
return `"${currentCategory.classifyName}"分类下还没有商品哦`
}
return '当前分类下还没有商品哦'
},
// 获取空状态提示
getEmptyTips() {
if (this.waresName) {
return ['检查搜索词是否正确', '浏览其他分类商品']
}
return ['试试其他分类', '商品正在陆续上架中']
},
// 清除搜索
clearSearch() {
this.waresName = ''
this.getAllGoods1()
},
changeCountry() {
this.isCountry = true
},
sureCountry(e) {
const { value } = e
this.pkCountry = value[0].id
this.pkCountryLabel = value[0].label
this.pkCountryImg = value[0].img
this.isCountry = false
uni.setStorageSync('pkCountry', this.pkCountry + '')
// 获取分类一级
this.getClassIfy()
this.$refs.cart.getCar()
},
getJScountry() {
api.currencyList().then(res => {
let data = res.data.map(item => {
return {
img: item.nationalFlag2,
id: item.pkId,
label: item.shortName,
}
})
this.countryList = [data]
this.countryList[0].forEach(item => {
if (item.id == this.pkCountry) {
this.pkCountryLabel = item.label
this.pkCountryImg = item.img
}
})
})
},
goShare() {
uni.navigateTo({
url: '/pages/specialArea/share?specialArea=7',
})
},
setSpecial(item) {
this.specialArea = item.value
this.getAllCategory()
},
addCar(item) {
let carList = {
pkCountry: this.pkCountry,
specialArea: item.specialArea,
number: 1,
waresCode: item.waresCode,
productGroup: item.productGroup,
}
if (
item.isMakerGift == 2 &&
(item.specialArea == 1 || item.specialArea == 3)
) {
this.$refs.selSpaceGoods.getData(carList)
} else {
api.addShopping(carList).then(res => {
if (res.code == 200) {
uni.showToast({
title: '购物车添加成功',
icon: 'success',
mask: true,
duration: 500,
})
setTimeout(() => {
this.$store
.dispatch('getCarLength', this.specialArea)
.then(res => {
this.shopCarLength = res.data.smallCount
})
}, 200)
}
})
}
},
getCatLength() {
this.$store.dispatch('getCarLength', this.specialArea).then(res => {
this.shopCarLength = res.data.smallCount
})
},
getClassIfy() {
api
.classifyList({
pkCountry: this.pkCountry,
specialArea: this.specialArea,
hierarchy: 0,
})
.then(res => {
// res.data.unshift({
// classifyName: '全部',
// pkId: '',
// })
this.oneList = res.data
this.oneId = this.oneList[0] ? this.oneList[0].pkId : ''
// 默认全部展开
this.expandedMenus = this.oneList.map(item => item.pkId)
this.getClassIfyTwo(this.oneList[0].pkId)
this.getAllGoods(this.oneList[0].pkId)
})
},
// 获取分类二级
getClassIfyTwo(pkId) {
api
.classifyList({
specialArea: this.specialArea,
pkParent: pkId,
hierarchy: 1,
pkCountry: this.pkCountry,
})
.then(res => {
res.data.unshift({
classifyName: '全部',
pkId: pkId,
})
this.twoList = res.data
this.twoList = this.twoList.filter(item => 'classifyName' in item)
this.twoId = pkId
})
},
getAllGoods(id) {
api
.getAllGoods({
pkCountry: this.pkCountry,
specialArea: Number(this.specialArea),
pkAreaClassify: id ? id : '',
})
.then(res => {
this.goodList = res.data
this.goodList.forEach(item => {
if (item.waresName.length > 11) {
item.waresName = item.waresName.substring(0, 11) + '...'
}
})
})
},
getAllGoods1(id) {
api
.getAllGoods({
pkCountry: this.pkCountry,
specialArea: this.specialArea,
waresName: this.waresName,
pkAreaClassify: id ? id : this.oneId,
})
.then(res => {
this.goodList = res.data
this.goodList.forEach(item => {
if (item.waresName.length > 11) {
item.waresName = item.waresName.substring(0, 11) + '...'
}
})
})
},
goDetails(item) {
if (item.specialArea === 14 && !Number(item.inventory)) {
return
}
if (item.preSaleStatus != 3 && item.isSale != 1) {
uni.navigateTo({
url:
'/pages/specialArea/details?waresCode=' +
item.waresCode +
'&specialArea=' +
item.specialArea,
})
}
},
// 处理库存百分比,移除百分号并转换为数字
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'
}
},
},
}
</script>
<style lang="scss" scoped>
.index_header {
background: #fff;
font-size: 18px;
font-family:
PingFang SC-Semibold,
PingFang SC;
font-weight: 600;
color: #333333;
text-align: center;
padding: 10px 0;
}
.content {
background: #f9f9f9;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.tabList_a {
/* 二级分类标签容器样式 */
margin-bottom: 10rpx;
}
/* 分类抽屉按钮 */
.category-drawer-btn {
position: fixed;
top: 10rpx;
right: 20rpx;
z-index: 999;
display: flex;
align-items: center;
padding: 16rpx 20rpx;
font-size: 24rpx;
color: #005bac;
font-weight: 500;
text {
margin-left: 8rpx;
}
&:active {
transform: scale(0.95);
background: rgba(240, 247, 255, 0.95);
}
}
.index_btm {
flex: 1;
display: flex;
.index_r {
flex: 1;
background: #fff;
display: flex;
flex-direction: column;
&.full-width {
margin-left: 0;
}
}
}
/* 分类抽屉遮罩 */
.drawer-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
opacity: 0;
transition: opacity 0.3s ease;
&.show {
opacity: 1;
}
}
/* 分类抽屉样式 */
.category-drawer {
position: fixed;
top: 0;
left: 0;
width: 600rpx;
height: 100vh;
background: #f8f9fa;
display: flex;
flex-direction: column;
z-index: 1001;
transform: translateX(-100%);
transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
&.show {
transform: translateX(0);
}
.drawer-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 40rpx 30rpx 30rpx;
background: #ffffff;
border-bottom: 1px solid #e9ecef;
.drawer-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
}
.drawer-content {
flex: 1;
overflow-y: auto;
padding: 20rpx 0;
/* 抽屉滚动条 */
&::-webkit-scrollbar {
width: 4rpx;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1);
border-radius: 2rpx;
}
.drawer-menu-group {
margin-bottom: 8rpx;
background: #ffffff;
border-radius: 12rpx;
margin: 0 20rpx 12rpx;
overflow: hidden;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
.drawer-first-level {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 30rpx;
font-weight: 600;
color: #333333;
transition: all 0.3s ease;
position: relative;
&.active {
background: linear-gradient(135deg, #005bac 0%, #0066cc 100%);
color: #ffffff;
.drawer-expand-icon {
.u-icon {
color: #ffffff !important;
}
}
}
.drawer-menu-text {
flex: 1;
font-size: 30rpx;
line-height: 1.3;
padding: 32rpx 24rpx;
cursor: pointer;
&:active {
background: rgba(0, 0, 0, 0.05);
}
}
.drawer-expand-icon {
transition: transform 0.3s ease;
padding: 32rpx 24rpx 32rpx 8rpx;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
&:active {
background: rgba(0, 0, 0, 0.05);
}
&.expanded {
transform: rotate(90deg);
}
}
}
.drawer-second-level-container {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s ease;
background: #f8f9fa;
&.expanded {
max-height: 1000rpx;
}
.drawer-second-level {
padding: 24rpx 48rpx;
font-size: 28rpx;
color: #666666;
border-top: 1px solid #e9ecef;
transition: all 0.2s ease;
position: relative;
&:active {
background: #e9ecef;
}
&.active {
background: linear-gradient(135deg, #005bac 0%, #0066cc 100%);
color: #fff;
font-weight: 500;
&::before {
content: '';
position: absolute;
left: 24rpx;
top: 50%;
transform: translateY(-50%);
width: 8rpx;
height: 8rpx;
background: #005bac;
border-radius: 50%;
}
}
.drawer-sub-menu-text {
font-size: 28rpx;
line-height: 1.3;
margin-left: 20rpx;
}
}
}
}
}
}
.classIfy {
padding: 20rpx 20rpx;
margin: 20rpx 0;
font-size: 26rpx;
font-family: Microsoft YaHei;
font-weight: 400;
color: #666666;
}
.actOne {
// border-left: 6rpx solid #005BAC;
color: #fff;
background: #005bac;
}
.tab {
display: flex;
align-items: center;
padding: 0 24rpx;
margin-top: 20rpx;
}
.tab_i {
// width: 120rpx;
text-align: center;
font-size: 14px;
font-weight: 600;
color: #999999;
margin-right: 28rpx;
white-space: nowrap;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f6f6f6;
color: #666;
border-radius: 200rpx;
padding: 0 20rpx;
display: flex;
justify-content: center;
align-items: center;
line-height: 1;
height: 58rpx;
box-sizing: border-box;
}
.actTab {
// width: 120rpx;
text-align: center;
font-size: 14px;
font-family:
PingFang SC-Semibold,
PingFang SC;
font-weight: 600;
// color: #005BAC;
background-color: #005bac;
color: #fff;
margin-right: 28rpx;
white-space: nowrap;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 200rpx;
padding: 0 20rpx;
display: flex;
justify-content: center;
align-items: center;
line-height: 1;
height: 58rpx;
box-sizing: border-box;
}
.heng {
width: 24px;
height: 2px;
background: #005bac;
border-radius: 1px 1px 1px 1px;
margin-top: 4rpx;
}
.heng1 {
width: 24px;
height: 2px;
background: f9f9f9;
border-radius: 1px 1px 1px 1px;
margin-top: 4rpx;
}
.heng2 {
width: 24px;
height: 2px;
background: f9f9f9;
border-radius: 1px 1px 1px 1px;
margin-top: 4rpx;
}
::v-deep .u-scroll-list {
padding-bottom: 10rpx;
}
.zhan {
height: 200px;
}
.goodList {
padding: 0 20rpx;
height: calc(100vh - 320rpx);
overflow-y: auto;
/* 空状态样式 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
min-height: 500rpx;
padding: 80rpx 40rpx;
.empty-icon {
margin-bottom: 40rpx;
opacity: 0.6;
animation: float 3s ease-in-out infinite;
}
.empty-title {
font-size: 36rpx;
font-weight: 600;
color: #333333;
margin-bottom: 16rpx;
}
.empty-desc {
font-size: 28rpx;
color: #666666;
margin-bottom: 40rpx;
text-align: center;
line-height: 1.5;
}
.empty-tips {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 50rpx;
text {
font-size: 24rpx;
color: #999999;
margin-bottom: 8rpx;
line-height: 1.4;
}
}
.empty-actions {
display: flex;
gap: 20rpx;
flex-wrap: wrap;
justify-content: center;
}
.empty-action {
display: flex;
align-items: center;
padding: 20rpx 32rpx;
border-radius: 50rpx;
font-size: 26rpx;
font-weight: 500;
transition: all 0.3s ease;
text {
margin-left: 8rpx;
}
&.primary {
background: linear-gradient(135deg, #005bac 0%, #0066cc 100%);
color: #ffffff;
box-shadow: 0 4rpx 12rpx rgba(0, 91, 172, 0.3);
&:active {
transform: scale(0.95);
box-shadow: 0 2rpx 8rpx rgba(0, 91, 172, 0.4);
}
}
&.secondary {
background: rgba(0, 91, 172, 0.1);
color: #005bac;
border: 2rpx solid rgba(0, 91, 172, 0.2);
&:active {
transform: scale(0.95);
background: rgba(0, 91, 172, 0.15);
}
}
}
}
.goodList_i {
// display: flex;
border-bottom: 1px solid #eee;
padding: 20rpx 0 10rpx;
position: relative;
.goodList_ir {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
font-size: 30rpx;
font-family: Microsoft YaHei;
font-weight: 400;
color: #333333;
margin-left: 24rpx;
.goodList_ib {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #f82c1a;
img {
width: 60rpx;
height: 60rpx;
}
}
}
.fly {
position: absolute;
width: 100%;
height: 100%;
top: 0;
background: #eee;
opacity: 0.5;
}
}
.cover {
width: 200rpx;
height: 200rpx;
background: #ffffff;
border: 1px solid #eeeeee;
border-radius: 10rpx;
}
}
.pv {
font-size: 26rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #999999;
}
.shareImg {
position: fixed;
margin: 14rpx 24rpx;
z-index: 9999;
right: 20rpx;
top: 5rpx;
}
.shareImg1 {
position: fixed;
margin: 14rpx 24rpx;
z-index: 1;
right: 10rpx;
top: 10rpx;
display: flex;
align-items: center;
img {
width: 40rpx;
height: 30rpx;
margin-right: 20rpx;
}
}
.qzbq {
background: #d61820;
border-radius: 2px 2px 2px 2px;
font-size: 10px;
// font-family: PingFang SC-Semibold, PingFang SC;
// font-weight: 600;
color: #ffffff;
padding: 0px 5px;
margin-right: 5px;
}
.search {
margin: 10rpx 20rpx;
padding: 10rpx;
background: #eeeeee;
border-radius: 20px;
font-size: 14px;
}
.image-container {
position: relative;
}
.triangle-badge {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-top: 100rpx solid #005bac;
border-right: 100rpx solid transparent;
border-radius: 10rpx 0 0 0;
z-index: 10;
}
.triangle-badge-text {
position: absolute;
color: #ffffff;
font-weight: 600;
line-height: 1;
transform: rotate(-45deg);
transform-origin: center;
white-space: nowrap;
text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.2);
}
/* 2个字样式 */
.triangle-badge-text.text-2 {
top: -76rpx;
left: 10rpx;
font-size: 24rpx;
}
/* 3个字样式 */
.triangle-badge-text.text-3 {
top: -70rpx;
left: -2rpx;
font-size: 24rpx;
}
/* 4个字样式 */
.triangle-badge-text.text-4 {
top: -72rpx;
left: -4rpx;
font-size: 20rpx;
}
/* 库存进度条样式 - 升级版 */
.inventory-progress-container {
// margin-bottom: 10rpx;
display: flex;
align-items: center;
width: 100%;
.inventory-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-right: 10rpx;
// margin-bottom: 12rpx;
.inventory-label {
display: flex;
align-items: center;
font-size: 24rpx;
.fire-icon,
.warning-icon {
font-size: 28rpx;
margin-right: 8rpx;
animation: iconBounce 1.5s ease-in-out infinite;
}
.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: 0;
flex: 1;
height: 18rpx;
margin-right: 10rpx;
background: rgba(0, 0, 0, 0.08);
border-radius: 12rpx;
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 iconBounce {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
}
@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%;
}
}
/* 空状态浮动动画 */
@keyframes float {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10rpx);
}
}
</style>