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

1052
pages/audit/detail.vue Normal file

File diff suppressed because it is too large Load Diff

290
pages/audit/index.vue Normal file
View File

@@ -0,0 +1,290 @@
<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" v-if="current == 0 || item.approvalName"
>@{{ item.approvalName }}请处理待处理审批单:
</view>
</view>
<view class="block">
<view class="line">
<view class="text-small">
{{ item.createName }}提交的{{ item.contractTypeName }}申请</view
>
</view>
<view class="line">
<view class="text-small"> {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small">等待</view>
<view class="text-small hot">{{ item.waitTime || "--" }}</view>
<view class="text-small">小时</view>
</view>
</view>
<view class="line" style="justify-content: flex-end">
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="current == 0"
:data-url="`/pages/audit/detail?id=${item.id}`"
>
处理
</button>
<button
v-else
@tap="goto"
:data-url="`/pages/audit/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="line">
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>合同提交时间: {{ formatDateTime(item.createTime) }}</view
>
</view>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></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";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
keyword: "",
current: 0,
list: ["待审批", "审批通过"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
// contractStatus: "2", // 交车许可 1表示 准许交车
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.customerName = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.queryPage.customerName = "";
this.keyword = "";
this.current = index;
// if (index == 1) {
// // 全部 (准许交车 + 已交车)
// this.queryPage.contractStatus = "3";
// } else {
// // 仅显示准许交车
// this.queryPage.contractStatus = "2";
// }
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
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;
if (this.current == 0) {
this.$api.audit
.queryAuditList(this.queryPage)
.then((res) => {
console.log(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;
});
} else {
this.$api.audit
.queryAuditedList(this.queryPage)
.then((res) => {
console.log(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() {},
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("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.block {
display: flex;
line-height: 1.5;
padding: 10px;
flex-direction: column;
align-items: left;
margin-bottom: 15rpx;
border: 1px solid #ccc;
}
.hot {
color: red;
}
.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 {
button {
width: 130rpx;
display: inline-block;
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>

87
pages/face/index.vue Normal file
View File

@@ -0,0 +1,87 @@
<template>
<view class="container">
<!-- 唤起上链公证签刷脸小程序提示文本 -->
<view class="btn-content">
<text>中间页唤起上链公证签刷脸小程序</text>
<!-- 点击按钮跳转刷脸小程序 -->
<button type="default" @click="goFaceAuth()">若未自动唤起手动点击跳转刷脸小程序</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bizToken: "", // 公证签业务 token
redirectUrl: "", // 重定向地址
goFaceDone: "" // 是否已自动跳转至公证签做人脸
};
},
onLoad: function(option) {
// 设置 bizToken 和 redirectUrl
this.bizToken = option.bizToken;
this.redirectUrl = option.redirectUrl;
this.goFaceDone=false
console.log('onLoad----this.goFaceDone',this.goFaceDone)
},
onShow: function(option) {
console.log('this.goFaceDone',this.goFaceDone)
// 自动请求跳转刷脸小程序
if (!this.goFaceDone) {
this.goFaceAuth()
return
}
// 从公证签小程序返回判断刷脸结果
const options = uni.getEnterOptionsSync();
console.log('---options', options);
if (
options.scene === 1038 &&
options.referrerInfo.extraData &&
options.referrerInfo.extraData.faceResult
) {
// 刷脸成功跳转签署页面,并携带重定向地址
uni.redirectTo({
url: `/pages/webview/index?url=${this.redirectUrl}&type=face`,
success: () => {},
fail: (err) => {
console.log('Failed to navigate back:', err);
},
});
}
},
methods: {
// 跳转刷脸小程序方法
goFaceAuth() {
this.goFaceDone = true;
uni.navigateToMiniProgram({
appId: 'wx1cf2708c2de46337',
path: 'pages/face/index?bizToken=' + this.bizToken,
success: (res) => {
// 打开成功
console.log('跳转成功,this.goFaceDone', this.goFaceDone);
},
fail(res) {
// 打开失败
console.log(res);
},
});
},
}
};
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh; /* 可以根据实际需求设置容器高度 */
}
.btn-content {
text-align: center;
}
</style>

673
pages/index/index.vue Normal file
View File

@@ -0,0 +1,673 @@
<template>
<view class="content showMap">
<u-toast ref="uToast"></u-toast>
<h5>业务菜单{{ _isOnline ? "" : "(当前接口为测试环境)" }}</h5>
<view class="menuList">
<view
class="menuItem"
@tap="goto('/pages/standbyVehicle/index')"
v-if="!isSafe && !isEnergyRole && beicheBtn"
>
<view class="menuContent"
><view class="text">备车</view>
<image
src="/static/beiche.png"
style="width: 95rpx; height: 56rpx"
></image>
<u-badge
v-if="todo.standByCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.standByCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge
></view>
</view>
<view
class="menuItem"
v-if="!isEnergyRole && jiaocheBtn"
@tap="goto('/pages/truckRent/index')"
>
<view class="menuContent">
<view class="text">交车</view>
<image
src="/static/jiaoche.png"
style="width: 89rpx; height: 57rpx"
></image>
<u-badge
v-if="todo.handoverCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.handoverCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
@tap="goto('/pages/returnCar/index')"
v-if="!isSafe && returnCarBtn"
>
<view class="menuContent">
<view class="text">还车</view>
<image
src="/static/huanche.png"
style="width: 89rpx; height: 57rpx"
></image>
<u-badge
v-if="todo.returnCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.returnCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
@tap="goto('/pageSub/failure/index')"
v-if="
!isSafe &&
!isBussinessRole &&
!isFinanceRole &&
!isEnergyRole &&
guzhangBtn
"
>
<view class="menuContent">
<view class="text">故障台账</view>
<image
style="width: 80rpx; height: 50rpx"
src="/static/fault.png"
></image>
<u-badge
v-if="todo.failureNumber != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.failureNumber"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
v-if="!isSafe && !isEnergyRole && auditBtn"
@tap="goto('/pages/audit/index')"
>
<view class="menuContent">
<view class="text">审批</view>
<image
style="width: 57rpx; height: 55rpx"
src="/static/audit.png"
></image>
<u-badge
v-if="todo.contractWaitApproval != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.contractWaitApproval"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<!-- v-if="!isSafe && !isBussinessRole && !isFinanceRole && !isEnergyRole" v-if="transactionManagement"-->
<view
class="menuItem"
v-if="transactionManagement"
@tap="goto('/pages/unusualActionApply/index')"
>
<view class="menuContent">
<view class="text">异动管理</view>
<image
style="width: 48rpx; height: 55rpx"
src="/static/yidong.png"
></image>
<u-badge
v-if="todo.transaction"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.transaction"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<!-- v-if="!isSafe && !isBussinessRole && !isFinanceRole && !isEnergyRole" -->
<view
class="menuItem"
v-if="annualVerificationNew"
@tap="goto('/pageSub/annualReview/index')"
>
<view class="menuContent">
<view class="text">年审待办</view>
<image
style="width: 54rpx; height: 54rpx"
src="/static/nianshen.png"
></image>
<!-- <u-badge
v-if="todo.vehicleAnnualInspection != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.vehicleAnnualInspection"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge> -->
</view>
</view>
<!-- v-if="truckPreparation" -->
<view
v-if="truckPreparation"
class="menuItem"
@tap="goto('/pageSub/truckPreparation/index')"
>
<view class="menuContent">
<view class="text">车辆整备</view>
<image
src="/static/zhengbei.png"
style="width: 95rpx; height: 56rpx"
></image>
</view>
</view>
<view
v-if="maintainTodo"
class="menuItem"
@tap="goto('/pages/maintain/index')"
>
<view class="menuContent">
<view class="text">保养待办</view>
<image
src="/static/baoyang.png"
style="width: 60rpx; height: 56rpx"
></image>
</view>
</view>
<view
v-if="returnCarCost"
class="menuItem"
@tap="goto('/pageSub/returnCarCost/index')"
>
<view class="menuContent">
<view class="text">费用核算</view>
<image
src="/static/cost.png"
style="width: 95rpx; height: 56rpx"
></image>
<u-badge
v-if="todo.returnCost != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.returnCost"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
</view>
<h5>BI报表</h5>
<view class="menuList">
<view class="menuItem" @tap="gotoBi('car')" v-if="carBiPage">
<view class="menuContent"
><view class="text">车辆统计</view>
<image
src="/static/bi.png"
style="width: 60rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('h2')" v-if="h2BiPage">
<view class="menuContent"
><view class="text">氢费统计</view>
<image
src="/static/hydrogen.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('daily')" v-if="dailyBiPage">
<view class="menuContent"
><view class="text">每日氢量表</view>
<image
src="/static/jiaqingzhan.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('electric')" v-if="electricBiPage">
<view class="menuContent"
><view class="text">每日电费表</view>
<image
src="/static/chongdianzhan_white.png"
style="width: 48rpx; height: 48rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('mileage')" v-if="weappMileageBi">
<view class="menuContent"
><view class="text">里程查询</view>
<image
src="/static/kachetou.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
</view>
<!-- <u-collapse :value="['basic', 'bi']" :border="false">
<u-collapse-item
title="业务菜单"
ref="basicCollapse"
name="basic"
v-if="isShowCollapse"
>
</u-collapse-item>
<u-collapse-item title="BI报表" name="bi" v-if="biPage">
</u-collapse-item>
</u-collapse> -->
<tab-bar></tab-bar>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { checkPagePermission } from "@/utils/permission.js";
import { baseUrl } from "@/utils/request.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
userInfo: {}, // 用户信息
loading: false,
home: {
training: 0,
examination: 0,
},
todo: {
standByCar: 0,
},
isShowCollapse: false,
};
},
computed: {
_isOnline() {
return baseUrl === "https://lnh2e.com/api/";
},
_userInfo() {
console.log("---------------------");
console.log(getUser());
return getUser() || {};
},
beicheBtn() {
return checkPagePermission("standbyVehicle");
},
biPage() {
return checkPagePermission("FineBI");
},
carBiPage() {
return checkPagePermission("truckOptBI");
},
h2BiPage() {
return checkPagePermission("hydrogenBill");
},
dailyBiPage() {
return checkPagePermission("dailyHydrogenOrderBI");
},
electricBiPage() {
return checkPagePermission("bi_ele_daily_summary");
},
weappMileageBi() {
return checkPagePermission("weappMileageBi");
},
//utils\permission.js记得改 不然没有外链接
jiaocheBtn() {
return checkPagePermission("applicationForDelivery");
},
returnCarBtn() {
return checkPagePermission("carapplicationForDelivery");
},
auditBtn() {
return checkPagePermission("contract");
},
guzhangBtn() {
return checkPagePermission("faultManagement");
},
returnCarCost() {
return checkPagePermission("returnCarCost");
},
maintainTodo() {
return checkPagePermission("maintain");
},
truckPreparation() {
return checkPagePermission("truckPreparation");
},
//年审待办
annualVerificationNew() {
return checkPagePermission("annualVerificationNew");
},
transactionManagement() {
return checkPagePermission("transactionManagement");
},
// isOutServiceRole() {
// const ids = this.userInfo?.roles?.map((item) => item.id) || [];
// if (ids.includes("202306091251370002")) {
// console.log("运维外勤");
// return true; //运维外勤
// } else {
// return false; //其他
// }
// },
currRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("1076403008717209600")) {
return 2; //安全经理
} else if (ids.includes("1012435145369616384")) {
return 1; //安全员
} else {
return 0; //其他
}
},
isSafe() {
return [1, 2].includes(this.currRole);
},
isEnergyRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0502") {
console.log("能源部");
return true; //
} else {
return false; //其他
}
},
isFinanceRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "02") {
console.log("财务部");
return true; //财务部
} else {
return false; //其他
}
},
isBussinessRole() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
},
},
onShow() {
// 这样数据是不会刷新的
this.userInfo = getUser() || {};
console.log(this.$store.state.resources);
this.getTodo();
if (this.$store.state?.resources?.length === 0) this.getUserMenu();
console.log(this.userInfo);
},
onPullDownRefresh(event) {
if (this.$store.state?.resources?.length === 0) this.getUserMenu();
this.getTodo()
.then((res) => {
uni.stopPullDownRefresh();
})
.catch((err) => {
uni.stopPullDownRefresh();
});
},
mounted() {
// this.$api.login
// .getUrl()
// .then((res) => {
// console.log("12312312312333#########################");
// console.log(res);
// })
// .catch((err) => {
// console.log("12312312312333#########################");
// console.log(err);
// });
this.$store.state.current = "index";
if (this._userInfo.id == "1131365259079106560") {
setTimeout(() => {
this.$store.state.current = "map";
uni.switchTab({
url: "/pages/map/index",
});
}, 500);
} else {
this.isShowCollapse = false;
setTimeout(() => {
this.isShowCollapse = true;
}, 100);
}
},
methods: {
async getUserMenu() {
await this.$api.login
.getUserMenu()
.then((res) => {
console.log(res);
this.$store.dispatch("setResources", res);
})
.catch((err) => {
console.log("error");
});
},
async getTodo() {
this.$api.standbyVehicle.getTodo().then((res) => {
this.todo.standByCar = res.standByCar;
this.todo.handoverCar = res.handoverCar;
this.todo.returnCar = res.returnCar;
this.todo.failureNumber = res.failureNumber;
this.todo.contractWaitApproval = res.contractWaitApproval;
this.todo.transaction = res.transaction || 0;
//this.todo.vehicleAnnualInspection = res.vehicleAnnualInspection || 0;
console.log(`this.home.standByCar:\n`, this.home.standByCar);
});
this.$api.returnCost.getCostToDo().then((res) => {
console.log(res.data);
this.todo.returnCost = res.data;
});
},
showToast(type, message) {
this.$refs.uToast.show({
type,
icon: false,
message,
});
},
goto(url) {
// uni.navigateTo({ url: e.target.dataset.url });可以用dataset取data-url <!-- data-url="/pages/annualReview/index"
uni.navigateTo({ url: url });
},
gotoBi(type) {
//carBiPage, h2BiPage,dailyBiPage 都是用的系统菜单配置的外链接
switch (type) {
case "car":
uni.navigateTo({
//https://wxaurl.cn/YIKi8duNbCh 根据地图路劲生成的url link
url: `/pages/webview/index?url=` + this.carBiPage,
});
break;
case "h2":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.h2BiPage,
});
break;
case "mileage":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.weappMileageBi,
});
break;
case "electric":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.electricBiPage,
});
break;
default:
uni.navigateTo({
url: `/pages/webview/index?url=` + this.dailyBiPage,
});
break;
}
},
},
};
</script>
<style lang="less" scoped>
.banner {
height: 30vh;
width: 100%;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.login-btn {
margin: 30rpx 0rpx;
}
.wexin-but::after {
border: unset !important;
}
.wexin-but {
border: unset !important;
border-radius: unset;
box-sizing: unset;
background-color: transparent;
padding-left: 0px;
padding-right: 0px;
}
/deep/.u-cell__body {
padding: 10px 15px !important;
}
// 或者直接覆盖 u-collapse-item 的样式
/deep/ .u-cell--clickable {
background-color: #e1eae5 !important;
}
/deep/ .u-cell__title-text {
font-size: unset !important;
line-height: unset !important;
color: unset !important;
}
/deep/ .u-cell__body {
font-size: unset !important;
color: unset !important;
}
/deep/ .u-cell__right-icon-wrap text {
font-size: 32rpx !important;
}
.content {
background: #e1eae5;
height: calc(100vh - 50px);
// h3 {
// font-weight: normal;
// text-align: center;
// border-bottom: 1rpx solid silver;
// padding: 20rpx 0;
// }
h5 {
padding: 10px;
}
.menuList {
display: flex;
flex-wrap: wrap;
// .menuItem:last-child {
// margin-right: auto;
// }
.menuItem {
padding: 18rpx;
flex: 0 0 33.3%;
box-sizing: border-box;
// margin-right: 56.6rpx;
// &:nth-of-type(4) {
// margin-right: 0;
// }
.menuContent {
position: relative;
text-align: right;
padding: 18rpx;
background-image: url(../../static/g_bg.png);
background-size: 100% 100%;
image {
width: 75rpx;
height: 75rpx;
margin-top: 10rpx;
}
.text {
// width: 125rpx;
text-align: left;
font-size: 32rpx;
color: #fff;
font-weight: bold;
}
/deep/.u-badge {
font-size: 30rpx;
}
/deep/.u-badge--not-dot {
padding: 15rpx 18rpx;
}
}
}
}
}
.showMap.content {
height: calc(100vh - 65px);
/deep/ .u-tabbar-item {
padding-bottom: 19px;
}
}
</style>

187
pages/login/login.vue Normal file
View File

@@ -0,0 +1,187 @@
<template>
<view class="content">
<u-loading-page bg-color="#a7a7a7" :loading="loading"></u-loading-page>
<!-- <view class="bt1 door" @tap="showBtn = true"></view>
<view class="bt2 door" v-if="showBtn" @tap="showUser = true"></view> -->
<image class="logo" src="/static/logo.png"></image>
<view class="helloTip"> Hello! </view>
<view class="helloText"> 欢迎使用广交投氢能车辆运营监控 </view>
<view class="remarkText"> 此小程序仅限氢能车辆运营方内部人员使用 </view>
<view style="width: 80%; margin-top: 80rpx">
<!-- <u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
:fontSize="30"
style="margin-bottom: 20rpx"
></u-subsection> -->
<!-- <view v-if="current == 0">
<login-user></login-user>
</view>
-->
</view>
<view class="loginBlock">
<view class="helloText"> </view>
<view>
<login-user></login-user>
</view>
</view>
</view>
</template>
<script>
import loginUser from "./user-login/index.vue";
// import loginDriver from "./driver-login/index.vue";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
components: {
loginUser,
// loginDriver,
},
data() {
return {
loading: false,
current: 0,
list: ["广交投员工", "司机"],
showUser: false,
showBtn: false,
};
},
onReady() {
// this.getToDo();
const tempIds = ["7NTdeu2Sft31k4wtCGVEjvfvvG3MDxAtUW3g17vv48E"];
wx.getSetting({
withSubscriptions: true,
success(res) {
// console.log(res.authSetting);
// console.log(res.subscriptionsSetting);
if (res.subscriptionsSetting[tempIds[0]] !== "accept") {
uni.showModal({
title: "授权提示",
content: "同意订阅通知消息吗?",
success: (res) => {
console.log(res);
if (res.confirm) {
uni.requestSubscribeMessage({
tmplIds: tempIds, // 需要下发的订阅消息模板id数组
success(res) {
console.log(res);
if (res[tempIds[0]] === "accept") {
console.log("用户同意订阅");
}
},
});
}
},
});
}
// res.subscriptionsSetting = {
// mainSwitch: true, // 订阅消息总开关
// itemSettings: { // 每一项开关
// SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息
// SYS_MSG_TYPE_RANK: 'accept'
// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息
// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
// }
// }
},
});
},
methods: {
sectionChange(index) {
this.current = index;
},
},
};
</script>
<style lang="less" scoped>
.content {
display: flex;
flex-direction: column;
height: 100vh;
padding: 40rpx;
background: linear-gradient(0deg, #b6e2fb, #2890e5);
justify-content: center;
position: relative;
font-family: MiSans-Semibold, MiSans-Demibold, "Segoe UI", Tahoma, Geneva,
Verdana, sans-serif;
}
.helloTip {
font-size: 100rpx;
color: #fff;
font-weight: bold;
margin-top: -200rpx;
}
.helloText {
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 46rpx;
color: #fff;
font-weight: 400;
}
.remarkText {
margin-top: 10rpx;
margin-bottom: 20rpx;
font-size: 36rpx;
color: #b54b45;
font-weight: 400;
}
.loginBlock {
display: flex;
flex-direction: column;
justify-content: center;
width: 685rpx;
height: 664rpx;
padding: 0 30rpx;
box-sizing: border-box;
// background-image: url("../../static/login_bg.png");
background-size: cover;
background-color: #fff;
// background: #ffffff;
border-radius: 20rpx;
.helloText {
color: #017043;
text-align: center;
font-weight: bold;
}
}
.logo {
position: absolute;
height: 76rpx;
/* width: 568rpx ; */
top: 40rpx;
right: 40rpx;
// margin-left: auto;
// margin-right: auto;
// margin-bottom: 50rpx;
}
// .door {
// width: 20px;
// height: 20px;
// background: green;
// }
// .bt1 {
// position: absolute;
// top: 10px;
// left: 10px;
// opacity: 0;
// }
// .bt2 {
// position: absolute;
// bottom: 10px;
// left: 10px;
// opacity: 0;
// }
.title {
font-size: 36rpx;
color: #8f8f94;
}
.login-btn {
margin: 30rpx 0rpx;
}
</style>

View File

@@ -0,0 +1,372 @@
<template>
<view>
<u--form
labelPosition="left"
:model="formData"
ref="uForm"
labelWidth="100"
:rules="rules"
class="loginForm"
>
<u-form-item prop="loginName">
<u--input
border="surround"
placeholder="账号"
shape="circle"
v-model="formData.loginName"
fontSize="30"
></u--input>
</u-form-item>
<u-form-item prop="pwd">
<u--input
border="surround"
placeholder="密码"
type="password"
shape="circle"
v-model="formData.pwd"
fontSize="30"
></u--input>
</u-form-item>
<view>
<checkbox-group @change="changeCheck">
<checkbox class="checkbox">
<view slot="label">
<view class="label">
阅读并同意
<view class="text_link" @tap="privatyShow = true"
>用户服务协议隐私政策</view
>
</view>
</view>
</checkbox>
</checkbox-group>
</view>
<!-- <view v-if="showAgreement" class="index-privaty">
<van-checkbox checked-color="#4A47E0" value="{{ hasAgreement }}" bind:change="onCheckboxChanged"/>
</view> -->
<view class="login-btn">
<button
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
class="u-button u-reset-button u-button--success u-button--square u-button--normal wexin-but"
>
授权登录
</button>
<u-button
@click="submit"
plain
color="#017043"
:hairline="false"
:loading="loading"
:disabled="loading"
>{{ `登 录` }}</u-button
>
</view>
</u--form>
<u-popup :show="privatyShow" mode="bottom" @close="privatyShow = false">
<scroll-view scroll-y="true" style="height: 95vh">
<view class="content">
<text style="text-align: center">隐私协议</text>
<view>
<text>概述</text>
<text
>本小程序是由羚牛氢能科技上海有限公司开发运营的一款产品以下简称我们帮助解决用户开通搭建小程序公众号网站方面遇到的问题可以达到快速上线的目的我们深知个人信息对您而言的重要性也感谢您对我们的信任我们将通过本政策向您说明互助文档会如何收集存储保护使用及对外提供您的信息并说明您享有的权利其中要点如下</text
>
<view>
<text
>1.
为了便于您了解您在使用我们的服务时我们需要收集的信息类型与用途我们将结合具体服务向您逐一说明</text
>
</view>
<view>
<text
>2.
为了向您提供服务所需我们会按照合法正当必要的原则收集您的信息</text
>
</view>
<view>
<text
>3.
如果为了向您提供服务而需要将您的信息共享至第三方我们将评估该第三方收集信息的合法性正当性必要性我们将要求第三方对您的信息采取保护措施并严格遵守相关法律法规与监管要求另外我们会按照法律法规及国家标准的要求以确认协议具体场景下的文案确认弹窗提示等形式征得您的同意或确认第三方已经征得您的同意</text
>
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>我们如何收集信息</text>
<text
>在您使用互助文档以下各项业务功能以下简称服务的过程中我们需要收集您的一些信息用以向您提供服务提升我们的服务质量保障您的账户和资金安全以及符合国家法律法规及监管规定</text
>
<view>
<text
>1.
依据法律法规及监管规定进行实名制管理在您注册互助文档账户或使用互助文档服务时您需提供手机号码或者第三方账号登陆信息作为账户登录名</text
>
</view>
<view>
<text>2. 身份验证</text>
<view>
<text>1登录验证</text>
<text
>为了让您更安全便捷地登录互助文档我们提供自动登陆服务您也可以选择密码登录短信验证码登录等其他方式</text
>
</view>
<view>
<text>2重要操作行为验证</text>
<text
>为了保障您的账户安全在您进行一些重要的账户操作时例如查看收藏下载应用内资料内容时我们需要验证您的身份为此您可能需向第三方安全服务提供商提交身份验证信息如您不同意提供前述信息您将无法完成特定操作但不影响您使用我们提供的其他服务</text
>
</view>
<!-- 省略其他子条款内容以类似方式嵌入 -->
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>3. 获取外部存储权限获取设备ID, MAC地址</text>
<text
>获取外部存储权限用于记录登录同意的信息下次登录不用重新选择获取设备IDMAC地址设备ID用于记录用户的唯一性MAC地址获取是用于确定用户是属于真实用户</text
>
<text
>本程序嵌入了百度插移动统计分析sdk百度移动SDK隐私政策说明具体隐私政策准则按百度移动SDK隐私为准</text
>
</view>
<view>
<text>4. 其他</text>
<text
>请您理解我们向您提供的服务是不断更新和发展的如您选择使用了前述说明当中尚未涵盖的其他服务基于该服务我们需要收集您的信息的我们会通过页面提示交互流程协议约定的方式另行向您说明信息收集的范围与目的并征得您的同意我们会按照本政策以及相应的用户协议约定使用存储对外提供及保护您的信息如您选择不提供前述信息您可能无法使用某项或某部分服务但不影响您使用我们提供的其他服务此外第三方主体可能会通过互助文档APP向您提供服务当您进入第三方主体运营的服务页面时请注意相关服务由第三方主体向您提供涉及到第三方主体向您收集个人信息的建议您仔细查看第三方主体的隐私政策或协议约定</text
>
</view>
</view>
<view>
<text>我们如何存储和保护信息</text>
<view>
<text
>1.
我们在中华人民共和国境内收集和产生的个人信息将存储在中华人民共和国境内如部分服务涉及跨境业务我们需要向境外机构传输境内收集的相关个人信息的我们会按照法律法规和相关监管部门的规定执行向您说明个人信息出境的目的以及涉及的个人信息类型征得您的同意并通过签订协议现场核查等有效措施要求境外机构为所获得的您的个人信息保密我们仅在本政策所述目的所必需期间和法律法规及监管规定的时限内保存您的个人信息</text
>
</view>
<view>
<text
>2.
为了保障您的信息安全我们在收集您的信息后将采取各种合理必要的措施保护您的信息例如在技术开发环境当中我们仅使用经过去标识化处理的信息进行统计分析对外提供研究报告时我们将对报告中所包含的信息进行去标识化处理我们会将去标识化后的信息与可用于恢复识别个人的信息分开存储确保在针对去标识化信息的后续处理中不重新识别个人</text
>
</view>
<view>
<text
>3.
我们承诺我们将使信息安全保护达到业界领先的安全水平为保障您的信息安全我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露毁损误用非授权访问非授权披露和更改的风险例如通过网络安全层软件SSL进行加密传输信息加密存储严格限制数据中心的访问传输和存储个人敏感信息时我们将采用加密权限控制去标识化等安全措施</text
>
</view>
<view>
<text
>4.
请您务必妥善保管好您的互助文档登录名及其他身份要素您在使用互助文档服务时我们会通过您的登录名及其他身份要素来识别您的身份一旦您泄漏了前述信息您可能会蒙受损失并可能对您产生不利如您发现互助文档登录名及/或其他身份要素可能或已经泄露时请您立即和我们取得联系以便我们及时采取相应措施以避免或降低相关损失</text
>
</view>
<view>
<text
>5.
在您终止使用互助文档服务后我们会停止对您的信息的收集和使用法律法规或监管部门另有规定的除外如我们停止运营我们将及时停止收集您个人信息的活动将停止运营的通知以逐一送达或公告的形式通知您并对所持有的您的个人信息进行删除或匿名化处理</text
>
</view>
</view>
</view>
</view>
</scroll-view>
</u-popup>
</view>
</template>
<script>
import { setToken, setUser } from "@/utils/auth.js";
import en from "@/utils/key.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
loading: false,
privatyShow: false,
showAgreement: false,
formData: {
loginName: "",
pwd: "",
},
rules: {
loginName: [
{
required: true,
message: "请输入账号",
trigger: ["blur", "change"],
},
],
pwd: [
{
required: true,
message: "请输入密码",
trigger: ["blur", "change"],
},
],
},
};
},
methods: {
changeCheck(e) {
if (e.detail.value.length > 0) {
this.showAgreement = true;
} else {
this.showAgreement = false;
}
},
getPhoneNumber(data) {
// 获取手机号
//debugger;
if (!this.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
duration: 1500,
});
return;
}
const _this = this;
if (!data.detail.errno) {
this.loading = true;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginByPhoneForDriver({
phoneCode: data.detail.code,
sessionCode: resp.code,
})
.then((res) => {
const result = res;
_this.loading = false;
setToken(result.token);
_this.getUserMenu();
setUser(result.userInfo);
uni.switchTab({
url: "/pages/index/index",
});
})
.catch((errors) => {
_this.loading = false;
});
},
});
}
},
async getUserMenu() {
await this.$api.login
.getUserMenu()
.then((res) => {
console.log(res);
this.$store.dispatch("setResources", res);
})
.catch((err) => {
console.log("error");
});
},
submit() {
if (!this.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
duration: 1500,
});
return;
}
this.$refs.uForm.validate().then(() => {
const nPwd = en.encrypt(this.formData.pwd);
this.loading = true;
const _this = this;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginUser({
loginName: _this.formData.loginName,
pwd: nPwd,
})
.then((res) => {
const result = res;
_this.loading = false;
setToken(result.token);
setUser(result.userInfo);
_this.getUserMenu();
setTimeout(() => {
uni.switchTab({
url: "/pages/index/index",
});
}, 500);
})
.catch((errors) => {
_this.loading = false;
});
},
});
});
},
},
onReady() {
try {
//如果需要兼容微信小程序并且校验规则中含有方法等只能通过setRules方法设置规则。
this.$refs.uForm.setRules(this.rules);
} catch (e) {}
},
};
</script>
<style lang="less" scoped>
/deep/ .u-input--circle {
background-color: #f5f6fa !important;
padding-left: 20px !important;
}
/deep/ .u-button {
border: none !important;
color: #017043;
margin-top: 10rpx;
width: auto;
}
.content {
padding: 10px;
}
.checkbox {
display: flex;
font-size: 28rpx;
.label {
display: flex;
padding-top: 5rpx;
flex-wrap: wrap;
}
.text_link {
color: #4a47e0;
}
}
/deep/ .wx-checkbox-input {
width: 36rpx !important;
height: 36rpx !important;
}
.login-btn {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
padding: 0 80rpx;
.wexin-but {
// width: 80%;
margin-top: 40rpx;
padding: 0rpx 122rpx;
border-radius: 50rpx;
box-sizing: border-box;
background-color: #017043;
color: white;
font-size: 38rpx;
}
}
</style>

