hui.zhou
parent
9740568620
commit
61fddda672
|
|
@ -9,6 +9,9 @@
|
||||||
<block v-if="showShrough">
|
<block v-if="showShrough">
|
||||||
<view v-if="goods['market_price']!=undefined && goods.market_price" class="fontFam line-through text-txGray text-20rpx">¥{{goods.market_price}}</view>
|
<view v-if="goods['market_price']!=undefined && goods.market_price" class="fontFam line-through text-txGray text-20rpx">¥{{goods.market_price}}</view>
|
||||||
</block>
|
</block>
|
||||||
|
<view v-if="cart" @click.stop="onCart">
|
||||||
|
<u-icon size="46" color="#f0ad4e" name="shopping-cart"></u-icon>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex items-center justify-between">
|
<view class="flex items-center justify-between">
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
|
|
@ -19,6 +22,7 @@
|
||||||
<view v-if="isCollection">
|
<view v-if="isCollection">
|
||||||
<u-icon size="36" color="#f0ad4e" name="star-fill"></u-icon>
|
<u-icon size="36" color="#f0ad4e" name="star-fill"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -42,12 +46,20 @@ export default {
|
||||||
showShrough:{
|
showShrough:{
|
||||||
type:Boolean,
|
type:Boolean,
|
||||||
default:false
|
default:false
|
||||||
|
},
|
||||||
|
cart:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {
|
||||||
|
onCart(){
|
||||||
|
this.$emit('cartClick',this.goods)
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,263 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<cu-navbar class="cu-navbar" :background="{ background: '#f5f5f5' }" :border-bottom="false" :isBack="false" :title="`购物车(${cartList.length})`">
|
||||||
|
<view slot="left" class="flex items-center pl-base text-xl font-medium text-txBase font-extrabold">
|
||||||
|
<!-- 左边返回箭头 -->
|
||||||
|
<view class="w-20rpx flex items-center mr-10rpx" @tap="back" v-if="isBack">
|
||||||
|
<image class="w-20rpx" src="/static/images/user/left_arrow.png" mode="widthFix"></image>
|
||||||
|
</view>
|
||||||
|
<!-- <view>购物车<text class="text-md">({{ cartList.length }})</text></view> -->
|
||||||
|
</view>
|
||||||
|
<!-- <view slot="right" class="mx-base relative" @tap="$u.route('/pageA/news/index')">
|
||||||
|
<u-icon name="chat" size="48"></u-icon>
|
||||||
|
<u-badge :is-dot="true" size="16" :offset="[0, 2]" type="warning"></u-badge>
|
||||||
|
</view> -->
|
||||||
|
<block v-if="isLogin">
|
||||||
|
<view class="pl-base text-xl font-medium text-txBase" @tap="changeEdit">
|
||||||
|
{{ navBarLeftText }}
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</cu-navbar>
|
||||||
|
<!-- 已登录 -->
|
||||||
|
<block v-if="cartList.length > 0">
|
||||||
|
<view class="bg-white rounded-xs card mx-base">
|
||||||
|
<block v-for="(item, index) in cartList" :key="item.id">
|
||||||
|
<cart-goods-item
|
||||||
|
:data="item"
|
||||||
|
:goods="item.sku"
|
||||||
|
:selected="isSelect(item)"
|
||||||
|
@select="onSelect"
|
||||||
|
@tap="onGoodsClick"
|
||||||
|
@num-change="onNumChange"
|
||||||
|
:isEdit="isEdit"
|
||||||
|
></cart-goods-item>
|
||||||
|
<u-line color="#E5E5E5" v-if="index != cartList.length - 1" />
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="fixed inset-x-0 bg-white px-18rpx py-20rpx bottom-card z-99">
|
||||||
|
<view class="flex w-full items-end">
|
||||||
|
<view class="flex items-end">
|
||||||
|
<view class="flex items-center" @tap="selectAll = !selectAll">
|
||||||
|
<image v-if="selectAll" class="w-32rpx h-32rpx flex-none mr-17rpx" src="/static/images/cart/check-round-fill.png" mode="scaleToFill" />
|
||||||
|
<image v-else class="w-32rpx h-32rpx flex-none mr-17rpx" src="/static/images/cart/check-round.png" mode="scaleToFill" />
|
||||||
|
<text class="text-lg">全选</text>
|
||||||
|
</view>
|
||||||
|
<view class="ml-30rpx">
|
||||||
|
<text>共 {{ cartList.length }} 件</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<block v-if="isEdit">
|
||||||
|
<view class="flex-1"></view>
|
||||||
|
<view>
|
||||||
|
<view :disabled="selectedCart.length == 0" class="btn btn-primary rounded-full text-lg px-30rpx py-10rpx" @tap="delShow = true">
|
||||||
|
移除
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<block v-else>
|
||||||
|
<view class="flex-1 text-right text-xl mr-20rpx">
|
||||||
|
<text>合计:</text>
|
||||||
|
<text class="text-txSvip">¥{{ calculate.amount }}</text>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view @tap="onSubmit" class="btn btn-primary rounded-full text-lg px-30rpx py-10rpx"> 确认下单 </view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="box-shdow inset-x-0 h-2rpx fixed bottom-card z-99"></view>
|
||||||
|
|
||||||
|
<view class="h-148rpx"></view>
|
||||||
|
</block>
|
||||||
|
<!-- 未登录 -->
|
||||||
|
<block v-else>
|
||||||
|
<view class="flex items-center justify-center flex-col bg-white py-100rpx">
|
||||||
|
<image src="/static/images/cart/empty-cart.png" class="w-300rpx h-254rpx" mode="scaleToFill" />
|
||||||
|
<view class="text-txGray text-md">购物车是空的</view>
|
||||||
|
<view class="w-full px-150rpx flex items-center mt-50rpx text-txBase text-md mx-100rpx justify-between">
|
||||||
|
<view @tap="jumpIndex" class="w-180rpx h-55rpx border border-txBase leading-55rpx text-center rounded-full"> 去逛逛</view>
|
||||||
|
<view @tap="$u.routeAuth('/pageA/collection/index')" class="w-180rpx h-55rpx border border-txBase leading-55rpx text-center rounded-full"
|
||||||
|
>看看关注</view
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
|
||||||
|
<!-- 删除提示 -->
|
||||||
|
<cu-modal
|
||||||
|
v-model="delShow"
|
||||||
|
:content="`确定要删除${selectedCart.length}种商品吗?`"
|
||||||
|
show-cancel-button
|
||||||
|
async-close
|
||||||
|
@confirm="delConfirm"
|
||||||
|
></cu-modal>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import CartGoodsItem from '@/pages/shop_cart/components/cart-goods-item.vue';
|
||||||
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
import { add, mcl } from '@/utils';
|
||||||
|
import CartMixin from '@/pages/shop_cart/mixin';
|
||||||
|
export default {
|
||||||
|
mixins: [CartMixin],
|
||||||
|
components: {
|
||||||
|
CartGoodsItem,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isBack: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
delShow: false,
|
||||||
|
isEdit: false,
|
||||||
|
calculate: {
|
||||||
|
amount: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onShow() {
|
||||||
|
this.getCartList();
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['cartList', 'selectedCart']),
|
||||||
|
navBarLeftText() {
|
||||||
|
return this.isEdit ? '完成' : '管理';
|
||||||
|
},
|
||||||
|
selectAll: {
|
||||||
|
set(val) {
|
||||||
|
this.setSelectedCart(val ? this.cartList.map((e) => e.id) : []);
|
||||||
|
},
|
||||||
|
get() {
|
||||||
|
return this.cartList.length == this.selectedCart.length && this.cartList.length > 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
selectedCorrect() {
|
||||||
|
return this.selectedCart?.filter((id) => this.cartList.findIndex((e) => e.id == id && e.sku.is_online) >= 0) ?? [];
|
||||||
|
},
|
||||||
|
|
||||||
|
height() {
|
||||||
|
const { windowHeight, statusBarHeight } = this.$u.sys();
|
||||||
|
return windowHeight - statusBarHeight - 44 + 'px';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
getCartList: 'goods/getCartList',
|
||||||
|
setSelectedCart: 'goods/setSelectedCart',
|
||||||
|
}),
|
||||||
|
//结算
|
||||||
|
onSubmit() {
|
||||||
|
if (this.selectedCorrect.length == 0) return this.$u.toast('请选择需要结算的商品');
|
||||||
|
const params = {
|
||||||
|
cards: this.selectedCorrect,
|
||||||
|
type: 'cart',
|
||||||
|
};
|
||||||
|
this.$u.route('/pages/confirm_order/confirm_order?data=' + encodeURIComponent(JSON.stringify(params)));
|
||||||
|
},
|
||||||
|
//数量改变
|
||||||
|
async onNumChange(value, id) {
|
||||||
|
await this.$api.put(
|
||||||
|
`/v1/shopping-cart-items/${id}`,
|
||||||
|
{
|
||||||
|
quantity: value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
custom: {
|
||||||
|
loading: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.getCartList();
|
||||||
|
},
|
||||||
|
//移除购物车
|
||||||
|
async delConfirm() {
|
||||||
|
if (this.selectedCart.length == 0) return this.$u.toast('您还未选择商品哦');
|
||||||
|
|
||||||
|
await this.$api.delete(
|
||||||
|
'/v1/shopping-cart-items',
|
||||||
|
{ ids: this.selectedCart },
|
||||||
|
{
|
||||||
|
custom: {
|
||||||
|
loading: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.delShow = false;
|
||||||
|
this.getCartList();
|
||||||
|
},
|
||||||
|
//编辑
|
||||||
|
changeEdit() {
|
||||||
|
this.isEdit = !this.isEdit;
|
||||||
|
},
|
||||||
|
//复选框
|
||||||
|
onSelect(id, selected) {
|
||||||
|
if (selected) {
|
||||||
|
this.setSelectedCart([...this.selectedCart, id]);
|
||||||
|
} else {
|
||||||
|
this.setSelectedCart(this.selectedCart.filter((e) => id != e));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//商品点击
|
||||||
|
onGoodsClick(e) {
|
||||||
|
if (this.isEdit) return false;
|
||||||
|
this.$u.route('/pages/product_details/index', {
|
||||||
|
skuId: e.id,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//计算价格
|
||||||
|
getCalculateAmount() {
|
||||||
|
const { is_vip } = this.$store.getters?.user ?? false;
|
||||||
|
const amount = this.cartList.reduce((pr, cu) => {
|
||||||
|
if (this.selectedCart.findIndex((e) => e == cu.id) >= 0) pr = add(mcl(is_vip ? cu.sku.vip_price : cu.sku.sell_price, cu.quantity), pr);
|
||||||
|
return pr;
|
||||||
|
}, 0);
|
||||||
|
this.calculate.amount = amount;
|
||||||
|
},
|
||||||
|
//是否勾选
|
||||||
|
isSelect({ id }) {
|
||||||
|
return this.selectedCart.some((item) => item == id);
|
||||||
|
},
|
||||||
|
back() {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
jumpIndex() {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectedCart: {
|
||||||
|
immediate: true,
|
||||||
|
handler(e) {
|
||||||
|
this.getCalculateAmount();
|
||||||
|
// console.log(e);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-card {
|
||||||
|
box-shadow: 0px -4rpx 8rpx rgba(0, 0, 0, 0.25);
|
||||||
|
bottom: var(--window-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-h {
|
||||||
|
padding: var(--window-bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-shdow {
|
||||||
|
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,249 @@
|
||||||
|
<template>
|
||||||
|
<view class="">
|
||||||
|
<view class="flex items-center px-40rpx text-32rpx bg-white py-30rpx sticky top-0 z-99">
|
||||||
|
<view class="mr-15rpx">商品信息</view>
|
||||||
|
<u-search @search="searchGoods" class="flex-1" placeholder="货号或名称" v-model="keyword" :show-action="false">
|
||||||
|
</u-search>
|
||||||
|
<u-icon @tap="onQR" class="ml-20rpx" name="scan" color="#333333" size="48"></u-icon>
|
||||||
|
</view>
|
||||||
|
<!-- 有商品时 -->
|
||||||
|
<block v-if="!isShow">
|
||||||
|
<!-- 搜索的商品列表 -->
|
||||||
|
<view class="px-30rpx bg-white" v-if="goodsList.length">
|
||||||
|
<block v-for="(item,index) in goodsList" :key="index">
|
||||||
|
<GoodsItem :isAdd="true" :goods="item" @addGood="addGood" />
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view v-if="chooseList.length>0" class="py-20rpx text-40rpx font-extrabold text-center">下单商品</view>
|
||||||
|
<!-- 提货数量 -->
|
||||||
|
<view class=" bg-white">
|
||||||
|
<u-swipe-action v-for="(item, index) in chooseList" :key="item.id" :show="item.show" :index="index" @click="click" @open="open" :options="options"
|
||||||
|
>
|
||||||
|
<view class="py-20rpx flex w-full items-start px-30rpx" >
|
||||||
|
<view
|
||||||
|
class="w-38rpx mt-8rpx h-38rpx rounded-full border border-hex-ef4444 border-solid text-center leading-38rpx text-hex-ef4444">
|
||||||
|
{{index+1}}
|
||||||
|
</view>
|
||||||
|
<view class="flex-1 ml-15rpx">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="flex flex-1 items-center justify-between">
|
||||||
|
<view>默认已提货量》</view>
|
||||||
|
<view>
|
||||||
|
<u-number-box :min="0" v-model="item.defaultNum" :max="item.num">
|
||||||
|
</u-number-box>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<GoodsItem class="px-0" :goods="item" @numChange="numChange" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-line v-if="chooseList.length-1!=index" :hair-line="false" color="#c8c9cc"></u-line>
|
||||||
|
</u-swipe-action>
|
||||||
|
</view>
|
||||||
|
<view class="h-180rpx"></view>
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="flex items-center justify-end bg-white bottom-card z-99 fixed inset-x-0">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view>
|
||||||
|
合计
|
||||||
|
<text class="ml-10rpx price-text text-hex-ef4444">{{totalPrice}}元</text>
|
||||||
|
</view>
|
||||||
|
<view class="ml-10rpx">
|
||||||
|
vip
|
||||||
|
<text class="ml-10rpx price-text text-hex-ef4444">{{vipPrice}}元</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view @click="qrCode" class="bg-hex-ef4444 h-100rpx w-210rpx text-white text-center leading-100rpx ml-30rpx">
|
||||||
|
生成二维码</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<!-- 无商品时 -->
|
||||||
|
<block v-else>
|
||||||
|
<view class="flex items-center justify-center flex-col mt-80rpx">
|
||||||
|
<image src="http://cdn.uviewui.com/uview/empty/car.png" mode="aspectFill"></image>
|
||||||
|
<view class="text-hex-909399 -mt-20rpx">请搜索您需要的商品</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<cu-modal v-model="modeShow" @confirm="confirm" confirm-color="#378264" show-cancel-button content="是否生成二维码?"
|
||||||
|
confirmText="确认" cancelText="再想想">
|
||||||
|
</cu-modal>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import GoodsItem from './components/goods-item.vue'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
GoodsItem
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
modeShow: false,
|
||||||
|
isShow: true,
|
||||||
|
id: '',
|
||||||
|
keyword: '',
|
||||||
|
list: [], //搜索的商品
|
||||||
|
chooseList: [], //选择的商品
|
||||||
|
goodItem: {},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: '删除',
|
||||||
|
style: {
|
||||||
|
backgroundColor: '#ef4444'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad({
|
||||||
|
id
|
||||||
|
}) {
|
||||||
|
this.id = id
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
//普通价格合计
|
||||||
|
totalPrice() {
|
||||||
|
const total = this.chooseList.reduce((pr, cu) => {
|
||||||
|
return pr + cu.sell_price * cu.num
|
||||||
|
}, 0)
|
||||||
|
return total.toFixed(2)
|
||||||
|
},
|
||||||
|
//会员价合计
|
||||||
|
vipPrice() {
|
||||||
|
const total = this.chooseList.reduce((pr, cu) => {
|
||||||
|
return pr + cu.vip_price * cu.num
|
||||||
|
}, 0)
|
||||||
|
return total.toFixed(2)
|
||||||
|
},
|
||||||
|
goodsList(){
|
||||||
|
return this.list?.map(e=>{
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
defaultNum:1,
|
||||||
|
num:1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
click(index,index1) {
|
||||||
|
|
||||||
|
if(index1==0){
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.chooseList.splice(index, 1)
|
||||||
|
this.chooseList[index].show = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
open(index) {
|
||||||
|
this.chooseList[index].show = true;
|
||||||
|
this.chooseList.forEach((val, idx) => {
|
||||||
|
if(index != idx) this.chooseList[idx].show = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//扫码
|
||||||
|
onQR(){
|
||||||
|
uni.scanCode({
|
||||||
|
onlyFromCamera: true,
|
||||||
|
success: ({result})=>{
|
||||||
|
this.keyword=result
|
||||||
|
this.searchGoods()
|
||||||
|
},
|
||||||
|
fail:err=>{
|
||||||
|
this.$u.toast('扫码失败,请重新扫描')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
async searchGoods() {
|
||||||
|
const resDate = await this.$api.get(`/v1/store/${this.id}/products`, {
|
||||||
|
params: {
|
||||||
|
keyword: this.keyword
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.list = resDate.data
|
||||||
|
if (this.list.length == 0) {
|
||||||
|
return this.$u.toast('暂未搜索到该商品')
|
||||||
|
}
|
||||||
|
this.isShow = false
|
||||||
|
// this.goodList=
|
||||||
|
// let goodsObj = resDate.data.length > 0 ? resDate.data[0] : {}
|
||||||
|
// goodsObj.defaultNum = 1
|
||||||
|
// goodsObj.num = 1
|
||||||
|
// this.goodItem = goodsObj
|
||||||
|
},
|
||||||
|
//添加商品
|
||||||
|
addGood(e) {
|
||||||
|
const result = this.chooseList.findIndex(item => item.id == e)
|
||||||
|
if (result == -1) {
|
||||||
|
const goodsItem=this.goodsList?.find(el=>el.id==e)
|
||||||
|
this.chooseList.push(Object.assign(goodsItem,{show:false}))
|
||||||
|
} else {
|
||||||
|
const num = this.chooseList[result].num + 1
|
||||||
|
this.getUpdate(result, num)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//商品数量改变
|
||||||
|
numChange(id, value) {
|
||||||
|
const Index = this.chooseList.findIndex(item => item.id == id)
|
||||||
|
this.getUpdate(Index, value)
|
||||||
|
},
|
||||||
|
//刷新页面
|
||||||
|
getUpdate(Index, val) {
|
||||||
|
this.chooseList[Index].num = val
|
||||||
|
this.chooseList[Index].defaultNum = val
|
||||||
|
this.chooseList = [...this.chooseList]
|
||||||
|
},
|
||||||
|
qrCode() {
|
||||||
|
if (this.chooseList.length == 0) {
|
||||||
|
return this.$u.toast('至少选选择一件商品')
|
||||||
|
}
|
||||||
|
this.modeShow = true
|
||||||
|
},
|
||||||
|
//生成二维码
|
||||||
|
async confirm() {
|
||||||
|
uni.showLoading({
|
||||||
|
title: '二维码生成中',
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const arrList = this.chooseList.map(item => {
|
||||||
|
return {
|
||||||
|
sku_id: item.id,
|
||||||
|
quantity: item.num,
|
||||||
|
send: item.defaultNum
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const obj = {
|
||||||
|
store_id: this.id,
|
||||||
|
products: arrList,
|
||||||
|
note: ''
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
image
|
||||||
|
} = await this.$api.post(`/v1/order-pre`, obj);
|
||||||
|
this.$u.route('/pageB/code/index', {
|
||||||
|
image
|
||||||
|
})
|
||||||
|
this.keyword = ''
|
||||||
|
this.list = []
|
||||||
|
this.chooseList = []
|
||||||
|
this.goodItem = {}
|
||||||
|
this.isShow = true
|
||||||
|
uni.hideLoading()
|
||||||
|
} catch (err) {}finally{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.bottom-card {
|
||||||
|
box-shadow: 0px -4rpx 8rpx rgba(0, 0, 0, 0.25);
|
||||||
|
bottom: var(--window-bottom);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,249 +1,305 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="">
|
<view class="u-wrap">
|
||||||
<view class="flex items-center px-40rpx text-32rpx bg-white py-30rpx sticky top-0 z-99">
|
<view class="u-search-box bg-white">
|
||||||
<view class="mr-15rpx">商品信息</view>
|
<view class="flex items-center">
|
||||||
<u-search @search="searchGoods" class="flex-1" placeholder="货号或名称" v-model="keyword" :show-action="false">
|
<view class="mr-15rpx">商品信息</view>
|
||||||
</u-search>
|
<u-search class="flex-1" placeholder="货号或名称" :show-action="false"> </u-search>
|
||||||
<u-icon @tap="onQR" class="ml-20rpx" name="scan" color="#333333" size="48"></u-icon>
|
<u-icon class="ml-20rpx" name="scan" color="#333333" size="48"></u-icon>
|
||||||
</view>
|
|
||||||
<!-- 有商品时 -->
|
|
||||||
<block v-if="!isShow">
|
|
||||||
<!-- 搜索的商品列表 -->
|
|
||||||
<view class="px-30rpx bg-white" v-if="goodsList.length">
|
|
||||||
<block v-for="(item,index) in goodsList" :key="index">
|
|
||||||
<GoodsItem :isAdd="true" :goods="item" @addGood="addGood" />
|
|
||||||
</block>
|
|
||||||
</view>
|
</view>
|
||||||
<view v-if="chooseList.length>0" class="py-20rpx text-40rpx font-extrabold text-center">下单商品</view>
|
</view>
|
||||||
<!-- 提货数量 -->
|
<view class="u-menu-wrap">
|
||||||
<view class=" bg-white">
|
<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop" :scroll-into-view="itemId">
|
||||||
<u-swipe-action v-for="(item, index) in chooseList" :key="item.id" :show="item.show" :index="index" @click="click" @open="open" :options="options"
|
<view
|
||||||
>
|
v-for="(item, index) in tabbar"
|
||||||
<view class="py-20rpx flex w-full items-start px-30rpx" >
|
:key="index"
|
||||||
<view
|
class="u-tab-item"
|
||||||
class="w-38rpx mt-8rpx h-38rpx rounded-full border border-hex-ef4444 border-solid text-center leading-38rpx text-hex-ef4444">
|
:class="[current == index ? 'u-tab-item-active' : '']"
|
||||||
{{index+1}}
|
@tap.stop="swichMenu(index)"
|
||||||
</view>
|
>
|
||||||
<view class="flex-1 ml-15rpx">
|
<text class="u-line-1">{{ item.name }}</text>
|
||||||
<view class="flex items-center">
|
</view>
|
||||||
<view class="flex flex-1 items-center justify-between">
|
</scroll-view>
|
||||||
<view>默认已提货量》</view>
|
<scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="right-box" @scroll="rightScroll">
|
||||||
<view>
|
<view class="page-view">
|
||||||
<u-number-box :min="0" v-model="item.defaultNum" :max="item.num">
|
<view class="class-item" :id="'item' + index" v-for="(item, index) in tabbar" :key="index">
|
||||||
</u-number-box>
|
<view class="item-title">
|
||||||
</view>
|
<text>{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="item-container">
|
||||||
|
<view class="thumb-box" v-for="(item1, index1) in item.foods" :key="index1" @tap="$u.route('/pageB/select_product/search?category=20')">
|
||||||
|
<image class="item-menu-image" :src="item1.icon" mode=""></image>
|
||||||
|
<view class="item-menu-name">{{ item1.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<GoodsItem class="px-0" :goods="item" @numChange="numChange" />
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<u-line v-if="chooseList.length-1!=index" :hair-line="false" color="#c8c9cc"></u-line>
|
</scroll-view>
|
||||||
</u-swipe-action>
|
</view>
|
||||||
</view>
|
|
||||||
<view class="h-180rpx"></view>
|
|
||||||
<!-- 底部按钮 -->
|
|
||||||
<view class="flex items-center justify-end bg-white bottom-card z-99 fixed inset-x-0">
|
|
||||||
<view class="flex items-center">
|
|
||||||
<view>
|
|
||||||
合计
|
|
||||||
<text class="ml-10rpx price-text text-hex-ef4444">{{totalPrice}}元</text>
|
|
||||||
</view>
|
|
||||||
<view class="ml-10rpx">
|
|
||||||
vip
|
|
||||||
<text class="ml-10rpx price-text text-hex-ef4444">{{vipPrice}}元</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view @click="qrCode" class="bg-hex-ef4444 h-100rpx w-210rpx text-white text-center leading-100rpx ml-30rpx">
|
|
||||||
生成二维码</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<!-- 无商品时 -->
|
|
||||||
<block v-else>
|
|
||||||
<view class="flex items-center justify-center flex-col mt-80rpx">
|
|
||||||
<image src="http://cdn.uviewui.com/uview/empty/car.png" mode="aspectFill"></image>
|
|
||||||
<view class="text-hex-909399 -mt-20rpx">请搜索您需要的商品</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<cu-modal v-model="modeShow" @confirm="confirm" confirm-color="#378264" show-cancel-button content="是否生成二维码?"
|
|
||||||
confirmText="确认" cancelText="再想想">
|
|
||||||
</cu-modal>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import GoodsItem from './components/goods-item.vue'
|
import classifyData from './classify.data.js';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
data() {
|
||||||
GoodsItem
|
return {
|
||||||
},
|
scrollTop: 0, //tab标题的滚动条位置
|
||||||
data() {
|
oldScrollTop: 0,
|
||||||
return {
|
current: 0, // 预设当前项的值
|
||||||
modeShow: false,
|
menuHeight: 0, // 左边菜单的高度
|
||||||
isShow: true,
|
menuItemHeight: 0, // 左边菜单item的高度
|
||||||
id: '',
|
itemId: '', // 栏目右边scroll-view用于滚动的id
|
||||||
keyword: '',
|
tabbar: classifyData,
|
||||||
list: [], //搜索的商品
|
menuItemPos: [],
|
||||||
chooseList: [], //选择的商品
|
arr: [],
|
||||||
goodItem: {},
|
scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
|
||||||
options: [
|
timer: null, // 定时器
|
||||||
{
|
};
|
||||||
text: '删除',
|
},
|
||||||
style: {
|
onLoad() {},
|
||||||
backgroundColor: '#ef4444'
|
onReady() {
|
||||||
}
|
this.getMenuItemTop();
|
||||||
}
|
},
|
||||||
]
|
methods: {
|
||||||
};
|
// 点击左边的栏目切换
|
||||||
},
|
async swichMenu(index) {
|
||||||
onLoad({
|
if (this.arr.length == 0) {
|
||||||
id
|
await this.getMenuItemTop();
|
||||||
}) {
|
|
||||||
this.id = id
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
//普通价格合计
|
|
||||||
totalPrice() {
|
|
||||||
const total = this.chooseList.reduce((pr, cu) => {
|
|
||||||
return pr + cu.sell_price * cu.num
|
|
||||||
}, 0)
|
|
||||||
return total.toFixed(2)
|
|
||||||
},
|
|
||||||
//会员价合计
|
|
||||||
vipPrice() {
|
|
||||||
const total = this.chooseList.reduce((pr, cu) => {
|
|
||||||
return pr + cu.vip_price * cu.num
|
|
||||||
}, 0)
|
|
||||||
return total.toFixed(2)
|
|
||||||
},
|
|
||||||
goodsList(){
|
|
||||||
return this.list?.map(e=>{
|
|
||||||
return {
|
|
||||||
...e,
|
|
||||||
defaultNum:1,
|
|
||||||
num:1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
if (index == this.current) return;
|
||||||
|
this.scrollRightTop = this.oldScrollTop;
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.scrollRightTop = this.arr[index];
|
||||||
|
this.current = index;
|
||||||
|
this.leftMenuStatus(index);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
// 获取一个目标元素的高度
|
||||||
click(index,index1) {
|
getElRect(elClass, dataVal) {
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
if(index1==0){
|
const query = uni.createSelectorQuery().in(this);
|
||||||
this.$nextTick(()=>{
|
query
|
||||||
this.chooseList.splice(index, 1)
|
.select('.' + elClass)
|
||||||
this.chooseList[index].show = false;
|
.fields(
|
||||||
|
{
|
||||||
|
size: true,
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
// 如果节点尚未生成,res值为null,循环调用执行
|
||||||
|
if (!res) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getElRect(elClass);
|
||||||
|
}, 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this[dataVal] = res.height;
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.exec();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 观测元素相交状态
|
||||||
|
async observer() {
|
||||||
|
this.tabbar.map((val, index) => {
|
||||||
|
let observer = uni.createIntersectionObserver(this);
|
||||||
|
// 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
|
||||||
|
// 如果跟.right-box底部相交,就动态设置左边栏目的活动状态
|
||||||
|
observer
|
||||||
|
.relativeTo('.right-box', {
|
||||||
|
top: 0,
|
||||||
})
|
})
|
||||||
}
|
.observe('#item' + index, (res) => {
|
||||||
},
|
if (res.intersectionRatio > 0) {
|
||||||
open(index) {
|
let id = res.id.substring(4);
|
||||||
this.chooseList[index].show = true;
|
this.leftMenuStatus(id);
|
||||||
this.chooseList.forEach((val, idx) => {
|
|
||||||
if(index != idx) this.chooseList[idx].show = false;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
//扫码
|
|
||||||
onQR(){
|
|
||||||
uni.scanCode({
|
|
||||||
onlyFromCamera: true,
|
|
||||||
success: ({result})=>{
|
|
||||||
this.keyword=result
|
|
||||||
this.searchGoods()
|
|
||||||
},
|
|
||||||
fail:err=>{
|
|
||||||
this.$u.toast('扫码失败,请重新扫描')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
async searchGoods() {
|
|
||||||
const resDate = await this.$api.get(`/v1/store/${this.id}/products`, {
|
|
||||||
params: {
|
|
||||||
keyword: this.keyword
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.list = resDate.data
|
|
||||||
if (this.list.length == 0) {
|
|
||||||
return this.$u.toast('暂未搜索到该商品')
|
|
||||||
}
|
|
||||||
this.isShow = false
|
|
||||||
// this.goodList=
|
|
||||||
// let goodsObj = resDate.data.length > 0 ? resDate.data[0] : {}
|
|
||||||
// goodsObj.defaultNum = 1
|
|
||||||
// goodsObj.num = 1
|
|
||||||
// this.goodItem = goodsObj
|
|
||||||
},
|
|
||||||
//添加商品
|
|
||||||
addGood(e) {
|
|
||||||
const result = this.chooseList.findIndex(item => item.id == e)
|
|
||||||
if (result == -1) {
|
|
||||||
const goodsItem=this.goodsList?.find(el=>el.id==e)
|
|
||||||
this.chooseList.push(Object.assign(goodsItem,{show:false}))
|
|
||||||
} else {
|
|
||||||
const num = this.chooseList[result].num + 1
|
|
||||||
this.getUpdate(result, num)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//商品数量改变
|
|
||||||
numChange(id, value) {
|
|
||||||
const Index = this.chooseList.findIndex(item => item.id == id)
|
|
||||||
this.getUpdate(Index, value)
|
|
||||||
},
|
|
||||||
//刷新页面
|
|
||||||
getUpdate(Index, val) {
|
|
||||||
this.chooseList[Index].num = val
|
|
||||||
this.chooseList[Index].defaultNum = val
|
|
||||||
this.chooseList = [...this.chooseList]
|
|
||||||
},
|
|
||||||
qrCode() {
|
|
||||||
if (this.chooseList.length == 0) {
|
|
||||||
return this.$u.toast('至少选选择一件商品')
|
|
||||||
}
|
|
||||||
this.modeShow = true
|
|
||||||
},
|
|
||||||
//生成二维码
|
|
||||||
async confirm() {
|
|
||||||
uni.showLoading({
|
|
||||||
title: '二维码生成中',
|
|
||||||
mask: true
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
const arrList = this.chooseList.map(item => {
|
|
||||||
return {
|
|
||||||
sku_id: item.id,
|
|
||||||
quantity: item.num,
|
|
||||||
send: item.defaultNum
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
const obj = {
|
});
|
||||||
store_id: this.id,
|
},
|
||||||
products: arrList,
|
// 设置左边菜单的滚动状态
|
||||||
note: ''
|
async leftMenuStatus(index) {
|
||||||
}
|
this.current = index;
|
||||||
const {
|
// 如果为0,意味着尚未初始化
|
||||||
image
|
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
|
||||||
} = await this.$api.post(`/v1/order-pre`, obj);
|
await this.getElRect('menu-scroll-view', 'menuHeight');
|
||||||
this.$u.route('/pageB/code/index', {
|
await this.getElRect('u-tab-item', 'menuItemHeight');
|
||||||
image
|
|
||||||
})
|
|
||||||
this.keyword = ''
|
|
||||||
this.list = []
|
|
||||||
this.chooseList = []
|
|
||||||
this.goodItem = {}
|
|
||||||
this.isShow = true
|
|
||||||
uni.hideLoading()
|
|
||||||
} catch (err) {}finally{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
// 将菜单活动item垂直居中
|
||||||
}
|
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
|
||||||
|
},
|
||||||
|
// 获取右边菜单每个item到顶部的距离
|
||||||
|
getMenuItemTop() {
|
||||||
|
new Promise((resolve) => {
|
||||||
|
let selectorQuery = uni.createSelectorQuery();
|
||||||
|
selectorQuery
|
||||||
|
.selectAll('.class-item')
|
||||||
|
.boundingClientRect((rects) => {
|
||||||
|
// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
|
||||||
|
if (!rects.length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getMenuItemTop();
|
||||||
|
}, 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rects.forEach((rect) => {
|
||||||
|
// 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
|
||||||
|
this.arr.push(rect.top - rects[0].top);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 右边菜单滚动
|
||||||
|
async rightScroll(e) {
|
||||||
|
this.oldScrollTop = e.detail.scrollTop;
|
||||||
|
if (this.arr.length == 0) {
|
||||||
|
await this.getMenuItemTop();
|
||||||
|
}
|
||||||
|
if (this.timer) return;
|
||||||
|
if (!this.menuHeight) {
|
||||||
|
await this.getElRect('menu-scroll-view', 'menuHeight');
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
// 节流
|
||||||
|
this.timer = null;
|
||||||
|
// scrollHeight为右边菜单垂直中点位置
|
||||||
|
let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
|
||||||
|
for (let i = 0; i < this.arr.length; i++) {
|
||||||
|
let height1 = this.arr[i];
|
||||||
|
let height2 = this.arr[i + 1];
|
||||||
|
// 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
|
||||||
|
if (!height2 || (scrollHeight >= height1 && scrollHeight < height2)) {
|
||||||
|
this.leftMenuStatus(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
</style>
|
<style lang="scss" scoped>
|
||||||
<style lang="scss">
|
.u-wrap {
|
||||||
.bottom-card {
|
height: calc(100vh);
|
||||||
box-shadow: 0px -4rpx 8rpx rgba(0, 0, 0, 0.25);
|
/* #ifdef H5 */
|
||||||
bottom: var(--window-bottom);
|
height: calc(100vh - var(--window-top));
|
||||||
}
|
/* #endif */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-search-box {
|
||||||
|
padding: 18rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-menu-wrap {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-search-inner {
|
||||||
|
background-color: rgb(234, 234, 234);
|
||||||
|
border-radius: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10rpx 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-search-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-tips-color;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-tab-view {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-tab-item {
|
||||||
|
height: 110rpx;
|
||||||
|
background: #f6f6f6;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #444;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-tab-item-active {
|
||||||
|
position: relative;
|
||||||
|
color: #000;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-tab-item-active::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
border-left: 4px solid $u-type-primary;
|
||||||
|
height: 32rpx;
|
||||||
|
left: 0;
|
||||||
|
top: 39rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-tab-view {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-box {
|
||||||
|
background-color: rgb(250, 250, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-view {
|
||||||
|
padding: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-item {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 16rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-item:last-child {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $u-main-color;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-menu-name {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $u-main-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-box {
|
||||||
|
width: 33.333333%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-menu-image {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,222 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<u-navbar :border-bottom="false" back-icon-color="#000000" :background="{ background: '#ffffff' }">
|
||||||
|
<view class="w-full">
|
||||||
|
<u-search placeholder="搜索商品" @change="Change" @search="Search" v-model="searchText" :show-action="false"></u-search>
|
||||||
|
</view>
|
||||||
|
<view slot="right" class="pr-26rpx pl-14rpx flex items-center" @tap="$u.route('/pageB/select_product/cart')">
|
||||||
|
<image class="w-48rpx h-48rpx" src="/static/images/cart/short-cart.png" mode="scaleToFill" />
|
||||||
|
</view>
|
||||||
|
</u-navbar>
|
||||||
|
<!-- tabs -->
|
||||||
|
<view class="fixed left-0 right-0 z-8 text-txGray text-lg w-full bg-white h-90rpx shadow-down flex items-center justify-around">
|
||||||
|
<view @tap.stop="handType('')" :class="!sort ? 'text-primary' : ''">综合</view>
|
||||||
|
<view @tap.stop="onPriceSort" class="flex items-center" :class="sort == 'price' || sort == '-price' ? 'text-primary' : ''">
|
||||||
|
<view>价格</view>
|
||||||
|
<view>
|
||||||
|
<trigonometry :key="'a' + key" direction="up" :color="sort == 'price' ? '#378264' : '#808080'"></trigonometry>
|
||||||
|
<trigonometry :key="'b' + key" direction="down" :color="sort == '-price' ? '#378264' : '#808080'"></trigonometry>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view @tap.stop="onSaleSort" :class="sort == 'sales' || sort == '-sales' ? 'text-primary' : ''" class="flex items-center">
|
||||||
|
<view>销量</view>
|
||||||
|
<view class="flex items-center justify-center flex-col ml-5rpx">
|
||||||
|
<trigonometry :key="'c' + key" direction="up" :color="sort == 'sales' ? '#378264' : '#808080'"></trigonometry>
|
||||||
|
<trigonometry :key="'d' + key" direction="down" :color="sort == '-sales' ? '#378264' : '#808080'"></trigonometry>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view @tap.stop="handType('release_at')" :class="sort == 'release_at' ? 'text-primary' : ''">上新</view>
|
||||||
|
</view>
|
||||||
|
<mescroll-body
|
||||||
|
top="90"
|
||||||
|
:height="height"
|
||||||
|
ref="mescrollRef"
|
||||||
|
@init="mescrollInit"
|
||||||
|
@down="downCallback"
|
||||||
|
@up="upCallback"
|
||||||
|
:down="downOption"
|
||||||
|
:up="upOption"
|
||||||
|
>
|
||||||
|
<view class="px-rowSm mt-20rpx">
|
||||||
|
<u-waterfall v-model="dataList" ref="uWaterfall">
|
||||||
|
<template v-slot:left="{ leftList }">
|
||||||
|
<view v-for="(item, index) in leftList" :key="index" class="px-rowSm mb-base">
|
||||||
|
<goods-item :goods="item" cart @cartClick="cartClick"></goods-item>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-slot:right="{ rightList }">
|
||||||
|
<view v-for="(item, index) in rightList" :key="index" class="px-rowSm mb-base">
|
||||||
|
<goods-item :goods="item" cart @cartClick="cartClick"></goods-item>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</u-waterfall>
|
||||||
|
</view>
|
||||||
|
</mescroll-body>
|
||||||
|
|
||||||
|
<!-- 规格弹窗 -->
|
||||||
|
<spec-popup
|
||||||
|
:key="productId"
|
||||||
|
:loading="loading"
|
||||||
|
:specs="specs"
|
||||||
|
:sku="detail"
|
||||||
|
v-model="show"
|
||||||
|
:quota-used="number"
|
||||||
|
:show-cart="popupType == 1 || popupType == 0"
|
||||||
|
:show-buy="popupType == 2 || popupType == 0"
|
||||||
|
:show-confirm="popupType == 3"
|
||||||
|
@add-cart="onAddCart"
|
||||||
|
@stepper-change="onChangeNumber"
|
||||||
|
>
|
||||||
|
</spec-popup>
|
||||||
|
|
||||||
|
<u-mask :show="loading">
|
||||||
|
<view style="display: flex; justify-content: center; align-items: center; height: 100%">
|
||||||
|
<text style="color: white">加载中</text>
|
||||||
|
<u-loading mode="flower" size="60" />
|
||||||
|
</view>
|
||||||
|
</u-mask>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
|
||||||
|
export default {
|
||||||
|
mixins: [MescrollMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
key: 0,
|
||||||
|
sort: '', //price 价格,sales 销量,release_at 上架时间。示例:price 按价格升序,-price 按价格降序
|
||||||
|
searchText: '',
|
||||||
|
category: '',
|
||||||
|
loading: false,
|
||||||
|
popupType: 1,
|
||||||
|
number: 1,
|
||||||
|
products: {},
|
||||||
|
productId: '',
|
||||||
|
skuId: '',
|
||||||
|
downOption: {
|
||||||
|
auto: false,
|
||||||
|
},
|
||||||
|
upOption: {
|
||||||
|
page: {
|
||||||
|
size: 20,
|
||||||
|
},
|
||||||
|
noMoreSize: 1,
|
||||||
|
},
|
||||||
|
show: false,
|
||||||
|
dataList: [], //获取到的数据
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
specs() {
|
||||||
|
return this.products?.spu_specs ?? [];
|
||||||
|
},
|
||||||
|
detail() {
|
||||||
|
return this.products?.sku ?? {};
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
const { windowHeight, statusBarHeight } = this.$u.sys();
|
||||||
|
return windowHeight - statusBarHeight - 44 + 'px';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad({ searchText, category }) {
|
||||||
|
this.searchText = searchText;
|
||||||
|
this.category = category;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
Change(e) {
|
||||||
|
if (e == '') uni.navigateBack();
|
||||||
|
},
|
||||||
|
Search() {
|
||||||
|
this.category = '';
|
||||||
|
this.downCallback();
|
||||||
|
},
|
||||||
|
onChangeNumber(e) {
|
||||||
|
this.number = e;
|
||||||
|
console.log(e);
|
||||||
|
},
|
||||||
|
//购物车点击
|
||||||
|
async cartClick(e) {
|
||||||
|
this.productId = e.id;
|
||||||
|
this.number = 1;
|
||||||
|
await this.getProducts();
|
||||||
|
this.show = true;
|
||||||
|
console.log(e);
|
||||||
|
},
|
||||||
|
onAddCart(e) {
|
||||||
|
console.log('添加到购物车数量:' + this.number);
|
||||||
|
console.log(e);
|
||||||
|
},
|
||||||
|
//获取商品详情
|
||||||
|
async getProducts() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const resData = await this.$api.get(`/v1/product/products/${this.productId}`);
|
||||||
|
this.products = resData;
|
||||||
|
this.skuId = this.products?.sku.id;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
downCallback() {
|
||||||
|
this.dataList = [];
|
||||||
|
this.$refs.uWaterfall.clear();
|
||||||
|
this.mescroll.resetUpScroll();
|
||||||
|
},
|
||||||
|
async upCallback(page) {
|
||||||
|
this.loadData(page);
|
||||||
|
},
|
||||||
|
loadData(page) {
|
||||||
|
let obj = {
|
||||||
|
page: page.num,
|
||||||
|
per_page: page.size,
|
||||||
|
category: this.category,
|
||||||
|
keyword: this.searchText,
|
||||||
|
sort: this.sort,
|
||||||
|
};
|
||||||
|
this.$api
|
||||||
|
.get(`/v1/product/products`, {
|
||||||
|
params: obj,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
this.mescroll.endSuccess(res.data.length);
|
||||||
|
if (page.num == 1) this.dataList = [];
|
||||||
|
this.dataList = this.dataList.concat(res.data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.mescroll.endErr();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//筛选
|
||||||
|
handType(val) {
|
||||||
|
if (this.sort == val) return;
|
||||||
|
this.$u.throttle(() => {
|
||||||
|
this.sort = val;
|
||||||
|
this.downCallback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//价格排序
|
||||||
|
onPriceSort() {
|
||||||
|
this.Refresh();
|
||||||
|
this.sort = this.sort == 'price' ? '-price' : 'price';
|
||||||
|
this.downCallback();
|
||||||
|
},
|
||||||
|
//销量排序
|
||||||
|
onSaleSort() {
|
||||||
|
this.Refresh();
|
||||||
|
this.sort = this.sort == 'sales' ? '-sales' : 'sales';
|
||||||
|
this.downCallback();
|
||||||
|
},
|
||||||
|
//刷新子组件
|
||||||
|
Refresh() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.key++;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss"></style>
|
||||||
|
|
@ -1,14 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<view class=" text-30rpx font-extrabold">
|
<view class="">
|
||||||
<loading-view v-if="isFirstLoading"></loading-view>
|
<loading-view v-if="isFirstLoading"></loading-view>
|
||||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
<view class="text-center text-42rpx pt-30rpx">
|
||||||
:down="downOption" :up="upOption">
|
线上预约店
|
||||||
<view class="grid grid-cols-2 gap-x-80rpx pt-20rpx px-80rpx">
|
</view>
|
||||||
<view @click="$u.route('/pageB/select_product/index',{id:item.id})" class="flex items-center justify-center flex-col mt-40rpx"
|
<view class="my-20rpx px-20rpx">
|
||||||
v-for="(item,index) in dataList" :key="index">
|
<image @click="$u.route('/pageB/select_product/index', { id: 0 })" mode="widtFix" class="w-full h-250rpx rounded-15rpx" src="/static/images/user/u=2313295534,3451005153&fm=253&fmt=auto&app=138&f=JPEG.webp"></image>
|
||||||
<u-image class="flex-none" width="240" height="240" :src="item.image" :lazy-load="true">
|
</view>
|
||||||
</u-image>
|
<view class="my-20rpx px-20rpx">
|
||||||
<view class="mt-15rpx">{{item.title}}</view>
|
<u-line></u-line>
|
||||||
|
</view>
|
||||||
|
<view class="text-center text-42rpx">
|
||||||
|
线下预约店
|
||||||
|
</view>
|
||||||
|
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
|
||||||
|
<view class="grid grid-cols-2 gap-x-80rpx pt-20rpx px-80rpx">
|
||||||
|
<view
|
||||||
|
@click="$u.route('/pageB/select_product/index', { id: item.id })"
|
||||||
|
class="flex items-center justify-center flex-col mt-40rpx text-30rpx font-extrabold"
|
||||||
|
v-for="(item, index) in dataList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<u-image class="flex-none" width="240" height="240" :src="item.image" :lazy-load="true"> </u-image>
|
||||||
|
<view class="mt-15rpx leading-40rpx">{{ item.title }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</mescroll-body>
|
</mescroll-body>
|
||||||
|
|
@ -16,52 +30,54 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
|
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
|
||||||
export default {
|
export default {
|
||||||
mixins: [MescrollMixin], // 使用mixin
|
mixins: [MescrollMixin], // 使用mixin
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isFirstLoading:true,
|
isFirstLoading: true,
|
||||||
downOption: {},
|
downOption: {},
|
||||||
upOption: {
|
upOption: {
|
||||||
page: {
|
page: {
|
||||||
size: 20
|
size: 20,
|
||||||
},
|
|
||||||
noMoreSize: 1
|
|
||||||
},
|
},
|
||||||
dataList: [], //获取到的数据
|
noMoreSize: 1,
|
||||||
};
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
setTimeout(()=>{
|
|
||||||
this.isFirstLoading=false
|
|
||||||
},300)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
downCallback() {
|
|
||||||
this.mescroll.resetUpScroll();
|
|
||||||
this.dataList = []
|
|
||||||
},
|
},
|
||||||
async upCallback(page) {
|
dataList: [], //获取到的数据
|
||||||
this.loadData(page);
|
};
|
||||||
},
|
},
|
||||||
loadData(page) {
|
onLoad() {
|
||||||
this.$api.get(`/v1/store`, {
|
setTimeout(() => {
|
||||||
|
this.isFirstLoading = false;
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
downCallback() {
|
||||||
|
this.mescroll.resetUpScroll();
|
||||||
|
this.dataList = [];
|
||||||
|
},
|
||||||
|
async upCallback(page) {
|
||||||
|
this.loadData(page);
|
||||||
|
},
|
||||||
|
loadData(page) {
|
||||||
|
this.$api
|
||||||
|
.get(`/v1/store`, {
|
||||||
params: {
|
params: {
|
||||||
page: page.num,
|
page: page.num,
|
||||||
per_page: page.size
|
per_page: page.size,
|
||||||
}
|
},
|
||||||
}).then(res => {
|
})
|
||||||
this.mescroll.endSuccess(res.data.length)
|
.then((res) => {
|
||||||
|
this.mescroll.endSuccess(res.data.length);
|
||||||
if (page.num == 1) this.dataList = [];
|
if (page.num == 1) this.dataList = [];
|
||||||
this.dataList = this.dataList.concat(res.data);
|
this.dataList = this.dataList.concat(res.data);
|
||||||
}).catch(err => {
|
|
||||||
this.mescroll.endErr()
|
|
||||||
})
|
})
|
||||||
},
|
.catch((err) => {
|
||||||
}
|
this.mescroll.endErr();
|
||||||
};
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -538,6 +538,22 @@
|
||||||
"navigationStyle": "default"
|
"navigationStyle": "default"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "select_product/search",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "搜索商品",
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "select_product/cart",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "搜索商品",
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "select_product/com_order",
|
"path": "select_product/com_order",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
||||||
|
|
@ -186,10 +186,14 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="w-710rpx bg-hex-f08003 text-white px-base m-auto rounded-xs mt-base text-center py-26rpx text-46rpx" v-if="is_company" @tap="$u.routeAuth('/pageB/select_store/index')">
|
||||||
|
帮用户下单
|
||||||
|
</view>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<view class="w-710rpx bg-white px-base m-auto rounded-xs mt-base">
|
<view class="w-710rpx bg-white px-base m-auto rounded-xs mt-base">
|
||||||
<!-- 销售端 -->
|
<!-- 销售端 -->
|
||||||
<view @tap="$u.routeAuth('/pageB/index/index')"
|
<!-- <view @tap="$u.routeAuth('/pageB/index/index')"
|
||||||
class="flex justify-between items-center py-base border-b border-txBorder" v-if="is_company">
|
class="flex justify-between items-center py-base border-b border-txBorder" v-if="is_company">
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<image class="w-32rpx h-32rpx" src="/static/images/user/my_account.png" mode=""></image>
|
<image class="w-32rpx h-32rpx" src="/static/images/user/my_account.png" mode=""></image>
|
||||||
|
|
@ -198,7 +202,7 @@
|
||||||
<view>
|
<view>
|
||||||
<u-icon color="#383838" name="arrow-right" size="32"></u-icon>
|
<u-icon color="#383838" name="arrow-right" size="32"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
<!-- #ifndef MP-WEIXIN -->
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
<view class="flex justify-between items-center py-base " @tap="$u.route(`/pages/web_view/index?url=${service}`)">
|
<view class="flex justify-between items-center py-base " @tap="$u.route(`/pages/web_view/index?url=${service}`)">
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue