Initial commit

This commit is contained in:
lnljyang
2025-12-30 09:44:46 +08:00
commit 82b8d21506
147 changed files with 39113 additions and 0 deletions

View File

@@ -0,0 +1,625 @@
<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>