Zlpt_Portal_h5/src/pages/cart/index.vue

684 lines
21 KiB
Vue
Raw Normal View History

2024-12-13 15:30:11 +08:00
<template>
<!-- 预约车 -->
2024-12-20 14:23:43 +08:00
<view class="h5-container cart-container">
<view class="nav-header">
<view style="display: flex; align-items: center">
<van-icon name="arrow-left" @click="onClickLeft()" />
<van-image height="1rem" width="3rem" :src="cartImg" />
<text> ({{ amountNum }}) </text>
</view>
<van-button
2024-12-26 18:17:45 +08:00
style="padding: 10px 20px"
2024-12-20 14:23:43 +08:00
type="primary"
size="mini"
class="primary-lease"
2024-12-26 18:17:45 +08:00
@click="onClickManage"
2024-12-20 14:23:43 +08:00
>
2024-12-26 18:17:45 +08:00
{{ isCartManage ? '退出管理' : '管理' }}
2024-12-20 14:23:43 +08:00
</van-button>
</view>
<scroll-view scroll-y :style="{ paddingBottom: actionBarHeight + 'px' }">
<view class="order-set" v-for="(item, index) in cartList" :key="index">
<van-row>
<van-col span="2">
2024-12-26 18:17:45 +08:00
<van-checkbox
2024-12-20 14:23:43 +08:00
v-model="item.isChecked"
icon-size="16px"
2024-12-26 18:17:45 +08:00
@change="onChangeAllCheckbox($event, index)"
/>
2024-12-20 14:23:43 +08:00
</van-col>
<van-col span="12">
<view class="company-box">
<van-image
fit="cover"
width="1.5rem"
height="1.2rem"
:src="companyImg"
/>
<view class="company-name">
<view> {{ item.companyPersonPhoneKey.companyName }} </view>
<van-image fit="cover" height="0.5rem" :src="companyBg" />
</view>
</view>
</van-col>
<van-col span="10" class="contacts">
2024-12-26 18:17:45 +08:00
<view> 联系人 {{ item.companyPersonPhoneKey.person }} </view>
<view>
{{ item.companyPersonPhoneKey.personPhone }}
</view>
2024-12-20 14:23:43 +08:00
</van-col>
</van-row>
<view v-for="(goods, i) in item.devInfoVoList" :key="i">
<van-row>
<van-col span="2">
2024-12-26 18:17:45 +08:00
<van-checkbox
2024-12-20 14:23:43 +08:00
v-model="goods.isChecked"
icon-size="16px"
2024-12-26 18:17:45 +08:00
@click="onChangeCheckbox($event, index)"
/>
2024-12-20 14:23:43 +08:00
</van-col>
<van-col span="22">
<view class="items-info">
<van-image
fit="cover"
height="4rem"
width="4rem"
:src="goods.picUrl"
/>
<view class="info">
<view style="color: #000">{{ goods.deviceName }}</view>
<view>装备编号{{ goods.code }}</view>
<view>装备型号{{ goods.typeName }}</view>
2024-12-26 18:17:45 +08:00
<view
style="
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
"
>
2024-12-20 14:23:43 +08:00
<text style="color: var(--van-submit-bar-price-color)">
2024-12-26 18:17:45 +08:00
租赁金额{{ goods.dayLeasePrice }}/
2024-12-20 14:23:43 +08:00
</text>
<van-stepper
button-size="16"
:max="goods.deviceCount"
v-model="goods.num"
2024-12-26 18:17:45 +08:00
v-if="!isCartManage"
/>
<van-icon
v-else
name="delete"
size="18"
@click="onDeleteCartGoods(goods.id)"
color="var(--van-submit-bar-price-color)"
2024-12-20 14:23:43 +08:00
/>
</view>
<view class="items-info">
{{ goods.rentBeginTime ? goods.rentBeginTime : '开始日期' }}
<van-image
width="1rem"
height="1rem"
:src="dateIcon"
style="margin: 0 6px"
@click="onSelectTime(1, index, i)"
/>
{{ goods.rentEndTime ? goods.rentEndTime : '结束日期' }}
<van-image
width="1rem"
height="1rem"
:src="dateIcon"
style="margin: 0 6px"
@click="onSelectTime(2, index, i)"
/>
</view>
<view>
租赁天数
{{ goods.days }}
</view>
</view>
</view>
</van-col>
</van-row>
2024-12-26 18:17:45 +08:00
<view
style="
margin-top: 14px;
display: flex;
justify-content: flex-end;
height: 30px;
line-height: 30px;
"
>
<text style="font-weight: bold; color: var(--van-submit-bar-price-color)">
2024-12-27 14:05:38 +08:00
2024-12-26 18:17:45 +08:00
{{ goods.num * goods.dayLeasePrice * goods.days }}
</text>
</view>
2024-12-20 14:23:43 +08:00
</view>
<van-row style="padding: 10px 0; margin-top: 10px; border-top: 1px solid #ccc">
2024-12-26 18:17:45 +08:00
<!-- <van-checkbox-group
2024-12-20 14:23:43 +08:00
v-model="item.protocolChecked"
shape="square"
icon-size="16px"
>
<van-checkbox name="1">
我已阅读并同意
<text class="protocol" @click.stop="onViewProtocol">
xxx公司协议
</text>
</van-checkbox>
2024-12-26 18:17:45 +08:00
</van-checkbox-group> -->
<van-checkbox v-model="item.protocolChecked" icon-size="16px">
我已阅读并同意
<text class="protocol" @click.stop="onViewProtocol"> xxx公司协议 </text>
</van-checkbox>
2024-12-20 14:23:43 +08:00
</van-row>
</view>
</scroll-view>
<van-popup v-model:show="showBottom" position="bottom" :destroy-on-close="true">
<van-date-picker
v-model="leaseTime"
@confirm="onConfirm"
@cancel="onCancel"
:min-date="minDate"
:max-date="maxDate"
title="选择日期"
/>
</van-popup>
2024-12-27 18:04:48 +08:00
<van-popup v-model:show="showBottomAddress" position="bottom" :style="{ height: '50%' }">
2024-12-20 14:23:43 +08:00
<van-address-list
v-model="chosenAddressId"
:list="addressList"
@click-item="onClickAddress"
2024-12-27 18:04:48 +08:00
@add="onAddAddress"
2024-12-20 14:23:43 +08:00
/>
</van-popup>
<van-submit-bar
button-color="#579d92"
button-text="提交"
:price="totalPrice"
@submit="onSubmitOrder"
2024-12-26 18:17:45 +08:00
v-if="!isCartManage"
2024-12-20 14:23:43 +08:00
>
<template #default>
<view class="amount"> 共计 {{ amountDevice }} 件装备 </view>
</template>
<template #tip>
<text @click="onClickLink">
{{ address.length === 0 ? '请选择收货地址' : `收货地址:${address}` }}
</text>
</template>
</van-submit-bar>
2024-12-26 18:17:45 +08:00
<van-submit-bar
button-color="#579d92"
button-text="删除"
@submit="onDeleteCart"
v-if="isCartManage"
>
<template #default>
<van-checkbox v-model="checkedAll" @change="onChangeDelete">全选</van-checkbox>
</template>
</van-submit-bar>
2024-12-13 15:30:11 +08:00
</view>
</template>
<script setup>
2024-12-20 14:23:43 +08:00
import companyImg from '@/static/goods/company-img.png'
import companyBg from '@/static/goods/company-bg.png'
import cartImg from '@/static/cart/cart.png'
import dateIcon from '@/static/goods/date-icon.png'
import { computed, nextTick, ref } from 'vue'
import { onHide, onLoad, onShow } from '@dcloudio/uni-app'
2024-12-26 18:17:45 +08:00
import {
getBookCarDetailsAPI,
getAddressListAPI,
submitBookCarAPI,
deleteBookCarAPI,
deleteBookCarByIdsAPI,
} from '@/services/cart/index.js'
2024-12-20 14:23:43 +08:00
import moment from 'moment'
const cartList = ref([])
const showBottom = ref(false)
const showBottomAddress = ref(false)
const minDate = new Date(moment().format('YYYY'), moment().format('MM') - 1, moment().format('DD'))
const maxDate = new Date(moment().format('YYYY') * 1 + 100, 12, 31)
const timeType = ref(0)
const activeIndex = ref(0)
const goodsIndex = ref(0)
const leaseTime = ref()
const address = ref('')
const actionBarHeight = ref()
const chosenAddressId = ref()
const addressList = ref([])
2024-12-26 18:17:45 +08:00
const isCartManage = ref(false)
const checkedAll = ref(false)
2024-12-20 14:23:43 +08:00
const onClickLeft = () => {
uni.showTabBar()
uni.switchTab({
url: '/pages/index/index',
})
}
const onSubmitOrder = async () => {
if (amountDevice.value < 1) {
showFailToast('请选择装备')
return
}
let isDays = false
try {
amountDeviceList.value.forEach((e) => {
if (e.days < 1) {
showFailToast('有装备租期未选择或租期为0请重新选择后再提交')
isDays = true
throw new Error()
}
})
} catch (error) {}
if (isDays) return
let isRead = false
try {
cartList.value.forEach((e) => {
2024-12-26 18:17:45 +08:00
const isSelect = e.devInfoVoList.some((j) => j.isChecked === true)
if (isSelect && !e.protocolChecked) {
2024-12-20 14:23:43 +08:00
showFailToast('请阅读公司合同')
isRead = true
throw new Error()
}
})
} catch (error) {}
if (isRead) return
if (address.value.length == 0) {
showFailToast('请选择收货地址')
return
}
// 组装参数
const detailsList = amountDeviceList.value.map((e) => {
return {
maId: e.maId,
id: e.id,
rentBeginTime: e.rentBeginTime + ' ' + '00:00:00',
rentEndTime: e.rentEndTime + ' ' + '00:00:00',
manageType: e.manageType,
days: e.days,
num: e.num,
costs: e.num * e.days * e.dayLeasePrice,
}
})
const paramsList = []
cartList.value.forEach((j, index) => {
let itemsArray = []
j.devInfoVoList.forEach((e) => {
2024-12-26 18:17:45 +08:00
if (e.isChecked) {
2024-12-20 14:23:43 +08:00
itemsArray.push({
maId: e.maId,
id: e.id,
2024-12-26 18:17:45 +08:00
rentBeginTime: e.rentBeginTime + ' ' + '00:00:00',
rentEndTime: e.rentEndTime + ' ' + '23:59:59',
2024-12-20 14:23:43 +08:00
manageType: e.manageType,
days: e.days,
num: e.num,
costs: e.num * e.days * e.dayLeasePrice,
})
}
})
if (itemsArray.length > 0) {
paramsList[index] = {
cost: 0,
detailsList: itemsArray,
address: address.value,
}
}
})
paramsList.forEach((e) => {
e.cost = e.detailsList.reduce((accumulator, currentValue) => {
return accumulator + currentValue.costs
}, 0)
})
const res = await submitBookCarAPI(paramsList)
if (res.code === 200) {
showSuccessToast('提交成功')
2024-12-26 18:17:45 +08:00
setTimeout(() => {
2024-12-27 18:04:48 +08:00
uni.navigateTo({ url: `/pages/order-list/index?type=2` })
2024-12-26 18:17:45 +08:00
}, 500)
// getDeviceDetailsData()
2024-12-20 14:23:43 +08:00
}
}
2024-12-27 18:04:48 +08:00
const onViewProtocol = () => {
uni.navigateTo({
url: '/pages/agreement/index',
})
}
2024-12-20 14:23:43 +08:00
const onSelectTime = (type, index, goodsI) => {
timeType.value = type
activeIndex.value = index
goodsIndex.value = goodsI
showBottom.value = true
}
const onConfirm = () => {
if (timeType.value === 1) {
cartList.value[activeIndex.value].devInfoVoList[goodsIndex.value].rentBeginTime =
leaseTime.value.join('-')
} else {
if (
moment(leaseTime.value.join('-')).isBefore(
moment(
cartList.value[activeIndex.value].devInfoVoList[goodsIndex.value].rentBeginTime,
),
)
) {
showFailToast('租赁结束日期不能小于租赁开始日期')
return
} else {
cartList.value[activeIndex.value].devInfoVoList[goodsIndex.value].rentEndTime =
leaseTime.value.join('-')
cartList.value[activeIndex.value].devInfoVoList[goodsIndex.value].days = moment(
leaseTime.value.join('-'),
).diff(
cartList.value[activeIndex.value].devInfoVoList[goodsIndex.value].rentBeginTime,
'day',
)
}
}
showBottom.value = false
leaseTime.value = []
}
2024-12-26 18:17:45 +08:00
const onClickManage = () => {
isCartManage.value = !isCartManage.value
}
2024-12-20 14:23:43 +08:00
const onCancel = () => {
showBottom.value = false
}
// 获取预约车列表
const getDeviceDetailsData = async () => {
const { data: res } = await getBookCarDetailsAPI()
cartList.value = res
cartList.value.forEach((e) => {
2024-12-26 18:17:45 +08:00
e.isChecked = false
e.protocolChecked = false
2024-12-20 14:23:43 +08:00
e.devInfoVoList.forEach((j) => {
2024-12-26 18:17:45 +08:00
e.isChecked = false
2024-12-20 14:23:43 +08:00
j.days = 0
j.num = 1
j.costs = 0
j.rentBeginTime = ''
j.rentEndTime = ''
j.lease_date = null
})
})
}
// 获取地址
const getAddressListData = async () => {
const { rows: res } = await getAddressListAPI()
addressList.value = res.map((e, index) => {
return {
id: index,
name: '',
tel: '',
address: `${e.provinceName}${e.cityName}${e.areaName}${e.address}`,
isDefault: false,
}
})
}
const totalPrice = computed(() => {
let orderAmountPice = 0
cartList.value.forEach((e) => {
e.devInfoVoList.forEach((g) => {
2024-12-26 18:17:45 +08:00
if (g.isChecked) {
2024-12-20 14:23:43 +08:00
orderAmountPice = g.num * g.dayLeasePrice * g.days + orderAmountPice
}
})
})
return orderAmountPice * 100
})
// 计算所有装备
const amountNum = computed(() => {
let amountNum = 0
cartList.value.forEach((e) => {
amountNum = e.devInfoVoList.length + amountNum
})
return amountNum
})
// 已勾选的装备列表
const amountDeviceList = computed(() => {
let selectList = []
cartList.value.forEach((e) => {
e.devInfoVoList.forEach((g) => {
2024-12-26 18:17:45 +08:00
if (g.isChecked) {
2024-12-20 14:23:43 +08:00
selectList.push(g)
}
})
})
return selectList
})
const amountDevice = computed(() => {
let amountNum = 0
cartList.value.forEach((e) => {
e.devInfoVoList.forEach((g) => {
2024-12-26 18:17:45 +08:00
if (g.isChecked) {
2024-12-20 14:23:43 +08:00
amountNum++
}
})
})
return amountNum
})
2024-12-26 18:17:45 +08:00
const onChangeAllCheckbox = (e, index) => {
2024-12-20 14:23:43 +08:00
cartList.value[index].devInfoVoList.forEach((j) => {
2024-12-26 18:17:45 +08:00
j.isChecked = e
2024-12-20 14:23:43 +08:00
})
2024-12-26 18:17:45 +08:00
checkedAll.value = cartList.value.every((i) => i.isChecked === true)
2024-12-20 14:23:43 +08:00
}
2024-12-26 18:17:45 +08:00
const onChangeCheckbox = (e, index) => {
const isCheckAll = cartList.value[index].devInfoVoList.every((j) => j.isChecked === true)
2024-12-20 14:23:43 +08:00
if (isCheckAll) {
2024-12-26 18:17:45 +08:00
cartList.value[index].isChecked = true
2024-12-20 14:23:43 +08:00
} else {
2024-12-26 18:17:45 +08:00
cartList.value[index].isChecked = false
2024-12-20 14:23:43 +08:00
}
2024-12-26 18:17:45 +08:00
checkedAll.value = cartList.value.every((i) => i.isChecked === true)
2024-12-20 14:23:43 +08:00
}
// 获取底部操作栏高度 适配底部内容
const getActionBarHeight = () => {
const query = uni.createSelectorQuery().in(this)
query
.select('.van-safe-area-bottom')
.boundingClientRect((data) => {
if (data) {
actionBarHeight.value = data.height
}
})
.exec()
}
2024-12-26 18:17:45 +08:00
const onChangeDelete = (val) => {
cartList.value.forEach((e) => {
e.isChecked = val
})
}
2024-12-20 14:23:43 +08:00
// 选择地址
const onClickLink = () => {
showBottomAddress.value = true
}
const onClickAddress = (res) => {
address.value = res.address
showBottomAddress.value = false
}
2024-12-26 18:17:45 +08:00
// 删除 底部操作
const onDeleteCart = () => {
showConfirmDialog({
title: '温馨提示',
message: '是否确定删除这条预约车记录',
})
.then(async () => {
let ids = []
cartList.value.forEach((e) => {
e.devInfoVoList.forEach((j) => {
if (j.isChecked) {
ids.push(j.id)
}
})
})
const res = await deleteBookCarByIdsAPI({ ids })
if (res.code === 200) {
showSuccessToast('删除成功')
getDeviceDetailsData()
}
})
.catch(() => {})
}
const onDeleteCartGoods = (id) => {
showConfirmDialog({
title: '温馨提示',
message: '是否确定删除这条预约车记录',
})
.then(async () => {
const res = await deleteBookCarAPI({ id })
if (res.code === 200) {
showSuccessToast('删除成功')
getDeviceDetailsData()
}
})
.catch(() => {})
}
2024-12-27 18:04:48 +08:00
const onAddAddress = () => {
// console.log('新增地址')
uni.navigateTo({ url: '/pages/add-address/index' })
}
2024-12-20 14:23:43 +08:00
onLoad(() => {
nextTick(() => {
getActionBarHeight()
})
})
onShow(() => {
getDeviceDetailsData()
getAddressListData()
uni.hideTabBar()
})
onHide(() => {
cartList.value = []
address.value = ''
})
2024-12-13 15:30:11 +08:00
</script>
2024-12-20 14:23:43 +08:00
<style lang="scss" scoped>
.cart-container {
padding: 10px;
box-sizing: border-box;
background: linear-gradient(to bottom, #bfdfdb, #f9f9f9, #fff);
}
.order-set {
background-color: #fff;
padding: 10px;
box-sizing: border-box;
border-radius: 6px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
.van-row {
padding: 2px 0;
display: flex;
align-items: center;
}
}
.nav-header {
height: 40px;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: $uni-navbar-bg-color;
text:nth-child(2) {
margin-left: 8px;
color: #0292f9;
font-size: 16px;
font-weight: bold;
font-style: italic;
}
}
.amount {
font-size: 13px;
color: #ccc;
}
.company-box {
display: flex;
align-items: center;
2024-12-13 15:30:11 +08:00
width: 100%;
2024-12-20 14:23:43 +08:00
.company-name {
width: 100%;
display: flex;
flex-direction: column;
view {
padding-left: 6px;
font-size: 13px;
font-weight: bold;
2024-12-27 18:04:48 +08:00
margin-bottom: -6px;
2024-12-20 14:23:43 +08:00
}
.van-image {
width: 100%;
}
}
}
.contacts {
2024-12-27 18:04:48 +08:00
font-size: 13px;
text-align: right;
2024-12-20 14:23:43 +08:00
}
.items-info {
display: flex;
2024-12-26 18:17:45 +08:00
2024-12-20 14:23:43 +08:00
align-items: center;
.info {
font-size: 12px;
2024-12-26 18:17:45 +08:00
flex: 1;
2024-12-20 14:23:43 +08:00
view {
padding: 1px 0 1px 10px;
font-size: 12px;
color: #6f6f6f;
.van-image {
margin: 0 4px;
}
}
& view:first-child {
font-size: 14px;
font-weight: bold;
}
}
}
.protocol {
font-size: 13px;
color: #1989fa;
}
:deep(.van-address-item__edit) {
display: none;
2024-12-13 15:30:11 +08:00
}
2024-12-26 18:17:45 +08:00
:deep(.van-submit-bar__bar) {
justify-content: space-between;
}
2024-12-27 18:04:48 +08:00
:deep(.van-address-item__name) {
margin-bottom: 0;
}
2024-12-13 15:30:11 +08:00
</style>