Commit b828866c authored by June's avatar June

feat:商品分组分类

parent d487ee16
...@@ -5,7 +5,7 @@ import dayjs from 'dayjs' ...@@ -5,7 +5,7 @@ import dayjs from 'dayjs'
import { removeStorage } from '@/lib/storage/index.js' import { removeStorage } from '@/lib/storage/index.js'
export default { export default {
onLaunch: async function() { onLaunch: async function() {
await this.checkUpdate() // 检查更新 this.checkUpdate() // 检查更新
this.setMobileData() // 获取系统信息和胶囊信息 this.setMobileData() // 获取系统信息和胶囊信息
const extConfig = wx.getExtConfigSync ? wx.getExtConfigSync(): {} const extConfig = wx.getExtConfigSync ? wx.getExtConfigSync(): {}
this.$store.state.user.appid = extConfig.appid this.$store.state.user.appid = extConfig.appid
......
import { request } from "@/lib/service" import { request } from "@/lib/service"
/**
* @desc 获取分类列表
*/
export function getCatetories() {
return request({
url: 'zsxcx/shopGoodsCategory.htm',
method: 'post'
})
}
/** /**
* @desc 店铺商品列表接口 * @desc 店铺商品列表接口
* @param { String } keywords 关键字:商品名称 * @param { String } keywords 关键字:商品名称
* @param { Number } cat_id * 分类ID * @param { Number } cat_id * 分类ID
*/ */
export function cateGoodsList(cat_id, keywords = '') { export function cateGoodsList({cat_id, keywords = '', page = 1, pagenum = 10}) {
return request({ return request({
url: 'zsxcx/shopGoods.htm', url: 'zsxcx/shopGoodsCustom.htm',
method: 'post', method: 'post',
data: { data: {
cat_id, cat_id,
keywords keywords,
page,
pagenum
} }
}) })
} }
/**
* 店铺商品分组分类
*/
export function groupCates() {
return request({
url: 'zsxcx/shopGoodsCategoryCustom.htm',
method: 'post'
})
}
/** /**
* @desc 首页展示栏商品接口 * @desc 首页展示栏商品接口
*/ */
......
const env = { const env = {
release: 'https://www.gelifood.com', // 正式版 release: 'https://www.gelifood.com', // 正式版
trial: 'https://www.gelifood.com', // 体验版 trial: 'https://www.gelifood.com', // 体验版
develop: 'https://www.gelifood.com' // 开发版 develop: 'https://d.gelifood.com' // 开发版
} }
// 不考虑其他端小程序直接这样配置 // 不考虑其他端小程序直接这样配置
......
{ {
"extEnable": true, "extEnable": true,
"extAppid": "wx537e892e36fbf79d", "extAppid": "wxd170058f4ad8fecd",
"ext": { "ext": {
"appid": "wx537e892e36fbf79d" "appid": "wxd170058f4ad8fecd"
} }
} }
\ No newline at end of file
...@@ -147,6 +147,45 @@ export function request (options) { ...@@ -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) { export function upload(options) {
const valite_err = validateOps(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 @@ ...@@ -19,9 +19,8 @@
<text class="font-24">搜索商品</text> <text class="font-24">搜索商品</text>
</navigator> </navigator>
</view> </view>
<!-- category 未优化,可以递归组件 --> <template v-if="cate_list.length === 0">
<template v-if="goods_list.length === 0">
<view class="flex j-center a-center w-100 category"> <view class="flex j-center a-center w-100 category">
<empty-view <empty-view
iconSrc="/static/images/common/noGoods.png" iconSrc="/static/images/common/noGoods.png"
...@@ -35,90 +34,78 @@ ...@@ -35,90 +34,78 @@
class="scroll-left" class="scroll-left"
scroll-y scroll-y
:scroll-into-view="leftScrollName" :scroll-into-view="leftScrollName"
@click="handleCate"
> >
<!-- 一级分类 --> <view
<view class="cate-item overtext-1"
class="w-100 px-3 py-2" :class="cate_cur === cate_idx ? 'cate-active' : null"
v-for="(cate_1, cate_idx_1) in cate_list" v-for="(cate, cate_idx) in cate_list"
:key="cate_1.cat_id" :key="cate.id"
:class="cate1_current === cate_1.cat_id ? 'cate-active' : null" :data-index="cate_idx"
@click.stop=""
> >
{{cate.cat_name}}
<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> </view>
</scroll-view> </scroll-view>
<view class="scroll-right flex-1"> <view class="scroll-right flex-1">
<view class="cates_title">{{cate1_name}} {{cate2_name ? '-' + cate2_name : ''}}</view> <template v-if="goods_list.length === 0">
<pull-list <view class="flex j-center a-center w-100 empty-wrap">
ref="pullList" <empty-view
:refresherEnabled="false" iconSrc="/static/images/common/noGoods.png"
> text="该分类暂无商品"
<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>
<view class="title">{{good.goods_name}}</view> </template>
<view class="descColor desc font-24 w-100 flex j-between a-center"> <template v-else>
<text class="flex-1">{{good.specification}}</text> <view class="cates_title">{{cate_name}}</view>
<text class="sale-count text-right">销量:{{good.virtual_quantity_sold}}</text> <pull-list
</view> ref="pullList"
<view class="w-100 flex j-between a-center"> :refresherEnabled="false"
<view class="flex j-start a-center"> >
<price
:is_inquiry="good.is_inquiry" <view
:price="good.shop_price" 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> </view>
<image
class="cart-icon"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
@click.stop="handlePop(good)"
/>
</view> </view>
</view> </view>
</view>
<view class="empty-text text-center mt-4 p-2">到底了,看看别的分类吧~</view>
<view class="empty-text text-center mt-4 p-2">到底了,看看别的分类吧~</view>
</pull-list>
</pull-list> </template>
</view> </view>
</view> </view>
</template> </template>
<!-- 购物弹窗 --> <!-- 购物弹窗 -->
<goods-popup ref="popup" :fitIphoneX="false" /> <goods-popup ref="popup" :fitIphoneX="false" />
...@@ -127,28 +114,24 @@ ...@@ -127,28 +114,24 @@
</template> </template>
<script> <script>
// 所有写法需要优化!!!
import pullList from '@/components/pull-list/index.vue' import pullList from '@/components/pull-list/index.vue'
import goodsPopup from '@/components/goods-popup/index.vue' import goodsPopup from '@/components/goods-popup/index.vue'
import overDue from '@/components/overDue-view/index.vue' import overDue from '@/components/overDue-view/index.vue'
import price from '@/components/price/index.vue' import price from '@/components/price/index.vue'
import { getCatetories, cateGoodsList } from '@/apis/category.js' import { cateGoodsList, groupCates } from '@/apis/category.js'
import { searchGoods, goodsSku } from '@/apis/goods.js' import { goodsSku } from '@/apis/goods.js'
import { baseUrl } from '@/config/index.js'
import common_share from '@/mixins/setting_share.js' import common_share from '@/mixins/setting_share.js'
import { mapState, mapActions } from 'vuex' import { mapState, mapActions } from 'vuex'
import { debounce } from '@/utils/common.js' import { debounce } from '@/utils/common.js'
import LoadMore from '@/utils/load-more.js'
let cat_id = 0 let cat_id = 0
export default { export default {
data() { data() {
return { return {
baseUrl, cate_cur: 0,
cate1_current: '1', // 和cateid对应则未选中状态 cate_name: '',
cate2_current: '0',
cate1_name: '',
cate2_name: '',
cate_list: [], // 分类列表 cate_list: [], // 分类列表
goods_list: [], // 分类商品列表 goods_list: [], // 分类商品列表
showNoMoreMsg: false showNoMoreMsg: false
...@@ -166,32 +149,32 @@ export default { ...@@ -166,32 +149,32 @@ export default {
isOverdue: state => state.user.isOverdue isOverdue: state => state.user.isOverdue
}) })
}, },
// async created() {
// this.getCate() created() {
// }, this.loadMore = new LoadMore()
},
onShow() { onShow() {
uni.showLoading() uni.showLoading()
this.getCate() this.getCate()
this.getCateGoods()
if(this.token) { if(this.token) {
this.setCount() this.setCount()
} }
uni.hideLoading() uni.hideLoading()
}, },
mixins: [common_share], mixins: [common_share],
methods: { methods: {
...mapActions('cart', ['setCount']), ...mapActions('cart', ['setCount']),
async getCate() { async getCate() {
try{ try{
const { status, data } = await getCatetories() const { status, data } = await groupCates()
if(status) { if(status) {
let cate_list = this.cate_list this.cate_list = data
cate_list = data cat_id = data[0].id
cat_id = cate_list[0].cat_id this.cate_name = data[0].cat_name
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() this.getCateGoods()
} }
}catch(e){ }catch(e){
...@@ -199,7 +182,36 @@ export default { ...@@ -199,7 +182,36 @@ export default {
this.$toast({title: e.msg || '获取分类失败'}) 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 分类一的下表 // 切换分类 type === 1 分类1 type === 2 分类2, cate1_idx 分类一的下表
cateChange(type, cate_id, cate1_idx, cate2_idx) { cateChange(type, cate_id, cate1_idx, cate2_idx) {
if(cat_id === cate_id) return if(cat_id === cate_id) return
...@@ -219,20 +231,6 @@ export default { ...@@ -219,20 +231,6 @@ export default {
this.getCateGoods() 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) { navDetail(good) {
...@@ -306,30 +304,34 @@ export default { ...@@ -306,30 +304,34 @@ export default {
overflow: hidden; overflow: hidden;
.scroll-left { .scroll-left {
flex: 0 0 180rpx; flex: 0 0 180rpx;
width: 180rpx;
overflow: hidden; overflow: hidden;
.cate-1_active { .cate-item {
color: $primary; box-sizing: border-box;
font-weight: bold; width: 100%;
} height: 80rpx;
.cate-2_active { padding: 0 10rpx;
color: $primary; line-height: 80rpx;
text-align: center;
} }
.cate-active { .cate-active {
font-weight: bold;
color: $primary;
background-color: #fff; background-color: #fff;
} }
.second-item {
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
} }
.scroll-right { .scroll-right {
position: relative; position: relative;
padding-top: 72rpx; padding-top: 72rpx;
background-color: #fff; background-color: #fff;
.empty-wrap {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.cates_title { .cates_title {
position: absolute; position: absolute;
left: 0; 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