<template>
|
<view class="pages-error">
|
<view class="switch-type">
|
<view class="switch-button-group">
|
<view class="switch-button" v-for="(page,index) in pageList" :key="page"
|
:class="curPageIndex ==index?'switch-button-checked':''" @click="onSelectPage(index)">
|
{{page}}
|
</view>
|
|
</view>
|
</view>
|
<swiper circular indicator-dots class="swiper" :current="curPageIndex" @change="changePageSwiper">
|
<swiper-item class="swiper-item">
|
|
<scroll-view class="list" enable-flex scroll-y refresher-enabled="true" :refresher-triggered="triggered"
|
:scroll-top="scrollTop" :refresher-threshold="100" @refresherpulling="onPulling"
|
@refresherrefresh="onRefresh" @refresherrestore="onRestore" @refresherabort="onAbort"
|
@scroll="scrollView">
|
<view class="list-tip"> {{translate('current_errors')}}</view>
|
<template v-if="errorList.length > 0">
|
<view class="list-view">
|
<view class="list-item" v-for="(item,index) in errorList" :key="index">
|
<LogItemView :logData="item" :isRuntime="true" :language='language'></LogItemView>
|
|
</view>
|
</view>
|
<view class="button-line"> <a-button type="primary" class="button" @click="clickClearError">
|
{{translate('clear_errors')}}
|
</a-button></view>
|
</template>
|
<view class="list-tip center" v-else>{{translate('current_no_error_messages')}}</view>
|
|
<view class="list-tip">{{translate('history_errors')}}</view>
|
<view class="list-view" v-if="errorHistory.length > 0">
|
<view class="list-item" v-for="(item,index) in errorHistory" :key="index">
|
<LogItemView :logData="item" :language='language' :downloadProgress="downloadProgress"
|
:downloading="downloadingFile== item.file_path"
|
:waiting="downloadList.includes(item.file_path)" @click-download="clickDownload">
|
</LogItemView>
|
</view>
|
</view>
|
<view class="list-tip center" v-else>{{translate('current_no_error_messages')}}</view>
|
|
</scroll-view>
|
|
|
</swiper-item>
|
<swiper-item class="swiper-item">
|
<view class="list">
|
<view class="list-tip">{{translate('log_time_range')}}</view>
|
<view class="list-line">
|
<view class="label">{{translate("start_time")}}:</view>
|
<view class="value">
|
<uni-datetime-picker type="datetime" v-model="start_time" :disabled="downloading">
|
{{start_time?start_time:translate('select_start_time')}}<uni-icons class="icon"
|
type="right" size="20" color="#888"></uni-icons></uni-datetime-picker>
|
|
</view>
|
|
</view>
|
<view class="list-line">
|
<view class="label">{{translate("end_time")}}:</view>
|
<view class="value">
|
<uni-datetime-picker type="datetime" v-model="end_time" :disabled="downloading">
|
{{end_time?end_time:translate('select_end_time')}}<uni-icons class="icon" type="right"
|
size="20" color="#888"></uni-icons></uni-datetime-picker>
|
</view>
|
</view>
|
<template v-if="!downloading">
|
<view class="button-line"> <a-button type="primary" class="button" @click="clickDownloadLog">
|
{{translate('download_log')}}
|
</a-button></view>
|
|
</template>
|
|
<view class="download-progress" v-else>
|
|
<view class="progress"> <progress :percent="downloadProgress" activeColor="#10AEFF"
|
stroke-width="3" />
|
</view>
|
<view class="tip">{{downloadingTip }}</view>
|
|
</view>
|
</view>
|
</swiper-item>
|
|
</swiper>
|
</view>
|
</template>
|
|
<script>
|
import {
|
showToast,
|
showModal,
|
showError,
|
showInfo
|
} from "@/comm/utils.js"
|
import TaskInit from "@/comm/extend.js"
|
|
import {
|
getErrorList,
|
getErrorHistory,
|
clearFault,
|
downloadError,
|
tarErrorLog,
|
queryErrorTaskStatus
|
} from "@/api/vehicle.js"
|
import LogItemView from "./infos/log-item.vue"
|
|
import {
|
Button
|
} from 'antd-mobile-vue-next'
|
import dayjs from "dayjs"
|
|
export default {
|
name: "PagesError",
|
components: {
|
|
'a-button': Button,
|
LogItemView,
|
},
|
data() {
|
return {
|
downloading: false,
|
downloadProgress: 0,
|
downloadingTip: "",
|
downloadingFile: "",
|
downloadList: [],
|
ip: "",
|
sceneId: "",
|
errorList: [],
|
errorHistory: [],
|
curPageIndex: 0,
|
pageList: [this.translate('errors'), this.translate('download_logs')],
|
language: "zh",
|
isPageVisible: false,
|
start_time: "",
|
end_time: "",
|
triggered: false,
|
scrollTop: 0,
|
old: {
|
triggered: 0,
|
scrollTop: 0
|
},
|
fileList: []
|
}
|
},
|
computed: {
|
|
},
|
|
onLoad(option) {
|
this.ip = option.ip || ""
|
uni.setNavigationBarTitle({
|
title: this.translate("errors")
|
})
|
const curLang = uni.getLocale()
|
if (curLang == "en") {
|
this.language = ""
|
}
|
this.isPageVisible = true
|
this.loadData()
|
},
|
onShow() {
|
this.isPageVisible = true
|
|
|
},
|
onHide() {
|
this.isPageVisible = false
|
|
},
|
methods: {
|
setData(obj) {
|
let that = this;
|
let keys = [];
|
let val, data;
|
|
Object.keys(obj).forEach(function(key) {
|
keys = key.split(".");
|
val = obj[key];
|
data = that.$data;
|
keys.forEach(function(key2, index) {
|
if (index + 1 == keys.length) {
|
that.$set(data, key2, val);
|
} else {
|
if (!data[key2]) {
|
that.$set(data, key2, {});
|
}
|
}
|
data = data[key2];
|
});
|
});
|
},
|
async loadData() {
|
try {
|
const _this = this
|
this.errorHistory = await this.loadErrorHistory()
|
this.errorList = await this.loadErrorList()
|
this.scrollTop = this.old.scrollTop
|
|
this.$nextTick(function() {
|
_this.scrollTop = 1
|
});
|
try {
|
const list = await TaskInit.fileUtils.listSavedFiles("download")
|
this.fileList = list.map((a) => a.name)
|
} catch (ex) {
|
console.log(ex)
|
}
|
|
} catch (ex) {
|
showError(ex, this.translate('error'))
|
}
|
},
|
|
async loadErrorHistory() {
|
try {
|
const list = await getErrorHistory(this.ip)
|
list.forEach((item) => {
|
const path = item.file_path
|
item.file_path = path.trim()
|
})
|
return list || []
|
} catch (ex) {
|
showError(ex, this.translate('error'))
|
|
return []
|
}
|
},
|
async loadErrorList() {
|
try {
|
const list = await getErrorList(this.ip)
|
return list || []
|
} catch (ex) {
|
showError(ex, this.translate('error'))
|
|
return []
|
}
|
},
|
async timerLoadErrorList() {
|
try {
|
if (this.isPageVisible)
|
this.errorList = await this.loadErrorList()
|
} catch (ex) {
|
showToast(ex)
|
} finally {
|
setTimeout(this.timerLoadErrorList, 10 * 1000);
|
}
|
},
|
onSelectPage(index) {
|
if (this.downloading)
|
return
|
this.setData({
|
curPageIndex: index
|
})
|
},
|
changePageSwiper(evt) {
|
if (this.downloading)
|
return
|
let index = evt.target.current || evt.detail.current;
|
this.setData({
|
curPageIndex: index
|
})
|
},
|
async clickClearError() {
|
try {
|
|
await clearFault(this.ip)
|
this.loadData()
|
} catch (ex) {
|
showError(ex)
|
}
|
},
|
clickDownload(item) {
|
var pathArr = item.file_path.split("/")
|
if (pathArr.length === 1) {
|
pathArr = item.file_path.split("\\")
|
}
|
const fileName = pathArr.pop()
|
console.log(fileName, this.fileList)
|
if (this.fileList.includes(fileName)) {
|
showModal({
|
title: "",
|
content: this.translate("log_downloaded_ask_redownloaded"),
|
confirmText: this.translate("yes"),
|
cancelText: this.translate("no")
|
}).then((res) => {
|
TaskInit.fileUtils.deleteSavedFile("download",fileName)
|
if (this.downloadingFile) {
|
this.downloadList.push(item.file_path)
|
} else
|
this.downloadErrorLog(item.file_path)
|
})
|
} else {
|
if (this.downloadingFile) {
|
this.downloadList.push(item.file_path)
|
} else
|
this.downloadErrorLog(item.file_path)
|
}
|
|
},
|
async clickDownloadLog() {
|
try {
|
this.downloadingTip = this.translate("package_download_logs")
|
this.downloadProgress = 0
|
this.downloading = true
|
const startTime = this.start_time ? TaskInit.dateUtils.formatDate(new Date(this.start_time),
|
"yyyyMMdd_hhmmss") : ""
|
const endTime = this.start_time ? TaskInit.dateUtils.formatDate(new Date(this.end_time),
|
"yyyyMMdd_hhmmss") : ""
|
const res = await tarErrorLog(this.ip, startTime, endTime)
|
if (res) {
|
const list = await queryErrorTaskStatus(this.ip, [res]) || []
|
if (list.length > 0) {
|
const item = list[0]
|
const path = item.path || ""
|
if (!path.trim()) {
|
showToast(this.translate("download_log_fail_not_get_filepath"))
|
return
|
}
|
if (this.downloadingFile) {
|
this.downloadList.push(path)
|
} else
|
this.downloadErrorLog(path)
|
|
} else {
|
this.downloading = false
|
showError(this.translate('download_logs_fail'))
|
}
|
} else {
|
this.downloading = false
|
showError(this.translate('download_logs_fail'))
|
}
|
} catch (ex) {
|
showError(ex)
|
this.downloading = false
|
} finally {
|
|
|
}
|
},
|
|
downloadErrorLog(path) {
|
const _this = this
|
this.downloading = true
|
this.downloadProgress = 0
|
this.downloadingFile = path
|
this.downloadingTip = `${this.translate("downloading_log")}:${this.downloadProgress}%`
|
downloadError(this.ip, path, (temppath) => {
|
console.log("下载成功:", temppath)
|
var pathArr = temppath.split("/")
|
if (pathArr.length === 1) {
|
pathArr = temppath.split("\\")
|
}
|
const fileName = pathArr.pop()
|
_this.downloading = false
|
_this.downloadProgress = 100
|
|
TaskInit.fileUtils.moveToLocal(temppath,"download", fileName).then((res) => {
|
console.log("保存成功:", res)
|
this.fileList.push(fileName)
|
showToast(_this.translate("download_success"))
|
|
}).catch((err) => {
|
console.log("保存失败:", err)
|
showToast(_this.translate("failed_save_file"))
|
|
}).finally(() => {
|
_this.downloadNextLogFile()
|
})
|
|
|
},
|
(docProgress, downloadHandle) => {
|
console.log("下载进度:", docProgress)
|
_this.setData({
|
downloadProgress: docProgress.progress,
|
downloadingTip: `${this.translate("downloading_log")}:${docProgress.progress}%`
|
})
|
},
|
(err) => {
|
_this.downloading = false
|
_this.downloadNextLogFile()
|
showError(err)
|
})
|
|
},
|
downloadNextLogFile() {
|
if (this.downloadList.length > 0) {
|
const path = this.downloadList.shift()
|
this.downloadErrorLog(path)
|
} else {
|
this.downloadingFile = ""
|
}
|
|
},
|
scrollView(e) { //nvue暂不支持滚动监听,可用bindingx代替
|
//console.log("scrollView:" + e.scrollTop);
|
this.old.scrollTop = e.detail.scrollTop
|
},
|
|
onPulling(e) {
|
|
this.old.triggered = e.detail.triggered
|
console.log("onPulling", this.old.triggered)
|
},
|
async onRefresh() {
|
try {
|
const _this = this
|
|
this.errorHistory = await getErrorHistory(this.ip) || []
|
this.errorList = await getErrorList(this.ip) || []
|
|
this.triggered = this.old.triggered
|
this.$nextTick(function() {
|
_this.triggered = false
|
});
|
showToast(this.translate("refresh_success"))
|
this.$forceUpdate();
|
} catch (ex) {
|
showToast(this.translate("refresh_failed_retry"))
|
}
|
},
|
|
onRestore() {
|
// console.log("onRestore");
|
this.triggered = 'restore'; // 需要重置
|
},
|
onAbort() {
|
// console.log("onAbort");
|
},
|
|
translate(t) {
|
if (typeof this.$t == "function") return this.$t(`page.${t}`)
|
else return t;
|
},
|
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.pages-error {
|
display: flex;
|
width: 750rpx;
|
height: 100vh;
|
flex-direction: column;
|
background-color: #F5F5F5;
|
|
.switch-type {
|
width: calc(100% - 40rpx);
|
margin: 20rpx 20rpx 10rpx 20rpx;
|
align-items: center;
|
vertical-align: middle;
|
|
.switch-button-group {
|
height: 32px;
|
border: 1px solid #dfdfdf;
|
border-radius: 15rpx;
|
background-color: #dfdfdf;
|
display: flex;
|
flex: row;
|
|
.switch-button {
|
flex: 1;
|
border-radius: 15rpx;
|
color: #000000A5;
|
height: 32px;
|
line-height: 32px;
|
text-align: center;
|
}
|
|
.switch-button-checked {
|
box-shadow: 0px 2px 8px 0px #0000000C;
|
background-color: #fff;
|
color: #262626;
|
}
|
|
}
|
|
}
|
|
.swiper {
|
|
width: calc(100% - 20rpx);
|
margin: 10rpx;
|
|
display: flex;
|
flex: 1;
|
}
|
|
.list {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
padding: 0 10rpx;
|
overflow: auto;
|
|
|
.list-tip {
|
width: 100%;
|
padding: 15rpx;
|
color: #888;
|
font-size: 25rpx;
|
}
|
|
.center {
|
text-align: center;
|
}
|
|
.list-view {
|
width: 100%;
|
//flex: 1;
|
border-radius: 10rpx;
|
background-color: #fff;
|
|
.list-item {
|
|
border-bottom: 1px solid #ddd;
|
display: flex;
|
flex-direction: row;
|
padding: 10rpx;
|
}
|
|
.list-item:last-child {
|
border-bottom: 0;
|
/* 右下角 */
|
}
|
|
}
|
|
.list-line {
|
display: flex;
|
flex-direction: row;
|
|
.label {
|
font-size: 32rpx;
|
flex: 1;
|
}
|
|
.value {
|
font-size: 32rpx;
|
color: #888;
|
}
|
|
.icon {
|
margin: 5rpx;
|
}
|
|
}
|
|
.button-line {
|
margin: 20rpx;
|
|
.button {
|
margin: auto;
|
width: 500rpx !important;
|
border-radius: 40rpx;
|
height: 80rpx;
|
line-height: 50rpx;
|
}
|
}
|
|
|
.download-progress {
|
display: flex;
|
flex-direction: column;
|
width: 100%;
|
|
.progress {
|
width: 100%;
|
|
}
|
|
.tip {
|
margin-top: 10rpx;
|
padding: 10rpx;
|
text-align: center;
|
}
|
}
|
|
|
|
}
|
|
|
|
}
|
</style>
|