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,591 @@
<template>
<view class="container">
<view class="header">基本信息</view>
<view class="item">
<view class="title">合同编号</view>
<u--input
border="surround"
v-model="datas.contract.contractNo"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">项目名称</view>
<u--input
border="surround"
v-model="datas.contract.projectName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户名称</view>
<u--input
border="surround"
v-model="datas.contract.customerName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">备车数量</view>
<u--input
border="surround"
v-model="datas.standbyVehicleQuantity"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">交车区域</view>
<u--input
border="surround"
v-model="datas.contract.deliveryAreaName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">交车地点</view>
<u--input
border="surround"
v-model="datas.contract.handoverAddress"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">备注</view>
<u--textarea
border="surround"
v-model="datas.remark"
disabled
fontSize="26"
autoHeight
></u--textarea>
</view>
<view class="header" style="margin-top: 30rpx">车辆信息</view>
<view class="carList">
<u-checkbox-group v-model="checkoutIds" size="36" placement="column">
<view v-for="item in detailList" :key="item.id">
<view class="carItem" v-if="!item.isHidden">
<u-checkbox
:customStyle="{
marginBottom: '8px',
position: 'absolute',
top: '6px',
left: '10px',
}"
:disabled="item.standbyStatus !== 4"
:key="index"
:label="` `"
:name="item.id"
>
</u-checkbox>
<view class="innerItem">
<view class="title">品牌</view>
<u--input
border="surround"
:value="brands[item.brand - 1].dicName"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">车型</view>
<u--input
border="surround"
:value="getModelName(item.model)"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">车牌</view>
<u--input
border="surround"
:value="item.plateNumber"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">约定交车日期</view>
<u--input
border="surround"
:value="formatDateTime(item.appointedDate)"
disabled
fontSize="26"
></u--input>
</view>
<!-- <view class="innerItem">
<view class="title">备车完成时间</view>
<u--input
border="surround"
:value="formatDateTime(item.standbyDate)"
disabled
fontSize="26"
></u--input>
</view> -->
<view class="innerItem">
<view class="title">状态</view>
<u--input
border="surround"
:value="item.standbyStatusName || ''"
disabled
fontSize="26"
></u--input>
</view>
<button
class="detailBtn"
:class="{ disabled: item.disabled }"
@tap="saveCache"
:data-id="item.id"
:data-status="item.standbyStatus"
:disabled="item.disabled"
>
备车信息
</button>
</view>
</view>
</u-checkbox-group>
</view>
<view class="btns">
<button class="cancel" @tap="navigateBack">取消</button>
<button
class="done"
:class="{ disabled: _disabled }"
:disabled="_disabled"
@tap="submitApprovalConfirm"
>
备车完成
</button>
</view>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
datas: {
contractNo: "合同编号",
projectName: "项目名称",
},
tempDetailList: [], // 临时车辆信息列表 (不包含是否禁用备车信息按钮 信息)
detailList: [], // 车辆信息列表
checkoutIds: [], // 检查单选中项
id: "1058472991198855168",
brands: [], // 车辆品牌字典列表
truckType: [], // 车辆型号字典列表
userInfo: {}, // 用户信息
cacheList: [], // 操作标识缓存信息
cacheKeys: [], // 所有车辆的id联结用于获取操作标识缓存
cacheRequestTimer: 0, // 定时请求定时器
doneBtnDisabled: false, // 备车完成按钮是否禁用
isRead: false, // 页面是否处于阅读模式
};
},
computed: {
// 大部分组件的禁用直接用 disabled查看模式或者已完成签署
_disabled() {
return this.isRead;
},
},
methods: {
getData() {
this.$api.standbyVehicle.getById({ id: this.id }).then((res) => {
if (res.code == 200) {
this.datas = res.data;
// let detailList = res.data.detailList.map((item) => {
// return item;
// });
// res.data.detailList.filter(
// (item) => ![0, 6].includes(item.standbyStatus)
// ) || [];
this.tempDetailList =
res.data.detailList.map((item) => {
item.isStandby = false;
if ([0, 6].includes(item.standbyStatus)) {
item.isHidden = true; //过滤0未备车6已撤销 不能用filter提交的时候要带上这些数据
} else {
item.isHidden = false;
}
return item;
}) || [];
const keys = this.tempDetailList.map((x) => x.id).join(",");
this.cacheKeys = keys;
this.getCache({ keys });
this.getOpManagerPhone();
}
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
getCache(params) {
this.$api.standbyVehicle.getCache(params).then((res) => {
if (res.code != 200) {
this.detailList = this.tempDetailList;
return;
}
for (let item of this.tempDetailList) {
item.disabled = false;
}
const cacheList = res.data;
for (let [key, value] of Object.entries(cacheList)) {
const targetIndex = this.tempDetailList.findIndex((x) => x.id == key);
// 备车车辆某记录正在被编辑,且被编辑的人员和当前用户手机号不同
// 则禁用备车信息按钮
if (targetIndex != -1 && value != this.userInfo.phone) {
this.tempDetailList[targetIndex].disabled = true;
}
}
this.detailList = [...this.tempDetailList];
});
},
saveCache(e) {
// 保存前重新获取该id最新的操作标识缓存查看是否已被别人占用
this.$api.standbyVehicle
.getCache({ keys: e.target.dataset.id })
.then((res) => {
console.log(`该id的缓存表示:\n`, res);
const _phone = res.data[e.target.dataset.id];
if (_phone && _phone != this.userInfo.phone) {
uni.showToast({
icon: "none",
title: "已有其他运维人员在编辑此车辆",
duration: 2000,
});
this.getData();
return;
}
// 如果没有其他人正在编辑则标识当前用户正在编辑此id
const id = e.target.dataset.id;
const phone = this.userInfo.phone;
console.log(this.isRead);
const isRead = this.isRead || e.target.dataset.status != 4;
console.log(`isRead:\n`, isRead);
this.$api.standbyVehicle
.saveCache({ key: id, value: phone })
.then((res) => {
console.log(res);
uni.navigateTo({
url: `/pages/standbyVehicle/detailInfo?id=${id}&mainId=${this.id}&isRead=${isRead}`,
});
});
});
},
navigateBack() {
uni.navigateBack();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
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)
);
},
getVehicleBrand() {
this.$api.standbyVehicle.getVehicleBrand().then((res) => {
this.brands = res;
});
},
getTruckType() {
this.$api.standbyVehicle.getTruckType().then((res) => {
this.truckType = res;
});
},
getOpManagerPhone() {
const regionCode = this.datas.contract.deliveryArea;
// 有些合同可能没有设置交车区域,因此无需做按钮权限校验
if (!regionCode) {
console.log(`该合同未设置交车区域,无法获取区域运维负责人`);
return;
}
// this.$api.standbyVehicle.getOpManagerPhone({ regionCode }).then((res) => {
// //2025.3.18修改,去掉控制
// // 如果当前区域运维负责人不是当前小程序用户 则禁用备车完成按钮
// // if (res != this.userInfo.phone) {
// // this.doneBtnDisabled = true;
// // } else {
// // this.doneBtnDisabled = false;
// // }
// console.log(res);
// });
},
submitApprovalConfirm() {
uni.showModal({
title: "提示",
content: "确认备车完成?",
success: (res) => {
if (res.confirm) {
this.submitApproval();
}
},
});
},
alert(msg) {
uni.showToast({
title: msg,
icon: "none",
duration: 1500,
});
},
// 备车完成
submitApproval() {
// 点击备车收再获取一下数据,确保页面即将要提交的的数据是最新的
if (this.checkoutIds.length === 0) {
uni.showToast({
title: "请先勾选车辆",
icon: "none",
});
return;
}
console.log(this.checkoutIds);
let flag = false;
for (let item of this.datas.detailList.filter((item) =>
this.checkoutIds.includes(item.id)
)) {
if (item.plateNumber && this.datas.approvalStatus === 4) {
if (
item.hasAdvertisement == null ||
item.hasTailboard == null ||
item.isHang == null ||
item.operationExpectedDeliveryDate == null ||
item.standbyDate == null
) {
console.log(item);
this.alert("请完整填写车牌为:" + item.plateNumber + "的车辆信息");
flag = true;
return false;
}
}
if (item.isHang == 1 && !item.hangPlateNumber) {
this.alert("请输入车牌为:" + item.plateNumber + "的挂车车牌号");
flag = true;
return false;
}
if (
item.operationExpectedDeliveryDate > item.appointedDate &&
!item.remark &&
this.datas.approvalStatus === 4
) {
this.alert(
"请输入车牌为:" +
item.plateNumber +
"的约定交车日期和运维预计交车日期不一致的备注"
);
flag = true;
return false;
}
}
if (flag) {
return;
}
this.datas.detailList
.filter((item) => this.checkoutIds.includes(item.id))
.map((item) => {
item.submitStatus = 1;
return item;
});
this.datas.submitApproval = true; // 标识让流程继续往下走
this.$api.standbyVehicle.edit(this.datas).then((res) => {
console.log(`编辑接口返回:\n`, res);
if (res == this.datas.id) {
uni.showToast({
title: "备车成功",
icon: "success",
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack();
}, 1500);
},
});
}
});
// this.$api.standbyVehicle.getById({ id: this.id }).then((res) => {
// if (res.code == 200) {
// this.datas = res.data;
// }
// });
},
getModelName(model) {
if (this.truckType.length == 0) {
return "";
}
return this.truckType.find((x) => x.dicCode == model)?.dicName ?? "";
},
},
onLoad(options) {
if (options.id) {
this.id = options.id;
}
if (options.isRead) {
this.isRead = Number(options.isRead);
}
this.userInfo = getUser() || {};
console.log(`userInfo:\n`, this.userInfo);
this.getVehicleBrand();
this.getTruckType();
// this.getData();
this.cacheRequestTimer = setInterval(() => {
this.getCache({ keys: this.cacheKeys });
}, 5000);
},
onPullDownRefresh() {
this.getData();
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onShow() {
this.getData();
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
this.cacheRequestTimer = setInterval(() => {
this.getCache({ keys: this.cacheKeys });
}, 5000);
}
},
onHide() {
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
}
},
destroyed() {
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
}
},
};
</script>
<style lang="less" scoped>
.container {
background-color: #d7d7d7;
padding: 30rpx;
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
}
}
.carList {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.carItem {
width: calc(100%);
background-color: white;
// height: 200rpx;
margin: 25rpx 0;
border-radius: 10rpx;
padding: 10rpx;
display: flex;
flex-wrap: wrap;
position: relative;
justify-content: space-between;
.innerItem {
width: 220rpx;
margin-bottom: 10rpx;
.title {
text-align: center;
margin-bottom: 10rpx;
font-size: 26rpx;
}
}
.detailBtn {
height: 60rpx;
width: 200rpx;
background-color: #1e98d7;
color: white;
border-radius: 10rpx;
text-align: center;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
margin: 0;
margin-top: 50rpx;
&.disabled {
background-color: #eee;
color: #ccc;
}
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 20rpx;
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;
}
.done {
background-color: #7ba746;
color: white;
}
.disabled {
opacity: 0.6;
}
}
}
/deep/ .u-textarea textarea {
font-size: 26rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入客户名称"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line">
<view class="text-normal">合同编号: {{ item.contractNo }}</view>
</view>
<view class="line">
<view class="text-normal">客户名称: {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small"
>合同约定数量: {{ item.contractVehicleQuantity }}</view
>
</view>
<view class="line">
<view class="text-small"
>待备车数量: {{ item.standbyVehicleQuantity }}</view
>
</view>
<view class="line">
<view class="text-small left"
>合同签订时间: {{ formatDateTime(item.signingDate) }}</view
>
<view class="text-small"
>约定交车时间: {{ formatDateTime(item.appointedDate) }}</view
>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 -->
<button
v-if="
submitButton &&
item.approvalStatus != 6 &&
item.standbyVehicleQuantity &&
item.standbyVehicleQuantity > 0
"
@tap="goto"
:data-url="`/pages/standbyVehicle/detail?id=${item.id}`"
>
备车办理
</button>
<button
@tap="goto"
:data-url="`/pages/standbyVehicle/detail?isRead=1&id=${item.id}`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待处理", "全部"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
approvalStatuss: [4], // 审批状态, 4表示待运维备车
filterCompleted: true, //增加参数 filterCompleted=true 过滤备车完成的记录
customerName: "", //客户名称
},
dataList: [],
// testRecord: {
// contractNo: "LNZLHTJX2023051201",
// customerName: "中外运物流华东有限公司",
// contractVehicleQuantity: 10,
// standbyVehicleQuantity: 10,
// signingDate: 1728489600000,
// appointedDate: 1728489600000,
// },
pageNo: 1,
noMoreData: false,
loading: false,
pageCode: "standbyVehicle",
keyword: "",
};
},
computed: {
submitButton: function () {
return checkButtonPermission("standbyVehicleSubmit", this.pageCode);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.customerName = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.keyword = ""; // 清空搜索关键字
this.queryPage.customerName = undefined; // 清空搜索关键字
this.current = index;
if (index == 1) {
// 待业务编辑 1
// 待审批 2
// 审批中 3
// 待运维备车 4
// 备车完成 5
// 已撤销 6
// 部分待业务编辑 7
// 终止 8
// 已全部交车 9
// 全部 (待运维备车 + 备车已完成)
this.queryPage.approvalStatuss = [4, 5, 1];
this.queryPage.filterCompleted = false; //增加参数 filterCompleted=true 过滤备车完成的记录
} else {
// 仅显示待运维备车
this.queryPage.approvalStatuss = [4, 1];
this.queryPage.filterCompleted = true; //增加参数 filterCompleted=true 过滤备车完成的记录
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
submitEvent() {
this.current = 1;
//提交后删除缓存
stora.remove("fault_fromData");
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
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)
);
},
loadmore() {
this.loading = true;
this.$api.standbyVehicle
.queryPageList(this.queryPage)
.then((res) => {
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {
// this.loadmore();
},
onShow() {
this.sectionChange(this.current);
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>