Browse Source

add classify for tid1878

tid1878
刘嘉炜 5 months ago
parent
commit
3f631a174c
  1. 6
      src/pages.json
  2. 2
      src/subpackage/mall/components/index_classify_bar.vue
  3. 13
      src/subpackage/mall/components/index_search_bar.vue
  4. 2
      src/subpackage/mall/components/specification_modal.vue
  5. 2
      src/subpackage/mall/js/api.js
  6. 25
      src/subpackage/mall/js/handle.js
  7. 441
      src/subpackage/mall/pages/classify.vue
  8. 36
      src/subpackage/mall/pages/goods_info.vue
  9. 12
      src/subpackage/mall/pages/index.vue
  10. BIN
      src/subpackage/mall/static/images/arrow_094.png
  11. BIN
      src/subpackage/mall/static/images/arrow_9ad_down.png

6
src/pages.json

@ -1011,6 +1011,12 @@
"style" : {
"navigationBarTitleText": "商品详情"
}
},
{
"path": "pages/classify",
"style" : {
"navigationBarTitleText": "商品分类"
}
}
]
}

2
src/subpackage/mall/components/index_classify_bar.vue

@ -12,7 +12,7 @@
</view>
</scroll-view>
<view class="icb-right-tab">
<view class="icb-right-tab" @click="$emit('click:classify')">
<image class="irt-img" mode="aspectFit" src="/subpackage/mall/static/images/classify.png"></image>
<view class="irt-txt">分类</view>
</view>

13
src/subpackage/mall/components/index_search_bar.vue

@ -7,7 +7,7 @@
</view>
<view class="isb-box" v-if="shoppingCart" @click="toShoppingCart">
<image class="ib-icon" src="/subpackage/mall/static/images/shopping_cart_333.png"></image>
<view class="ib-num">88</view>
<view class="ib-num" v-if="cartNUmShow > 0">{{ cartNUmShow }}</view>
</view>
</view>
</template>
@ -18,6 +18,17 @@ export default {
shoppingCart: {
type: Boolean,
default: false
},
cartNum: {
type: Number,
default: 0
}
},
computed: {
cartNUmShow(){
let { cartNum } = this;
if(!isNaN(cartNum))return cartNum > 99 ? 99 : cartNum;
return 0;
}
}
}

2
src/subpackage/mall/components/specification_modal.vue

@ -117,6 +117,7 @@ export default {
* @param {Array} specArr[].value 规格值
* @param {Boolean} onlyGet 是否只获取选择数据
* @param {Function} success 回调函数
* @param {Function} addCartComplete 回调函数
}
}
*/
@ -166,6 +167,7 @@ export default {
setTimeout(_=>{
this.hide();
this.resetData();
initData?.addCartComplete?.();
}, 1000);
}, 300, true),

2
src/subpackage/mall/js/api.js

@ -8,6 +8,8 @@ export const MALL_API = {
homeGoodsBuy:`${ORIGIN}/shop2/homeGoodsBuy`, //商品详情 - 立即购买
goodsCartList:`${ORIGIN}/shop2/goodsCartList`, //购物车 - 商品列表
goodsComment:`${ORIGIN}/shop2/goodsComment`, //商品评价列表
goodsList:`${ORIGIN}/shop2/goodsList`, //商品列表
goodsCateList:`${ORIGIN}/shop2/goodsCateList`, // 商品分类列表
}
export default { ORIGIN, MALL_API };

25
src/subpackage/mall/js/handle.js

@ -0,0 +1,25 @@
import { MALL_API } from "./api";
import server from "./server";
// 购物车商品列表
export function goodsCartList(brand_id){
return server.post({
url: MALL_API.goodsCartList,
data: { brand_id },
isDefaultGet: false,
})
.then(res => {
let _data = res?.data || {};
if(_data.code === 0){
let _ls = _data?.data ?? [];
//product_invalid 商品状态 0-正常 1-已失效
return ({
totalList: _ls,
validList: _ls.filter(item => item.product_invalid === 0),
invalidList: _ls.filter(item => item.product_invalid === 0),
});
}else{
return Promise.reject(_data);
}
})
}

