Files
gjt_mini/pages/truckRent/detailInfo.vue
2025-12-30 09:44:46 +08:00

625 lines
17 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>
<view class="container">
<view class="item">
<view class="title required">品牌</view>
<u-picker :show="showBrandPicker" :columns="[brands]" keyName="dicName" :immediateChange="true"
@confirm="confirmBand" @cancel="showBrandPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="brands[info.brand - 1].dicName" @tap="showBrandPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">型号</view>
<u--input border="surround" :value="modelName" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">车牌号</view>
<u-picker :show="showPlateNumberPicker" :columns="[inStoreList]" keyName="plateNumber" :immediateChange="true"
@confirm="confirmPlateNumber" @cancel="showPlateNumberPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="info.plateNumber" @tap="showPlateNumberPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">车架号</view>
<u--input border="surround" v-model="info.vin" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">车身广告</view>
<u-picker :show="showHasAdvPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmHasAdv" @cancel="showHasAdvPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.hasAdvertisement - 1].dicName" @tap="showHasAdvPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">尾板</view>
<u-picker :show="showHasTailPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmHasTail" @cancel="showHasTailPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.hasTailboard - 1].dicName" @tap="showHasTailPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">是否有挂</view>
<u-picker :show="showIsHangPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmIsHang" @cancel="showIsHangPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.isHang - 1].dicName" @tap="showIsHangPicker = true">
</u--input>
</view>
<view class="item">
<view class="title">挂车牌号</view>
<u--input border="surround" v-model="info.hangPlateNumber" fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">合同交车日期</view>
<u--input border="surround" :value="formatDateTime(info.handoverDate)" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">约定交车日期</view>
<u--input border="surround" :value="formatDateTime(info.appointedDate)" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title">运维预计交车日期</view>
<u-datetime-picker
:show="showPredictDatePicker"
mode="date"
@confirm="confirmPredictDate"
@cancel="showPredictDatePicker = false"
></u-datetime-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="formatDateTime(info.operationExpectedDeliveryDate)" @tap="showPredictDatePicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">是否一致</view>
<u-switch v-model="info.isAccord" size="50"
disabled
:inactiveValue="0" :activeValue="1"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view class="item">
<view class="title">备注</view>
<u--textarea border="surround" v-model="info.remark" fontSize="26" autoHeight></u--textarea>
</view>
<view class="item">
<button class="btn checkList required" @tap="openCheckListPopup">备车检查单</button>
</view>
<view class="item">
<view class="title required">备车完成</view>
<u-switch v-model="prepareOk" size="50"
@change="prepareOkChange"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view class="item">
<view class="title">备车完成时间</view>
<u--input border="surround" disabled fontSize="26"
:value="formatDateTime(info.standbyDate, 'hour')">
</u--input>
</view>
<view class="btns">
<button class="save" @tap="saveStandbyVehicleDetail">保存</button>
<button class="cancel" @tap="navigateBack">取消</button>
</view>
<u-popup :show="checkListShow" mode="right" @close="checkListShow = false">
<scroll-view scroll-y="true" style="height: 95vh;">
<no-bad-table :columns="columns" :list="formDataList" :spanArr="spanArr"
:slot-cols="['dataCategory', 'dataName', 'takeTruck', 'quantity']"
:span-method="objectSpanMethod">
<template v-slot="{ row, col, index }">
<view v-if="col.key == 'dataCategory'" style="white-space: pre-wrap">
{{ row.dataCategory }}
</view>
<view v-else-if="col.key == 'dataName'" style="white-space: pre-wrap">
{{ row.dataName }}
</view>
<view v-else-if="col.key == 'takeTruck'" style="display: flex; justify-content: center;">
<u-switch size="50"
v-model="row.takeTruck"
@change="switchTakeTruck(index)"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view v-else-if="col.key == 'quantity' && !row.notUpdate" style="display: flex; justify-content: center;">
<u--input border="surround" fontSize="26"
type="number"
:value="row.quantity"
@change="inputQuality($event, index)"
>
</u--input>
</view>
</template>
</no-bad-table>
<view class="btns">
<button class="save" @tap="saveFormDataList">保存</button>
<button class="cancel" @tap="cancelFormDataChange">取消</button>
</view>
</scroll-view>
</u-popup>
</view>
</template>
<script>
import {
getUser
} from "@/utils/auth.js";
export default {
options: {
styleIsolation: 'shared', // 解除样式隔离
},
data() {
return {
mainId: 0, // 备车主表id
id: 0, // 备车单中某一辆车辆信息id
info: {}, // 该备车车辆记录的数据
brands: [],
truckType: [],
yesNoDic: [],
showBrandPicker: false,
showHasAdvPicker: false, // hasAdvertisement
showHasTailPicker: false, // hasTailboard
showIsHangPicker: false,
showPredictDatePicker: false,
showPlateNumberPicker: false,
prepareOk: false, // 备车完成 switch
checkListShow: false, // 检查单弹窗
formDataList: [], // 备车单数据
spanArr: [],
columns: [
{
title: "检查类别",
key: "dataCategory"
},
{
title: '检查项目',
key: 'dataName'
},
{
title: '选择',
key: 'takeTruck'
},
{
title: '数量',
key: 'quantity'
}
],
inStoreList: [], // 在库状态车辆列表
}
},
methods: {
getData() {
this.$api.standbyVehicle.getById({ id: this.mainId }).then(res => {
if (res.code != 200 || !res.data.detailList) {
return
}
this.info = res.data.detailList.find(x => x.id == this.id)
// 已有备车完成时间,说明已备完车
if (this.info.standbyDate) {
this.prepareOk = true
}
this.getInStoreList()
// formDataList为深度拷贝的一个对象并不会直接影响到该车辆的检查单信息
this.formDataList = this.processFormDataList(this.deepClone(this.info.formDataList))
this.getSpanArr(this.formDataList)
// console.log(`this.info:\n`, this.info)
console.log(`this.formDataList:\n`, this.formDataList)
})
},
getDic() {
this.$api.standbyVehicle.getVehicleBrand().then(res => {
this.brands = res
})
this.$api.standbyVehicle.getTruckType().then(res => {
this.truckType = res
})
this.$api.standbyVehicle.getYesNoDic().then(res => {
this.yesNoDic = res
})
},
formatDateTime(obj, type = "date") {
if (obj == null) {
return ""
}
// 精确到日
if (type == "date") {
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return y + "-" + m.substring(m.length - 2, m.length) + "-" + d.substring(d.length - 2, d.length);
}
// 精确到小时
else if (type == "hour") {
const date = new Date(obj); // 将时间戳转换为毫秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:00`;
}
},
timestampToDateAndBack(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始所以要+1
const day = date.getDate().toString().padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
const newTimestamp = new Date(`${formattedDate} 00:00:00`).getTime();
return newTimestamp;
},
getNowTimestamp() {
// 获取当前时间精确到小时的时间戳
const now = new Date();
now.setMinutes(0, 0, 0); // 设置分钟、秒、毫秒为0
return now.getTime(); // 返回时间戳
},
confirmBand(e) {
// 没有更改
if (e.indexs[0] + 1 == this.info.brand) {
this.showBrandPicker = false
return
}
this.info.brand = e.indexs[0] + 1
this.showBrandPicker = false
this.getInStoreList() // 品牌一变,需要重新获取车牌号列表(每种品牌的车牌号列表不同)
this.info.plateNumber = ""
this.info.vin = ""
},
confirmHasAdv(e) {
this.info.hasAdvertisement = e.indexs[0] + 1
this.showHasAdvPicker = false
},
confirmHasTail(e) {
this.info.hasTailboard = e.indexs[0] + 1
this.showHasTailPicker = false
},
confirmIsHang(e) {
this.info.isHang = e.indexs[0] + 1
this.showIsHangPicker= false
},
confirmPredictDate(e) {
// 首次选择日期时,时间戳信息精确到了秒,故这里统一处理,使之仅精确到日
this.info.operationExpectedDeliveryDate = this.timestampToDateAndBack(e.value)
this.showPredictDatePicker = false
},
confirmPlateNumber(e) {
console.log(e)
this.info.plateNumber = e.value[0].plateNumber
this.info.vin = e.value[0].vin
this.info.truckId = e.value[0].id // 换车牌本质是换这个车辆id
this.showPlateNumberPicker = false
},
prepareOkChange(value) {
if (value) {
this.info.standbyDate = this.getNowTimestamp()
// 比较备车完成时间和约定交车日期,若是同一天(或早于约定日期) 则认为 "一致"将isAccord设置为1
if (this.timestampToDateAndBack(this.info.standbyDate) <= this.info.appointedDate) {
this.info.isAccord = 1
} else {
this.info.isAccord = 0
}
} else {
this.info.standbyDate = null
this.info.isAccord = 0
}
},
navigateBack() {
uni.navigateBack()
},
switchTakeTruck(index) {
this.formDataList[index].takeTruck = !this.formDataList[index].takeTruck
},
inputQuality(value, index) {
value = value.replace(/[^0-9.]/g, '')
this.formDataList[index].quantity = value
},
processFormDataList(dataList) {
dataList = dataList.filter(x => x.dataName != "检查项目")
for (let item of dataList) {
if (item.takeTruck == "true") {
item.takeTruck = true
} else if (item.takeTruck == "false") {
item.takeTruck = false
}
if (item.quantity !== "" && item.quantity !== null) {
item.quantity = parseFloat(Number(item.quantity).toFixed(2))
}
}
return dataList
},
// https://www.cnblogs.com/janni/p/12992591.html
getSpanArr(data) {
this.spanArr = []
for (let i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0
} else {
// 判断当前元素与上一个元素是否相同 dataCategory (类别字段)
if (data[i].dataCategory === data[i - 1].dataCategory) {
this.spanArr[this.pos] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.pos = i;
}
}
}
},
objectSpanMethod(row, column, rowIndex, columnIndex) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
}
}
},
// https://www.kancloud.cn/uview/uview-ui_v2/2579089
deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== 'object') return obj;
if (obj instanceof Date) {
let date = new Date();
date.setTime(obj.getTime());
return date;
}
if (obj instanceof RegExp) {
let re = new RegExp(obj.source);
re.lastIndex = obj.lastIndex;
return re;
}
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = this.deepClone(obj[key]);
}
}
return newObj;
},
openCheckListPopup() {
if (!this.info.truckId) {
uni.showToast({
title: '请先选择车牌号',
duration: 1500,
icon: "error"
})
return
}
if (this.info.formDataList.length == 0) {
this.$api.standbyVehicle.getFormDataListByTruckId({ id: this.info.truckId }).then(res => {
this.formDataList = this.processFormDataList(res.data)
this.getSpanArr(this.formDataList)
this.checkListShow = true
uni.setNavigationBarTitle({
title: '备车检查单'
});
})
} else {
this.checkListShow = true
uni.setNavigationBarTitle({
title: '备车检查单'
});
}
},
saveFormDataList() {
this.checkListShow = false
this.info.formDataList = this.deepClone(this.formDataList)
uni.setNavigationBarTitle({
title: '备车信息'
});
},
cancelFormDataChange() {
this.formDataList = this.processFormDataList(this.deepClone(this.info.formDataList))
this.getSpanArr(this.formDataList)
this.checkListShow = false
uni.setNavigationBarTitle({
title: '备车信息'
});
},
// 保存备车信息表
saveStandbyVehicleDetail() {
if (!this.info.plateNumber) {
uni.showToast({
title: '请选择车牌号',
duration: 1500,
icon: "error"
})
return
}
this.$api.standbyVehicle.saveStandbyVehicleDetail(this.info).then(res => {
// todo res是接口data数据之后研究一下如何获取整个内容
if (res == this.info.id) {
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
});
}
})
},
getInStoreList() {
this.$api.truck.queryInStoreList({ brand: this.info.brand, model: this.info.model }).then(res => {
this.inStoreList = res
})
}
},
computed: {
modelName() {
if (this.truckType.length == 0) {
return ""
}
return this.truckType.find(x => x.dicCode == this.info.model)?.dicName ?? ""
}
},
onLoad(options) {
if (options.id) {
this.id = options.id
}
if (options.mainId) {
this.mainId = options.mainId
}
this.getData()
this.getDic()
this.userInfo = getUser() || {}
console.log(`userInfo:\n`, this.userInfo)
},
onPullDownRefresh(){
uni.stopPullDownRefresh() //刷新数据之后停止刷新效果
},
onShow() {
},
destroyed(){
console.log(`备车信息页 destroyed`)
this.$api.standbyVehicle.delCache({ key: this.id }).then(res => {
console.log(`清空操作标识`)
console.log(res)
})
},
}
</script>
<style lang="less" scoped>
.container {
// background-color: #d7d7d7;
padding: 30rpx;
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: '*';
color: red;
margin-right: 3rpx;
}
}
.btn.checkList {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
background-color: #7ba746;
color: white;
margin-left: 0;
&.required::before {
content: '*';
color: red;
margin-right: 3rpx;
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 40rpx;
button {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
}
.cancel {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
.save {
background-color: #7ba746;
color: white;
}
}
}
/deep/ picker-view {
height: 450rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: #dadbde !important;
border-style: solid;
}
/deep/ .u-switch {
border-color: rgba(0, 0, 0, 0.12) !important;
}
/deep/ .u-slide-right-enter-to.u-slide-right-enter-active {
width: 750rpx;
}
/deep/ .td_wrap {
height: auto !important;
}
/deep/ checkbox-group view.td {
width: 186rpx !important;
}
/deep/ checkbox-group view.td_wrap {
width: 186rpx !important;
}
/deep/ .no-bad-table-wrap .td.rowspan {
display: flex;
align-items: center;
justify-content: center;
}
/deep/ .div-table-head .thead .tr view {
width: 186rpx !important;
}
/deep/ no-bad-table {
overflow-x: hidden;
}
/deep/ .no-bad-table-wrap .thead .tr .td {
background-color: #7ba746;
color: white;
}
/deep/ .no-bad-table-wrap .thead .tr .td .td_wrap {
background-color: #7ba746;
color: white;
}
</style>