Commit b828866c authored by June's avatar June

feat:商品分组分类

parent d487ee16
......@@ -5,7 +5,7 @@ import dayjs from 'dayjs'
import { removeStorage } from '@/lib/storage/index.js'
export default {
onLaunch: async function() {
await this.checkUpdate() // 检查更新
this.checkUpdate() // 检查更新
this.setMobileData() // 获取系统信息和胶囊信息
const extConfig = wx.getExtConfigSync ? wx.getExtConfigSync(): {}
this.$store.state.user.appid = extConfig.appid
......
import { request } from "@/lib/service"
/**
* @desc 获取分类列表
*/
export function getCatetories() {
return request({
url: 'zsxcx/shopGoodsCategory.htm',
method: 'post'
})
}
/**
* @desc 店铺商品列表接口
* @param { String } keywords 关键字:商品名称
* @param { Number } cat_id * 分类ID
*/
export function cateGoodsList(cat_id, keywords = '') {
export function cateGoodsList({cat_id, keywords = '', page = 1, pagenum = 10}) {
return request({
url: 'zsxcx/shopGoods.htm',
url: 'zsxcx/shopGoodsCustom.htm',
method: 'post',
data: {
cat_id,
keywords
keywords,
page,
pagenum
}
})
}
/**
* 店铺商品分组分类
*/
export function groupCates() {
return request({
url: 'zsxcx/shopGoodsCategoryCustom.htm',
method: 'post'
})
}
/**
* @desc 首页展示栏商品接口
*/
......
const env = {
release: 'https://www.gelifood.com', // 正式版
trial: 'https://www.gelifood.com', // 体验版
develop: 'https://www.gelifood.com' // 开发版
develop: 'https://d.gelifood.com' // 开发版
}
// 不考虑其他端小程序直接这样配置
......
{
"extEnable": true,
"extAppid": "wx537e892e36fbf79d",
"extAppid": "wxd170058f4ad8fecd",
"ext": {
"appid": "wx537e892e36fbf79d"
"appid": "wxd170058f4ad8fecd"
}
}
\ No newline at end of file
......@@ -147,6 +147,45 @@ export function request (options) {
})
}
// 请求
// export function testrequest (options) {
// const valite_err = validateOps(options)
// if(valite_err) return Toast({title: valite_err})
// options.method = options.method ? options.method.toUpperCase() : "GET" // 默认get
// options.url = `${options.url}`
// if(options.needMask) {
// uni.showLoading({title: '加载中...', mask: true})
// }
// return new Promise((resolve, reject) => {
// const token = store.state.user.token || ''
// const appid = store.state.user.appid || ''
// uni.request({
// ...options,
// header: {
// 'content-type': 'application/x-www-form-urlencoded',
// 'token': token,
// 'appid': appid
// },
// success: res => {
// successRes(res, options, resolve, reject)
// },
// fail: err => {
// Toast({title: '网络开小差了,请检查网络!'})
// options.errCb && typeof options.errCb === 'function' && options.errCb();
// reject({
// status: false,
// code: 400,
// data: err
// })
// },
// complete: () => {
// options.completeCb && typeof options.completeCb === 'function' && options.completeCb();
// options.needMask && uni.hideLoading()
// }
// })
// })
// }
// 上传文件
export function upload(options) {
const valite_err = validateOps(options)
......
<template>
<view class="category-wrap w-100">
<template v-if="isOverdue">
<view style="width: 100vw; height: 100vh;display: flex;justify-content: center;align-items: center;">
<over-due />
</view>
</template>
<template v-else>
<!-- search bar -->
<view class="searchBar-wrap flex j-center a-center w-100">
<navigator
class="search flex j-center a-center"
hover-class="none"
url="/pages/search/index"
>
<image class="search-icon mr-1" src="/static/images/common/icon-search.png" mode="aspectFit" />
<text class="font-24">搜索商品</text>
</navigator>
</view>
<!-- category 未优化,可以递归组件 -->
<template v-if="goods_list.length === 0">
<view class="flex j-center a-center w-100 category">
<empty-view
iconSrc="/static/images/common/noGoods.png"
text="店铺尚未上架商品"
/>
</view>
</template>
<template v-else>
<view class="category flex j-between w-100 font-24">
<scroll-view
class="scroll-left"
scroll-y
:scroll-into-view="leftScrollName"
>
<!-- 一级分类 -->
<view
class="w-100 px-3 py-2"
v-for="(cate_1, cate_idx_1) in cate_list"
:key="cate_1.cat_id"
:class="cate1_current === cate_1.cat_id ? 'cate-active' : null"
@click.stop=""
>
<view
class="mb-2"
@click.stop="cateChange(1, cate_1.cat_id, cate_idx_1)"
:class="cate1_current === cate_1.cat_id ? 'cate-1_active' : null"
>{{cate_1.cat_name}}</view>
<view v-show="cate1_current === cate_1.cat_id && cate_1.list.length > 0">
<!-- 二级分类 -->
<view
class="ml-2 second-item"
v-for="(cate_2, cate_idx_2) in cate_1.list"
:key="cate_2.cat_id"
>
<view
:class="cate2_current === cate_2.cat_id ? 'cate-2_active' : null"
@click.stop="cateChange(2, cate_2.cat_id, cate_idx_1, cate_idx_2)"
>{{cate_2.cat_name}}</view>
</view>
</view>
</view>
</scroll-view>
<view class="scroll-right flex-1">
<view class="cates_title">{{cate1_name}} {{cate2_name ? '-' + cate2_name : ''}}</view>
<pull-list
ref="pullList"
:refresherEnabled="false"
>
<view
class="goods-item flex j-start a-center"
v-for="good in goods_list"
:key="good.goods_id"
@click="navDetail(good)"
>
<image
class="goods-cover mr-2"
lazy-load
:src="baseUrl + '/' + good.goods_thumb"
mode="aspectFit"
/>
<view class="goods-price flex-1 flex flex-column j-between font-28">
<view class="title">{{good.goods_name}}</view>
<view class="descColor desc font-24 w-100 flex j-between a-center">
<text class="flex-1">{{good.specification}}</text>
<text class="sale-count text-right">销量:{{good.virtual_quantity_sold}}</text>
</view>
<view class="w-100 flex j-between a-center">
<view class="flex j-start a-center">
<price
:is_inquiry="good.is_inquiry"
:price="good.shop_price"
/>
<text class="primaryColor font-28">{{good.least_str}}</text>
</view>
<image
class="cart-icon"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
@click.stop="handlePop(good)"
/>
</view>
</view>
</view>
<view class="empty-text text-center mt-4 p-2">到底了,看看别的分类吧~</view>
</pull-list>
</view>
</view>
</template>
<!-- 购物弹窗 -->
<goods-popup ref="popup" :fitIphoneX="false" />
</template>
</view>
</template>
<script>
// 所有写法需要优化!!!
import pullList from '@/components/pull-list/index.vue'
import goodsPopup from '@/components/goods-popup/index.vue'
import overDue from '@/components/overDue-view/index.vue'
import price from '@/components/price/index.vue'
import { getCatetories, cateGoodsList } from '@/apis/category.js'
import { searchGoods, goodsSku } from '@/apis/goods.js'
import { baseUrl } from '@/config/index.js'
import common_share from '@/mixins/setting_share.js'
import { mapState, mapActions } from 'vuex'
import { debounce } from '@/utils/common.js'
let cat_id = 0
export default {
data() {
return {
baseUrl,
cate1_current: '1', // 和cateid对应则未选中状态
cate2_current: '0',
cate1_name: '',
cate2_name: '',
cate_list: [], // 分类列表
goods_list: [], // 分类商品列表
showNoMoreMsg: false
}
},
components: {
pullList,
goodsPopup,
overDue,
price
},
computed: {
...mapState({
token: state => state.user.token,
isOverdue: state => state.user.isOverdue
})
},
// async created() {
// this.getCate()
// },
onShow() {
uni.showLoading()
this.getCate()
this.getCateGoods()
if(this.token) {
this.setCount()
}
uni.hideLoading()
},
mixins: [common_share],
methods: {
...mapActions('cart', ['setCount']),
async getCate() {
try{
const { status, data } = await getCatetories()
if(status) {
let cate_list = this.cate_list
cate_list = data
cat_id = cate_list[0].cat_id
this.cate1_current = cate_list[0].cat_id
this.cate_list = cate_list
this.cate1_name = cate_list[0].cat_name
// this.cate2_name = cate_list[0].list[0].cat_name
this.getCateGoods()
}
}catch(e){
console.log(e)
this.$toast({title: e.msg || '获取分类失败'})
}
},
// 切换分类 type === 1 分类1 type === 2 分类2, cate1_idx 分类一的下表
cateChange(type, cate_id, cate1_idx, cate2_idx) {
if(cat_id === cate_id) return
const cate_list = this.cate_list
if(type === 1) {
this.cate1_current = cate_id
this.cate2_current = "0" // 初始化,让二级不在激活状态
cat_id = cate_id
this.cate1_name = cate_list[cate1_idx].cat_name
this.cate2_name = ''
} else if(type === 2) {
this.cate2_current = cate_id
cat_id = cate_id
this.cate2_name = cate_list[cate1_idx].list[cate2_idx].cat_name
}
this.$refs.pullList.scroll2Top()
this.getCateGoods()
},
// 获取分类商品
async getCateGoods() {
try{
const { status, data } = await cateGoodsList(cat_id)
if(status) {
this.goods_list = data
} else {
this.goods_list = []
}
}catch(e){
console.log(e)
this.$toast({title: e.msg || '程序错误'})
}
},
// 商品详情
navDetail(good) {
uni.navigateTo({
url: `/pages/goods/detail?goods_id=${good.goods_id}&shop_id=${good.shop_id}&agent_id=${good.agent_id}`
})
},
// tolower() {
// console.log('触底了')
// },
// 点击拉起弹窗
handlePop: debounce(async function(goods) {
try{
uni.showLoading({
title: '加载中...',
mask: true
})
const { status, data } = await goodsSku(goods.goods_id)
if(status) {
console.log(data)
const params = {
goodsInfo: {
cover: `${this.baseUrl}/${goods.goods_thumb}`,
title: goods.goods_name,
is_inquiry: goods.is_inquiry,
unit: goods.goods_unit
},
skuData: data
}
console.log(params)
this.$refs.popup.show(params)
}
uni.hideLoading()
}catch(e){
console.log(e)
uni.hideLoading()
//TODO handle the exception
}
}, 800)
}
}
// disableScroll: true
</script>
<style lang="scss" scoped>
.category-wrap {
height: 100vh;
box-sizing: border-box;
border-top: 1rpx solid $line;
overflow: hidden;
.searchBar-wrap {
height: 112rpx;
background-color: #fff;
.search {
width: 690rpx;
height: 72rpx;
border-radius: 4rpx;
background-color: $mainBg;
.search-icon {
width: 32rpx;
height: 32rpx;
}
}
}
.category{
height: calc(100vh - 112rpx);
background-color: $mainBg;
overflow: hidden;
.scroll-left {
flex: 0 0 180rpx;
overflow: hidden;
.cate-1_active {
color: $primary;
font-weight: bold;
}
.cate-2_active {
color: $primary;
}
.cate-active {
background-color: #fff;
}
.second-item {
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
}
.scroll-right {
position: relative;
padding-top: 72rpx;
background-color: #fff;
.cates_title {
position: absolute;
left: 0;
top: 0;
right: 0;
z-index: 2;
height: 72rpx;
line-height: 72rpx;
margin-left: 20rpx;
background-color: #fff;
}
.empty-text {
font-size: 20rpx;
color: $desc;
}
.goods-item {
@include borderBox(20rpx, 20rpx);
border-bottom: 1rpx solid $line;
.goods-cover {
flex: 0 0 160rpx;
width: 160rpx;
height: 160rpx;
}
.goods-price {
height: 160rpx;
.title {
@include text-ellipsis(1);
color: #343434;
}
.desc{
.spec {
@include text-ellipsis(1);
}
.sale-count {
flex: 0 0 200rpx;
}
}
.price-txt {
color: $primary;
}
.cart-icon {
width: 34rpx;
height: 32rpx;
}
}
}
}
}
}
</style>
......@@ -19,9 +19,8 @@
<text class="font-24">搜索商品</text>
</navigator>
</view>
<!-- category 未优化,可以递归组件 -->
<template v-if="goods_list.length === 0">
<template v-if="cate_list.length === 0">
<view class="flex j-center a-center w-100 category">
<empty-view
iconSrc="/static/images/common/noGoods.png"
......@@ -35,90 +34,78 @@
class="scroll-left"
scroll-y
:scroll-into-view="leftScrollName"
@click="handleCate"
>
<!-- 一级分类 -->
<view
class="w-100 px-3 py-2"
v-for="(cate_1, cate_idx_1) in cate_list"
:key="cate_1.cat_id"
:class="cate1_current === cate_1.cat_id ? 'cate-active' : null"
@click.stop=""
<view
class="cate-item overtext-1"
:class="cate_cur === cate_idx ? 'cate-active' : null"
v-for="(cate, cate_idx) in cate_list"
:key="cate.id"
:data-index="cate_idx"
>
<view
class="mb-2"
@click.stop="cateChange(1, cate_1.cat_id, cate_idx_1)"
:class="cate1_current === cate_1.cat_id ? 'cate-1_active' : null"
>{{cate_1.cat_name}}</view>
<view v-show="cate1_current === cate_1.cat_id && cate_1.list.length > 0">
<!-- 二级分类 -->
<view
class="ml-2 second-item"
v-for="(cate_2, cate_idx_2) in cate_1.list"
:key="cate_2.cat_id"
>
<view
:class="cate2_current === cate_2.cat_id ? 'cate-2_active' : null"
@click.stop="cateChange(2, cate_2.cat_id, cate_idx_1, cate_idx_2)"
>{{cate_2.cat_name}}</view>
</view>
</view>
{{cate.cat_name}}
</view>
</scroll-view>
<view class="scroll-right flex-1">
<view class="cates_title">{{cate1_name}} {{cate2_name ? '-' + cate2_name : ''}}</view>
<pull-list
ref="pullList"
:refresherEnabled="false"
>
<view
class="goods-item flex j-start a-center"
v-for="good in goods_list"
:key="good.goods_id"
@click="navDetail(good)"
>
<image
class="goods-cover mr-2"
lazy-load
:src="baseUrl + '/' + good.goods_thumb"
mode="aspectFit"
<template v-if="goods_list.length === 0">
<view class="flex j-center a-center w-100 empty-wrap">
<empty-view
iconSrc="/static/images/common/noGoods.png"
text="该分类暂无商品"
/>
<view class="goods-price flex-1 flex flex-column j-between font-28">
<view class="title">{{good.goods_name}}</view>
<view class="descColor desc font-24 w-100 flex j-between a-center">
<text class="flex-1">{{good.specification}}</text>
<text class="sale-count text-right">销量:{{good.virtual_quantity_sold}}</text>
</view>
<view class="w-100 flex j-between a-center">
<view class="flex j-start a-center">
<price
:is_inquiry="good.is_inquiry"
:price="good.shop_price"
</view>
</template>
<template v-else>
<view class="cates_title">{{cate_name}}</view>
<pull-list
ref="pullList"
:refresherEnabled="false"
>
<view
class="goods-item flex j-start a-center"
v-for="good in goods_list"
:key="good.goods_id"
@click="navDetail(good)"
>
<image
class="goods-cover mr-2"
lazy-load
:src="baseUrl + '/' + good.goods_thumb"
mode="aspectFit"
/>
<view class="goods-price flex-1 flex flex-column j-between font-28">
<view class="title">{{good.goods_name}}</view>
<view class="descColor desc font-24 w-100 flex j-between a-center">
<text class="flex-1">{{good.specification}}</text>
<text class="sale-count text-right">销量:{{good.virtual_quantity_sold}}</text>
</view>
<view class="w-100 flex j-between a-center">
<view class="flex j-start a-center">
<price
:is_inquiry="good.is_inquiry"
:price="good.shop_price"
/>
<text class="primaryColor font-28">{{good.least_str}}</text>
</view>
<image
class="cart-icon"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
@click.stop="handlePop(good)"
/>
<text class="primaryColor font-28">{{good.least_str}}</text>
</view>
<image
class="cart-icon"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
@click.stop="handlePop(good)"
/>
</view>
</view>
</view>
<view class="empty-text text-center mt-4 p-2">到底了,看看别的分类吧~</view>
</pull-list>
<view class="empty-text text-center mt-4 p-2">到底了,看看别的分类吧~</view>
</pull-list>
</template>
</view>
</view>
</template>
<!-- 购物弹窗 -->
<goods-popup ref="popup" :fitIphoneX="false" />
......@@ -127,28 +114,24 @@
</template>
<script>
// 所有写法需要优化!!!
import pullList from '@/components/pull-list/index.vue'
import goodsPopup from '@/components/goods-popup/index.vue'
import overDue from '@/components/overDue-view/index.vue'
import price from '@/components/price/index.vue'
import { getCatetories, cateGoodsList } from '@/apis/category.js'
import { searchGoods, goodsSku } from '@/apis/goods.js'
import { baseUrl } from '@/config/index.js'
import { cateGoodsList, groupCates } from '@/apis/category.js'
import { goodsSku } from '@/apis/goods.js'
import common_share from '@/mixins/setting_share.js'
import { mapState, mapActions } from 'vuex'
import { debounce } from '@/utils/common.js'
import LoadMore from '@/utils/load-more.js'
let cat_id = 0
export default {
data() {
return {
baseUrl,
cate1_current: '1', // 和cateid对应则未选中状态
cate2_current: '0',
cate1_name: '',
cate2_name: '',
cate_cur: 0,
cate_name: '',
cate_list: [], // 分类列表
goods_list: [], // 分类商品列表
showNoMoreMsg: false
......@@ -166,32 +149,32 @@ export default {
isOverdue: state => state.user.isOverdue
})
},
// async created() {
// this.getCate()
// },
created() {
this.loadMore = new LoadMore()
},
onShow() {
uni.showLoading()
this.getCate()
this.getCateGoods()
if(this.token) {
this.setCount()
}
uni.hideLoading()
},
mixins: [common_share],
methods: {
...mapActions('cart', ['setCount']),
async getCate() {
try{
const { status, data } = await getCatetories()
const { status, data } = await groupCates()
if(status) {
let cate_list = this.cate_list
cate_list = data
cat_id = cate_list[0].cat_id
this.cate1_current = cate_list[0].cat_id
this.cate_list = cate_list
this.cate1_name = cate_list[0].cat_name
// this.cate2_name = cate_list[0].list[0].cat_name
this.cate_list = data
cat_id = data[0].id
this.cate_name = data[0].cat_name
this.getCateGoods()
}
}catch(e){
......@@ -199,7 +182,36 @@ export default {
this.$toast({title: e.msg || '获取分类失败'})
}
},
// 切换分类
handleCate(e) {
const { index } = e.target.dataset
if(this.cate_cur === index) return
const cate_list = this.cate_list
this.cate_cur = index
cat_id = cate_list[index].id
this.cate_name = cate_list[index].cat_name
this.loadMore.resetParams()
this.getCateGoods()
},
// 获取分类商品
async getCateGoods() {
try{
const { status, data } = await this.loadMore.getList({cat_id}, cateGoodsList)
if(status) {
this.goods_list = data
this.cate
} else {
this.goods_list = []
}
}catch(e){
console.log(e)
this.$toast({title: e.msg || '程序错误'})
}
},
// 切换分类 type === 1 分类1 type === 2 分类2, cate1_idx 分类一的下表
cateChange(type, cate_id, cate1_idx, cate2_idx) {
if(cat_id === cate_id) return
......@@ -219,20 +231,6 @@ export default {
this.getCateGoods()
},
// 获取分类商品
async getCateGoods() {
try{
const { status, data } = await cateGoodsList(cat_id)
if(status) {
this.goods_list = data
} else {
this.goods_list = []
}
}catch(e){
console.log(e)
this.$toast({title: e.msg || '程序错误'})
}
},
// 商品详情
navDetail(good) {
......@@ -306,30 +304,34 @@ export default {
overflow: hidden;
.scroll-left {
flex: 0 0 180rpx;
width: 180rpx;
overflow: hidden;
.cate-1_active {
color: $primary;
font-weight: bold;
}
.cate-2_active {
color: $primary;
.cate-item {
box-sizing: border-box;
width: 100%;
height: 80rpx;
padding: 0 10rpx;
line-height: 80rpx;
text-align: center;
}
.cate-active {
font-weight: bold;
color: $primary;
background-color: #fff;
}
.second-item {
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
}
.scroll-right {
position: relative;
padding-top: 72rpx;
background-color: #fff;
.empty-wrap {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.cates_title {
position: absolute;
left: 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment