mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2025-12-06 18:03:27 +08:00
【新增】前端【分类】模块集成仿点餐模式,并添加了可后台选择。
This commit is contained in:
@@ -17,3 +17,95 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.main { width: 100%; height: 100%; position: relative; display: flex; flex-direction: column; }
|
||||
|
||||
.nav { width: 100%; height: 212rpx; flex-shrink: 0; display: flex; flex-direction: column;
|
||||
.header { width: 100%; display: flex; align-items: center; justify-content: space-between; padding: 20rpx; background-color: #ffffff; height: 140rpx;
|
||||
.left { flex: 1; display: flex; flex-direction: column;
|
||||
.store-name { display: flex; justify-content: flex-start; align-items: center; font-size: 32rpx; margin-bottom: 10rpx;
|
||||
.iconfont { margin-left: 10rpx; line-height: 100%; }
|
||||
}
|
||||
.store-location { display: flex; justify-content: flex-start; align-items: center; color: #919293; font-size: 24rpx;
|
||||
.iconfont { vertical-align: middle; display: table-cell; color: #ADB838; line-height: 100%; }
|
||||
}
|
||||
}
|
||||
.right { background-color: #F5F5F5; border-radius: 38rpx; display: flex; align-items: center; font-size: 24rpx; padding: 0 38rpx; color: #919293;
|
||||
.dinein, .takeout { position: relative; display: flex; align-items: center;
|
||||
&.active { padding: 14rpx 38rpx; color: #ffffff; background-color: #E8EACF; border-radius: 38rpx; }
|
||||
}
|
||||
.takeout { margin-left: 20rpx; height: 100%; flex: 1; padding: 14rpx 0; }
|
||||
.dinein.active { margin-left: -38rpx; }
|
||||
.takeout.active { margin-right: -38rpx; }
|
||||
}
|
||||
}
|
||||
.coupon { flex: 1; width: 100%; background-color: #E8EACF; font-size: 28rpx; color: #ADB838; padding: 0 20rpx; display: flex; align-items: center; overflow: hidden;
|
||||
.title { flex: 1; margin-left: 10rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.iconfont { line-height: 100%; }
|
||||
}
|
||||
}
|
||||
.content { flex: 1; overflow: hidden; width: 100%; display: flex;
|
||||
.menus { width: 200rpx; overflow: hidden; background-color: #F5F5F5;
|
||||
.wrapper { width: 100%; height: 100%;
|
||||
.menu { display: flex; align-items: center; justify-content: flex-start; padding: 30rpx 20rpx; font-size: 26rpx; color: #919293; position: relative;
|
||||
&:nth-last-child(1) { margin-bottom: 130rpx; }
|
||||
&.current { background-color: #ffffff; color: #5A5B5C; }
|
||||
.dot { position: absolute; width: 34rpx; height: 34rpx; line-height: 34rpx; font-size: 22rpx; background-color: #ADB838; color: #ffffff; top: 16rpx; right: 10rpx; border-radius: 100%; text-align: center; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods { flex: 1; overflow: hidden; background-color: #ffffff;
|
||||
.wrapper { width: 100%; height: 100%; padding: 20rpx;
|
||||
.ads { height: calc(300 / 550 * 510rpx);
|
||||
image { width: 100%; height: 100%; border-radius: 8rpx; }
|
||||
}
|
||||
.list { width: 100%; font-size: 28rpx; padding-bottom: 30rpx;
|
||||
.category { width: 100%;
|
||||
.title { padding: 30rpx 0; display: flex; align-items: center; color: #5A5B5C;
|
||||
.icon { width: 38rpx; height: 38rpx; margin-left: 10rpx; }
|
||||
}
|
||||
}
|
||||
.items { display: flex; flex-direction: column; padding-bottom: -30rpx;
|
||||
.good { display: flex; align-items: center; margin-bottom: 30rpx;
|
||||
.image { width: 160rpx; height: 160rpx; margin-right: 20rpx; border-radius: 8rpx; }
|
||||
.right { flex: 1; height: 160rpx; overflow: hidden; display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; padding-right: 14rpx;
|
||||
.name { font-size: 28rpx; margin-bottom: 10rpx; }
|
||||
.tips { width: 100%; height: 40rpx; line-height: 40rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 24rpx; color: #919293; margin-bottom: 10rpx; }
|
||||
.price_and_action { width: 100%; display: flex; justify-content: space-between; align-items: center;
|
||||
.price { font-size: 28rpx; font-weight: 600; }
|
||||
.btn-group { display: flex; justify-content: space-between; align-items: center; position: relative;
|
||||
.btn { padding: 0 20rpx; box-sizing: border-box; font-size: 24rpx; height: 44rpx; line-height: 44rpx;
|
||||
&.property_btn { border-radius: 24rpx; }
|
||||
&.add_btn,
|
||||
&.reduce_btn { padding: 0; width: 44rpx; border-radius: 44rpx; }
|
||||
}
|
||||
.dot { position: absolute; background-color: #ffffff; border: 1px solid #ADB838; color: #ADB838; font-size: 24rpx; width: 36rpx; height: 36rpx; line-height: 36rpx; text-align: center; border-radius: 100%; right: -12rpx; top: -10rpx; }
|
||||
.number { width: 44rpx; height: 44rpx; line-height: 44rpx; text-align: center; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.cart-box { position: fixed; bottom: 30rpx; left: 30rpx; right: 30rpx; height: 96rpx; border-radius: 48rpx; box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.2); background-color: #FFFFFF; display: flex; align-items: center; justify-content: space-between; z-index: 10;
|
||||
.cart-img { width: 96rpx; height: 96rpx; position: relative; margin-top: -48rpx; }
|
||||
.pay-btn { height: 100%; padding: 0 30rpx; color: #FFFFFF; border-radius: 0 50rpx 50rpx 0; display: flex; align-items: center; font-size: 28rpx; }
|
||||
.mark { padding-left: 46rpx; margin-right: 30rpx; position: relative;
|
||||
.tag { background-color: #FAB714; color: #ffffff; display: flex; justify-content: center; align-items: center; font-size: 24rpx; position: absolute; right: -10rpx; top: -50rpx; border-radius: 100%; padding: 4rpx; width: 40rpx; height: 40rpx; opacity: .9; }
|
||||
}
|
||||
.price { flex: 1; color: #5A5B5C; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
.text-color-base { color: #5A5B5C; }
|
||||
text-color-assist { color: #919293; }
|
||||
.overflow-hidden { overflow: hidden !important; }
|
||||
.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
@@ -52,13 +52,75 @@
|
||||
</scroll-view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="u-menu-wrap coreshop-flex-direction-row" v-if="CateStyle==4">
|
||||
<view class="main" :style="'height:' + scorllH+'px;'">
|
||||
<view class="content" :style="'height:' + scorllH+'px;'">
|
||||
<scroll-view class="menus" scroll-with-animation scroll-y :scroll-top="headerH" :style="'height:' + scorllH+'px;'">
|
||||
<view class="wrapper">
|
||||
<view class="menu" :id="`menu-${item.id}`" :class="{'current': item.id === currentCateId}" v-for="(item, index) in menus"
|
||||
:key="index" @tap="handleMenuTap(item.id)">
|
||||
<text>{{ item.name }}</text>
|
||||
<!--<view class="dot" v-show="menuCartNum(item.id)">{{ menuCartNum(item.id) }}</view>-->
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<scroll-view class="goods" scroll-with-animation scroll-y :scroll-top="headerH" :style="'height:' + scorllH+'px;'">
|
||||
<view class="wrapper">
|
||||
<view class="list">
|
||||
<view class="category" v-for="(good, key) in goodsList" :key="key" :id="`cate-${good.id}`">
|
||||
<view class="items">
|
||||
<view class="good">
|
||||
<image :src="good.images" class="image" @tap="goGoodsDetail(good.id)"></image>
|
||||
<view class="right">
|
||||
<text class="name u-line-1" @tap="goGoodsDetail(good.id)">{{ good.name }}</text>
|
||||
<text class="tips u-line-1" @tap="goGoodsDetail(good.id)">{{ good.brief }}</text>
|
||||
<view class="price_and_action">
|
||||
<text class="price">¥{{ good.price }}</text>
|
||||
<view class="btn-group">
|
||||
<button type="primary" class="btn property_btn" hover-class="none" size="mini" @tap="showGoodSkuModal(good)">
|
||||
选规格
|
||||
</button>
|
||||
<!--<view class="dot">111</view>-->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore :status="status" :icon-type="iconType" :load-text="loadText" margin-top="20" margin-bottom="20" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 购物车栏 end -->
|
||||
</view>
|
||||
|
||||
<vk-data-goods-sku-popup ref="skuPopup"
|
||||
v-model="skuKey"
|
||||
border-radius="20"
|
||||
:amount-type="0"
|
||||
:localdata="goodsSkuInfo"
|
||||
:mode="skuMode"
|
||||
@open="onOpenSkuPopup"
|
||||
@close="onCloseSkuPopup"
|
||||
@add-cart="addCart"
|
||||
@buy-now="buyNow"></vk-data-goods-sku-popup>
|
||||
</view>
|
||||
<!-- 购物车栏 begin -->
|
||||
<view class="cart-box">
|
||||
<view class="mark">
|
||||
<image src="https://files.cdn.coreshop.cn/static/template/diancan/images/cart.png" class="cart-img"></image>
|
||||
<view class="tag">{{cartNums}}</view>
|
||||
</view>
|
||||
<view class="price">¥{{cartMoney}}</view>
|
||||
<button type="primary" class="pay-btn" @tap="redirectCart" :disabled="cartNums<=0">去结算</button>
|
||||
</view>
|
||||
<!-- 登录提示 -->
|
||||
<coreshop-login-modal></coreshop-login-modal>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import { mapMutations, mapActions, mapState } from 'vuex';
|
||||
export default {
|
||||
|
||||
data() {
|
||||
@@ -70,28 +132,89 @@
|
||||
menuItemHeight: 0, // 左边菜单item的高度,
|
||||
beans: [],
|
||||
isChild: false,
|
||||
searchKey: ''
|
||||
searchKey: '',
|
||||
|
||||
headerH: 0,
|
||||
scorllH: 0, //滚动区域全屏
|
||||
cartNums: 0, // 购物车数量
|
||||
cartMoney: 0, // 购物车数量
|
||||
menus: [],//所有分类
|
||||
goodsList: [], //所有商品
|
||||
menuScrollIntoView: '',
|
||||
good: {},
|
||||
currentCateId: 0,//默认分类
|
||||
scrollTop: 0,
|
||||
loadStatus: 'loadmore',
|
||||
loadIconType: 'flower',
|
||||
loadText: {
|
||||
loadmore: '轻轻上拉',
|
||||
loading: '努力加载中',
|
||||
nomore: '实在没有了'
|
||||
},
|
||||
type: 2, // 1加入购物车 2购买
|
||||
cartType: this.$globalConstVars.paymentType.common,
|
||||
page: 1,
|
||||
limit: 10,
|
||||
// 是否打开SKU弹窗
|
||||
skuKey: false,
|
||||
// SKU弹窗模式
|
||||
skuMode: 1,
|
||||
// 后端返回的商品信息
|
||||
goodsSkuInfo: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
hasLogin: state => state.hasLogin,
|
||||
userInfo: state => state.userInfo,
|
||||
}),
|
||||
hasLogin: {
|
||||
get() {
|
||||
return this.$store.state.hasLogin;
|
||||
},
|
||||
set(val) {
|
||||
this.$store.commit('hasLogin', val);
|
||||
}
|
||||
},
|
||||
userInfo: {
|
||||
get() {
|
||||
return this.$store.state.userInfo;
|
||||
},
|
||||
set(val) {
|
||||
this.$store.commit('userInfo', val);
|
||||
}
|
||||
},
|
||||
CateStyle() {
|
||||
return this.$store.state.config.cateStyle ? this.$store.state.config.cateStyle : 3;
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
uni.getSystemInfo({
|
||||
success: (e) => {
|
||||
// #ifndef MP
|
||||
this.StatusBar = e.statusBarHeight;
|
||||
if (e.platform == 'android') {
|
||||
this.headerH = e.statusBarHeight + 50;
|
||||
} else {
|
||||
this.headerH = e.statusBarHeight + 45;
|
||||
};
|
||||
// #endif
|
||||
this.scorllH = e.windowHeight - e.statusBarHeight - 50;
|
||||
}
|
||||
})
|
||||
|
||||
this.categories();
|
||||
// 获取购物车数量
|
||||
if (this.$store.state.config.cateStyle == 4) {
|
||||
this.getCartNums();
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
if (this.loadStatus != 'nomore') {
|
||||
this.getGoods();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
categories() {
|
||||
this.$u.api.categories().then(res => {
|
||||
if (res.status) {
|
||||
this.tabbar = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
getImg() {
|
||||
return Math.floor(Math.random() * 35);
|
||||
},
|
||||
// 点击左边的栏目切换
|
||||
async swichMenu(index) {
|
||||
if (index == this.current) return;
|
||||
@@ -131,7 +254,209 @@
|
||||
} else {
|
||||
this.$refs.uToast.show({ message: '请输入查询关键字', type: 'warning', })
|
||||
}
|
||||
}
|
||||
},
|
||||
categories() {
|
||||
this.$u.api.categories().then(res => {
|
||||
if (res.status) {
|
||||
this.tabbar = res.data;
|
||||
if (this.$store.state.config.cateStyle == 4) {
|
||||
this.menus = res.data;
|
||||
if (res.data.length > 0) {
|
||||
this.currentCateId = res.data[0].id;
|
||||
|
||||
}
|
||||
this.getGoods();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 打开sku弹出
|
||||
openSkuPopup() {
|
||||
this.skuKey = true;
|
||||
},
|
||||
closeSkuPopup() {
|
||||
this.skuKey = false;
|
||||
},
|
||||
// sku组件监听
|
||||
onOpenSkuPopup() {
|
||||
//console.log("监听 - 打开sku组件");
|
||||
},
|
||||
onCloseSkuPopup() {
|
||||
//console.log("监听 - 关闭sku组件");
|
||||
},
|
||||
showGoodSkuModal(item) {
|
||||
console.log(item);
|
||||
if (item.id) {
|
||||
this.getGoodsDetail(item.id);
|
||||
}
|
||||
},
|
||||
// 获取商品详情
|
||||
getGoodsDetail(goodsId) {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
let _this = this;
|
||||
let data = {
|
||||
id: goodsId,
|
||||
data: true
|
||||
}
|
||||
// 如果用户已经登录 要传用户token
|
||||
let userToken = this.$db.get("userToken");
|
||||
if (userToken) {
|
||||
this.$u.api.goodsDetailByToken(data).then(res => {
|
||||
if (res.status == true) {
|
||||
_this.goodsSkuInfo = res.data.skuList;
|
||||
_this.openSkuPopup();
|
||||
uni.hideLoading();
|
||||
} else {
|
||||
_this.$refs.uToast.show({
|
||||
message: res.msg, type: 'error', complete: function () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}
|
||||
})
|
||||
uni.hideLoading();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$u.api.goodsDetail(data).then(res => {
|
||||
if (res.status == true) {
|
||||
_this.goodsSkuInfo = res.data.skuList;
|
||||
_this.openSkuPopup();
|
||||
uni.hideLoading();
|
||||
} else {
|
||||
_this.$refs.uToast.show({
|
||||
message: res.msg, type: 'error', complete: function () {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}
|
||||
})
|
||||
uni.hideLoading();
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 加入购物车按钮
|
||||
addCart(selectShop) {
|
||||
//console.log("监听 - 加入购物车");
|
||||
//console.log(selectShop);
|
||||
var that = this;
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
if (!this.hasLogin) {
|
||||
uni.hideLoading();
|
||||
this.$store.commit('showLoginTip', true);
|
||||
return false;
|
||||
}
|
||||
if (selectShop.buy_num > 0) {
|
||||
let data = {
|
||||
productId: selectShop._id,
|
||||
nums: selectShop.buy_num,
|
||||
type: 1,
|
||||
}
|
||||
this.$u.api.addCart(data).then(res => {
|
||||
if (res.status) {
|
||||
uni.hideLoading();
|
||||
that.getCartNums(); // 获取购物车数量
|
||||
that.$refs.uToast.show({ message: res.msg, type: 'success' });
|
||||
} else {
|
||||
that.$u.toast(res.msg);
|
||||
uni.hideLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
that.closeSkuPopup();
|
||||
},
|
||||
// 立即购买
|
||||
buyNow(selectShop) {
|
||||
//console.log("监听 - 立即购买");
|
||||
//console.log(selectShop);
|
||||
var that = this;
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
if (!this.hasLogin) {
|
||||
uni.hideLoading();
|
||||
this.$store.commit('showLoginTip', true);
|
||||
return false;
|
||||
}
|
||||
if (selectShop.buy_num > 0) {
|
||||
let data = {
|
||||
productId: selectShop._id,
|
||||
nums: selectShop.buy_num,
|
||||
type: 2,
|
||||
cartType: this.cartType
|
||||
}
|
||||
this.$u.api.addCart(data).then(res => {
|
||||
if (res.status) {
|
||||
let cartIds = res.data;
|
||||
that.$u.route('/pages/placeOrder/index/index?cartIds=' + JSON.stringify(cartIds));
|
||||
uni.hideLoading();
|
||||
} else {
|
||||
this.$u.toast(res.msg);
|
||||
uni.hideLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
that.closeSkuPopup();
|
||||
},
|
||||
|
||||
handleMenuTap(id) {
|
||||
this.currentCateId = id
|
||||
this.page = 1;
|
||||
this.goodsList = [];
|
||||
this.getGoods();
|
||||
//this.$nextTick(() => this.cateScrollTop = this.goods.find(item => item.id == id).top)
|
||||
},
|
||||
//取得商品数据
|
||||
getGoods: function () {
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
var _this = this;
|
||||
let data = {
|
||||
page: this.page,
|
||||
limit: this.limit,
|
||||
};
|
||||
var where = {
|
||||
catId: this.currentCateId,
|
||||
};
|
||||
data.where = JSON.stringify(where);
|
||||
_this.$u.api.goodsList(data).then(res => {
|
||||
if (res.status) {
|
||||
const _list = res.data.list;
|
||||
_this.goodsList = [..._this.goodsList, ..._list];
|
||||
if (res.data.totalCount > _this.goodsList.length) {
|
||||
_this.loadStatus = 'loadmore';
|
||||
_this.page++;
|
||||
} else {
|
||||
// 数据已加载完毕
|
||||
_this.loadStatus = 'nomore';
|
||||
}
|
||||
uni.hideLoading();
|
||||
} else {
|
||||
// 接口请求出错了
|
||||
uni.hideLoading();
|
||||
this.$u.toast(res.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取购物车数量
|
||||
getCartNums() {
|
||||
let userToken = this.$db.get("userToken");
|
||||
if (userToken && userToken != '') {
|
||||
// 获取购物车数量
|
||||
this.$u.api.getCartNumAndMoney().then(res => {
|
||||
if (res.status) {
|
||||
this.cartNums = res.data.count;
|
||||
this.cartMoney = res.data.money;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
BIN
CoreCms.Net.Web.Admin/wwwroot/static/images/common/diancan.png
Normal file
BIN
CoreCms.Net.Web.Admin/wwwroot/static/images/common/diancan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 206 KiB |
@@ -253,6 +253,10 @@
|
||||
<input type="radio" lay-filter="cateStyle" name="cateStyle" value="3" title="二级小图" {{d.data.configs['cateStyle']['sValue']==="3" ? 'checked':''}}>
|
||||
<img src="/static/images/common/two-small.png" onclick="layui.coreHelper.viewImage('/static/images/common/two-small.png')">
|
||||
</div>
|
||||
<div class="classifyimg-item">
|
||||
<input type="radio" lay-filter="cateStyle" name="cateStyle" value="4" title="仿点餐模式" {{d.data.configs['cateStyle']['sValue']==="4" ? 'checked':''}}>
|
||||
<img src="/static/images/common/diancan.png" onclick="layui.coreHelper.viewImage('/static/images/common/diancan.png')">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux list-tag">
|
||||
1、一级大图分类图标尺寸建议:350px*150px<br />
|
||||
2、一级小图分类图标尺寸建议:105px*105px<br />
|
||||
|
||||
Reference in New Issue
Block a user