441
src/subpackage/mall/pages/classify.vue

@ -0,0 +1,441 @@
<template>
<view class="mall-classify">
<view class="mc-search-bar">
<index-search-bar shopping-cart :cart-num="goodsCartNum"></index-search-bar>
</view>
<view class="mc-section">
<scroll-view class="ms-classify" :style="scrollStyle" scroll-y>
<view class="mc-box">
<view :class="['mc-item','defaultOne', curTab == -1 ? 'activeOne' : '',curTab==0?'filletOne':'']" @click="likeChange()">️猜你喜欢</view>
<view
v-for="(e, i) in goodsCateList"
:key="i"
:class="['mc-item', curTab == i ? 'active' : '',curTab == (i + 1)?'filletUnder':'', curTab == (i - 1)?'filletOn':'']"
@click="tabChange(e,i)"
>
{{ e.product_cate_name || '-' }}
</view>
</view>
</scroll-view>
<scroll-view class="ms-goods" :style="scrollStyle" scroll-y scroll-with-animation>
<!-- 除猜你喜欢外显示 -->
<view class="mg-tab" v-if="curTab != -1">
<view v-for="(e, i) in goodsKeyList" :key="i" :class="['mt-item', curItemTab == e.id ? 'active' : '']" @click="tabItemChange(e)">
{{ e.name }}
<view v-if="curItemTab == i && curItemTab!=0">
<image
:src="isSort ? '/subpackage/mall/static/images/arrow_9ad_down.png' : '/subpackage/mall/static/images/arrow_094.png'"
:style="isSort ? 'transform: rotateZ(180deg)' : ''"
></image>
<image
:src="isSort ? '/subpackage/mall/static/images/arrow_094.png' : '/subpackage/mall/static/images/arrow_9ad_down.png'"
:style="isSort ? 'transform: rotateZ(180deg)' : ''"
></image>
</view>
</view>
</view>
<view class="mg-list">
<view class="ml-item" v-for="(e, i) in goodsList" :key="i" @click="goodsItemChange(e.id)">
<image mode="aspectFill" :src="e.product_imgs[0] || ''"></image>
<view>
<view>{{e.product_name || ''}}</view>
<view>{{e.product_text || ''}}</view>
<!-- 特价标签 现在不做 -->
<!-- <view class="mi-tags">
<view class="mt-b">特价</view>
</view> -->
<view class="mi-price">
<view class="mp-price">
<text>¥</text>
<text>{{e.product_price || 0}}</text>
<!-- 单位: /2 -->
<text>{{''}}</text>
<text v-if="e.product_spec_multi == 0 && e.product_price_show != 0">¥{{e.product_price_show || 0}}</text>
</view>
<view class="mp-btn" @click.stop="addGoodsChange(e)"></view>
</view>
</view>
</view>
</view>
<view class="mg-tip">我是有底线的</view>
</scroll-view>
</view>
<!-- 分类 -->
<spacification-modal ref="spacificationModal" button-txt="加入购物车"></spacification-modal>
</view>
</template>
<script>
import { routeTo, showLoad, hideLoad, showModal, getNodeMes } from "@/utils/util.js";
import { MALL_API } from "../js/api";
import server from "../js/server";
import { goodsCartList } from "../js/handle";
import spacificationModal from "../components/specification_modal.vue";
import indexSearchBar from "../components/index_search_bar.vue";
export default {
components: { spacificationModal, indexSearchBar },
computed: {
scrollStyle() {
let { scrollHeight } = this;
return `height: ${scrollHeight}px;`;
}
},
data() {
return {
scrollHeight: 658, // 658 ipx
brand_id: '',
curTab: -1, //id, -1
curItemTab: 0,
isSort: true,
goodsKeyList: [{id: 0, name: '综合'},{id: 1, name: '销量'},{id: 2, name: '价格'}],
goodsCateList: [], //
goodsList: [], //
goodsCartNum: 0, //
cateId: -1,
};
},
async onLoad(opts) {
let _bid = opts?.brand_id ?? '';
this.brand_id = _bid
this.setScrollHeight();
this.getCateList(_bid);
this.getGoodsList({ brand_id: _bid, recommend: 1 });
},
async onShow() {
let { brand_id } = this;
this.getCartList(brand_id);
},
methods: {
async setScrollHeight() {
let searchBar = await getNodeMes('.mc-search-bar');
let sysInfo = uni.getWindowInfo();
this.scrollHeight = (sysInfo.windowHeight - searchBar.height) || 658; // 658 ipx
},
//
tabChange(e,i) {
let { brand_id } = this;
this.isSort = true
this.curTab = i;
this.cateId = e.id
this.getGoodsList({ brand_id, cateid: e.id });
},
//
likeChange(){
let { brand_id } = this;
this.curTab = -1;
this.getGoodsList({ brand_id, recommend: 1 });
},
//
tabItemChange(e) {
let { brand_id } = this;
this.curItemTab = e.id;
this.isSort = !this.isSort;
let sort = '';
if(e.id == 1 && !this.isSort) sort = 'product_sale_nums|desc'; //
if(e.id == 1 && this.isSort) sort = 'product_sale_nums|asc'; //
if(e.id == 2 && !this.isSort) sort = 'product_price|desc'; //
if(e.id == 2 && this.isSort) sort = 'product_price|asc'; //
this.$nextTick(_=>{
this.getGoodsList({
brand_id,
cateid: this.cateId,
show_sort: sort,
});
})
},
goodsItemChange(id) {
let { brand_id } = this;
routeTo(`/subpackage/mall/pages/goods_info?id=${id}&brand_id=${brand_id}`,'nT')
},
async addGoodsChange(e) {
let { brand_id } = this;
//
// product_spec_multi 1
if(e.product_spec_multi == 1){
return this.$refs.spacificationModal.alert({
id: e?.id ?? '',
brand_id: brand_id,
poster: e?.product_imgs?.[0] ?? '',
name: e?.product_name ?? '',
price: e?.product_price ?? '',
specArr: e?.product_spec ?? [],
addCartComplete: res => {
this.getCartList(brand_id);
}
});
}
//
await this.$refs?.spacificationModal?.goodsCartAdd({ brand_id, id: e?.id, });
this.getCartList(brand_id);
},
//
getCateList(brand_id) {
showLoad();
return server.post({
url: MALL_API.goodsCateList,
data: { brand_id},
isDefaultGet: false,
})
.then(res => {
hideLoad();
let _data = res?.data || {};
if(_data.code === 0){
return this.goodsCateList = _data?.data ?? [];
}else{
return Promise.reject(_data);
}
})
.catch(err => {
hideLoad();
showModal({ content: err.message || '加载失败!' });
console.warn('subpackage mall pages classify getCateList err --->', err);
})
},
// psrecommend1ID;
getGoodsList({brand_id, cateid='', show_sort='', recommend='', page = 1, page_size = 20}){
// show_sort: egproduct_price|descproduct_sale_nums|asc
// product_price product_sale_nums descdescasc
// show_sort
let _query = { brand_id, cateid, show_sort, recommend, page, page_size };
showLoad();
return server.post({
url: MALL_API.goodsList,
data: _query,
isDefaultGet: false,
})
.then(res => {
hideLoad();
let _data = res?.data || {};
if(_data.code === 0){
return this.goodsList = _data?.data?.list ?? [];
}else{
return Promise.reject(_data);
}
})
.catch(err => {
hideLoad();
showModal({ content: err.message || '加载失败!' });
console.warn('subpackage mall pages classify getGoodsList err --->', err);
})
},
// -
async getCartList(brand_id) {
try{
let { validList } = await goodsCartList(brand_id);
let _length = validList?.length ?? 0;
this.goodsCartNum = _length > 100 ? 99 : _length;
}catch(err){
console.warn('subpackage mall pages classify getCartList err --->', err);
}
},
}
};
</script>
<style lang="scss">
.mall-classify {
.mc-section {
display: flex;
justify-content: space-between;
.ms-classify {
flex-shrink: 0;
flex-grow: 0;
width: 180upx;
background-color: #ededf5;
.mc-box{
background-color: #fff;
}
.mc-item {
padding: 0 10upx;
height: 92upx;
line-height: 92upx;
text-align: center;
font-size: 28upx;
color: #9a9a9d;
background-color: #ededf5;
@include tHide(1);
}
.active {
font-weight: 500;
background-color: #fff;
}
.filletOn{
border-top-right-radius: 10rpx;
}
.filletUnder{
border-bottom-right-radius: 10rpx;
}
.filletOne{
border-bottom-right-radius: 10rpx;
}
.defaultOne {
color: #333;
}
.activeOne {
color: $mColor;
background-color: #fff;
}
}
.ms-goods {
// width: 570upx;
flex-grow: 1;
.mg-tab {
flex-grow: 1;
width: 100%;
height: 92rpx;
padding: 0rpx 40rpx;
background-color: #fbfbff;
@include ctf(space-between);
//
/* #ifndef APP-PLUS-NVUE */
display: flex;
position: -webkit-sticky;
/* #endif */
position: sticky;
top: var(--window-top);
z-index: 6;
.mt-item {
color: #9a9a9d;
font-size: 24rpx;
min-width: 80rpx;
@include ctf(flex-start);
> view {
margin-left: 10rpx;
display: flex;
flex-direction: column;
> image {
flex-shrink: 0;
width: 12rpx;
height: 12rpx;
}
}
}
.active {
color: $mColor;
}
}
.mg-list {
padding: 20upx 20upx 30upx;
background-color: #fff;
.ml-item {
padding-bottom: 28upx;
display: flex;
justify-content: space-between;
> image {
flex-shrink: 0;
margin-right: 20upx;
width: 172upx;
height: 172upx;
}
> view {
flex-grow: 1;
background-color: #fff;
> view:first-child {
margin-bottom: 10upx;
font-size: 28upx;
line-height: 40upx;
@include tHide(2);
}
> view:nth-child(2) {
margin-bottom: 14upx;
line-height: 32upx;
min-height: 32rpx;
font-size: 22upx;
color: #9a9a9d;
@include tHide(1);
}
.mi-tags {
margin-bottom: 10upx;
@include ctf(flex-start);
.mt-a {
margin-right: 10upx;
padding: 0 6upx;
border-radius: 6upx;
line-height: 28upx;
font-size: 20upx;
color: #ff873d;
background: rgba(246, 132, 62, 0.28);
}
.mt-b {
padding: 0 8upx;
font-size: 20upx;
line-height: 28upx;
border-radius: 8upx;
color: #e60012;
border: 2upx solid rgba($color: #e60213, $alpha: 0.5);
// background: rgba(230, 0, 18, 0.13);
}
}
.mi-price {
@include ctf(space-between);
.mp-price {
flex-grow: 1;
@include tHide(1);
line-height: 40upx;
color: #ff873d;
> text {
&:first-child {
font-size: 28upx;
}
&:nth-child(2) {
font-size: 36upx;
}
&:nth-child(3) {
font-size: 26upx;
color: #333;
}
&:nth-child(4) {
font-size: 26upx;
color: #9a9a9d;
text-decoration: line-through;
margin-left: 30upx;
}
}
}
.mp-btn {
flex-shrink: 0;
flex-grow: 0;
position: relative;
margin-left: 10upx;
width: 36upx;
height: 36upx;
border-radius: 50%;
background-color: $mColor;
&::before,
&::after {
content: '';
display: block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
border-radius: 2upx;
width: 20upx;
height: 4upx;
}
&::after {
height: 20upx;
width: 4upx;
}
}
}
}
}
}
.mg-tip {
height: 200upx;
line-height: 200upx;
text-align: center;
font-size: 28upx;
color: #9a9a9d;
background-color: #f2f2f7;
}
}
}
}
</style>

36
src/subpackage/mall/pages/goods_info.vue

@ -138,6 +138,7 @@ import specificationModal from "../components/specification_modal.vue";
import appraiseItem from "../components/appraise_item.vue";
import { MALL_API } from "../js/api";
import server from "../js/server";
import { goodsCartList } from "../js/handle";
export default {
components: {
serviceModal,
@ -351,7 +352,6 @@ export default {
hideLoad();
let _data = res?.data || {};
if(_data.code === 0){
console.log('subpackage mall pages goods_info getGoodsInfo res --->', _data);
return this.goodsInfo = _data?.data ?? {};
}else{
return Promise.reject(_data);
@ -359,10 +359,7 @@ export default {
})
.catch(err => {
hideLoad();
showModal({
title: '提示',
content: err.message || '加载失败!'
})
showModal({ content: err.message || '加载失败!' });
console.warn('subpackage mall pages goods_info getGoodsInfo err --->', err);
})
},
@ -394,29 +391,14 @@ export default {
})
},
//
goodsCartList({ brand_id }){
return server.post({
url: MALL_API.goodsCartList,
data: { brand_id },
isDefaultGet: false,
})
.then(res => {
let _data = res?.data || {};
if(_data.code === 0){
console.log('subpackage mall pages goods_info goodsCartList res --->', _data);
let _ls = _data?.data ?? [];
//product_invalid 0- 1-
let validLs = _ls.filter(item => item.product_invalid === 0);
let _length = validLs?.length ?? 0;
this.goodsCartNum = _length > 100 ? 99 : _length;
return _ls;
}else{
return Promise.reject(_data);
}
})
.catch(err => {
async goodsCartList({ brand_id }){
try{
let { validList } = await goodsCartList(brand_id);
let _length = validList?.length ?? 0;
this.goodsCartNum = _length > 100 ? 99 : _length;
}catch(err){
console.warn('subpackage mall pages goods_info goodsCartList err --->', err);
})
}
},
/**
* 获取商品评价列表

12
src/subpackage/mall/pages/index.vue

@ -48,6 +48,7 @@
<index-classify-bar
:classify-ls="goodsCateClassify"
v-model="goodsCateIdx"
@click:classify="toClassify"
></index-classify-bar>
<view class="mi-classify-list">
<view class="mcl-item" v-for="(e, i) in goodsCateList" :key="i">
@ -118,6 +119,10 @@ export default {
this.getHomeData({ brand_id: _bid });
},
methods: {
toClassify(){
let { brand_id } = this;
routeTo(`/subpackage/mall/pages/classify?brand_id=${brand_id}`,'nT');
},
getGridLsFor(key){
let { showdata } = this;
return showdata?.[key]?.grid_setting ?? [];
@ -149,11 +154,6 @@ export default {
//
// product_spec_multi 1
if(e.product_spec_multi == 1){
// e.product_spec.push({
// id: 3,
// name: 'test',
// value: ['test1', 'test2', 'test3']
// })
this.$refs.spacificationModal.alert({
id: e?.id ?? '',
brand_id: brand_id,
@ -166,8 +166,6 @@ export default {
}
this.$refs?.spacificationModal?.goodsCartAdd({ brand_id, id: e?.id, });
},
//
isShow(val) {

BIN
src/subpackage/mall/static/images/arrow_094.png

After

Width: 12  |  Height: 14  |  Size: 169 B

BIN
src/subpackage/mall/static/images/arrow_9ad_down.png

After

Width: 12  |  Height: 14  |  Size: 165 B

Loading…
Cancel
Save