835 lines
20 KiB
Vue

<template>
<view class="container">
<scroll-view class="scrollWrap" scroll-x="true" scroll-with-animation>
<view class="scrollItem" style="width: 50%;" v-for="(item,index) in changeList" :key="index"
:class="{active:tabIndex == index}" :data-current="tabIndex" @click="sendTabItem(item,index)">
{{item.title}}
</view>
</scroll-view>
<view v-show="tabIndex === 0">
<scroll-view scroll-y="true" :style="{ height: scrollHeight+ 'px' }">
<uni-card>
<uni-forms ref="ebikeInfoForm">
<uni-forms-item label="车辆编号">
<bikeCodeScan ref="childComponent" @scan-change="bikeCodeScanChange"
:codeValue="ebikeInfo.bikeCode"/>
</uni-forms-item>
<uni-forms-item label="故障部位">
<view class="deepBlackBoldText">
{{ebikeGZInfo.faultPart}}
</view>
</uni-forms-item>
<uni-forms-item label="故障内容">
<view class="deepBlackBoldText">
{{ebikeGZInfo.faultDescription}}
</view>
</uni-forms-item>
<uni-forms-item v-if="ebikeGZInfo.fileList" label="故障照片">
<uni-file-picker readonly="true" limit="9" :value="ebikeGZInfo.fileList"></uni-file-picker>
</uni-forms-item>
<uni-forms-item label="上报人">
<view class="deepBlackBoldText">
{{ebikeGZInfo.reportUser}}
</view>
</uni-forms-item>
<uni-forms-item label="上报来源">
<view class="deepBlackBoldText">
{{ebikeGZInfo.reportSource}}
</view>
</uni-forms-item>
<uni-forms-item label="上报时间">
<view class="deepBlackBoldText">
{{ebikeGZInfo.reportAt}}
</view>
</uni-forms-item>
<uni-forms-item label="在线状态">
<view class="deepBlackBoldText">
{{ebikeGZInfo.zxstate}}
</view>
</uni-forms-item>
<uni-forms-item label="电池电量">
<view class="deepBlackBoldText">
{{ebikeGZInfo.batteryLevel}}
</view>
</uni-forms-item>
<uni-forms-item label="车辆位置">
<view class="flex justify-between" @click="viewMap(ebikeGZInfo.longitude,ebikeGZInfo.latitude)">
<view class="deepBlackBoldText" style="line-height: 20px;">
<span v-if="ebikeGZInfo.longitude & ebikeGZInfo.latitude">查看地图</span>
<view style="font-size: 12px;">
{{ebikeGZInfo.longitude+','+ ebikeGZInfo.latitude}}
</view>
</view>
<view v-if="ebikeGZInfo.longitude & ebikeGZInfo.latitude">
<uni-icons type="right" size="20"></uni-icons>
</view>
</view>
</uni-forms-item>
<uni-forms-item label="信号强度">
<view class="deepBlackBoldText">
{{ebikeGZInfo.signalStrength}}
</view>
</uni-forms-item>
</uni-forms>
</uni-card>
<uni-card>
<view class="example">
<view class="button-group">
<button size="mini" @click="execDetection({url:'unlock'})">开锁</button>
<button size="mini" @click="execDetection({url:''})">推车</button>
<button size="mini" @click="execDetection({url:'openBatteryLock'})">电池仓库</button>
<button size="mini" @click="execDetection({url:'openHelmet'})">开头盔锁</button>
</view>
</view>
</uni-card>
<uni-popup ref="popup" class="unipopup" :mask-click="false">
<view v-if="popuptextlx==1" class="bg-white boxcenter">
<view class="textbox">
此设备无故障上报记录,是否进行故障上报?
</view>
<view class="example">
<view class="buttongroup">
<button @click="closePopup" class="cu-btn lg lines-blue">返回</button>
<button @click="gotoFaultReport" class="cu-btn lg bg-blue">去上报</button>
</view>
</view>
</view>
<view v-if="popuptextlx==2" class="bg-white boxcenter">
<view class="textbox">
当前车辆故障如下,可选择进行维修:
</view>
<view class="textlist">
<scroll-view class="scroll-container" scroll-y style="height: 170px;">
<view v-for="(item,index) in gzlist" :key="index">
<view class="flex gzboxlist">
<view @click="check(item,index)">
<aip-checkbox :key="keys" :check="item.checked" v-if="true"></aip-checkbox>
</view>
<view class="item">
<view class="wz14">
{{item.faultPart}}
</view>
<view class="wz12">
{{item.faultDescription}}
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="example">
<view class="buttongroup">
<button @click="closePopup" class="cu-btn lg lines-blue">返回</button>
<button @click="createTicket" class="cu-btn lg bg-blue">接单维修</button>
</view>
</view>
</view>
</uni-popup>
</scroll-view>
<view class="nav-panel">
<uni-goods-nav :fill="true" :options="[]" :buttonGroup="navButtonGroup" @buttonClick="navButtonClick" />
</view>
</view>
<view v-show="tabIndex === 1">
<z-paging ref="paging" :fixed="false" height="95vh" v-model="faultHistoryList" @query="loadMoreData"
:default-page-no="1" :default-page-size="2" :auto-show-back-to-top="true">
<view v-for="item in faultHistoryList" :key="index">
<uni-card>
<uni-forms ref="ebikeInfoForm" :modelValue="item">
<uni-forms-item label="车辆编号">
<view class="deepBlackBoldText">
{{item.bikeCode}}
</view>
</uni-forms-item>
<uni-forms-item label="故障部位">
<view class="deepBlackBoldText">
{{item.faultPart}}
</view>
</uni-forms-item>
<uni-forms-item label="故障内容">
<view class="deepBlackBoldText">
{{item.faultDescription}}
</view>
</uni-forms-item>
<uni-forms-item label="上报时间">
<view class="deepBlackBoldText">
{{item.reportAt}}
</view>
</uni-forms-item>
<uni-forms-item label="处理时间">
<view class="deepBlackBoldText">
{{item.handleAt}}
</view>
</uni-forms-item>
<uni-forms-item label="处理人">
<view class="deepBlackBoldText">
{{item.receiverName}}
</view>
</uni-forms-item>
<uni-forms-item label="处理结果">
<view class="deepBlackBoldText">
{{item.handleResult}}
</view>
</uni-forms-item>
</uni-forms>
</uni-card>
</view>
</z-paging>
</view>
</view>
<uni-popup ref="popup_bottom" class="unipopup" type="bottom" background-color="#fff">
<view class="boxbottomclass padding">
<view class="title">
处理故障
</view>
<!-- <view class="butboxchilren">
<uni-data-checkbox mode="button" v-model="clgzvalue" :localdata="clgzlist"></uni-data-checkbox>
</view> -->
<view class="butboxchilren">
<view class="butwz">
填写处理结果
</view>
<uni-easyinput type="textarea" v-model="handleResult" placeholder="请输入处理结果" />
</view>
<view class="butboxchilren">
<view class="butwz">
故障照片
</view>
<view class="example-body">
<uni-file-picker limit="9" @select="selectImg" @delete="delChangeImg"
:value="fileLists"></uni-file-picker>
</view>
</view>
</view>
<view class="button-group">
<button class="cu-btn lg lines-blue" style=" width: 45%; color:#0078d4;" @click="closePopupbottom">
取消
</button>
<button class="cu-btn lg bg-blue" style=" width: 45% ;color: white;" @click="submitGzInfo">
提交
</button>
</view>
</uni-popup>
<zero-loading v-if="isloading" color="#c1c1c0" type="pulse" mask="true"></zero-loading>
</template>
<script setup>
import {
reactive,
ref,
onMounted,
} from 'vue';
import * as api from '@/utils/api.js';
import config from '../../../utils/config';
import {
showModelMessage
} from '@/utils/tools.js';
import {
onLoad
} from '@dcloudio/uni-app';
const ebikeInfo = ref({});
const isloading = ref(false)
const bikeCodeScanChange = (data) => {
userInfo.value = uni.getStorageSync('userInfo');
const bikeCode = data;
ebikeInfo.value.bikeCode = data;
const params = {
"receiverId": userInfo.value.staffId,
"bikeCode": bikeCode
}
api.callEbikeInfo("getBikeINfoData?bikeCode=" + bikeCode).then((res) => {
if (res.code == 200) {
ebikeInfo.value.ecuId = res.data.ecuId;
ebikeInfo.value.bikeId = res.data.bikeId;
ebikeInfo.value.ecuSn = res.data.ecuSn;
api.callEbikeInfo("inspectHaveOrNotWorkOrder", params).then((res) => {
if (res.code == 200) {
orderId.value = res.data;
api.callEbikeInfo("getFaultInfo?orderId=" + res.data, {}, "get").then((
res1) => {
if (res1.code == 200) {
popup.value.close("center");
ebikeGZInfo.value = res1.data;
}
})
api.callCoreApi("online?ecuId=" + ebikeInfo.value.ecuId +
"&bikeId=" + ebikeInfo.value.bikeId, {}, 'get')
.then((
ecudata) => {
ebikeGZInfo.value.zxstate = ecudata
.data.message;
});
api.callCoreApi("gps?ecuId=" + ebikeInfo.value.ecuId +
"&bikeId=" + ebikeInfo.value.bikeId, {}, 'get')
.then((ecudata) => {
api.callCoreApi("gpsMsg" + "?ecuSn=" + ebikeInfo.value
.ecuSn, {}, 'get').then((res) => {
ebikeGZInfo.value.batteryLevel = res.data
.soc + "%"
ebikeGZInfo.value.signalStrength = res.data
.gsm
})
});
} else {
api.callEbikeInfo("getFaultReportList?bikeCode=" + bikeCode, 'get').then((
res) => {
if (res.code == 200) {
if (res.data != null && res.data.length > 0) {
popuptextlx.value = 2;
gzlist.value = res.data
popup.value.open("center");
} else {
popuptextlx.value = 1;
popup.value.open("center");
}
}
})
}
})
} else {
showModelMessage(res.message)
}
});
};
const selectImg = (data) => {
const file = data.tempFiles[0];
api.fileUpload(file).then(res => {
if (res.code == 200) {
fileLists.value.push(res.data)
} else {
// 上传失败,删除列表最后一个文件
if (fileLists.value.length > 0) {
fileLists.value.pop(); // 删除最后一个文件
} else {
// 如果列表为空,则设置为 null
fileLists.value = [];
}
}
});
}
const delChangeImg = (res) => {
const fileUniqueKey = fileLists.value[res.index].fileUniqueKey;
fileLists.value.splice(res.index, 1);
api.callEbikeInfo("deletedFile?fileUniqueKey=" + fileUniqueKey, {}, "get");
}
const fileLists = ref([]);
const orderId = ref("");
const handleResult = ref(null)
const clgzvalue = ref("1"); //处理故障类型 1 处理故障 2 故障误报
const clgzlist = ref([{
text: '故障误报',
value: 2
}, {
text: '处理故障',
value: 1
}]);
const ebikeGZInfo = ref({
bikeCode: '',
longitude: '',
latitude: ''
});
const navButtonGroup = [{
text: '取消工单',
backgroundColor: '#0078D4',
color: "#fff"
}, {
text: '处理完成',
backgroundColor: '#0078D4',
color: "#fff"
}];
const popup_bottom = ref(null);
const popuptextlx = ref(1)
const tabIndex = ref(0)
const gzlist = ref([]);
const keys = ref(0)
const scrollHeight = ref(0);
const typepopup = ref("center");
const popup = ref(null);
const userInfo = ref(null);
const changeList = ref([{
id: 0,
title: '故障详情'
},
{
id: 1,
title: '故障历史'
}
]);
const faultHistoryList = ref([]);
const paging = ref(null);
const loadMoreData = (pageNo, pageSize) => {
if (!ebikeInfo.value.bikeId) {
paging.value.complete([]);
return;
}
// 组装参数
const params = {
"bikeId": ebikeInfo.value.bikeId,
"pageParam": {
"pageNum": pageNo,
"pageSize": pageSize
}
}
api.callEbikeInfo("getFaultHistoryList", params).then((res) => {
if (res.code === 200) {
const records = res.data;
paging.value.complete(res.data);
} else {
paging.value.complete(false);
}
});
};
const sendTabItem = (data) => {
let index = data['id'];
if (tabIndex.value == index) return;
if (index == 1) { //查看故障历史请先扫码
if (!checkscan()) {
return
}
paging.value.reload();
}
tabIndex.value = index;
}
const navButtonClick = (data) => {
if (!checkscan()) {
return
}
const {
index,
content
} = data;
if (index == 0) { //取消工单
api.callEbikeInfo("canCellWorkOrder?orderId=" + orderId.value+"&orderType=1", {}, "get").then((res) => {
if (res.code == 200) {
uni.showToast({
title: "取消成功!",
icon: "success",
duration: 1000,
mask: true,
success: () => {
setTimeout(() => {
uni.switchTab({
url: "/pages/mine/mine"
});
}, 1000);
}
});
} else {
uni.showToast({
title: "取消工单失败!",
icon: "error",
duration: 1000,
mask: true
});
}
})
} else if (index == 1) {
//打开处理页面
popup_bottom.value.open("bottom");
}
}
const closePopup = () => {
popup.value.close("center");
uni.switchTab({
url: "/pages/mine/mine"
})
}
const closePopupbottom = () => {
popup_bottom.value.close("bottom");
}
//提交上报工单
const submitGzInfo = () => {
uni.showModal({
title: '确认提交',
content: '您确定要进行提交操作吗?',
success: (res) => {
if (res.confirm) {
const params = {
"orderId": orderId.value,
"handleResult": handleResult.value,
"fileList": fileLists.value
}
api.callEbikeInfo("faultHandelComplete", params).then((res) => {
if (res.code == 200) {
uni.showToast({
title: "提交成功!",
icon: "success",
duration: 1000,
mask: true,
success: () => {
// 在 Toast 显示结束后再跳转到 mine 页面
setTimeout(() => {
uni.switchTab({
url: "/pages/mine/mine"
});
}, 1000); // 延迟时间与Toast的显示时间相同
}
});
} else {
uni.showToast({
title: "提交失败",
icon: 'error',
duration: 1000,
mask: true
})
}
})
} else if (res.cancel) {}
}
});
};
const checkscan = () => {
if (!ebikeInfo.value.bikeCode) {
showModelMessage("请先扫车辆码或输入车辆码");
return false;
}
if (!ebikeInfo.value.bikeId) {
showModelMessage("车辆信息不存在");
return false;
}
return true;
}
const createTicket = () => {
if (isloading.value) {
return;
}
isloading.value = true;
//生成工单
const faultIds = gzlist.value.filter(item => item.checked === true).map(item => item.faultReportId);
const params = {
"bikeCode": ebikeInfo.value.bikeCode,
"faultIds": faultIds,
"receiverId": userInfo.value.staffId
}
api.callEbikeInfo("createWorkOrder", params).then((res) => {
if (res.code == 200) {
ebikeInfo.value.orderId = res.data;
orderId.value = res.data;
popup.value.close("center");
api.callEbikeInfo("getFaultInfo?orderId=" + res.data, {}, "get").then((res1) => {
if (res1.code == 200) {
ebikeGZInfo.value = res1.data;
}
isloading.value = false;
})
api.callCoreApi("online?ecuId=" + ebikeInfo.value.ecuId +
"&bikeId=" + ebikeInfo.value.bikeId, {}, 'get')
.then((
ecudata) => {
ebikeGZInfo.value.zxstate = ecudata
.data.message;
});
api.callCoreApi("gps?ecuId=" + ebikeInfo.value.ecuId +
"&bikeId=" + ebikeInfo.value.bikeId, {}, 'get')
.then((ecudata) => {
api.callCoreApi("gpsMsg" + "?ecuSn=" + ebikeInfo.value
.ecuSn, {}, 'get').then((res) => {
ebikeGZInfo.value.batteryLevel = res.data
.soc + "%"
ebikeGZInfo.value.signalStrength = res.data
.gsm
})
});
} else {
isloading.value = false;
}
})
}
const gotoFaultReport = () => {
uni.navigateTo({
url: "/pages/devops/faultreport/faultreport",
});
}
const check = (item, index) => {
item.checked = !item.checked;
keys.value = keys.value == 1 ? 0 : 1;
}
const execDetection = (url) => {
if (!checkscan()) {
return
}
uni.showLoading({
title: "指令下发中...",
mask: true
})
var paramName = "ecuId";
var data = ebikeInfo.value.ecuId
var bikeId = ebikeInfo.value.bikeId
api.callCoreApi(url['url'] + "?ecuId=" + data + "&bikeId=" + bikeId, {}, 'get').then((res) => {
uni.hideLoading();
var title = res.data.message;
var icon = "";
if (res.data.code == 200) {
icon = "success"
} else {
icon = "error"
}
uni.showToast({
title: title,
icon: icon,
duration: 2000,
mask: true
});
});
}
const viewMap = (lng,lat) => {
uni.navigateTo({
url: "/pages/map/map-findbike?longitude=" + lng + "&latitude=" + lat,
});
}
const bikeCode = ref("");
const childComponent = ref(null);
onLoad((options) => {
userInfo.value = uni.getStorageSync('userInfo');
const systemInfo = uni.getSystemInfoSync();
const screenHeight = systemInfo.screenHeight;
const statusBarHeight = systemInfo.statusBarHeight;
scrollHeight.value = screenHeight - statusBarHeight - 158;
if (options.bikeCode) {
bikeCode.value = options.bikeCode
}
})
onMounted(() => {
if (bikeCode.value != "") {
if (childComponent.value) {
childComponent.value.onSetValue(bikeCode.value); // 调用子组件暴露的方法来更新子组件值
}
bikeCodeScanChange(bikeCode.value);
}
})
</script>
<style>
.deepBlackBoldText {
/* color: #000000; */
font-weight: bold;
}
.uni-forms-item {
position: relative;
display: flex;
flex-direction: row;
margin-bottom: 10px !important
}
.uni-forms-item__content {
position: relative;
font-size: 14px;
flex: 1;
box-sizing: border-box;
flex-direction: row;
line-height: 36px;
}
.select-area {
padding: 0 0 12rpx 0;
background-color: #fff;
}
.select-top {
position: relative;
width: 100%;
height: 88rpx;
}
.nav-panel {
position: fixed;
bottom: 0rpx;
width: 100%;
padding-bottom: 20px;
background-color: #fff;
z-index: 105;
}
.view-body {
display: flex;
width: 100%;
height: 20px;
}
.example {
text-align: center;
}
.view-title {}
.view-content {
margin-left: 30px;
}
.container {
padding: 0px 0px;
background-color: #f3f4f6;
}
.boxcenter {
width: 290px;
padding: 15px;
}
.buttongroup {
display: flex;
justify-content: space-between;
}
.textbox {
width: 100%;
padding: 15px 5px;
text-align: center;
font-size: 14px;
letter-spacing: 1px;
}
.textlist {
height: 180px;
}
.gzboxlist {
width: 100%;
padding: 0px;
height: 50px;
border: solid 1px rgb(229, 229, 229);
align-items: center;
margin: 6px 0px;
}
.wz14 {
font-size: 14px;
line-height: 15px;
}
.wz12 {
font-size: 12px;
line-height: 15px;
color: rgb(191, 191, 191);
}
.unipopup .uni-popup {
z-index: 199;
}
.tabs-container {
position: -webkit-sticky;
position: sticky;
top: 64px;
z-index: 99;
color: #333;
}
.scrollWrap {
height: 40px;
line-height: 40px;
width: 100%;
white-space: nowrap;
text-align: center;
font-size: 14px;
background-color: #fff;
}
.scrollWrap .scrollItem {
display: inline-block;
width: 25%;
font-size: 25rpx;
}
.scrollWrap .active {
color: #009DFF !important;
position: relative;
font-weight: 600;
font-weight: bold;
text-decoration: underline;
text-underline-offset: 4px;
}
.scrollWrap .active :after {
content: "";
display: block;
position: absolute;
bottom: 0;
left: calc(50% - 5px);
width: 10px;
height: 2px;
background-color: #009DFF !important;
}
.button-group button {
color: #fff;
background-color: rgb(0, 120, 212);
margin-left: 2%;
display: inline-block;
line-height: 2.3;
font-size: 13px;
width: 23%;
height: 35px;
padding: 3px 0px;
}
.boxbottomclass {
min-height: 410px;
}
.title {
line-height: 30px;
text-align: center;
font-size: 18px;
letter-spacing: 2px;
font-weight: bold;
}
.butboxchilren {
margin: 15px;
}
.butboxchilren .uni-data-checklist .checklist-group {
justify-content: center;
}
.butwz {
font-size: 12px;
line-height: 30px;
color: rgb(140, 140, 140);
}
.uni-card {
border-radius: 15px !important;
}
.form_item {
position: relative;
font-size: 14px;
flex: 1;
box-sizing: border-box;
flex-direction: row;
line-height: 20px;
}
</style>