Files
jjx-wap/pages/shop/shop.vue
T
2026-10-08 18:34:09 +08:00

359 lines
8.7 KiB
Vue

<template> <!-- 商城 -->
<view class="wrap">
<!-- 吸顶 -->
<u-sticky offset-top="0" customNavHeight="0">
<!-- 顶部 -->
<uiheader title="金久信特产商城"></uiheader>
<!-- 搜索栏 -->
<cmsearch :k="keyword" @search="search" placeholder="请输入商品名称等搜索"></cmsearch>
<!-- 轮播图-传值:list="数组" -->
<cmswiper page="shop" height="320rpx"></cmswiper>
<view class="layout-sch bg-white flex justify-between align-center" @click="showAddress">
<view class="select down flex-1">{{ locationValue ? locationValue : '选择地区' }}</view>
<!-- <view class="flex-1"></view>-->
<view class="logo">
<image class="full" src="/static/img/shoplogo.png" mode=""></image>
</view>
<!-- <view class="name m-left-10">金久信特产商城</view>-->
</view>
<!-- 滑动区 -->
<view class="flex justify-start items-center bg-white">
<scroll-view class="scroll-box flex-1" @scroll="onCateScroll" scroll-x="true">
<view class="item" :class="{ active: categoryId === null }" @click="selectCate(null)">
<view class="text break">全部</view>
</view>
<view class="item" :class="{ active: categoryId === item._id }" v-for="(item,index) in categoryList"
:key="index" @click="selectCate(item._id)">
<view class="text break">{{ item.name }}</view>
</view>
</scroll-view>
<view >
<u-icon name="arrow-right-double" :color="hasMore ? '#A92924' : '#AAAAAA'"/>
</view>
</view>
</u-sticky>
<!-- 列表 -->
<uiswiper :ad="27" padding="10rpx 20rpx"></uiswiper>
<uiswiper :ad="28" padding="10rpx 20rpx"></uiswiper>
<uiswiper :ad="29" padding="10rpx 20rpx"></uiswiper>
<uiswiper :ad="30" padding="10rpx 20rpx"></uiswiper>
<uiswiper :ad="31" padding="10rpx 20rpx"></uiswiper>
<view class="layout layout-shop flex justify-between flex-wrap">
<view class="item pos-r" @click="detailLink(item._id)" v-for="(item, index) in goodsList" :key="index">
<view class="img">
<image class="full" :src="item.cover" mode="aspectFill"/>
</view>
<text class="recommend" v-if="item.recommend === 1">荐</text>
<view class="info">
<view class="title text-both">
{{ item.name }}
</view>
<view class="price m-top-10">
<text class="current">&yen;<text class="blod">{{ item.amount }}</text>
到手价
</text>
<!-- <text class="cost m-left-10">&yen;35.5</text>-->
</view>
</view>
</view>
</view>
<!-- 没有数据 u-empty是框架组件 cmempty是自己封装组件 -->
<u-empty mode="list" text="暂无更多内容~" v-if="goodsList.length === 0"></u-empty>
<!-- <cmempty></cmempty> -->
<collapse></collapse>
<AddressSelect ref="AddressSelect" @confirm="regionConfirm"/>
<view class="issue" @click="$jump('/pages/shop/cart')">
<u-icon name="shopping-cart" color="#fff" size="24"></u-icon>
<text class="cartNum" v-if="cartNum > 0">{{ cartNum }}</text>
</view>
</view>
</template>
<script>
import uiheader from '@/components/index/header'
import cmsearch from '@/components/common/search'
import cmempty from '@/components/common/empty'
import cmswiper from '@/components/common/swiper'
import Collapse from "@/components/index/collapse.vue";
import AddressSelect from "@/components/AddressSelect.vue";
import uiswiper from "@/components/index/swiper.vue";
export default {
components: {
uiswiper,
AddressSelect,
Collapse,
uiheader,
cmsearch,
cmempty,
cmswiper,
},
data() {
return {
categoryList: [],
goodsList: [],
options: [],
address: [],
pageIndex: 1,
pageSize: 20,
total: 0,
categoryId: null,
keyword: null,
locationValue: null,
region: {
province: {
code: null,
name: null,
},
city: {
code: null,
name: null,
},
},
cartNum: 0,
hasMore: true
}
},
methods: {
showAddress() {
this.$refs.AddressSelect.open(this.region, 2, true);
},
regionConfirm({province, city}) {
this.region = {province, city}
this.locationValue = `${province.name}${city.name}`
this.getGoodsList()
},
handTab(val, index) {
this.custIndex = index
},
detailLink(id) {
vk.navigateTo(`/pages/shop/detail?id=${id}`, {
id,
})
},
getCategoryList() {
vk.callFunction({
url: 'client/goods/category/pub/getList'
}).then(res => {
this.categoryList = res.rows
})
},
search(keyword) {
this.keyword = keyword
this.getGoodsList()
},
getGoodsList(pageIndex = 1) {
vk.callFunction({
url: 'client/goods/list/pub/getList',
data: {
pageIndex,
pageSize: this.pageSize,
city: this.region.city ? this.region.city.code : null,
parentId: this.categoryId,
keyword: this.keyword
}
}).then(res => {
this.goodsList = res.rows
})
},
getCartNum() {
vk.callFunction({
url: 'client/cart/kh/getNum',
}).then(({data}) => {
this.cartNum = data
})
},
selectCate(cateId) {
if (this.categoryId === cateId) this.categoryId = null
else this.categoryId = cateId
this.getGoodsList()
},
onCateScroll({detail: {scrollLeft, scrollWidth}}) {
const wrapWidth = uni.upx2px(690)
const maxScrollLeft = scrollWidth - wrapWidth
console.log(maxScrollLeft, scrollLeft)
this.hasMore = scrollLeft + 50 < maxScrollLeft
}
},
onLoad(option) {
if (option.keyword) this.keyword = option.keyword
this.getCategoryList()
this.getGoodsList()
this.getCartNum()
}
}
</script>
<style lang="scss">
.layout-sch {
padding: 30rpx 30rpx;
.select {
position: relative;
width: 260rpx;
height: 40rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #333;
padding: 10rpx 30rpx 10rpx 20rpx;
border: 1px solid #f2f2f2;
overflow: hidden;
}
.down::after {
position: absolute;
right: 20rpx;
top: 50%;
z-index: 9;
content: '';
margin-top: -6rpx;
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 12rpx solid #999999;
}
.logo {
width: 80rpx;
height: 60rpx;
}
.name {
font-size: 32rpx;
font-weight: 600;
line-height: 44rpx;
color: #101010;
}
}
.scroll-box {
// width: 690rpx;
width: 690rpx;
//height: 80rpx;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
align-items: center;
white-space: nowrap;
background: #ffffff;
.item {
display: inline-block;
margin-right: 10rpx;
height: 60rpx;
padding: 0 20rpx;
font-size: 28rpx;
line-height: 60rpx;
text-align: center;
color: #454545;
border-radius: 6rpx;
background: #f2f2f2;
&:last-child {
margin-right: 0;
}
}
.active {
color: #ffffff;
background: #A92924;
}
}
.layout-shop {
margin: 20rpx 30rpx;
.item {
margin-top: 30rpx;
width: 330rpx;
height: auto;
background: #ffffff;
border-radius: 20rpx;
overflow: hidden;
&:nth-child(1), &:nth-child(2) {
margin-top: 0rpx;
}
.img {
width: 100%;
height: 320rpx;
}
.info {
padding: 20rpx 10rpx;
.title {
width: 100%;
height: 72rpx;
font-size: 28rpx;
line-height: 36rpx;
color: #101010;
}
.bs {
font-size: 22rpx;
line-height: 32rpx;
color: #ffffff;
padding: 0 8rpx;
background: #A92924;
border-radius: 12rpx;
}
.price {
width: 100%;
//height: 32rpx;
overflow: hidden;
}
.current {
font-size: 24rpx;
line-height: 32rpx;
color: #A92924;
.blod {
font-size: 28rpx;
font-weight: 600;
}
}
.cost {
font-size: 24rpx;
line-height: 32rpx;
color: #666666;
}
}
}
}
.recommend {
position: absolute;
right: 0;
top: 0;
padding: 5px;
background-color: #bf2b28;
color: white;
font-size: 30rpx;
z-index: 1;
}
.cartNum {
position: absolute;
right: -10rpx;
top: -10rpx;
padding: 5px;
background-color: #FFFFFF;
color: #bf2b28;
font-size: 20rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 25rpx;
width: 25rpx;
height: 25rpx;
border: 1px solid #bf2b28;
}
</style>