2060
pages/maintain/detail.vue Normal file

File diff suppressed because it is too large Load Diff

309
pages/maintain/index.vue Normal file
View File

@@ -0,0 +1,309 @@
<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" v-if="item.maintenanceStatus === 0">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">未保养</view>
</view>
<view class="line" v-else-if="item.maintenanceStatus == 1">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">已保养</view>
</view>
<!-- <u-badge
:isDot="true"
type="warning"
v-if="item.preparationStatus === 0"
></u-badge>
<u-badge
:isDot="true"
type="error"
v-if="item.preparationStatus === 2"
></u-badge>
<u-badge
:isDot="true"
type="success"
v-if="item.preparationStatus === 1"
></u-badge> -->
<view class="line">
<view class="text-small"
>项目名称: {{ item.projectName || "--" }}</view
>
</view>
<view class="line">
<view class="text-small"
>资产状态: {{ item.truckRentStatusName }}</view
>
</view>
<view class="line" v-if="current === 1">
<view class="text-small"
>维修站: {{ item.maintainSiteName || "--" }}</view
>
</view>
<view class="line">
<view class="text-small">负责人: {{ item.handlerName || "--" }}</view>
</view>
<view
class="line"
v-if="current === 1"
style="justify-content: space-between"
>
<view class="text-small left"
>公司应支付: {{ item.companyPayable || 0 }}</view
>
<view class="text-small"
>公司已支付: {{ item.companyPayed || 0 }}</view
>
</view>
<view
class="line"
v-if="current === 1"
style="justify-content: space-between"
>
<view class="text-small left"
>客户应支付: {{ item.customerPayable || 0 }}</view
>
<view class="text-small"
>客户已支付: {{ item.customerPayed || 0 }}</view
>
</view>
<view class="line" style="justify-content: flex-end">
<view class="text-small right">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 v-if="[0, 2].includes(item.preparationStatus)" -->
<button
@tap="goto"
:data-url="`/pages/maintain/detail?id=${item.id}`"
>
编辑
</button>
<button
@tap="goto"
:data-url="`/pages/maintain/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["未保养", "已保养"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "",
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = ""; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
// 显示已整备
this.queryPage.maintenanceStatus = 1;
} else {
// 显示未整备
this.queryPage.maintenanceStatus = 0;
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
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.maintainTodo
.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() {},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !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>

1639
pages/map/index.vue Normal file

File diff suppressed because it is too large Load Diff

84
pages/my/my.vue Normal file
View File

@@ -0,0 +1,84 @@
<template>
<view class="content">
<view>
<u-cell-group>
<u-cell title="姓名/账号" :value="userInfo.userName"></u-cell>
<u-cell title="手机号" :value="userInfo.phone"></u-cell>
<u-cell title="身份证" :value="userInfo.idNo"></u-cell>
</u-cell-group>
<u-button
@click="logout"
type="primary"
:hairline="false"
:loading="loading"
:disabled="loading"
style="margin-top: 50rpx"
>退出登录</u-button
>
<u-modal
:show="loading"
@cancel="cancel"
:showCancelButton="true"
:asyncClose="true"
@confirm="confirm"
>
<view class="slot-content">
<text>退出账号</text>
</view>
</u-modal>
</view>
<tab-bar></tab-bar>
</view>
</template>
<script>
import { getUser, removeToken, removeUser } from "@/utils/auth.js";
export default {
data() {
return {
loading: false,
userInfo: {},
};
},
mounted() {
this.userInfo = getUser() || {};
},
methods: {
logout() {
this.loading = true;
},
cancel() {
this.loading = false;
},
confirm() {
this.$api.login
.logout()
.then((res) => {
removeToken();
removeUser();
uni.reLaunch({
url: "/pages/login/login",
});
this.$store.state.current = "index";
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
},
};
</script>
<style lang="less" scoped>
/deep/.u-cell__body {
padding: 10px 15px !important;
}
.content {
height: calc(100vh - 65px);
/deep/ .u-tabbar-item {
padding-bottom: 19px;
}
}
</style>

1917
pages/returnCar/cost.vue Normal file

File diff suppressed because it is too large Load Diff

3869
pages/returnCar/detail.vue Normal file

File diff suppressed because it is too large Load Diff

582
pages/returnCar/index.vue Normal file
View File

@@ -0,0 +1,582 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
v-if="!isEnergyRole"
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.projectName }}</view>
</view>
<view class="line">
<view class="text-small">客户名称: {{ item.customerName }}</view>
</view>
<!-- <view class="line">
<view class="text-small">交车区域: {{ item.deliveryAreaName }}</view>
</view> -->
<view class="line">
<view class="text-small"
>交车地点: {{ item.handoverAddressName }}</view
>
</view>
<view class="line">
<view class="text-small"
>还车地点: {{ item.returnLocationName }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>还车时间: {{ formatDateTime(item.returnDate) }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="
item.taskStatus == 0 &&
editButton &&
current == 0 &&
[null, 1].includes(item.vehicleArrival)
"
:data-url="`/pages/returnCar/detail?id=${item.id}`"
>
编辑
<!-- item.taskStatus == 0 && //未提交编辑
isServiceDep && //是运维
current === 0 && //菜单是待还车
item.vehicleArrival === 1 //已到达 -->
</button>
<button
v-if="
current === 0 && isOutServiceRole && item.vehicleArrival === 0
"
@tap="reachCar(item.id)"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
车辆到达
</button>
<button
v-if="
isOutServiceRole &&
item.returnLocationType === 2 &&
item.taskStatus === 1
"
@tap="parkingFunc(item.id)"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
停车场
</button>
<!-- <button
@tap="goto"
v-if="
!(
(isBussinessDep && current === 1) ||
(isServiceDep && current === 0) ||
(isFinanceDep && current === 1)
)
"
:data-url="`/pages/returnCar/cost?id=${item.id}`"
>
费用核算
</button>
<button
v-if="
current === 1 &&
isFinanceDep &&
item.returnCostApprovalStatus != 30
"
@tap="goto"
:data-url="`/pages/returnCar/cost?id=${item.id}`"
>
费用结算
</button> -->
<!-- :data-url="
isCostUser || (isServiceDep && current == 1)
? `/pages/returnCar/cost?id=${item.id}&isRead=1`
: `/pages/returnCar/detail?id=${item.id}&isRead=1`
" -->
<button
@tap="goto"
:data-url="`/pages/returnCar/detail?id=${item.id}&isRead=1`"
>
查看
</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>
<u-modal
:show="showParkingModal"
@confirm="confirmModal"
@cancel="cancelModal"
:showCancelButton="true"
buttonReverse
:asyncClose="true"
>
<view class="slot-content testClass">
<view class="item">
<view class="title">停车场确认</view>
<u-picker
:show="showParkingPicker"
:columns="[parkingList]"
keyName="dicName"
:immediateChange="true"
@confirm="confirmPark"
@cancel="showParkingPicker = false"
>
</u-picker>
<u--input
border="surround"
disabled
fontSize="26"
placeholder="请选择停车场"
:value="getParkingName(parking)"
@tap="showParkingPicker = true"
>
</u--input>
</view>
</view>
</u-modal>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待还车", "全部"],
currRowId: "",
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
taskStatus: "0", // 编辑完成 0 表示待编辑 1 表示编辑完成
// deliveryPermits: ['1'] // 交车许可 1表示 准许交车
},
dataList: [],
pageNo: 1,
userInfo: {},
noMoreData: false,
loading: false,
showParkingPicker: false,
showParkingModal: false,
parking: "",
parkingList: [],
keyword: "", //搜索关键字
pageCode: "carapplicationForDelivery", //页面编码
// banPlateNumber: [工单#7045017 工单 1023 标红车辆车辆车牌号恢复为黑色
// "粤AGP7018",
// "粤AGR6879",
// "粤AGR9815",
// "粤AGP9825",
// "粤AGP6639",
// "粤AGP5158",
// "粤AGP6651",
// "粤AGP9331",
// "粤AGP9786",
// "粤AGR9866",
// "粤AGR8500",
// "粤AGR9877",
// "粤AGR5547",
// "粤AGR8531",
// "粤AGQ0119",
// ],
};
},
computed: {
editButton: function () {
return checkButtonPermission(
"carapplicationForDeliveryEdit",
this.pageCode
);
},
isCostUser() {
return this.isEnergyRole || this.isBussinessDep || this.isFinanceDep;
},
isOutServiceRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("202306091251370002")) {
console.log("运维外勤");
return true; //运维外勤
} else {
return false; //其他
}
},
isServiceDep() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0601") {
console.log("运维部");
return true; //运维部
} else {
return false; //其他
}
},
isEnergyRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0502") {
console.log("能源部");
return true; //
} else {
return false; //其他
}
},
isFinanceDep() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "02") {
console.log("财务部");
return true; //财务部
} else {
return false; //其他
}
},
isBussinessDep() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
// const ids = this.userInfo?.roles?.map((item) => item.id) || [];
// if (ids.includes("1066262176854999040")) {
},
},
onLoad() {
this.userInfo = getUser() || {};
// this.$nextTick(() => {
// if (this.isBussinessDep) {
// this.list = ["费用核算", "已提交"];
// } else if (this.isFinanceDep) {
// this.list = ["费用核算", "费用结算"];
// }
// });
},
methods: {
async getParkList() {
await this.$api.returnCar
.getParkingPageList({
pageNo: 1,
pageSize: 999,
})
.then((res) => {
if (res) {
let datas = res?.data;
this.parkingList = datas.records.map((item) => {
return {
dicCode: item.id,
dicName: item.parkingName,
};
});
}
});
},
cancelModal() {
this.parking = "";
this.currRowId = "";
this.showParkingModal = false;
},
getDicValue(dic, dicCode) {
if (dic.length == 0) {
return "";
}
return dic.find((x) => x.dicCode == dicCode)?.dicName ?? "";
},
async parkingFunc(val) {
this.currRowId = val;
this.parking = "";
await this.getParkList();
this.showParkingModal = true;
},
confirmModal() {
if (!this.parking) {
uni.showToast({
title: "停车场不能为空",
icon: "none",
duration: 1500,
});
this.showParkingModal = false;
return;
}
const _this = this;
this.$api.returnCar
.updateParking({
id: this.currRowId,
returnLocation: this.parking,
returnLocationType: 1,
})
.then((res) => {
if (res) {
uni.showToast({
title: "操作成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
this.showParkingModal = false;
},
confirmPark(e) {
console.log(e);
this.parking = e.value[0].dicCode;
this.showParkingPicker = false;
},
getParkingName(dicCode) {
console.log(dicCode);
return this.getDicValue(this.parkingList, dicCode);
},
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
this.queryPage.vehicleArrival = "";
this.queryPage.taskStatus = "1";
if (this.isServiceDep) {
this.queryPage.vehicleArrival = "1"; // 已到车
}
// if (this.isBussinessDep || this.isFinanceDep) {
// this.queryPage.vehicleArrival = "1";
// this.queryPage.returnCostApprovalStatus = [10, 30]; // 已大提交
// }
} else {
// 仅显示待还车
this.queryPage.vehicleArrival = "";
this.queryPage.taskStatus = "0";
// if (this.isBussinessDep || this.isEnergyRole || this.isFinanceDep) {
// this.queryPage.vehicleArrival = "1"; // 已到车
// this.queryPage.taskStatus = "1";
// this.queryPage.returnCostApprovalStatus = [0, 40]; //未大提交
// }
//偷懒写法
// if (this.isBussinessDep) {
// this.queryPage.vehicleArrival = "0";
// }
}
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.returnCar
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
reachCar(id) {
const _this = this;
uni.showModal({
title: "提示",
content: "确认到达?",
success: (res) => {
if (res.confirm) {
this.$api.returnCar.sureReturn({ id }).then((res) => {
if (res) {
uni.showToast({
title: "操作成功",
icon: "success",
duration: 1500,
success() {
_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("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
/deep/ .testClass {
width: 80%;
}
.item {
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
}
.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>

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>

3331
pages/truckRent/detail.vue Normal file

File diff suppressed because it is too large Load Diff

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>

478
pages/truckRent/index.vue Normal file
View File

@@ -0,0 +1,478 @@
<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" v-if="item.safetyAuditStatus == 1 && isSafe">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">待安检</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 2 && isSafe">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">驳回</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 3 && isSafe">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">已通过</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 4 && isSafe">
<u-badge :isDot="true" type="info"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">待审批</view>
</view>
<view class="line">
<view class="text-normal">合同编号: {{ item.contractNo }}</view>
</view>
<view class="line">
<view class="text-normal">项目名称: {{ item.projectName }}</view>
</view>
<view class="line">
<view class="text-small">客户名称: {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small">交车区域: {{ item.deliveryAreaName }}</view>
</view>
<view class="line">
<view class="text-small">交车地点: {{ item.handoverAddress }}</view>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>交车时间: {{ formatDateTime(item.handoverDate) }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="item.deliveryPermit == 1 && currSafeRole === 0 && editButton"
:data-url="`/pages/truckRent/detail?id=${item.id}`"
>
编辑
</button>
<button
@tap="returnCar(item.id)"
v-if="isBussinessRole && current === 0"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
还车
</button>
<button
@tap="cancelReturnCar(item.id)"
v-if="isBussinessRole && current === 1"
>
撤销还车
</button>
<button
@tap="goto"
v-if="currSafeRole === 1 && [1, 2].includes(item.safetyAuditStatus)"
:data-url="`/pages/truckRent/detail?id=${item.id}${
currSafeRole !== 0 ? '&isRead=1&isSafe=1' : ''
}`"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
安全检查
</button>
<button
@tap="goto"
v-if="currSafeRole === 2 && item.safetyAuditStatus === 4"
:data-url="`/pages/truckRent/detail?id=${item.id}${
currSafeRole !== 0 ? '&isRead=1&isSafe=1' : ''
}`"
>
<!-- :disabled="item.safetyAuditStatus !== 4" -->
安全审批
</button>
<button
@tap="goto"
:data-url="`/pages/truckRent/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
<custom-modal ref="customModal" @submit="returnCarFunc" />
</view>
</template>
<script>
import CustomModal from "./modal.vue";
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
import { getUser } from "@/utils/auth.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
components: {
CustomModal,
},
data() {
return {
current: 0,
userInfo: {}, // 用户信息
list: ["待交车", "全部"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
// deliveryPermits: ["1"], // 交车许可 1表示 准许交车
},
costDepList: [], //费用部门
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "", //搜索关键字
pageCode: "applicationForDelivery",
currId: "",
};
},
computed: {
editButton: function () {
return checkButtonPermission("applicationForDeliveryEdit", this.pageCode);
},
currSafeRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("1076403008717209600")) {
return 2; //安全经理
} else if (ids.includes("1012435145369616384")) {
return 1; //安全员
} else {
return 0; //其他
}
},
isBussinessRole() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
},
isSafe() {
return [1, 2].includes(this.currSafeRole);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if ([1, 2].includes(this.currSafeRole)) {
if (index == 1) {
// 已通过
this.queryPage.safetyAuditStatus = ["3"];
} else {
// 未通过
this.queryPage.safetyAuditStatus = ["1", "2", "4"];
}
} else if (this.isBussinessRole) {
if (index == 1) {
console.log("业务助理-待还车");
// 业务助理,待还车
this.queryPage.vehicleArrival = "0";
this.queryPage.taskStatus = "";
} else {
// 全部
this.queryPage.vehicleArrival = "2";
this.queryPage.taskStatus = "1";
}
} else {
if (index == 1) {
// 全部 (准许交车 + 已交车)
this.queryPage.deliveryPermits = ["1", "3"];
} else {
// 仅显示准许交车
this.queryPage.deliveryPermits = ["1"];
}
}
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;
if (this.isBussinessRole && this.current == 1) {
this.$api.returnCar
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
} else {
this.$api.truckRent
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
}
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
returnCar(id) {
this.currId = id;
this.$refs.customModal.openModal();
},
returnCarFunc(isHasOkPack) {
const _this = this;
this.$api.returnCar
.startReturn({ id: this.currId, hasOkPack: isHasOkPack })
.then((res) => {
if (res) {
uni.showToast({
title: "还车成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
// const _this = this;
// uni.showModal({
// title: "提示",
// cancelText: "无",
// confirmText: "有",
// content: "请确认退还车辆有无无忧包?",
// success: (res) => {
// if (res.confirm) {
// this.$api.returnCar
// .startReturn({ id, hasOkPack: isHasOkPack })
// .then((res) => {
// if (res) {
// uni.showToast({
// title: "还车成功",
// icon: "success",
// duration: 1500,
// success() {
// _this.sectionChange(_this.current);
// },
// });
// }
// });
// }
// },
// });
},
cancelReturnCar(id) {
const _this = this;
uni.showModal({
title: "提示",
content: "确认撤销本次还车?",
success: (res) => {
if (res.confirm) {
this.$api.returnCar.cancelReturn({ id }).then((res) => {
if (res) {
uni.showToast({
title: "撤销成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
}
},
});
},
// getCostDeps() {
// this.$api.returnCar.getCostDeps().then((res) => {
// this.costDepList = res;
// });
// },
},
onLoad() {
// this.getCostDeps();
this.userInfo = getUser() || {};
console.log(this.userInfo);
if ([1, 2].includes(this.currSafeRole)) {
this.list = ["未通过", "已通过"]; //安全模块
} else if (this.isBussinessRole) {
this.list = ["全部", "待还车"]; //交还车-费用核算
}
},
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("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--success {
background-color: #5ac725 !important;
}
/deep/ .u-badge--info {
background-color: #fcae63 !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !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>

112
pages/truckRent/modal.vue Normal file
View File

@@ -0,0 +1,112 @@
<template>
<view class="custom-modal" v-if="show">
<view class="modal-overlay" @click="closeModal"></view>
<view class="modal-container">
<view class="modal-header">提示</view>
<view class="modal-content">请确认退还车辆有无无忧包?</view>
<view class="modal-footer">
<button class="btn cancel" @click="handleCancel"></button>
<button class="btn confirm" @click="handleConfirm"></button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
show: false,
};
},
methods: {
openModal() {
this.show = true;
},
closeModal() {
this.show = false;
},
handleCancel() {
console.log("点击了无");
this.$emit("submit", false);
this.closeModal();
},
handleConfirm() {
console.log("点击了有");
this.$emit("submit", true);
this.closeModal();
},
},
};
</script>
<style>
.custom-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
}
.modal-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
}
.modal-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
}
.modal-header {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 20rpx;
}
.modal-content {
font-size: 28rpx;
text-align: center;
margin-bottom: 30rpx;
color: #666;
}
.modal-footer {
display: flex;
justify-content: space-between;
}
.btn {
flex: 1;
margin: 0 40rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 28rpx;
text-align: center;
}
.cancel {
background-color: #f0f0f0;
color: #333;
}
.confirm {
background-color: #007aff;
color: #fff;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,416 @@
<template>
<view>
<u-sticky>
<u-button text="新增" @click="addFailuer"></u-button>
<!-- <u-search placeholder="请输入车牌号" v-model="keyword" :showAction="false" @search="searchList()"></u-search> -->
<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"
v-if="item.approvalStatus == 10 && item.isSubmit != 0"
>
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">待审批</view>
</view>
<view class="line" v-else-if="item.approvalStatus === 0">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">待提交</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 40">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal">驳回</view>
</view>
<view class="line" v-else-if="item.approvalStatus === 60">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">异动超时</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 99">
<u-badge :isDot="true" type="info"></u-badge>
<view class="text-normal">已撤销</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 30">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal">进行中</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 50">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal">异动完成</view>
</view>
<!-- <view class="line" v-else-if="item.approvalStatus == 30">
<u-badge
:isDot="true"
:type="item.transactionStatus === 2 ? 'success' : 'error'"
></u-badge>
<view class="text-normal">{{
item.transactionStatus === 2 ? "异动完成" : "进行中"
}}</view>
</view> -->
<view class="line">
<view class="text-small">车牌号: {{ item.plateNumber || "" }}</view>
</view>
<view class="line">
<view class="text-small">申请人: {{ item.applyUserName || "" }}</view>
</view>
<view
class="line"
v-if="![0, 10].includes(item.approvalStatus) && item.approvalName"
>
<view class="text-small">审批人: {{ item.approvalName || "" }}</view>
</view>
<view class="line">
<view class="text-small"
>开始时间:
{{ formatDateTime(item.transactionStartTime, "minute") }}</view
>
</view>
<view class="line">
<view class="text-small"
>异动目的地: {{ item.transactionAddressName || "" }}</view
>
</view>
<!-- <view class="line">
<view class="text-small"
>结束时间: {{ formatDateTime(item.approvalTime, "minute") }}</view
>
</view> -->
<view class="buttons">
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}`"
v-if="editButton && [0, 30, 40, 60].includes(item.approvalStatus)"
>
<!-- 25.2.24 注释&&
![2, 3].includes(item.transactionStatus)
2现为approvalStatus50 3为99
去除异动状态沿用审批状态字段当做异动状态显示 仅在前端显示为异动
-->
<!--
item.applyUserId === userId 编辑按钮不跟申请人挂钩跟外勤挂钩
[30, 40].includes(item.approvalStatus) 30通过 40驳回
[2, 3].includes(item.transactionStatus) 2异动完成 3撤销 -->
编辑
</button>
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}&isAudit=1`"
v-if="item.approvalStatus === 10 && auditButton"
>
审批
</button>
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}&isRead=1`"
>
查看
</button>
<button
@tap="cancelApply(item.id)"
v-if="
item.applyUserId == userId &&
![50, 99].includes(item.approvalStatus)
"
>
撤销
</button>
<!-- 25.2.24 注释 ![2, 3].includes(item.transactionStatus) &&
item.approvalStatus !== 99
2现为approvalStatus50 3为99
去除异动状态,沿用审批状态字段当做异动状态显示 仅在前端显示为异动
-->
</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 { getUser } from "@/utils/auth.js";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
keyword: "",
userId: null,
current: 0,
list: ["审批通过", "待审批"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, // 每页查询条数
total: 0, // 总页数
pages: -1, // 总页数
approvalStatusList: [30, 50, 60], // 审批状态集合
wxOrder: 2,
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
pageCode: "transactionManagement",
};
},
computed: {
auditButton: function () {
console.log(checkButtonPermission("transactionAudit", this.pageCode));
return checkButtonPermission("transactionAudit", this.pageCode);
},
editButton: function () {
return checkButtonPermission("transactionEdit", this.pageCode);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
console.log(index);
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
this.queryPage.approvalStatusList = [0, 10, 40, 99]; // 待提交,待审批,审批不通过,已撤销
this.queryPage.wxOrder = 1;
} else {
this.queryPage.approvalStatusList = [30, 50, 60]; //审批通过 60过期
this.queryPage.wxOrder = 2;
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj, type = "data") {
if (obj == null) {
return "";
}
const date = new Date(obj);
if (type === "date") {
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 === "minute") {
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");
const minute = String(date.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}`;
}
},
loadmore() {
this.loading = true;
this.$api.unusualActionApply
.queryPageList(this.queryPage)
.then((res) => {
console.log(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;
});
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
// formatPlateNumber(plateNumbers) {
// if (!plateNumbers) return ""; // 如果为空,返回空字符串
// const plates = plateNumbers.split(","); // 将字符串按逗号分隔成数组
// if (plates.length > 1) {
// return `${plates[0]}...`; // 如果有多个车牌号,返回第一个加上“...”
// }
// return plates[0]; // 如果只有一个车牌号,直接返回
// },
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
cancelApply(id) {
uni.showModal({
title: "提示",
content: "是否撤销本次异动申请?",
success: (res) => {
if (res.confirm) {
this.cancelApplyApi(id);
}
},
});
},
//撤销异动申请
cancelApplyApi(id) {
if (id) {
this.$api.unusualActionApply.revokeTransaction({ id }).then((res) => {
if (res) {
uni.showToast({
title: "撤销成功",
icon: "success",
duration: 1500,
success: () => {
this.sectionChange(this.current);
},
});
}
});
}
},
addFailuer() {
uni.navigateTo({ url: `/pages/unusualActionApply/detail` });
},
},
onLoad() {
this.userInfo = getUser() || {};
this.userId = this.userInfo.id;
console.log("userId type:", typeof this.userId);
},
onPullDownRefresh() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
/deep/ .u-icon__icon {
font-size: 26rpx !important;
}
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !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 {
margin-left: 20rpx;
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>

39
pages/webview/index.vue Normal file
View File

@@ -0,0 +1,39 @@
<template>
<view>
<!-- WebView 组件 -->
<web-view ref="webView" :src="url" @message="handleGetMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
url: '' // WebView 的初始地址
}
},
onLoad: function (option) {
this.url = decodeURIComponent(option.url)
this.type = option.type
},
methods: {
handleGetMessage: function(e) {
console.log(e,'\n进入handleGetMessage方法')
console.log('handleGetMessage',e)
if(e.detail.data[0].result=='success'){
// 如果是人脸验证,则需要额外再跳一层
if (this.type == "face") {
console.log("人脸识别方式")
uni.navigateBack()
} else {
// 页面会自动往回跳1层短信认证时不需要手动uni.navigateBack
console.log("短信验证方式")
}
}
},
},
}
</script>