【前端】纸掌柜h5端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

576 lines
17 KiB

<template>
<view class="wrapper">
<view v-if="!hasLogin" class="flex-row-center-center">
<view style="margin-top: 400rpx">
<text style="font-size: 34rpx">请先</text>
<text style="color: #007aff; font-size: 34rpx" @click="go2('login')">登录</text>
</view>
</view>
<view v-else>
<uni-nav-bar :fixed="true" color="#ffffff" background-color="#ffffff" :status-bar="true">
<view slot="left" class="left-title">购物车</view>
<view slot="right" class="right-title" @tap="delTap">删除</view>
</uni-nav-bar>
<view class="">
<scroll-list ref="list" :option="option" @load="upCallback" @refresh="downCallback" style="background-color: #ffffff">
<view class="group-box" v-for="(item, index) in list" :key="index">
<uGap></uGap>
<view class="group-checkbox">
<view class="checkbox" @tap="checkboxGroupTap(item, index)">
<image
class="select-img"
:src="item.checkedGroup ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
<!-- <checkbox-group @change="onCheck"><checkbox value="cb" :checked="checked" color="#000000" style="transform: scale(0.7)" /></checkbox-group> -->
</view>
<view class="">{{ item.supplierName }}</view>
</view>
<view class="list-box" v-for="(subItem, subIndex) in item.carItemList" :key="subIndex">
<view class="checkbox" @tap="checkboxTap(item, subItem)">
<image
class="select-img"
:src="subItem.checked ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
<!-- <checkbox-group @change="onCheck"><checkbox value="cb" :checked="checked" color="#000000" style="transform: scale(0.7)" /></checkbox-group> -->
</view>
<view class="list-row">
<image
class="image"
@tap="seeDetailsTap(subItem)"
:src="subItem.productImg || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default-small.png'"
mode=""
></image>
<view class="right">
<view class="name">{{ subItem.productName }}</view>
<view class="measure">{{ subItem.gramWeight }}g{{ subItem.width }}*{{ subItem.length }} | {{ subItem.quantity }}</view>
<view class="weight">预估重量{{ subItem.weight }}</view>
<view class="price-row">
<view class="value">¥{{ subItem.price }}</view>
<view class=""><qnInputNumber :quantity="subItem.quantity" @change="change($event, item, subItem)" /></view>
</view>
</view>
</view>
</view>
</view>
<view slot="empty">
<no-data></no-data>
</view>
</scroll-list>
<view class="footer-box">
<view class="row">
<view class="left" @tap="selectAll">
<view class="">
<image
class="select-img"
:src="allSelected ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
</view>
<view class=""><text class="check-text">全选</text></view>
</view>
<view class="right">
<view class="">
<text class="name">应付</text>
<text class="value">¥{{ totalPrice }}</text>
</view>
<view class="right-balance-btn" @tap="closeAnAccountTap">结算</view>
</view>
</view>
</view>
</view>
<uni-popup ref="popup" type="center" :mask-click="false">
<view class="popup-box">
<view class="tip-title">{{ onlyQuantity ? '确定将当前纸品删除吗?' : (allSelected ? '确定将购物车纸品删除吗?' : '确定将当前纸品删除吗?') }}</view>
<view class="operation-row">
<view class="cancel-text" @tap="cancelTap">{{onlyQuantity ? '我在想想' : '取消'}}</view>
<view class="line"></view>
<view class="confirm-text" @tap="confirmTap">确定</view>
</view>
</view>
</uni-popup>
</view>
</view>
</template>
<script>
import uGap from '@/components/u-gap/u-gap.vue'
import qnFooter from '@/components/qn-footer/qn-footer.vue'
import { go2 } from '@/utils/hook.js'
import qnInputNumber from '@/components/qn-input-number/qn-input-number.vue'
import { getShoppingCarList, removeShoppingCar, closePaperReserve } from '@/apis/cartApi.js'
import noData from './no-data.vue'
import { round } from '@/utils/index.js'
export default {
components: { uGap, qnInputNumber, qnFooter, noData },
data() {
return {
option: {
size: 10,
auto: true,
// height: '90%',
emptyText: '暂无数据~',
background: '#F7F8FA',
disabled: false
},
params: {
// userId: this.$store.state.userInfo.userId || null
},
pagination: {
pageNum: 0, // 初始会执行一次下拉加载
pageSize: 10
},
checked: false,
list: [],
idList: [],
onlyQuantity: false,
}
},
created() {
let that = this
uni.getSystemInfo({
success: function (res) {
that.option.height = res.windowHeight * (750 / res.windowWidth) - 180
}
})
},
onShow() {
this.hasLogin && this.downCallback()
},
computed: {
hasLogin() {
return this.$store.state.qnToken != ''
},
allSelected: {
get() {
if (this.list && this.list.length) {
return this.list.every((shop) => {
return shop.checkedGroup
})
}
return false
},
set(val) {
if (this.list && this.list.length) {
this.list.forEach((shop) => {
shop.checkedGroup = val
shop.carItemList.forEach((good) => {
good.checked = val
})
})
}
}
},
totalPrice() {
let num = 0
if (this.list && this.list.length) {
this.list.forEach((shop) => {
shop.carItemList.forEach((good) => {
if (good.checked) {
num += round(good.price * good.weight, 2)
}
})
})
}
return num
}
},
methods: {
go2,
// 跳转详情
seeDetailsTap(item) {
// go2('paper-details', { id: '681179176769818624' })
},
// 结算
closeAnAccountTap() {
let orderGoodsList = []
this.list.forEach((el) => {
el.carItemList.forEach((good) => {
if (good.checked) {
let obj = {
buyTon: good.weight,
gramWeight: good.gramWeight,
length: good.length,
mallSupplierId: el.supplierId,
pieceQuantity: good.quantity,
productId: good.productId,
productSkuId: good.productSkuId,
unitPrice: good.price,
width: good.width
}
orderGoodsList.push(obj)
}
})
})
if (orderGoodsList.length === 0) {
uni.showToast({
title: '暂未选择商品',
icon: 'none'
})
return
}
const params = {
orderGoodsList: orderGoodsList,
purchaserEnterpriseId: this.$store.state.companyInfo.id,
userId: this.$store.state.userInfo.userId
// purchaserEnterpriseId: '677166943471538176',
// userId: '573244119569272832',
}
// console.log('params', params)
closePaperReserve(params).then((res) => {
if (res) {
go2('order-make', { orderId: res.orderId })
}
})
},
getList() {
return new Promise((resolve, reject) => {
getShoppingCarList({ ...this.params, ...this.pagination })
.then((res) => {
console.log('购物车', res)
if (res) {
res.records.forEach((el) => {
el.checkedGroup = false
el.carItemList.forEach((item) => {
item.checked = false
})
})
if (this.pagination.pageNum == 1) {
this.list = res.records
} else {
this.list = this.list.concat(res.records)
}
// this.list = []
// this.list = [...this.list, ...[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
resolve({ list: this.list, total: res.total })
}
})
.catch((err) => {
reject(err)
})
})
},
downCallback() {
this.pagination.pageNum = 1
this.getList()
.then(({ list, total }) => {
this.$refs.list.refreshSuccess({ list, total })
})
.catch((e) => {
console.error('e:', e)
this.$refs.list.refreshFail()
})
},
upCallback() {
this.pagination.pageNum++
this.getList()
.then(({ list, total }) => {
this.$refs.list.loadSuccess({ list, total })
})
.catch(() => {
this.$refs.list.loadFail()
})
},
// 分组全选
checkboxGroupTap(item, index) {
item.checkedGroup = !item.checkedGroup
item.carItemList.forEach((el) => {
el.checked = item.checkedGroup
})
},
/**
* @param {Object} shop
* @param {Object} good 子项
*/
checkboxTap(shop, good) {
good.checked = !good.checked
// 所在店铺根据商品是否全部选中
shop.checkedGroup = this.isShopSelectedAll(shop.carItemList)
},
// 店铺中的商品是否全选
isShopSelectedAll(products) {
let tempArr = true
for (var j = 0; j < products.length; j++) {
if (!products[j].checked) {
tempArr = false
break
}
}
return tempArr
},
// 全选
selectAll() {
this.allSelected = !this.allSelected
},
delTap() {
// idList
this.idList = []
let quantity = 0
this.list.forEach((el) => {
el.carItemList.forEach((good) => {
if (good.checked) {
quantity = good.quantity
this.idList.push(good.id)
}
})
})
if (this.idList.length === 0) {
uni.showToast({
title: '暂未选择商品',
icon: 'none'
})
return
}
// 单一纸品删除,数量为0时,提示用户确认后删除纸品
if(this.idList.length == 1 && quantity == 0) {
this.onlyQuantity = true
}else {
this.onlyQuantity = false
}
this.$refs.popup.open('center')
},
confirmTap() {
const params = {
idList: this.idList,
userId: this.$store.state.userInfo.userId
}
removeShoppingCar(params).then((res) => {
this.$refs.popup.close()
if (res) {
uni.showToast({
title: '删除成功!',
icon: 'success'
})
this.downCallback()
}
})
},
cancelTap() {
this.$refs.popup.close()
},
/**
* @param {Number} num
* 计数器返回值
*/
change(num, shop, good) {
good.quantity = num
good.weight = round(good.gramWeight * good.width * good.length * good.quantity * 1e-12, 4)
// let buyTon = Number(good.gramWeight) * Number(good.quantity)
// good.weight = (buyTon / (1000 * 1000)).toFixed(4)
}
}
}
</script>
<style lang="scss">
.wrapper {
.left-title {
font-size: 40rpx;
color: #000000;
letter-spacing: 0;
font-weight: 500;
}
.right-title {
font-size: 28rpx;
color: #f5222d;
text-align: right;
font-weight: 500;
float: right;
}
.group-box {
// padding: 0rpx 32rpx;
.group-checkbox {
display: flex;
flex-direction: row;
align-items: center;
height: 88rpx;
background: #ffffff;
padding: 0rpx 32rpx;
}
}
.select-img {
width: 32rpx;
height: 32rpx;
}
.checkbox {
flex: 0 0 35rpx;
margin-right: 20rpx;
}
.list-box {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
border-top: 2rpx solid rgba(221, 221, 221, 0.5);
padding: 28rpx 32rpx 40rpx 32rpx;
.list-row {
flex: 1;
display: flex;
flex-direction: row;
.image {
flex: 0 0 180rpx;
width: 180rpx;
height: 180rpx;
border-radius: 8px;
margin-right: 16rpx;
}
.right {
flex: 1;
width: 100%;
}
.name {
font-size: 34rpx;
color: #333333;
letter-spacing: 0;
text-align: left;
font-weight: 600;
padding-top: 10rpx;
}
.measure {
font-size: 24rpx;
color: #333333;
letter-spacing: 0;
text-align: left;
font-weight: 500;
margin-top: 16rpx;
}
.weight {
text-align: center;
font-size: 24rpx;
color: #888888;
font-weight: 400;
text-align: right;
padding-top: 8rpx;
}
.price-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-top: 12rpx;
.value {
font-size: 30rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
}
}
}
.footer-box {
.check-text {
font-size: 24rpx;
color: #333333;
letter-spacing: 0;
text-align: center;
font-weight: 400;
padding-left: 12rpx;
vertical-align: middle;
}
.row {
display: flex;
flex-direction: row;
align-items: center;
height: 96rpx;
background: #ffffff;
padding: 0rpx 32rpx;
.left {
flex: 0 0 200rpx;
display: flex;
flex-direction: row;
// align-items: center;
}
.right {
// flex: 1;
flex-shrink: 1;
flex-grow: 1;
// width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.name {
font-size: 28rpx;
color: rgba(0, 0, 0, 0.85);
text-align: right;
font-weight: 400;
}
.value {
vertical-align: middle;
font-size: 36rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
}
.right-balance-btn {
width: 201rpx;
height: 76rpx;
line-height: 76rpx;
background: #007aff;
border-radius: 38rpx;
font-size: 32rpx;
color: #ffffff;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
}
}
.popup-box {
width: 540rpx;
height: 226rpx;
background: #ffffff;
border-radius: 14rpx;
.tip-title {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 126rpx;
font-size: 32rpx;
color: #333333;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
.operation-row {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 100rpx;
background: #ffffff;
border-top: 2rpx solid rgba(221, 221, 221, 0.5);
.cancel-text {
flex-grow: 1;
flex-shrink: 1;
font-size: 36rpx;
color: #000000;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
.line {
flex-grow: 0;
flex-shrink: 0;
width: 2rpx;
height: 100rpx;
border-left: 2rpx solid #dcdee3;
}
.confirm-text {
flex-grow: 1;
flex-shrink: 1;
font-size: 36rpx;
color: #108ee9;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
}
}
}
</style>