Zlpt_Portal/src/views/cart/index.vue

936 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="display: flex; flex-direction: column; height: 100vh">
<div style="width: 100%; background-color: #f5f5f5">
<Header class="wapper" />
</div>
<div class="container">
<el-breadcrumb separator="/" class="primary-lease">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>预约车</el-breadcrumb-item>
</el-breadcrumb>
<div class="cart-title">
<div></div>
<div style="margin: 0 8px">预约车</div>
<div>({{ amountNum }})</div>
</div>
<el-row class="cart-th">
<el-col :span="2">
<div>
<el-checkbox v-model="allChecked" @change="onChangeAll" :key="allKey">
全选
</el-checkbox>
</div>
</el-col>
<el-col :span="9">
<div>装备信息</div>
</el-col>
<el-col :span="3">
<div>租期</div>
</el-col>
<el-col :span="2">
<div>日租金/元</div>
</el-col>
<el-col :span="2">
<div>天数</div>
</el-col>
<el-col :span="2">
<div>数量</div>
</el-col>
<el-col :span="2">
<div>总金额/元</div>
</el-col>
<el-col :span="2">
<div>操作</div>
</el-col>
</el-row>
<div class="cart-tbody" v-for="(item, index) in cardList" :key="index">
<el-row style="border-bottom: 1px solid #ccc">
<el-col :span="1">
<div style="text-align: center">
<el-checkbox
v-model="item.isChecked"
:key="index"
@change="onChangeCompany($event, index, item)"
>
</el-checkbox>
</div>
</el-col>
<el-col :span="22" class="cart-user-info">
<div>{{ item.companyPersonPhoneKey.companyName }}</div>
<div class="user-name">{{ item.companyPersonPhoneKey.person }}</div>
<div class="user-phone">{{ item.companyPersonPhoneKey.personPhone }}</div>
</el-col>
</el-row>
<el-row class="cart-list" v-for="(goods, j) in item.devInfoVoList" :key="goods.id">
<el-col :span="1">
<div style="text-align: center">
<el-checkbox
v-model="goods.isChecked"
@change="onChangeGoods(index)"
:key="goods.id"
>
</el-checkbox>
</div>
</el-col>
<el-col :span="9" class="goods-info">
<img :src="goods.picUrl" alt="" />
<div class="goods-code">
<div style="font-size: 14px; font-weight: bold">
{{ goods.deviceName }}
</div>
<div>装备编号: {{ goods.code }}</div>
<div>装备型号: {{ goods.typeName }}</div>
</div>
</el-col>
<el-col :span="4">
<div class="lease-date">
<div style="margin-bottom: 8px">
{{ goods.rentBeginTime }}
<span v-if="goods.rentBeginTime && goods.rentEndTime">~</span>
{{ goods.rentEndTime }}
</div>
<!-- <el-date-picker
style="width: 100px; margin-top: 10px"
v-model="goods.lease_date"
type="daterange"
size="small"
value-format="YYYY-MM-DD"
@change="onLeaseDateChange($event, goods)"
>
</el-date-picker> -->
<CustomDatePickerButton
:modelValue="goods.lease_date"
:companyIndex="index"
:goodsIndex="j"
type="primary"
size="large"
placeholder="选择日期"
@onLeaseDateChange="onLeaseDateChange"
/>
</div>
</el-col>
<el-col :span="2">
<div class="red-font">
{{ goods.dayLeasePrice }}
</div>
</el-col>
<el-col :span="2">
<div class="red-font" style="color: #0062ff">
{{ goods.days }}
</div>
</el-col>
<el-col :span="2">
<div>
<el-input-number
v-model="goods.num"
style="width: 100px"
:min="1"
:max="goods.deviceCount || 1"
size="small"
/>
</div>
</el-col>
<el-col :span="2">
<div class="red-font">
{{ goods.num * goods.days * goods.dayLeasePrice }}
</div>
</el-col>
<el-col :span="2">
<div>
<!-- <el-button
link
@click="onDeleteGoods(goods.id)"
style="color: #ff4800; font-weight: bold"
>
删除
</el-button> -->
<el-popconfirm
width="220"
:icon="InfoFilled"
icon-color="#626AEF"
title="确定删除该条预约车记录吗?"
@confirm="onDeleteGoods(goods.id)"
>
<template #reference>
<el-button link style="color: #ff4800; font-weight: bold">
删除</el-button
>
</template>
<template #actions="{ confirm }">
<el-button size="small">取消</el-button>
<el-button type="danger" size="small" @click="confirm()">
确定
</el-button>
</template>
</el-popconfirm>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="16">
<div class="checkbox-container">
<el-checkbox v-model="item.protocolChecked">
我已阅读并同意签署
</el-checkbox>
<a @click.stop="handleViewWord(index)">
《{{ item.companyPersonPhoneKey.companyName }}租赁服务合同》
</a>
</div>
</el-col>
</el-row>
</div>
<div class="protocol-handle" v-if="cardList.length > 0">
<el-row style="margin: 15px 0">
<el-col :span="24">
<el-collapse v-model="activeNames">
<el-collapse-item :title="addressTitle" name="1">
<template v-if="addressList.length > 0">
<div
:key="index"
class="address-item"
@click="onSelectAddress(item.addressName)"
v-for="(item, index) in addressList"
>
{{ item.addressName }}
</div>
</template>
<template v-else>
<div style="width: 100%; text-align: center; font-size: 14px">
当前没有收货地址...
<a
style="
color: #00a288;
cursor: pointer;
margin-left: 5px;
text-decoration: underline;
"
@click="onAddAddress"
>
点击新增
</a>
</div>
</template>
</el-collapse-item>
</el-collapse>
</el-col>
</el-row>
<el-row style="display: flex; align-items: center">
<el-col :span="16">
<!-- <div class="checkbox-container">
<el-checkbox v-model="protocolChecked">
我已阅读并同意签署
<a @click="handleViewWord"> 《xxxx公司租赁服务合同》 </a>
</el-checkbox>
</div> -->
</el-col>
<el-col :span="3">
<div>
共:<span style="color: #ff4800; font-weight: bold">{{
amountDevice
}}</span>
件装备
</div>
</el-col>
<el-col :span="3">
<div class="red-font">
订单总金额:<span style="color: #ff4800; font-weight: bold"
>{{ orderAmountPice }} 元</span
>
</div>
</el-col>
<el-col :span="2">
<div style="text-align: right">
<el-button
size="small"
@click="onCartSubmit"
style="padding: 12px 24px; background-color: #1abc9c; color: #fff"
>提交</el-button
>
</div>
</el-col>
</el-row>
</div>
<Empty v-if="cardList.length == 0" />
</div>
<FooterInfo />
<!-- 租赁协议 -->
<el-dialog
v-model="dialogFormVisibleSettleWord"
:title="settleWordTitle"
width="50%"
align-center
destroy-on-close
:close-on-click-modal="false"
>
<!-- <div style="display: flex; justify-content: center"> -->
<!-- <img src="@/assets/img/zuLin.png" style="width: 100%; height: 600px" /> -->
<!-- </div> -->
<div v-html="bookCarAgreement"></div>
<div style="display: flex; justify-content: flex-end; margin-bottom: 10px">
<span class="dialog-footer">
<el-button type="primary" @click="dialogFormVisibleSettleWord = false"
>关 闭</el-button
>
<el-button @click="submitBtn" type="success"> 下载 </el-button>
</span>
</div>
<div id="mmm" style="height: 600px"></div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import Header from 'components/header/index.vue'
import FooterInfo from 'components/FooterInfo/index.vue'
import Empty from 'components/Empty/index.vue'
import { ElMessage } from 'element-plus'
import {
getBookCarDetailsApi,
submitBookCarApi,
deleteCartByIdApi,
getBookCarAgreementApi,
} from 'http/api/cart/index'
import { getAddressListApi } from 'http/api/address-manage/index'
import moment, { max } from 'moment'
import { InfoFilled } from '@element-plus/icons-vue'
import CustomDatePickerButton from './components/date-picker-button.vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from '../../store/user'
import jsPreviewDocx from '@js-preview/docx'
import '@js-preview/docx/lib/index.css'
const userStore = useStore()
const router = useRouter()
// const protocolChecked = ref<boolean>(false)
const allKey = ref(0)
const cardList = ref<any>([])
const bookCarAgreement = ref('')
const addressTitle = ref('请选择收货地址')
const activeNames = ref('')
const addressList = ref<any>([])
const getBookCarDetailsData = async () => {
const res: any = await getBookCarDetailsApi()
cardList.value = []
cardList.value = res.data
cardList.value.forEach((e: any) => {
e.isChecked = false
e.protocolChecked = false
e.devInfoVoList.forEach((j: any) => {
j.days = 0
j.num = 1
j.costs = 0
j.rentBeginTime = ''
j.rentEndTime = ''
j.lease_date = null
})
})
}
onMounted(() => {
getBookCarDetailsData()
})
// 日期change事件
// const onLeaseDateChange = (e: any, item: any) => {
// console.log(e, '*****')
// if (!e) {
// item.rentBeginTime = ''
// item.rentEndTime = ''
// item.days = 0
// } else {
// item.rentBeginTime = e[0]
// item.rentEndTime = e[1]
// item.days = moment(e[1]).diff(e[0], 'day')
// }
// }
const onLeaseDateChange = (value: any, companyIndex: number, goodsIndex: number) => {
if (!value) {
cardList.value[companyIndex].devInfoVoList[goodsIndex].rentBeginTime = ''
cardList.value[companyIndex].devInfoVoList[goodsIndex].rentEndTime = ''
cardList.value[companyIndex].devInfoVoList[goodsIndex].days = 0
} else {
cardList.value[companyIndex].devInfoVoList[goodsIndex].rentBeginTime = value[0]
cardList.value[companyIndex].devInfoVoList[goodsIndex].rentEndTime = value[1]
cardList.value[companyIndex].devInfoVoList[goodsIndex].days =
moment(value[1]).diff(value[0], 'day') + 1
}
// cardList.value.forEach((e: any) => {
// e.devInfoVoList.forEach((j: any) => {
// if (!value) {
// j.rentBeginTime = ''
// j.rentEndTime = ''
// j.days = 0
// } else {
// j.rentBeginTime = value[0]
// j.rentEndTime = value[1]
// j.days = moment(value[1]).diff(value[0], 'day')
// }
// })
// })
}
// 删除按钮
const onDeleteGoods = async (id: number | string) => {
const res: any = await deleteCartByIdApi({ id })
if (res.code == 200) {
ElMessage({
showClose: false,
message: '删除成功',
type: 'success',
})
getBookCarDetailsData()
}
}
// 全选change事件
const onChangeAll = (e: boolean) => {
cardList.value.forEach((item: any) => {
item.isChecked = e
item.devInfoVoList.forEach((j: any) => {
j.isChecked = e
})
})
}
// 公司全选事件
const onChangeGoods = (index: number) => {
cardList.value[index].isChecked = cardList.value[index].devInfoVoList.every(
(e: any) => e.isChecked === true,
)
}
// 公司全选事件
const onChangeCompany = (e: boolean, index: number, item: any) => {
cardList.value[index].devInfoVoList.every((j) => (j.isChecked = e))
}
// 计算所有装备
const amountNum = computed(() => {
let amountNum = 0
cardList.value.forEach((e: any) => {
amountNum = e.devInfoVoList.length + amountNum
})
return amountNum
})
// 计算全选按钮的选中状态
const allChecked = computed(() => {
if (cardList.value.length < 1) {
return false
} else {
return cardList.value.every((e: any) => e.isChecked === true)
}
})
// 已勾选的装备数量
const amountDevice = computed(() => {
let amountNum = 0
cardList.value.forEach((e: any) => {
e.devInfoVoList.forEach((g: any) => {
if (g.isChecked) {
amountNum++
}
})
})
return amountNum
})
// 已勾选的装备数量
const amountDeviceList = computed(() => {
let selectList: any = []
cardList.value.forEach((e: any) => {
e.devInfoVoList.forEach((g: any) => {
if (g.isChecked) {
selectList.push(g)
}
})
})
return selectList
})
// 计算订单总价格
const orderAmountPice = computed(() => {
let orderAmountPice = 0
cardList.value.forEach((e: any) => {
e.devInfoVoList.forEach((g: any) => {
if (g.isChecked) {
orderAmountPice = g.num * g.dayLeasePrice * g.days + orderAmountPice
}
})
})
return orderAmountPice
})
// 提交按钮
const onCartSubmit = async () => {
ElMessage.closeAll()
if (amountDevice.value < 1) {
ElMessage({
showClose: false,
message: '请选择装备',
type: 'error',
})
return
}
let isRead = false
try {
cardList.value.forEach((e: any) => {
const isSelect = e.devInfoVoList.some((j: any) => j.isChecked === true)
if (isSelect && !e.protocolChecked) {
ElMessage({
showClose: false,
message: '请阅读公司合同',
type: 'error',
})
isRead = true
throw new Error()
}
})
} catch (error) {}
if (isRead) return
// if (!protocolChecked.value) {
// ElMessage({
// showClose: false,
// message: '请阅读公司合同',
// type: 'error',
// })
// return
// }
if (addressTitle.value === '请选择收货地址') {
ElMessage({
showClose: false,
message: '请选择收货地址',
type: 'error',
})
return
}
let isDays = false
try {
amountDeviceList.value.forEach((e: any) => {
if (e.days < 1) {
ElMessage({
showClose: false,
message: '有装备租期未选择或租期为0请重新选择后再提交',
type: 'error',
})
isDays = true
throw new Error()
}
})
} catch (error) {}
if (isDays) return
// 组装参数
const detailsList = amountDeviceList.value.map((e: any) => {
return {
maId: e.maId,
id: e.id,
rentBeginTime: e.rentBeginTime + ' ' + '00:00:00',
rentEndTime: e.rentEndTime + ' ' + '23:59:59',
manageType: e.manageType,
days: e.days,
num: e.num,
costs: e.num * e.days * e.dayLeasePrice,
}
})
const paramsList: any = []
cardList.value.forEach((j: any, index: any) => {
let itemsArray: any = []
j.devInfoVoList.forEach((e: any) => {
if (e.isChecked) {
itemsArray.push({
maId: e.maId,
id: e.id,
rentBeginTime: e.rentBeginTime + ' ' + '00:00:00',
rentEndTime: e.rentEndTime + ' ' + '23:59:59',
manageType: e.manageType,
days: e.days,
num: e.num,
costs: e.num * e.days * e.dayLeasePrice,
})
}
})
paramsList[index] = {
cost: 0,
detailsList: itemsArray,
address: addressTitle.value.split('')[1],
}
})
paramsList.forEach((e: any) => {
e.cost = e.detailsList.reduce((accumulator: any, currentValue: any) => {
return accumulator + currentValue.costs
}, 0)
})
// const submitParams = {
// cost: orderAmountPice.value,
// detailsList,
// }
const res: any = await submitBookCarApi(paramsList)
if (res.code === 200) {
ElMessage({
showClose: false,
message: '提交成功',
type: 'success',
})
userStore.editcurrentMenuItem('orderManagement')
setTimeout(() => {
router.push({
name: 'my-user',
})
}, 500)
// allKey.value++
// getBookCarDetailsData()
}
// console.log(res, '预约车提交结果')
}
const wordUrl = ref('')
const settleWordTitle = ref('')
const dialogFormVisibleSettleWord: any = ref(false)
//租赁服务合同
// const handleViewWord = async (index: any) => {
// // 组装参数
// const { companyName, companyId } = cardList.value[index].companyPersonPhoneKey
// let cost = 0
// let detailsList: any = []
// const isSelect = cardList.value[index].devInfoVoList.some((e: any) => e.isChecked == true)
// if (!isSelect) {
// ElMessage({
// showClose: false,
// message: '请勾选装备...',
// type: 'error',
// })
// return
// }
// cardList.value[index].devInfoVoList.map((e: any) => {
// if (e.isChecked) {
// detailsList.push({
// rentBeginTime: e.rentBeginTime,
// rentEndTime: e.rentEndTime,
// manageType: e.manageType,
// days: e.days,
// num: e.num,
// costs: e.num * e.days * e.dayLeasePrice,
// deviceName: e.deviceName,
// dayLeasePrice: e.dayLeasePrice,
// })
// cost = cost + e.num * e.days * e.dayLeasePrice
// }
// })
// const queryParams = {
// companyName: localStorage.getItem('currentCompanyName'),
// czcompanyName: companyName,
// companyId,
// cost,
// detailsList,
// }
// console.log('查询参数', queryParams)
// const res: any = await getBookCarAgreementApi(queryParams)
// bookCarAgreement.value = res.msg
// dialogFormVisibleSettleWord.value = true
// // settleWordTitle.value = '租赁服务合同'
// // // const orderId = row.orderId
// // // const res: any = await getContractDetailApi({ orderId })
// // // 打开租赁服务合同弹框
// // wordUrl.value = 'http://127.0.0.1:29300/statics/2024/12/16/test_20241216154423A003.docx'
// // dialogFormVisibleSettleWord.value = true
// // setTimeout(() => {
// // const myDocxPreviewer = jsPreviewDocx.init(document.getElementById('mmm'))
// // //传递要预览的文件地址即可
// // myDocxPreviewer
// // .preview(wordUrl.value)
// // .then((res) => {
// // console.log('预览完成')
// // })
// // .catch((e) => {
// // console.log('1111', wordUrl.value)
// // console.log('预览失败', e)
// // })
// // }, 1000)
// }
//租赁服务合同
const handleViewWord = async (index: any) => {
// 组装参数
const { companyName, companyId, personPhone } = cardList.value[index].companyPersonPhoneKey
let cost = 0
let detailsList: any = []
const isSelect = cardList.value[index].devInfoVoList.some((e: any) => e.isChecked == true)
if (!isSelect) {
ElMessage({
showClose: false,
message: '请勾选装备...',
type: 'error',
})
return
}
let isDays = true
cardList.value[index].devInfoVoList.map((e: any) => {
if (e.rentBeginTime == '' || e.rentEndTime == '') {
isDays = false
return
}
if (e.isChecked) {
detailsList.push({
rentBeginTime: e.rentBeginTime + ' ' + '00:00:00',
rentEndTime: e.rentEndTime + ' ' + '23:59:59',
manageType: e.manageType,
days: e.days,
num: e.num,
costs: e.num * e.days * e.dayLeasePrice,
deviceName: e.deviceName,
dayLeasePrice: e.dayLeasePrice,
})
cost = cost + e.num * e.days * e.dayLeasePrice
}
})
if (!isDays) {
ElMessage({
showClose: false,
message: '请选择租期',
type: 'error',
})
return
}
const queryParams = {
companyName: localStorage.getItem('currentCompanyName'),
czcompanyName: companyName,
companyId,
cost,
detailsList,
personPhone,
}
console.log('查询参数', queryParams)
try {
const res: any = await getBookCarAgreementApi(queryParams)
if (import.meta.env.VITE_API_URL == '/proxyApi') {
wordUrl.value = res.data.url
} else {
wordUrl.value = 'http://sgwpdm.ah.sgcc.com.cn/iws/ahbns/' + res.data.url
}
console.log('🚀 ~ handleViewWord ~ wordUrl.value:', wordUrl.value)
dialogFormVisibleSettleWord.value = true
settleWordTitle.value = '租赁服务合同'
setTimeout(() => {
const myDocxPreviewer = jsPreviewDocx.init(document.getElementById('mmm'))
//传递要预览的文件地址即可
myDocxPreviewer
.preview(wordUrl.value)
.then((res) => {
console.log('预览完成')
})
.catch((e) => {
console.log('1111', wordUrl.value)
console.log('预览失败', e)
})
}, 1000)
} catch (error) {
console.log('error', error)
}
}
// 下载合同为 Word 文件
const submitBtn = () => {
window.location.href = wordUrl.value
}
// 获取收货地址
const getReceiptGoodsAddress = async () => {
const res: any = await getAddressListApi({})
addressList.value = res.rows.map((e: any) => {
return {
addressName: `${e.provinceName}${e.cityName}${e.areaName}${e.address}`,
}
})
}
// 去往地址管理
const onAddAddress = () => {
userStore.editcurrentMenuItem('address-manage')
setTimeout(() => {
router.push({
name: 'my-user',
})
}, 500)
}
// 选择收货地址
const onSelectAddress = (address: any) => {
addressTitle.value = '收货地址:' + address
activeNames.value = ''
}
getReceiptGoodsAddress()
</script>
<style lang="scss" scoped>
.container {
// width: 1200px;
width: 1552px;
margin: 15px auto;
flex: 1;
// min-height: 550px;
background: #eeeff6;
font-size: 16px;
padding: 20px 10px;
background-color: #fff;
border-radius: 15px;
.cart-title {
margin-top: 20px;
padding: 10px 0;
display: flex;
align-items: center;
font-size: 18px;
font-weight: bold;
letter-spacing: 1px;
}
.cart-title div:first-child {
width: 5px;
height: 20px;
background-color: #00a288;
}
.cart-th {
margin: 15px 0;
font-size: 18px;
div {
text-align: center;
}
}
.cart-tbody {
background: #fff;
padding: 8px 12px;
margin: 10px;
.cart-user-info {
display: flex;
align-items: center;
.user-name,
.user-phone {
padding: 3px 18px;
border: 1px solid #ccc;
}
.user-name {
margin-left: 20px;
border-right: none;
}
}
.cart-list {
margin: 15px 0;
display: flex;
align-items: center;
div {
text-align: center;
}
.goods-info {
display: flex;
align-content: center;
img {
width: 160px;
height: 100px;
}
.goods-code {
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
div {
text-align: left;
}
}
}
.lease-date {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.red-font {
color: #ff4800;
font-weight: bold;
}
}
}
.protocol-handle {
background: #fff;
padding: 8px 12px;
margin: 10px;
.checkbox-container a {
color: #ff4800;
text-decoration: underline;
}
}
}
.address-item {
margin: 0 auto;
padding: 6px 10px;
cursor: pointer;
}
.address-item:hover {
background-color: #c9e7e5;
}
#mmm {
width: 100%;
height: 500px;
}
.checkbox-container {
display: flex;
align-items: center;
}
.checkbox-container a {
color: #ff4800;
text-decoration: underline;
cursor: pointer;
}
</style>