Compare commits

...

2 Commits

3 changed files with 450 additions and 15 deletions

View File

@ -1,5 +1,6 @@
const http = uni.$u.http
//会员专区商品列表
export const getAreaGoods = params =>
http.post('/sale/api/retail-wares/wares-list', params)
export const getAreaGoods = params => {
return http.post('/sale/api/retail-wares/wares-list', params)
}

View File

@ -1,6 +1,5 @@
<template>
<view class="contain">
<!-- Tab选项卡 -->
<view class="tab-container">
<view class="tab-wrapper">
<view
@ -16,7 +15,132 @@
</view>
</view>
<view class="goods-container">
<!-- 分类和搜索区域 - 仅在北大甄选时显示 -->
<view class="category-container" v-if="activeTab === 43">
<view class="category-section">
<view class="category-left">
<view
v-for="item in oneList"
:class="[
'category-item',
oneId == item.pkId ? 'category-active' : '',
]"
@click="selectOneCategory(item)"
:key="item.pkId"
>
{{ item.classifyName }}
</view>
</view>
<view class="category-right">
<!-- 二级分类 -->
<scroll-view
class="category-scroll"
scroll-x="true"
:show-scrollbar="false"
v-if="twoList.length > 0"
>
<view class="category-tabs">
<view
v-for="(item, index) in twoList"
:key="index"
@click="selectTwoCategory(item)"
:class="[twoId == item.pkId ? 'tab-active' : 'tab-item']"
>
{{ item.classifyName }}
</view>
</view>
</scroll-view>
<!-- 搜索框 -->
<view class="search-container">
<view class="search-input-wrapper">
<u--input
class="search-input"
placeholder="请输入商品名称"
placeholderStyle="font-size:14px;"
prefixIcon="search"
shape="circle"
v-model="waresName"
border="none"
prefixIconStyle="font-size: 22px;color: #909399"
@confirm="searchGoods"
/>
</view>
</view>
<!-- 北大甄选的商品列表 -->
<view class="goods-list-container">
<scroll-view
class="goodList"
scroll-y="true"
enhanced
:show-scrollbar="false"
>
<view
v-for="item in goodList"
:key="item.waresCode"
class="goodList_i"
>
<img :src="item.cover1" class="cover" alt="" />
<view class="goodList_ir">
<view class="tit1">
{{ item.waresName }}
</view>
<view class="goodList_ib">
<view class="price-container">
<!-- <text class="currency"></text> -->
<text class="price">{{
formatCurrency(item.waresPrice)
}}</text>
<text v-if="item.isSale === 1" class="sale-status"
>已售罄</text
>
</view>
<!-- <img @click.stop="addCar(item)"
src="@/static/images/cart.png"
alt=""> -->
</view>
<!-- 数量控制区域 -->
<view class="quantity-section" v-if="item.isSale !== 1">
<view class="quantity-control">
<view
class="quantity-btn minus"
:class="{ disabled: item.quantity <= 1 }"
@click.stop="updateQuantity(item, -1)"
>
<text class="quantity-icon"></text>
</view>
<view class="quantity-display">
<text class="quantity-text">{{
item.quantity || 1
}}</text>
</view>
<view
class="quantity-btn plus"
@click.stop="updateQuantity(item, 1)"
>
<text class="quantity-icon">+</text>
</view>
</view>
<view class="toBuy" @click.stop="goBuy(item)">购买</view>
</view>
<!-- 禁售状态 -->
<view class="sold-out-section" v-if="item.isSale === 1">
<view class="sold-out-btn">暂时缺货</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- 精品专区的商品容器 -->
<view class="goods-container" v-if="activeTab !== 43">
<scroll-view
class="goodList"
scroll-y="true"
@ -70,7 +194,7 @@
</view>
</view>
</view>
<view class="list-bottom">
<view class="list-bottom" v-if="activeTab !== 43">
<text class="bottom-text"> 已显示全部商品 </text>
</view>
</scroll-view>
@ -80,6 +204,8 @@
<script>
import * as api from '@/config/login.js'
import * as goodsApi from '@/config/goods.js'
import { getAreaGoods } from '@/config/special-area.js'
import { setToken } from '@/config/auth.js'
import { formatCurrency } from '@/util/index.js'
@ -100,10 +226,21 @@ export default {
value: 41,
},
],
//
oneList: [], //
oneId: '', // ID
twoList: [], //
twoId: '', // ID
waresName: '', //
userInfo: {}, //
pkCountry: 1, // ID
categoryLoaded: false, //
}
},
onLoad(options) {
this.pkParent = options.pkParent
this.userInfo = uni.getStorageSync('User') || {}
this.pkCountry = this.userInfo.pkCountry || 1
this.getToken()
},
methods: {
@ -116,7 +253,16 @@ export default {
.then(res => {
setToken(res.data.access_token, res.data.expires_in)
uni.setStorageSync('regiest-login', '1')
this.getList()
// tab
if (this.activeTab === 43) {
// -
this.getClassIfy()
} else {
// -
this.getList()
}
this.getCode()
})
},
@ -144,7 +290,18 @@ export default {
if (this.activeTab !== value) {
this.activeTab = value
this.goodList = [] //
this.getList() //
//
this.clearSearchAndCategory()
// tab
if (value === 43) {
// -
this.getClassIfy()
} else {
// -
this.getList()
}
}
},
updateQuantity(item, change) {
@ -164,6 +321,101 @@ export default {
url: '/pages/shareArea/hiOrder?allData=' + JSON.stringify(item),
})
},
//
getClassIfy() {
goodsApi
.classifyList({
pkCountry: this.pkCountry,
specialArea: this.activeTab,
hierarchy: 0,
})
.then(res => {
this.oneList = res.data || []
this.categoryLoaded = true
if (this.oneList.length > 0) {
this.oneId = this.oneList[0].pkId
this.getClassIfyTwo(this.oneList[0].pkId)
this.getAllGoodsWithCategory(this.oneList[0].pkId)
}
})
.catch(err => {
console.error('获取分类失败:', err)
})
},
//
getClassIfyTwo(pkId) {
goodsApi
.classifyList({
specialArea: this.activeTab,
pkParent: pkId,
hierarchy: 1,
pkCountry: this.pkCountry,
})
.then(res => {
const twoListData = res.data || []
twoListData.unshift({
classifyName: '全部',
pkId: pkId,
})
this.twoList = twoListData
this.twoId = pkId
})
.catch(err => {
console.error('获取二级分类失败:', err)
})
},
//
getAllGoodsWithCategory(id) {
const params = {
pkCountry: this.pkCountry,
specialArea: this.activeTab,
pkAreaClassify: id || this.oneId,
shareMemberCode: this.pkParent,
waresName: '',
}
//
if (this.waresName.trim()) {
params.waresName = this.waresName.trim()
}
api
.queryWares(params)
.then(res => {
// quantity
this.goodList = (res.data || []).map(item => ({
...item,
quantity: item.quantity || 1,
}))
})
.catch(err => {
console.log(err, '...err')
console.error('获取商品列表失败:', err)
this.goodList = []
})
},
//
selectOneCategory(item) {
this.oneId = item.pkId
this.getAllGoodsWithCategory(item.pkId)
this.getClassIfyTwo(item.pkId)
},
//
selectTwoCategory(item) {
this.twoId = item.pkId
this.getAllGoodsWithCategory(item.pkId)
},
//
searchGoods() {
this.getAllGoodsWithCategory()
},
//
clearSearchAndCategory() {
this.waresName = ''
this.oneId = ''
this.twoId = ''
this.oneList = []
this.twoList = []
},
},
}
</script>
@ -172,10 +424,197 @@ export default {
.contain {
background: #f8fafc;
min-height: 100vh;
height: 100vh;
display: flex;
flex-direction: column;
}
//
.category-container {
background: #ffffff;
border-bottom: 1rpx solid #e2e8f0;
flex: 1;
height: 0;
display: flex;
flex-direction: column;
.category-section {
flex: 1;
display: flex;
height: 0rpx;
.category-left {
width: 200rpx;
background: #f8fafc;
border-right: 1rpx solid #e2e8f0;
overflow-y: auto;
flex-shrink: 0;
.category-item {
padding: 24rpx 20rpx;
font-size: 26rpx;
color: #64748b;
text-align: center;
border-bottom: 1rpx solid #f1f5f9;
transition: all 0.2s ease;
&.category-active {
background: #005bac;
color: #ffffff;
font-weight: 600;
}
&:active {
background: rgba(0, 91, 172, 0.1);
}
}
}
.category-right {
flex: 1;
display: flex;
flex-direction: column;
background: #fff;
.category-scroll {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f1f5f9;
.category-tabs {
display: flex;
white-space: nowrap;
.tab-item,
.tab-active {
padding: 12rpx 24rpx;
margin-right: 20rpx;
border-radius: 20rpx;
font-size: 26rpx;
white-space: nowrap;
transition: all 0.2s ease;
}
.tab-item {
background: #f8fafc;
color: #64748b;
border: 1rpx solid #e2e8f0;
}
.tab-active {
background: #005bac;
color: #ffffff;
font-weight: 600;
}
}
}
.search-container {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f1f5f9;
.search-input-wrapper {
display: flex;
align-items: center;
background: #f8fafc;
border-radius: 24rpx;
border: 1rpx solid #e2e8f0;
padding: 0 20rpx;
.search-input {
flex: 1;
height: 72rpx;
font-size: 28rpx;
color: #1f2937;
&::placeholder {
color: #9ca3af;
}
}
.search-icon {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: #005bac;
border-radius: 50%;
margin-left: 12rpx;
.search-text {
color: #ffffff;
font-size: 24rpx;
}
&:active {
background: #004494;
transform: scale(0.95);
}
}
}
}
//
.goods-list-container {
flex: 1;
overflow: hidden;
background: #fff;
.goodList {
padding: 0;
.goodList_i {
padding: 8rpx;
img {
height: 140rpx;
width: 140rpx;
border-radius: 12rpx;
}
.goodList_ir {
margin-left: 8rpx;
.tit1 {
font-size: 26rpx;
margin-bottom: 8rpx;
}
.goodList_ib {
.price-container {
.price {
font-size: 28rpx;
color: #f82c1a;
}
}
}
.quantity-section {
.quantity-control {
.quantity-btn {
width: 40rpx;
height: 40rpx;
.quantity-icon {
font-size: 24rpx;
}
}
.quantity-display {
height: 40rpx;
}
}
.toBuy {
font-size: 24rpx;
color: #ffffff;
padding: 8rpx 16rpx;
border-radius: 12rpx;
}
.sold-out-btn {
font-size: 24rpx;
color: #ffffff;
padding: 8rpx 16rpx;
border-radius: 12rpx;
}
}
}
}
}
}
}
}
}
// Tab -
.tab-container {
// background: #ffffff;
@ -258,11 +697,12 @@ export default {
//
.goods-container {
// flex: 1;
flex: 1;
background: #f8fafc;
padding: 24rpx 24rpx 0;
position: relative;
z-index: 3;
overflow: hidden;
.section-title {
text-align: center;
@ -287,7 +727,7 @@ export default {
//
.goodList {
// height: calc(100vh - 400rpx);
height: 100%;
padding: 0 8rpx;
.goodList_i {

View File

@ -1,9 +1,3 @@
<!--
* @Descripttion:
* @version:
* @Author: kBank
* @Date: 2022-11-21 15:11:22
-->
<template>
<view class="content">
<backIcon :diff="diff"></backIcon>